Skip to content

Commit 440bf0d

Browse files
authored
Merge pull request #40 from xp-framework/feature/global-package
Add support for the global package
2 parents 802fbfd + b472246 commit 440bf0d

File tree

4 files changed

+67
-16
lines changed

4 files changed

+67
-16
lines changed

src/main/php/lang/reflection/Package.class.php

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
<?php namespace lang\reflection;
22

3-
use lang\{ClassLoader, IClassLoader, Reflection, IllegalArgumentException};
3+
use lang\{ClassLoader, IClassLoader, Reflection, IllegalArgumentException, Value};
44

55
/**
66
* Represents a namespace, which may exist in various class loaders
77
*
88
* @test lang.reflection.unittest.PackageTest
99
*/
10-
class Package {
10+
class Package implements Value {
1111
private $name;
1212

1313
/**
@@ -21,6 +21,9 @@ public function __construct(... $components) {
2121
$this->name= rtrim(strtr(implode('.', $components), '\\', '.'), '.');
2222
}
2323

24+
/** Returns whether this is the global package */
25+
public function global(): bool { return '' === $this->name; }
26+
2427
/** Returns this package's name (in dotted form) */
2528
public function name(): string { return $this->name; }
2629

@@ -39,13 +42,16 @@ public function classLoaders() {
3942
}
4043

4144
/**
42-
* Returns this package's parent, if any
45+
* Returns this package's parent. Returns NULL if this package refers to the
46+
* global package.
4347
*
4448
* @return ?self
4549
*/
4650
public function parent() {
51+
if ('' === $this->name) return null;
52+
4753
$p= strrpos($this->name, '.');
48-
return false === $p ? null : new Package(substr($this->name, 0, $p));
54+
return false === $p ? new Package() : new Package(substr($this->name, 0, $p));
4955
}
5056

5157
/**
@@ -54,7 +60,7 @@ public function parent() {
5460
* @return iterable
5561
*/
5662
public function children() {
57-
$base= $this->name.'.';
63+
$base= $this->name ? $this->name.'.' : '';
5864
$loader= ClassLoader::getDefault();
5965
foreach ($loader->packageContents($this->name) as $entry) {
6066
if ('/' === $entry[strlen($entry) - 1]) {
@@ -70,7 +76,7 @@ public function children() {
7076
*/
7177
public function types() {
7278
$ext= strlen(\xp::CLASS_FILE_EXT);
73-
$base= $this->name.'.';
79+
$base= $this->name ? $this->name.'.' : '';
7480
$loader= ClassLoader::getDefault();
7581
foreach ($loader->packageContents($this->name) as $entry) {
7682
if (0 === substr_compare($entry, \xp::CLASS_FILE_EXT, -$ext)) {
@@ -87,15 +93,36 @@ public function types() {
8793
* @throws lang.IllegalArgumentException
8894
*/
8995
public function type($name) {
96+
if ('' === $this->name) return Reflection::type($name);
97+
98+
// Compare type package and this package
9099
$type= strtr($name, '\\', '.');
91100
$p= strrpos($type, '.');
92-
93101
if (false === $p) {
94-
return Reflection::of($this->name.'.'.$type);
102+
return Reflection::type($this->name.'.'.$type);
95103
} else if (0 === strncmp($this->name, $type, $p)) {
96-
return Reflection::of($type);
97-
} else {
98-
throw new IllegalArgumentException('Given type '.$type.' is not in package '.$this->name);
104+
return Reflection::type($type);
99105
}
106+
107+
throw new IllegalArgumentException('Given type '.$type.' is not in package '.$this->name);
108+
}
109+
110+
/** @return string */
111+
public function hashCode() { return md5($this->name); }
112+
113+
/** @return string */
114+
public function toString() { return nameof($this).'<'.$this->name().'>'; }
115+
116+
/**
117+
* Compares this member to another value
118+
*
119+
* @param var $value
120+
* @return int
121+
*/
122+
public function compareTo($value) {
123+
return $value instanceof self
124+
? $this->name <=> $value->name
125+
: 1
126+
;
100127
}
101128
}

src/main/php/lang/reflection/Type.class.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,12 @@ public function is($type): bool {
8383
}
8484

8585
/**
86-
* Returns this type's package, or NULL if this type is in the global namespace.
86+
* Returns this type's package
8787
*
88-
* @return ?lang.reflection.Package
88+
* @return lang.reflection.Package
8989
*/
9090
public function package() {
91-
$name= $this->reflect->getNamespaceName();
92-
return $name ? new Package($name) : null;
91+
return new Package($this->reflect->getNamespaceName());
9392
}
9493

9594
/**

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,21 @@ public function name($arg) {
1111
Assert::equals('lang.reflection', (new Package($arg))->name());
1212
}
1313

14+
#[Test]
15+
public function global() {
16+
Assert::true((new Package())->global());
17+
}
18+
19+
#[Test, Values(['lang', 'lang.reflection', 'lang.reflect.unittest'])]
20+
public function leveled($package) {
21+
Assert::false((new Package($package))->global());
22+
}
23+
24+
#[Test]
25+
public function global_name() {
26+
Assert::equals('', (new Package())->name());
27+
}
28+
1429
#[Test]
1530
public function create_via_components() {
1631
Assert::equals('lang.reflection.unittest', (new Package('lang', 'reflection', 'unittest'))->name());
@@ -26,6 +41,16 @@ public function parent() {
2641
Assert::equals(new Package('lang'), (new Package('lang.reflection'))->parent());
2742
}
2843

44+
#[Test]
45+
public function parent_of_toplevel() {
46+
Assert::equals(new Package(), (new Package('lang'))->parent());
47+
}
48+
49+
#[Test]
50+
public function global_package_has_no_parent() {
51+
Assert::null((new Package())->parent());
52+
}
53+
2954
#[Test]
3055
public function children() {
3156
Assert::equals(

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public function package() {
5151

5252
#[Test]
5353
public function global_namespace() {
54-
Assert::null(Reflection::of(\Throwable::class)->package());
54+
Assert::equals(new Package(), Reflection::of(\Throwable::class)->package());
5555
}
5656

5757
#[Test]

0 commit comments

Comments
 (0)