diff --git a/ChangeLog.md b/ChangeLog.md index 71ba294c..aa6f1e31 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -3,6 +3,12 @@ XP Compiler ChangeLog ## ?.?.? / ????-??-?? +## 8.2.0 / 2022-01-30 + +* Support passing emitter-augmenting class names to the instanceFor() + method of `lang.ast.CompilingClassLoader`. + (@thekid) + ## 8.1.0 / 2022-01-29 * Merged PR #131: Inline nullable checks when casting - @thekid diff --git a/src/main/php/lang/ast/CompilingClassloader.class.php b/src/main/php/lang/ast/CompilingClassloader.class.php index 2f509f59..b8f04102 100755 --- a/src/main/php/lang/ast/CompilingClassloader.class.php +++ b/src/main/php/lang/ast/CompilingClassloader.class.php @@ -28,7 +28,7 @@ static function __static() { /** Creates a new instances with a given PHP runtime */ private function __construct($emit) { - $this->version= str_replace('⋈', '+', $emit->getSimpleName()); + $this->version= strtr($emit->getSimpleName(), ['⋈' => '+', '·' => '.']); Compiled::$emit[$this->version]= $emit->newInstance(); stream_wrapper_register($this->version, Compiled::class); @@ -242,13 +242,14 @@ public function instanceId() { } /** - * Fetch instance of classloader by path + * Fetch instance of classloader by version * - * @param string path the identifier - * @return lang.IClassLoader + * @param string $version + * @return lang.IClassLoader */ public static function instanceFor($version) { - $emit= Emitter::forRuntime($version, [XpMeta::class]); + sscanf($version, "%[^+]+%[^\r]", $emitter, $augmented); + $emit= Emitter::forRuntime($emitter, $augmented ? explode('+', $augmented) : [XpMeta::class]); $id= $emit->getName(); if (!isset(self::$instance[$id])) { diff --git a/src/main/php/lang/ast/Emitter.class.php b/src/main/php/lang/ast/Emitter.class.php index 53c12927..c7cc5b1a 100755 --- a/src/main/php/lang/ast/Emitter.class.php +++ b/src/main/php/lang/ast/Emitter.class.php @@ -29,11 +29,10 @@ public static function forRuntime($runtime, $emitters= []) { $extended= ['kind' => 'class', 'extends' => [$p->loadClass($impl)], 'implements' => [], 'use' => []]; foreach ($emitters as $class) { if ($class instanceof XPClass) { - $impl.= '⋈'.$class->getSimpleName(); + $impl.= '⋈'.strtr($class->getName(), ['.' => '·']); $extended['use'][]= $class; } else { - $d= strrpos(strtr($class, '\\', '.'), '.'); - $impl.= '⋈'.(false === $d ? $class : substr($class, $d + 1)); + $impl.= '⋈'.strtr($class, ['.' => '·', '\\' => '·']); $extended['use'][]= XPClass::forName($class); } } diff --git a/src/test/php/lang/ast/unittest/loader/CompilingClassLoaderTest.class.php b/src/test/php/lang/ast/unittest/loader/CompilingClassLoaderTest.class.php index 6188491c..1ed682f0 100755 --- a/src/test/php/lang/ast/unittest/loader/CompilingClassLoaderTest.class.php +++ b/src/test/php/lang/ast/unittest/loader/CompilingClassLoaderTest.class.php @@ -54,12 +54,12 @@ public function supports_php($version) { #[Test] public function string_representation() { - Assert::equals('CompilingCL', CompilingClassLoader::instanceFor('php:7.0.0')->toString()); + Assert::equals('CompilingCL', CompilingClassLoader::instanceFor('php:7.0.0')->toString()); } #[Test] public function hashcode() { - Assert::equals('CPHP70+XpMeta', CompilingClassLoader::instanceFor('php:7.0.0')->hashCode()); + Assert::equals('CPHP70+lang.ast.emit.php.XpMeta', CompilingClassLoader::instanceFor('php:7.0.0')->hashCode()); } #[Test] @@ -77,6 +77,14 @@ public function compare() { Assert::equals(1, $cl->compareTo(null), 'does not equal null'); } + #[Test] + public function instanced_for_augmented() { + Assert::equals( + 'PHP80+lang.ast.emit.php.XpMeta', + CompilingClassLoader::instanceFor('php:8.0.0+lang.ast.emit.php.XpMeta')->instanceId() + ); + } + #[Test] public function package_contents() { $contents= $this->compile(['Tests' => '