From a8d6af0f42a8bf27ca6f66ed9d7e49b95d1df4ab Mon Sep 17 00:00:00 2001 From: Alan Huang Date: Tue, 7 Aug 2012 09:28:49 -0700 Subject: [PATCH] Infrastructure changes to support scoped symbols Summary: - import_project_symbols supports an optional extra field, which is the context of the symbol. - Symbol query can take a symbol argument, either as a parameter or a URL component (so you can now jump nav to `s Zerg/rush`, for example). - Conduit method not yet updated. Will do that later. NOTE: Not providing a context is distinct from providing an empty context, because an empty context stands for top-level context, i.e. functions and classes for PHP. It will not find class methods, etc. It is possible that we should use some weird token that could not normally be a context name to stand in for empty context. Test Plan: Do a bunch of symbol searches. Reviewers: epriestley Reviewed By: epriestley CC: nh, aran, Korvin Maniphest Tasks: T1602 Differential Revision: https://secure.phabricator.com/D3148 --- scripts/symbols/import_project_symbols.php | 60 ++++++++----------- .../controller/DiffusionSymbolController.php | 7 +++ .../diffusion/query/DiffusionSymbolQuery.php | 17 ++++++ 3 files changed, 50 insertions(+), 34 deletions(-) diff --git a/scripts/symbols/import_project_symbols.php b/scripts/symbols/import_project_symbols.php index 8aef684a40..4ff2a3f2cd 100755 --- a/scripts/symbols/import_project_symbols.php +++ b/scripts/symbols/import_project_symbols.php @@ -30,19 +30,12 @@ EOSYNOPSIS $args->parseStandardArguments(); $args->parse( array( - array( - 'name' => 'ignore-duplicates', - 'help' => 'Ignore duplicate symbols, choosing one at random. By '. - 'default, this script throws if given duplicate '. - 'symbols.', - ), array( 'name' => 'more', 'wildcard' => true, ), )); -$ignore_duplicates = $args->getArg('ignore-duplicates'); $more = $args->getArg('more'); if (count($more) !== 1) { $args->printHelpAndExit(); @@ -66,42 +59,39 @@ $input = file_get_contents('php://stdin'); $input = trim($input); $input = explode("\n", $input); -$map = array(); $symbols = array(); foreach ($input as $key => $line) { $line_no = $key + 1; $matches = null; - $ok = preg_match('/^([^ ]+) ([^ ]+) ([^ ]+) (\d+) (.*)$/', $line, $matches); + $ok = preg_match( + '/^((?P[^ ]+)? )?(?P[^ ]+) (?P[^ ]+) '. + '(?P[^ ]+) (?P\d+) (?P.*)$/', + $line, + $matches); if (!$ok) { throw new Exception( - "Line #{$line_no} of input is invalid. Expected five space-delimited ". - "fields: symbol name, symbol type, symbol language, line number, path. ". + "Line #{$line_no} of input is invalid. Expected five or six ". + "space-delimited fields: maybe symbol context, symbol name, symbol ". + "type, symbol language, line number, path. ". "For example:\n\n". "idx function php 13 /path/to/some/file.php\n\n". "Actual line was:\n\n". "{$line}"); } - list($all, $name, $type, $lang, $line_number, $path) = $matches; + if (empty($matches['context'])) { + $matches['context'] = ''; + } + $context = $matches['context']; + $name = $matches['name']; + $type = $matches['type']; + $lang = $matches['lang']; + $line_number = $matches['line']; + $path = $matches['path']; - if (isset($map[$name][$type][$lang])) { - if ($ignore_duplicates) { - echo "Ignoring duplicate definition of '{$name}' on line {$line_no}.\n"; - } else { - $previous = $map[$name][$type][$lang] + 1; - throw new Exception( - "Line #{$line_no} of input is invalid. It specifies a duplicate ". - "symbol (same name, language, and type) which has already been ". - "defined elsewhere. You must preprocess the symbol list to remove ". - "duplicates and choose exactly one master definition for each ". - "symbol, or specify --ignore-duplicates. This symbol was previously ". - "defined on line #{$previous}.\n\n". - "Line #{$line_no}:\n". - $line."\n\n". - "Line #{$previous}:\n". - $input[$previous - 1]); - } - } else { - $map[$name][$type][$lang] = $key; + if (strlen($context) > 128) { + throw new Exception( + "Symbol context '{$context}' defined on line #{$line_no} is too long, ". + "maximum symbol context length is 128 characters."); } if (strlen($name) > 128) { @@ -130,6 +120,7 @@ foreach ($input as $key => $line) { } $symbols[] = array( + 'ctxt' => $context, 'name' => $name, 'type' => $type, 'lang' => $lang, @@ -150,8 +141,9 @@ $sql = array(); foreach ($symbols as $dict) { $sql[] = qsprintf( $conn_w, - '(%d, %s, %s, %s, %d, %d)', + '(%d, %s, %s, %s, %s, %d, %d)', $project->getID(), + $dict['ctxt'], $dict['name'], $dict['type'], $dict['lang'], @@ -171,8 +163,8 @@ foreach (array_chunk($sql, 128) as $chunk) { queryfx( $conn_w, 'INSERT INTO %T - (arcanistProjectID, symbolName, symbolType, symbolLanguage, lineNumber, - pathID) VALUES %Q', + (arcanistProjectID, symbolContext, symbolName, symbolType, + symbolLanguage, lineNumber, pathID) VALUES %Q', $symbol->getTableName(), implode(', ', $chunk)); } diff --git a/src/applications/diffusion/controller/DiffusionSymbolController.php b/src/applications/diffusion/controller/DiffusionSymbolController.php index 42caa0aea6..74de67ead0 100644 --- a/src/applications/diffusion/controller/DiffusionSymbolController.php +++ b/src/applications/diffusion/controller/DiffusionSymbolController.php @@ -31,6 +31,10 @@ final class DiffusionSymbolController extends DiffusionController { $query = new DiffusionSymbolQuery(); $query->setName($this->name); + if ($request->getStr('context') !== null) { + $query->setContext($request->getStr('context')); + } + if ($request->getStr('type')) { $query->setType($request->getStr('type')); } @@ -122,6 +126,7 @@ final class DiffusionSymbolController extends DiffusionController { $rows[] = array( phutil_escape_html($symbol->getSymbolType()), + phutil_escape_html($symbol->getSymbolContext()), phutil_escape_html($symbol->getSymbolName()), phutil_escape_html($symbol->getSymbolLanguage()), phutil_escape_html($project_name), @@ -133,6 +138,7 @@ final class DiffusionSymbolController extends DiffusionController { $table->setHeaders( array( 'Type', + 'Context', 'Name', 'Language', 'Project', @@ -140,6 +146,7 @@ final class DiffusionSymbolController extends DiffusionController { )); $table->setColumnClasses( array( + '', '', 'pri', '', diff --git a/src/applications/diffusion/query/DiffusionSymbolQuery.php b/src/applications/diffusion/query/DiffusionSymbolQuery.php index 25b6e49a1a..c8af76bdc8 100644 --- a/src/applications/diffusion/query/DiffusionSymbolQuery.php +++ b/src/applications/diffusion/query/DiffusionSymbolQuery.php @@ -29,6 +29,7 @@ */ final class DiffusionSymbolQuery extends PhabricatorOffsetPagedQuery { + private $context; private $namePrefix; private $name; @@ -44,6 +45,15 @@ final class DiffusionSymbolQuery extends PhabricatorOffsetPagedQuery { /* -( Configuring the Query )---------------------------------------------- */ + /** + * @task config + */ + public function setContext($context) { + $this->context = $context; + return $this; + } + + /** * @task config */ @@ -180,6 +190,13 @@ final class DiffusionSymbolQuery extends PhabricatorOffsetPagedQuery { private function buildWhereClause($conn_r) { $where = array(); + if (isset($this->context)) { + $where[] = qsprintf( + $conn_r, + 'symbolContext = %s', + $this->context); + } + if ($this->name) { $where[] = qsprintf( $conn_r,