Chris@13: conditionalScopes++; Chris@13: } elseif ($node instanceof Function_) { Chris@13: $name = $this->getFullyQualifiedName($node->name); Chris@13: Chris@13: // @todo add an "else" here which adds a runtime check for instances where we can't tell Chris@13: // whether a function is being redefined by static analysis alone. Chris@13: if ($this->conditionalScopes === 0) { Chris@17: if (\function_exists($name) || Chris@17: isset($this->currentScope[\strtolower($name)])) { Chris@17: $msg = \sprintf('Cannot redeclare %s()', $name); Chris@13: throw new FatalErrorException($msg, 0, E_ERROR, null, $node->getLine()); Chris@13: } Chris@13: } Chris@13: Chris@17: $this->currentScope[\strtolower($name)] = true; Chris@13: } Chris@13: } Chris@13: Chris@13: /** Chris@13: * Validate that function calls will succeed. Chris@13: * Chris@13: * @throws FatalErrorException if a function is redefined Chris@13: * @throws FatalErrorException if the function name is a string (not an expression) and is not defined Chris@13: * Chris@13: * @param Node $node Chris@13: */ Chris@13: public function leaveNode(Node $node) Chris@13: { Chris@13: if (self::isConditional($node)) { Chris@13: $this->conditionalScopes--; Chris@13: } elseif ($node instanceof FuncCall) { Chris@13: // if function name is an expression or a variable, give it a pass for now. Chris@13: $name = $node->name; Chris@13: if (!$name instanceof Expr && !$name instanceof Variable) { Chris@17: $shortName = \implode('\\', $name->parts); Chris@13: $fullName = $this->getFullyQualifiedName($name); Chris@17: $inScope = isset($this->currentScope[\strtolower($fullName)]); Chris@17: if (!$inScope && !\function_exists($shortName) && !\function_exists($fullName)) { Chris@17: $message = \sprintf('Call to undefined function %s()', $name); Chris@13: throw new FatalErrorException($message, 0, E_ERROR, null, $node->getLine()); Chris@13: } Chris@13: } Chris@13: } Chris@13: } Chris@13: Chris@13: private static function isConditional(Node $node) Chris@13: { Chris@13: return $node instanceof If_ || Chris@13: $node instanceof While_ || Chris@13: $node instanceof Do_ || Chris@13: $node instanceof Switch_; Chris@13: } Chris@13: }