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}
0 commit comments