public function enterNode(\PHPParser_Node $node) { // Determine info about the closure's location if (!$this->closureNode) { if ($node instanceof \PHPParser_Node_Stmt_Namespace) { $this->location->namespace = is_array($node->name->parts) ? implode('\\', $node->name->parts) : null; } if ($node instanceof \PHPParser_Node_Stmt_Trait) { $this->location->trait = $this->location->namespace . '\\' . $node->name; $this->location->class = null; } elseif ($node instanceof \PHPParser_Node_Stmt_Class) { $this->location->class = $this->location->namespace . '\\' . $node->name; $this->location->trait = null; } } // Locate the node of the closure if ($node instanceof \PHPParser_Node_Expr_Closure) { if ($node->getAttribute('startLine') == $this->reflection->getStartLine()) { if ($this->closureNode) { throw new \RuntimeException('Two closures were declared on the same line of code. Cannot determine ' . 'which closure was the intended target.'); } else { $this->closureNode = $node; } } } }
private function processFunction(array $definition, PHPParser_Node $node) { $message = array(GettextExtractor_Extractor::LINE => $node->getLine()); foreach ($definition as $type => $position) { if (!isset($node->args[$position - 1])) { return; } $arg = $node->args[$position - 1]->value; if ($arg instanceof PHPParser_Node_Scalar_String) { $message[$type] = $arg->value; } elseif ($arg instanceof PHPParser_Node_Expr_Array) { foreach ($arg->items as $item) { if ($item->value instanceof PHPParser_Node_Scalar_String) { $message[$type][] = $item->value->value; } } if (count($message) === 1) { // line only return; } } else { return; } } if (is_array($message[GettextExtractor_Extractor::SINGULAR])) { foreach ($message[GettextExtractor_Extractor::SINGULAR] as $value) { $tmp = $message; $tmp[GettextExtractor_Extractor::SINGULAR] = $value; $this->data[] = $tmp; } } else { $this->data[] = $message; } }
/** * Dumps a node or array. * * @param array|PHPParser_Node $node Node or array to dump * * @return string Dumped value */ public function dump($node) { if ($node instanceof PHPParser_Node) { $r = $node->getType() . '('; } elseif (is_array($node)) { $r = 'array('; } else { throw new InvalidArgumentException('Can only dump nodes and arrays.'); } foreach ($node as $key => $value) { $r .= "\n" . ' ' . $key . ': '; if (null === $value) { $r .= 'null'; } elseif (false === $value) { $r .= 'false'; } elseif (true === $value) { $r .= 'true'; } elseif (is_scalar($value)) { $r .= $value; } else { $r .= str_replace("\n", "\n" . ' ', $this->dump($value)); } } return $r . "\n" . ')'; }
/** * {@inheritdoc} */ public function leaveNode(PHPParser_Node $node) { if (!isset($this->metaData[$node->getType()])) { return; } $this->checkSize($node); }
/** * Swap out __DIR__ and __FILE__ constants, because the default ones when * calling eval() don't make sense. * * @param Node $node * * @return null|FunctionCall|StringNode */ public function enterNode(Node $node) { if ($node instanceof DirConstant) { return new FunctionCall(new Name('getcwd'), array(), $node->getAttributes()); } elseif ($node instanceof FileConstant) { return new StringNode('', $node->getAttributes()); } }
public function leaveNode(\PHPParser_Node $node) { if (isset($node->stmts)) { $node->stmts = new BlockNode($node->stmts, $node->getLine()); } if ($node instanceof \PHPParser_Node_Stmt_Namespace) { $node->setAttribute('imports', $this->imports); } }
/** * Validate that namespaced constant references will succeed. * * Note that this does not (yet) detect constants defined in the current code * snippet. It won't happen very often, so we'll punt for now. * * @throws FatalErrorException if a constant reference is not defined. * * @param Node $node */ public function leaveNode(Node $node) { if ($node instanceof ConstantFetch && count($node->name->parts) > 1) { $name = $this->getFullyQualifiedName($node->name); if (!defined($name)) { throw new FatalErrorException(sprintf('Undefined constant %s', $name), 0, 1, null, $node->getLine()); } } }
/** * Normalizes a node: Converts builder objects to nodes. * * @param PHPParser_Node|PHPParser_Builder $node The node to normalize * * @return PHPParser_Node The normalized node */ protected function normalizeNode($node) { if ($node instanceof PHPParser_Builder) { return $node->getNode(); } elseif ($node instanceof PHPParser_Node) { return $node; } throw new LogicException('Expected node or builder object'); }
/** * {@inheritDoc} */ public function leaveNode(\PHPParser_Node $node) { if ($node->getType() === 'Stmt_Class') { if ($this->newInterface) { $this->newContent[] = $this->buildNewInterface(); } $this->newInterface = false; } parent::leaveNode($node); }
/** * @param \PHPParser_Node $node * @return PHPParser_Node|void */ public function leaveNode(PHPParser_Node $node) { if (NULL !== $node->__get('class')) { $oldClassName = Tx_PhpParser_Parser_Utility_NodeConverter::getValueFromNode($node->__get('class')); if (strpos($oldClassName, $this->oldClassPrefix) !== FALSE) { $newClassName = str_replace($this->oldClassPrefix, $this->newClassPrefix, $oldClassName); $node->setClass(Tx_PhpParser_Parser_NodeFactory::buildNodeFromName($newClassName)); return $node; } } }
public function getNodeCode(\PHPParser_Node $node) { $startPos = $node->getAttribute('startOffset'); $endPos = $node->getAttribute('endOffset'); if ($startPos === null || $endPos === null) { return ''; // just to be sure } $startOffset = $this->tokenToStartOffset[$startPos]; $endOffset = $this->tokenToEndOffset[$endPos]; return substr($this->code, $startOffset, $endOffset - $startOffset); }
public function leaveNode(\PHPParser_Node $node) { if ($node instanceof \PHPParser_Node_Stmt_Trait) { // Leave traits implemented as classes. // It prevents that files that require/use them break. $klass = new \PhpParser\Node\Stmt\Class_($node->name, ['stmts' => $node->stmts], $node->getAttributes()); return $klass; } if ($node instanceof \PHPParser_Node_Stmt_TraitUse) { return false; } }
protected function compileNode(\PHPParser_Node $node, Zval\Ptr $returnContext = null) { $nodeType = $node->getType(); if (isset($this->operators[$nodeType])) { call_user_func_array(array($this, 'compile' . $this->operators[$nodeType][0]), array_merge(array($node, $returnContext), array_slice($this->operators[$nodeType], 1))); return; } $methodName = 'compile_' . $nodeType; if (!method_exists($this, $methodName)) { var_dump($node); throw new CompileException($nodeType . ' not supported yet', $node->line); } call_user_func(array($this, $methodName), $node, $returnContext); }
/** * {@inheritdoc} */ public function leaveNode(PHPParser_Node $node) { return; switch ($node->getType()) { case 'Stmt_ClassMethod': case 'Expr_Closure': case 'Stmt_Function': case 'Stmt_If': case 'Stmt_Do': case 'Stmt_While': case 'Stmt_For': case 'Stmt_Foreach': break; } }
/** * @depends testConstruct */ public function testChange(PHPParser_Node $node) { // change of line $node->setLine(15); $this->assertEquals(15, $node->getLine()); // direct modification $node->subNode = 'newValue'; $this->assertEquals('newValue', $node->subNode); // indirect modification $subNode =& $node->subNode; $subNode = 'newNewValue'; $this->assertEquals('newNewValue', $node->subNode); // removal unset($node->subNode); $this->assertFalse(isset($node->subNode)); }
public function enterNode(PHPParser_Node $node) { if ($node instanceof PHPParser_Node_Stmt_Namespace) { $this->namespace = $node->name; $this->aliases = array(); } elseif ($node instanceof PHPParser_Node_Stmt_UseUse) { if (isset($this->aliases[$node->alias])) { throw new PHPParser_Error(sprintf('Cannot use "%s" as "%s" because the name is already in use', $node->name, $node->alias), $node->getLine()); } $this->aliases[$node->alias] = $node->name; } elseif ($node instanceof PHPParser_Node_Stmt_Class) { if (null !== $node->extends) { $node->extends = $this->resolveClassName($node->extends); } foreach ($node->implements as &$interface) { $interface = $this->resolveClassName($interface); } $this->addNamespacedName($node); } elseif ($node instanceof PHPParser_Node_Stmt_Interface) { foreach ($node->extends as &$interface) { $interface = $this->resolveClassName($interface); } $this->addNamespacedName($node); } elseif ($node instanceof PHPParser_Node_Stmt_Trait) { $this->addNamespacedName($node); } elseif ($node instanceof PHPParser_Node_Stmt_Function) { $this->addNamespacedName($node); } elseif ($node instanceof PHPParser_Node_Stmt_Const) { foreach ($node->consts as $const) { $this->addNamespacedName($const); } } elseif ($node instanceof PHPParser_Node_Expr_StaticCall || $node instanceof PHPParser_Node_Expr_StaticPropertyFetch || $node instanceof PHPParser_Node_Expr_ClassConstFetch || $node instanceof PHPParser_Node_Expr_New || $node instanceof PHPParser_Node_Expr_Instanceof) { if ($node->class instanceof PHPParser_Node_Name) { $node->class = $this->resolveClassName($node->class); } } elseif ($node instanceof PHPParser_Node_Expr_FuncCall || $node instanceof PHPParser_Node_Expr_ConstFetch) { if ($node->name instanceof PHPParser_Node_Name) { $node->name = $this->resolveOtherName($node->name); } } elseif ($node instanceof PHPParser_Node_Stmt_TraitUse) { foreach ($node->traits as &$trait) { $trait = $this->resolveClassName($trait); } } elseif ($node instanceof PHPParser_Node_Param && $node->type instanceof PHPParser_Node_Name) { $node->type = $this->resolveClassName($node->type); } }
/** * {@inheritDoc} */ public function leaveNode(\PHPParser_Node $node) { switch ($node->getType()) { case 'Stmt_Class': case 'Stmt_Interface': case 'Stmt_Trait': $this->currentClass = false; break; case 'Stmt_ClassMethod': $this->currentMethod = false; break; case 'PhpFile': if ($this->currentPhpFile->isModified()) { return $this->currentPhpFile; } break; } }
public function leaveNode(PHPParser_Node $node) { if ($node instanceof PHPParser_Node_Expr_Array) { return new PHPParser_Node_Expr_AssignListInner($node->getSubNodes()); } elseif ($node instanceof PHPParser_Node_Expr_Variable || $node instanceof PHPParser_Node_Expr_ConstFetch) { return null; } elseif ($node instanceof PHPParser_Node_Name && $node->parts[0] === "null") { return new PHPParser_Node_Expr_Pass(array()); } elseif ($node instanceof PHPParser_Node_Expr_ArrayItem) { if ($node->key !== null) { throw new PHPParser_Error(self::keyFound, $node->getLine()); } if ($node->byRef !== false) { throw new PHPParser_Error(self::byRefFound, $node->getLine()); } } else { return $node; } }
/** * Pretty prints a node. * * @param PHPParser_Node $node Node to be pretty printed * * @return string Pretty printed node */ protected function p(PHPParser_Node $node) { $type = $node->getType(); if (isset($this->precedanceMap[$type])) { $precedence = $this->precedanceMap[$type]; if ($precedence >= $this->precedenceStack[$this->precedenceStackPos]) { $this->precedenceStack[++$this->precedenceStackPos] = $precedence; $return = '(' . $this->{'p' . $type}($node) . ')'; --$this->precedenceStackPos; } else { $this->precedenceStack[++$this->precedenceStackPos] = $precedence; $return = $this->{'p' . $type}($node); --$this->precedenceStackPos; } return $return; } else { return $this->{'p' . $type}($node); } }
public function enterNode(\PHPParser_Node $node) { if (!$node instanceof \PHPParser_Node_Scalar_String) { return; } $id = $node->value; if (preg_match('/(\\.\\.|\\.\\.\\.)/', $id)) { return; } if (preg_match('/^http/', $id)) { return; } if (preg_match('/.*\\./', $id)) { $domain = 'messages'; $message = new Message($id, $domain); $message->addSource(new FileSource((string) $this->file, $node->getLine())); $this->catalogue->add($message); } }
/** * {@inheritdoc} */ public function leaveNode(\PHPParser_Node $node) { switch ($node->getType()) { case 'Stmt_ClassMethod': $this->currentMethodRelevant = false; break; case 'Stmt_Class': // generate foreach ($this->factoryMethodStack as $name => $calling) { $factory = new \PHPParser_Node_Stmt_ClassMethod($name); $factory->type = \PHPParser_Node_Stmt_Class::MODIFIER_PROTECTED; $factory->params = $this->getProcessedArgument($calling->args); $class = $calling->getAttribute('classShortcut'); $factory->stmts = array(new \PHPParser_Node_Stmt_Return(new \PHPParser_Node_Expr_New(new \PHPParser_Node_Name($class), $factory->params))); $this->currentClassStmts[] = $factory; } break; } return parent::leaveNode($node); }
public function leaveNode(\PHPParser_Node $node) { switch ($node->getType()) { case 'Scalar_MagicConst_Line': return new NumberNode($node->getAttribute('startLine')); case 'Scalar_MagicConst_File': return new StringNode($this->location->file); case 'Scalar_MagicConst_Dir': return new StringNode($this->location->directory); case 'Scalar_MagicConst_Function': return new StringNode($this->location->function); case 'Scalar_MagicConst_Namespace': return new StringNode($this->location->namespace); case 'Scalar_MagicConst_Class': return new StringNode($this->location->class); case 'Scalar_MagicConst_Method': return new StringNode($this->location->method); case 'Scalar_MagicConst_Trait': return new StringNode($this->location->trait); } }
/** * Returns the type of the given node in the flow scope. * * If the node cannot be matched to a slot, or simply is not capable of being * refined, then this method returns null. * * @return PhpType|null */ public function getTypeIfRefinable(\PHPParser_Node $node, LinkedFlowScope $scope) { switch (true) { case $node instanceof \PHPParser_Node_Expr_ArrayDimFetch: $varType = $this->getTypeIfRefinable($node->var, $scope); if ($varType && $varType->isArrayType()) { $dim = \Scrutinizer\PhpAnalyzer\PhpParser\NodeUtil::getValue($node->dim); if ($dim->isEmpty()) { return null; } return $dim->flatMap([$varType, 'getItemType'])->getOrCall([$varType, 'getElementType']); } return null; // Handle the common pattern of assigning the result of an expression // inside of a condition, e.g. ``if (null !== $obj = $this->findObj())``. // Handle the common pattern of assigning the result of an expression // inside of a condition, e.g. ``if (null !== $obj = $this->findObj())``. case $node instanceof \PHPParser_Node_Expr_Assign: case $node instanceof \PHPParser_Node_Expr_AssignRef: if (TypeInference::hasQualifiedName($node->var) && null !== ($qualifiedName = TypeInference::getQualifiedName($node->var)) && null !== ($nameVar = $scope->getSlot($node->var->name))) { if (null !== ($nameType = $nameVar->getType())) { return $nameType; } return $node->var->getAttribute('type'); } return null; case $node instanceof \PHPParser_Node_Expr_Variable: if (is_string($node->name)) { $nameVar = $scope->getSlot($node->name); if (null !== $nameVar) { if (null !== $nameVar->getType()) { return $nameVar->getType(); } return $node->getAttribute('type'); } } return null; case $node instanceof \PHPParser_Node_Expr_StaticPropertyFetch: case $node instanceof \PHPParser_Node_Expr_PropertyFetch: if (null === ($qualifiedName = TypeInference::getQualifiedName($node))) { return null; } $propVar = $scope->getSlot($qualifiedName); if (null !== $propVar && null !== $propVar->getType()) { return $propVar->getType(); } if (null !== ($type = $node->getAttribute('type'))) { return $type; } return null; } return null; }
/** * Validate that function calls will succeed. * * @throws FatalErrorException if a function is redefined. * @throws FatalErrorException if the function name is a string (not an expression) and is not defined. * * @param Node $node */ public function leaveNode(Node $node) { if ($node instanceof FunctionStatement) { $name = $this->getFullyQualifiedName($node->name); if (function_exists($name) || isset($this->currentScope[strtolower($name)])) { throw new FatalErrorException(sprintf('Cannot redeclare %s()', $name), 0, 1, null, $node->getLine()); } $this->currentScope[strtolower($name)] = true; } elseif ($node instanceof FunctionCall) { // if function name is an expression, give it a pass for now. $name = $node->name; if (!$name instanceof Expression) { $shortName = implode('\\', $name->parts); $fullName = $this->getFullyQualifiedName($name); if (!isset($this->currentScope[strtolower($fullName)]) && !function_exists($shortName) && !function_exists($fullName)) { $message = sprintf('Call to undefined function %s()', $name); throw new FatalErrorException($message, 0, 1, null, $node->getLine()); } } } }
public function setInput($code, \PHPParser_Node $ast = null) { $this->astStream->setAst($ast ?: PhpParser\ParseUtils::parse($code)); $this->tokenStream->setCode($code); $lastNode = null; while ($this->moveNext()) { if ($lastNode !== $this->node) { $this->node->setAttribute('start_token', $this->token); if (null !== $lastNode) { $lastNode->setAttribute('end_token', $this->token->getPreviousToken()->get()); } } $lastNode = $this->node; } $this->reset(); }
private function getDocCommentForNode(\PHPParser_Node $node) { // check if there is a doc comment for the ID argument // ->trans(/** @Desc("FOO") */ 'my.id') if (null !== ($comment = $node->args[0]->getDocComment())) { return $comment->getText(); } // this may be placed somewhere up in the hierarchy, // -> /** @Desc("FOO") */ trans('my.id') // /** @Desc("FOO") */ ->trans('my.id') // /** @Desc("FOO") */ $translator->trans('my.id') if (null !== ($comment = $node->getDocComment())) { return $comment->getText(); } elseif (null !== $this->previousNode && $this->previousNode->getDocComment() !== null) { $comment = $this->previousNode->getDocComment(); return is_object($comment) ? $comment->getText() : $comment; } return null; }
protected function addNamespacedName(PHPParser_Node $node) { if (null !== $this->namespace) { $node->namespacedName = clone $this->namespace; $node->namespacedName->append($node->name); } else { $node->namespacedName = new PHPParser_Node_Name($node->name, $node->getAttributes()); } }
private function attachLiteralTypes(\PHPParser_Node $node, \PHPParser_Node $parent = null) { switch (true) { case $node instanceof \PHPParser_Node_Name_FullyQualified: $node->setAttribute('type', $this->typeRegistry->getClassOrCreate(implode("\\", $node->parts))); break; case $node instanceof \PHPParser_Node_Name: if ($parent instanceof \PHPParser_Node_Expr_New || $parent instanceof \PHPParser_Node_Expr_StaticPropertyFetch || $parent instanceof \PHPParser_Node_Expr_StaticCall || $parent instanceof \PHPParser_Node_Expr_Instanceof || $parent instanceof \PHPParser_Node_Stmt_Catch) { $name = implode("\\", $node->parts); $lowerName = strtolower($name); if ('static' === $name) { $node->setAttribute('type', $this->typeRegistry->getThisType($this->scope->getTypeOfThis())); } else { if ('self' === $name) { $node->setAttribute('type', $this->scope->getTypeOfThis()); } else { if ('parent' === $name) { $thisType = $this->scope->getTypeOfThis()->toMaybeObjectType(); if (null === $thisType || !$thisType->isClass() || null === $thisType->getSuperClassType()) { $node->setAttribute('type', $this->typeRegistry->getNativeType('unknown')); } else { $node->setAttribute('type', $thisType->getSuperClassType()); } } else { $node->setAttribute('type', $this->typeRegistry->getClassOrCreate($name)); } } } } break; case $node instanceof \PHPParser_Node_Expr_Array: case $node instanceof \PHPParser_Node_Expr_Cast_Array: // We only do attach the generic array type on the first build. // For subsequent builds, other passes likely have already made // the array type more specific. if (null === $node->getAttribute('type')) { $node->setAttribute('type', $this->typeRegistry->getNativeType('array')); } break; case $node instanceof \PHPParser_Node_Expr_UnaryMinus: case $node instanceof \PHPParser_Node_Expr_UnaryPlus: case $node instanceof \PHPParser_Node_Scalar_LNumber: case $node instanceof \PHPParser_Node_Scalar_LineConst: $node->setAttribute('type', $this->typeRegistry->getNativeType('integer')); break; case $node instanceof \PHPParser_Node_Scalar_DNumber: $node->setAttribute('type', $this->typeRegistry->getNativeType('double')); break; case $node instanceof \PHPParser_Node_Scalar_String: case $node instanceof \PHPParser_Node_Scalar_FileConst: case $node instanceof \PHPParser_Node_Scalar_DirConst: $node->setAttribute('type', $this->typeRegistry->getNativeType('string')); break; case $node instanceof \PHPParser_Node_Expr_ClassConstFetch: if ($node->class instanceof \PHPParser_Node_Name && in_array($node->class->parts[0], array('self', 'static')) && null !== ($thisType = $this->scope->getTypeOfThis()) && null !== ($objType = $thisType->toMaybeObjectType()) && ($objType->isClass() || $objType->isInterface()) && $objType->hasConstant($node->name)) { $node->setAttribute('type', $objType->getConstant($node->name)->getPhpType()); } break; case $node instanceof \PHPParser_Node_Expr_ConstFetch: $nameParts = $node->name->parts; if (1 === count($nameParts)) { $name = strtolower($nameParts[0]); if ('true' === $name) { $node->setAttribute('type', $this->typeRegistry->getNativeType('boolean')); } else { if ('false' === $name) { $node->setAttribute('type', $this->typeRegistry->getNativeType('false')); } else { if ('null' === $name) { $node->setAttribute('type', $this->typeRegistry->getNativeType('null')); } } } } break; } }
/** * Returns the class a method was called on. * * @param \PHPParser_Node $node * * @return null|PhpType */ public function getCalledClassByNode(\PHPParser_Node $node) { switch (true) { case $node instanceof \PHPParser_Node_Expr_MethodCall: if (null === ($objType = $node->var->getAttribute('type'))) { return null; } return $objType->restrictByNotNull()->toMaybeObjectType(); case $node instanceof \PHPParser_Node_Expr_StaticCall: if (null === ($objType = $node->class->getAttribute('type'))) { return null; } return $objType->restrictByNotNull()->toMaybeObjectType(); case $node instanceof \PHPParser_Node_Expr_New: if (null === ($objType = $node->getAttribute('type'))) { return null; } return $objType->restrictByNotNull()->toMaybeObjectType(); default: throw new \InvalidArgumentException('The node class "' . get_class($node) . '" is not resolvable to a function/method.'); } }
public function enterNode(\PHPParser_Node $node) { if ($node instanceof \PHPParser_Node_Stmt_Namespace) { $this->namespace = implode('\\', $node->name->parts); return; } if ($node instanceof \PHPParser_Node_Stmt_Class) { $name = '' === $this->namespace ? $node->name : $this->namespace . '\\' . $node->name; if (!class_exists($name)) { return; } $ref = new \ReflectionClass($name); if (!$ref->isSubclassOf('Symfony\\Component\\Security\\Core\\Exception\\AuthenticationException') && $ref->name !== 'Symfony\\Component\\Security\\Core\\Exception\\AuthenticationException') { return; } if (!$ref->hasMethod('getMessageKey')) { return; } $this->inAuthException = true; return; } if (!$this->inAuthException) { return; } if ($node instanceof \PHPParser_Node_Stmt_ClassMethod) { if ('getmessagekey' === strtolower($node->name)) { $this->inGetMessageKey = true; } return; } if (!$this->inGetMessageKey) { return; } if (!$node instanceof \PHPParser_Node_Stmt_Return) { return; } $ignore = false; $desc = $meaning = null; if ($docComment = $node->getDocComment()) { foreach ($this->docParser->parse($docComment->getText(), 'file ' . $this->file . ' near line ' . $node->getLine()) as $annot) { if ($annot instanceof Ignore) { $ignore = true; } else { if ($annot instanceof Desc) { $desc = $annot->text; } else { if ($annot instanceof Meaning) { $meaning = $annot->text; } } } } } if (!$node->expr instanceof \PHPParser_Node_Scalar_String) { if ($ignore) { return; } $message = sprintf('Could not extract id from return value, expected scalar string but got %s (in %s on line %d).', get_class($node->expr), $this->file, $node->expr->getLine()); if ($this->logger) { $this->logger->err($message); return; } throw new RuntimeException($message); } $message = Message::create($node->expr->value, $this->domain)->setDesc($desc)->setMeaning($meaning)->addSource(new FileSource((string) $this->file, $node->expr->getLine())); $this->catalogue->add($message); }