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 @@ -609,6 +609,7 @@ 'DivinerFileAtomizer' => 'applications/diviner/atomizer/DivinerFileAtomizer.php', 'DivinerFindController' => 'applications/diviner/controller/DivinerFindController.php', 'DivinerGenerateWorkflow' => 'applications/diviner/workflow/DivinerGenerateWorkflow.php', + 'DivinerLanguageConstant' => 'applications/diviner/constants/DivinerLanguageConstant.php', 'DivinerLiveAtom' => 'applications/diviner/storage/DivinerLiveAtom.php', 'DivinerLiveBook' => 'applications/diviner/storage/DivinerLiveBook.php', 'DivinerLivePublisher' => 'applications/diviner/publisher/DivinerLivePublisher.php', diff --git a/src/applications/diviner/application/PhabricatorApplicationDiviner.php b/src/applications/diviner/application/PhabricatorApplicationDiviner.php --- a/src/applications/diviner/application/PhabricatorApplicationDiviner.php +++ b/src/applications/diviner/application/PhabricatorApplicationDiviner.php @@ -29,7 +29,7 @@ '/book/'. '(?P<book>[^/]+)/'. '(?P<type>[^/]+)/'. - '(?:(?P<context>[^/]+)/)?'. + '(?P<context>[^/]+)/'. '(?P<name>[^/]+)/'. '(?:(?P<index>\d+)/)?' => 'DivinerAtomController', ); diff --git a/src/applications/diviner/atom/DivinerAtom.php b/src/applications/diviner/atom/DivinerAtom.php --- a/src/applications/diviner/atom/DivinerAtom.php +++ b/src/applications/diviner/atom/DivinerAtom.php @@ -9,6 +9,8 @@ const TYPE_FUNCTION = 'function'; const TYPE_INTERFACE = 'interface'; + const CONTEXT_SEPARATOR = ':'; + private $type; private $name; private $file; @@ -57,6 +59,20 @@ } public function setContext($context) { + $language = $this->getLanguage(); + if (!$language) { + throw new Exception("Call setLanguage() before setContext()"); + } + // Normalize the context based on the atom's language + $separator = id(new DivinerLanguageConstant()) + ->getContextSeparatorForLanguage($language); + $context = trim($context, $separator); + $context = str_replace($separator, DivinerAtom::CONTEXT_SEPARATOR, + $context); + if (!strlen($context)) { + $context = null; + } + $this->context = $context; return $this; } @@ -294,7 +310,6 @@ return implode('/', $parts); } - public function toDictionary() { // NOTE: If you change this format, bump the format version in // getAtomSerializationVersion(). @@ -345,8 +360,8 @@ ->setLine(idx($dictionary, 'line')) ->setHash(idx($dictionary, 'hash')) ->setLength(idx($dictionary, 'length')) - ->setContext(idx($dictionary, 'context')) ->setLanguage(idx($dictionary, 'language')) + ->setContext(idx($dictionary, 'context')) ->setParentHash(idx($dictionary, 'parentHash')) ->setDocblockRaw(idx($dictionary, 'docblockRaw')) ->setProperties(idx($dictionary, 'properties')); diff --git a/src/applications/diviner/constants/DivinerLanguageConstant.php b/src/applications/diviner/constants/DivinerLanguageConstant.php new file mode 100644 --- /dev/null +++ b/src/applications/diviner/constants/DivinerLanguageConstant.php @@ -0,0 +1,20 @@ +<?php + +class DivinerLanguageConstant { + + public function getContextSeparatorForLanguage($language) { + switch ($language) { + case 'php': + $separator = '\\'; + break; + case 'human': + $separator = ''; + break; + default: + $separator = '.'; + break; + } + return $separator; + } + +} diff --git a/src/applications/diviner/controller/DivinerAtomController.php b/src/applications/diviner/controller/DivinerAtomController.php --- a/src/applications/diviner/controller/DivinerAtomController.php +++ b/src/applications/diviner/controller/DivinerAtomController.php @@ -16,7 +16,7 @@ $this->bookName = $data['book']; $this->atomType = $data['type']; $this->atomName = $data['name']; - $this->atomContext = nonempty(idx($data, 'context'), null); + $this->atomContext = $data['context']; $this->atomIndex = nonempty(idx($data, 'index'), null); } @@ -293,7 +293,7 @@ private function renderAtomTag(DivinerLiveSymbol $symbol) { return id(new PHUITagView()) ->setType(PHUITagView::TYPE_OBJECT) - ->setName($symbol->getName()) + ->setName($symbol->getTitle()) ->setHref($symbol->getURI()); } @@ -513,6 +513,17 @@ break; } + switch ($symbol->getType()) { + case DivinerAtom::TYPE_CLASS: + case DivinerAtom::TYPE_INTERFACE: + case DivinerAtom::TYPE_FUNCTION: + $name = $symbol->getTitle(); + break; + default: + $name = $symbol->getName(); + break; + } + $out[] = phutil_tag( $anchor ? 'a' : 'span', array( @@ -520,7 +531,7 @@ 'href' => $anchor ? '#'.$anchor : null, 'name' => $is_link ? null : $anchor, ), - $symbol->getName()); + $name); $out = phutil_implode_html(' ', $out); diff --git a/src/applications/diviner/controller/DivinerBookController.php b/src/applications/diviner/controller/DivinerBookController.php --- a/src/applications/diviner/controller/DivinerBookController.php +++ b/src/applications/diviner/controller/DivinerBookController.php @@ -43,6 +43,7 @@ $properties = $this->buildPropertyList($book); $atoms = id(new DivinerAtomQuery()) + ->needAtoms(true) ->setViewer($viewer) ->withBookPHIDs(array($book->getPHID())) ->execute(); diff --git a/src/applications/diviner/query/DivinerAtomQuery.php b/src/applications/diviner/query/DivinerAtomQuery.php --- a/src/applications/diviner/query/DivinerAtomQuery.php +++ b/src/applications/diviner/query/DivinerAtomQuery.php @@ -46,6 +46,9 @@ } public function withContexts(array $contexts) { + if ($contexts == array(DivinerAtom::CONTEXT_SEPARATOR)) { + $contexts = array(); + } $this->contexts = $contexts; return $this; } diff --git a/src/applications/diviner/storage/DivinerLiveSymbol.php b/src/applications/diviner/storage/DivinerLiveSymbol.php --- a/src/applications/diviner/storage/DivinerLiveSymbol.php +++ b/src/applications/diviner/storage/DivinerLiveSymbol.php @@ -63,6 +63,9 @@ if ($this->getContext()) { $parts[] = $this->getContext(); } + else { + $parts[] = DivinerAtom::CONTEXT_SEPARATOR; + } $parts[] = $this->getName(); @@ -103,12 +106,31 @@ return parent::save(); } + public function getLanguage() { + // TODO: add this as a column? + try { + return $this->getAtom()->getLanguage(); + } + catch (PhabricatorDataNotAttachedException $e) { + return ''; + } + } + public function getTitle() { $title = parent::getTitle(); if (!strlen($title)) { $title = $this->getName(); } - return $title; + $separator = id(new DivinerLanguageConstant()) + ->getContextSeparatorForLanguage($this->getLanguage()); + $context = str_replace(DivinerAtom::CONTEXT_SEPARATOR, $separator, + $this->getContext()); + + if (strlen($context)) { + $context .= $separator; + } + + return $context.$title; } public function setTitle($value) {