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; } }
public function leaveNode(\PHPParser_Node $node) { if ($node instanceof \PHPParser_Node_Expr_StaticCall) { if (!$node->name || 'postEvent' !== $node->name) { return; } if (empty($node->class->parts) || !in_array('Piwik', $node->class->parts)) { return; } $event = array('name' => '', 'category' => '', 'arguments' => array(), 'comment' => null, 'file' => $this->piwikFile, 'line' => $node->getLine(), 'class' => $this->getCurrentClass(), 'namespace' => $this->getCurrentNamespace()); $args = $node->args; if (!empty($args)) { $eventArg = array_shift($args); $event['name'] = $this->getEventName($eventArg, $event); $event['category'] = $this->getCategoryFromEventName($event['name']); } if (!empty($args)) { $event['arguments'] = $this->getArg(array_shift($args)); } $docComment = $this->getDocComment($node); if (!empty($docComment)) { $event['comment'] = $docComment; } else { echo sprintf("Hook %s has no documentation\n", $event['name']); } if (!empty($event['comment']['ignore'])) { return; } $this->events[] = $event; } }
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()); } } }
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; } }
/** * Search token stream for the corresponding node * * @param PHPParser_Node $node Current node * * @return integer */ private function findStackPointer($node) { $tokens = $this->phpcsFile->getTokens(); foreach ($tokens as $stackPtr => $token) { if ($node->getLine() > $token['line']) { continue; } return $stackPtr; } }
/** * 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 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) { $aliasName = strtolower($node->alias); if (isset($this->aliases[$aliasName])) { 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[$aliasName] = $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_Stmt_Catch) { $node->type = $this->resolveClassName($node->type); } 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); } }
/** * @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_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); } }
private function getLineOfReturn(\PHPParser_Node $node) { $comment = $node->getDocComment(); return $node->getLine() - substr_count($comment, "\n", strripos($comment, '@return')) - 1; }
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); }
public function leaveNode(\PHPParser_Node $node) { switch (true) { case $node instanceof \PHPParser_Node_Stmt_Function: case $node instanceof \PHPParser_Node_Stmt_ClassMethod: if (0 === count($node->stmts)) { break; } if (null === ($comment = $node->getDocComment()) || !preg_match('#@Assertions\\(([0-9]+)\\)#', $comment, $match)) { $this->testCase->fail(sprintf('Each method, and function must have an @Assertions() annotation, but found none on line %d.', $node->getLine())); } $this->testCase->assertEquals($match[1], $this->curAssertions, sprintf('The number of expected assertions does not equal the actually performed number of assertions for function/method on line %d.', $node->getLine())); break; } }
private function shouldTraverseMethodCall(NodeTraversal $t, \PHPParser_Node $node, \PHPParser_Node $parent = null) { $type = $node->var->getAttribute('type'); if (null === $type || !is_string($node->name)) { return true; } if (!$type->toMaybeObjectType()) { return true; } $methodName = strtolower($node->name); $zendExtension = $this->typeRegistry->getClassOrCreate('ReflectionZendExtension'); $extension = $this->typeRegistry->getClassOrCreate('ReflectionExtension'); $function = $this->typeRegistry->getClassOrCreate('ReflectionFunction'); $parameter = $this->typeRegistry->getClassOrCreate('ReflectionParameter'); $method = $this->typeRegistry->getClassOrCreate('ReflectionMethod'); $class = $this->typeRegistry->getClassOrCreate('ReflectionClass'); switch (true) { case $this->isSubtype($type, $zendExtension): case $this->isSubtype($type, $extension): case $this->isSubType($type, $function): case $this->isSubType($type, $parameter): case $this->isSubType($type, $method): if ('getname' === $methodName) { $this->phpFile->addComment($node->getLine(), $this->createGetNameComment($node)); return false; } return true; case $this->isSubType($type, $class): if ('getname' === $methodName) { if ($node->var instanceof \PHPParser_Node_Expr_MethodCall && null !== ($innerType = $node->var->var->getAttribute('type')) && ($this->isSubType($innerType, $this->typeRegistry->getClassOrCreate('ReflectionMethod')) || $this->isSubType($innerType, $this->typeRegistry->getClassOrCreate('ReflectionProperty')))) { $propertyAccess = new \PHPParser_Node_Expr_PropertyFetch($node->var->var, 'class'); $this->phpFile->addComment($node->getLine(), Comment::warning('reflection_usage.declaring_class_name', 'Consider using ``%property_access%``. There is [an issue](https://bugs.php.net/bug.php?id=61384) with ``getName()`` and APC-enabled PHP versions.', array('property_access' => self::$prettyPrinter->prettyPrintExpr($propertyAccess)))->varyIn(array())); } else { $this->phpFile->addComment($node->getLine(), $this->createGetNameComment($node)); } return false; } return true; default: return true; } }
/** * @return int */ public function getLine() { return $this->node->getLine(); }
public static function getStringRepr(\PHPParser_Node $node) { static $prettyPrinter; if (null === $prettyPrinter) { $prettyPrinter = new \PHPParser_PrettyPrinter_Zend(); } if ($node instanceof \PHPParser_Node_Stmt_If || $node instanceof \PHPParser_Node_Stmt_ElseIf) { $label = 'if ('; $label .= $prettyPrinter->prettyPrintExpr($node->cond); $label .= ')'; return $label; } if ($node instanceof \PHPParser_Node_Stmt_Label) { return 'Label ' . $node->name; } if ($node instanceof \PHPParser_Node_Stmt_Echo) { return 'echo ' . $prettyPrinter->prettyPrint($node->exprs); } if ($node instanceof \PHPParser_Node_Scalar_String) { return 'string(' . strlen($node->value) . ') ' . var_export($node->value, true); } if ($node instanceof \PHPParser_Node_Expr_Variable) { if (is_string($node->name)) { return '$' . $node->name; } return 'Variable'; } if ($node instanceof BlockNode) { $str = 'Block'; if ($parent = $node->getAttribute('parent')) { $str .= ' of ' . self::getStringRepr($parent); } else { $str .= ' (global)'; } return $str; } if ($node instanceof \PHPParser_Node_Expr_Assign) { return 'Assign (L' . $node->getLine() . ')'; } if ($node instanceof \PHPParser_Node_Stmt_Catch) { return 'catch ' . implode("\\", $node->type->parts); } return get_class($node); }
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->getLine()); } }
private function optimizeAssertFalse(\PHPParser_Node $node) { if (!isset($node->args[0])) { return; } $arg = $node->args[0]->value; $betterExpr = null; switch (true) { case $arg instanceof \PHPParser_Node_Expr_Greater: $betterExpr = clone $node; $betterExpr->name = 'assertLessThanOrEqual'; $betterExpr->args = $this->createArgs($arg->right, $arg->left); break; case $arg instanceof \PHPParser_Node_Expr_GreaterOrEqual: $betterExpr = clone $node; $betterExpr->name = 'assertLessThan'; $betterExpr->args = $this->createArgs($arg->right, $arg->left); break; case $arg instanceof \PHPParser_Node_Expr_Smaller: $betterExpr = clone $node; $betterExpr->name = 'assertGreaterThanOrEqual'; $betterExpr->args = $this->createArgs($arg->left, $arg->right); break; case $arg instanceof \PHPParser_Node_Expr_SmallerOrEqual: $betterExpr = clone $node; $betterExpr->name = 'assertGreaterThan'; $betterExpr->args = $this->createArgs($arg->left, $arg->right); break; } if ($betterExpr) { if (isset($node->args[1])) { $this->phpFile->addComment($node->getLine(), Comment::warning('phpunit.more_specific_assertion_for_false_with_custom_message', 'Instead of ``assertFalse()`` consider using ``%expr%``.', array('expr' => self::$prettyPrinter->prettyPrintExpr($betterExpr)))); } else { $this->phpFile->addComment($node->getLine(), Comment::warning('phpunit.more_specific_assertion_for_false', 'Instead of ``assertFalse()`` use ``%expr%``. This will lead to a better error message when the test fails.', array('expr' => self::$prettyPrinter->prettyPrintExpr($betterExpr)))); } } }
private function checkParameters(\PHPParser_Node $node, AbstractFunction $function, array $args, \Scrutinizer\PhpAnalyzer\Model\MethodContainer $clazz = null) { $missingArgs = $this->argumentChecker->getMissingArguments($function, $args, $clazz); if (!empty($missingArgs)) { if (count($missingArgs) > 1) { $this->phpFile->addComment($node->getLine(), Comment::error('usage.missing_multiple_required_arguments', 'The call to ``%function_name%()`` misses some required arguments starting with ``$%parameter_name%``.', array('function_name' => $function->getName(), 'parameter_name' => reset($missingArgs)))); } else { $this->phpFile->addComment($node->getLine(), Comment::error('usage.missing_required_argument', 'The call to ``%function_name%()`` misses a required argument ``$%parameter_name%``.', array('function_name' => $function->getName(), 'parameter_name' => reset($missingArgs)))); } } if ('disabled' !== $this->getSetting('argument_type_checks')) { $argTypes = array(); foreach ($args as $arg) { $argTypes[] = $arg->getAttribute('type') ?: $this->typeRegistry->getNativeType('unknown'); } $mismatchedTypes = $this->argumentChecker->getMismatchedArgumentTypes($function, $argTypes, $clazz); foreach ($mismatchedTypes as $index => $type) { $this->phpFile->addComment($args[$index]->getLine(), Comment::warning('usage.argument_type_mismatch', '``%expr%`` of type ``%expr_type%`` is not a sub-type of ``%expected_type%``.', array('expr' => self::$prettyPrinter->prettyPrintExpr($args[$index]->value), 'expr_type' => (string) $argTypes[$index], 'expected_type' => (string) $type))); } } }