-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
::namespace #178
Labels
Comments
This would break class constants named namespace: $ xp -w 'class T { const namespace = "ns"; } return T::namespace'
ns |
Implementation: diff --git a/src/main/php/lang/ast/emit/PHP.class.php b/src/main/php/lang/ast/emit/PHP.class.php
index fe08e57..6342402 100755
--- a/src/main/php/lang/ast/emit/PHP.class.php
+++ b/src/main/php/lang/ast/emit/PHP.class.php
@@ -1086,17 +1086,17 @@ abstract class PHP extends Emitter {
$result->out->write("{$scope->type}::");
}
- // Rewrite T::member to T::$member for XP enums
- if (
- $scope->member instanceof Literal &&
- is_string($scope->type) &&
- 'class' !== $scope->member->expression &&
- $result->codegen->lookup($scope->type)->rewriteEnumCase($scope->member->expression)
- ) {
- $result->out->write('$'.$scope->member->expression);
- } else {
- $this->emitOne($result, $scope->member);
+ // Rewrite ::class and ::namespace to namespace resolution; T::member to T::$member for XP enums
+ if ($scope->member instanceof Literal) {
+ if ('namespace' === $scope->member->expression || 'class' === $scope->member->expression) {
+ $result->out->write('class');
+ return;
+ } else if (is_string($scope->type) && $result->codegen->lookup($scope->type)->rewriteEnumCase($scope->member->expression)) {
+ $result->out->write('$'.$scope->member->expression);
+ return;
+ }
}
+ $this->emitOne($result, $scope->member);
}
protected function emitInstance($result, $instance) {
diff --git a/src/test/php/lang/ast/unittest/emit/NamespacesTest.class.php b/src/test/php/lang/ast/unittest/emit/NamespacesTest.class.php
index 7fe7dcc..8db6133 100755
--- a/src/test/php/lang/ast/unittest/emit/NamespacesTest.class.php
+++ b/src/test/php/lang/ast/unittest/emit/NamespacesTest.class.php
@@ -84,4 +84,14 @@ class NamespacesTest extends EmittingTest {
}');
Assert::equals(new Date('1977-12-14'), $r);
}
+
+ #[Test]
+ public function namespace_resolution() {
+ $r= $this->run('namespace util; class %T {
+ public function run() {
+ return cmd::namespace;
+ }
+ }');
+ Assert::equals('util\\cmd', $r);
+ }
}
\ No newline at end of file |
Someone suggested this to return the namespace name of a class in https://externals.io/message/113269: use util\cmd\Console;
$ns= Console::namespace; // "util\cmd" If we introduced this feature as described above, the above would yield "util\cmd\Console". Currently, it yields an error for an undefined class constant. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
How about using
::namespace
for namespace resolution just like::class
?Example:
This would simply be emitted as
::class
, which already does everything we want; however, usingapi::class
in this place doesn't convey the intent correctly!The text was updated successfully, but these errors were encountered: