1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-29 02:02:41 +01:00

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
This commit is contained in:
Alan Huang 2012-08-07 09:28:49 -07:00
parent 1c98ca7042
commit a8d6af0f42
3 changed files with 50 additions and 34 deletions

View file

@ -30,19 +30,12 @@ EOSYNOPSIS
$args->parseStandardArguments(); $args->parseStandardArguments();
$args->parse( $args->parse(
array( array(
array(
'name' => 'ignore-duplicates',
'help' => 'Ignore duplicate symbols, choosing one at random. By '.
'default, this script throws if given duplicate '.
'symbols.',
),
array( array(
'name' => 'more', 'name' => 'more',
'wildcard' => true, 'wildcard' => true,
), ),
)); ));
$ignore_duplicates = $args->getArg('ignore-duplicates');
$more = $args->getArg('more'); $more = $args->getArg('more');
if (count($more) !== 1) { if (count($more) !== 1) {
$args->printHelpAndExit(); $args->printHelpAndExit();
@ -66,42 +59,39 @@ $input = file_get_contents('php://stdin');
$input = trim($input); $input = trim($input);
$input = explode("\n", $input); $input = explode("\n", $input);
$map = array();
$symbols = array(); $symbols = array();
foreach ($input as $key => $line) { foreach ($input as $key => $line) {
$line_no = $key + 1; $line_no = $key + 1;
$matches = null; $matches = null;
$ok = preg_match('/^([^ ]+) ([^ ]+) ([^ ]+) (\d+) (.*)$/', $line, $matches); $ok = preg_match(
'/^((?P<context>[^ ]+)? )?(?P<name>[^ ]+) (?P<type>[^ ]+) '.
'(?P<lang>[^ ]+) (?P<line>\d+) (?P<path>.*)$/',
$line,
$matches);
if (!$ok) { if (!$ok) {
throw new Exception( throw new Exception(
"Line #{$line_no} of input is invalid. Expected five space-delimited ". "Line #{$line_no} of input is invalid. Expected five or six ".
"fields: symbol name, symbol type, symbol language, line number, path. ". "space-delimited fields: maybe symbol context, symbol name, symbol ".
"type, symbol language, line number, path. ".
"For example:\n\n". "For example:\n\n".
"idx function php 13 /path/to/some/file.php\n\n". "idx function php 13 /path/to/some/file.php\n\n".
"Actual line was:\n\n". "Actual line was:\n\n".
"{$line}"); "{$line}");
} }
list($all, $name, $type, $lang, $line_number, $path) = $matches; if (empty($matches['context'])) {
$matches['context'] = '';
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 { $context = $matches['context'];
$map[$name][$type][$lang] = $key; $name = $matches['name'];
$type = $matches['type'];
$lang = $matches['lang'];
$line_number = $matches['line'];
$path = $matches['path'];
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) { if (strlen($name) > 128) {
@ -130,6 +120,7 @@ foreach ($input as $key => $line) {
} }
$symbols[] = array( $symbols[] = array(
'ctxt' => $context,
'name' => $name, 'name' => $name,
'type' => $type, 'type' => $type,
'lang' => $lang, 'lang' => $lang,
@ -150,8 +141,9 @@ $sql = array();
foreach ($symbols as $dict) { foreach ($symbols as $dict) {
$sql[] = qsprintf( $sql[] = qsprintf(
$conn_w, $conn_w,
'(%d, %s, %s, %s, %d, %d)', '(%d, %s, %s, %s, %s, %d, %d)',
$project->getID(), $project->getID(),
$dict['ctxt'],
$dict['name'], $dict['name'],
$dict['type'], $dict['type'],
$dict['lang'], $dict['lang'],
@ -171,8 +163,8 @@ foreach (array_chunk($sql, 128) as $chunk) {
queryfx( queryfx(
$conn_w, $conn_w,
'INSERT INTO %T 'INSERT INTO %T
(arcanistProjectID, symbolName, symbolType, symbolLanguage, lineNumber, (arcanistProjectID, symbolContext, symbolName, symbolType,
pathID) VALUES %Q', symbolLanguage, lineNumber, pathID) VALUES %Q',
$symbol->getTableName(), $symbol->getTableName(),
implode(', ', $chunk)); implode(', ', $chunk));
} }

View file

@ -31,6 +31,10 @@ final class DiffusionSymbolController extends DiffusionController {
$query = new DiffusionSymbolQuery(); $query = new DiffusionSymbolQuery();
$query->setName($this->name); $query->setName($this->name);
if ($request->getStr('context') !== null) {
$query->setContext($request->getStr('context'));
}
if ($request->getStr('type')) { if ($request->getStr('type')) {
$query->setType($request->getStr('type')); $query->setType($request->getStr('type'));
} }
@ -122,6 +126,7 @@ final class DiffusionSymbolController extends DiffusionController {
$rows[] = array( $rows[] = array(
phutil_escape_html($symbol->getSymbolType()), phutil_escape_html($symbol->getSymbolType()),
phutil_escape_html($symbol->getSymbolContext()),
phutil_escape_html($symbol->getSymbolName()), phutil_escape_html($symbol->getSymbolName()),
phutil_escape_html($symbol->getSymbolLanguage()), phutil_escape_html($symbol->getSymbolLanguage()),
phutil_escape_html($project_name), phutil_escape_html($project_name),
@ -133,6 +138,7 @@ final class DiffusionSymbolController extends DiffusionController {
$table->setHeaders( $table->setHeaders(
array( array(
'Type', 'Type',
'Context',
'Name', 'Name',
'Language', 'Language',
'Project', 'Project',
@ -140,6 +146,7 @@ final class DiffusionSymbolController extends DiffusionController {
)); ));
$table->setColumnClasses( $table->setColumnClasses(
array( array(
'',
'', '',
'pri', 'pri',
'', '',

View file

@ -29,6 +29,7 @@
*/ */
final class DiffusionSymbolQuery extends PhabricatorOffsetPagedQuery { final class DiffusionSymbolQuery extends PhabricatorOffsetPagedQuery {
private $context;
private $namePrefix; private $namePrefix;
private $name; private $name;
@ -44,6 +45,15 @@ final class DiffusionSymbolQuery extends PhabricatorOffsetPagedQuery {
/* -( Configuring the Query )---------------------------------------------- */ /* -( Configuring the Query )---------------------------------------------- */
/**
* @task config
*/
public function setContext($context) {
$this->context = $context;
return $this;
}
/** /**
* @task config * @task config
*/ */
@ -180,6 +190,13 @@ final class DiffusionSymbolQuery extends PhabricatorOffsetPagedQuery {
private function buildWhereClause($conn_r) { private function buildWhereClause($conn_r) {
$where = array(); $where = array();
if (isset($this->context)) {
$where[] = qsprintf(
$conn_r,
'symbolContext = %s',
$this->context);
}
if ($this->name) { if ($this->name) {
$where[] = qsprintf( $where[] = qsprintf(
$conn_r, $conn_r,