Esempio n. 1
0
void SwitchStatement::analyzeProgram(AnalysisResultConstRawPtr ar) {
  if (ar->getPhase() == AnalysisResult::AnalyzeAll &&
      m_exp->is(Expression::KindOfSimpleVariable)) {
    auto exp = dynamic_pointer_cast<SimpleVariable>(m_exp);
    if (exp && exp->getSymbol() && exp->getSymbol()->isClassName()) {
      // Mark some classes as volatile since the name is used in switch
      for (int i = 0; i < m_cases->getCount(); i++) {
        auto stmt = dynamic_pointer_cast<CaseStatement>((*m_cases)[i]);
        assert(stmt);
        ExpressionPtr caseCond = stmt->getCondition();
        if (caseCond && caseCond->isScalar()) {
          auto name = dynamic_pointer_cast<ScalarExpression>(caseCond);
          if (name && name->isLiteralString()) {
            string className = name->getLiteralString();
            ClassScopePtr cls = ar->findClass(toLower(className));
            if (cls && cls->isUserClass()) {
              cls->setVolatile();
            }
          }
        }
      }
      // Also note this down as code error
      ConstructPtr self = shared_from_this();
      Compiler::Error(Compiler::ConditionalClassLoading, self);
    }
  }
}
Esempio n. 2
0
void ClassVariable::analyzeProgram(AnalysisResultConstRawPtr ar) {
  auto phase = ar->getPhase();
  if (phase != AnalysisResult::AnalyzeAll) {
    return;
  }
  auto scope = getClassScope();
  for (int i = 0; i < m_declaration->getCount(); i++) {
    auto exp = (*m_declaration)[i];
    bool error;
    if (exp->is(Expression::KindOfAssignmentExpression)) {
      auto assignment =
        dynamic_pointer_cast<AssignmentExpression>(exp);
      auto var =
        dynamic_pointer_cast<SimpleVariable>(assignment->getVariable());
      auto value = assignment->getValue();
      scope->getVariables()->setClassInitVal(var->getName(), value);
      error = scope->getVariables()->markOverride(ar, var->getName());
    } else {
      auto var = dynamic_pointer_cast<SimpleVariable>(exp);
      error = scope->getVariables()->markOverride(ar, var->getName());
      scope->getVariables()->setClassInitVal(var->getName(),
                                             makeConstant(ar, "null"));
    }
    if (error) {
      Compiler::Error(Compiler::InvalidOverride, exp);
    }
  }
}
Esempio n. 3
0
void InterfaceStatement::onParse(AnalysisResultConstRawPtr ar,
                                 FileScopePtr scope) {
  std::vector<std::string> bases;
  if (m_base) m_base->getStrings(bases);

  for (auto &b : bases) {
    ar->parseOnDemandByClass(b);
  }

  auto stmt = dynamic_pointer_cast<Statement>(shared_from_this());

  std::vector<UserAttributePtr> attrs;
  if (m_attrList) {
    for (int i = 0; i < m_attrList->getCount(); ++i) {
      auto a = dynamic_pointer_cast<UserAttribute>((*m_attrList)[i]);
      attrs.push_back(a);
    }
  }

  auto classScope =
    std::make_shared<ClassScope>(
      scope, ClassScope::KindOf::Interface, m_originalName, "", bases,
      m_docComment, stmt, attrs);

  setBlockScope(classScope);
  scope->addClass(ar, classScope);

  if (m_stmt) {
    for (int i = 0; i < m_stmt->getCount(); i++) {
      auto ph = dynamic_pointer_cast<IParseHandler>((*m_stmt)[i]);
      ph->onParseRecur(ar, scope, classScope);
    }
    checkArgumentsToPromote(scope, ExpressionListPtr(), T_INTERFACE);
  }
}
Esempio n. 4
0
void InterfaceStatement::analyzeProgram(AnalysisResultConstRawPtr ar) {
  if (ar->getPhase() != AnalysisResult::AnalyzeAll) return;
  std::vector<std::string> bases;
  if (m_base) m_base->getStrings(bases);
  for (unsigned int i = 0; i < bases.size(); i++) {
    ClassScopePtr cls = ar->findClass(bases[i]);
    if (cls) {
      if (!cls->isInterface()) {
        Compiler::Error(
          Compiler::InvalidDerivation,
          shared_from_this(),
          cls->getOriginalName() + " must be an interface");
      }
    }
  }
}
Esempio n. 5
0
void NewObjectExpression::analyzeProgram(AnalysisResultConstRawPtr ar) {
  FunctionCall::analyzeProgram(ar);
  if (ar->getPhase() == AnalysisResult::AnalyzeAll) {
    resolveClass();

    if (m_params) {
      m_params->markParams();
    }
  }
}
Esempio n. 6
0
bool InterfaceStatement::checkVolatileBases(AnalysisResultConstRawPtr ar) {
  ClassScopeRawPtr classScope = getClassScope();
  assert(!classScope->isVolatile());
  auto const& bases = classScope->getBases();
  for (auto it = bases.begin(); it != bases.end(); ++it) {
    ClassScopePtr base = ar->findClass(*it);
    if (base && base->isVolatile()) return true;
  }
  return false;
}
Esempio n. 7
0
void DynamicFunctionCall::analyzeProgram(AnalysisResultConstRawPtr ar) {
  FunctionCall::analyzeProgram(ar);
  if (ar->getPhase() >= AnalysisResult::AnalyzeAll) {
    if (hasStaticClass()) {
      resolveClass();
    }
    if (m_params) {
      m_params->markParams();
    }
  }
}
Esempio n. 8
0
void ClosureExpression::analyzeProgram(AnalysisResultConstRawPtr ar) {
  always_assert(getFileScope() == FileScope::getCurrent());

  auto const sameScope = m_func->getFileScope() == FileScope::getCurrent();
  if (sameScope) {
    // Closures in flattened traits could come from another file.
    // Only let the owner analyze them
    ar->analyzeProgram(m_func);

    if (m_captureState == CaptureState::Unknown) {
      assert(m_type == ClosureType::Short);
      FileScope::getCurrent()->addLambda(ClosureExpressionRawPtr{this});
    }
  } else {
    if (m_captureState == CaptureState::Unknown) {
      assert(m_type == ClosureType::Short);
      ar->lock()->addClonedLambda(ClosureExpressionRawPtr{this});
    }
  }

  if (m_vars && ar->getPhase() == AnalysisResult::AnalyzeAll) {
    if (sameScope) analyzeVarsForClosure(ar);
    analyzeVarsForClosureExpression(ar);
  }

  if (!sameScope || m_func->getModifiers()->isStatic()) return;
  auto const funcScope = getFunctionScope();
  auto const container = funcScope->getContainingNonClosureFunction();
  if (container && container->isStatic()) {
    m_func->getModifiers()->add(T_STATIC);
  } else {
    auto const closureFuncScope = m_func->getFunctionScope();
    if (m_type != ClosureType::Short ||
        closureFuncScope->containsThis()) {
      funcScope->setContainsThis();
    }
  }
}
Esempio n. 9
0
void UseTraitStatement::onParseRecur(AnalysisResultConstRawPtr ar,
                                     FileScopeRawPtr fs,
                                     ClassScopePtr scope) {
  if (scope->isInterface()) {
    parseTimeFatal(fs,
                   "Interfaces cannot use traits");
  }
  std::vector<std::string> usedTraits;
  getUsedTraitNames(usedTraits);
  for (auto &t : usedTraits) {
    ar->parseOnDemandByClass(toLower(t));
  }
  scope->addUsedTraits(usedTraits);
}