langkit.dsl_unparse: fix handing of ".super" expressions

This commit is contained in:
Pierre-Marie de Rodat
2023-09-22 13:02:11 +00:00
parent d8f032ed49
commit 1f09bb3ef4
12 changed files with 101 additions and 149 deletions

View File

@@ -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 = ""

View File

@@ -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 {
}

View File

@@ -1,5 +1,6 @@
import lexer_example
@with_lexer(foo_lexer)
grammar foo_grammar {
@main_rule main_rule <- or(Example("example") | Number(@number))
}

View File

@@ -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 {
}

View File

@@ -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 {
}

View File

@@ -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
}

View File

@@ -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 {
}

View File

@@ -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

View File

@@ -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')

View File

@@ -1 +1 @@
driver: python
driver: lkt_compile

View File

@@ -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()
}

View File

@@ -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")