Example #1
0
 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);
 }
Example #2
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());
 }
Example #3
0
 /**
  * @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();
 }
Example #4
0
 /**
  * @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;
 }
Example #5
0
 /**
  * @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);
     }
 }
Example #6
0
 /**
  * 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();
     }
 }
Example #7
0
 /**
  * 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()];
 }
Example #8
0
 /**
  * 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();
 }
Example #9
0
 /**
  * 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();
 }
Example #10
0
 /** @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);
 }
Example #13
0
 /**
  * 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())));
 }
Example #15
0
 /**
  * @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;
 }