Server IP : 127.0.0.2 / Your IP : 3.142.237.71 Web Server : Apache/2.4.18 (Ubuntu) System : User : www-data ( ) PHP Version : 7.0.33-0ubuntu0.16.04.16 Disable Function : disk_free_space,disk_total_space,diskfreespace,dl,exec,fpaththru,getmyuid,getmypid,highlight_file,ignore_user_abord,leak,listen,link,opcache_get_configuration,opcache_get_status,passthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,php_uname,phpinfo,posix_ctermid,posix_getcwd,posix_getegid,posix_geteuid,posix_getgid,posix_getgrgid,posix_getgrnam,posix_getgroups,posix_getlogin,posix_getpgid,posix_getpgrp,posix_getpid,posix,_getppid,posix_getpwnam,posix_getpwuid,posix_getrlimit,posix_getsid,posix_getuid,posix_isatty,posix_kill,posix_mkfifo,posix_setegid,posix_seteuid,posix_setgid,posix_setpgid,posix_setsid,posix_setuid,posix_times,posix_ttyname,posix_uname,pclose,popen,proc_open,proc_close,proc_get_status,proc_nice,proc_terminate,shell_exec,source,show_source,system,virtual MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /var/www/html/vendor/jeremeamia/superclosure/src/Analyzer/ |
Upload File : |
<?php namespace SuperClosure\Analyzer; use SuperClosure\Analyzer\Visitor\ThisDetectorVisitor; use SuperClosure\Exception\ClosureAnalysisException; use SuperClosure\Analyzer\Visitor\ClosureLocatorVisitor; use SuperClosure\Analyzer\Visitor\MagicConstantVisitor; use PhpParser\NodeTraverser; use PhpParser\PrettyPrinter\Standard as NodePrinter; use PhpParser\Error as ParserError; use PhpParser\Node\Expr\Variable as VariableNode; use PhpParser\NodeVisitor\NameResolver; use PhpParser\Parser as CodeParser; use PhpParser\ParserFactory; use PhpParser\Lexer\Emulative as EmulativeLexer; /** * This is the AST based analyzer. * * We're using reflection and AST-based code parser to analyze a closure and * determine its code and context using the nikic/php-parser library. The AST * based analyzer and has more capabilities than the token analyzer, but is, * unfortunately, about 25 times slower. */ class AstAnalyzer extends ClosureAnalyzer { protected function determineCode(array &$data) { // Find the closure by traversing through a AST of the code. // Note: This also resolves class names to their FQCNs while traversing. $this->locateClosure($data); // Make a second pass through the AST, but only through the closure's // nodes, to resolve any magic constants to literal values. $traverser = new NodeTraverser; $traverser->addVisitor(new MagicConstantVisitor($data['location'])); $traverser->addVisitor($thisDetector = new ThisDetectorVisitor); $data['ast'] = $traverser->traverse([$data['ast']])[0]; $data['hasThis'] = $thisDetector->detected; // Bounce the updated AST down to a string representation of the code. $data['code'] = (new NodePrinter)->prettyPrint([$data['ast']]); } /** * Parses the closure's code and produces an abstract syntax tree (AST). * * @param array $data * * @throws ClosureAnalysisException if there is an issue finding the closure */ private function locateClosure(array &$data) { try { $locator = new ClosureLocatorVisitor($data['reflection']); $fileAst = $this->getFileAst($data['reflection']); $fileTraverser = new NodeTraverser; $fileTraverser->addVisitor(new NameResolver); $fileTraverser->addVisitor($locator); $fileTraverser->traverse($fileAst); } catch (ParserError $e) { // @codeCoverageIgnoreStart throw new ClosureAnalysisException( 'There was an error analyzing the closure code.', 0, $e ); // @codeCoverageIgnoreEnd } $data['ast'] = $locator->closureNode; if (!$data['ast']) { // @codeCoverageIgnoreStart throw new ClosureAnalysisException( 'The closure was not found within the abstract syntax tree.' ); // @codeCoverageIgnoreEnd } $data['location'] = $locator->location; } /** * Returns the variables that in the "use" clause of the closure definition. * These are referred to as the "used variables", "static variables", or * "closed upon variables", "context" of the closure. * * @param array $data */ protected function determineContext(array &$data) { // Get the variable names defined in the AST $refs = 0; $vars = array_map(function ($node) use (&$refs) { if ($node->byRef) { $refs++; } if ($node->var instanceof VariableNode) { // For PHP-Parser >=4.0 return $node->var->name; } else { // For PHP-Parser <4.0 return $node->var; } }, $data['ast']->uses); $data['hasRefs'] = ($refs > 0); // Get the variable names and values using reflection $values = $data['reflection']->getStaticVariables(); // Combine the names and values to create the canonical context. foreach ($vars as $name) { if (isset($values[$name])) { $data['context'][$name] = $values[$name]; } } } /** * @param \ReflectionFunction $reflection * * @throws ClosureAnalysisException * * @return \PhpParser\Node[] */ private function getFileAst(\ReflectionFunction $reflection) { $fileName = $reflection->getFileName(); if (!file_exists($fileName)) { throw new ClosureAnalysisException( "The file containing the closure, \"{$fileName}\" did not exist." ); } return $this->getParser()->parse(file_get_contents($fileName)); } /** * @return CodeParser */ private function getParser() { if (class_exists('PhpParser\ParserFactory')) { return (new ParserFactory)->create(ParserFactory::PREFER_PHP7); } return new CodeParser(new EmulativeLexer); } }