Skip to content

Commit 50f4d99

Browse files
committed
Fix #10 and generic components resolution inside namespaces
1 parent a1d6e9c commit 50f4d99

File tree

3 files changed

+21
-16
lines changed

3 files changed

+21
-16
lines changed

ChangeLog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ XP generics for PHP - ChangeLog
55

66
## 2.1.0 / 2024-08-04
77

8+
* Fixed generic type component resolution inside namespaces - @thekid
9+
* Fixed issue #10: *Undefined property: lang\ast\types\IsValue::$name*
10+
(@thekid)
811
* Merged PR #9: Implement resolving `T<string>::class` - @thekid
912

1013
## 2.0.1 / 2024-08-03

src/main/php/lang/ast/syntax/php/Generics.class.php

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -46,41 +46,42 @@ public static function components($types) {
4646
*
4747
* @param lang.ast.types.IsGeneric $type
4848
* @param ?lang.ast.nodes.TypeDeclaration $enclosing
49+
* @param bool literal
4950
* @param string
5051
*/
51-
public static function typename($type, $enclosing) {
52+
public static function typename($type, $enclosing, $literal= false) {
5253
if (null === $enclosing || $type instanceof IsLiteral) {
5354
return $type->name();
5455
} else if ($type instanceof IsGeneric) {
5556
$components= '';
5657
foreach ($type->components as $component) {
57-
$components.= ', '.self::typename($component, $enclosing);
58+
$components.= ', '.self::typename($component, $enclosing, $literal);
5859
}
59-
return self::typename($type->base, $enclosing).'<'.substr($components, 2).'>';
60+
return self::typename($type->base, $enclosing, $literal).'<'.substr($components, 2).'>';
6061
} else if ($type instanceof IsArray) {
61-
return self::typename($type->component, $enclosing).'[]';
62+
return self::typename($type->component, $enclosing, $literal).'[]';
6263
} else if ($type instanceof IsMap) {
63-
return '[:'.self::typename($type->value, $enclosing).']';
64+
return '[:'.self::typename($type->value, $enclosing, $literal).']';
6465
} else if ($type instanceof IsNullable) {
65-
return '?'.self::typename($type->element, $enclosing);
66+
return '?'.self::typename($type->element, $enclosing, $literal);
6667
} else if ($type instanceof IsUnion) {
6768
$union= '';
6869
foreach ($type->components as $component) {
69-
$union.= '|'.self::typename($component, $enclosing);
70+
$union.= '|'.self::typename($component, $enclosing, $literal);
7071
}
7172
return substr($union, 1);
7273
} else if ($type instanceof IsIntersection) {
7374
$intersection= '';
7475
foreach ($type->components as $component) {
75-
$intersection.= '&'.self::typename($component, $enclosing);
76+
$intersection.= '&'.self::typename($component, $enclosing, $literal);
7677
}
7778
return substr($intersection, 1);
7879
} else if ($type instanceof IsFunction) {
7980
$parameters= '';
8081
foreach ($type->signature as $parameter) {
81-
$parameters.= ', '.self::typename($parameter, $enclosing);
82+
$parameters.= ', '.self::typename($parameter, $enclosing, $literal);
8283
}
83-
return '(function('.substr($parameters, 2).'): '.self::typename($type->returns, $enclosing).')';
84+
return '(function('.substr($parameters, 2).'): '.self::typename($type->returns, $enclosing, $literal).')';
8485
} else if ('self' === $type->literal || 'static' === $type->literal) {
8586
return $enclosing->name->name();
8687
} else if ('parent' === $type->literal) {
@@ -89,7 +90,8 @@ public static function typename($type, $enclosing) {
8990
$enclosing->name instanceof IsGenericDeclaration &&
9091
in_array($type->literal(), $enclosing->name->components())
9192
) {
92-
return "'.\${$type->name()}->getName().'";
93+
$component= '$'.substr($type->literal, strrpos($type->literal, '\\') + 1);
94+
return $literal ? $component : "'.{$component}->getName().'";
9395
} else {
9496
return $type->name();
9597
}
@@ -148,8 +150,8 @@ public static function method($method, $type) {
148150
// Check all parameter types
149151
$params= [];
150152
foreach ($method->signature->parameters as $parameter) {
151-
if ($parameter->type && false !== strpos(self::typename($parameter->type, $type), '$')) {
152-
$params[]= $parameter->type->name().($parameter->variadic ? '...' : '');
153+
if ($parameter->type && false !== strpos($name= self::typename($parameter->type, $type, true), '$')) {
154+
$params[]= str_replace('$', '', $name).($parameter->variadic ? '...' : '');
153155
$parameter->type= null;
154156
} else {
155157
$params[]= '';
@@ -158,8 +160,8 @@ public static function method($method, $type) {
158160
$params && $r[]= [new Literal("'params'"), new Literal("'".implode(', ', $params)."'")];
159161

160162
// Check return type
161-
if ($method->signature->returns && false !== strpos(self::typename($method->signature->returns, $type), '$')) {
162-
$r[]= [new Literal("'return'"), new Literal("'".$method->signature->returns->name()."'")];
163+
if ($method->signature->returns && false !== strpos($name= self::typename($method->signature->returns, $type, true), '$')) {
164+
$r[]= [new Literal("'return'"), new Literal("'".str_replace('$', '', $name)."'")];
163165
$method->signature->returns= null;
164166
}
165167

src/test/php/lang/ast/syntax/php/unittest/GenericsTest.class.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ public static function fixture() {
189189

190190
#[Test]
191191
public function string_queue() {
192-
$r= $this->run('class %T<E> {
192+
$r= $this->run('namespace test; class %T<E> {
193193
private array<E> $elements= [];
194194
195195
public function __construct(E... $elements) {

0 commit comments

Comments
 (0)