diff --git a/langkit/dsl_unparse.py b/langkit/dsl_unparse.py index dfaf601fe..df2554c0f 100644 --- a/langkit/dsl_unparse.py +++ b/langkit/dsl_unparse.py @@ -1141,7 +1141,7 @@ def emit_expr(expr, **ctx): args.append(ee(arg)) for kw, arg in expr.arguments.kwargs.items(): args.append("{}={}".format(kw, ee(arg))) - return "super({})".format(", ".join(args)) + return "{}.super({})".format(ee(expr.prefix), ", ".join(args)) elif isinstance(expr, Concat): result = "" diff --git a/testsuite/tests/properties/invalid_super/bad_args.lkt b/testsuite/tests/properties/invalid_super/bad_args.lkt new file mode 100644 index 000000000..3e5046675 --- /dev/null +++ b/testsuite/tests/properties/invalid_super/bad_args.lkt @@ -0,0 +1,12 @@ +import common + +class FooNode implements Node[FooNode] { + @export fun p(): Int = 1 +} + +class Example: FooNode implements TokenNode { + fun p(): Int = node.super("foo") +} + +class Number: FooNode implements TokenNode { +} diff --git a/testsuite/tests/properties/invalid_super/foo.lkt b/testsuite/tests/properties/invalid_super/common.lkt similarity index 83% rename from testsuite/tests/properties/invalid_super/foo.lkt rename to testsuite/tests/properties/invalid_super/common.lkt index 1bcf2e387..2be65c4cf 100644 --- a/testsuite/tests/properties/invalid_super/foo.lkt +++ b/testsuite/tests/properties/invalid_super/common.lkt @@ -1,5 +1,6 @@ import lexer_example +@with_lexer(foo_lexer) grammar foo_grammar { @main_rule main_rule <- or(Example("example") | Number(@number)) } diff --git a/testsuite/tests/properties/invalid_super/invalid_prefix.lkt b/testsuite/tests/properties/invalid_super/invalid_prefix.lkt new file mode 100644 index 000000000..ffc687c5d --- /dev/null +++ b/testsuite/tests/properties/invalid_super/invalid_prefix.lkt @@ -0,0 +1,12 @@ +import common + +class FooNode implements Node[FooNode] { + @export fun p(): Int = 1 +} + +class Example: FooNode implements TokenNode { + fun p(): Int = node.parent.super() + 1 +} + +class Number: FooNode implements TokenNode { +} diff --git a/testsuite/tests/properties/invalid_super/no_overriden.lkt b/testsuite/tests/properties/invalid_super/no_overriden.lkt new file mode 100644 index 000000000..78c8eb9a0 --- /dev/null +++ b/testsuite/tests/properties/invalid_super/no_overriden.lkt @@ -0,0 +1,11 @@ +import common + +class FooNode implements Node[FooNode] { + @export fun p(): Int = node.super() + 1 +} + +class Example: FooNode implements TokenNode { +} + +class Number: FooNode implements TokenNode { +} diff --git a/testsuite/tests/properties/invalid_super/overridden_abstract.lkt b/testsuite/tests/properties/invalid_super/overridden_abstract.lkt new file mode 100644 index 000000000..780348648 --- /dev/null +++ b/testsuite/tests/properties/invalid_super/overridden_abstract.lkt @@ -0,0 +1,13 @@ +import common + +class FooNode implements Node[FooNode] { + @export @abstract fun p(): Int +} + +class Example: FooNode implements TokenNode { + @export fun p(): Int = node.super() + 1 +} + +class Number: FooNode implements TokenNode { + @export fun p(): Int = 0 +} diff --git a/testsuite/tests/properties/invalid_super/self_prefix.lkt b/testsuite/tests/properties/invalid_super/self_prefix.lkt new file mode 100644 index 000000000..7037b079a --- /dev/null +++ b/testsuite/tests/properties/invalid_super/self_prefix.lkt @@ -0,0 +1,13 @@ +import common + +class FooNode implements Node[FooNode] { + fun p1(): Int = 1 + @export fun p2(): Int = self.p1 +} + +class Example: FooNode implements TokenNode { + fun p2(): Int = node.super() +} + +class Number: FooNode implements TokenNode { +} diff --git a/testsuite/tests/properties/invalid_super/test.out b/testsuite/tests/properties/invalid_super/test.out index 8c6c7a851..12b833b32 100644 --- a/testsuite/tests/properties/invalid_super/test.out +++ b/testsuite/tests/properties/invalid_super/test.out @@ -1,19 +1,31 @@ -== test_bad_args == -test.py:XXX: error: The last argument is unexpected +== bad_args.lkt == +bad_args.lkt:8:20: error: The last argument is unexpected +8 | fun p(): Int = node.super("foo") + | ^^^^^^^^^^^^^^^^^ -== test_invalid_prefix == -test.py:XXX: error: .super() is allowed on Self or Entity only -== test_no_overridden == -test.py:XXX: error: There is no overridden property to call +== invalid_prefix.lkt == +invalid_prefix.lkt:8:20: error: .super() is allowed on Self or Entity only +8 | fun p(): Int = node.parent.super() + 1 + | ^^^^^^^^^^^^^^^^^^^ -== test_overridden_abstract == -test.py:XXX: error: Cannot call abstract overridden property -== test_overridden_abstract_runtime_check == -test.py:XXX: error: Cannot call abstract overridden property +== no_overriden.lkt == +no_overriden.lkt:4:28: error: There is no overridden property to call +4 | @export fun p(): Int = node.super() + 1 + | ^^^^^^^^^^^^ -== test_self_prefix == -test.py:XXX: error: Call to FooNode.p2 must be done on an entity -Done +== overridden_abstract.lkt == +overridden_abstract.lkt:8:28: error: Cannot call abstract overridden property +8 | @export fun p(): Int = node.super() + 1 + | ^^^^^^^^^^^^ + + +== self_prefix.lkt == +self_prefix.lkt:9:21: error: Call to FooNode.p2 must be done on an entity +9 | fun p2(): Int = node.super() + | ^^^^^^^^^^^^ + + +lkt_compile: Done diff --git a/testsuite/tests/properties/invalid_super/test.py b/testsuite/tests/properties/invalid_super/test.py deleted file mode 100644 index e3553332f..000000000 --- a/testsuite/tests/properties/invalid_super/test.py +++ /dev/null @@ -1,126 +0,0 @@ -""" -Check that invalid uses of the ".super()" construct are properly rejected. -""" - -from langkit.dsl import ASTNode, T -from langkit.expressions import AbstractKind, Entity, Self, langkit_property - -from utils import emit_and_print_errors - - -def test_bad_args(): - class FooNode(ASTNode): - @langkit_property(public=True, return_type=T.Int) - def p(): - return 1 - - class Example(FooNode): - token_node = True - - @langkit_property() - def p(): - return Self.super("foo") - - class Number(FooNode): - token_node = True - - -def test_no_overridden(): - class FooNode(ASTNode): - @langkit_property(public=True, return_type=T.Int) - def p(): - return Self.super() + 1 - - class Example(FooNode): - token_node = True - - class Number(FooNode): - token_node = True - - -def test_overridden_abstract(): - class FooNode(ASTNode): - @langkit_property(public=True, return_type=T.Int, - kind=AbstractKind.abstract) - def p(): - pass - - class Example(FooNode): - token_node = True - - @langkit_property(public=True, return_type=T.Int) - def p(): - return Self.super() + 1 - - class Number(FooNode): - token_node = True - - @langkit_property() - def p(): - return 0 - - -def test_overridden_abstract_runtime_check(): - class FooNode(ASTNode): - @langkit_property(public=True, return_type=T.Int, - kind=AbstractKind.abstract_runtime_check) - def p(): - pass - - class Example(FooNode): - token_node = True - - @langkit_property() - def p(): - return Self.super() + 1 - - class Number(FooNode): - token_node = True - - -def test_invalid_prefix(): - class FooNode(ASTNode): - @langkit_property(public=True, return_type=T.Int) - def p(): - return 1 - - class Example(FooNode): - token_node = True - - @langkit_property() - def p(): - return Self.parent.super() + 1 - - class Number(FooNode): - token_node = True - - -def test_self_prefix(): - class FooNode(ASTNode): - @langkit_property() - def p1(): - return 1 - - @langkit_property(public=True, return_type=T.Int) - def p2(): - return Entity.p1 - - class Example(FooNode): - token_node = True - - @langkit_property() - def p2(): - return Self.super() - - class Number(FooNode): - token_node = True - - -for key, value in sorted(locals().items()): - if key.startswith('test'): - print('== {} =='.format(key)) - value() - emit_and_print_errors(lkt_file='foo.lkt') - print('') - -print('Done') diff --git a/testsuite/tests/properties/invalid_super/test.yaml b/testsuite/tests/properties/invalid_super/test.yaml index 30423a038..4a499fbd3 100644 --- a/testsuite/tests/properties/invalid_super/test.yaml +++ b/testsuite/tests/properties/invalid_super/test.yaml @@ -1 +1 @@ -driver: python +driver: lkt_compile diff --git a/testsuite/tests/properties/super/expected_concrete_syntax.lkt b/testsuite/tests/properties/super/expected_concrete_syntax.lkt index 131ecf738..17d0a0ec5 100644 --- a/testsuite/tests/properties/super/expected_concrete_syntax.lkt +++ b/testsuite/tests/properties/super/expected_concrete_syntax.lkt @@ -11,23 +11,23 @@ grammar foo_grammar { @export fun root2(a: String, b: String): String = (a & (" + ")) & b - @export fun root3(): Bool = self.info.rebindings.do((_) => true) + @export fun root3(): Bool = self.info.rebindings != null[EnvRebindings] } @abstract class Expr: FooNode { - fun root1(): Array[Int] = super() & ([2]) + fun root1(): Array[Int] = node.super() & ([2]) } class Name: Expr implements TokenNode { - fun root1(): Array[Int] = super() & ([3]) + fun root1(): Array[Int] = node.super() & ([3]) fun root2(a: String, b: String): String = ( ("<") & ( - super((("[") & a) & ("]"), b=(("{") & b) & ("}")) + node.super((("[") & a) & ("]"), b=(("{") & b) & ("}")) ) ) & (">") - fun root3(): Bool = super() + fun root3(): Bool = self.super() } diff --git a/testsuite/tests/properties/super/test.py b/testsuite/tests/properties/super/test.py index d38bc023c..b957994e1 100644 --- a/testsuite/tests/properties/super/test.py +++ b/testsuite/tests/properties/super/test.py @@ -4,7 +4,7 @@ Check that the ".super()" DSL construct works as expected. from langkit.compiled_types import T from langkit.dsl import ASTNode, abstract -from langkit.expressions import Entity, Self, String, langkit_property +from langkit.expressions import Entity, No, Self, String, langkit_property from utils import build_and_run @@ -20,7 +20,7 @@ class FooNode(ASTNode): @langkit_property(public=True) def root3(): - return Entity.info.rebindings.then(lambda _: True) + return Entity.info.rebindings != No(T.EnvRebindings) @abstract @@ -49,5 +49,9 @@ class Name(Expr): return Entity.super() -build_and_run(lkt_file="expected_concrete_syntax.lkt", py_script="main.py") +build_and_run( + lkt_file="expected_concrete_syntax.lkt", + py_script="main.py", + types_from_lkt=True, +) print("Done")