function enterNode(\PhpParser\Node $node) { if ($node instanceof \PhpParser\Node\Stmt\Namespace_) { $this->addNamespace(array('namespace' => $node->name->toString(), 'line' => $node->getLine(), 'file' => $this->file)); } if ($node instanceof \PhpParser\Node\Stmt\Use_) { foreach ($node->uses as $use) { $this->addUse(array('name' => $use->name, 'alias' => $use->alias)); } } if ($node instanceof \PhpParser\Node\Stmt\Class_) { $this->addClass(array('name' => $node->name, 'extends' => $node->extends, 'implements' => $node->implements, 'abstract' => $node->isAbstract(), 'final' => $node->isFinal(), 'comment' => $node->getDocComment(), 'doc' => $this->doc_comment_parser->parse($node->getDocComment()), 'line' => $node->getLine(), 'file' => $this->file)); } if ($node instanceof \PhpParser\Node\Stmt\Interface_) { $this->addInterface(array('name' => $node->name, 'extends' => $node->extends, 'comment' => $node->getDocComment(), 'doc' => $this->doc_comment_parser->parse($node->getDocComment()), 'line' => $node->getLine(), 'file' => $this->file)); } if ($node instanceof \PhpParser\Node\Stmt\ClassMethod) { $this->addClassMethod(array('byRef' => $node->byRef, 'name' => $node->name, 'params' => $node->params, 'returnType' => $node->returnType, 'public' => $node->isPublic(), 'protected' => $node->isProtected(), 'private' => $node->isPrivate(), 'abstract' => $node->isAbstract(), 'final' => $node->isFinal(), 'static' => $node->isStatic(), 'comment' => $node->getDocComment(), 'doc' => $this->doc_comment_parser->parse($node->getDocComment()), 'line' => $node->getLine(), 'file' => $this->file)); } if ($node instanceof \PhpParser\Node\Stmt\Property) { $this->last_property = $node; } if ($node instanceof \PhpParser\Node\Stmt\PropertyProperty) { $this->addClassProperty(array('name' => $node->name, 'default' => $node->default, 'public' => $this->last_property->isPublic(), 'protected' => $this->last_property->isProtected(), 'private' => $this->last_property->isPrivate(), 'static' => $this->last_property->isStatic(), 'comment' => $node->getDocComment(), 'doc' => $this->doc_comment_parser->parse($node->getDocComment()), 'line' => $node->getLine(), 'file' => $this->file)); } // $this->logger->info(get_class($node)); }
protected function p(\PhpParser\Node $node) { $prefix = ''; if ($node->getLine() > $this->cur_ln) { $prefix = str_repeat("\n", $node->getLine() - $this->cur_ln); $this->cur_ln = $node->getLine(); } return $prefix . $this->{'p' . $node->getType()}($node); }
/** * @test */ public function itShouldCallScanAndWriteOnSuccess() { $this->node->getLine()->shouldBeCalled()->willReturn(120); $this->detector->scan($this->node)->shouldBeCalled()->willReturn(true); $this->detector->isBoolExpression($this->node)->shouldBeCalled()->willReturn(true); $this->analyser->foundAssumption(120)->shouldBeCalled(); $this->analyser->foundBoolExpression()->shouldBeCalled(); $this->nodeVisitor->enterNode($this->node->reveal()); }
/** * @param string $message */ public function trace($message, Node $node, $class = null) { if ($this->trace === true) { $this->cleanProgressbar(); $space = 35 - strlen($message); $spaceAfterMessage = str_repeat(' ', $space <= 1 ? 1 : $space); $spaceAfterLine = str_repeat(' ', 5 - strlen($node->getLine())); $this->output->writeln(sprintf('[%s]%s line "%s"%s class "%s"', $message, $spaceAfterMessage, $node->getLine(), $spaceAfterLine, $class)); $this->reDrawProgressBar(); } }
/** * {@inheritdoc} */ public function enterNode(Node $node) { if ($node instanceof Node\Expr\FuncCall && isset($node->name) && isset($node->name->parts) && ($node->name->parts[0] == '__' || $node->name->parts[0] == '_c') && isset($node->args[0]) && isset($node->args[0]->value->value) && is_string($string = $node->args[0]->value->value)) { $key = $node->name->parts[0] == '__' ? 2 : 3; $domain = isset($node->args[$key]) && is_string($node->args[$key]->value->value) ? $node->args[$key]->value->value : 'messages'; $this->results[$domain][$string][] = ['file' => $this->file, 'line' => $node->getLine()]; } elseif ($node instanceof Node\Expr\MethodCall && isset($node->name) && ($node->name == 'trans' || $node->name == 'transChoice') && isset($node->args[0]) && isset($node->args[0]->value->value) && is_string($string = $node->args[0]->value->value)) { $key = $node->name == 'trans' ? 2 : 3; $domain = isset($node->args[$key]) && is_string($node->args[$key]->value->value) ? $node->args[$key]->value->value : 'messages'; $this->results[$domain][$string][] = ['file' => $this->file, 'line' => $node->getLine()]; } }
/** * @param Node $node * * @return void */ public function leaveNode(Node $node) { if (!$node instanceof Node\Expr\Exit_) { return; } $this->addError(sprintf('Found a forbidden exit statement.'), $node->getLine(), ParseError::TYPE_ERROR); }
/** * {@inheritdoc} */ public function leaveNode(Node $node) { // Keep traces of global variable if ($node instanceof Node\Stmt\Global_) { foreach ($node->vars as $variable) { $this->globalsInCurrentLocalScope[] = $variable->name; } } // Check if the variable is marked as global or used in the global scope if ($node instanceof Node\Expr\Variable) { if ($this->isInGlobalScope || in_array($node->name, $this->globalsInCurrentLocalScope)) { $this->checkIfGlobalVariableWasRemoved($node->name, $node->getLine()); } } // Check if the variable is used from the $GLOBALS variable if ($node instanceof Node\Expr\ArrayDimFetch) { if ($node->var instanceof Node\Expr\Variable && $node->var->name === 'GLOBALS' && $node->dim instanceof Node\Scalar\String_) { $this->checkIfGlobalVariableWasRemoved($node->dim->value, $node->dim->getLine()); } } // Check if we re-enter in the global scope if ($node instanceof Node\FunctionLike) { $this->isInGlobalScope = true; $this->globalsInCurrentLocalScope = array(); } }
/** * {@inheritdoc} */ public function enterNode(Node $node) { if ($node instanceof Node\Expr\New_ && $node->class instanceof Node\Name) { $classUsage = new ClassUsage($node->class->toString(), $node->getLine()); $this->phpFileInfo->addClassUsage($classUsage); } }
public function enterNode(PhpParser\Node $node) { if ($node instanceof Stmt\Function_) { // create new context, keep parent $this->stack->start(new FunctionContext($node->name, $node->getLine(), $node->getAttribute('endLine'))); } }
/** * {@inheritdoc} */ public function enterNode(Node $node) { if ($node instanceof Node\Stmt\Class_ && $node->extends instanceof Node\Name) { $superTypeUsage = new SuperTypeUsage($node->extends->toString(), $node->namespacedName->toString(), $node->getLine()); $this->phpFileInfo->addSuperTypeUsage($superTypeUsage); } }
public final function enter(Node $node) { switch ($node->getType()) { case 'Stmt_Namespace': $this->namespace = $node->name; $this->aliases = array(); // @todo : with multiple namespaces in one file : does this bug ? // leave() shouldn't reset these values ? break; case '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; break; case 'Stmt_Class': $this->context->pushState('class', $node); $this->enterClassNode($node); break; case 'Stmt_Trait': $this->context->pushState('trait', $node); $this->enterTraitNode($node); break; case 'Stmt_Interface': $this->context->pushState('interface', $node); $this->enterInterfaceNode($node); break; } }
public function leaveNode(Node $node) { if ($node instanceof Node\Scalar\String_ || $node instanceof Node\Stmt\InlineHTML) { $new_data = array('filename' => $this->filename, 'line' => $node->getLine(), 'value' => (string) $node->value); array_push($this->data, $new_data); } }
/** * {@inheritdoc} */ public function leaveNode(Node $node) { if ($node instanceof Stmt\Class_ || $node instanceof Stmt\Interface_ || $node instanceof Stmt\Trait_) { $this->check($node->name, $node->getLine(), '"%s" is now a reserved type and can no longer be used as the name of a class/interface/trait.'); } elseif ($node instanceof Stmt\Use_ && $node->type === Stmt\Use_::TYPE_NORMAL) { $this->check($node->uses[0]->alias, $node->getLine(), '"%s" is now a reserved type and can no longer be used as an alias.'); } elseif ($node instanceof Node\Expr\FuncCall && $node->name instanceof Node\Name && $node->name->parts === array('class_alias')) { $args = $node->args; if (!empty($args[1]) && $args[1]->value instanceof Node\Scalar\String_) { $fqcn = $args[1]->value->value; $parts = explode('\\', $fqcn); $className = end($parts); $this->check($className, $node->getLine(), '"%s" is now a reserved type and can no longer be used in class_alias().'); } } }
/** * @link http://www.slideshare.net/rdohms/your-code-sucks-lets-fix-it-15471808 * @link http://www.slideshare.net/guilhermeblanco/object-calisthenics-applied-to-php * * @param Node $node * * @return void */ public function leaveNode(Node $node) { if (!$node instanceof Node\Stmt\Else_ && !$node instanceof Node\Stmt\ElseIf_) { return; } $this->addError(sprintf('Object Calisthenics error: Do not use the "%s" keyword!', $node instanceof Node\Stmt\ElseIf_ ? 'elseif' : 'else'), $node->getLine(), ParseError::TYPE_ERROR); }
/** * {@inheritdoc} */ public function enterNode(Node $node) { if ($node instanceof Node\Stmt\ClassLike) { if (isset($node->namespacedName)) { $this->parentName = $node->namespacedName->toString(); } else { $this->parentName = $node->name; } } if ($node instanceof Node\Expr\MethodCall) { // skips concat method names like $twig->{'get'.ucfirst($type)}() if ($node->name instanceof Node\Expr\BinaryOp\Concat) { return; } // skips variable methods like $definition->$method if (!is_string($node->name)) { return; } $type = $node->var->getAttribute('guessedType', null); if (null !== $type) { $methodUsage = new MethodUsage($node->name, $type, $node->getLine(), false); $this->phpFileInfo->addMethodUsage($methodUsage); } } }
/** * {@inheritdoc} */ public function enterNode(Node $node) { if ($node instanceof Node\Param && $node->type instanceof Node\Name) { $typeHintUsage = new TypeHintUsage($node->type->toString(), $node->getLine()); $this->phpFileInfo->addTypeHintUsage($typeHintUsage); } }
/** * {@inheritdoc} */ public function enterNode(Node $node) { if ($node instanceof Node\Expr\AssignRef) { $this->phpFileInfo->addDeprecatedLanguageUsage(new DeprecatedLanguageUsage('assign by reference(&=)', 'Since PHP 5.3 use normal assignment instead.', $node->getLine())); } if ($node instanceof Node\Stmt\Class_) { $method = $node->getMethod($node->name); if ($method instanceof Node\Stmt\ClassMethod) { $this->phpFileInfo->addDeprecatedLanguageUsage(new DeprecatedLanguageUsage('PHP4 constructor', 'Since PHP 7.0, use __construct() instead.', $method->getLine())); } } if ($node instanceof Node\Arg) { if (true === $node->byRef) { $this->phpFileInfo->addDeprecatedLanguageUsage(new DeprecatedLanguageUsage('call-time pass-by-reference', 'Since PHP 5.3 and removed in PHP 5.4', $node->getLine())); } } }
/** * {@inheritdoc} */ public function leaveNode(Node $node) { if ($node instanceof Node\Expr\AssignRef) { if ($node->expr instanceof Node\Expr\New_) { $this->errorCollection->add(new Error($this->parserContext->getFilename(), $node->getLine(), 'New objects cannot be assigned by reference.')); } } }
/** * {@inheritdoc} */ public function leaveNode(Node $node) { if ($node instanceof Stmt\Class_ || $node instanceof Stmt\Interface_ || $node instanceof Stmt\Trait_) { // Check that class is not namespaced and is in the list of added classes if (isset($node->namespacedName) && count($node->namespacedName->parts) === 1 && in_array($node->name, self::$addedClasses)) { $this->errorCollection->add(new Error($this->parserContext->getFilename(), $node->getLine(), sprintf('"%s" cannot be used as class/interface/trait name.', $node->name), 'You should either rename your class/trait/interface or put it in a namespace.')); } } }
/** * {@inheritdoc} */ public function leaveNode(Node $node) { if ($node instanceof Node\Expr\FuncCall && $node->name instanceof Node\Name) { $name = strtolower(end($node->name->parts)); if (array_key_exists($name, self::$removedFunctions)) { $this->errorCollection->add(new Error($this->parserContext->getFilename(), $node->getLine(), sprintf('The function %s() was removed.', $name), self::$removedFunctions[$name])); } } }
/** * {@inheritdoc} */ public function enterNode(Node $node) { if ($node instanceof Node\Scalar\LNumber) { $originalValue = $node->getAttribute('originalValue'); if ($originalValue && $this->isInvalidOctalLiteral($originalValue)) { $this->errorCollection->add(new Error($this->parserContext->getFilename(), $node->getLine(), sprintf('"%s" is an invalid octal literal and will now triggers a parse error.', $originalValue))); } } }
/** * {@inheritdoc} */ public function enterNode(Node $node) { if ($node instanceof Node\Stmt\Class_) { $phpFileInfo = $this->phpFileInfo; array_map(function (Node\Name $interface) use($node, $phpFileInfo) { $interfaceUsage = new InterfaceUsage($interface->toString(), $node->namespacedName->toString(), $node->getLine()); $phpFileInfo->addInterfaceUsage($interfaceUsage); }, $node->implements); } }
/** * 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 ConstFetch && 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()); } } elseif ($node instanceof ClassConstFetch) { $this->validateClassConstFetchExpression($node); } }
/** * @param Node $node * * @return void */ public function leaveNode(Node $node) { if (!$node instanceof Node\Expr\FuncCall) { return; } $function = $node->name; if (!in_array($function, $this->blacklist)) { return; } $this->addError(sprintf('Found blacklisted "%s" function call', $function), $node->getLine(), ParseError::TYPE_ERROR); }
/** * {@inheritdoc} */ public function enterNode(Node $node) { if ($node instanceof Node\Expr\StaticCall && isset($node->name) && isset($node->class) && $node->class->getLast() == 'JText') { if (isset($node->args[0]) && isset($node->args[0]->value) && $node->args[0]->value instanceof Node\Scalar\String_) { $methods = array('_', 'script', 'sprintf'); if (in_array($node->name, $methods)) { $string = $node->args[0]->value->value; $this->results[$string][] = ['file' => $this->file, 'line' => $node->getLine()]; } } } }
/** * {@inheritdoc} * @throws \PhpParser\Error */ public function leaveNode(Node $node) { if ($node instanceof Node\Stmt\ClassLike) { if (!$node->name) { return; } if (!$this->getAdt()->hasDeclaredGlobalNamespace()) { throw new Error('DeclaredNamespace is already defined', $node->getLine()); } $this->collect(new Node\Name($node->namespacedName), $node); } }
/** * @inheritdoc */ public function enterNode(Node $node) { if ($this->mode & self::MODE_ADDITION) { if ($node instanceof Node\Stmt\Function_ || $node instanceof Node\Stmt\ClassMethod || $node instanceof Node\Expr\Closure) { if (!empty($node->params)) { foreach ($node->params as $param) { if ($param->variadic) { $this->getResult()->addRequirement(Reason::VARIADIC_ARGUMENT, $param->getLine()); } } } } elseif ($node instanceof Node\Expr\FuncCall || $node instanceof Node\Expr\MethodCall || $node instanceof Node\Expr\StaticCall) { if (!empty($node->args)) { foreach ($node->args as $arg) { if ($arg->unpack === true) { $this->getResult()->addRequirement(Reason::ARGUMENT_UNPACKING, $arg->getLine()); } } } } elseif ($node instanceof Node\Stmt\Const_ || $node instanceof Node\Stmt\ClassConst) { foreach ($node->consts as $const) { if (!$const->value instanceof Node\Scalar && !($const->value instanceof Node\Expr\ClassConstFetch || $const->value instanceof Node\Expr\ConstFetch)) { $this->getResult()->addRequirement(Reason::CONSTANT_SCALAR_EXPRESSION, $const->getLine()); } } } elseif ($node instanceof Node\Expr\AssignOp\Pow || $node instanceof Node\Expr\BinaryOp\Pow) { $this->getResult()->addRequirement(Reason::POW_OPERATOR, $node->getLine()); } elseif ($node instanceof Node\Stmt\Use_) { $cat = null; if ($node->type === Node\Stmt\Use_::TYPE_CONSTANT) { $cat = Reason::CONSTANT_IMPORT_USE; } elseif ($node->type === Node\Stmt\Use_::TYPE_FUNCTION) { $cat = Reason::FUNCTION_IMPORT_USE; } if ($cat !== null) { $this->getResult()->addRequirement($cat, $node->getLine()); } } } }
/** * 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 FunctionStmt) { $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 FuncCall) { // if function name is an expression or a variable, give it a pass for now. $name = $node->name; if (!$name instanceof Expression && !$name instanceof Variable) { $shortName = implode('\\', $name->parts); $fullName = $this->getFullyQualifiedName($name); $inScope = isset($this->currentScope[strtolower($fullName)]); if (!$inScope && !function_exists($shortName) && !function_exists($fullName)) { $message = sprintf('Call to undefined function %s()', $name); throw new FatalErrorException($message, 0, 1, null, $node->getLine()); } } } }
/** * {@inheritdoc} */ public function enterNode(Node $node) { if ($node instanceof Node\Stmt\ClassLike) { if (isset($node->namespacedName)) { $this->parentName = $node->namespacedName->toString(); } else { $this->parentName = $node->name; } } if ($node instanceof Node\Stmt\ClassMethod) { $methodDefinition = new MethodDefinition($node->name, $this->parentName, $node->getLine()); $this->phpFileInfo->addMethodDefinition($methodDefinition); } }
/** * {@inheritdoc} */ public function leaveNode(Node $node) { if ($node instanceof Node\Expr\List_) { $isEmpty = true; foreach ($node->vars as $var) { if ($var) { $isEmpty = false; } } if ($isEmpty) { $this->errorCollection->add(new Error($this->parserContext->getFilename(), $node->getLine(), 'Empty list() assignments are no longer supported.', 'You should set at least one assignment in the list.')); } } }