Skip to content

Commit 39f40d8

Browse files
committed
Allow extending classes and implementing interfaces from modules
1 parent efa65b6 commit 39f40d8

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

src/main/php/lang/ClassLoader.class.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ public static function registerLoader(IClassLoader $l, $before= false) {
134134
*/
135135
public static function declareModule($l) {
136136
$moduleInfo= $l->getResource('module.xp');
137-
if (!preg_match('/module ([a-z_\/\.-]+)(\(([^\)]+)\))?\s*{/', $moduleInfo, $m)) {
137+
if (!preg_match('/module ([a-z_\/\.-]+)(.*){/', $moduleInfo, $m)) {
138138
raise('lang.ElementNotFoundException', 'Missing or malformed module-info in '.$l->toString());
139139
}
140140

@@ -145,9 +145,15 @@ public static function declareModule($l) {
145145
$class= $decl;
146146
}
147147

148+
if (strstr($m[2], 'extends')) {
149+
$parent= $m[2];
150+
} else {
151+
$parent= ' extends \lang\reflect\Module '.$m[2];
152+
}
153+
148154
$dyn= DynamicClassLoader::instanceFor('modules');
149155
$dyn->setClassBytes($class, strtr($moduleInfo, [
150-
$m[0] => 'class '.$decl.' extends \lang\reflect\Module {',
156+
$m[0] => 'class '.$decl.$parent.'{',
151157
'<?php' => '', '?>' => ''
152158
]));
153159
return $dyn->loadClass($class)->newInstance($m[1], $l);

src/test/php/net/xp_framework/unittest/reflection/ModuleLoadingTest.class.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,4 +85,22 @@ public function initialize() {
8585
}']));
8686
$this->assertEquals(1, Module::forName('xp-framework/initialized')->initialized);
8787
}
88+
89+
#[@test]
90+
public function module_inheritance() {
91+
$cl= ClassLoader::defineClass('net.xp_framework.unittest.reflection.BaseModule', 'lang.reflect.Module', []);
92+
$this->register(new LoaderProviding([
93+
'module.xp' => '<?php module xp-framework/child extends net\xp_framework\unittest\reflection\BaseModule { }'
94+
]));
95+
$this->assertEquals($cl, Module::forName('xp-framework/child')->getClass()->getParentclass());
96+
}
97+
98+
#[@test]
99+
public function module_implementation() {
100+
$cl= ClassLoader::defineInterface('net.xp_framework.unittest.reflection.IModule', []);
101+
$this->register(new LoaderProviding([
102+
'module.xp' => '<?php module xp-framework/impl implements net\xp_framework\unittest\reflection\IModule { }'
103+
]));
104+
$this->assertTrue(in_array($cl, Module::forName('xp-framework/impl')->getClass()->getInterfaces()));
105+
}
88106
}

0 commit comments

Comments
 (0)