Skip to content

Commit a6fb5f5

Browse files
authored
Merge pull request #45 from xp-framework/feature/package
Add `Reflection::package()` utility method
2 parents 54a1e67 + fad0292 commit a6fb5f5

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

src/main/php/lang/Reflection.class.php

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
use lang\meta\{MetaInformation, FromSyntaxTree, FromAttributes};
44
use lang\reflection\{Type, Package};
5-
use lang\{ClassLoader, ClassNotFoundException};
5+
use lang\{ClassLoader, ClassNotFoundException, IllegalArgumentException};
66

77
/**
88
* Factory for reflection instances.
@@ -56,6 +56,35 @@ public static function type($arg) {
5656
}
5757
}
5858

59+
/**
60+
* Returns a reflection package for a given argument.
61+
*
62+
* @param string|object|lang.XPClass|lang.reflection.Type|ReflectionClass $arg
63+
* @return lang.reflection.Type
64+
* @throws lang.IllegalArgumentException
65+
*/
66+
public static function package($arg) {
67+
if ($arg instanceof XPClass) {
68+
return new Package($arg->getPackage()->getName());
69+
} else if ($arg instanceof \ReflectionClass) {
70+
return new Package($arg->getNamespaceName());
71+
} else if ($arg instanceof Type) {
72+
return $arg->package();
73+
} else if (is_object($arg)) {
74+
$class= get_class($arg);
75+
return new Package(substr($class, 0, strrpos($class, '\\')));
76+
} else {
77+
$cl= ClassLoader::getDefault();
78+
$name= strtr($arg, '\\', '.');
79+
if ($cl->providesPackage($name)) {
80+
return new Package($name);
81+
} else if ($cl->providesClass($name)) {
82+
return new Package(substr($name, 0, strrpos($name, '.')));
83+
}
84+
throw new IllegalArgumentException('No package named '.$name);
85+
}
86+
}
87+
5988
/**
6089
* Creates a new reflection instance, which may either refer to a type
6190
* or to a package.

src/test/php/lang/reflection/unittest/ReflectionTest.class.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,19 @@ private function arguments() {
1919
yield [new ReflectionObject($this), 'reflection object'];
2020
}
2121

22+
/** @return iterable */
23+
private function packages() {
24+
yield [__NAMESPACE__, 'namespace literal'];
25+
yield ['lang.reflection.unittest', 'namespace name'];
26+
yield [self::class, 'class literal'];
27+
yield [nameof($this), 'class name'];
28+
yield [$this, 'instance'];
29+
yield [Type::forName(self::class), 'type'];
30+
yield [Reflection::of(self::class), 'reflection'];
31+
yield [new ReflectionClass($this), 'reflection class'];
32+
yield [new ReflectionObject($this), 'reflection object'];
33+
}
34+
2235
#[Test, Values(from: 'arguments')]
2336
public function of($argument) {
2437
Assert::equals(nameof($this), Reflection::of($argument)->name());
@@ -29,6 +42,11 @@ public function type($argument) {
2942
Assert::equals(nameof($this), Reflection::type($argument)->name());
3043
}
3144

45+
#[Test, Values(from: 'packages')]
46+
public function package($argument) {
47+
Assert::equals(new Package('lang.reflection.unittest'), Reflection::package($argument));
48+
}
49+
3250
#[Test]
3351
public function of_package_name() {
3452
Assert::instance(Package::class, Reflection::of('lang.reflection.unittest'));

0 commit comments

Comments
 (0)