codetools: FindBlockStart: fixed when starting on last atom of block, bug #20797

git-svn-id: trunk@33915 -
This commit is contained in:
mattias 2011-12-02 20:07:45 +00:00
parent 55135cb93d
commit 3ec95f8d25
2 changed files with 34 additions and 26 deletions

View File

@ -4887,6 +4887,7 @@ function TStandardCodeTool.FindBlockStart(const CursorPos: TCodeXYPosition;
// jump to beginning of current block // jump to beginning of current block
// e.g. bracket open, 'begin', 'repeat', ... // e.g. bracket open, 'begin', 'repeat', ...
var CleanCursorPos: integer; var CleanCursorPos: integer;
CursorOnStart: Boolean;
begin begin
Result:=false; Result:=false;
// scan code // scan code
@ -4899,29 +4900,33 @@ begin
ReadNextAtom; ReadNextAtom;
try try
repeat repeat
ReadPriorAtom; //debugln(['TStandardCodeTool.FindBlockStart AAA1 ',CleanPosToStr(CurPos.StartPos),' ',GetAtom]);
if (CurPos.StartPos<0) then begin if (CurPos.StartPos<0) then begin
// start of source found -> this is always a block start // start of source found -> this is always a block start
CurPos.StartPos:=1; CurPos.StartPos:=1;
Result:=true; exit(true);
exit;
end end
else if Src[CurPos.StartPos] in [')',']','}'] then begin else if Src[CurPos.StartPos] in [')',']','}'] then begin
// jump backward to matching bracket // jump backward to matching bracket
CursorOnStart:=(CleanCursorPos=CurPos.StartPos);
if not ReadBackwardTilAnyBracketClose then exit; if not ReadBackwardTilAnyBracketClose then exit;
if CursorOnStart then exit(true);
end end
else if WordIsBlockStatementStart.DoItCaseInsensitive(Src, else if WordIsBlockStatementStart.DoItCaseInsensitive(Src,
CurPos.StartPos,CurPos.EndPos-CurPos.StartPos) then CurPos.StartPos,CurPos.EndPos-CurPos.StartPos) then
begin begin
// block start found // block start found
Result:=true; exit(true);
exit;
end else if UpAtomIs('END') or UpAtomIs('FINALLY') or UpAtomIs('EXCEPT') end else if UpAtomIs('END') or UpAtomIs('FINALLY') or UpAtomIs('EXCEPT')
or UpAtomIs('UNTIL') then or UpAtomIs('UNTIL') then
begin begin
// read backward till BEGIN, CASE, ASM, RECORD, REPEAT // read backward till BEGIN, CASE, ASM, RECORD, REPEAT
CursorOnStart:=(CleanCursorPos>=CurPos.StartPos)
and (CleanCursorPos<CurPos.EndPos);
ReadBackTilBlockEnd(true); ReadBackTilBlockEnd(true);
if CursorOnStart then exit(true);
end; end;
ReadPriorAtom;
until false; until false;
finally finally
if Result then begin if Result then begin

View File

@ -36,9 +36,9 @@ var
'program TestStdCodeTools;'+LineEnding 'program TestStdCodeTools;'+LineEnding
+'begin'+LineEnding +'begin'+LineEnding
+' if true then {begin1}begin'+LineEnding +' if true then {begin1}begin'+LineEnding
+' {try}try'+LineEnding +' {try1}try'+LineEnding
+' writeln;'+LineEnding +' writeln;'+LineEnding
+' finally'+LineEnding +' {try1finally}finally'+LineEnding
+' writeln;'+LineEnding +' writeln;'+LineEnding
+' {try1end}end;'+LineEnding +' {try1end}end;'+LineEnding
+' writeln;'+LineEnding +' writeln;'+LineEnding
@ -69,31 +69,34 @@ var
Result:=dbgs(XY)+': '+copy(Line,1,XY.X-1)+'|'+copy(Line,XY.X,length(Line)); Result:=dbgs(XY)+': '+copy(Line,1,XY.X-1)+'|'+copy(Line,XY.X,length(Line));
end; end;
var procedure Test(aTitle, StartMarker,EndMarker: string);
Tool: TCodeTool; var
BlockStart: TPoint; BlockStart: TPoint;
BlockEnd: TPoint; BlockEnd: TPoint;
NewCode: TCodeBuffer; NewCode: TCodeBuffer;
NewX: integer; NewX: integer;
NewY: integer; NewY: integer;
NewTopline: integer; NewTopline: integer;
begin
BlockStart:=GetMarker(StartMarker);
BlockEnd:=GetMarker(EndMarker);
//debugln(['TTestCTStdCodetools.TestCTStdFindBlockStart BlockStart=',GetInfo(BlockStart),' BlockEnd=',GetInfo(BlockEnd)]);
if not CodeToolBoss.FindBlockStart(Code,BlockEnd.X,BlockEnd.Y,NewCode,NewX,NewY,NewTopline)
then
AssertEquals(aTitle+': '+CodeToolBoss.ErrorMessage,true,false)
else
AssertEquals(aTitle,GetInfo(BlockStart),GetInfo(Point(NewX,NewY)))
end;
begin begin
Code:=CodeToolBoss.CreateFile('TestStdCodeTools.pas'); Code:=CodeToolBoss.CreateFile('TestStdCodeTools.pas');
Tool:=CodeToolBoss.GetCodeToolForSource(Code,false,true) as TCodeTool;
// scan source // scan source
Code.Source:=GetSource(); Code.Source:=GetSource();
Tool.BuildTree(lsrEnd);
BlockStart:=GetMarker('{begin1}');
BlockEnd:=GetMarker('{begin1end}');
debugln(['TTestCTStdCodetools.TestCTStdFindBlockStart BlockStart=',GetInfo(BlockStart),' BlockEnd=',GetInfo(BlockEnd)]);
if not CodeToolBoss.FindBlockStart(Code,BlockEnd.X,BlockEnd.Y,NewCode,NewX,NewY,NewTopline)
then
AssertEquals('CodeToolBoss.FindBlockStart: begin,try,finally,end|end: '+CodeToolBoss.ErrorMessage,true,false)
else
AssertEquals('CodeToolBoss.FindBlockStart: begin,try,finally,end|end:',GetInfo(BlockStart),GetInfo(Point(NewX,NewY)))
Test('begin,try,finally,end|end','begin1','begin1end');
Test('begin,try,finally,|end,end','try1finally','try1end');
Test('begin,try,finally,|end,end','try1','try1finally');
end; end;
initialization initialization