/** * @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\Param && $node->type instanceof Node\Name) { $typeHintUsage = new TypeHintUsage($node->type->toString(), $node->getLine()); $this->phpFileInfo->addTypeHintUsage($typeHintUsage); } }
/** * Checks if a function, class or method is too long according to its lines of code * * @param Node $node * @param int $threshold * @return bool */ protected function isTooLong(Node $node, $threshold) { $startLine = $node->getAttribute('startLine'); $endLine = $node->getAttribute('endLine'); $loc = $endLine - $startLine; return $loc > $threshold; }
/** * @param Node|string|array|\Traversable|array $symbol * @return Node|string|array|\Traversable|array */ public function push($symbol) { if ($symbol === false || $symbol === null || $symbol === '') { return $symbol; } if ($symbol instanceof Buffer) { $this->push($symbol->toValue()); } elseif ($symbol instanceof Node) { $this->parts[] = $symbol; $this->length++; } elseif (is_string($symbol)) { $len = count($this->parts); if ($len > 0 && is_string($this->parts[$len - 1])) { $this->parts[$len - 1] .= $symbol; } else { $this->parts[] = $symbol; } $this->length += strlen($symbol); $this->strLength += strlen($symbol); } elseif ($symbol instanceof \Traversable || is_array($symbol)) { $ret = []; foreach ($symbol as $part) { $ret[] = $this->push($part); } return $ret; } else { throw new \InvalidArgumentException(sprintf('Part type unsupported: %s', get_class($symbol))); } return $symbol; }
public function leaveNode(Node $node) { $type = $node->getType(); if ($type == "Expr_BinaryOp_Concat") { if ($node->right) { //转为symbol $right_symbol = SymbolUtils::getSymbolByNode($node->right); $right_symbol != null && array_push($this->items, $right_symbol); } if ($node->left->getType() != "Expr_BinaryOp_Concat") { $left_symbol = SymbolUtils::getSymbolByNode($node->left); $left_symbol != null && array_push($this->items, $left_symbol); } } else { if ($type == "Scalar_Encapsed") { foreach ($node->parts as $item) { if (!is_object($item)) { $valueSymbol = new ValueSymbol(); $valueSymbol->setValue($item); $valueSymbol != null && array_push($this->items, $valueSymbol); } else { $setItem = SymbolUtils::getSymbolByNode($item); $setItem != null && array_push($this->items, $setItem); } } } } }
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'))); } }
/** * @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); }
public function enterNode(Node $node) { if ($node->getType() == 'Stmt_Use') { foreach ($node->uses as $use) { $this->uses[] = $use; } } // echo $node->getType() . "\n"; if (isset($node->class) && $node->class) { if ($node->class->getType() != 'Name_FullyQualified') { $this->names[] = $node->class; } } if (isset($node->extends) && $node->extends) { if ($node->extends->getType() != 'Name_FullyQualified') { $this->names[] = $node->extends; } } if (isset($node->implements) && $node->implements) { foreach ($node->implements as $implements) { if ($implements->getType() != 'Name_FullyQualified') { $this->names[] = $implements; } } } if (isset($node->params)) { foreach ($node->params as $param) { if ($param->type && !is_string($param->type)) { if ($param->type->getType() != 'Name_FullyQualified') { $this->names[] = $param->type; } } } } }
public function enterNode(Node $node) { if (!empty($this->stack)) { $node->setAttribute('parent', $this->stack[count($this->stack) - 1]); } $this->stack[] = $node; }
/** * {@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); } }
/** * {@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(); } }
public function enterNode(Node $node) { if (empty($this->node) && $this->line == $node->getAttribute('endLine')) { $this->node = $node; } parent::enterNode($node); }
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); } }
/** * Called when entering a node. * * Return value semantics: * * null: $node stays as-is * * otherwise: $node is set to the return value * * @param Node $node Node * * @return null|Node Node */ public function enterNode(Node $node) { if (isset($node->returnType)) { var_dump($node->returnType); die; } elseif ($node instanceof Node\Param) { if ($node->hasAttribute("generic_name")) { $type = $node->getAttribute("generic_name"); if (isset($this->genericTypes[$type])) { $node->type = new Node\Name\FullyQualified($this->genericTypes[$type]); } else { throw new \LogicException("Bad generic found"); } } elseif ($node->type instanceof Node\Name && $node->type->hasAttribute("generics") && $node->type->getAttribute("generics")) { $type = $node->getAttribute("original_type")->parts; foreach ($node->type->getAttribute("generics") as $generic) { if (isset($this->genericTypes[$generic])) { $value = str_replace("\\", Engine::NS_TOKEN, $this->genericTypes[$generic]); $type[] = Engine::CLASS_TOKEN . $value . Engine::CLASS_TOKEN; } else { throw new \LogicException("Bad generic found"); } } $node->type = new Node\Name\FullyQualified($type); } elseif ((string) $node->name == "item") { var_dump($node); die; } } }
/** * Check all nodes * * @param Node $node * @return void **/ public function enterNode(Node $node) { // Skip nodes without comments. if (!$node->hasAttribute("comments")) { return; } // Check if annotations should be preserved. Only nodes with actual // doc comment blocks are processed. $comments = []; if ($this->preserveAnnotations) { $docComment = $node->getDocComment(); if ($docComment) { $text = $docComment->getText(); // Check if it is a doc comment. if (strpos($text, "/**") !== false) { $text = $this->stripComment($text); if ($text) { $comments = [new Comment($text)]; } } } } // Remove (or set) comments. $node->setAttribute("comments", $comments); return $node; }
public static function isEqual(\PhpParser\Node $nodeA, \PhpParser\Node $nodeB) { if ($nodeA->getType() !== $nodeB->getType()) { return false; } $subNodesA = $nodeA->getSubNodeNames(); $subNodesB = $nodeB->getSubNodeNames(); if ($subNodesA !== $subNodesB) { return false; } foreach ($subNodesA as $key) { $valueA = $nodeA->{$key}; $valueB = $nodeB->{$key}; $result = true; if ($valueA instanceof \PhpParser\Node && $valueB instanceof \PhpParser\Node) { $result = self::isEqual($valueA, $valueB); } else { $result = $valueA === $valueB; } if (!$result) { return false; } } return true; }
public function leaveNode(\PhpParser\Node $node) { if (($parentFile = $this->getCurrentFile()) !== null) { if ($node instanceof \PhpParser\Node\Expr\Include_) { $currentFile = self::getIncludeFile($node->expr, ['__DIR__' => dirname($parentFile), '__FILE__' => $parentFile]); if ($node->type == \PhpParser\Node\Expr\Include_::TYPE_INCLUDE_ONCE || $node->type == \PhpParser\Node\Expr\Include_::TYPE_REQUIRE_ONCE) { if ($this->getPhpFileCombine()->isParsed($currentFile)) { return \PhpParser\NodeTraverser::REMOVE_NODE; } } if ($this->getPhpFileCombine()->parseFile($currentFile, $parentFile) === false) { return \PhpParser\NodeTraverser::REMOVE_NODE; } $stmts = $this->getPhpFileCombine()->traverseIncludeNodes()->getStmts(); if (isset($stmts[0])) { if ($stmts[0] instanceof \PhpParser\Node\Stmt\Namespace_ === false) { $stmts[0]->setAttribute('comments', array_merge($node->getAttribute('comments', []), $stmts[0]->getAttribute('comments', []))); } else { $stmts[0]->stmts[0]->setAttribute('comments', array_merge($node->getAttribute('comments', []), $stmts[0]->stmts[0]->getAttribute('comments', []))); } } return $stmts; } } }
/** * {@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); } } }
public function enterNode(AstNode $node) { // Determine information about the closure's location if (!$this->closureNode) { if ($node instanceof NamespaceNode) { $namespace = $node->name && is_array($node->name->parts) ? implode('\\', $node->name->parts) : null; $this->location['namespace'] = $namespace; } if ($node instanceof TraitNode) { $this->location['trait'] = $node->name; $this->location['class'] = null; } elseif ($node instanceof ClassNode) { $this->location['class'] = $node->name; $this->location['trait'] = null; } } // Locate the node of the closure if ($node instanceof ClosureNode) { if ($node->getAttribute('startLine') == $this->location['line']) { if ($this->closureNode) { $line = $this->location['file'] . ':' . $node->getAttribute('startLine'); throw new ClosureAnalysisException("Two closures were " . "declared on the same line ({$line}) of code. Cannot " . "determine which closure was the intended target."); } else { $this->closureNode = $node; } } } }
/** * {@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 function leaveNode(Node $node) { if (!$node instanceof ConstFetch) { $callback = [$this, 'rewrite' . ucfirst($node->getType())]; if (is_callable($callback)) { call_user_func_array($callback, [$node]); } return; } if ($this->disable_const_rewrite_level > 0) { return; } if (!$node->name instanceof Name) { return; } if (!$node->name->isUnqualified()) { return; } if (!ConstantPatcher::isBlacklisted((string) $node->name)) { $replacement = new FullyQualified(array()); $replacement->set('\\__ConstProxy__::get(\'' . (string) $node->name . '\')'); $pos = $node->getAttribute('startTokenPos'); ConstantPatcher::$replacement[$pos] = '\\__ConstProxy__::get(\'' . (string) $node->name . '\')'; $node->name = $replacement; } }
public function enter(\PhpParser\Node $node) { if ($node->getType() == 'Stmt_ClassMethod') { // NS $methodName = $node->name; $currentFqcn = $this->getCurrentFqcn(); $declaringFqcn = $this->getReflectionContext()->getDeclaringClass($currentFqcn, $methodName); // Vertices $signatureIndex = $declaringFqcn . '::' . $methodName; $classVertex = $this->findVertex('interface', $currentFqcn); $signatureVertex = $this->findVertex('method', $signatureIndex); // if current class == declaring class, we add the edge if ($declaringFqcn == $currentFqcn) { $this->getGraph()->addEdge($classVertex, $signatureVertex); // I -> M // and we link the signature to the params foreach ($node->params as $idx => $param) { // adding edge from signature to param : $paramVertex = $this->findVertex('param', $signatureIndex . '/' . $idx); // it is possible to not find the param because the signature // is external to the source code : if (!is_null($paramVertex)) { $this->getGraph()->addEdge($signatureVertex, $paramVertex); // M -> P // now the type of the param : $this->typeHintParam($param, $paramVertex); } } } } }
/** * @inheritDoc */ public function resolveVariableType(Node $node) { // $this->call() if ($node instanceof Node\Expr\MethodCall && property_exists($node->var, 'name') && null === $node->getAttribute('guessedType', null)) { if ('container' == $node->var->name && $this->isController($this->table->lookUp('this')->type())) { $context = self::CONTAINER; } else { $context = $this->table->lookUp($node->var->name)->type(); } $type = $this->getType($context, $node->name, $node); if (null !== $type) { $node->setAttribute('guessedType', $type); } } // $x = $this->call() if ($node instanceof Node\Expr\Assign && $node->var instanceof Node\Expr\Variable && $node->expr instanceof Node\Expr\MethodCall && property_exists($node->expr->var, 'name') && null === $node->getAttribute('guessedType', null)) { if ('container' == $node->expr->var->name && $this->isController($this->table->lookUp('this')->type())) { $context = self::CONTAINER; } else { $context = $this->table->lookUp($node->expr->var->name)->type(); } $type = $this->getType($context, $node->expr->name, $node->expr); if (null !== $type) { $node->var->setAttribute('guessedType', $type); $this->table->setSymbol($node->var->name, $type); } } }
/** * Enter the node and record the name. * * @param \PhpParser\Node $node * * @return \PhpParser\Node */ public function enterNode(Node $node) { if ($node instanceof FullyQualified) { $this->names[] = $node->toString(); } return $node; }
public final function enter(Node $node) { if ($node->getType() == 'Stmt_ClassMethod' && $node->isPublic()) { $fqcn = $this->getCurrentFqcn(); $this->enterPublicMethod($fqcn, $node); } }
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\Name) { if ($node->toString() == $this->fromNs) { $node->set($this->toNs); } } }
/** * Swap out __DIR__ and __FILE__ constants, because the default ones when * calling eval() don't make sense. * * @param Node $node * * @return null|FuncCall|StringNode */ public function enterNode(Node $node) { if ($node instanceof Dir) { return new FuncCall(new Name('getcwd'), array(), $node->getAttributes()); } elseif ($node instanceof File) { return new StringNode('', $node->getAttributes()); } }
function node_props(Node $node) { $props = []; foreach ($node->getSubNodeNames() as $prop) { $props[$prop] = $node->{$prop}; } return $props; }
/** * {@inheritdoc} */ public function enterNode(Node $node) { if ($node instanceof Node\Expr\FuncCall && ($node->name->parts[0] == '__' || $node->name->parts[0] == '_c') && isset($node->args[0]) && 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()]; } }