1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-11-25 16:22:42 +01:00

Add a "SymbolEngine" to support top-level ref resolution by symbol

Summary:
Ref T13490. I'm continuing to move toward modernizing "amend", which needs to load some objects by symbol at top level.

Add an API to support this.

Test Plan: Added an API caller to "arc inspect", ran it and hit the new code. Things seemed to work.

Maniphest Tasks: T13490

Differential Revision: https://secure.phabricator.com/D21094
This commit is contained in:
epriestley 2020-04-12 10:52:00 -07:00
parent 5fc50c226a
commit ff4c1e7c81
8 changed files with 165 additions and 7 deletions

View file

@ -437,6 +437,7 @@ phutil_register_library_map(array(
'ArcanistSubversionAPI' => 'repository/api/ArcanistSubversionAPI.php',
'ArcanistSubversionWorkingCopy' => 'workingcopy/ArcanistSubversionWorkingCopy.php',
'ArcanistSummaryLintRenderer' => 'lint/renderer/ArcanistSummaryLintRenderer.php',
'ArcanistSymbolEngine' => 'ref/symbol/ArcanistSymbolEngine.php',
'ArcanistSymbolRef' => 'ref/symbol/ArcanistSymbolRef.php',
'ArcanistSyntaxErrorXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistSyntaxErrorXHPASTLinterRule.php',
'ArcanistSystemConfigurationSource' => 'config/source/ArcanistSystemConfigurationSource.php',
@ -1381,7 +1382,10 @@ phutil_register_library_map(array(
'ArcanistReusedIteratorXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistRevertWorkflow' => 'ArcanistWorkflow',
'ArcanistRevisionCommitMessageHardpointQuery' => 'ArcanistWorkflowHardpointQuery',
'ArcanistRevisionRef' => 'ArcanistRef',
'ArcanistRevisionRef' => array(
'ArcanistRef',
'ArcanistDisplayRefInterface',
),
'ArcanistRevisionRefSource' => 'Phobject',
'ArcanistRevisionSymbolHardpointQuery' => 'ArcanistWorkflowHardpointQuery',
'ArcanistRevisionSymbolRef' => 'ArcanistSymbolRef',
@ -1417,6 +1421,7 @@ phutil_register_library_map(array(
'ArcanistSubversionAPI' => 'ArcanistRepositoryAPI',
'ArcanistSubversionWorkingCopy' => 'ArcanistWorkingCopy',
'ArcanistSummaryLintRenderer' => 'ArcanistLintRenderer',
'ArcanistSymbolEngine' => 'Phobject',
'ArcanistSymbolRef' => 'ArcanistRef',
'ArcanistSyntaxErrorXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistSystemConfigurationSource' => 'ArcanistFilesystemConfigurationSource',

View file

@ -76,6 +76,17 @@ final class ArcanistGitCommitSymbolCommitHardpointQuery
$results[$key] = $hash_map[$symbol];
}
foreach ($results as $key => $result) {
if ($result === null) {
continue;
}
$ref = id(new ArcanistCommitRef())
->setCommitHash($result);
$results[$key] = $ref;
}
yield $this->yieldMap($results);
}

View file

@ -1,7 +1,9 @@
<?php
final class ArcanistRevisionRef
extends ArcanistRef {
extends ArcanistRef
implements
ArcanistDisplayRefInterface {
const HARDPOINT_COMMITMESSAGE = 'ref.revision.commitmessage';
@ -77,4 +79,12 @@ final class ArcanistRevisionRef
return $this->sources;
}
public function getDisplayRefObjectName() {
return $this->getMonogram();
}
public function getDisplayRefTitle() {
return $this->getName();
}
}

View file

@ -0,0 +1,78 @@
<?php
final class ArcanistSymbolEngine
extends Phobject {
private $workflow;
private $refs = array();
public function setWorkflow($workflow) {
$this->workflow = $workflow;
return $this;
}
public function getWorkflow() {
return $this->workflow;
}
public function loadRevisionForSymbol($symbol) {
$refs = $this->loadRevisionsForSymbols(array($symbol));
return head($refs)->getObject();
}
public function loadRevisionsForSymbols(array $symbols) {
return $this->loadRefsForSymbols(
new ArcanistRevisionSymbolRef(),
$symbols);
}
public function loadUserForSymbol($symbol) {
$refs = $this->loadUsersForSymbols(array($symbol));
return head($refs)->getObject();
}
public function loadUsersForSymbols(array $symbols) {
return $this->loadRefsForSymbols(
new ArcanistUserSymbolRef(),
$symbols);
}
public function loadCommitForSymbol($symbol) {
$refs = $this->loadCommitsForSymbols(array($symbol));
return head($refs)->getObject();
}
public function loadCommitsForSymbols(array $symbols) {
return $this->loadRefsForSymbols(
new ArcanistCommitSymbolRef(),
$symbols);
}
public function loadRefsForSymbols(
ArcanistSymbolRef $template,
array $symbols) {
$refs = array();
$load_refs = array();
foreach ($symbols as $symbol) {
$ref = id(clone $template)
->setSymbol($symbol);
$ref_key = $ref->getSymbolEngineCacheKey();
if (!isset($this->refs[$ref_key])) {
$this->refs[$ref_key] = $ref;
$load_refs[] = $ref;
}
$refs[$symbol] = $ref;
}
$workflow = $this->getWorkflow();
if ($load_refs) {
$workflow->loadHardpoints($refs, ArcanistSymbolRef::HARDPOINT_OBJECT);
}
return $refs;
}
}

View file

@ -4,6 +4,7 @@ abstract class ArcanistSymbolRef
extends ArcanistRef {
private $symbol;
private $cacheKey;
const HARDPOINT_OBJECT = 'ref.symbol.object';
@ -24,6 +25,27 @@ abstract class ArcanistSymbolRef
return $this->symbol;
}
final public function getSymbolEngineCacheKey() {
if ($this->cacheKey === null) {
$parts = array();
$parts[] = sprintf('class(%s)', get_class($this));
foreach ($this->newCacheKeyParts() as $part) {
$parts[] = $part;
}
$parts[] = $this->getSymbol();
$this->cacheKey = implode('.', $parts);
}
return $this->cacheKey;
}
protected function newCacheKeyParts() {
return array();
}
final public function attachObject(ArcanistRef $object) {
return $this->attachHardpoint(self::HARDPOINT_OBJECT, $object);
}
@ -36,6 +58,4 @@ abstract class ArcanistSymbolRef
return $symbol;
}
}

View file

@ -34,8 +34,6 @@ final class ArcanistUserRef
}
public function getRealName() {
var_dump($this->parameters);
return idxv($this->parameters, array('fields', 'realName'));
}

View file

@ -14,6 +14,12 @@ final class ArcanistUserSymbolRef
return pht('User Symbol "%s"', $this->getSymbol());
}
protected function newCacheKeyParts() {
return array(
sprintf('type(%s)', $this->type),
);
}
public function getSymbolType() {
return $this->type;
}

View file

@ -76,7 +76,9 @@ abstract class ArcanistWorkflow extends Phobject {
private $configurationEngine;
private $configurationSourceList;
private $viewer;
private $hardpointEngine;
private $symbolEngine;
private $promptMap;
final public function setToolset(ArcanistToolset $toolset) {
@ -2298,7 +2300,7 @@ abstract class ArcanistWorkflow extends Phobject {
->setExecutableFuture($future);
}
final protected function loadHardpoints(
final public function loadHardpoints(
$objects,
$requests) {
@ -2401,4 +2403,32 @@ abstract class ArcanistWorkflow extends Phobject {
return clone $prompt;
}
final protected function getSymbolEngine() {
if ($this->symbolEngine === null) {
$this->symbolEngine = $this->newSymbolEngine();
}
return $this->symbolEngine;
}
private function newSymbolEngine() {
return id(new ArcanistSymbolEngine())
->setWorkflow($this);
}
final protected function getViewer() {
if (!$this->viewer) {
$viewer = $this->getSymbolEngine()
->loadUserForSymbol('viewer()');
// TODO: Deal with anonymous stuff.
if (!$viewer) {
throw new Exception(pht('No viewer!'));
}
$this->viewer = $viewer;
}
return $this->viewer;
}
}