void GlobalStatement::inferTypes(AnalysisResultPtr ar) { IMPLEMENT_INFER_AND_CHECK_ASSERT(getScope()); BlockScopePtr scope = getScope(); for (int i = 0; i < m_exp->getCount(); i++) { ExpressionPtr exp = (*m_exp)[i]; VariableTablePtr variables = scope->getVariables(); variables->setAttribute(VariableTable::NeedGlobalPointer); if (exp->is(Expression::KindOfSimpleVariable)) { SimpleVariablePtr var = dynamic_pointer_cast<SimpleVariable>(exp); const std::string &name = var->getName(); /* If we have already seen this variable in the current scope and it is not a global variable, record this variable as "redeclared" which will force Variant type. */ variables->setAttribute(VariableTable::InsideGlobalStatement); variables->checkRedeclared(name, KindOfGlobalStatement); variables->addLocalGlobal(name); var->setContext(Expression::Declaration); var->inferAndCheck(ar, Type::Any, true); variables->forceVariant(ar, name, VariableTable::AnyVars); variables->clearAttribute(VariableTable::InsideGlobalStatement); } else { variables->forceVariants(ar, VariableTable::AnyVars); variables->setAttribute(VariableTable::ContainsLDynamicVariable); assert(exp->is(Expression::KindOfDynamicVariable)); exp->inferAndCheck(ar, Type::Any, true); } } }
void IncludeExpression::analyzeProgram(AnalysisResultPtr ar) { if (!m_include.empty()) { if (ar->getPhase() == AnalysisResult::AnalyzeInclude) { ar->parseOnDemand(m_include); } else if (ar->getPhase() == AnalysisResult::AnalyzeAll) { analyzeInclude(ar, m_include); } } if (!getScope()->inPseudoMain() && !m_privateScope) { VariableTablePtr var = getScope()->getVariables(); var->setAttribute(VariableTable::ContainsLDynamicVariable); var->forceVariants(ar, VariableTable::AnyVars); } UnaryOpExpression::analyzeProgram(ar); }
void IncludeExpression::analyzeProgram(AnalysisResultPtr ar) { if (!m_include.empty()) { if (ar->getPhase() == AnalysisResult::AnalyzeAll || ar->getPhase() == AnalysisResult::AnalyzeFinal) { if (analyzeInclude(ar, m_include)) { FunctionScopePtr func = getFunctionScope(); getFileScope()->addIncludeDependency(ar, m_include, func && func->isInlined()); } } } VariableTablePtr var = getScope()->getVariables(); var->setAttribute(VariableTable::ContainsLDynamicVariable); var->forceVariants(ar, VariableTable::AnyVars); UnaryOpExpression::analyzeProgram(ar); }
void IncludeExpression::analyzeProgram(AnalysisResultPtr ar) { if (ar->isFirstPass()) { ConstructPtr self = shared_from_this(); if (m_op == T_INCLUDE || m_op == T_REQUIRE) { ar->getCodeError()->record(self, CodeError::UseInclude, self); } } string include = getCurrentInclude(ar); if (!include.empty()) { if (ar->getPhase() == AnalysisResult::AnalyzeInclude) { analyzeInclude(ar, include); } } if (!ar->getScope()->inPseudoMain()) { VariableTablePtr var = ar->getScope()->getVariables(); var->setAttribute(VariableTable::ContainsLDynamicVariable); var->forceVariants(ar); } UnaryOpExpression::analyzeProgram(ar); }
/** * ArrayElementExpression comes from: * * reference_variable[|expr] * ->object_dim_list[|expr] * encaps T_VARIABLE[expr] * encaps ${T_STRING[expr]} */ TypePtr ArrayElementExpression::inferTypes(AnalysisResultPtr ar, TypePtr type, bool coerce) { ConstructPtr self = shared_from_this(); if (m_offset && !(m_context & (UnsetContext | ExistContext | InvokeArgument | LValue | RefValue))) { setLocalEffect(DiagnosticEffect); } if (m_context & (AssignmentLHS|OprLValue)) { clearLocalEffect(AccessorEffect); } else if (m_context & (LValue | RefValue)) { setLocalEffect(CreateEffect); } // handling $GLOBALS[...] if (m_variable->is(Expression::KindOfSimpleVariable)) { SimpleVariablePtr var = dynamic_pointer_cast<SimpleVariable>(m_variable); if (var->getName() == "GLOBALS") { clearLocalEffect(AccessorEffect); m_global = true; m_dynamicGlobal = true; getScope()->getVariables()-> setAttribute(VariableTable::NeedGlobalPointer); VariableTablePtr vars = ar->getVariables(); Lock l(ar->getMutex()); if (m_offset && m_offset->is(Expression::KindOfScalarExpression)) { ScalarExpressionPtr offset = dynamic_pointer_cast<ScalarExpression>(m_offset); if (offset->isLiteralString()) { m_globalName = offset->getIdentifier(); if (!m_globalName.empty()) { m_dynamicGlobal = false; clearLocalEffect(DiagnosticEffect); getScope()->getVariables()-> setAttribute(VariableTable::NeedGlobalPointer); TypePtr ret; if (coerce) { ret = vars->add(m_globalName, type, true, ar, self, ModifierExpressionPtr()); } else { ret = vars->checkVariable(m_globalName, type, coerce, ar, self); } getScope()->getVariables()->addSuperGlobal(m_globalName); return ret; } } } else { vars->setAttribute(VariableTable::ContainsDynamicVariable); } if (hasContext(LValue) || hasContext(RefValue)) { vars->forceVariants(ar, VariableTable::AnyVars); vars->setAttribute(VariableTable::ContainsLDynamicVariable); } if (m_offset) { m_offset->inferAndCheck(ar, Type::Primitive, false); } return m_implementedType = Type::Variant; // so not to lose values } } if ((hasContext(LValue) || hasContext(RefValue)) && !hasContext(UnsetContext)) { m_variable->setContext(LValue); } TypePtr varType; if (m_offset) { varType = m_variable->inferAndCheck(ar, coerce ? Type::AutoSequence : Type::Sequence, coerce); m_offset->inferAndCheck(ar, Type::Some, false); } else { if (hasContext(ExistContext) || hasContext(UnsetContext)) { if (getScope()->isFirstPass()) { Compiler::Error(Compiler::InvalidArrayElement, self); } } m_variable->inferAndCheck(ar, Type::Array, true); } if (varType && Type::SameType(varType, Type::String)) { m_implementedType.reset(); return Type::String; } TypePtr ret = propagateTypes(ar, Type::Variant); m_implementedType = Type::Variant; return ret; // so not to lose values }