mirror of
https://github.com/AdaCore/langkit.git
synced 2026-02-12 12:28:12 -08:00
langkit.dsl_unparse: fix handing of ".super" expressions
This commit is contained in:
@@ -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 = ""
|
||||
|
||||
12
testsuite/tests/properties/invalid_super/bad_args.lkt
Normal file
12
testsuite/tests/properties/invalid_super/bad_args.lkt
Normal 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 {
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import lexer_example
|
||||
|
||||
@with_lexer(foo_lexer)
|
||||
grammar foo_grammar {
|
||||
@main_rule main_rule <- or(Example("example") | Number(@number))
|
||||
}
|
||||
12
testsuite/tests/properties/invalid_super/invalid_prefix.lkt
Normal file
12
testsuite/tests/properties/invalid_super/invalid_prefix.lkt
Normal 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 {
|
||||
}
|
||||
11
testsuite/tests/properties/invalid_super/no_overriden.lkt
Normal file
11
testsuite/tests/properties/invalid_super/no_overriden.lkt
Normal 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 {
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
13
testsuite/tests/properties/invalid_super/self_prefix.lkt
Normal file
13
testsuite/tests/properties/invalid_super/self_prefix.lkt
Normal 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 {
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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')
|
||||
@@ -1 +1 @@
|
||||
driver: python
|
||||
driver: lkt_compile
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user