function it_parses_a_file(NodeTraverserInterface $traverser) { $file = new SplFileInfo('php://memory'); $traverser->traverse([])->shouldBeCalled(); $errors = $this->parse($file); $errors->shouldBeAnInstanceOf(ParseErrorsCollection::class); $errors->count()->shouldBe(0); }
/** * @param PathCheckSettings $checkSettings */ public function check(PathCheckSettings $checkSettings) { $this->visitorResolver->setLevel($checkSettings->getMessageLevel()); foreach ($this->visitorResolver->resolve() as $visitor) { $this->traverser->addVisitor($visitor); } $this->pathChecker->check($this->pathTraversableFactory->createTraversable($checkSettings->getCheckedPaths(), $checkSettings->getCheckedFileExtensions(), $checkSettings->getExcludedPaths()), $checkSettings->getUseRelativePaths()); }
/** * @param string $file * * @return RefClass[] * @throws RuntimeException */ protected function parseFile($file) { $stmts = $this->phpParser->parse(file_get_contents($file)); $visitor = new RefVisitor($file); $this->traverser->addVisitor($visitor); $this->traverser->traverse($stmts); $this->traverser->removeVisitor($visitor); return $visitor->getClasses(); }
/** * @param array $files * @return Result */ public function analyse(array $files) { foreach ($files as $file) { $this->currentFilePath = $file; $this->currentFile = []; $statements = $this->parser->parse(file_get_contents($file)); if (is_array($statements) || $statements instanceof Node) { $this->traverser->traverse($statements); } } return $this->result; }
/** * @param string $code * * @return ParserResult * * @throws ParserException */ public function parse($code) { try { $stmts = $this->parser->parse($code); $visitor = $this->createVisitor(); $this->nodeTraverser->addVisitor($visitor); $this->nodeTraverser->traverse($stmts); return $visitor->getResult(); } catch (Error $e) { throw new ParserException("Failed to parse PHP file: " . $e->getMessage(), $e->getCode(), $e); } }
/** * Parse the given file to check potential errors. * * @param \SplFileInfo $file */ public function parse(\SplFileInfo $file) { try { $content = file_get_contents($file->getRealPath()); if (strlen($content) > 0) { // Keep the context up to date $this->parserContext->setFilename($file->getRealPath()); // Parse the file content $stmts = $this->parser->parse($content); // Traverse the statements $this->traverser->traverse($stmts); } } catch (PhpParserError $e) { echo 'Parse Error: ', $e->getMessage(); } }
/** * Convert a ClassModel into an array of statements for the php parser * * @param ClassModel $classModel * @return array */ public function transform(ClassModel $classModel) { // create namespace $namespace = $this->factory->namespace($classModel->getNamespace()); // create class $class = $this->factory->class($classModel->getName()); $class->implement($classModel->getInterface()); // add class properties foreach ($classModel->getProperties() as $propertyModel) { $property = $this->factory->property($propertyModel->getName()); $property->setDefault($propertyModel->getDefaultValue()); switch ($propertyModel->getVisibility()) { case PropertyModel::VISIBILITY_PUBLIC: $property->makePublic(); break; case PropertyModel::VISIBILITY_PROTECTED: $property->makeProtected(); break; case PropertyModel::VISIBILITY_PRIVATE: $property->makePrivate(); break; default: throw new UnexpectedValueException('Property visibility must be public, protected, private'); } // add property to class $class->addStmt($property); } // add class methods foreach ($classModel->getMethods() as $methodModel) { $method = $this->factory->method($methodModel->getName()); $method->makePublic(); // add method body $body = '<?php ' . $methodModel->getBody(); $methodStatements = $this->parser->parse($body); if (null !== $methodStatements) { $methodStatements = $this->nodeTraverser->traverse($methodStatements); $method->addStmts($methodStatements); } // add method parameters foreach ($methodModel->getParameters() as $parameterModel) { $parameter = $this->factory->param($parameterModel->getName()); if ($parameterModel->hasTypeHint()) { $parameter->setTypeHint($parameterModel->getTypeHint()); } if ($parameterModel->isOptional()) { $parameter->setDefault($parameterModel->getDefaultValue()); } $method->addParam($parameter); } // add method to class $class->addStmt($method); } // add class to namespace $namespace->addStmt($class); // return an array of statements return [$namespace->getNode()]; }
/** * Execute the current Analysis * * Parses the given code and runs the currently attached visitors. If run has already been called the previously * generated result will be returned. The result instance returned by this method is sealed. * Visitors that are attached **after** run is called are ignored on subsequent calls. * * @see RequirementAnalysisResult::seal * * @return AnalysisResult The sealed result. */ public function run() { if (!$this->isAnalyserRun()) { $stmts = $this->parse(); // RequirementAnalyserAwareInterface visitors will call getResult on this instance. $this->nodeTraverser->traverse($stmts); $this->getResult()->seal(); } return $this->getResult(); }
/** * Extracts user defined PHP Type's from a source php file. * * @param string $package * @param string $version * @param string $file * @return array */ private function getTypes($package, $version, $file) { $fullPath = $this->vendorDir . '/' . $package . '/' . $version . '/' . $file; $src = $this->filesystem->read($fullPath); $ast = $this->parser->parse($src); $this->traverser->addVisitor($this->typeExtracator); $this->traverser->traverse($ast); $this->traverser->removeVisitor($this->typeExtracator); return $this->typeExtracator->getTypes(); }
/** @inheritdoc */ public function renameConflicts(array $conflicts) { $replacements = []; $this->traverser->addVisitor($this->reNamer); foreach ($conflicts as $package => $types) { foreach ($types as $type => $versions) { foreach ($versions as $version => $files) { $composer = $this->reader->setPackage($package)->setVersion($version)->getComposerObject(); if ($this->hasNs($type)) { $split = $this->splitNsandClass($type); $fromNs = $split['ns']; $psrNs = $this->getPsrNs($composer, $fromNs); $toNs = $psrNs . $this->sanitizeVersionNo($version); $diff = str_replace($psrNs, '', $fromNs); if ($psrNs != $diff . '\\') { $toNs = $toNs . '\\' . $diff; } $newFullyQualifiedType = $toNs . '\\' . $split['class']; } else { $fromNs = $type; $toNs = $type . '_' . $this->sanitizeVersionNo($version); $newFullyQualifiedType = $toNs; } $this->reNamer->rename($fromNs, $toNs); $replacements[] = ['package' => $package, 'version' => $version, 'originalFullyQualifiedType' => $type, 'originalNamespace' => $fromNs, 'newFullyQualifiedType' => $newFullyQualifiedType, 'newNamespace' => $toNs, 'replacedIn' => $files]; foreach ($files as $file) { $fullPath = $this->vendorDir . '/' . $package . '/' . $version . '/' . $file; $src = $this->filesystem->read($fullPath); $ast = $this->parser->parse($src); $newAst = $this->traverser->traverse($ast); $code = $this->prettyPrinter->prettyPrintFile($newAst); $this->filesystem->update($fullPath, $code); } } } } $this->traverser->removeVisitor($this->reNamer); return $replacements; }
private function traverseStringAST(string $stringAST) { return $this->traverser->traverse($this->parser->parse($stringAST)); }
function it_should_pass_visitor_configuration_to_a_configuration_aware_visitor(ContainerInterface $container, ParserContext $context, NodeTraverserInterface $traverser, ConfigurableVisitorInterface $visitor) { $visitorAlias = 'configurable_visitor'; $configuration = ['key' => 'value']; $this->registerVisitorId($visitorAlias, $visitorAlias); $this->registerContext($context); $this->registerOptions(['visitors' => [$visitorAlias => $configuration]]); $container->get($visitorAlias)->willReturn($visitor); $visitor->configure($configuration)->shouldBeCalled(); $traverser->addVisitor($visitor)->shouldBeCalled(); $this->configure($traverser); }
/** * Create a generator using sensible defaults when possible * * @return Generator */ public function build() { if (null === $this->namespacePrefix) { $this->namespacePrefix = 'Dynamo'; } if (null === $this->parameterDataProviderFactory) { $this->parameterDataProviderFactory = new ParameterDataProviderFactory(); } if (null === $this->reader) { $this->reader = new AnnotationReader(); } if (null === $this->annotationDataProviderFactory) { $this->annotationDataProviderFactory = new AnnotationDataProviderFactory($this->reader); } if (null === $this->methodDataProviderFactory) { $this->methodDataProviderFactory = new MethodDataProviderFactory($this->parameterDataProviderFactory, $this->annotationDataProviderFactory); } if (null === $this->interfaceDataProviderFactory) { $this->interfaceDataProviderFactory = new InterfaceDataProviderFactory($this->methodDataProviderFactory, $this->reader); } if (null === $this->parameterModelFactory) { $this->parameterModelFactory = new ParameterModelFactory(); } if (null === $this->methodModelFactory) { $this->methodModelFactory = new MethodModelFactory($this->parameterModelFactory); } if (null === $this->eventDispatcher) { $this->eventDispatcher = new EventDispatcher(); } if (null === $this->classModelFactory) { $this->classModelFactory = new ClassModelFactory($this->namespacePrefix, $this->interfaceDataProviderFactory, $this->methodModelFactory, $this->eventDispatcher); } if (null === $this->cacheDir) { $this->cacheDir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'dynamo'; } if (null === $this->filesystem) { $this->filesystem = new Filesystem(); } if (null === $this->builderFactory) { $this->builderFactory = new BuilderFactory(); } if (null === $this->lexer) { $this->lexer = new Lexer(); } if (null === $this->parser) { $this->parser = new Parser($this->lexer); } if (null === $this->traverser) { $this->traverser = new NodeTraverser(); } $this->traverser->addVisitor(new NameResolver()); if (null === $this->classModelTransformer) { $this->classModelTransformer = new ClassModelTransformer($this->builderFactory, $this->parser, $this->traverser); } if (null === $this->printer) { $this->printer = new Standard(); } if (null === $this->classModelCacher) { $this->classModelCacher = new ClassModelCacher($this->cacheDir, $this->filesystem, $this->classModelTransformer, $this->printer); } $generator = new Generator($this->classModelFactory, $this->classModelCacher); return $generator; }
private function traverseClassAST(string $className) : array { return $this->traverser->traverse($this->parser->parse(file_get_contents((new \ReflectionClass($className))->getFileName()))); }
/** * @param NodeTraverserInterface $traverser * * @throws \GrumPHP\Exception\RuntimeException */ public function configure(NodeTraverserInterface $traverser) { $this->guardTaskHasVisitors(); $this->guardContextIsRegistered(); $configuredVisitors = $this->loadEnabledVisitorsForCurrentOptions(); $configuredVisitorIds = array_keys($configuredVisitors); $registeredVisitors = $this->registeredVisitorIds; $registeredVisitorsIds = array_keys($registeredVisitors); $visitorIds = array_values(array_intersect($registeredVisitorsIds, $configuredVisitorIds)); $unknownConfiguredVisitorIds = array_diff($configuredVisitorIds, $registeredVisitorsIds); if (count($unknownConfiguredVisitorIds)) { throw new RuntimeException(sprintf('Found unknown php_parser visitors: %s', implode(',', $unknownConfiguredVisitorIds))); } foreach ($visitorIds as $visitorAlias) { $visitorId = $registeredVisitors[$visitorAlias]; $visitor = $this->container->get($visitorId); if ($visitor instanceof ContextAwareVisitorInterface) { $visitor->setContext($this->context); } $options = $configuredVisitors[$visitorAlias]; if ($visitor instanceof ConfigurableVisitorInterface && is_array($options)) { $visitor->configure($options); } $traverser->addVisitor($visitor); } // Reset context to make sure the next configure call will actually run in the correct context: $this->context = null; }