public function pushState($stateKey, Node $node) { if ($this->debug) { printf("Stacking %s %s %s %d\n", $stateKey, $node->getType(), $node->name, count($this->stateStack)); } $state = $this->getState($stateKey); array_unshift($this->stateStack, ['node' => $node, 'state' => $state, 'key' => $state->getName(), 'nodeType' => $node->getType()]); }
/** * {@inheritdoc} */ public function enterNode(Node $node) { if (isset($this->mapping[$node->getType()])) { // We have a mapping, so resolve the assign operation to // Separate assign and operation nodes $class = $this->mapping[$node->getType()]; return new Node\Expr\Assign($node->var, new $class($node->var, $node->expr)); } }
/** * @param Node $stmts * @return Node\Expr\List_ * @throws \Exception */ private function getListPart(Node $stmts) { if ($stmts->getType() === 'Expr_Assign' && $stmts->var->getType() === 'Expr_List') { return $stmts->var; } elseif ($stmts->getType() === 'Expr_List') { return $stmts; } else { throw new \Exception("Unknown statement: " . $stmts->getType()); } }
private function getUnexpectedThing(Node $node) { switch ($node->getType()) { case 'Scalar_String': case 'Scalar_LNumber': case 'Scalar_DNumber': return json_encode($node->value); case 'Expr_ConstFetch': return (string) $node->name; default: return $node->getType(); } }
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 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 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 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 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); } } } } }
/** * @param Node $node * @param $context * @return AbstractTranspiler * @throws NotImplementedException */ public static function create(Node $node, $context) { if ($context === null) { throw new ContextNotProvidedException('You have to provide the context'); } $type = $node->getType(); if (!array_key_exists($type, self::$transpilersMap)) { print_R($type); die; throw new NotImplementedException("'" . $node->getType() . "' not implemented."); } $className = "\\Php2js\\Transpilers\\" . self::$transpilersMap[$type] . 'Transpiler'; $transpiler = new $className($node); $transpiler->setContext($context); return $transpiler; }
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 final function enter(Node $node) { if ($node->getType() == 'Stmt_ClassMethod' && $node->isPublic()) { $fqcn = $this->getCurrentFqcn(); $this->enterPublicMethod($fqcn, $node); } }
protected function enterMethodCode(Node $node) { switch ($node->getType()) { case 'Expr_New': $this->pushViolation($node, 'static factory (OCP violation)'); break; } }
/** * @inheritdoc */ public function enter(Node $node) { switch ($node->getType()) { case 'PhpFile': $this->context->pushState('file', $node); break; } }
/** * @inheritdoc */ public function leaveNode(Node $node) { switch ($node->getType()) { case 'Stmt_Class': $this->currentClass = null; break; case 'Stmt_ClassMethod': $this->currentMethod = null; break; } }
public function enter(Node $node) { switch ($node->getType()) { case 'Stmt_ClassMethod': if ($node->isPublic()) { $fqcn = $this->getCurrentFqcn(); $this->getReflectionContext()->addMethodToClass($fqcn, $node->name); } break; } }
/** * Prints an expression node with the least amount of parentheses necessary to preserve the meaning. * * @param Node $node Node to pretty print * @param int $parentPrecedence Precedence of the parent operator * @param int $parentAssociativity Associativity of parent operator * (-1 is left, 0 is nonassoc, 1 is right) * @param int $childPosition Position of the node relative to the operator * (-1 is left, 1 is right) * * @return string The pretty printed node */ public function convert(Node $node, $parentPrecedence, $parentAssociativity, $childPosition) { $type = $node->getType(); if ($this->dispatcher->issetPrecedenceMap($type) === true) { $childPrecedences = $this->dispatcher->getPrecedenceMap($type); $childPrecedence = $childPrecedences[0]; if ($childPrecedence > $parentPrecedence || $parentPrecedence == $childPrecedence && $parentAssociativity != $childPosition) { return '(' . $this->dispatcher->{'p' . $type}($node) . ')'; } } return $this->dispatcher->{'p' . $type}($node); }
protected function enterMethodCode(Node $node) { if ($node->getType() === 'Expr_MethodCall') { $called = $node->name; if (!$this->hasMethod($called)) { $this->nestedCall++; } if ($this->nestedCall >= $this->threshold) { $this->pushViolation($node, 'chained calls after ' . $called); } } }
/** * isAllowedNode * * @param PhpParser\Node $node * @return bool */ protected function isAllowedNode(\PhpParser\Node $node) { switch ($node->getType()) { case 'Stmt_Class': case 'Stmt_Interface': case 'Expr_Include': return true; break; default: return false; break; } }
protected function resolveStack(Node $node, array $stack) { if (!$node->num) { return new Goto_(end($stack), $node->getAttributes()); } if ($node->num instanceof LNumber) { $num = $node->num->value - 1; if ($num >= count($stack)) { throw new \LogicException("Too high of a count for " . $node->getType()); } $loc = array_slice($stack, -1 * $num, 1); return new Goto_($loc[0], $node->getAttributes()); } throw new \LogicException("Unimplemented Node Value Type"); }
/** * @param Node $node */ public function leaveNode(Node $node) { switch ($node->getType()) { case 'Expr_New': case 'Expr_Instanceof': case 'Expr_StaticCall': case 'Expr_StaticPropertyFetch': case 'Expr_ClassConstFetch': $this->processExpr($node); break; case 'Stmt_Class': $this->processStmt($node); break; } }
public function enter(Node $node) { switch ($node->getType()) { case 'Stmt_ClassMethod': if ($node->isPublic()) { $this->context->pushState('trait-method', $node); $this->enterPublicMethod($node); } break; case 'Stmt_TraitUse': $fqcn = $this->getCurrentFqcn(); $currentVertex = $this->findVertex('trait', $fqcn); $this->enterTraitUse($node, $currentVertex); break; } }
public function enter(Node $node) { $this->currentFqcn = $this->context->getState('file')->getNamespacedName($this->context->getNodeFor($this->getParentName())); $this->currentMethodNode = $this->context->getNodeFor($this->getName()); $this->fileState = $this->context->getState('file'); switch ($node->getType()) { case 'Expr_MethodCall': $this->enterMethodCall($node); break; case 'Expr_New': $this->enterNewInstance($node); break; case 'Expr_StaticCall': $this->enterStaticCall($node); break; } }
protected function constructMessage($annotation, Node $node) { if ($node instanceof FuncCall) { $name = $node->name; } else { $name = $node->getType(); } $message = $this->defaultMessageHeader . $name; if ($annotation == Annotation::UNKNOWN) { $message = "A possible " . $message; return new Warning($message, $node); } else { if ($annotation == Annotation::TAINTED) { $message = "An " . $message; return new Error($message, $node); } } }
public function enterNode(Node $node) { ++$this->node_count; $type = $node->getType(); if ($type == 'Stmt_Return') { $this->has_return = true; } if (!isset($this->allowed_node_types_map[$type])) { $this->errors[] = "Illegal instruction of type {$type} found."; } // check function calls if ($type == 'Expr_FuncCall') { $this->validateFunctionCall($node); } // check variables if ($type == 'Expr_Variable') { $this->validateVariable($node); } }
public function leaveNode(Node $node) { if ($node->getType() === 'Stmt_ClassMethod') { // filters param without type-hint $filtered = []; foreach ($node->params as $param) { if (is_null($param->type)) { $filtered[$param->name] = true; } } // intersect with variable called with method $result = array_intersect_key($this->objectName, $filtered); foreach ($result as $key => $calling) { $this->pushViolation($calling, "Method is called on parameter \${$key} without type-hint"); } $this->objectName = []; } parent::leaveNode($node); }
protected function enterMethodCode(Node $node) { switch ($node->getType()) { case 'Expr_New': $this->pushViolation($node, 'new statement'); break; case 'Expr_StaticCall': if ($node->class instanceof Node\Name) { $name = $node->class->toString(); // exclude static call (as seen by PhpParser) on itself : if (!in_array($name, ['parent', 'self', 'static']) && $name !== $this->currentClass) { $this->pushViolation($node, 'static call'); } } break; case 'Stmt_Global': $this->pushViolation($node, 'global keyword'); break; } }
public function leaveNode(AstNode $node) { switch ($node->getType()) { case 'Scalar_MagicConst_Class': return new StringNode($this->location['class']); case 'Scalar_MagicConst_Dir': return new StringNode($this->location['directory']); case 'Scalar_MagicConst_File': return new StringNode($this->location['file']); case 'Scalar_MagicConst_Function': return new StringNode($this->location['function']); case 'Scalar_MagicConst_Line': return new NumberNode($node->getAttribute('startLine')); case 'Scalar_MagicConst_Method': return new StringNode($this->location['method']); case 'Scalar_MagicConst_Namespace': return new StringNode($this->location['namespace']); case 'Scalar_MagicConst_Trait': return new StringNode($this->location['trait']); } }
protected function enterMethodCode(Node $node) { switch ($node->getType()) { case 'Expr_Instanceof': $skip = false; if ($node->class instanceof Node\Name) { // I accept a clean use of instanceof on an interface $name = (string) $node->class; $skip = interface_exists($name); } if (!$skip) { $this->pushViolation($node, 'use of instanceof'); } break; case 'Expr_FuncCall': if (in_array($node->name, $this->forbidden)) { $this->pushViolation($node, 'use of ' . $node->name); } break; } }
/** * @param Node $node * @param $context * @return AbstractTranspiler * @throws NotImplementedException */ public static function create(Node $node, $context) { if ($context === null) { throw new ContextNotProvidedException('You have to provide the context'); } $type = $node->getType(); if (!array_key_exists($type, self::$transpilersMap)) { $className = "\\Php2js\\Transpilers\\" . self::$transpilersMap['Scalar_String'] . 'Transpiler'; //throw new NotImplementedException("'" . $node->getType() . "' not implemented."); } else { $className = "\\Php2js\\Transpilers\\" . self::$transpilersMap[$type] . 'Transpiler'; } $transpiler = new $className($node); $transpiler->setContext($context); print "1111111111111111\n"; print $type; //$str=serialize($context); //print $str; //print(serialize($context->node->name)); //print(serialize($context->node->value)); //print(serialize($context->node->expr)); return $transpiler; }