void IncludeExpression::analyzeProgram(AnalysisResultPtr ar) { if (!m_include.empty()) { if (ar->getPhase() == AnalysisResult::AnalyzeAll || ar->getPhase() == AnalysisResult::AnalyzeFinal) { analyzeInclude(ar, m_include); } } VariableTablePtr var = getScope()->getVariables(); var->setAttribute(VariableTable::ContainsLDynamicVariable); UnaryOpExpression::analyzeProgram(ar); }
void SimpleVariable::analyzeProgram(AnalysisResultPtr ar) { m_superGlobal = BuiltinSymbols::IsSuperGlobal(m_name); m_superGlobalType = BuiltinSymbols::GetSuperGlobalType(m_name); VariableTablePtr variables = getScope()->getVariables(); if (m_superGlobal) { variables->setAttribute(VariableTable::NeedGlobalPointer); } else if (m_name == "GLOBALS") { m_globals = true; } else { m_sym = variables->addSymbol(m_name); } if (ar->getPhase() == AnalysisResult::AnalyzeAll) { if (FunctionScopePtr func = getFunctionScope()) { if (m_name == "this" && getClassScope()) { func->setContainsThis(); m_this = true; if (!hasContext(ObjectContext)) { func->setContainsBareThis(); if (variables->getAttribute(VariableTable::ContainsDynamicVariable)) { ClassScopePtr cls = getClassScope(); TypePtr t = cls->isRedeclaring() ? Type::Variant : Type::CreateObjectType(cls->getName()); variables->add(m_sym, t, true, ar, shared_from_this(), getScope()->getModifiers()); } } } if (m_sym && !(m_context & AssignmentLHS) && !((m_context & UnsetContext) && (m_context & LValue))) { m_sym->setUsed(); } } } else if (ar->getPhase() == AnalysisResult::AnalyzeFinal) { if (m_sym && !m_sym->isSystem() && !(getContext() & (LValue|RefValue|RefParameter|UnsetContext|ExistContext)) && m_sym->getDeclaration().get() == this && !variables->getAttribute(VariableTable::ContainsLDynamicVariable) && !getScope()->is(BlockScope::ClassScope)) { if (getScope()->inPseudoMain()) { Compiler::Error(Compiler::UseUndeclaredGlobalVariable, shared_from_this()); } else { Compiler::Error(Compiler::UseUndeclaredVariable, shared_from_this()); } } } }
void GlobalStatement::inferTypes(AnalysisResultPtr ar) { BlockScopePtr scope = ar->getScope(); scope->getVariables()->setAttribute(VariableTable::InsideGlobalStatement); for (int i = 0; i < m_exp->getCount(); i++) { ExpressionPtr exp = (*m_exp)[i]; if (exp->is(Expression::KindOfSimpleVariable)) { SimpleVariablePtr var = dynamic_pointer_cast<SimpleVariable>(exp); VariableTablePtr variables = scope->getVariables(); 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->checkRedeclared(name, KindOfGlobalStatement); /* If this is not a top-level global statement, the variable also needs to be Variant type. This should not be a common use case in php code. */ if (!isTopLevel()) { variables->addNestedGlobal(name); } var->setContext(Expression::Declaration); var->inferAndCheck(ar, NEW_TYPE(Any), true); if (variables->needLocalCopy(name)) { variables->forceVariant(ar, name); variables->setAttribute(VariableTable::NeedGlobalPointer); } ConstructPtr decl = ar->getVariables()->getDeclaration(var->getName()); if (decl) { ar->getDependencyGraph()->add(DependencyGraph::KindOfGlobalVariable, ar->getName(), var->getName(), var, var->getName(), decl); } } else { if (ar->isFirstPass()) { ar->getCodeError()->record(shared_from_this(), CodeError::UseDynamicGlobal, exp); } m_dynamicGlobal = true; } } FunctionScopePtr func = ar->getFunctionScope(); scope->getVariables()->clearAttribute(VariableTable::InsideGlobalStatement); }
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 DynamicFunctionCall::analyzeProgram(AnalysisResultPtr ar) { FunctionCall::analyzeProgram(ar); if (ar->getPhase() >= AnalysisResult::AnalyzeAll) { if (!m_className.empty()) { resolveClass(); } if (!m_class) { addUserClass(ar, m_className); } if (m_params) { m_params->markParams(canInvokeFewArgs()); } if (!m_class && m_className.empty()) { FunctionScopePtr fs = getFunctionScope(); VariableTablePtr vt = fs->getVariables(); vt->setAttribute(VariableTable::ContainsDynamicFunctionCall); } } }
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(); // handling $GLOBALS[...] if (m_variable->is(Expression::KindOfSimpleVariable)) { SimpleVariablePtr var = dynamic_pointer_cast<SimpleVariable>(m_variable); if (var->getName() == "GLOBALS") { clearEffect(AccessorEffect); m_global = true; m_dynamicGlobal = true; ar->getScope()->getVariables()-> setAttribute(VariableTable::NeedGlobalPointer); VariableTablePtr vars = ar->getVariables(); 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; ar->getScope()->getVariables()-> setAttribute(VariableTable::NeedGlobalPointer); TypePtr ret; ConstructPtr decl = vars->getDeclaration(m_globalName); if (decl) { ar->getDependencyGraph()-> add(DependencyGraph::KindOfGlobalVariable, ar->getName(), m_globalName, self, m_globalName, decl); } if (coerce) { ret = vars->add(m_globalName, type, true, ar, self, ModifierExpressionPtr()); } else { int p; ret = vars->checkVariable(m_globalName, type, coerce, ar, self, p); } ar->getScope()->getVariables()->addSuperGlobal(m_globalName); return ret; } } } else { vars->setAttribute(VariableTable::ContainsDynamicVariable); } if (hasContext(LValue) || hasContext(RefValue)) { if (ar->isFirstPass()) { ar->getCodeError()->record(self, CodeError::UseLDynamicVariable, self); } ar->getVariables()->forceVariants(ar); ar->getVariables()-> setAttribute(VariableTable::ContainsLDynamicVariable); } else { if (ar->isFirstPass()) { ar->getCodeError()->record(self, CodeError::UseRDynamicVariable, self); } } if (m_offset) { m_offset->inferAndCheck(ar, NEW_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, NEW_TYPE(Sequence), false); m_offset->inferAndCheck(ar, NEW_TYPE(Some), false); } else { if (hasContext(ExistContext) || hasContext(UnsetContext)) { if (ar->isFirstPass()) { ar->getCodeError()->record(self, CodeError::InvalidArrayElement, self); } } m_variable->inferAndCheck(ar, Type::Array, true); } if (varType && Type::SameType(varType, Type::String)) { clearEffect(AccessorEffect); m_implementedType.reset(); return Type::String; } if (varType && Type::SameType(varType, Type::Array)) { clearEffect(AccessorEffect); } if (hasContext(LValue) || hasContext(RefValue)) setEffect(CreateEffect); TypePtr ret = propagateTypes(ar, Type::Variant); m_implementedType = Type::Variant; return ret; // so not to lose values }
void SimpleVariable::analyzeProgram(AnalysisResultPtr ar) { m_superGlobal = BuiltinSymbols::IsSuperGlobal(m_name); m_superGlobalType = BuiltinSymbols::GetSuperGlobalType(m_name); VariableTablePtr variables = getScope()->getVariables(); if (m_superGlobal) { variables->setAttribute(VariableTable::NeedGlobalPointer); } else if (m_name == "GLOBALS") { m_globals = true; } else { m_sym = variables->addDeclaredSymbol(m_name, shared_from_this()); } if (ar->getPhase() == AnalysisResult::AnalyzeAll) { if (FunctionScopePtr func = getFunctionScope()) { if (m_name == "this" && func->mayContainThis()) { func->setContainsThis(); m_this = true; if (!hasContext(ObjectContext)) { bool unset = hasAllContext(UnsetContext | LValue); func->setContainsBareThis( true, hasAnyContext(RefValue | RefAssignmentLHS) || m_sym->isRefClosureVar() || unset); if (variables->getAttribute(VariableTable::ContainsDynamicVariable)) { ClassScopePtr cls = getClassScope(); TypePtr t = !cls || cls->isRedeclaring() ? Type::Variant : Type::CreateObjectType(cls->getName()); variables->add(m_sym, t, true, ar, shared_from_this(), getScope()->getModifiers()); } } } if (m_sym && !(m_context & AssignmentLHS) && !((m_context & UnsetContext) && (m_context & LValue))) { m_sym->setUsed(); } } } else if (ar->getPhase() == AnalysisResult::AnalyzeFinal) { if (m_sym && !m_this) { if (!m_sym->isSystem() && !(getContext() & (LValue|RefValue|RefParameter|UnsetContext|ExistContext)) && m_sym->getDeclaration().get() == this) { assert(!m_sym->isParameter()); if (!variables->getAttribute(VariableTable::ContainsLDynamicVariable) && !getScope()->is(BlockScope::ClassScope)) { if (getScope()->inPseudoMain()) { Compiler::Error(Compiler::UseUndeclaredGlobalVariable, shared_from_this()); } else if (!m_sym->isClosureVar()) { Compiler::Error(Compiler::UseUndeclaredVariable, shared_from_this()); } } } // check function parameter that can occur in lval context if (m_sym->isParameter() && m_context & (LValue | RefValue | DeepReference | UnsetContext | InvokeArgument | OprLValue | DeepOprLValue)) { m_sym->setLvalParam(); } } } }
/** * 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))) { setEffect(DiagnosticEffect); } if (m_context & (AssignmentLHS|OprLValue)) { clearEffect(AccessorEffect); } else if (m_context & (LValue | RefValue)) { setEffect(CreateEffect); } // handling $GLOBALS[...] if (m_variable->is(Expression::KindOfSimpleVariable)) { SimpleVariablePtr var = dynamic_pointer_cast<SimpleVariable>(m_variable); if (var->getName() == "GLOBALS") { clearEffect(AccessorEffect); m_global = true; m_dynamicGlobal = true; getScope()->getVariables()-> setAttribute(VariableTable::NeedGlobalPointer); VariableTablePtr vars = ar->getVariables(); 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; clearEffect(DiagnosticEffect); getScope()->getVariables()-> setAttribute(VariableTable::NeedGlobalPointer); TypePtr ret; if (coerce) { ret = vars->add(m_globalName, type, true, ar, self, ModifierExpressionPtr()); } else { int p; ret = vars->checkVariable(m_globalName, type, coerce, ar, self, p); } getScope()->getVariables()->addSuperGlobal(m_globalName); return ret; } } } else { vars->setAttribute(VariableTable::ContainsDynamicVariable); } if (hasContext(LValue) || hasContext(RefValue)) { ar->getVariables()->forceVariants(ar, VariableTable::AnyVars); ar->getVariables()-> 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)) { clearEffect(AccessorEffect); m_implementedType.reset(); return Type::String; } if (varType && Type::SameType(varType, Type::Array)) { clearEffect(AccessorEffect); } TypePtr ret = propagateTypes(ar, Type::Variant); m_implementedType = Type::Variant; return ret; // so not to lose values }