Beispiel #1
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();
 }
Beispiel #2
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;
 }
Beispiel #3
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);
     }
 }
Beispiel #4
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();
     }
 }
Beispiel #5
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);
 }
Beispiel #6
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()];
 }
Beispiel #7
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();
 }
Beispiel #8
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();
 }
Beispiel #9
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));
 }
 private function traverseClassAST(string $className) : array
 {
     return $this->traverser->traverse($this->parser->parse(file_get_contents((new \ReflectionClass($className))->getFileName())));
 }