Esempio n. 1
0
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(toLower(base));
    for (unsigned int j = 0; j < parents.size(); j++) {
      parents[j]->checkDerivation(ar, seen);
    }
  }

  seen.erase(m_name);
}
Esempio n. 2
0
int ClassScope::implementsArrayAccess(AnalysisResultPtr ar) {
    hphp_const_char_imap<int>::iterator it = m_implemented.find("arrayaccess");
    if (it != m_implemented.end()) {
        return it->second;
    }

    int ret = 0;
    unsigned s = m_parent.empty() ? 0 : 1;
    for (unsigned i = s; i < m_bases.size(); i++) {
        if (strcasecmp(m_bases[i].c_str(), "arrayaccess")) {
            ret = 1;
            break;
        }
    }

    if (s && !ret) {
        int yes = 0, no = 0;
        const ClassScopePtrVec &classes = ar->findClasses(m_parent);
        BOOST_FOREACH(ClassScopePtr cls, classes) {
            int a = cls->implementsArrayAccess(ar);
            if (a < 0) {
                yes = no = 1;
                break;
            }
            if (a > 0) {
                yes++;
            } else {
                no++;
            }
        }