Skip to content

Commit 1ddce7c

Browse files
author
Patrick Quist
committed
Report a syntax error at its line, not its column
TPasSyntaxTreeBuilder.Run turns an ESyntaxError into an ESyntaxTreeException, whose constructor takes the line first and the column second. It passed E.PosXY.X, E.PosXY.Y, but TmwBasePasLex.GetPosXY puts the column in X and the line in Y, so the two came out swapped. The EParserException path next to it was right; ParserMessage already passes Y, X. ESyntaxError is what ExpectedFatal raises, which is how an unexpected end of file is reported. A unit that stops after the `begin` of a routine on line 5 unit Broken; interface implementation procedure Run; begin was reported at line 6, col 5 instead of line 5, col 6.
1 parent 9bb8fbf commit 1ddce7c

2 files changed

Lines changed: 24 additions & 1 deletion

File tree

‎Source/DelphiAST.pas‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2672,7 +2672,7 @@ function TPasSyntaxTreeBuilder.Run(SourceStream: TStream): TSyntaxNode;
26722672
on E: EParserException do
26732673
raise ESyntaxTreeException.Create(E.Line, E.Col, Lexer.FileName, E.Message, Result);
26742674
on E: ESyntaxError do
2675-
raise ESyntaxTreeException.Create(E.PosXY.X, E.PosXY.Y, Lexer.FileName, E.Message, Result);
2675+
raise ESyntaxTreeException.Create(E.PosXY.Y, E.PosXY.X, Lexer.FileName, E.Message, Result);
26762676
else
26772677
FreeAndNil(Result);
26782678
raise;

‎Test/UnitTests/DelphiAST.Tests.pas‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,28 @@ procedure TestInvalidSyntax;
258258
AssertTrue(Raised, 'Invalid syntax did not raise ESyntaxTreeException');
259259
end;
260260

261+
procedure TestUnexpectedEndOfFilePosition;
262+
var
263+
Root: TSyntaxNode;
264+
Raised: Boolean;
265+
begin
266+
Root := nil;
267+
Raised := False;
268+
try
269+
Root := ParseSource('unit Broken;' + sLineBreak + 'interface' + sLineBreak +
270+
'implementation' + sLineBreak + 'procedure Run;' + sLineBreak + 'begin');
271+
except
272+
on E: ESyntaxTreeException do
273+
begin
274+
Raised := True;
275+
AssertEquals(5, E.Line, 'The end of file is on line 5.');
276+
AssertEquals(6, E.Col, 'The end of file is after the 5 characters of "begin".');
277+
end;
278+
end;
279+
Root.Free;
280+
AssertTrue(Raised, 'An unexpected end of file did not raise ESyntaxTreeException');
281+
end;
282+
261283
{$IFNDEF FPC}
262284
procedure TestBinarySerializationRoundTrip;
263285
var
@@ -296,6 +318,7 @@ procedure RunAllTests;
296318
RunTest('AST.ConstantEndPosition', TestConstantEndPosition);
297319
RunTest('AST.VariableEndPosition', TestVariableEndPosition);
298320
RunTest('Parser.InvalidSyntax', TestInvalidSyntax);
321+
RunTest('Parser.UnexpectedEndOfFilePosition', TestUnexpectedEndOfFilePosition);
299322
{$IFNDEF FPC}
300323
RunTest('Serialization.BinaryRoundTrip', TestBinarySerializationRoundTrip);
301324
{$ENDIF}

0 commit comments

Comments
 (0)