public function didMarkupText()
 {
     $engine = $this->getEngine();
     $key = self::KEY_RULE_ATOM_REF;
     $data = $engine->getTextMetadata($key, array());
     $renderer = $engine->getConfig('diviner.renderer');
     foreach ($data as $token => $ref_dict) {
         $ref = DivinerAtomRef::newFromDictionary($ref_dict);
         $title = $ref->getTitle();
         $href = null;
         if ($renderer) {
             // Here, we're generating documentation. If possible, we want to find
             // the real atom ref so we can render the correct default title and
             // render invalid links in an alternate style.
             $ref = $renderer->normalizeAtomRef($ref);
             if ($ref) {
                 $title = nonempty($ref->getTitle(), $ref->getName());
                 $href = $renderer->getHrefForAtomRef($ref);
             }
         } else {
             // Here, we're generating comment text or something like that. Just
             // link to Diviner and let it sort things out.
             $href = id(new PhutilURI('/diviner/find/'))->setQueryParams(array('book' => $ref->getBook(), 'name' => $ref->getName(), 'type' => $ref->getType(), 'context' => $ref->getContext(), 'jump' => true));
         }
         // TODO: This probably is not the best place to do this. Move it somewhere
         // better when it becomes more clear where it should actually go.
         if ($ref) {
             switch ($ref->getType()) {
                 case 'function':
                 case 'method':
                     $title = $title . '()';
                     break;
             }
         }
         if ($this->getEngine()->isTextMode()) {
             if ($href) {
                 $link = $title . ' <' . PhabricatorEnv::getProductionURI($href) . '>';
             } else {
                 $link = $title;
             }
         } else {
             if ($href) {
                 if ($this->getEngine()->isHTMLMailMode()) {
                     $href = PhabricatorEnv::getProductionURI($href);
                 }
                 $link = $this->newTag('a', array('class' => 'atom-ref', 'href' => $href), $title);
             } else {
                 $link = $this->newTag('span', array('class' => 'atom-ref-invalid'), $title);
             }
         }
         $engine->overwriteStoredText($token, $link);
     }
 }
 public function findAtomByRef(DivinerAtomRef $ref)
 {
     if ($ref->getBook() != $this->getConfig('name')) {
         return null;
     }
     if ($this->atomNameMap === null) {
         $name_map = array();
         foreach ($this->getPublishCache()->getIndex() as $hash => $dict) {
             $name_map[$dict['name']][$hash] = $dict;
         }
         $this->atomNameMap = $name_map;
     }
     $name = $ref->getName();
     if (empty($this->atomNameMap[$name])) {
         return null;
     }
     $candidates = $this->atomNameMap[$name];
     foreach ($candidates as $key => $dict) {
         $candidates[$key] = DivinerAtomRef::newFromDictionary($dict);
         if ($ref->getType()) {
             if ($candidates[$key]->getType() != $ref->getType()) {
                 unset($candidates[$key]);
             }
         }
         if ($ref->getContext()) {
             if ($candidates[$key]->getContext() != $ref->getContext()) {
                 unset($candidates[$key]);
             }
         }
     }
     // If we have exactly one uniquely identifiable atom, return it.
     if (count($candidates) == 1) {
         return $this->getAtomFromNodeHash(last_key($candidates));
     }
     return null;
 }
Esempio n. 3
0
 protected function buildWhereClause(AphrontDatabaseConnection $conn_r)
 {
     $where = array();
     if ($this->ids) {
         $where[] = qsprintf($conn_r, 'id IN (%Ld)', $this->ids);
     }
     if ($this->phids) {
         $where[] = qsprintf($conn_r, 'phid IN (%Ls)', $this->phids);
     }
     if ($this->bookPHIDs) {
         $where[] = qsprintf($conn_r, 'bookPHID IN (%Ls)', $this->bookPHIDs);
     }
     if ($this->types) {
         $where[] = qsprintf($conn_r, 'type IN (%Ls)', $this->types);
     }
     if ($this->names) {
         $where[] = qsprintf($conn_r, 'name IN (%Ls)', $this->names);
     }
     if ($this->titles) {
         $hashes = array();
         foreach ($this->titles as $title) {
             $slug = DivinerAtomRef::normalizeTitleString($title);
             $hash = PhabricatorHash::digestForIndex($slug);
             $hashes[] = $hash;
         }
         $where[] = qsprintf($conn_r, 'titleSlugHash in (%Ls)', $hashes);
     }
     if ($this->contexts) {
         $with_null = false;
         $contexts = $this->contexts;
         foreach ($contexts as $key => $value) {
             if ($value === null) {
                 unset($contexts[$key]);
                 $with_null = true;
                 continue;
             }
         }
         if ($contexts && $with_null) {
             $where[] = qsprintf($conn_r, 'context IN (%Ls) OR context IS NULL', $contexts);
         } else {
             if ($contexts) {
                 $where[] = qsprintf($conn_r, 'context IN (%Ls)', $contexts);
             } else {
                 if ($with_null) {
                     $where[] = qsprintf($conn_r, 'context IS NULL');
                 }
             }
         }
     }
     if ($this->indexes) {
         $where[] = qsprintf($conn_r, 'atomIndex IN (%Ld)', $this->indexes);
     }
     if ($this->isDocumentable !== null) {
         $where[] = qsprintf($conn_r, 'isDocumentable = %d', (int) $this->isDocumentable);
     }
     if ($this->isGhost !== null) {
         if ($this->isGhost) {
             $where[] = qsprintf($conn_r, 'graphHash IS NULL');
         } else {
             $where[] = qsprintf($conn_r, 'graphHash IS NOT NULL');
         }
     }
     if ($this->nodeHashes) {
         $where[] = qsprintf($conn_r, 'nodeHash IN (%Ls)', $this->nodeHashes);
     }
     if ($this->nameContains) {
         // NOTE: This `CONVERT()` call makes queries case-insensitive, since
         // the column has binary collation. Eventually, this should move into
         // fulltext.
         $where[] = qsprintf($conn_r, 'CONVERT(name USING utf8) LIKE %~', $this->nameContains);
     }
     if ($this->repositoryPHIDs) {
         $where[] = qsprintf($conn_r, 'repositoryPHID IN (%Ls)', $this->repositoryPHIDs);
     }
     $where[] = $this->buildPagingClause($conn_r);
     return $this->formatWhereClause($where);
 }
 private function getEdges($node_hash)
 {
     $atom_cache = $this->getAtomCache();
     $atom = $atom_cache->getAtom($node_hash);
     $refs = array();
     // Make the atom depend on its own symbol, so that all atoms with the same
     // symbol are dirtied (e.g., if a codebase defines the function `f()`
     // several times, all of them should be dirtied when one is dirtied).
     $refs[DivinerAtomRef::newFromDictionary($atom)->toHash()] = true;
     foreach (array_merge($atom['extends'], $atom['links']) as $ref_dict) {
         $ref = DivinerAtomRef::newFromDictionary($ref_dict);
         if ($ref->getBook() == $atom['book']) {
             $refs[$ref->toHash()] = true;
         }
     }
     return array_keys($refs);
 }
 public function getHrefForAtomRef(DivinerAtomRef $ref)
 {
     $depth = 1;
     $atom = $this->peekAtomStack();
     if ($atom) {
         $depth = $this->getAtomHrefDepth($atom);
     }
     $href = str_repeat('../', $depth);
     $book = $ref->getBook();
     $type = $ref->getType();
     $name = $ref->getName();
     $context = $ref->getContext();
     $href .= $book . '/' . $type . '/';
     if ($context !== null) {
         $href .= $context . '/';
     }
     $href .= $name . '/index.html';
     return $href;
 }
Esempio n. 6
0
 public static function newFromDictionary(array $dictionary)
 {
     $atom = id(new DivinerAtom())->setBook(idx($dictionary, 'book'))->setType(idx($dictionary, 'type'))->setName(idx($dictionary, 'name'))->setFile(idx($dictionary, 'file'))->setLine(idx($dictionary, 'line'))->setHash(idx($dictionary, 'hash'))->setLength(idx($dictionary, 'length'))->setContext(idx($dictionary, 'context'))->setLanguage(idx($dictionary, 'language'))->setParentHash(idx($dictionary, 'parentHash'))->setDocblockRaw(idx($dictionary, 'docblockRaw'))->setProperties(idx($dictionary, 'properties'));
     foreach (idx($dictionary, 'warnings', array()) as $warning) {
         $atom->addWarning($warning);
     }
     foreach (idx($dictionary, 'childHashes', array()) as $child) {
         $atom->addChildHash($child);
     }
     foreach (idx($dictionary, 'extends', array()) as $extends) {
         $atom->addExtends(DivinerAtomRef::newFromDictionary($extends));
     }
     return $atom;
 }
 public function setTitle($value)
 {
     $this->writeField('title', $value);
     if (strlen($value)) {
         $slug = DivinerAtomRef::normalizeTitleString($value);
         $hash = PhabricatorHash::digestForIndex($slug);
         $this->titleSlugHash = $hash;
     } else {
         $this->titleSlugHash = null;
     }
     return $this;
 }
Esempio n. 8
0
 public static function newFromDictionary(array $dict)
 {
     $obj = new DivinerAtomRef();
     $obj->setBook(idx($dict, 'book'));
     $obj->setContext(idx($dict, 'context'));
     $obj->setType(idx($dict, 'type'));
     $obj->setName(idx($dict, 'name'));
     $obj->group = idx($dict, 'group');
     $obj->index = idx($dict, 'index');
     $obj->summary = idx($dict, 'summary');
     $obj->title = idx($dict, 'title');
     return $obj;
 }