Changeset View
Changeset View
Standalone View
Standalone View
src/applications/diviner/query/DivinerAtomQuery.php
| Show First 20 Lines • Show All 145 Lines • ▼ Show 20 Lines | protected function willFilterPage(array $atoms) { | ||||
| if ($this->needAtoms) { | if ($this->needAtoms) { | ||||
| $atom_data = id(new DivinerLiveAtom())->loadAllWhere( | $atom_data = id(new DivinerLiveAtom())->loadAllWhere( | ||||
| 'symbolPHID IN (%Ls)', | 'symbolPHID IN (%Ls)', | ||||
| mpull($atoms, 'getPHID')); | mpull($atoms, 'getPHID')); | ||||
| $atom_data = mpull($atom_data, null, 'getSymbolPHID'); | $atom_data = mpull($atom_data, null, 'getSymbolPHID'); | ||||
| foreach ($atoms as $key => $atom) { | foreach ($atoms as $key => $atom) { | ||||
| $data = idx($atom_data, $atom->getPHID()); | $data = idx($atom_data, $atom->getPHID()); | ||||
| if (!$data) { | |||||
| unset($atoms[$key]); | |||||
| continue; | |||||
| } | |||||
| $atom->attachAtom($data); | $atom->attachAtom($data); | ||||
| } | } | ||||
| } | } | ||||
| // Load all of the symbols this symbol extends, recursively. Commonly, | // Load all of the symbols this symbol extends, recursively. Commonly, | ||||
| // this means all the ancestor classes and interfaces it extends and | // this means all the ancestor classes and interfaces it extends and | ||||
| // implements. | // implements. | ||||
| if ($this->needExtends) { | if ($this->needExtends) { | ||||
| // First, load all the matching symbols by name. This does 99% of the | // First, load all the matching symbols by name. This does 99% of the | ||||
| // work in most cases, assuming things are named at all reasonably. | // work in most cases, assuming things are named at all reasonably. | ||||
| $names = array(); | $names = array(); | ||||
| foreach ($atoms as $atom) { | foreach ($atoms as $atom) { | ||||
| if (!$atom->getAtom()) { | |||||
| continue; | |||||
| } | |||||
| foreach ($atom->getAtom()->getExtends() as $xref) { | foreach ($atom->getAtom()->getExtends() as $xref) { | ||||
| $names[] = $xref->getName(); | $names[] = $xref->getName(); | ||||
| } | } | ||||
| } | } | ||||
| if ($names) { | if ($names) { | ||||
| $xatoms = id(new DivinerAtomQuery()) | $xatoms = id(new DivinerAtomQuery()) | ||||
| ->setViewer($this->getViewer()) | ->setViewer($this->getViewer()) | ||||
| ->withNames($names) | ->withNames($names) | ||||
| ->needExtends(true) | ->needExtends(true) | ||||
| ->needAtoms(true) | ->needAtoms(true) | ||||
| ->needChildren($this->needChildren) | ->needChildren($this->needChildren) | ||||
| ->execute(); | ->execute(); | ||||
| $xatoms = mgroup($xatoms, 'getName', 'getType', 'getBookPHID'); | $xatoms = mgroup($xatoms, 'getName', 'getType', 'getBookPHID'); | ||||
| } else { | } else { | ||||
| $xatoms = array(); | $xatoms = array(); | ||||
| } | } | ||||
| foreach ($atoms as $atom) { | foreach ($atoms as $atom) { | ||||
| $alang = $atom->getAtom()->getLanguage(); | $atom_lang = null; | ||||
| $atom_extends = array(); | |||||
| if ($atom->getAtom()) { | |||||
| $atom_lang = $atom->getAtom()->getLanguage(); | |||||
| $atom_extends = $atom->getAtom()->getExtends(); | |||||
| } | |||||
| $extends = array(); | $extends = array(); | ||||
| foreach ($atom->getAtom()->getExtends() as $xref) { | |||||
| foreach ($atom_extends as $xref) { | |||||
| // If there are no symbols of the matching name and type, we can't | // If there are no symbols of the matching name and type, we can't | ||||
| // resolve this. | // resolve this. | ||||
| if (empty($xatoms[$xref->getName()][$xref->getType()])) { | if (empty($xatoms[$xref->getName()][$xref->getType()])) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| // If we found matches in the same documentation book, prefer them | // If we found matches in the same documentation book, prefer them | ||||
| // over other matches. Otherwise, look at all the the matches. | // over other matches. Otherwise, look at all the the matches. | ||||
| $matches = $xatoms[$xref->getName()][$xref->getType()]; | $matches = $xatoms[$xref->getName()][$xref->getType()]; | ||||
| if (isset($matches[$atom->getBookPHID()])) { | if (isset($matches[$atom->getBookPHID()])) { | ||||
| $maybe = $matches[$atom->getBookPHID()]; | $maybe = $matches[$atom->getBookPHID()]; | ||||
| } else { | } else { | ||||
| $maybe = array_mergev($matches); | $maybe = array_mergev($matches); | ||||
| } | } | ||||
| if (!$maybe) { | if (!$maybe) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| // Filter out matches in a different language, since, e.g., PHP | // Filter out matches in a different language, since, e.g., PHP | ||||
| // classes can not implement JS classes. | // classes can not implement JS classes. | ||||
| $same_lang = array(); | $same_lang = array(); | ||||
| foreach ($maybe as $xatom) { | foreach ($maybe as $xatom) { | ||||
| if ($xatom->getAtom()->getLanguage() == $alang) { | if ($xatom->getAtom()->getLanguage() == $atom_lang) { | ||||
| $same_lang[] = $xatom; | $same_lang[] = $xatom; | ||||
| } | } | ||||
| } | } | ||||
| if (!$same_lang) { | if (!$same_lang) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 163 Lines • ▼ Show 20 Lines | final class DivinerAtomQuery extends PhabricatorCursorPagedPolicyAwareQuery { | ||||
| * as well. | * as well. | ||||
| * @return map<string, string> Hashes of atoms' children. | * @return map<string, string> Hashes of atoms' children. | ||||
| */ | */ | ||||
| private function getAllChildHashes(array $symbols, $recurse_up) { | private function getAllChildHashes(array $symbols, $recurse_up) { | ||||
| assert_instances_of($symbols, 'DivinerLiveSymbol'); | assert_instances_of($symbols, 'DivinerLiveSymbol'); | ||||
| $hashes = array(); | $hashes = array(); | ||||
| foreach ($symbols as $symbol) { | foreach ($symbols as $symbol) { | ||||
| foreach ($symbol->getAtom()->getChildHashes() as $hash) { | $child_hashes = array(); | ||||
| if ($symbol->getAtom()) { | |||||
| $child_hashes = $symbol->getAtom()->getChildHashes(); | |||||
| } | |||||
| foreach ($child_hashes as $hash) { | |||||
| $hashes[$hash] = $hash; | $hashes[$hash] = $hash; | ||||
| } | } | ||||
| if ($recurse_up) { | if ($recurse_up) { | ||||
| $hashes += $this->getAllChildHashes($symbol->getExtends(), true); | $hashes += $this->getAllChildHashes($symbol->getExtends(), true); | ||||
| } | } | ||||
| } | } | ||||
| return $hashes; | return $hashes; | ||||
| Show All 13 Lines | private function attachAllChildren( | ||||
| array $symbols, | array $symbols, | ||||
| array $children, | array $children, | ||||
| $recurse_up) { | $recurse_up) { | ||||
| assert_instances_of($symbols, 'DivinerLiveSymbol'); | assert_instances_of($symbols, 'DivinerLiveSymbol'); | ||||
| assert_instances_of($children, 'DivinerLiveSymbol'); | assert_instances_of($children, 'DivinerLiveSymbol'); | ||||
| foreach ($symbols as $symbol) { | foreach ($symbols as $symbol) { | ||||
| $child_hashes = array(); | |||||
| $symbol_children = array(); | $symbol_children = array(); | ||||
| foreach ($symbol->getAtom()->getChildHashes() as $hash) { | |||||
| if ($symbol->getAtom()) { | |||||
| $child_hashes = $symbol->getAtom()->getChildHashes(); | |||||
| } | |||||
| foreach ($child_hashes as $hash) { | |||||
| if (isset($children[$hash])) { | if (isset($children[$hash])) { | ||||
| $symbol_children[] = $children[$hash]; | $symbol_children[] = $children[$hash]; | ||||
| } | } | ||||
| } | } | ||||
| $symbol->attachChildren($symbol_children); | $symbol->attachChildren($symbol_children); | ||||
| if ($recurse_up) { | if ($recurse_up) { | ||||
| $this->attachAllChildren($symbol->getExtends(), $children, true); | $this->attachAllChildren($symbol->getExtends(), $children, true); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| public function getQueryApplicationClass() { | public function getQueryApplicationClass() { | ||||
| return 'PhabricatorDivinerApplication'; | return 'PhabricatorDivinerApplication'; | ||||
| } | } | ||||
| } | } | ||||