Phan in Browser
(Uses
Phan
5.4.1 and PHP 8.2.0RC5. Best viewed in Firefox/Chrome)
Loading...
Loading...
use Phan\Config; use Phan\Issue; use Phan\IssueInstance; use Phan\Output\HTML; use Phan\Output\IssuePrinterInterface; use Symfony\Component\Console\Output\OutputInterface; use Phan\CLI; use Phan\Phan; error_reporting(E_ALL); ini_set('display_errors', 'stderr'); putenv('NO_COLOR=1'); try { $phar_path = 'phan-5.4.1.phar'; if (!file_exists($phar_path)) { fwrite(STDERR, "Could not load '$phar_path' - this may not have been included when generating this site with emscripten\n"); exit(1); } $phar = "phar://$phar_path"; gc_disable(); $data = require($phar . '/src/Phan/Language/Internal/ClassDocumentationMap.php'); require_once($phar . '/src/requirements.php'); $code_base = require_once($phar . '/src/codebase.php'); require_once($phar . '/src/Phan/Bootstrap.php'); file_put_contents('input', $CONTENTS_TO_ANALYZE); Config::setValue('file_list', ['input']); // These plugins are what you'd see with --init-level=2 Config::setValue('plugins', [ 'AlwaysReturnPlugin', 'DollarDollarPlugin', 'DuplicateArrayKeyPlugin', 'DuplicateExpressionPlugin', 'PregRegexCheckerPlugin', 'PrintfCheckerPlugin', 'SleepCheckerPlugin', 'UnreachableCodePlugin', 'UseReturnValuePlugin', 'EmptyStatementListPlugin', 'StrictComparisonPlugin', 'LoopVariableReusePlugin', ]); // This is stricter, though. Config::setValue('plugin_config', [ 'infer_pure_methods' => true, ]); $cli = CLI::fromRawValues([ 'output-mode' => 'html', 'allow-polyfill-parser' => false, 'use-fallback-parser' => false, 'redundant-condition-detection' => false, 'dead-code-detection' => false, 'no-progress-bar' => false, ], []); // Analyze the file list provided via the CLI $is_issue_found = Phan::analyzeFileList( $code_base, function (bool $recompute_file_list = false) use ($cli) : array { return $cli->getFileList(); } ); } catch (\Throwable $e) { echo "Caught $e\n"; }
function demo_error_handler(int $errno, string $errstr, string $errfile, int $errline) : bool { fwrite(STDERR, "$errfile:$errline [$errno] $errstr\n"); ob_start(); debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); fwrite(STDERR, ob_get_clean()); return false; } try { error_reporting(E_ALL); ini_set("display_errors", "stderr"); set_error_handler('demo_error_handler'); eval($CONTENTS_TO_ANALYZE); } catch (Throwable $e) { fwrite(STDERR, "Caught " . $e); }
function demo($param, $arg) : ?int { // Phan can infer types, detect missing elements, // and detect incorrect calls. global $argc; var_export(new my_class()); $cond = $param > 5; if (!($arg instanceof SplObjectStorage)) { return $argc; } $arg->attach($cond); $arg->atach(new stdClass()); $arg->attach( new MyClass($argc), [], 'extra' ); // Phan can detect redundant/impossible conditions // and unused variables. $always_true = is_bool($cond); echo "Missing variable is $argv\n"; return $arg; } class MyClass { public function __construct(string $x = null) { // and detect undeclared properties, etc. $this->x = $x; } } demo(2, new SplObjectStorage());