diff --git a/components/codetools/stdcodetools.pas b/components/codetools/stdcodetools.pas index 261b951f3b..2b41ed96e8 100644 --- a/components/codetools/stdcodetools.pas +++ b/components/codetools/stdcodetools.pas @@ -43,6 +43,7 @@ interface { $DEFINE DisableIgnoreErrorAfter} { $DEFINE VerboseGetStringConstBounds} +{ $DEFINE ShowCompleteBlock} uses {$IFDEF MEM_CHECK} @@ -5152,6 +5153,8 @@ type btCaseColon, btCaseElse, btRepeat, + btIf, + btIfElse, btClass, btInterface, btObject, @@ -5197,6 +5200,9 @@ var Stack.Capacity:=Stack.Capacity*2; ReAllocMem(Stack.Stack,SizeOf(TBlock)*Stack.Capacity); end; + {$IFDEF ShowCompleteBlock} + DebugLn([GetIndentStr(Stack.Top*2),'BeginBlock ',CleanPosToStr(StartPos),' ',GetAtom]); + {$ENDIF} Block:=@Stack.Stack[Stack.Top]; Block^.Typ:=Typ; Block^.StartPos:=StartPos; @@ -5204,6 +5210,9 @@ var procedure EndBlock(var Stack: TBlockStack); 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); end; @@ -5291,23 +5300,8 @@ var if (CurPos.StartPos>SrcLen) or (CurPos.StartPos>=StartNode.EndPos) then break; - // 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 IndentbtAsm then begin if UpAtomIs('TRY') then 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) - 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) - else if UpAtomIs('REPEAT') then + end else if UpAtomIs('REPEAT') then BeginBlock(Stack,btRepeat,CurPos.StartPos) else if UpAtomIs('UNTIL') then begin if TopBlockType(Stack)=btRepeat then begin @@ -5380,6 +5396,8 @@ var end; end else if UpAtomIs('ASM') then begin BeginBlock(Stack,btAsm,CurPos.StartPos); + end else if UpAtomIs('IF') then begin + BeginBlock(Stack,btIf,CurPos.StartPos) end else if UpAtomIs('CASE') then begin BeginBlock(Stack,btCase,CurPos.StartPos) end else if UpAtomIs('OF') then begin @@ -5387,6 +5405,11 @@ var BeginBlock(Stack,btCaseOf,CurPos.StartPos); end else if UpAtomIs('ELSE') then begin case TopBlockType(Stack) of + btIf: + begin + if not EndBlockIsOk then exit; + BeginBlock(Stack,btIfElse,CurPos.StartPos); + end; btCaseOf: begin if not EndBlockIsOk then exit; @@ -5395,7 +5418,12 @@ var btCaseColon,btRepeat: begin // 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; end; end; @@ -5403,6 +5431,27 @@ var 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