private function narrowMaybeConditionScope(\PHPParser_Node $expr, LinkedFlowScope $blindScope, $condition) { // In contrast to a non-short-circuiting condition scope, for may-be short-circuiting scopes, // we make the simplification to not narrow down the expression, and the defining expression // by always using the defining expression in case the variable is of boolean type and never // if it has a different type. if (NodeUtil::isName($expr) && null !== ($defExpr = $expr->getAttribute('defining_expr')) && null !== ($exprType = $expr->getAttribute('type')) && $exprType->isBooleanType()) { return $this->firstPreciserScopeKnowingConditionOutcome($defExpr, $blindScope, $condition); } return $this->firstPreciserScopeKnowingConditionOutcome($expr, $blindScope, $condition); }
private function addToDefIfLocal($name, \PHPParser_Node $node = null, \PHPParser_Node $rValue = null, DefinitionLattice $definitions) { $var = $this->scope->getVar($name); if (null === $var) { return; } // Invalidate other definitions if they depended on this variable as it has been changed. foreach ($definitions as $otherVar) { if (null === ($otherDef = $definitions[$otherVar])) { continue; } if ($otherDef->dependsOn($var)) { $definitions[$otherVar] = null; } } // The node can be null if we are dealing with a conditional definition. For conditional // definitions, this analysis cannot do much. if (null === $node) { $definitions[$var] = null; return; } $definition = new Definition($node, $rValue); if (null !== $rValue) { NodeTraversal::traverseWithCallback($rValue, new PreOrderCallback(function ($t, \PHPParser_Node $node) use($definition) { if (NodeUtil::isScopeCreator($node)) { return false; } if (!NodeUtil::isName($node)) { return; } if (null === ($var = $this->scope->getVar($node->name))) { if (null !== $this->logger) { $this->logger->debug(sprintf('Could not find variable "%s" in the current scope. ' . 'This could imply an error in SyntacticScopeCreator.', $node->name)); } // We simply assume that the variable was declared so that we can properly // invalidate the definition if it is changed. For this analysis, it does not // matter whether it actually exists. A later pass will add a warning anyway. $var = $this->scope->declareVar($node->name); } $definition->addDependentVar($var); })); } $definitions[$var] = $definition; }
private function addToUseIfLocal(\PHPParser_Node $varNode, \PHPParser_Node $cfgNode, UseLattice $uses) { if (!NodeUtil::isName($varNode)) { return; } $name = $varNode->name; $var = $this->scope->getVar($name); if (null === $var) { return; } $uses->addUse($var, $cfgNode, $varNode); }