Skip to content

Commit dd36747

Browse files
committed
Fix parsing errors on some semicolon-delimited generic type parameters
Specifically, in routine implementation headers. Previously, only comma-delimited type parameters were parsing correctly.
1 parent 9063b07 commit dd36747

File tree

4 files changed

+36
-2
lines changed

4 files changed

+36
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Fixed
1111

12+
- Parsing errors on semicolon-delimited generic type parameters in routine implementation headers.
1213
- Incorrect return types for `Length`, `High`, and `Low` on open/dynamic arrays depending on the
1314
compiler version and toolchain.
1415
- Name resolution failures on explicit references to default array properties with overloads on

delphi-frontend/src/main/antlr3/au/com/integradev/delphi/antlr/Delphi.g

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -724,7 +724,12 @@ genericConstraint : typeReference
724724
| CONSTRUCTOR
725725
;
726726
genericArguments : '<' typeReferenceOrStringOrFile (',' typeReferenceOrStringOrFile)* '>'
727-
-> ^(TkGenericArguments<GenericArgumentsNodeImpl> typeReferenceOrStringOrFile typeReferenceOrStringOrFile*)
727+
-> ^(TkGenericArguments<GenericArgumentsNodeImpl> '<' typeReferenceOrStringOrFile (',' typeReferenceOrStringOrFile)* '>')
728+
;
729+
routineNameGenericArguments : '<' typeReferenceOrStringOrFile (commaOrSemicolon typeReferenceOrStringOrFile)* '>'
730+
-> ^(TkGenericArguments<GenericArgumentsNodeImpl> '<' typeReferenceOrStringOrFile (commaOrSemicolon typeReferenceOrStringOrFile)* '>')
731+
;
732+
commaOrSemicolon : ',' | ';'
728733
;
729734

730735
//----------------------------------------------------------------------------
@@ -810,7 +815,7 @@ routineDeclarationName : (
810815
)
811816
-> ^(TkRoutineName<RoutineNameNodeImpl> $decl)
812817
;
813-
routineImplementationName : nameReference -> ^(TkRoutineName<RoutineNameNodeImpl> nameReference)
818+
routineImplementationName : routineNameReference -> ^(TkRoutineName<RoutineNameNodeImpl> routineNameReference)
814819
;
815820
routineKey : PROCEDURE
816821
| CONSTRUCTOR
@@ -1182,6 +1187,12 @@ simpleNameReference : ident
11821187
extendedNameReference : extendedIdent genericArguments? ('.' extendedNameReference)?
11831188
-> ^(TkNameReference<NameReferenceNodeImpl> extendedIdent genericArguments? ('.' extendedNameReference)?)
11841189
;
1190+
routineNameReference : ident routineNameGenericArguments? ('.' extendedRoutineNameReference)?
1191+
-> ^(TkNameReference<NameReferenceNodeImpl> ident routineNameGenericArguments? ('.' extendedRoutineNameReference)?)
1192+
;
1193+
extendedRoutineNameReference : extendedIdent routineNameGenericArguments? ('.' extendedRoutineNameReference)?
1194+
-> ^(TkNameReference<NameReferenceNodeImpl> extendedIdent routineNameGenericArguments? ('.' extendedRoutineNameReference)?)
1195+
;
11851196
extendedIdent : ident
11861197
| keywords -> ^({changeTokenType(TkIdentifier)})
11871198
;

delphi-frontend/src/test/java/au/com/integradev/delphi/antlr/GrammarTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,4 +348,9 @@ void testImmediatelyTerminatedComments() {
348348
void testConditionalAsm() {
349349
assertParsed("ConditionalAsm.pas");
350350
}
351+
352+
@Test
353+
void testSemicolonSeparatedGenericArguments() {
354+
assertParsed("SemicolonSeparatedGenericArguments.pas");
355+
}
351356
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
unit SemicolonSeparatedGenericArguments;
2+
3+
interface
4+
5+
implementation
6+
7+
type
8+
TFoo = class
9+
class procedure Bar<T; C>;
10+
end;
11+
12+
class procedure TFoo.Bar<T; C>;
13+
begin
14+
// ...
15+
end;
16+
17+
end.

0 commit comments

Comments
 (0)