| 
									
										
										
										
											2011-09-04 18:24:46 -07:00
										 |  |  | #!/usr/bin/env php
 | 
					
						
							|  |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | $root = dirname(dirname(dirname(__FILE__))); | 
					
						
							|  |  |  | require_once $root.'/scripts/__init_script__.php'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-03 10:11:17 +10:00
										 |  |  | $args = new PhutilArgumentParser($argv); | 
					
						
							|  |  |  | $args->setSynopsis(<<<EOSYNOPSIS | 
					
						
							|  |  |  | **generate_php_symbols.php** [__options__] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Generate repository symbols using XHPAST. Paths are read from stdin. | 
					
						
							|  |  |  | EOSYNOPSIS | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  | $args->parseStandardArguments(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if (posix_isatty(STDIN)) { | 
					
						
							| 
									
										
										
										
											2011-09-04 18:24:46 -07:00
										 |  |  |   echo phutil_console_format( | 
					
						
							| 
									
										
										
										
											2015-05-03 10:11:17 +10:00
										 |  |  |     "%s\n", | 
					
						
							|  |  |  |     pht( | 
					
						
							|  |  |  |       'Usage: %s', | 
					
						
							|  |  |  |       "find . -type f -name '*.php' | ./generate_php_symbols.php")); | 
					
						
							| 
									
										
										
										
											2011-09-04 18:24:46 -07:00
										 |  |  |   exit(1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | $input = file_get_contents('php://stdin'); | 
					
						
							|  |  |  | $data = array(); | 
					
						
							|  |  |  | $futures = array(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-03 10:11:17 +10:00
										 |  |  | foreach (explode("\n", trim($input)) as $file) { | 
					
						
							| 
									
										
										
										
											2011-09-04 18:24:46 -07:00
										 |  |  |   $file = Filesystem::readablePath($file); | 
					
						
							|  |  |  |   $data[$file] = Filesystem::readFile($file); | 
					
						
							| 
									
										
										
										
											2015-02-03 06:59:15 +11:00
										 |  |  |   $futures[$file] = PhutilXHPASTBinary::getParserFuture($data[$file]); | 
					
						
							| 
									
										
										
										
											2011-09-04 18:24:46 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-03 10:11:17 +10:00
										 |  |  | $futures = new FutureIterator($futures); | 
					
						
							|  |  |  | foreach ($futures->limit(8) as $file => $future) { | 
					
						
							| 
									
										
										
										
											2011-09-04 18:24:46 -07:00
										 |  |  |   $tree = XHPASTTree::newFromDataAndResolvedExecFuture( | 
					
						
							|  |  |  |     $data[$file], | 
					
						
							|  |  |  |     $future->resolve()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   $root = $tree->getRootNode(); | 
					
						
							| 
									
										
										
										
											2012-08-08 17:06:05 -07:00
										 |  |  |   $scopes = array(); | 
					
						
							| 
									
										
										
										
											2011-09-04 18:24:46 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   $functions = $root->selectDescendantsOfType('n_FUNCTION_DECLARATION'); | 
					
						
							|  |  |  |   foreach ($functions as $function) { | 
					
						
							|  |  |  |     $name = $function->getChildByIndex(2); | 
					
						
							| 
									
										
										
										
											2015-05-03 10:11:17 +10:00
										 |  |  |     // Skip anonymous functions.
 | 
					
						
							| 
									
										
										
										
											2014-01-23 17:01:11 -08:00
										 |  |  |     if (!$name->getConcreteString()) { | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-09-04 18:24:46 -07:00
										 |  |  |     print_symbol($file, 'function', $name); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   $classes = $root->selectDescendantsOfType('n_CLASS_DECLARATION'); | 
					
						
							|  |  |  |   foreach ($classes as $class) { | 
					
						
							|  |  |  |     $class_name = $class->getChildByIndex(1); | 
					
						
							|  |  |  |     print_symbol($file, 'class', $class_name); | 
					
						
							| 
									
										
										
										
											2012-08-08 17:06:05 -07:00
										 |  |  |     $scopes[] = array($class, $class_name); | 
					
						
							| 
									
										
										
										
											2011-09-04 18:24:46 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   $interfaces = $root->selectDescendantsOfType('n_INTERFACE_DECLARATION'); | 
					
						
							|  |  |  |   foreach ($interfaces as $interface) { | 
					
						
							|  |  |  |     $interface_name = $interface->getChildByIndex(1); | 
					
						
							| 
									
										
										
										
											2012-08-24 16:58:31 -07:00
										 |  |  |     // We don't differentiate classes and interfaces in highlighters.
 | 
					
						
							|  |  |  |     print_symbol($file, 'class', $interface_name); | 
					
						
							| 
									
										
										
										
											2012-08-08 17:06:05 -07:00
										 |  |  |     $scopes[] = array($interface, $interface_name); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   $constants = $root->selectDescendantsOfType('n_CONSTANT_DECLARATION_LIST'); | 
					
						
							|  |  |  |   foreach ($constants as $constant_list) { | 
					
						
							|  |  |  |     foreach ($constant_list->getChildren() as $constant) { | 
					
						
							|  |  |  |       $constant_name = $constant->getChildByIndex(0); | 
					
						
							|  |  |  |       print_symbol($file, 'constant', $constant_name); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   foreach ($scopes as $scope) { | 
					
						
							| 
									
										
										
										
											2015-05-03 10:11:17 +10:00
										 |  |  |     // This prints duplicate symbols in the case of nested classes.
 | 
					
						
							|  |  |  |     // Luckily, PHP doesn't allow those.
 | 
					
						
							| 
									
										
										
										
											2012-08-08 17:06:05 -07:00
										 |  |  |     list($class, $class_name) = $scope; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $consts = $class->selectDescendantsOfType( | 
					
						
							|  |  |  |       'n_CLASS_CONSTANT_DECLARATION_LIST'); | 
					
						
							|  |  |  |     foreach ($consts as $const_list) { | 
					
						
							|  |  |  |       foreach ($const_list->getChildren() as $const) { | 
					
						
							|  |  |  |         $const_name = $const->getChildByIndex(0); | 
					
						
							|  |  |  |         print_symbol($file, 'class_const', $const_name, $class_name); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $members = $class->selectDescendantsOfType( | 
					
						
							|  |  |  |       'n_CLASS_MEMBER_DECLARATION_LIST'); | 
					
						
							|  |  |  |     foreach ($members as $member_list) { | 
					
						
							|  |  |  |       foreach ($member_list->getChildren() as $member) { | 
					
						
							|  |  |  |         if ($member->getTypeName() == 'n_CLASS_MEMBER_MODIFIER_LIST') { | 
					
						
							|  |  |  |           continue; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         $member_name = $member->getChildByIndex(0); | 
					
						
							|  |  |  |         print_symbol($file, 'member', $member_name, $class_name); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $methods = $class->selectDescendantsOfType('n_METHOD_DECLARATION'); | 
					
						
							|  |  |  |     foreach ($methods as $method) { | 
					
						
							|  |  |  |       $method_name = $method->getChildByIndex(2); | 
					
						
							|  |  |  |       print_symbol($file, 'method', $method_name, $class_name); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-09-04 18:24:46 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-03 10:11:17 +10:00
										 |  |  | function print_symbol($file, $type, XHPASTNode $node, $context = null) { | 
					
						
							| 
									
										
										
										
											2011-09-04 18:24:46 -07:00
										 |  |  |   $parts = array( | 
					
						
							| 
									
										
										
										
											2012-08-08 17:06:05 -07:00
										 |  |  |     $context ? $context->getConcreteString() : '', | 
					
						
							| 
									
										
										
										
											2015-05-03 10:11:17 +10:00
										 |  |  |     // Variable tokens are `$name`, not just `name`, so strip the "$"" off of
 | 
					
						
							| 
									
										
										
										
											2012-08-08 17:06:05 -07:00
										 |  |  |     // class field names
 | 
					
						
							| 
									
										
										
										
											2015-05-03 10:11:17 +10:00
										 |  |  |     ltrim($node->getConcreteString(), '$'), | 
					
						
							| 
									
										
										
										
											2011-09-04 18:24:46 -07:00
										 |  |  |     $type, | 
					
						
							|  |  |  |     'php', | 
					
						
							| 
									
										
										
										
											2015-05-03 10:11:17 +10:00
										 |  |  |     $node->getLineNumber(), | 
					
						
							| 
									
										
										
										
											2011-09-04 18:24:46 -07:00
										 |  |  |     '/'.ltrim($file, './'), | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  |   echo implode(' ', $parts)."\n"; | 
					
						
							|  |  |  | } |