@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Allow ghost atoms to be rendered

Summary: Ref T4558. Allow ghost atoms to be rendered in #diviner. This functionality didn't exist previously, but was hinted at by the TODO comments.

Test Plan: Generated #diviner documentation for rARC and then removed a class (before re-generating the documentation). Navigated to the documentation for the removed class and saw "This atom no longer exists".

Reviewers: epriestley, #blessed_reviewers

Reviewed By: epriestley, #blessed_reviewers

Subscribers: epriestley

Maniphest Tasks: T4558

Differential Revision: https://secure.phabricator.com/D13114

+101 -58
+63 -47
src/applications/diviner/controller/DivinerAtomController.php
··· 35 35 return new Aphront404Response(); 36 36 } 37 37 38 - // TODO: This query won't load ghosts, because they'll fail `needAtoms()`. 39 - // Instead, we might want to load ghosts and render a message like 40 - // "this thing existed in an older version, but no longer does", especially 41 - // if we add content like comments. 42 - 43 38 $symbol = id(new DivinerAtomQuery()) 44 39 ->setViewer($viewer) 45 40 ->withBookPHIDs(array($book->getPHID())) ··· 47 42 ->withNames(array($this->atomName)) 48 43 ->withContexts(array($this->atomContext)) 49 44 ->withIndexes(array($this->atomIndex)) 50 - ->withGhosts(false) 51 45 ->withIsDocumentable(true) 52 46 ->needAtoms(true) 53 47 ->needExtends(true) ··· 66 60 $book->getShortTitle(), 67 61 '/book/'.$book->getName().'/'); 68 62 69 - $atom_short_title = $atom->getDocblockMetaValue( 70 - 'short', 71 - $symbol->getTitle()); 63 + $atom_short_title = $atom 64 + ? $atom->getDocblockMetaValue('short', $symbol->getTitle()) 65 + : $symbol->getTitle(); 72 66 73 67 $crumbs->addTextCrumb($atom_short_title); 74 68 ··· 78 72 id(new PHUITagView()) 79 73 ->setType(PHUITagView::TYPE_STATE) 80 74 ->setBackgroundColor(PHUITagView::COLOR_BLUE) 81 - ->setName(DivinerAtom::getAtomTypeNameString($atom->getType()))); 75 + ->setName(DivinerAtom::getAtomTypeNameString( 76 + $atom ? $atom->getType() : $symbol->getType()))); 82 77 83 78 $properties = id(new PHUIPropertyListView()); 84 79 85 - $group = $atom->getProperty('group'); 80 + $group = $atom ? $atom->getProperty('group') : $symbol->getGroupName(); 86 81 if ($group) { 87 82 $group_name = $book->getGroupName($group); 88 83 } else { 89 84 $group_name = null; 90 85 } 91 86 92 - $this->buildDefined($properties, $symbol); 93 - $this->buildExtendsAndImplements($properties, $symbol); 87 + $document = id(new PHUIDocumentView()) 88 + ->setBook($book->getTitle(), $group_name) 89 + ->setHeader($header) 90 + ->addClass('diviner-view') 91 + ->setFontKit(PHUIDocumentView::FONT_SOURCE_SANS) 92 + ->appendChild($properties); 93 + 94 + if ($atom) { 95 + $this->buildDefined($properties, $symbol); 96 + $this->buildExtendsAndImplements($properties, $symbol); 97 + 98 + $warnings = $atom->getWarnings(); 99 + if ($warnings) { 100 + $warnings = id(new PHUIInfoView()) 101 + ->setErrors($warnings) 102 + ->setTitle(pht('Documentation Warnings')) 103 + ->setSeverity(PHUIInfoView::SEVERITY_WARNING); 104 + } 94 105 95 - $warnings = $atom->getWarnings(); 96 - if ($warnings) { 97 - $warnings = id(new PHUIInfoView()) 98 - ->setErrors($warnings) 99 - ->setTitle(pht('Documentation Warnings')) 100 - ->setSeverity(PHUIInfoView::SEVERITY_WARNING); 106 + $document->appendChild($warnings); 101 107 } 102 108 103 109 $methods = $this->composeMethods($symbol); ··· 113 119 } 114 120 $engine->process(); 115 121 116 - $content = $this->renderDocumentationText($symbol, $engine); 122 + if ($atom) { 123 + $content = $this->renderDocumentationText($symbol, $engine); 124 + $document->appendChild($content); 125 + } 117 126 118 127 $toc = $engine->getEngineMetadata( 119 128 $symbol, ··· 121 130 PhutilRemarkupHeaderBlockRule::KEY_HEADER_TOC, 122 131 array()); 123 132 124 - $document = id(new PHUIDocumentView()) 125 - ->setBook($book->getTitle(), $group_name) 126 - ->setHeader($header) 127 - ->addClass('diviner-view') 128 - ->setFontKit(PHUIDocumentView::FONT_SOURCE_SANS) 129 - ->appendChild($properties) 130 - ->appendChild($warnings) 131 - ->appendChild($content); 133 + if (!$atom) { 134 + $document->appendChild( 135 + id(new PHUIInfoView()) 136 + ->setSeverity(PHUIInfoView::SEVERITY_NOTICE) 137 + ->appendChild( 138 + pht( 139 + 'This atom no longer exists.'))); 140 + } 132 141 133 - $document->appendChild($this->buildParametersAndReturn(array($symbol))); 142 + if ($atom) { 143 + $document->appendChild($this->buildParametersAndReturn(array($symbol))); 144 + } 134 145 135 146 if ($methods) { 136 147 $tasks = $this->composeTasks($symbol); ··· 202 213 } 203 214 204 215 $section = id(new DivinerSectionView()) 205 - ->setHeader(pht('Methods')); 216 + ->setHeader(pht('Methods')); 206 217 207 218 foreach ($methods as $spec) { 208 219 $matom = last($spec['atoms']); ··· 473 484 $atom = $symbol->getAtom(); 474 485 475 486 $out = array(); 476 - if ($atom->getProperty('final')) { 477 - $out[] = 'final'; 478 - } 487 + 488 + if ($atom) { 489 + if ($atom->getProperty('final')) { 490 + $out[] = 'final'; 491 + } 479 492 480 - if ($atom->getProperty('abstract')) { 481 - $out[] = 'abstract'; 482 - } 493 + if ($atom->getProperty('abstract')) { 494 + $out[] = 'abstract'; 495 + } 483 496 484 - if ($atom->getProperty('access')) { 485 - $out[] = $atom->getProperty('access'); 486 - } 497 + if ($atom->getProperty('access')) { 498 + $out[] = $atom->getProperty('access'); 499 + } 487 500 488 - if ($atom->getProperty('static')) { 489 - $out[] = 'static'; 501 + if ($atom->getProperty('static')) { 502 + $out[] = 'static'; 503 + } 490 504 } 491 505 492 506 switch ($symbol->getType()) { ··· 530 544 531 545 $out = phutil_implode_html(' ', $out); 532 546 533 - $parameters = $atom->getProperty('parameters'); 534 - if ($parameters !== null) { 535 - $pout = array(); 536 - foreach ($parameters as $parameter) { 537 - $pout[] = idx($parameter, 'name', '...'); 547 + if ($atom) { 548 + $parameters = $atom->getProperty('parameters'); 549 + if ($parameters !== null) { 550 + $pout = array(); 551 + foreach ($parameters as $parameter) { 552 + $pout[] = idx($parameter, 'name', '...'); 553 + } 554 + $out = array($out, '('.implode(', ', $pout).')'); 538 555 } 539 - $out = array($out, '('.implode(', ', $pout).')'); 540 556 } 541 557 542 558 return phutil_tag(
+28 -9
src/applications/diviner/query/DivinerAtomQuery.php
··· 151 151 152 152 foreach ($atoms as $key => $atom) { 153 153 $data = idx($atom_data, $atom->getPHID()); 154 - if (!$data) { 155 - unset($atoms[$key]); 156 - continue; 157 - } 158 154 $atom->attachAtom($data); 159 155 } 160 156 } ··· 170 166 171 167 $names = array(); 172 168 foreach ($atoms as $atom) { 169 + if (!$atom->getAtom()) { 170 + continue; 171 + } 172 + 173 173 foreach ($atom->getAtom()->getExtends() as $xref) { 174 174 $names[] = $xref->getName(); 175 175 } ··· 189 189 } 190 190 191 191 foreach ($atoms as $atom) { 192 - $alang = $atom->getAtom()->getLanguage(); 192 + $atom_lang = null; 193 + $atom_extends = array(); 194 + 195 + if ($atom->getAtom()) { 196 + $atom_lang = $atom->getAtom()->getLanguage(); 197 + $atom_extends = $atom->getAtom()->getExtends(); 198 + } 199 + 193 200 $extends = array(); 194 - foreach ($atom->getAtom()->getExtends() as $xref) { 195 201 202 + foreach ($atom_extends as $xref) { 196 203 // If there are no symbols of the matching name and type, we can't 197 204 // resolve this. 198 205 if (empty($xatoms[$xref->getName()][$xref->getType()])) { ··· 216 223 // classes can not implement JS classes. 217 224 $same_lang = array(); 218 225 foreach ($maybe as $xatom) { 219 - if ($xatom->getAtom()->getLanguage() == $alang) { 226 + if ($xatom->getAtom()->getLanguage() == $atom_lang) { 220 227 $same_lang[] = $xatom; 221 228 } 222 229 } ··· 396 403 397 404 $hashes = array(); 398 405 foreach ($symbols as $symbol) { 399 - foreach ($symbol->getAtom()->getChildHashes() as $hash) { 406 + $child_hashes = array(); 407 + 408 + if ($symbol->getAtom()) { 409 + $child_hashes = $symbol->getAtom()->getChildHashes(); 410 + } 411 + 412 + foreach ($child_hashes as $hash) { 400 413 $hashes[$hash] = $hash; 401 414 } 402 415 if ($recurse_up) { ··· 426 439 assert_instances_of($children, 'DivinerLiveSymbol'); 427 440 428 441 foreach ($symbols as $symbol) { 442 + $child_hashes = array(); 429 443 $symbol_children = array(); 430 - foreach ($symbol->getAtom()->getChildHashes() as $hash) { 444 + 445 + if ($symbol->getAtom()) { 446 + $child_hashes = $symbol->getAtom()->getChildHashes(); 447 + } 448 + 449 + foreach ($child_hashes as $hash) { 431 450 if (isset($children[$hash])) { 432 451 $symbol_children[] = $children[$hash]; 433 452 }
+10 -2
src/applications/diviner/storage/DivinerLiveSymbol.php
··· 98 98 return $this->assertAttached($this->atom); 99 99 } 100 100 101 - public function attachAtom(DivinerLiveAtom $atom) { 102 - $this->atom = DivinerAtom::newFromDictionary($atom->getAtomData()); 101 + public function attachAtom(DivinerLiveAtom $atom = null) { 102 + if ($atom === null) { 103 + $this->atom = null; 104 + } else { 105 + $this->atom = DivinerAtom::newFromDictionary($atom->getAtomData()); 106 + } 103 107 return $this; 104 108 } 105 109 ··· 229 233 230 234 231 235 public function getMarkupText($field) { 236 + if (!$this->getAtom()) { 237 + return; 238 + } 239 + 232 240 return $this->getAtom()->getDocblockText(); 233 241 } 234 242