Skip to content

Commit e4258bc

Browse files
Patrick Quistclaude
andcommitted
Give ntVariable an end position
Same gap as the previous commit, same shape of fix. A variable declaration produced a node positioned at its name with no end at all, so a declaration whose type or initialiser spans lines reported only its first line: var Grid: array[0..1] of Integer; VarDeclaration pushed ntVariables with FStack.Push, so the VarList that RearrangeVarSection rebuilds each variable from had no extent to pass on. Both now push compound nodes, and the rebuilt ntVariable inherits the end via AssignEndPositionFrom - the second caller for the helper added in the previous commit, which is the pattern it exists for. The compound ntVariables nodes are the throwaway VarSect children that VarSection frees, so the output footprint matches the constant change exactly: VARIABLE gains begin/end, and the VARIABLES section node that reaches the tree is untouched. Names sharing one line (`A, B: Integer;`) each get the declaration's extent, which is the whole declaration they share. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 378d904 commit e4258bc

2 files changed

Lines changed: 39 additions & 2 deletions

File tree

‎Source/DelphiAST.pas‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3210,9 +3210,11 @@ procedure TPasSyntaxTreeBuilder.VarAbsolute;
32103210

32113211
procedure TPasSyntaxTreeBuilder.VarDeclaration;
32123212
begin
3213-
FStack.Push(ntVariables);
3213+
//compound: a variable's type or initialiser can span lines, so record where it ends.
3214+
FStack.PushCompoundSyntaxNode(ntVariables);
32143215
try
32153216
inherited;
3217+
SetCurrentCompoundNodesEndPosition;
32163218
finally
32173219
FStack.Pop;
32183220
end;
@@ -3303,9 +3305,12 @@ procedure TPasSyntaxTreeBuilder.RearrangeVarSection(const VarSect: TSyntaxNode);
33033305
begin
33043306
if Variable.Typ <> ntName then
33053307
Continue;
3306-
Temp := FStack.Push(ntVariable);
3308+
//compound: start from the name, end from the VarList that measured the declaration.
3309+
Temp := FStack.PushCompoundSyntaxNode(ntVariable);
33073310
try
33083311
Temp.AssignPositionFrom(Variable);
3312+
if VarList is TCompoundSyntaxNode then
3313+
TCompoundSyntaxNode(Temp).AssignEndPositionFrom(TCompoundSyntaxNode(VarList));
33093314
FStack.AddChild(Variable.Clone);
33103315
if Assigned(TypeInfo) then
33113316
FStack.AddChild(TypeInfo.Clone);

‎Test/UnitTests/DelphiAST.Tests.pas‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,37 @@ procedure TestConstantEndPosition;
210210
end;
211211
end;
212212

213+
procedure TestVariableEndPosition;
214+
var
215+
Root, Node, Spanning, Single: TSyntaxNode;
216+
begin
217+
Root := ParseSource('unit Vars;' + sLineBreak + 'interface' + sLineBreak + 'var' +
218+
sLineBreak + ' Spanning: array[0..1] of' + sLineBreak + ' Integer;' + sLineBreak +
219+
' Single: Integer;' + sLineBreak + 'implementation' + sLineBreak + 'end.');
220+
try
221+
Spanning := nil;
222+
Single := nil;
223+
for Node in FindDescendant(Root, ntVariables).ChildNodes do
224+
if Node.Typ = ntVariable then
225+
if Node.Line = 4 then
226+
Spanning := Node
227+
else if Node.Line = 6 then
228+
Single := Node;
229+
230+
AssertNotNil(Spanning, 'No variable starting on line 4');
231+
AssertTrue(Spanning is TCompoundSyntaxNode,
232+
'Variable node must be compound so it can carry an end position');
233+
AssertEquals(5, TCompoundSyntaxNode(Spanning).EndLine,
234+
'A variable whose declaration spans lines must reach its last line');
235+
236+
AssertNotNil(Single, 'No variable starting on line 6');
237+
AssertEquals(6, TCompoundSyntaxNode(Single).EndLine,
238+
'A single-line variable must end on its own line, not run on to what follows');
239+
finally
240+
Root.Free;
241+
end;
242+
end;
243+
213244
procedure TestInvalidSyntax;
214245
var
215246
Root: TSyntaxNode;
@@ -263,6 +294,7 @@ procedure RunAllTests;
263294
RunTest('Writer.LiteralsUnicodeAndXmlEscaping', TestLiteralsAndUnicode);
264295
RunTest('AST.SourcePositions', TestSourcePositions);
265296
RunTest('AST.ConstantEndPosition', TestConstantEndPosition);
297+
RunTest('AST.VariableEndPosition', TestVariableEndPosition);
266298
RunTest('Parser.InvalidSyntax', TestInvalidSyntax);
267299
{$IFNDEF FPC}
268300
RunTest('Serialization.BinaryRoundTrip', TestBinarySerializationRoundTrip);

0 commit comments

Comments
 (0)