-
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
Support generic methods #3
Labels
Comments
thekid
added
enhancement
New feature or request
help wanted
Extra attention is needed
labels
Nov 12, 2022
The call introduces an ambiguity in the parser, which would need to be solved by looking ahead for a closing $reverse= self::reverse<string>($list)
// ^
// Up until here... ----------´
// ...it could also be a class constant, which is compared with "less than" to a constant, e.g:
$reverse= self::reverse < string;
$mismatch= self::REQUIRED < PHP_VERSION; |
The call to reverse() could be rewritten as follows: // self::reverse($list), infer type
invoke(self::class, 'reverse', [], $list);
// self::reverse<string>($list), supply type
invoke(self::class, 'reverse', ['string'], $list); The reverse() method is emitted as follows: #[Generic(self: 'E', params: 'List<E>')]
public function reverse($list) {
for ($i= $list->size() - 1; $i >= 0; $i--) {
yield $list->get($i);
}
} The invoke() helper would:
|
Testdiff --git a/src/test/php/lang/ast/syntax/php/unittest/MethodsTest.class.php b/src/test/php/lang/ast/syntax/php/unittest/MethodsTest.class.php
index af6d975..8866b99 100755
--- a/src/test/php/lang/ast/syntax/php/unittest/MethodsTest.class.php
+++ b/src/test/php/lang/ast/syntax/php/unittest/MethodsTest.class.php
@@ -139,4 +139,20 @@ class MethodsTest extends EmittingTest {
}
}');
}
+
+ #[Test]
+ public function generic_method() {
+ $r= $this->run('class %T {
+ public static function sort<E>(array<E> $elements) {
+ sort($elements);
+ return $elements;
+ }
+
+ public function run($elements) {
+ return self::sort<string>($elements);
+ }
+ }', ['C', 'A', 'B']);
+
+ Assert::equals(['A', 'B', 'C'], $r);
+ }
}
\ No newline at end of file Syntactic support
Emitting idea// Input
public static function sort<E>(array<E> $elements) {
sort($elements);
return $elements;
}
$sorted= T::sort([1, 2, 3]);
$sorted= T::sort<int>([1, 2, 3]);
// Output
public static function __sort($types, ... $args) {
foreach ($types as $i => $type) {
$type->isInstance($args[$i]) || throw new IllegalArgumentException('...');
}
list($E)= $types;
list($elements)= $args;
sort($elements);
return $elements;
}
public static function sort($elements) {
return self::__sort([typeof($elements)], $elements);
}
$sorted= T::sort([1, 2, 3]);
$sorted= T::__sort([Type::forName('int')], [1, 2, 3]); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Like the reverse() method in the following example:
The text was updated successfully, but these errors were encountered: