public function transpile($srcPath, $dstPath) { // transpile based on target version $code = file_get_contents($srcPath); // Parse into statements $parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7); $stmts = $parser->parse($code); if (!$stmts) { throw new ParseException(sprintf("Unable to parse PHP file '%s'\n", $srcPath)); } // Custom traversal does the actual transpiling $traverser = self::getTraverser(); $stmts = $traverser->traverse($stmts); $prettyPrinter = new Standard(); if ($dstPath == '-') { // Output directly to stdout $this->getIo()->output($this->getStub() . $prettyPrinter->prettyPrint($stmts)); } else { $dir = dirname($dstPath); if (!is_dir($dir) || !is_writeable($dir)) { @mkdir($dir, 0777, true); if (!is_dir($dir) || !is_writeable($dir)) { throw new InvalidOptionException(sprintf('Destination directory "%s" does not exist or is not writable or could not be created.', $dir)); } } file_put_contents($dstPath, $this->getStub() . $prettyPrinter->prettyPrint($stmts)); } }
/** * @param EntityMapping $modelMapping * @param string $namespace * @param string $path * @param bool $override * @return void */ public function generate(EntityMapping $modelMapping, $namespace, $path, $override = false) { $abstractNamespace = $namespace . '\\Base'; if (!is_dir($path)) { mkdir($path, 0777, true); } $abstractPath = $path . DIRECTORY_SEPARATOR . 'Base'; if (!is_dir($abstractPath)) { mkdir($abstractPath, 0777, true); } $abstracClassName = 'Abstract' . $modelMapping->getName(); $classPath = $path . DIRECTORY_SEPARATOR . $modelMapping->getName() . '.php'; $abstractClassPath = $abstractPath . DIRECTORY_SEPARATOR . $abstracClassName . '.php'; $nodes = array(); $nodes = array_merge($nodes, $this->generatePropertyNodes($modelMapping)); $nodes = array_merge($nodes, $this->generateConstructNodes($modelMapping)); $nodes = array_merge($nodes, $this->generateMethodNodes($modelMapping)); $nodes = array_merge($nodes, $this->generateMetadataNodes($modelMapping)); $nodes = array(new Node\Stmt\Namespace_(new Name($abstractNamespace), array(new Class_('Abstract' . $modelMapping->getName(), array('type' => 16, 'stmts' => $nodes))))); $abstractClassCode = $this->phpGenerator->prettyPrint($nodes); file_put_contents($abstractClassPath, '<?php' . PHP_EOL . PHP_EOL . $abstractClassCode); if (file_exists($classPath) && !$override) { return; } $nodes = array(new Node\Stmt\Namespace_(new Name($namespace), array(new Class_($modelMapping->getName(), array('extends' => new FullyQualified($abstractNamespace . '\\' . $abstracClassName)))))); $classCode = $this->phpGenerator->prettyPrint($nodes); file_put_contents($classPath, '<?php' . PHP_EOL . PHP_EOL . $classCode); }
/** * @param ClassReflection $reflection * * @return string */ public function __invoke(ClassReflection $reflection) { $stubCode = ClassGenerator::fromReflection($reflection)->generate(); $isInterface = $reflection->isInterface(); if (!($isInterface || $reflection->isTrait())) { return $stubCode; } return $this->prettyPrinter->prettyPrint($this->replaceNodesRecursively($this->parser->parse('<?php ' . $stubCode), $isInterface)); }
/** * @param Mapping $mapping * @param string $path * * @return string */ public function generate(Mapping $mapping, $path) { $nodes = array_merge($this->generatePropertyNodes(), $this->generateMethodNodes($mapping)); $lazyNamespaceParts = explode('\\', $mapping->getLazyClass()); $lazyClass = array_pop($lazyNamespaceParts); $classNode = new Namespace_(new Name(implode('\\', $lazyNamespaceParts)), array(new Class_($lazyClass, array('extends' => new Name('\\' . $mapping->getOriginalClass()), 'stmts' => $nodes)))); $phpCode = '<?php' . "\n\n" . $this->phpGenerator->prettyPrint(array($classNode)); file_put_contents($path . DIRECTORY_SEPARATOR . $lazyClass . '.php', $phpCode); }
/** * @inheritDoc */ public function printContext(ContextInterface $context) { $this->output->writeln(''); $this->output->writeln(sprintf('File: %s', $context->getCheckedResourceName())); foreach ($context->getMessages() as $message) { $nodes = $this->nodeStatementsRemover->removeInnerStatements($message->getNodes()); $this->output->writeln(sprintf('Line %d. %s: %s', $message->getLine(), $message->getText(), $this->prettyPrinter->prettyPrint($nodes))); } $this->output->writeln(''); }
/** * @param Message $message * * @return string */ private function formatMessage(Message $message) { $nodes = $this->nodeStatementsRemover->removeInnerStatements($message->getNodes()); $prettyPrintedNodes = str_replace("\n", "\n ", $this->prettyPrinter->prettyPrint($nodes)); $text = $message->getRawText(); $color = self::$colors[$message->getLevel()]; if ($color) { $text = sprintf('<fg=%s>%s</fg=%s>', $color, $text, $color); } return sprintf("> Line <fg=cyan>%s</fg=cyan>: %s\n %s", $message->getLine(), $text, $prettyPrintedNodes); }
/** * {@inheritdoc} */ public function printContext(ContextInterface $context) { $this->output->writeln(''); $this->output->writeln(sprintf('File: <fg=cyan>%s</fg=cyan>', $context->getCheckedResourceName())); foreach ($context->getMessages() as $message) { $nodes = $this->nodeStatementsRemover->removeInnerStatements($message->getNodes()); $this->output->writeln(sprintf("> Line <fg=cyan>%s</fg=cyan>: <fg=yellow>%s</fg=yellow>\n %s", $message->getLine(), $message->getRawText(), str_replace("\n", "\n ", $this->prettyPrinter->prettyPrint($nodes)))); } foreach ($context->getErrors() as $error) { $this->output->writeln(sprintf('> <fg=red>%s</fg=red>', $error->getText())); } $this->output->writeln(''); }
/** * @param AnnotationManager $annotationManager * @param ServiceManager $serviceManager * @param RouteManager $routeManager * @param Standard $prettyPrinter */ public function updateCache(AnnotationManager $annotationManager, ServiceManager $serviceManager, RouteManager $routeManager, Standard $prettyPrinter) { $classInfos = $annotationManager->buildClassInfosBasedOnPaths($this->paths); $code = "<?php\n\n"; foreach ($classInfos as $classInfo) { $code .= $prettyPrinter->prettyPrint($serviceManager->generateCode($classInfo)); $code .= "\n\n"; } foreach ($classInfos as $classInfo) { $code .= $prettyPrinter->prettyPrint($routeManager->generateCode($classInfo)); $code .= "\n\n"; } file_put_contents($this->cacheFile, $code); }
/** * Get a pretty printed string of code from a file while applying visitors. * * @param string $file * * @throws \RuntimeException * * @return string */ public function getCode($file, $comments = true) { if (!is_string($file) || empty($file)) { throw new RuntimeException('Invalid filename provided.'); } if (!is_readable($file)) { throw new RuntimeException("Cannot open {$file} for reading."); } if ($comments) { $content = file_get_contents($file); } else { $content = php_strip_whitespace($file); } $parsed = $this->parser->parse($content); $stmts = $this->traverser->traverseFile($parsed, $file); $pretty = $this->printer->prettyPrint($stmts); if (substr($pretty, 30) === '<?php declare(strict_types=1);' || substr($pretty, 30) === "<?php\ndeclare(strict_types=1);") { $pretty = substr($pretty, 32); } elseif (substr($pretty, 31) === "<?php\r\ndeclare(strict_types=1);") { $pretty = substr($pretty, 33); } elseif (substr($pretty, 5) === '<?php') { $pretty = substr($pretty, 7); } return $this->getCodeWrappedIntoNamespace($parsed, $pretty); }
/** * @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 Node|ClassMethod $stmt Узел * @param Method[] $methods Список методов * * @return void */ private function extractMethod($stmt, array &$methods) { if (!$stmt instanceof ClassMethod) { return; } $skip = $this->isPublicOnly && $stmt->isPublic() === false; if (!$skip) { $methods[] = new Method(new MethodContext($this->context->namespace, $this->context->class), $stmt->name, $this->printer->prettyPrint([$stmt])); } }
private function createClass($commande, $description) { $output = $this->_output; $root = ROOT . DS; $app = $root . 'app' . DS . "Application"; $lib = $root . 'library' . DS . "commands.php"; // create command name $name = S::create($commande)->replace(':', ' ')->toTitleCase()->replace(' ', '')->append("Command")->__toString(); // create FQN $fqn = "Application\\Commands\\" . $name; // check avaibality // load commands.php file $code = file_get_contents($lib); $parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP5); $prettyPrinter = new PrettyPrinter\Standard(); $stmts = $parser->parse($code); foreach ($stmts[0]->expr as $express) { $tmp = $express[0]->value->value; if (S::create($tmp)->humanize()->__toString() == S::create($fqn)->humanize()->__toString()) { $output->writeln("This command already exists in commands.php"); die; } } // commands not exists add it to commands.php $nb = count($stmts[0]->expr->items); $ligne = 4 + $nb; $attributes = array("startLine" => $ligne, "endLine" => $ligne, "kind" => 2); $obj = new \PhpParser\Node\Expr\ArrayItem(new \PhpParser\Node\Scalar\String_($fqn, $attributes), null, false, $attributes); array_push($stmts[0]->expr->items, $obj); $code = $prettyPrinter->prettyPrint($stmts); $code = "<?php \r\n" . $code; $output->writeln("Create FQN commande " . $fqn); $path = $app . DS . "Commands" . DS . $name . ".php"; $arg1 = new \PhpParser\Node\Arg(new \PhpParser\Node\Scalar\String_($commande)); $arg2 = new \PhpParser\Node\Arg(new \PhpParser\Node\Scalar\String_($description)); $arg3 = new \PhpParser\Node\Arg(new \PhpParser\Node\Scalar\String_('Start process')); $arg4 = new \PhpParser\Node\Arg(new \PhpParser\Node\Scalar\String_('Finished')); $factory = new BuilderFactory(); $node = $factory->namespace('Application\\Commands')->addStmt($factory->use('Symfony\\Component\\Console\\Command\\Command'))->addStmt($factory->use('Symfony\\Component\\Console\\Input\\InputArgument'))->addStmt($factory->use('Symfony\\Component\\Console\\Input\\InputInterface'))->addStmt($factory->use('Symfony\\Component\\Console\\Input\\InputOption'))->addStmt($factory->use('Symfony\\Component\\Console\\Output\\OutputInterface'))->addStmt($factory->class($name)->extend('Command')->addStmt($factory->method('configure')->makeProtected()->addStmt(new Node\Expr\MethodCall(new Node\Expr\Variable('this'), "setName", array($arg1)))->addStmt(new Node\Expr\MethodCall(new Node\Expr\Variable('this'), "setDescription", array($arg2))))->addStmt($factory->method('execute')->makeProtected()->addParam($factory->param('input')->setTypeHint('InputInterface'))->addParam($factory->param('output')->setTypeHint('OutputInterface'))->addStmt(new Node\Expr\MethodCall(new Node\Expr\Variable('output'), "writeln", array($arg3)))->addStmt(new Node\Expr\MethodCall(new Node\Expr\Variable('output'), "writeln", array($arg4)))))->getNode(); $stmts = array($node); $prettyPrinter = new PrettyPrinter\Standard(); $php = $prettyPrinter->prettyPrintFile($stmts); file_put_contents($path, $php); $fs = new Filesystem(); // if file exists add command to commands.php if ($fs->exists($path)) { $output->writeln("File saved in " . $path); $output->writeln("Register command to console"); file_put_contents($lib, $code); } else { $output->writeln("File not created"); } }
function pp($nodes) { static $prettyPrinter; if (!$prettyPrinter) { $prettyPrinter = new PrettyPrinter\Standard(); } if (!is_array($nodes)) { $nodes = func_get_args(); } echo $prettyPrinter->prettyPrint($nodes) . "\n"; die(1); }
/** * @param ControllerSpec $spec */ public function generate(ControllerSpec $spec) { $printer = new PrettyPrinter(); $ast = $this->doGenerate($spec); $ast = $this->processorDispatcher->process($ast); $event = new ControllerGenerated($spec, $ast); $this->eventDispatcher->dispatch(ControllerGenerated::EVENT_NAME, $event); $code = $printer->prettyPrint($ast); $controllerFile = $spec->getBundle()->getPath() . '/Controller/' . $spec->getName() . 'Controller.php'; file_put_contents($controllerFile, "<?php\n" . $code); $event = new ControllerSaved($spec, $controllerFile); $this->eventDispatcher->dispatch(ControllerSaved::EVENT_NAME, $event); }
/** * Obfuscate a single file's contents * * @param string $source * @return string obfuscated contents **/ public function obfuscateFileContents($source, $file = false) { $traverser = new PhpParser\NodeTraverser(); if (input::get('ReplaceVariables')) { /** * all $vars */ $traverser->addVisitor(new \Controllers\Obfuscator\ScrambleVariable($this)); $traverser->addVisitor(new \Controllers\Obfuscator\ScrambleString($this)); } if (input::get('ReplaceFunctions')) { /** * all OOP functions */ $traverser->addVisitor(new \Controllers\Obfuscator\ScrambleFunction($this)); /** * all NONE OOP functions (NATIVE) */ $traverser->addVisitor(new \Controllers\Obfuscator\ScrambleNativeFunction($this)); } if (input::get('ReplaceVariables')) { /** * all OOP $this->vars */ $traverser->addVisitor(new \Controllers\Obfuscator\ScrambleProperty($this)); } //if( input::get('ReplaceSmart') ) { //$traverser->addVisitor(new \Controllers\Obfuscator\ScrambleSmart($this)); //} $parser = new Parser(new Lexer()); // traverse $stmts = $traverser->traverse($parser->parse($source)); $prettyPrinter = new PrettyPrinter(); $nodeDumper = new PhpParser\NodeDumper(); Debugbar::debug($stmts); // pretty print $code = "<?php\n" . $prettyPrinter->prettyPrint($stmts); if (Input::has('test')) { @header("Content-Type:text/plain"); print_r($this->getFuncPack()); print_r($this->getVarPack()); echo '<pre>'; echo $nodeDumper->dump($stmts), "\n"; echo htmlentities($code); echo '</pre>'; } return $code; }
/** * Get a pretty printed string of code from a file while applying visitors. * * @param string $file * * @throws \RuntimeException * * @return string */ protected function getCode($file) { if (!is_readable($file)) { throw new \RuntimeException("Cannot open {$file} for reading"); } if ($this->input->getOption('strip_comments')) { $content = php_strip_whitespace($file); } else { $content = file_get_contents($file); } $parsed = $this->parser->parse($content); $stmts = $this->getTraverser()->traverseFile($parsed, $file); $pretty = $this->printer->prettyPrint($stmts); // Remove the open PHP tag if (substr($pretty, 5) === '<?php') { $pretty = substr($pretty, 7); } return $this->getCodeWrappedIntoNamespace($parsed, $pretty); }
public function onControllerGenerated(ControllerGenerated $event) { $spec = $event->getControllerSpec(); $printer = new PrettyPrinter(); $stmts = array(); echo "Generating tests for {$spec->getName()}:\n"; $stmts[] = $this->factory->namespace(array($spec->getBundle()->getNamespace(), 'Tests', 'Controller')); $stmts[] = $this->factory->use('Symfony\\Bundle\\FrameworkBundle\\Test\\WebTestCase'); $class = $this->factory->class($spec->getName() . 'ControllerTest')->extend('WebTestCase'); foreach ($spec->getActions() as $action) { $class->addStmt($this->buildAction($action)); echo " test{$action}\n"; } $stmts[] = $class; $nodes = array_map(function ($stmt) { return $stmt->getNode(); }, $stmts); $code = $printer->prettyPrint($nodes); $testCaseFile = $spec->getBundle()->getPath() . '/Tests/Controller/' . $spec->getName() . 'ControllerTest.php'; file_put_contents($testCaseFile, "<?php\n" . $code); }
/** * Get a pretty printed string of code from a file while applying visitors. * * @param string $file * * @throws \RuntimeException * * @return string */ protected function getCode($file) { if (!is_readable($file)) { throw new \RuntimeException("Cannot open {$file} for reading"); } if ($this->input->getOption('strip_comments')) { $content = php_strip_whitespace($file); } else { $content = file_get_contents($file); } $parsed = $this->parser->parse($content); $stmts = $this->getTraverser()->traverseFile($parsed, $file); $pretty = $this->printer->prettyPrint($stmts); // Remove the open PHP tag if (substr($pretty, 5) === '<?php') { $pretty = substr($pretty, 7); } // Add a wrapping namespace if needed if (strpos($pretty, 'namespace ') === false) { $pretty = "namespace {\n" . $pretty . "\n}\n"; } return $pretty; }
/** * @covers NameResolver */ public function testResolveLocations() { $code = <<<'EOC' <?php namespace NS; class A extends B implements C { use A; } interface A extends C { public function a(A $a); } A::b(); A::$b; A::B; new A; $a instanceof A; namespace\a(); namespace\A; try { $someThing; } catch (A $a) { $someThingElse; } EOC; $expectedCode = <<<'EOC' namespace NS; class A extends \NS\B implements \NS\C { use \NS\A; } interface A extends \NS\C { public function a(\NS\A $a); } \NS\A::b(); \NS\A::$b; \NS\A::B; new \NS\A(); $a instanceof \NS\A; \NS\a(); \NS\A; try { $someThing; } catch (\NS\A $a) { $someThingElse; } EOC; $parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative()); $prettyPrinter = new PhpParser\PrettyPrinter\Standard(); $traverser = new PhpParser\NodeTraverser(); $traverser->addVisitor(new NameResolver()); $stmts = $parser->parse($code); $stmts = $traverser->traverse($stmts); $this->assertEquals($expectedCode, $prettyPrinter->prettyPrint($stmts)); }
/** * @covers PhpParser\NodeVisitor\NameResolver */ public function testResolveLocations() { $code = <<<'EOC' <?php namespace NS; class A extends B implements C, D { use E, F, G { f as private g; E::h as i; E::j insteadof F, G; } } interface A extends C, D { public function a(A $a) : A; } function fn() : A {} function fn2() : array {} function() : A {}; A::b(); A::$b; A::B; new A; $a instanceof A; namespace\a(); namespace\A; try { $someThing; } catch (A $a) { $someThingElse; } EOC; $expectedCode = <<<'EOC' namespace NS; class A extends \NS\B implements \NS\C, \NS\D { use \NS\E, \NS\F, \NS\G { f as private g; \NS\E::h as i; \NS\E::j insteadof \NS\F, \NS\G; } } interface A extends \NS\C, \NS\D { public function a(\NS\A $a) : \NS\A; } function fn() : \NS\A { } function fn2() : array { } function () : \NS\A { }; \NS\A::b(); \NS\A::$b; \NS\A::B; new \NS\A(); $a instanceof \NS\A; \NS\a(); \NS\A; try { $someThing; } catch (\NS\A $a) { $someThingElse; } EOC; $parser = new PhpParser\Parser\Php7(new PhpParser\Lexer\Emulative()); $prettyPrinter = new PhpParser\PrettyPrinter\Standard(); $traverser = new PhpParser\NodeTraverser(); $traverser->addVisitor(new NameResolver()); $stmts = $parser->parse($code); $stmts = $traverser->traverse($stmts); $this->assertSame($this->canonicalize($expectedCode), $prettyPrinter->prettyPrint($stmts)); }
/** Validate passed callable for execution * * @param callable|string $code The callable or string of code to validate * * @return $this Returns the PHPSandbox instance for fluent querying */ public function validate($code) { $this->preparsed_code = $this->disassemble($code); $factory = new ParserFactory(); $parser = $factory->create(ParserFactory::PREFER_PHP5); try { $this->parsed_ast = $parser->parse($this->preparsed_code); } catch (ParserError $error) { $this->validationError("Could not parse sandboxed code!", Error::PARSER_ERROR, null, $this->preparsed_code, $error); } $prettyPrinter = new Standard(); if ($this->allow_functions && $this->auto_whitelist_functions || $this->allow_constants && $this->auto_whitelist_constants || $this->allow_classes && $this->auto_whitelist_classes || $this->allow_interfaces && $this->auto_whitelist_interfaces || $this->allow_traits && $this->auto_whitelist_traits || $this->allow_globals && $this->auto_whitelist_globals) { $traverser = new NodeTraverser(); $whitelister = new SandboxWhitelistVisitor($this); $traverser->addVisitor($whitelister); $traverser->traverse($this->parsed_ast); } $traverser = new NodeTraverser(); $validator = new ValidatorVisitor($this); $traverser->addVisitor($validator); $this->prepared_ast = $traverser->traverse($this->parsed_ast); $this->prepared_code = $prettyPrinter->prettyPrint($this->prepared_ast); return $this; }
/** * Get the default value from a method parameter * * @param mixed $default * @return string */ private function getDefaultValue($default) { $default = $this->prettyPrinter->prettyPrint([$default]); $default = str_replace(';', '', $default); return $default; }
private function processNode(\PhpParser\Node $node, Scope $scope, \Closure $nodeCallback) { $nodeCallback($node, $scope); if ($node instanceof \PhpParser\Node\Stmt\ClassLike) { if ($node instanceof Node\Stmt\Trait_) { return; } if (isset($node->namespacedName)) { $scope = $scope->enterClass((string) $node->namespacedName); } else { $scope = $scope->enterAnonymousClass($this->anonymousClassReflection); } } elseif ($node instanceof Node\Stmt\TraitUse) { $this->processTraitUse($node, $scope, $nodeCallback); } elseif ($node instanceof \PhpParser\Node\Stmt\Function_) { $scope = $scope->enterFunction($this->broker->getFunction($node->namespacedName, $scope)); } elseif ($node instanceof \PhpParser\Node\Stmt\ClassMethod) { $scope = $this->enterClassMethod($scope, $node); } elseif ($node instanceof \PhpParser\Node\Stmt\Namespace_) { $scope = $scope->enterNamespace((string) $node->name); } elseif ($node instanceof \PhpParser\Node\Expr\StaticCall && (is_string($node->class) || $node->class instanceof \PhpParser\Node\Name) && is_string($node->name) && (string) $node->class === 'Closure' && $node->name === 'bind') { $thisType = null; if (isset($node->args[1])) { $argValue = $node->args[1]->value; if ($argValue instanceof Expr\ConstFetch && (string) $argValue->name === 'null') { $thisType = null; } else { $thisType = $scope->getType($argValue); } } $scopeClass = 'static'; if (isset($node->args[2])) { $argValue = $node->args[2]->value; $argValueType = $scope->getType($argValue); if ($argValueType->getClass() !== null) { $scopeClass = $argValueType->getClass(); } elseif ($argValue instanceof Expr\ClassConstFetch && $argValue->name === 'class' && $argValue->class instanceof Name) { $resolvedName = $scope->resolveName($argValue->class); if ($resolvedName !== null) { $scopeClass = $resolvedName; } } elseif ($argValue instanceof Node\Scalar\String_) { $scopeClass = $argValue->value; } } $closureBindScope = $scope->enterClosureBind($thisType, $scopeClass); } elseif ($node instanceof \PhpParser\Node\Expr\Closure) { $scope = $scope->enterAnonymousFunction($node->params, $node->uses, $node->returnType); } elseif ($node instanceof Foreach_) { if ($node->valueVar instanceof Variable) { $scope = $scope->enterForeach($node->expr, $node->valueVar->name, $node->keyVar !== null && $node->keyVar instanceof Variable ? $node->keyVar->name : null); } else { if ($node->keyVar !== null && $node->keyVar instanceof Variable) { $scope = $scope->assignVariable($node->keyVar->name); } if ($node->valueVar instanceof Array_) { $scope = $this->lookForArrayDestructuringArray($scope, $node->valueVar); } else { $scope = $this->lookForAssigns($scope, $node->valueVar); } } } elseif ($node instanceof Catch_) { if (isset($node->types)) { $nodeTypes = $node->types; } elseif (isset($node->type)) { $nodeTypes = [$node->type]; } else { throw new \PHPStan\ShouldNotHappenException(); } $scope = $scope->enterCatch($nodeTypes, $node->var); } elseif ($node instanceof For_) { foreach ($node->init as $initExpr) { $scope = $this->lookForAssigns($scope, $initExpr); } foreach ($node->cond as $condExpr) { $scope = $this->lookForAssigns($scope, $condExpr); } foreach ($node->loop as $loopExpr) { $scope = $this->lookForAssigns($scope, $loopExpr); } } elseif ($node instanceof If_) { $scope = $this->lookForAssigns($scope, $node->cond); $ifScope = $scope; $scope = $this->lookForTypeSpecifications($scope, $node->cond); $this->processNode($node->cond, $scope, $nodeCallback); $this->processNodes($node->stmts, $scope, $nodeCallback); foreach ($node->elseifs as $elseif) { $this->processNode($elseif, $ifScope, $nodeCallback); $ifScope = $this->lookForAssigns($ifScope, $elseif->cond); } if ($node->else !== null) { $this->processNode($node->else, $ifScope, $nodeCallback); } return; } elseif ($node instanceof Switch_) { $scope = $this->lookForAssigns($scope, $node->cond); $switchScope = $scope; $switchConditionIsTrue = $node->cond instanceof Expr\ConstFetch && strtolower((string) $node->cond->name) === 'true'; foreach ($node->cases as $caseNode) { if ($caseNode->cond !== null) { $switchScope = $this->lookForAssigns($switchScope, $caseNode->cond); if ($switchConditionIsTrue) { $switchScope = $this->lookForTypeSpecifications($switchScope, $caseNode->cond); } } $this->processNode($caseNode, $switchScope, $nodeCallback); if ($this->hasEarlyTermination($caseNode->stmts, $switchScope)) { $switchScope = $scope; } } return; } elseif ($node instanceof ElseIf_) { $scope = $this->lookForAssigns($scope, $node->cond); $scope = $this->lookForTypeSpecifications($scope, $node->cond); } elseif ($node instanceof While_) { $scope = $this->lookForAssigns($scope, $node->cond); $scope = $this->lookForTypeSpecifications($scope, $node->cond); } elseif ($this->polluteCatchScopeWithTryAssignments && $node instanceof TryCatch) { foreach ($node->stmts as $statement) { $scope = $this->lookForAssigns($scope, $statement); } } elseif ($node instanceof Ternary) { $scope = $this->lookForAssigns($scope, $node->cond); } elseif ($node instanceof Do_) { foreach ($node->stmts as $statement) { $scope = $this->lookForAssigns($scope, $statement); } } elseif ($node instanceof FuncCall) { $scope = $scope->enterFunctionCall($node); } elseif ($node instanceof Expr\StaticCall) { $scope = $scope->enterFunctionCall($node); } elseif ($node instanceof MethodCall) { if ($scope->getType($node->var)->getClass() === 'Closure' && $node->name === 'call' && isset($node->args[0])) { $closureCallScope = $scope->enterClosureBind($scope->getType($node->args[0]->value), 'static'); } $scope = $scope->enterFunctionCall($node); } elseif ($node instanceof Array_) { foreach ($node->items as $item) { $scope = $this->lookForAssigns($scope, $item->value); } } elseif ($node instanceof New_ && $node->class instanceof Class_) { $node->args = []; foreach ($node->class->stmts as $i => $statement) { if ($statement instanceof Node\Stmt\ClassMethod && $statement->name === '__construct') { unset($node->class->stmts[$i]); $node->class->stmts = array_values($node->class->stmts); break; } } $code = $this->printer->prettyPrint([$node]); $classReflection = new \ReflectionClass(eval(sprintf('return %s', $code))); $this->anonymousClassReflection = $this->broker->getClassFromReflection($classReflection); } elseif ($node instanceof BooleanNot) { $scope = $scope->enterNegation(); } $originalScope = $scope; foreach ($node->getSubNodeNames() as $subNodeName) { $scope = $originalScope; $subNode = $node->{$subNodeName}; if (is_array($subNode)) { $argClosureBindScope = null; if (isset($closureBindScope) && $subNodeName === 'args') { $argClosureBindScope = $closureBindScope; } $this->processNodes($subNode, $scope, $nodeCallback, $argClosureBindScope); } elseif ($subNode instanceof \PhpParser\Node) { if ($node instanceof Coalesce && $subNodeName === 'left') { $scope = $this->assignVariable($scope, $subNode); } if ($node instanceof Ternary && $subNodeName === 'if') { $scope = $this->lookForTypeSpecifications($scope, $node->cond); } if ($node instanceof BooleanAnd && $subNodeName === 'right') { $scope = $this->lookForTypeSpecifications($scope, $node->left); } if (($node instanceof Assign || $node instanceof AssignRef) && $subNodeName === 'var') { $scope = $this->lookForEnterVariableAssign($scope, $node->var); } $nodeScope = $scope; if ($node instanceof MethodCall && $subNodeName === 'var' && isset($closureCallScope)) { $nodeScope = $closureCallScope; } $this->processNode($subNode, $nodeScope, $nodeCallback); } } }
/** * Retrieves the body of this function as code. * * If a PrettyPrinter is provided as a paramter, it will be used, otherwise * a default will be used. * * Note that the formatting of the code may not be the same as the original * function. If specific formatting is required, you should provide your * own implementation of a PrettyPrinter to unparse the AST. * * @param PrettyPrinterAbstract|null $printer * @return string */ public function getBodyCode(PrettyPrinterAbstract $printer = null) { if (null === $printer) { $printer = new StandardPrettyPrinter(); } return $printer->prettyPrint($this->getBodyAst()); }
public function getMessage() { $formatter = new Standard(); $code = $formatter->prettyPrint(array($this->node)); return 'Magic usage : ' . $code; }
protected function visitMethod(ClassMethod $node) { $m = new PhpMethod($node->name); $m->setAbstract($node->isAbstract()); $m->setFinal($node->isFinal()); $m->setVisibility($this->getVisibility($node)); $m->setStatic($node->isStatic()); $m->setReferenceReturned($node->returnsByRef()); // docblock if (($doc = $node->getDocComment()) !== null) { $m->setDocblock($doc->getReformattedText()); $docblock = $m->getDocblock(); $m->setDescription($docblock->getShortDescription()); $m->setLongDescription($docblock->getLongDescription()); } // params $params = $m->getDocblock()->getTags('param'); foreach ($node->params as $param) { /* @var $param Param */ $p = new PhpParameter(); $p->setName($param->name); $p->setPassedByReference($param->byRef); if (is_string($param->type)) { $p->setType($param->type); } else { if ($param->type instanceof Name) { $p->setType(implode('\\', $param->type->parts)); } } $default = $param->default; if ($default !== null) { $p->setDefaultValue($this->getValue($default)); } $tag = $params->find($p, function (ParamTag $t, $p) { return $t->getVariable() == '$' . $p->getName(); }); if ($tag !== null) { $p->setType($tag->getType(), $tag->getDescription()); } $m->addParameter($p); } // return type and description $returns = $m->getDocblock()->getTags('return'); if ($returns->size() > 0) { $return = $returns->get(0); $m->setType($return->getType(), $return->getDescription()); } // body $stmts = $node->getStmts(); if (is_array($stmts) && count($stmts)) { $prettyPrinter = new Standard(); $m->setBody($prettyPrinter->prettyPrint($stmts)); } $this->struct->setMethod($m); }