mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-22 06:42:41 +01:00
Arc liberate: support traits
Summary: Looks like this is all that's needed? Ref T15751 Test Plan: R12 has some scenarios for testing this. Also ran `arc liberate --clean` on arc and phorge repos, and the generated map did not change. Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15751 Differential Revision: https://we.phorge.it/D25551
This commit is contained in:
parent
7c5e607e97
commit
f6261dc614
3 changed files with 32 additions and 21 deletions
|
@ -332,11 +332,16 @@ final class PhutilLibraryMapBuilder extends Phobject {
|
||||||
'xmap' => array(),
|
'xmap' => array(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$type_translation = array(
|
||||||
|
'interface' => 'class',
|
||||||
|
'trait' => 'class',
|
||||||
|
);
|
||||||
|
|
||||||
// Detect duplicate symbols within the library.
|
// Detect duplicate symbols within the library.
|
||||||
foreach ($symbol_map as $file => $info) {
|
foreach ($symbol_map as $file => $info) {
|
||||||
foreach ($info['have'] as $type => $symbols) {
|
foreach ($info['have'] as $type => $symbols) {
|
||||||
foreach ($symbols as $symbol => $declaration) {
|
foreach ($symbols as $symbol => $declaration) {
|
||||||
$lib_type = ($type == 'interface') ? 'class' : $type;
|
$lib_type = idx($type_translation, $type, $type);
|
||||||
if (!empty($library_map[$lib_type][$symbol])) {
|
if (!empty($library_map[$lib_type][$symbol])) {
|
||||||
$prior = $library_map[$lib_type][$symbol];
|
$prior = $library_map[$lib_type][$symbol];
|
||||||
throw new Exception(
|
throw new Exception(
|
||||||
|
|
|
@ -398,6 +398,12 @@ final class PhutilSymbolLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static function classLikeExists($name) {
|
||||||
|
return class_exists($name, false) ||
|
||||||
|
interface_exists($name, false) ||
|
||||||
|
trait_exists($name, false);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @task internal
|
* @task internal
|
||||||
*/
|
*/
|
||||||
|
@ -411,7 +417,7 @@ final class PhutilSymbolLoader {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (class_exists($name, false) || interface_exists($name, false)) {
|
if (self::classLikeExists($name)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -431,7 +437,7 @@ final class PhutilSymbolLoader {
|
||||||
$load_failed = pht('function');
|
$load_failed = pht('function');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!class_exists($name, false) && !interface_exists($name, false)) {
|
if (!self::classLikeExists($name)) {
|
||||||
$load_failed = pht('class or interface');
|
$load_failed = pht('class or interface');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,18 +112,6 @@ foreach ($namespaces as $namespace) {
|
||||||
$namespace, $path, pht('namespace `%s` statements', 'use'));
|
$namespace, $path, pht('namespace `%s` statements', 'use'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$possible_traits = $root->selectDescendantsOfType('n_CLASS_DECLARATION');
|
|
||||||
foreach ($possible_traits as $possible_trait) {
|
|
||||||
$attributes = $possible_trait->getChildByIndex(0);
|
|
||||||
// Can't use getChildByIndex here because not all classes have attributes
|
|
||||||
foreach ($attributes->getChildren() as $attribute) {
|
|
||||||
if (strtolower($attribute->getConcreteString()) === 'trait') {
|
|
||||||
phutil_fail_on_unsupported_feature($possible_trait, $path, pht('traits'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -( Marked Externals )------------------------------------------------------
|
// -( Marked Externals )------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
@ -256,17 +244,29 @@ foreach ($calls as $call) {
|
||||||
|
|
||||||
// Find classes declared by this file.
|
// Find classes declared by this file.
|
||||||
|
|
||||||
|
|
||||||
// This is "class X ... { ... }".
|
// This is "class X ... { ... }".
|
||||||
$classes = $root->selectDescendantsOfType('n_CLASS_DECLARATION');
|
function build_have_element_for_class_declaration(XHPASTNode $class_node) {
|
||||||
foreach ($classes as $class) {
|
$class_name = $class_node->getChildByIndex(1);
|
||||||
$class_name = $class->getChildByIndex(1);
|
|
||||||
$have[] = array(
|
$type = 'class';
|
||||||
'type' => 'class',
|
$attributes = $class_node->getChildByIndex(0);
|
||||||
|
foreach ($attributes->getChildren() as $attribute) {
|
||||||
|
if (strtolower($attribute->getConcreteString()) === 'trait') {
|
||||||
|
$type = 'trait';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'type' => $type,
|
||||||
'symbol' => $class_name,
|
'symbol' => $class_name,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$classes = $root->selectDescendantsOfType('n_CLASS_DECLARATION');
|
||||||
|
foreach ($classes as $class) {
|
||||||
|
$have[] = build_have_element_for_class_declaration($class);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Find classes used by this file. We identify these:
|
// Find classes used by this file. We identify these:
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in a new issue