mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-13 02:49:06 +02:00
codetools: complete block: fixed parsing try..finally, if..else
git-svn-id: trunk@20196 -
This commit is contained in:
parent
9edbd4c618
commit
5c4cc7cb58
@ -43,6 +43,7 @@ interface
|
|||||||
|
|
||||||
{ $DEFINE DisableIgnoreErrorAfter}
|
{ $DEFINE DisableIgnoreErrorAfter}
|
||||||
{ $DEFINE VerboseGetStringConstBounds}
|
{ $DEFINE VerboseGetStringConstBounds}
|
||||||
|
{ $DEFINE ShowCompleteBlock}
|
||||||
|
|
||||||
uses
|
uses
|
||||||
{$IFDEF MEM_CHECK}
|
{$IFDEF MEM_CHECK}
|
||||||
@ -5152,6 +5153,8 @@ type
|
|||||||
btCaseColon,
|
btCaseColon,
|
||||||
btCaseElse,
|
btCaseElse,
|
||||||
btRepeat,
|
btRepeat,
|
||||||
|
btIf,
|
||||||
|
btIfElse,
|
||||||
btClass,
|
btClass,
|
||||||
btInterface,
|
btInterface,
|
||||||
btObject,
|
btObject,
|
||||||
@ -5197,6 +5200,9 @@ var
|
|||||||
Stack.Capacity:=Stack.Capacity*2;
|
Stack.Capacity:=Stack.Capacity*2;
|
||||||
ReAllocMem(Stack.Stack,SizeOf(TBlock)*Stack.Capacity);
|
ReAllocMem(Stack.Stack,SizeOf(TBlock)*Stack.Capacity);
|
||||||
end;
|
end;
|
||||||
|
{$IFDEF ShowCompleteBlock}
|
||||||
|
DebugLn([GetIndentStr(Stack.Top*2),'BeginBlock ',CleanPosToStr(StartPos),' ',GetAtom]);
|
||||||
|
{$ENDIF}
|
||||||
Block:=@Stack.Stack[Stack.Top];
|
Block:=@Stack.Stack[Stack.Top];
|
||||||
Block^.Typ:=Typ;
|
Block^.Typ:=Typ;
|
||||||
Block^.StartPos:=StartPos;
|
Block^.StartPos:=StartPos;
|
||||||
@ -5204,6 +5210,9 @@ var
|
|||||||
|
|
||||||
procedure EndBlock(var Stack: TBlockStack);
|
procedure EndBlock(var Stack: TBlockStack);
|
||||||
begin
|
begin
|
||||||
|
{$IFDEF ShowCompleteBlock}
|
||||||
|
DebugLn([GetIndentStr(Stack.Top*2),'EndBlock ',GetAtom,' ',CleanPosToStr(CurPos.StartPos),', started at ',CleanPosToStr(Stack.Stack[Stack.Top].StartPos)]);
|
||||||
|
{$ENDIF}
|
||||||
dec(Stack.Top);
|
dec(Stack.Top);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -5291,23 +5300,8 @@ var
|
|||||||
if (CurPos.StartPos>SrcLen) or (CurPos.StartPos>=StartNode.EndPos) then
|
if (CurPos.StartPos>SrcLen) or (CurPos.StartPos>=StartNode.EndPos) then
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// check if line start
|
|
||||||
InCursorBlock:=(CursorBlockLvl>=0) and (CursorBlockLvl=Stack.Top)
|
InCursorBlock:=(CursorBlockLvl>=0) and (CursorBlockLvl=Stack.Top)
|
||||||
and (not BehindCursorBlock);
|
and (not BehindCursorBlock);
|
||||||
LineStart:=InCursorBlock and (LastPos>0)
|
|
||||||
and not PositionsInSameLine(Src,LastPos,CurPos.StartPos);
|
|
||||||
if LineStart then
|
|
||||||
Indent:=GetLineIndent(Src,CurPos.StartPos);
|
|
||||||
|
|
||||||
if LineStart then begin
|
|
||||||
// atom is in same block as cursor (not sub block)
|
|
||||||
// and first atom of a line
|
|
||||||
// => check indent
|
|
||||||
if Indent<CursorBlockIndent then begin
|
|
||||||
//DebugLn(['ReadStatements Indent=',Indent,' < CursorBlockIndent=',CursorBlockIndent]);
|
|
||||||
NeedCompletion:=true;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
// check block starts/ends
|
// check block starts/ends
|
||||||
case CurPos.Flag of
|
case CurPos.Flag of
|
||||||
@ -5324,7 +5318,25 @@ var
|
|||||||
btCaseColon,btRepeat:
|
btCaseColon,btRepeat:
|
||||||
begin
|
begin
|
||||||
// missing semicolon or until
|
// missing semicolon or until
|
||||||
NeedCompletion:=true;
|
if InCursorBlock then begin
|
||||||
|
{$IFDEF ShowCompleteBlock}
|
||||||
|
DebugLn(['ReadStatements NeedCompletion: unexpected end at ',CleanPosToStr(CurPos.StartPos),': missing semicolon or until ',CleanPosToStr(Stack.Stack[Stack.Top].StartPos)]);
|
||||||
|
{$ENDIF}
|
||||||
|
NeedCompletion:=true;
|
||||||
|
end;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
btTry:
|
||||||
|
begin
|
||||||
|
// missing finally/except
|
||||||
|
DebugLn(['ReadStatements AAA1 CursorBlockLvl=',CursorBlockLvl,' Stack.Top=',Stack.Top,' BehindCursorBlock=',BehindCursorBlock]);
|
||||||
|
DebugLn(['ReadStatements unexpected end at ',CleanPosToStr(CurPos.StartPos),': missing finally ',CleanPosToStr(Stack.Stack[Stack.Top].StartPos)]);
|
||||||
|
if InCursorBlock then begin
|
||||||
|
{$IFDEF ShowCompleteBlock}
|
||||||
|
DebugLn(['ReadStatements NeedCompletion: unexpected end at ',CleanPosToStr(CurPos.StartPos),': missing finally ',CleanPosToStr(Stack.Stack[Stack.Top].StartPos)]);
|
||||||
|
{$ENDIF}
|
||||||
|
NeedCompletion:=true;
|
||||||
|
end;
|
||||||
break;
|
break;
|
||||||
end;
|
end;
|
||||||
btAsm:
|
btAsm:
|
||||||
@ -5358,7 +5370,7 @@ var
|
|||||||
if TopBlockType(Stack)=btCaseOf then
|
if TopBlockType(Stack)=btCaseOf then
|
||||||
BeginBlock(Stack,btCaseColon,CurPos.StartPos);
|
BeginBlock(Stack,btCaseColon,CurPos.StartPos);
|
||||||
cafSemicolon:
|
cafSemicolon:
|
||||||
if TopBlockType(Stack)=btCaseColon then
|
if TopBlockType(Stack) in [btCaseColon,btIf,btIfElse] then
|
||||||
if not EndBlockIsOk then exit;
|
if not EndBlockIsOk then exit;
|
||||||
cafBegin:
|
cafBegin:
|
||||||
BeginBlock(Stack,btBegin,CurPos.StartPos);
|
BeginBlock(Stack,btBegin,CurPos.StartPos);
|
||||||
@ -5366,11 +5378,15 @@ var
|
|||||||
if TopBlockType(Stack)<>btAsm then begin
|
if TopBlockType(Stack)<>btAsm then begin
|
||||||
if UpAtomIs('TRY') then
|
if UpAtomIs('TRY') then
|
||||||
BeginBlock(Stack,btTry,CurPos.StartPos)
|
BeginBlock(Stack,btTry,CurPos.StartPos)
|
||||||
else if UpAtomIs('FINALLY') then
|
else if UpAtomIs('FINALLY') then begin
|
||||||
|
if TopBlockType(Stack)=btTry then
|
||||||
|
if not EndBlockIsOk then exit;
|
||||||
BeginBlock(Stack,btFinally,CurPos.StartPos)
|
BeginBlock(Stack,btFinally,CurPos.StartPos)
|
||||||
else if UpAtomIs('EXCEPT') then
|
end else if UpAtomIs('EXCEPT') then begin
|
||||||
|
if TopBlockType(Stack)=btTry then
|
||||||
|
if not EndBlockIsOk then exit;
|
||||||
BeginBlock(Stack,btExcept,CurPos.StartPos)
|
BeginBlock(Stack,btExcept,CurPos.StartPos)
|
||||||
else if UpAtomIs('REPEAT') then
|
end else if UpAtomIs('REPEAT') then
|
||||||
BeginBlock(Stack,btRepeat,CurPos.StartPos)
|
BeginBlock(Stack,btRepeat,CurPos.StartPos)
|
||||||
else if UpAtomIs('UNTIL') then begin
|
else if UpAtomIs('UNTIL') then begin
|
||||||
if TopBlockType(Stack)=btRepeat then begin
|
if TopBlockType(Stack)=btRepeat then begin
|
||||||
@ -5380,6 +5396,8 @@ var
|
|||||||
end;
|
end;
|
||||||
end else if UpAtomIs('ASM') then begin
|
end else if UpAtomIs('ASM') then begin
|
||||||
BeginBlock(Stack,btAsm,CurPos.StartPos);
|
BeginBlock(Stack,btAsm,CurPos.StartPos);
|
||||||
|
end else if UpAtomIs('IF') then begin
|
||||||
|
BeginBlock(Stack,btIf,CurPos.StartPos)
|
||||||
end else if UpAtomIs('CASE') then begin
|
end else if UpAtomIs('CASE') then begin
|
||||||
BeginBlock(Stack,btCase,CurPos.StartPos)
|
BeginBlock(Stack,btCase,CurPos.StartPos)
|
||||||
end else if UpAtomIs('OF') then begin
|
end else if UpAtomIs('OF') then begin
|
||||||
@ -5387,6 +5405,11 @@ var
|
|||||||
BeginBlock(Stack,btCaseOf,CurPos.StartPos);
|
BeginBlock(Stack,btCaseOf,CurPos.StartPos);
|
||||||
end else if UpAtomIs('ELSE') then begin
|
end else if UpAtomIs('ELSE') then begin
|
||||||
case TopBlockType(Stack) of
|
case TopBlockType(Stack) of
|
||||||
|
btIf:
|
||||||
|
begin
|
||||||
|
if not EndBlockIsOk then exit;
|
||||||
|
BeginBlock(Stack,btIfElse,CurPos.StartPos);
|
||||||
|
end;
|
||||||
btCaseOf:
|
btCaseOf:
|
||||||
begin
|
begin
|
||||||
if not EndBlockIsOk then exit;
|
if not EndBlockIsOk then exit;
|
||||||
@ -5395,7 +5418,12 @@ var
|
|||||||
btCaseColon,btRepeat:
|
btCaseColon,btRepeat:
|
||||||
begin
|
begin
|
||||||
// missing semicolon
|
// missing semicolon
|
||||||
NeedCompletion:=true;
|
if InCursorBlock then begin
|
||||||
|
{$IFDEF ShowCompleteBlock}
|
||||||
|
DebugLn(['ReadStatements NeedCompletion: unexpected else at ',CleanPosToStr(CurPos.StartPos),': missing semicolon or until. block start: ',CleanPosToStr(Stack.Stack[Stack.Top].StartPos)]);
|
||||||
|
{$ENDIF}
|
||||||
|
NeedCompletion:=true;
|
||||||
|
end;
|
||||||
break;
|
break;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -5403,6 +5431,27 @@ var
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
// check if line start
|
||||||
|
InCursorBlock:=(CursorBlockLvl>=0) and (CursorBlockLvl=Stack.Top)
|
||||||
|
and (not BehindCursorBlock);
|
||||||
|
LineStart:=InCursorBlock and (LastPos>0)
|
||||||
|
and not PositionsInSameLine(Src,LastPos,CurPos.StartPos);
|
||||||
|
if LineStart then
|
||||||
|
Indent:=GetLineIndent(Src,CurPos.StartPos);
|
||||||
|
|
||||||
|
if LineStart then begin
|
||||||
|
// atom is in same block as cursor (not sub block)
|
||||||
|
// and first atom of a line
|
||||||
|
// => check indent
|
||||||
|
if Indent<CursorBlockIndent then begin
|
||||||
|
//DebugLn(['ReadStatements Indent=',Indent,' < CursorBlockIndent=',CursorBlockIndent]);
|
||||||
|
{$IFDEF ShowCompleteBlock}
|
||||||
|
DebugLn(['ReadStatements NeedCompletion: at ',CleanPosToStr(CurPos.StartPos),' Indent=',Indent,' < CursorBlockIndent=',CursorBlockIndent]);
|
||||||
|
{$ENDIF}
|
||||||
|
NeedCompletion:=true;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
LastPos:=CurPos.StartPos;
|
LastPos:=CurPos.StartPos;
|
||||||
until false;
|
until false;
|
||||||
|
|
||||||
@ -5410,6 +5459,9 @@ var
|
|||||||
|
|
||||||
if (not NeedCompletion) and (Stack.Top>=0)
|
if (not NeedCompletion) and (Stack.Top>=0)
|
||||||
and (not BehindCursorBlock) and (CursorBlockLvl=Stack.Top) then begin
|
and (not BehindCursorBlock) and (CursorBlockLvl=Stack.Top) then begin
|
||||||
|
{$IFDEF ShowCompleteBlock}
|
||||||
|
DebugLn(['ReadStatements NeedCompletion: in cursor block, block not closed']);
|
||||||
|
{$ENDIF}
|
||||||
NeedCompletion:=true;
|
NeedCompletion:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -5435,6 +5487,8 @@ var
|
|||||||
AfterGap:=gtNone;
|
AfterGap:=gtNone;
|
||||||
Include(BeautifyFlags,bcfDoNotIndentFirstLine);
|
Include(BeautifyFlags,bcfDoNotIndentFirstLine);
|
||||||
end;
|
end;
|
||||||
|
else
|
||||||
|
exit;
|
||||||
end;
|
end;
|
||||||
if not Replace(NewCode,InsertPos,InsertPos,Indent,FrontGap,AfterGap,
|
if not Replace(NewCode,InsertPos,InsertPos,Indent,FrontGap,AfterGap,
|
||||||
BeautifyFlags) then exit;
|
BeautifyFlags) then exit;
|
||||||
|
Loading…
Reference in New Issue
Block a user