private function loadSymbolForAtom(DivinerAtom $atom) { $symbol = id(new DivinerAtomQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withBookPHIDs(array($this->loadBook()->getPHID()))->withTypes(array($atom->getType()))->withNames(array($atom->getName()))->withContexts(array($atom->getContext()))->withIndexes(array($this->getAtomSimilarIndex($atom)))->withIncludeUndocumentable(true)->withIncludeGhosts(true)->executeOne(); if ($symbol) { return $symbol; } return id(new DivinerLiveSymbol())->setBookPHID($this->loadBook()->getPHID())->setType($atom->getType())->setName($atom->getName())->setContext($atom->getContext())->setAtomIndex($this->getAtomSimilarIndex($atom)); }
public function attachAtom(DivinerLiveAtom $atom = null) { if ($atom === null) { $this->atom = null; } else { $this->atom = DivinerAtom::newFromDictionary($atom->getAtomData()); } return $this; }
protected function renderResultList(array $symbols, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($symbols, 'DivinerLiveSymbol'); $viewer = $this->requireViewer(); $list = id(new PHUIObjectItemListView())->setUser($viewer); foreach ($symbols as $symbol) { $type = $symbol->getType(); $type_name = DivinerAtom::getAtomTypeNameString($type); $item = id(new PHUIObjectItemView())->setHeader($symbol->getTitle())->setHref($symbol->getURI())->addAttribute($symbol->getSummary())->addIcon('none', $type_name); $list->addItem($item); } return $list; }
protected function renderAtomList(array $symbols) { assert_instances_of($symbols, 'DivinerLiveSymbol'); $list = array(); foreach ($symbols as $symbol) { switch ($symbol->getType()) { case DivinerAtom::TYPE_FUNCTION: $title = $symbol->getTitle() . '()'; break; default: $title = $symbol->getTitle(); break; } $item = id(new DivinerBookItemView())->setTitle($title)->setHref($symbol->getURI())->setSubtitle($symbol->getSummary())->setType(DivinerAtom::getAtomTypeNameString($symbol->getType())); $list[] = $item; } return $list; }
private function renderDocumentationText(DivinerLiveSymbol $symbol, PhabricatorMarkupEngine $engine) { $field = 'default'; $content = $engine->getOutput($symbol, $field); if (strlen(trim($symbol->getMarkupText($field)))) { $content = phutil_tag('div', array('class' => 'phabricator-remarkup diviner-remarkup-section'), $content); } else { $atom = $symbol->getAtom(); $content = phutil_tag('div', array('class' => 'diviner-message-not-documented'), DivinerAtom::getThisAtomIsNotDocumentedString($atom->getType())); } return $content; }
protected function shouldGenerateDocumentForAtom(DivinerAtom $atom) { switch ($atom->getType()) { case DivinerAtom::TYPE_METHOD: case DivinerAtom::TYPE_FILE: return false; case DivinerAtom::TYPE_ARTICLE: default: break; } return true; }
/** * Get a global version number, which changes whenever any atom or atomizer * implementation changes in a way which is not backward-compatible. */ private function getDivinerAtomWorldVersion() { $version = array(); $version['atom'] = DivinerAtom::getAtomSerializationVersion(); $version['rules'] = $this->getRules(); $atomizers = id(new PhutilSymbolLoader())->setAncestorClass('DivinerAtomizer')->setConcreteOnly(true)->selectAndLoadSymbols(); $atomizer_versions = array(); foreach ($atomizers as $atomizer) { $atomizer_versions[$atomizer['name']] = call_user_func(array($atomizer['name'], 'getAtomizerVersion')); } ksort($atomizer_versions); $version['atomizers'] = $atomizer_versions; return md5(serialize($version)); }
private function parseReturnType(DivinerAtom $atom, XHPASTNode $decl) { $return_spec = array(); $metadata = $atom->getDocblockMeta(); $return = idx($metadata, 'return'); $type = null; $docs = null; if (!$return) { $return = idx($metadata, 'returns'); if ($return) { $atom->addWarning(pht('Documentation uses `%s`, but should use `%s`.', '@returns', '@return')); } } $return = (array) $return; if (count($return) > 1) { $atom->addWarning(pht('Documentation specifies `%s` multiple times.', '@return')); } $return = head($return); if ($atom->getName() == '__construct' && $atom->getType() == 'method') { $return_spec = array('doctype' => 'this', 'docs' => '//Implicit.//'); if ($return) { $atom->addWarning(pht('Method `%s` has explicitly documented `%s`. The `%s` method ' . 'always returns `%s`. Diviner documents this implicitly.', '__construct()', '@return', '__construct()', '$this')); } } else { if ($return) { $split = preg_split('/(?<!,)\\s+/', trim($return), 2); if (!empty($split[0])) { $type = $split[0]; } if ($decl->getChildByIndex(1)->getTypeName() == 'n_REFERENCE') { $type = $type . ' &'; } if (!empty($split[1])) { $docs = $split[1]; } $return_spec = array('doctype' => $type, 'docs' => $docs); } else { $return_spec = array('type' => 'wild'); } } $atom->setProperty('return', $return_spec); }
protected function getAtomHrefDepth(DivinerAtom $atom) { if ($atom->getContext()) { return 4; } else { return 3; } }
public function addChild(DivinerAtom $atom) { if ($this->childHashes) { throw new Exception(pht('Child hashes have already been computed!')); } $atom->setParent($this); $this->children[] = $atom; return $this; }
/** * Get a global version number, which changes whenever any atom or atomizer * implementation changes in a way which is not backward-compatible. */ private function getDivinerAtomWorldVersion() { $version = array(); $version['atom'] = DivinerAtom::getAtomSerializationVersion(); $version['rules'] = $this->getRules(); $atomizers = id(new PhutilClassMapQuery())->setAncestorClass('DivinerAtomizer')->execute(); $atomizer_versions = array(); foreach ($atomizers as $atomizer) { $name = get_class($atomizer); $atomizer_versions[$name] = call_user_func(array($name, 'getAtomizerVersion')); } ksort($atomizer_versions); $version['atomizers'] = $atomizer_versions; return md5(serialize($version)); }
private function parseReturnType(DivinerAtom $atom, XHPASTNode $decl) { $return_spec = array(); $metadata = $atom->getDocblockMeta(); $return = idx($metadata, 'return'); if (!$return) { $return = idx($metadata, 'returns'); if ($return) { $atom->addWarning(pht('Documentation uses `@returns`, but should use `@return`.')); } } if ($atom->getName() == '__construct' && $atom->getType() == 'method') { $return_spec = array('doctype' => 'this', 'docs' => '//Implicit.//'); if ($return) { $atom->addWarning('Method __construct() has explicitly documented @return. The ' . '__construct() method always returns $this. Diviner documents ' . 'this implicitly.'); } } else { if ($return) { $split = preg_split('/\\s+/', trim($return), $limit = 2); if (!empty($split[0])) { $type = $split[0]; } if ($decl->getChildByIndex(1)->getTypeName() == 'n_REFERENCE') { $type = $type . ' &'; } $docs = null; if (!empty($split[1])) { $docs = $split[1]; } $return_spec = array('doctype' => $type, 'docs' => $docs); } else { $return_spec = array('type' => 'wild'); } } $atom->setProperty('return', $return_spec); }
private function getAtomRelativePath(DivinerAtom $atom) { $ref = $atom->getRef(); $book = $ref->getBook(); $type = $ref->getType(); $context = $ref->getContext(); $name = $ref->getName(); $path = array('docs', $book, $type); if ($context !== null) { $path[] = $context; } $path[] = $name; $index = $this->getAtomSimilarIndex($atom); if ($index !== null) { $path[] = '@' . $index; } $path[] = null; return implode(DIRECTORY_SEPARATOR, $path); }
public function attachAtom(DivinerLiveAtom $atom) { $this->atom = DivinerAtom::newFromDictionary($atom->getAtomData()); return $this; }