Path: blob/master/scripts/symbols/generate_php_symbols.php
12241 views
#!/usr/bin/env php1<?php23$root = dirname(dirname(dirname(__FILE__)));4require_once $root.'/scripts/__init_script__.php';56$args = new PhutilArgumentParser($argv);7$args->setSynopsis(<<<EOSYNOPSIS8**generate_php_symbols.php** [__options__]910Generate repository symbols using XHPAST. Paths are read from stdin.11EOSYNOPSIS12);13$args->parseStandardArguments();1415if (posix_isatty(STDIN)) {16echo phutil_console_format(17"%s\n",18pht(19'Usage: %s',20"find . -type f -name '*.php' | ./generate_php_symbols.php"));21exit(1);22}2324$input = file_get_contents('php://stdin');25$data = array();26$futures = array();2728foreach (explode("\n", trim($input)) as $file) {29if (!strlen($file)) {30continue;31}3233$file = Filesystem::readablePath($file);34$data[$file] = Filesystem::readFile($file);35$futures[$file] = PhutilXHPASTBinary::getParserFuture($data[$file]);36}3738$futures = new FutureIterator($futures);39foreach ($futures->limit(8) as $file => $future) {40$tree = XHPASTTree::newFromDataAndResolvedExecFuture(41$data[$file],42$future->resolve());4344$root = $tree->getRootNode();45$scopes = array();4647$functions = $root->selectDescendantsOfType('n_FUNCTION_DECLARATION');48foreach ($functions as $function) {49$name = $function->getChildByIndex(2);50// Skip anonymous functions.51if (!$name->getConcreteString()) {52continue;53}54print_symbol($file, 'function', $name);55}5657$classes = $root->selectDescendantsOfType('n_CLASS_DECLARATION');58foreach ($classes as $class) {59$class_name = $class->getChildByIndex(1);60print_symbol($file, 'class', $class_name);61$scopes[] = array($class, $class_name);62}6364$interfaces = $root->selectDescendantsOfType('n_INTERFACE_DECLARATION');65foreach ($interfaces as $interface) {66$interface_name = $interface->getChildByIndex(1);67// We don't differentiate classes and interfaces in highlighters.68print_symbol($file, 'class', $interface_name);69$scopes[] = array($interface, $interface_name);70}7172$constants = $root->selectDescendantsOfType('n_CONSTANT_DECLARATION_LIST');73foreach ($constants as $constant_list) {74foreach ($constant_list->getChildren() as $constant) {75$constant_name = $constant->getChildByIndex(0);76print_symbol($file, 'constant', $constant_name);77}78}7980foreach ($scopes as $scope) {81// This prints duplicate symbols in the case of nested classes.82// Luckily, PHP doesn't allow those.83list($class, $class_name) = $scope;8485$consts = $class->selectDescendantsOfType(86'n_CLASS_CONSTANT_DECLARATION_LIST');87foreach ($consts as $const_list) {88foreach ($const_list->getChildren() as $const) {89$const_name = $const->getChildByIndex(0);90print_symbol($file, 'class_const', $const_name, $class_name);91}92}9394$members = $class->selectDescendantsOfType(95'n_CLASS_MEMBER_DECLARATION_LIST');96foreach ($members as $member_list) {97foreach ($member_list->getChildren() as $member) {98if ($member->getTypeName() == 'n_CLASS_MEMBER_MODIFIER_LIST') {99continue;100}101$member_name = $member->getChildByIndex(0);102print_symbol($file, 'member', $member_name, $class_name);103}104}105106$methods = $class->selectDescendantsOfType('n_METHOD_DECLARATION');107foreach ($methods as $method) {108$method_name = $method->getChildByIndex(2);109print_symbol($file, 'method', $method_name, $class_name);110}111}112}113114function print_symbol($file, $type, XHPASTNode $node, $context = null) {115$parts = array(116$context ? $context->getConcreteString() : '',117// Variable tokens are `$name`, not just `name`, so strip the "$"" off of118// class field names119ltrim($node->getConcreteString(), '$'),120$type,121'php',122$node->getLineNumber(),123'/'.ltrim($file, './'),124);125echo implode(' ', $parts)."\n";126}127128129