protected function setUp() { $this->traverser = new NodeTraverser(); $this->visitor = new ClassVisitor(); $this->traverser->addVisitor($this->visitor); $this->parser = new Parser(new Lexer()); }
protected function setUp() { $this->parser = new \PhpParser\Parser(new \PhpParser\Lexer()); $this->traverser = new \PhpParser\NodeTraverser(); $this->sut = $this->createVisitor(); $this->traverser->addVisitor($this->sut); }
/** * @param \PhpParser\Parser $parser * @param Compiler $compiler */ public function __construct(\PhpParser\Parser $parser, Compiler $compiler) { $this->nodeTraverser = new \PhpParser\NodeTraverser(); $this->nodeTraverser->addVisitor(new \PhpParser\NodeVisitor\NameResolver()); $this->parser = $parser; $this->compiler = $compiler; }
/** * Parse a file and return found tags. * * @param string $filePath Full path to filename. * @return array */ public function getTags($filePath) { // Create a PHP-Parser instance. $parser = new PhpParser(new Lexer(array('usedAttributes' => array('startLine', 'endLine', 'startFilePos', 'endFilePos')))); // Parse the source code into a list of statements. $source = $this->getContents($filePath); $statements = $parser->parse($source); $traverser = new NodeTraverser(); // Make sure all names are resolved as fully qualified. $traverser->addVisitor(new NameResolver()); // Create visitors that turn statements into tags. $visitors = array(new Visitor\ClassDefinition(), new Visitor\ClassReference(), new Visitor\ConstantDefinition(), new Visitor\FunctionDefinition(), new Visitor\GlobalVariableDefinition(), new Visitor\InterfaceDefinition(), new Visitor\TraitDefinition()); foreach ($visitors as $visitor) { $traverser->addVisitor($visitor); } $traverser->traverse($statements); // Extract tags from the visitors. $tags = array(); foreach ($visitors as $visitor) { $tags = array_merge($tags, array_map(function (Tag $tag) use($source) { $comment = substr($source, $tag->getStartFilePos(), $tag->getEndFilePos() - $tag->getStartFilePos() + 1); if (($bracePos = strpos($comment, '{')) !== false) { $comment = substr($comment, 0, $bracePos) . ' {}'; } return $tag->setComment(preg_replace('/\\s+/', ' ', $comment)); }, $visitor->getTags())); } return $tags; }
public function __construct(OutputInterface $output) { $this->parser = new Parser(new Lexer()); $this->traverser = new NodeTraverser(); $this->nodeVisitor = new PhpStringFinder($output); $this->traverser->addVisitor($this->nodeVisitor); }
/** * DefaultPhpFileExtractor constructor. * @param DocParser $docParser * @param FileSourceFactory $fileSourceFactory */ public function __construct(DocParser $docParser, FileSourceFactory $fileSourceFactory) { $this->docParser = $docParser; $this->fileSourceFactory = $fileSourceFactory; $this->traverser = new NodeTraverser(); $this->traverser->addVisitor($this); }
/** * @param $code * @param bool $autoFix - In case of true - pretty code will be generated (avaiable by getPrettyCode method) * @return Logger */ public function lint($code, $autoFix = false) { $this->autoFix = $autoFix; $this->prettyCode = ''; $this->logger = new Logger(); try { $stmts = $this->parser->parse($code); } catch (Error $e) { $this->logger->addRecord(new LogRecord('', '', Logger::LOGLEVEL_ERROR, $e->getMessage(), '')); return $this->logger; } $traverser = new NodeTraverser(); $rulesVisitor = new RulesVisitor($this->rules, $this->autoFix); $traverser->addVisitor($rulesVisitor); $traverser->traverse($stmts); $messages = $rulesVisitor->getLog(); foreach ($messages as $message) { $this->logger->addRecord(new LogRecord($message['line'], $message['column'], $message['level'], $message['message'], $message['name'])); } if ($autoFix) { $prettyPrinter = new PrettyPrinter\Standard(); $this->prettyCode = $prettyPrinter->prettyPrint($stmts); } $sideEffectVisitor = new SideEffectsVisitor(); $traverser->addVisitor($sideEffectVisitor); $traverser->traverse($stmts); if ($sideEffectVisitor->isMixed()) { $this->logger->addRecord(new LogRecord('', '', Logger::LOGLEVEL_ERROR, 'A file SHOULD declare new symbols (classes, functions, constants, etc.) and cause no other side' . 'effects, or it SHOULD execute logic with side effects, but SHOULD NOT do both.', '')); } return $this->logger; }
/** * @param Parser $parser * @param NodeTraverser $traverser * @param TombstoneVisitor $visitor */ public function __construct(Parser $parser, NodeTraverser $traverser, TombstoneVisitor $visitor) { $this->parser = $parser; $this->visitor = $visitor; $this->traverser = $traverser; $this->traverser->addVisitor($visitor); }
/** * @param RuleCollection $rules * @param bool $fix * @param book $debug */ public function __construct($rules, $fix = false, $debug = false) { $parserFactory = new ParserFactory(); $this->parser = $parserFactory->create(ParserFactory::PREFER_PHP7); $this->traverser = new NodeTraverser(); $this->linterVisitor = new LinterVisitor($rules, $fix, $debug); $this->traverser->addVisitor($this->linterVisitor); }
protected function parsePhpFileFromStringAndTraverseWithVisitor(PhpFileInfo $phpFileInfo, $source, VisitorInterface $visitor) { $traverser = new NodeTraverser(); $traverser->addVisitor(new NameResolver()); $traverser->addVisitor($visitor->setPhpFileInfo($phpFileInfo)); $parser = new Parser(new Emulative()); $traverser->traverse($parser->parse($source)); return $phpFileInfo; }
/** * Get the fullyqualified imports and typehints. * * @param string $path * * @return string[] */ public function analyze($path) { $traverser = new NodeTraverser(); $traverser->addVisitor(new NameResolver()); $traverser->addVisitor($imports = new ImportVisitor()); $traverser->addVisitor($names = new NameVisitor()); $traverser->traverse($this->parser->parse(file_get_contents($path))); return array_unique(array_merge($imports->getImports(), $names->getNames())); }
/** * @param string $code * @param int $lineNumber * @return Node */ public function parse($code, $lineNumber) { $stmts = $this->parser->parse($code); $this->nodeVisitor->setLine($lineNumber); $this->nodeTraverser->addVisitor($this->nodeVisitor); $this->nodeTraverser->traverse($stmts); $node = $this->nodeVisitor->getNode(); return $node; }
/** * ValidationExtractor constructor. * @param $metadataFactory */ public function __construct($metadataFactory) { if (!($metadataFactory instanceof MetadataFactoryInterface || $metadataFactory instanceof LegacyMetadataFactoryInterface || $metadataFactory instanceof ClassMetadataFactoryInterface)) { throw new \InvalidArgumentException(sprintf('%s expects an instance of MetadataFactoryInterface or ClassMetadataFactoryInterface', get_class($this))); } $this->metadataFactory = $metadataFactory; $this->traverser = new NodeTraverser(); $this->traverser->addVisitor($this); }
/** * Get the modified AST * * @param string $view * @return array */ protected function modified($view) { $ast = $this->parser->parse($view); $traverser = new NodeTraverser(); $traverser->addVisitor(new Modifiers\RegisterDeviseTags($this->parser)); $traverser->addVisitor(new Modifiers\AddPlaceHolderTags($this->parser)); $traverser->addVisitor(new Modifiers\EchoDeviseMagic($this->parser)); return $traverser->traverse($ast); }
public function __construct() { $this->registry = new Registry(); $this->parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7); $this->traverser = new NodeTraverser(); $visitors = [new NameResolver(), new ClassVisitor($this->registry), new InterfaceVisitor($this->registry), new FunctionVisitor($this->registry), new TraitVisitor($this->registry)]; foreach ($visitors as $visitor) { $this->traverser->addVisitor($visitor); } }
/** * Traverse the parser nodes so we can extract the information * * @param $content * @param array $nodeVisitors * @internal param bool $addInterface */ protected function traverse($content, array $nodeVisitors = []) { $nodes = $this->phpParser->parse($content); $traverser = new NodeTraverser(); $traverser->addVisitor(new NameResolver()); foreach ($nodeVisitors as $nodeVisitor) { $traverser->addVisitor($nodeVisitor); } $traverser->traverse($nodes); }
public function __construct(Config $config, LoggerInterface $logger) { $this->config = $config; $this->logger = $logger; $this->parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7); $this->traverser = new NodeTraverser(); $this->collector = new Collector(); // Add visitors. $this->traverser->addVisitor(new NodeVisitor($this->collector, $this->config)); }
/** * @param PhpFileInfo $phpFileInfo * @param $source * * @return array */ private function parseFileAndReturnClassUsages(PhpFileInfo $phpFileInfo, $source) { $traverser = new NodeTraverser(); $traverser->addVisitor(new NameResolver()); $findArguments = new FindArguments(); $traverser->addVisitor($findArguments->setPhpFileInfo($phpFileInfo)); $parser = new Parser(new Emulative()); $traverser->traverse($parser->parse($source)); $usages = array_map(function (TypeHintUsage $usage) { return $usage->name() . '::' . $usage->getLineNumber(); }, $phpFileInfo->typeHintUsages()); return $usages; }
/** * @param Traversable|array[] $ASTs a series of AST roots * * @return string[] all the found symbols */ public function __invoke(Traversable $ASTs) : array { // note: dependency injection is not really feasible for these two, as they need to co-exist in parallel $traverser = new NodeTraverser(); $traverser->addVisitor(new NameResolver()); $traverser->addVisitor($collector = new DefinedSymbolCollector()); $astSymbols = []; foreach ($ASTs as $astRoot) { $traverser->traverse($astRoot); $astSymbols[] = $collector->getDefinedSymbols(); } return array_values(array_unique(array_merge([], ...$astSymbols))); }
/** * @param $code * * @return ParseErrorsCollection */ protected function visit($code) { $context = $this->createContext(); $visitor = $this->getVisitor(); $visitor->setContext($context); $parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7); $traverser = new NodeTraverser(); $traverser->addVisitor(new NameResolver()); $traverser->addVisitor($visitor); $stmts = $parser->parse($code); $traverser->traverse($stmts); return $context->getErrors(); }
public static function init(LocatorInterface $locator) { $refParser = new \ReflectionClass(Parser::class); $isNewParser = $refParser->isInterface(); if (!$isNewParser) { self::$parser = new Parser(new Lexer(['usedAttributes' => ['comments', 'startLine', 'endLine', 'startTokenPos', 'endTokenPos', 'startFilePos', 'endFilePos']])); } else { self::$parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7); } self::$traverser = $traverser = new NodeTraverser(); $traverser->addVisitor(new NameResolver()); $traverser->addVisitor(new RootNamespaceNormalizer()); self::$locator = $locator; }
/** * @param StaticAnalysisVisitorInterface[] $staticAnalysisVisitors * @param ViolationVisitorInterface[] $violationVisitors * @param NodeTraverser $baseTraverser * @param NodeTraverser $staticTraverser * @param NodeTraverser $violationTraverser */ public function __construct(array $staticAnalysisVisitors, array $violationVisitors, NodeTraverser $baseTraverser, NodeTraverser $staticTraverser, NodeTraverser $violationTraverser) { parent::__construct(new Lexer()); $this->nameResolver = $baseTraverser; $this->staticTraverser = $staticTraverser; foreach ($staticAnalysisVisitors as $visitor) { $this->staticTraverser->addVisitor($visitor); } $this->violationTraverser = $violationTraverser; $this->violationVisitors = $violationVisitors; foreach ($violationVisitors as $visitor) { $this->violationTraverser->addVisitor($visitor); } }
/** * @param $content * @param $prefix * * @return string */ public function addNamespacePrefix($content, $prefix) { $traverser = new NodeTraverser(); $traverser->addVisitor(new NamespaceScoperNodeVisitor($prefix)); $traverser->addVisitor(new UseNamespaceScoperNodeVisitor($prefix)); $traverser->addVisitor(new FullyQualifiedNamespaceUseScoperNodeVisitor($prefix)); try { $statements = $this->parser->parse($content); } catch (Error $error) { throw new ParsingException($error->getMessage()); } $statements = $traverser->traverse($statements); $prettyPrinter = new Standard(); return $prettyPrinter->prettyPrintFile($statements) . "\n"; }
/** * @param $rulesPath * @return array */ public function loadRules($rulesPath) { $parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7); $targetFiles = getTargetFiles($rulesPath); foreach ($targetFiles as $file) { $code = file_get_contents($file); $stmts = $parser->parse($code); $traverser = new NodeTraverser(); $visitor = new RulesLoadVisitor(); $traverser->addVisitor($visitor); $traverser->traverse($stmts); $namespace = $visitor->getNamespace(); $className = $visitor->getClassName(); if (!is_null($namespace) && !is_null($className)) { include $file; $fullClassName = $namespace . '\\' . $className; if (class_exists($fullClassName)) { $implements = class_implements($fullClassName); if (in_array(RuleBaseInterfase::class, $implements)) { $this->rules[] = $fullClassName; $this->addRecord(Logger::LOGLEVEL_OK, "Loaded rules: {$fullClassName} - " . $fullClassName::getDescription(), $file); } else { $this->addRecord(Logger::LOGLEVEL_ERROR, "Class {$fullClassName} must implements RulesBaseInterface", $file); } } else { $this->addRecord(Logger::LOGLEVEL_ERROR, "Class {$fullClassName} doesn't exists in {$file}", $file); } } else { $this->addRecord(Logger::LOGLEVEL_ERROR, 'File doesn\'t contains correct class defenition', $file); } } return $this->rules; }
public function implement($class) { $parts = $orig_parts = explode("\\", ltrim($class, "\\")); $real_class_parts = []; while ($part = array_shift($parts)) { if (strpos($part, self::CLASS_TOKEN) !== false) { break; } $real_class_parts[] = $part; } array_unshift($parts, $part); $types = []; foreach ($parts as $part) { $types[] = str_replace([self::CLASS_TOKEN, self::NS_TOKEN], ["", "\\"], $part); } $real_class = implode("\\", $real_class_parts); if (!class_exists($real_class)) { throw new \RuntimeException("Attempting to use generics on unknown class {$real_class}"); } if (!($ast = $this->compiler->getClass($real_class))) { throw new \RuntimeException("Attempting to use generics with non-generic class"); } $generator = new Generator($ast->getAttribute("generics"), $types); $traverser = new NodeTraverser(); $traverser->addVisitor($generator); $ast = $traverser->traverse([$ast]); $ast[0]->name = array_pop($orig_parts); $ast[0]->extends = new Node\Name\FullyQualified($real_class_parts); array_unshift($ast, new Node\Stmt\Namespace_(new Node\Name($orig_parts))); return $this->prettyPrinter->prettyPrint($ast); }
/** * @param array $args */ public function handle(array $args) { $this->cli->out(sprintf('PHPAssumptions analyser v%s by @rskuipers', Cli::VERSION))->br(); try { $this->cli->arguments->parse($args); } catch (\Exception $e) { $this->cli->usage($args); return; } switch ($this->cli->arguments->get('format')) { case 'xml': $output = new XmlOutput($this->cli, $this->cli->arguments->get('output')); break; default: $output = new PrettyOutput($this->cli); break; } $nodeTraverser = new NodeTraverser(); $analyser = new Analyser($this->parser, $nodeTraverser); $nodeTraverser->addVisitor(new NodeVisitor($analyser, new Detector())); $target = $this->cli->arguments->get('path'); $targets = []; if (is_file($target)) { $targets[] = $target; } else { $directory = new \RecursiveDirectoryIterator($target); $iterator = new \RecursiveIteratorIterator($directory); $regex = new \RegexIterator($iterator, '/^.+\\.php$/i', \RecursiveRegexIterator::GET_MATCH); foreach ($regex as $file) { $targets[] = $file[0]; } } $result = $analyser->analyse($targets); $output->output($result); }
/** * @param ExerciseInterface $exercise * @param string $fileName * @return ResultInterface */ public function check(ExerciseInterface $exercise, $fileName) { if (!$exercise instanceof FunctionRequirementsExerciseCheck) { throw new \InvalidArgumentException(); } $requiredFunctions = $exercise->getRequiredFunctions(); $bannedFunctions = $exercise->getBannedFunctions(); $code = file_get_contents($fileName); try { $ast = $this->parser->parse($code); } catch (Error $e) { return Failure::fromCheckAndCodeParseFailure($this, $e, $fileName); } $visitor = new FunctionVisitor($requiredFunctions, $bannedFunctions); $traverser = new NodeTraverser(); $traverser->addVisitor($visitor); $traverser->traverse($ast); $bannedFunctions = []; if ($visitor->hasUsedBannedFunctions()) { $bannedFunctions = array_map(function (FuncCall $node) { return ['function' => $node->name->__toString(), 'line' => $node->getLine()]; }, $visitor->getBannedUsages()); } $missingFunctions = []; if (!$visitor->hasMetFunctionRequirements()) { $missingFunctions = $visitor->getMissingRequirements(); } if (!empty($bannedFunctions) || !empty($missingFunctions)) { return new FunctionRequirementsFailure($this, $bannedFunctions, $missingFunctions); } return Success::fromCheck($this); }
/** * @param Node\Stmt\Class_ $node * * @return Node\Stmt\Class_ */ public function resolveConstructor(Node\Stmt\Class_ $node) { foreach ($node->stmts as $key => $stmt) { if ($stmt instanceof Node\Stmt\ClassMethod && $stmt->name === '__construct') { // this will make problems we need an layer above which chains the variable resolvers // because we need may need more than this resolver // skip constructor if is abstract if ($stmt->isAbstract()) { return $node; } // change recursivly the nodes $subTraverser = new NodeTraverser(); foreach ($this->visitors as $visitor) { $subTraverser->addVisitor($visitor); } // the table switches to a method scope // $x = ... will be treated normal // $this->x = ... will be stored in the above class scope and is available afterwards $this->table->enterScope(new TableScope(TableScope::CLASS_METHOD_SCOPE)); $subTraverser->traverse($stmt->params); $nodes = $subTraverser->traverse($stmt->stmts); $this->table->leaveScope(); //override the old statement $stmt->stmts = $nodes; // override the classmethod statement in class $node->stmts[$key] = $stmt; // return the changed node to override it return $node; } } // no constructor defined return $node; }
public function test() { $class = get_class($this); $class = substr($class, 41); $file_name = $class . '.inc'; $parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7); $traverser = new NodeTraverser(); // add your visitor $collector = new Collector(); $traverser->addVisitor(new NodeVisitor($collector, new Config())); try { $code = file_get_contents(__DIR__ . '/../tests/' . $file_name); // parse $stmts = $parser->parse($code); // traverse $traverser->traverse($stmts); $found = $collector->get(); foreach ($found as &$item) { unset($item['node']); } $this->assertEquals($this->expectations(), $found); } catch (Error $e) { echo 'Parse Error: ', $e->getMessage(); } }
public function __construct(array $ast) { $this->ast = $ast; $this->visitor = new ExtractNames(); $traverser = new NodeTraverser(); $traverser->addVisitor($this->visitor); $traverser->traverse($this->ast); }