/** * @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(); } }
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); }
/** * 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)); }
private function traverseClassAST(string $className) : array { return $this->traverser->traverse($this->parser->parse(file_get_contents((new \ReflectionClass($className))->getFileName()))); }