Example #1
0
 /**
  * @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;
 }
Example #4
0
 /**
  * @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);
 }
Example #8
0
 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();
     }
 }
Example #12
0
 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);
     }
 }
Example #14
0
 /**
  * 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;
         }
     }
 }
Example #15
0
 /**
  * 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;
 }
Example #16
0
 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);
     }
 }
Example #21
0
 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;
     }
 }
Example #22
0
 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);
         }
     }
 }
Example #24
0
 /**
  * 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;
     }
 }
Example #27
0
 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());
     }
 }
Example #29
0
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()];
     }
 }