Skip to content

Commit 1bd9ef2

Browse files
committed
Adapt syntax to accept legacy 'is' in pattern details
1 parent de5959c commit 1bd9ef2

File tree

20 files changed

+175
-33
lines changed

20 files changed

+175
-33
lines changed

lkql/build/railroad-diagrams/pattern_arg.svg

Lines changed: 11 additions & 11 deletions
Loading

lkql/language/parser.py

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -927,19 +927,28 @@ class NodeKindPattern(NodePattern):
927927
kind_name = Field(type=Identifier)
928928

929929

930+
class PatternDetailDelimiter(LkqlNode):
931+
"""
932+
Pattern detail delimiter, either 'is' (old syntax) or ':' (new syntax).
933+
"""
934+
enum_node = True
935+
alternatives = ['is', 'colon']
936+
937+
930938
@abstract
931939
class NodePatternDetail(LkqlNode):
932940
"""
933941
Access to a field, property or selector inside a node pattern.
934942
"""
935-
pass
943+
pattern_detail_delimiter = AbstractField(type=PatternDetailDelimiter)
936944

937945

938946
class NodePatternField(NodePatternDetail):
939947
"""
940948
Access to a field in a node pattern.
941949
"""
942950
identifier = Field(type=Identifier)
951+
pattern_detail_delimiter = Field(type=PatternDetailDelimiter)
943952
expected_value = Field(type=BasePattern)
944953

945954

@@ -948,6 +957,7 @@ class NodePatternProperty(NodePatternDetail):
948957
Access to a property in a node pattern.
949958
"""
950959
call = Field(type=FunCall)
960+
pattern_detail_delimiter = Field(type=PatternDetailDelimiter)
951961
expected_value = Field(type=BasePattern)
952962

953963

@@ -956,18 +966,19 @@ class NodePatternSelector(NodePatternDetail):
956966
Use of a selector in a node pattern
957967
"""
958968
call = Field(type=SelectorCall)
969+
pattern_detail_delimiter = Field(type=PatternDetailDelimiter)
959970
pattern = Field(type=BasePattern)
960971

961972

962973
class ExtendedNodePattern(NodePattern):
963974
"""
964975
Node pattern of the form:
965976
966-
``KindName(field=val, prop() is val, any selector is Pattern)``
977+
``KindName(field: Pattern, prop(): Pattern, any selector: Pattern)``
967978
968979
For instance::
969980
970-
ObjectDecl(children: AspectAssoc)
981+
ObjectDecl(any children: AspectAssoc)
971982
"""
972983
node_pattern = Field(type=ValuePattern)
973984
details = Field(type=NodePatternDetail.list)
@@ -1114,10 +1125,21 @@ class Tuple(Expr):
11141125
),
11151126
tuple_pattern=TuplePattern("(", List(G.value_pattern, sep=","), ")"),
11161127

1128+
pattern_detail_delimiter=Or(
1129+
PatternDetailDelimiter.alt_is("is"),
1130+
PatternDetailDelimiter.alt_colon(":"),
1131+
),
1132+
11171133
pattern_arg=Or(
1118-
NodePatternSelector(G.selector_call, ":", G.or_pattern),
1119-
NodePatternField(G.id, ":", c(), G.or_pattern),
1120-
NodePatternProperty(G.fun_call, ":", c(), G.or_pattern)
1134+
NodePatternSelector(
1135+
G.selector_call, G.pattern_detail_delimiter, G.or_pattern
1136+
),
1137+
NodePatternField(
1138+
G.id, G.pattern_detail_delimiter, c(), G.or_pattern
1139+
),
1140+
NodePatternProperty(
1141+
G.fun_call, G.pattern_detail_delimiter, c(), G.or_pattern
1142+
)
11211143
),
11221144

11231145
selector_call=SelectorCall(

lkql_checker/src/gnatcheck-compiler.adb

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ package body Gnatcheck.Compiler is
293293
-- We assume the following format of the message:
294294
-- filename:line:column: <message body>
295295
--
296-
-- If this format is violated we display the line as unparasable.
296+
-- If this format is violated we display the line as unparsable.
297297

298298
-- Try to match the diagnostic to extract information
299299
Match (Match_Diagnosis, Msg, Matches);
@@ -302,6 +302,9 @@ package body Gnatcheck.Compiler is
302302
return;
303303
end if;
304304

305+
Msg_Start := Matches (5).First;
306+
Msg_End := Matches (5).Last;
307+
305308
SF := File_Find
306309
(Msg (Matches (1).First .. Matches (1).Last),
307310
Use_Short_Name => True);
@@ -310,8 +313,18 @@ package body Gnatcheck.Compiler is
310313
Sloc.Column := Column_Number'Value
311314
(Msg (Matches (4).First .. Matches (4).Last));
312315

313-
Msg_Start := Matches (5).First;
314-
Msg_End := Matches (5).Last;
316+
-- Handle internal warnings before any other kind of error, because
317+
-- they don't have an Ada source location
318+
--
319+
-- TODO: We want to refactor this logic and make the logic of
320+
-- handling internal errors more general.
321+
if Msg_End - Msg_Start > 22
322+
and then Msg
323+
(Msg_Start .. Msg_Start + 22) = "warning: internal issue"
324+
then
325+
Warning (Msg (Msg_Start + 27 .. Msg_End));
326+
return;
327+
end if;
315328

316329
-- Test if the provided sources is present and is not ignored
317330
if not Present (SF) or else Source_Info (SF) = Ignore_Unit then
@@ -374,7 +387,7 @@ package body Gnatcheck.Compiler is
374387

375388
if Msg_End - Msg_Start > 21
376389
and then Msg
377-
(Msg_Start + 7 .. Msg_Start + 20) = "internal error"
390+
(Msg_Start + 7 .. Msg_Start + 20) = "internal issue"
378391
then
379392
Kind := Internal_Error;
380393
else

lkql_jit/language/src/main/java/com/adacore/lkql_jit/checker/utils/CheckerUtils.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,10 +281,11 @@ public String diagnostic(
281281
SourceLocation lkqlErrorLocation,
282282
String ruleName) {
283283

284-
var adaLoc = adaErrorLocation != null ? adaErrorLocation.display(true) + ": " : "";
284+
var adaLoc =
285+
adaErrorLocation != null ? adaErrorLocation.display(true) + ": " : "null:0:0: ";
285286
var lkqlLoc =
286287
lkqlErrorLocation != null
287-
? "internal error at " + lkqlErrorLocation.display(true) + ": "
288+
? "internal issue at " + lkqlErrorLocation.display(true) + ": "
288289
: "";
289290
var rulePart =
290291
ruleName == null || ruleName.isBlank()

lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/passes/FramingPass.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,16 @@ public Void visit(Liblkqllang.OpPlus opPlus) {
642642
return null;
643643
}
644644

645+
@Override
646+
public Void visit(Liblkqllang.PatternDetailDelimiterColon patternDetailDelimiterColon) {
647+
return null;
648+
}
649+
650+
@Override
651+
public Void visit(Liblkqllang.PatternDetailDelimiterIs patternDetailDelimiterIs) {
652+
return null;
653+
}
654+
645655
@Override
646656
public Void visit(Liblkqllang.BinOp binOp) {
647657
traverseChildren(binOp);

lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/passes/TranslationPass.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,27 @@ public LKQLNode visit(Liblkqllang.OpPlus opPlus) {
610610
return null;
611611
}
612612

613+
@Override
614+
public LKQLNode visit(Liblkqllang.PatternDetailDelimiterColon patternDetailDelimiterColon) {
615+
return null;
616+
}
617+
618+
@Override
619+
public LKQLNode visit(Liblkqllang.PatternDetailDelimiterIs patternDetailDelimiterIs) {
620+
var ctx = LKQLLanguage.getContext(null);
621+
ctx.getDiagnosticEmitter()
622+
.emitDiagnostic(
623+
CheckerUtils.MessageKind.WARNING,
624+
"'is' syntax is deprecated for patterns. Please consider migrating your"
625+
+ " code via 'lkql refactor -r IS_TO_COLON"
626+
+ patternDetailDelimiterIs.getUnit().getFileName()
627+
+ "'.",
628+
null,
629+
SourceSectionWrapper.create(
630+
patternDetailDelimiterIs.getSourceLocationRange(), source));
631+
return null;
632+
}
633+
613634
@Override
614635
public LKQLNode visit(Liblkqllang.OpMinus opMinus) {
615636
return null;
@@ -1621,6 +1642,8 @@ public LKQLNode visit(Liblkqllang.NodePatternField nodePatternField) {
16211642
final String name = nodePatternField.fIdentifier().getText();
16221643
final BasePattern expected = (BasePattern) nodePatternField.fExpectedValue().accept(this);
16231644

1645+
nodePatternField.fPatternDetailDelimiter().accept(this);
1646+
16241647
// Return the new node pattern field detail
16251648
return NodePatternFieldNodeGen.create(loc(nodePatternField), name, expected);
16261649
}
@@ -1639,6 +1662,8 @@ public LKQLNode visit(Liblkqllang.NodePatternProperty nodePatternProperty) {
16391662
final BasePattern expected =
16401663
(BasePattern) nodePatternProperty.fExpectedValue().accept(this);
16411664

1665+
nodePatternProperty.fPatternDetailDelimiter().accept(this);
1666+
16421667
// Return the new node pattern property detail
16431668
return NodePatternPropertyNodeGen.create(
16441669
loc(nodePatternProperty), propertyName, argList, expected);
@@ -1664,6 +1689,8 @@ public LKQLNode visit(Liblkqllang.NodePatternSelector nodePatternSelector) {
16641689
// Exit the node pattern selector frame
16651690
this.scriptFrames.exitFrame();
16661691

1692+
nodePatternSelector.fPatternDetailDelimiter().accept(this);
1693+
16671694
// Return the new selector node pattern detail
16681695
return new NodePatternSelector(loc(nodePatternSelector), selectorCall, pattern);
16691696
}

testsuite/tests/gnatcheck_errors/invalid_lkql_rules_config/test.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Invalid LKQL semantic
22
=====================
33

4-
gnatcheck: error raised by the worker: Error during file processing: error: internal error at invalid_semantic.lkql:1:25: Type error: expected Int but got Bool (invalid_semantic.lkql)
4+
gnatcheck: error raised by the worker: Error during file processing: null:0:0: error: internal issue at invalid_semantic.lkql:1:25: Type error: expected Int but got Bool (invalid_semantic.lkql)
55
gnatcheck: No rule to check specified
66
try "gnatcheck --help" for more information.
77
>>>program returned status code 2

testsuite/tests/gnatcheck_errors/lkql_error/test.out

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@ Total gnatcheck failures: 9
3232

3333
6. Gnatcheck internal errors
3434

35-
main.adb:1:01: error: internal error at foo.lkql:4:17: Null receiver in dot access [foo]
36-
main.adb:1:01: error: internal error at foo_unit.lkql:4:22: Null receiver in dot access [foo_unit]
37-
main.adb:1:11: error: internal error at foo.lkql:4:17: Null receiver in dot access [foo]
38-
main.adb:1:18: error: internal error at foo.lkql:4:17: Null receiver in dot access [foo]
39-
main.adb:2:06: error: internal error at foo.lkql:4:17: Null receiver in dot access [foo]
40-
main.adb:3:04: error: internal error at foo.lkql:4:17: Null receiver in dot access [foo]
41-
main.adb:3:08: error: internal error at foo.lkql:4:17: Null receiver in dot access [foo]
42-
main.adb:4:05: error: internal error at foo.lkql:4:17: Null receiver in dot access [foo]
43-
main.adb:4:10: error: internal error at foo.lkql:4:17: Null receiver in dot access [foo]
35+
main.adb:1:01: error: internal issue at foo.lkql:4:17: Null receiver in dot access [foo]
36+
main.adb:1:01: error: internal issue at foo_unit.lkql:4:22: Null receiver in dot access [foo_unit]
37+
main.adb:1:11: error: internal issue at foo.lkql:4:17: Null receiver in dot access [foo]
38+
main.adb:1:18: error: internal issue at foo.lkql:4:17: Null receiver in dot access [foo]
39+
main.adb:2:06: error: internal issue at foo.lkql:4:17: Null receiver in dot access [foo]
40+
main.adb:3:04: error: internal issue at foo.lkql:4:17: Null receiver in dot access [foo]
41+
main.adb:3:08: error: internal issue at foo.lkql:4:17: Null receiver in dot access [foo]
42+
main.adb:4:05: error: internal issue at foo.lkql:4:17: Null receiver in dot access [foo]
43+
main.adb:4:10: error: internal issue at foo.lkql:4:17: Null receiver in dot access [foo]
4444

4545
>>>program returned status code 2
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
procedure Main is
2+
begin
3+
null;
4+
end Main;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
project Prj is
2+
end Prj;

0 commit comments

Comments
 (0)