void ClassScope::checkDerivation(AnalysisResultPtr ar, hphp_string_iset &seen) { seen.insert(m_name); hphp_string_iset bases; for (int i = m_bases.size() - 1; i >= 0; i--) { const string &base = m_bases[i]; if (seen.find(base) != seen.end() || bases.find(base) != bases.end()) { Compiler::Error( Compiler::InvalidDerivation, m_stmt, "The class hierarchy contains a circular reference involving " + base); if (i == 0 && !m_parent.empty()) { assert(base == m_parent); m_parent.clear(); } m_bases.erase(m_bases.begin() + i); continue; } bases.insert(base); ClassScopePtrVec parents = ar->findClasses(Util::toLower(base)); for (unsigned int j = 0; j < parents.size(); j++) { parents[j]->checkDerivation(ar, seen); } } seen.erase(m_name); }
const ClassScopePtrVec & AnalysisResult::findRedeclaredClasses(const std::string &name) const { StringToClassScopePtrVecMap::const_iterator iter = m_classDecs.find(name); if (iter == m_classDecs.end()) { static ClassScopePtrVec empty; empty.clear(); return empty; } return iter->second; }
void FileScope::getClassesFlattened(ClassScopePtrVec &classes) const { for (const auto& clsVec : m_classes) { for (auto cls : clsVec.second) { classes.push_back(cls); } } }
void AnalysisResult::docJson(const string &filename) { ofstream f(filename.c_str()); if (f.fail()) { Logger::Error("Could not open file for writing doc JSON: %s", filename.c_str()); return; } JSON::DocTarget::OutputStream out(f, shared_from_this()); JSON::DocTarget::MapStream ms(out); ms.add("userland", m_fileScopes); ClassScopePtrVec systemClasses; systemClasses.reserve(m_systemClasses.size()); for (StringToClassScopePtrMap::iterator it = m_systemClasses.begin(); it != m_systemClasses.end(); ++it) { systemClasses.push_back(it->second); } // just generate system classes for now ms.add("system", systemClasses); ms.done(); f.close(); }