Changeset View
Changeset View
Standalone View
Standalone View
src/infrastructure/edges/type/PhabricatorEdgeType.php
Show First 20 Lines • Show All 150 Lines • ▼ Show 20 Lines | /* -( Loading Types )------------------------------------------------------ */ | ||||
/** | /** | ||||
* @task load | * @task load | ||||
*/ | */ | ||||
public static function getAllTypes() { | public static function getAllTypes() { | ||||
static $type_map; | static $type_map; | ||||
if ($type_map === null) { | if ($type_map === null) { | ||||
$types = id(new PhutilSymbolLoader()) | $types = id(new PhutilClassMapQuery()) | ||||
->setAncestorClass(__CLASS__) | ->setAncestorClass(__CLASS__) | ||||
->loadObjects(); | ->setUniqueMethod('getEdgeConstant') | ||||
->execute(); | |||||
$map = array(); | |||||
foreach ($types as $class => $type) { | |||||
$const = $type->getEdgeConstant(); | |||||
if (isset($map[$const])) { | |||||
throw new Exception( | |||||
pht( | |||||
'Two edge types ("%s", "%s") share the same edge constant '. | |||||
'(%d). Each edge type must have a unique constant.', | |||||
$class, | |||||
get_class($map[$const]), | |||||
$const)); | |||||
} | |||||
$map[$const] = $type; | |||||
} | |||||
// Check that all the inverse edge definitions actually make sense. If | // Check that all the inverse edge definitions actually make sense. If | ||||
// edge type A says B is its inverse, B must exist and say that A is its | // edge type A says B is its inverse, B must exist and say that A is its | ||||
// inverse. | // inverse. | ||||
foreach ($map as $const => $type) { | foreach ($types as $const => $type) { | ||||
$inverse = $type->getInverseEdgeConstant(); | $inverse = $type->getInverseEdgeConstant(); | ||||
if ($inverse === null) { | if ($inverse === null) { | ||||
continue; | continue; | ||||
} | } | ||||
if (empty($map[$inverse])) { | if (empty($types[$inverse])) { | ||||
throw new Exception( | throw new Exception( | ||||
pht( | pht( | ||||
'Edge type "%s" ("%d") defines an inverse type ("%d") which '. | 'Edge type "%s" ("%d") defines an inverse type ("%d") which '. | ||||
'does not exist.', | 'does not exist.', | ||||
get_class($type), | get_class($type), | ||||
$const, | $const, | ||||
$inverse)); | $inverse)); | ||||
} | } | ||||
$inverse_inverse = $map[$inverse]->getInverseEdgeConstant(); | $inverse_inverse = $types[$inverse]->getInverseEdgeConstant(); | ||||
if ($inverse_inverse !== $const) { | if ($inverse_inverse !== $const) { | ||||
throw new Exception( | throw new Exception( | ||||
pht( | pht( | ||||
'Edge type "%s" ("%d") defines an inverse type ("%d"), but that '. | 'Edge type "%s" ("%d") defines an inverse type ("%d"), but that '. | ||||
'inverse type defines a different type ("%d") as its '. | 'inverse type defines a different type ("%d") as its '. | ||||
'inverse.', | 'inverse.', | ||||
get_class($type), | get_class($type), | ||||
$const, | $const, | ||||
$inverse, | $inverse, | ||||
$inverse_inverse)); | $inverse_inverse)); | ||||
} | } | ||||
} | } | ||||
$type_map = $map; | $type_map = $types; | ||||
} | } | ||||
return $type_map; | return $type_map; | ||||
} | } | ||||
/** | /** | ||||
* @task load | * @task load | ||||
Show All 13 Lines |