codetools: parsing if-then-else in TPascalParserTool.ReadTilBlockEnd, bug #23542

git-svn-id: trunk@39656 -
This commit is contained in:
mattias 2012-12-26 19:38:02 +00:00
parent 9862bf3af8
commit 17337ba49d
2 changed files with 44 additions and 10 deletions

View File

@ -1361,6 +1361,7 @@ begin
Add('TRY' ,{$ifdef FPC}@{$endif}AllwaysTrue); Add('TRY' ,{$ifdef FPC}@{$endif}AllwaysTrue);
Add('ASM' ,{$ifdef FPC}@{$endif}AllwaysTrue); Add('ASM' ,{$ifdef FPC}@{$endif}AllwaysTrue);
Add('CASE' ,{$ifdef FPC}@{$endif}AllwaysTrue); Add('CASE' ,{$ifdef FPC}@{$endif}AllwaysTrue);
Add('IF' ,{$ifdef FPC}@{$endif}AllwaysTrue);
end; end;
UnexpectedKeyWordInBeginBlock:=TKeyWordFunctionList.Create('UnexpectedKeyWordInBeginBlock'); UnexpectedKeyWordInBeginBlock:=TKeyWordFunctionList.Create('UnexpectedKeyWordInBeginBlock');

View File

@ -283,9 +283,10 @@ implementation
type type
TEndBlockType = (ebtBegin, ebtAsm, ebtTry, ebtCase, ebtRepeat, ebtRecord, TEndBlockType = (ebtBegin, ebtAsm, ebtTry, ebtCase, ebtRepeat, ebtIf,
ebtClass, ebtObject); ebtRecord, ebtClass, ebtObject);
TTryType = (ttNone, ttFinally, ttExcept); TTryType = (ttNone, ttFinally, ttExcept);
TIfType = (itNone, itThen, itElse);
function ProcHeadAttributesToStr(Attr: TProcHeadAttributes): string; function ProcHeadAttributesToStr(Attr: TProcHeadAttributes): string;
var var
@ -2649,11 +2650,12 @@ end;
function TPascalParserTool.ReadTilBlockEnd( function TPascalParserTool.ReadTilBlockEnd(
StopOnBlockMiddlePart, CreateNodes: boolean): boolean; StopOnBlockMiddlePart, CreateNodes: boolean): boolean;
// after reading cursor will be on the keyword ending the block (e.g. 'end') // after reading cursor will be on the atom ending the block (e.g. 'end', 'until', or ';')
var BlockType: TEndBlockType; var BlockType: TEndBlockType;
TryType: TTryType; TryType: TTryType;
BlockStartPos: integer; BlockStartPos: integer;
Desc: TCodeTreeNodeDesc; Desc: TCodeTreeNodeDesc;
IfType: TIfType;
procedure SaveRaiseExceptionWithBlockStartHint(const AMessage: string); procedure SaveRaiseExceptionWithBlockStartHint(const AMessage: string);
var CaretXY: TCodeXYPosition; var CaretXY: TCodeXYPosition;
@ -2698,7 +2700,9 @@ var BlockType: TEndBlockType;
begin begin
Result:=true; Result:=true;
TryType:=ttNone; TryType:=ttNone;
IfType:=itNone;
Desc:=ctnNone; Desc:=ctnNone;
//debugln(['TPascalParserTool.ReadTilBlockEnd START ',GetAtom]);
if UpAtomIs('BEGIN') then begin if UpAtomIs('BEGIN') then begin
BlockType:=ebtBegin; BlockType:=ebtBegin;
Desc:=ctnBeginBlock; Desc:=ctnBeginBlock;
@ -2706,6 +2710,8 @@ begin
BlockType:=ebtRepeat BlockType:=ebtRepeat
else if UpAtomIs('TRY') then else if UpAtomIs('TRY') then
BlockType:=ebtTry BlockType:=ebtTry
else if UpAtomIs('IF') then
BlockType:=ebtIf
else if UpAtomIs('CASE') then else if UpAtomIs('CASE') then
BlockType:=ebtCase BlockType:=ebtCase
else if UpAtomIs('ASM') then else if UpAtomIs('ASM') then
@ -2724,18 +2730,20 @@ begin
BlockStartPos:=CurPos.StartPos; BlockStartPos:=CurPos.StartPos;
repeat repeat
ReadNextAtom; ReadNextAtom;
//debugln(['TPascalParserTool.ReadTilBlockEnd next=',GetAtom]);
if (CurPos.StartPos>SrcLen) then if (CurPos.StartPos>SrcLen) then
SaveRaiseExceptionWithBlockStartHint(ctsUnexpectedEndOfSource); SaveRaiseExceptionWithBlockStartHint(ctsUnexpectedEndOfSource);
if not (CurPos.Flag in AllCommonAtomWords) then continue;
if (CurPos.Flag=cafEND) then begin if (CurPos.Flag=cafEND) then begin
// end
if (BlockType<>ebtAsm) or (CurPos.StartPos=1) or (Src[CurPos.StartPos-1]<>'@') if (BlockType<>ebtAsm) or (CurPos.StartPos=1) or (Src[CurPos.StartPos-1]<>'@')
then begin then begin
if BlockType=ebtRepeat then if BlockType=ebtRepeat then
RaiseStrExpectedWithBlockStartHint('"until"'); RaiseStrExpectedWithBlockStartHint('"until"');
if (BlockType=ebtTry) and (TryType=ttNone) then if (BlockType=ebtTry) and (TryType=ttNone) then
RaiseStrExpectedWithBlockStartHint('"finally"'); RaiseStrExpectedWithBlockStartHint('"finally"');
if (BlockType=ebtIf) and (IfType=itNone) then
RaiseStrExpectedWithBlockStartHint('"then"');
if Desc<>ctnNone then begin if Desc<>ctnNone then begin
CurNode.EndPos:=CurPos.EndPos; CurNode.EndPos:=CurPos.EndPos;
EndChildNode; EndChildNode;
@ -2747,12 +2755,24 @@ begin
UndoReadNextAtom; UndoReadNextAtom;
break; break;
end; end;
end else if EndKeyWordFuncList.DoIdentifier(@Src[CurPos.StartPos]) end else if CurPos.Flag=cafSemicolon then begin
or UpAtomIs('REPEAT') then // ;
begin if BlockType=ebtIf then begin
if (IfType=itNone) then
RaiseStrExpectedWithBlockStartHint('"then"');
if Desc<>ctnNone then begin
CurNode.EndPos:=CurPos.EndPos;
EndChildNode;
end;
break;
end;
end else if CurPos.Flag<>cafWord then begin
continue;
end else if BlockStatementStartKeyWordFuncList.DoIdentifier(@Src[CurPos.StartPos])
then begin
if BlockType=ebtAsm then if BlockType=ebtAsm then
SaveRaiseUnexpectedKeyWordInAsmBlock; SaveRaiseUnexpectedKeyWordInAsmBlock;
if (BlockType<>ebtRecord) or (not UpAtomIs('CASE')) then if (BlockType<>ebtRecord) then
ReadTilBlockEnd(false,CreateNodes); ReadTilBlockEnd(false,CreateNodes);
end else if UpAtomIs('UNTIL') then begin end else if UpAtomIs('UNTIL') then begin
if BlockType<>ebtRepeat then if BlockType<>ebtRepeat then
@ -2774,6 +2794,19 @@ begin
TryType:=ttExcept; TryType:=ttExcept;
end else end else
RaiseStrExpectedWithBlockStartHint('"end"'); RaiseStrExpectedWithBlockStartHint('"end"');
end else if UpAtomIs('THEN') then begin
if (BlockType=ebtIf) and (IfType=itNone) then begin
debugln(['TPascalParserTool.ReadTilBlockEnd BBB1']);
if StopOnBlockMiddlePart then break;
IfType:=itThen;
end else
RaiseStrExpectedWithBlockStartHint('"if"');
end else if UpAtomIs('ELSE') then begin
if (BlockType=ebtIf) and (IfType=itThen) then begin
if StopOnBlockMiddlePart then break;
IfType:=itElse;
end else
RaiseStrExpectedWithBlockStartHint('"if"');
end else if CreateNodes and UpAtomIs('WITH') then begin end else if CreateNodes and UpAtomIs('WITH') then begin
ReadWithStatement(true,CreateNodes); ReadWithStatement(true,CreateNodes);
end else if CreateNodes and UpAtomIs('ON') and (BlockType=ebtTry) end else if CreateNodes and UpAtomIs('ON') and (BlockType=ebtTry)
@ -2783,7 +2816,7 @@ begin
// check for unexpected keywords // check for unexpected keywords
case BlockType of case BlockType of
ebtBegin,ebtTry,ebtCase,ebtRepeat: ebtBegin,ebtTry,ebtIf,ebtCase,ebtRepeat:
if UnexpectedKeyWordInBeginBlock.DoIdentifier(@Src[CurPos.StartPos]) then if UnexpectedKeyWordInBeginBlock.DoIdentifier(@Src[CurPos.StartPos]) then
SaveRaiseUnexpectedKeyWordInBeginEndBlock; SaveRaiseUnexpectedKeyWordInBeginEndBlock;