Page MenuHomePhabricator

D13036.id31480.diff
No OneTemporary

D13036.id31480.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -507,6 +507,8 @@
'DiffusionEmptyResultView' => 'applications/diffusion/view/DiffusionEmptyResultView.php',
'DiffusionExistsQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionExistsQueryConduitAPIMethod.php',
'DiffusionExternalController' => 'applications/diffusion/controller/DiffusionExternalController.php',
+ 'DiffusionExternalSymbolQuery' => 'applications/diffusion/symbol/DiffusionExternalSymbolQuery.php',
+ 'DiffusionExternalSymbolsSource' => 'applications/diffusion/symbol/DiffusionExternalSymbolsSource.php',
'DiffusionFileContent' => 'applications/diffusion/data/DiffusionFileContent.php',
'DiffusionFileContentQuery' => 'applications/diffusion/query/filecontent/DiffusionFileContentQuery.php',
'DiffusionFileContentQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionFileContentQueryConduitAPIMethod.php',
@@ -2955,6 +2957,7 @@
'PhortuneSubscriptionWorker' => 'applications/phortune/worker/PhortuneSubscriptionWorker.php',
'PhortuneTestPaymentProvider' => 'applications/phortune/provider/PhortuneTestPaymentProvider.php',
'PhortuneWePayPaymentProvider' => 'applications/phortune/provider/PhortuneWePayPaymentProvider.php',
+ 'PhpExternalSymbolsSource' => 'applications/diffusion/symbol/PhpExternalSymbolsSource.php',
'PhragmentBrowseController' => 'applications/phragment/controller/PhragmentBrowseController.php',
'PhragmentCanCreateCapability' => 'applications/phragment/capability/PhragmentCanCreateCapability.php',
'PhragmentConduitAPIMethod' => 'applications/phragment/conduit/PhragmentConduitAPIMethod.php',
@@ -3097,6 +3100,7 @@
'ProjectRemarkupRule' => 'applications/project/remarkup/ProjectRemarkupRule.php',
'ProjectRemarkupRuleTestCase' => 'applications/project/remarkup/__tests__/ProjectRemarkupRuleTestCase.php',
'ProjectReplyHandler' => 'applications/project/mail/ProjectReplyHandler.php',
+ 'PythonExternalSymbolsSource' => 'applications/diffusion/symbol/PythonExternalSymbolsSource.php',
'QueryFormattingTestCase' => 'infrastructure/storage/__tests__/QueryFormattingTestCase.php',
'ReleephAuthorFieldSpecification' => 'applications/releeph/field/specification/ReleephAuthorFieldSpecification.php',
'ReleephBranch' => 'applications/releeph/storage/ReleephBranch.php',
@@ -6479,6 +6483,7 @@
'PhortuneSubscriptionWorker' => 'PhabricatorWorker',
'PhortuneTestPaymentProvider' => 'PhortunePaymentProvider',
'PhortuneWePayPaymentProvider' => 'PhortunePaymentProvider',
+ 'PhpExternalSymbolsSource' => 'DiffusionExternalSymbolsSource',
'PhragmentBrowseController' => 'PhragmentController',
'PhragmentCanCreateCapability' => 'PhabricatorPolicyCapability',
'PhragmentConduitAPIMethod' => 'ConduitAPIMethod',
@@ -6663,6 +6668,7 @@
'ProjectRemarkupRule' => 'PhabricatorObjectRemarkupRule',
'ProjectRemarkupRuleTestCase' => 'PhabricatorTestCase',
'ProjectReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler',
+ 'PythonExternalSymbolsSource' => 'DiffusionExternalSymbolsSource',
'QueryFormattingTestCase' => 'PhabricatorTestCase',
'ReleephAuthorFieldSpecification' => 'ReleephFieldSpecification',
'ReleephBranch' => array(
diff --git a/src/applications/diffusion/controller/DiffusionSymbolController.php b/src/applications/diffusion/controller/DiffusionSymbolController.php
--- a/src/applications/diffusion/controller/DiffusionSymbolController.php
+++ b/src/applications/diffusion/controller/DiffusionSymbolController.php
@@ -12,7 +12,7 @@
->setViewer($user)
->setName($this->name);
- if ($request->getStr('context') !== null) {
+ if ($request->getStr('context')) {
$query->setContext($request->getStr('context'));
}
@@ -47,63 +47,69 @@
$symbols = $query->execute();
- // For PHP builtins, jump to php.net documentation.
- if ($request->getBool('jump') && count($symbols) == 0) {
- if ($request->getStr('lang', 'php') == 'php') {
- if ($request->getStr('type', 'function') == 'function') {
- $functions = get_defined_functions();
- if (in_array($this->name, $functions['internal'])) {
- return id(new AphrontRedirectResponse())
- ->setIsExternal(true)
- ->setURI('http://www.php.net/function.'.$this->name);
- }
- }
- if ($request->getStr('type', 'class') == 'class') {
- if (class_exists($this->name, false) ||
- interface_exists($this->name, false)) {
- if (id(new ReflectionClass($this->name))->isInternal()) {
- return id(new AphrontRedirectResponse())
- ->setIsExternal(true)
- ->setURI('http://www.php.net/class.'.$this->name);
- }
- }
- }
- }
+
+
+ $external_query = id(new DiffusionExternalSymbolQuery())
+ ->withNames(array($this->name));
+
+ if ($request->getStr('context')) {
+ $external_query->withContexts(array($request->getStr('context')));
+ }
+
+ if ($request->getStr('type')) {
+ $external_query->withTypes(array($request->getStr('type')));
+ }
+
+ if ($request->getStr('lang')) {
+ $external_query->withLanguages(array($request->getStr('lang')));
+ }
+
+ $external_sources = id(new PhutilSymbolLoader())
+ ->setAncestorClass('DiffusionExternalSymbolsSource')
+ ->loadObjects();
+ $results = array($symbols);
+ foreach ($external_sources as $source) {
+ $results[] = $source->lookupSymbol($external_query);
+ }
+ $symbols = array_mergev($results);
+
+ if ($request->getBool('jump') && count($symbols) == 1) {
+ // If this is a clickthrough from Differential, just jump them
+ // straight to the target if we got a single hit.
+ $symbol = head($symbols);
+ return id(new AphrontRedirectResponse())
+ ->setIsExternal($symbol->isExternal())
+ ->setURI($symbol->getURI());
}
$rows = array();
foreach ($symbols as $symbol) {
- $file = $symbol->getPath();
- $line = $symbol->getLineNumber();
+ $href = $symbol->getURI();
- $repo = $symbol->getRepository();
- if ($repo) {
- $href = $symbol->getURI();
-
- if ($request->getBool('jump') && count($symbols) == 1) {
- // If this is a clickthrough from Differential, just jump them
- // straight to the target if we got a single hit.
- return id(new AphrontRedirectResponse())->setURI($href);
- }
+ if ($symbol->isExternal()) {
+ $source = $symbol->getSource();
+ $location = $symbol->getLocation();
+ } else {
+ $repo = $symbol->getRepository();
+ $file = $symbol->getPath();
+ $line = $symbol->getLineNumber();
- $location = phutil_tag(
- 'a',
- array(
- 'href' => $href,
- ),
- $file.':'.$line);
- } else if ($file) {
+ $source = $repo->getMonogram();
$location = $file.':'.$line;
- } else {
- $location = '?';
}
+ $location = phutil_tag(
+ 'a',
+ array(
+ 'href' => $href,
+ ),
+ $location);
$rows[] = array(
$symbol->getSymbolType(),
$symbol->getSymbolContext(),
$symbol->getSymbolName(),
$symbol->getSymbolLanguage(),
- $repo->getMonogram(),
+ $source,
$location,
);
}
@@ -115,8 +121,8 @@
pht('Context'),
pht('Name'),
pht('Language'),
- pht('Repository'),
- pht('File'),
+ pht('Source'),
+ pht('Location'),
));
$table->setColumnClasses(
array(
diff --git a/src/applications/diffusion/symbol/DiffusionExternalSymbolQuery.php b/src/applications/diffusion/symbol/DiffusionExternalSymbolQuery.php
new file mode 100644
--- /dev/null
+++ b/src/applications/diffusion/symbol/DiffusionExternalSymbolQuery.php
@@ -0,0 +1,40 @@
+<?php
+
+final class DiffusionExternalSymbolQuery {
+ private $languages = array();
+ private $types = array();
+ private $names = array();
+ private $contexts = array();
+
+ public function withLanguages(array $languages) {
+ $this->languages = $languages;
+ return $this;
+ }
+ public function withTypes(array $types) {
+ $this->types = $types;
+ return $this;
+ }
+ public function withNames(array $names) {
+ $this->names = $names;
+ return $this;
+ }
+ public function withContexts(array $contexts) {
+ $this->contexts = $contexts;
+ return $this;
+ }
+
+
+ public function getLanguages() {
+ return $this->languages;
+ }
+ public function getTypes() {
+ return $this->types;
+ }
+ public function getNames() {
+ return $this->names;
+ }
+ public function getContexts() {
+ return $this->contexts;
+ }
+
+}
diff --git a/src/applications/diffusion/symbol/DiffusionExternalSymbolsSource.php b/src/applications/diffusion/symbol/DiffusionExternalSymbolsSource.php
new file mode 100644
--- /dev/null
+++ b/src/applications/diffusion/symbol/DiffusionExternalSymbolsSource.php
@@ -0,0 +1,15 @@
+<?php
+
+abstract class DiffusionExternalSymbolsSource {
+
+ /**
+ * @return list of PhabricatorRepositorySymbol
+ */
+ abstract public function lookupSymbol(DiffusionExternalSymbolQuery $query);
+
+ protected function buildExternalSymbol() {
+ return id(new PhabricatorRepositorySymbol())
+ ->setIsExternal(true)
+ ->makeEphemeral();
+ }
+}
diff --git a/src/applications/diffusion/symbol/PhpExternalSymbolsSource.php b/src/applications/diffusion/symbol/PhpExternalSymbolsSource.php
new file mode 100644
--- /dev/null
+++ b/src/applications/diffusion/symbol/PhpExternalSymbolsSource.php
@@ -0,0 +1,49 @@
+<?php
+
+final class PhpExternalSymbolsSource extends DiffusionExternalSymbolsSource {
+
+ public function lookupSymbol(DiffusionExternalSymbolQuery $query) {
+ $langs = $query->getLanguages();
+ if ($langs && !in_array('php', $langs)) {
+ return array();
+ }
+
+ $names = $query->getNames();
+ $symbols = array();
+
+ $types = $query->getTypes();
+ if (!$types || in_array('function', $types)) {
+ $functions = get_defined_functions();
+ $functions = $functions['internal'];
+
+ foreach ($names as $name) {
+ if (in_array($name, $functions)) {
+ $symbols[] = $this->buildExternalSymbol()
+ ->setSymbolName($name)
+ ->setSymbolType('function')
+ ->setSource('PHP')
+ ->setLocation('Manual at php.net')
+ ->setSymbolLanguage('PHP')
+ ->setExternalURI('http://www.php.net/function.'.$name);
+ }
+ }
+ }
+ if (!$types || in_array('class', $types)) {
+ foreach ($names as $name) {
+ if (class_exists($name, false) || interface_exists($name, false)) {
+ if (id(new ReflectionClass($name))->isInternal()) {
+ $symbols[] = $this->buildExternalSymbol()
+ ->setSymbolName($name)
+ ->setSymbolType('class')
+ ->setSource('PHP')
+ ->setLocation('Manual at php.net')
+ ->setSymbolLanguage('PHP')
+ ->setExternalURI('http://www.php.net/class.'.$name);
+ }
+ }
+ }
+ }
+
+ return $symbols;
+ }
+}
diff --git a/src/applications/diffusion/symbol/PythonExternalSymbolsSource.php b/src/applications/diffusion/symbol/PythonExternalSymbolsSource.php
new file mode 100644
--- /dev/null
+++ b/src/applications/diffusion/symbol/PythonExternalSymbolsSource.php
@@ -0,0 +1,135 @@
+<?php
+
+final class PythonExternalSymbolsSource extends DiffusionExternalSymbolsSource {
+
+ public function lookupSymbol(DiffusionExternalSymbolQuery $query) {
+ $langs = $query->getLanguages();
+ if ($langs && !array_intersect(array('py', 'python'), $langs)) {
+ return array();
+ }
+
+ $names = $query->getNames();
+ $symbols = array();
+
+ $types = $query->getTypes();
+ if ($types && !in_array('builtin', $types)) {
+ return $symbols;
+ }
+
+ foreach ($names as $name) {
+ if (idx(self::$python2Builtins, $name)) {
+ $symbols[] = $this->buildExternalSymbol()
+ ->setSymbolName($name)
+ ->setSymbolType('builtin')
+ ->setSource('Standard Library')
+ ->setLocation('The Python 2 Standard Library')
+ ->setSymbolLanguage('Python')
+ ->setExternalURI(
+ 'https://docs.python.org/2/library/functions.html#'.$name);
+ }
+ if (idx(self::$python3Builtins, $name)) {
+ $symbols[] = $this->buildExternalSymbol()
+ ->setSymbolName($name)
+ ->setSymbolType('builtin')
+ ->setSource('Standard Library')
+ ->setLocation('The Python 3 Standard Library')
+ ->setSymbolLanguage('Python')
+ ->setExternalURI(
+ 'https://docs.python.org/3/library/functions.html#'.$name);
+ }
+ }
+ return $symbols;
+ }
+
+ private static $python2Builtins = array(
+ '__import__' => true,
+ 'abs' => true,
+ 'all' => true,
+ 'any' => true,
+ 'basestring' => true,
+ 'bin' => true,
+ 'bool' => true,
+ 'bytearray' => true,
+ 'callable' => true,
+ 'chr' => true,
+ 'classmethod' => true,
+ 'cmp' => true,
+ 'compile' => true,
+ 'complex' => true,
+ 'delattr' => true,
+ 'dict' => true,
+ 'dir' => true,
+ 'divmod' => true,
+ 'enumerate' => true,
+ 'eval' => true,
+ 'execfile' => true,
+ 'file' => true,
+ 'filter' => true,
+ 'float' => true,
+ 'format' => true,
+ 'frozenset' => true,
+ 'getattr' => true,
+ 'globals' => true,
+ 'hasattr' => true,
+ 'hash' => true,
+ 'help' => true,
+ 'hex' => true,
+ 'id' => true,
+ 'input' => true,
+ 'int' => true,
+ 'isinstance' => true,
+ 'issubclass' => true,
+ 'iter' => true,
+ 'len' => true,
+ 'list' => true,
+ 'locals' => true,
+ 'long' => true,
+ 'map' => true,
+ 'max' => true,
+ 'memoryview' => true,
+ 'min' => true,
+ 'next' => true,
+ 'object' => true,
+ 'oct' => true,
+ 'open' => true,
+ 'ord' => true,
+ 'pow' => true,
+ 'print' => true,
+ 'property' => true,
+ 'range' => true,
+ 'raw_input' => true,
+ 'reduce' => true,
+ 'reload' => true,
+ 'repr' => true,
+ 'reversed' => true,
+ 'round' => true,
+ 'set' => true,
+ 'setattr' => true,
+ 'slice' => true,
+ 'sorted' => true,
+ 'staticmethod' => true,
+ 'str' => true,
+ 'sum' => true,
+ 'super' => true,
+ 'tuple' => true,
+ 'type' => true,
+ 'unichr' => true,
+ 'unicode' => true,
+ 'vars' => true,
+ 'xrange' => true,
+ 'zip' => true,
+ );
+
+ // This list only contains functions that are new or changed between the
+ // Python versions.
+ private static $python3Builtins = array(
+ 'ascii' => true,
+ 'bytes' => true,
+ 'filter' => true,
+ 'map' => true,
+ 'next' => true,
+ 'range' => true,
+ 'super' => true,
+ 'zip' => true,
+ );
+}
diff --git a/src/applications/repository/storage/PhabricatorRepositorySymbol.php b/src/applications/repository/storage/PhabricatorRepositorySymbol.php
--- a/src/applications/repository/storage/PhabricatorRepositorySymbol.php
+++ b/src/applications/repository/storage/PhabricatorRepositorySymbol.php
@@ -15,6 +15,10 @@
protected $symbolLanguage;
protected $pathID;
protected $lineNumber;
+ private $isExternal;
+ private $source;
+ private $location;
+ private $externalURI;
private $path = self::ATTACHABLE;
private $repository = self::ATTACHABLE;
@@ -40,6 +44,10 @@
}
public function getURI() {
+ if ($this->isExternal) {
+ return $this->externalURI;
+ }
+
$request = DiffusionRequest::newFromDictionary(
array(
'user' => PhabricatorUser::getOmnipotentUser(),
@@ -71,4 +79,32 @@
return $this;
}
+ public function isExternal() {
+ return $this->isExternal;
+ }
+ public function setIsExternal($is_external) {
+ $this->isExternal = $is_external;
+ return $this;
+ }
+
+ public function getSource() {
+ return $this->source;
+ }
+ public function setSource($source) {
+ $this->source = $source;
+ return $this;
+ }
+
+ public function getLocation() {
+ return $this->location;
+ }
+ public function setLocation($location) {
+ $this->location = $location;
+ return $this;
+ }
+
+ public function setExternalURI($external_uri) {
+ $this->externalURI = $external_uri;
+ return $this;
+ }
}

File Metadata

Mime Type
text/plain
Expires
Sun, Mar 23, 12:14 AM (1 w, 1 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7717609
Default Alt Text
D13036.id31480.diff (16 KB)

Event Timeline