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:
parent
1c98ca7042
commit
a8d6af0f42
3 changed files with 50 additions and 34 deletions
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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',
|
||||||
'',
|
'',
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue