fcl-passrc: resolver: fixed error during parsing with-do

git-svn-id: trunk@41082 -
This commit is contained in:
Mattias Gaertner 2019-01-27 10:03:09 +00:00
parent 597a23d278
commit fb78404e1c
2 changed files with 78 additions and 11 deletions

View File

@ -5625,14 +5625,13 @@ var
var var
SubBlock: TPasImplElement; SubBlock: TPasImplElement;
Left, Right: TPasExpr; Left, Right, Expr: TPasExpr;
El : TPasImplElement; El : TPasImplElement;
lt : TLoopType; lt : TLoopType;
SrcPos: TPasSourcePos; SrcPos: TPasSourcePos;
Name: String; Name: String;
TypeEl: TPasType; TypeEl: TPasType;
ImplRaise: TPasImplRaise; ImplRaise: TPasImplRaise;
Expr: TPasExpr;
begin begin
NewImplElement:=nil; NewImplElement:=nil;
@ -5829,12 +5828,11 @@ begin
SrcPos:=CurTokenPos; SrcPos:=CurTokenPos;
NextToken; NextToken;
El:=TPasImplWithDo(CreateElement(TPasImplWithDo,'',CurBlock,SrcPos)); El:=TPasImplWithDo(CreateElement(TPasImplWithDo,'',CurBlock,SrcPos));
Left:=DoParseExpression(CurBlock); Expr:=DoParseExpression(CurBlock);
//writeln(i,'WITH Expr="',Expr,'" Token=',CurTokenText); //writeln(i,'WITH Expr="',Expr,'" Token=',CurTokenText);
TPasImplWithDo(El).AddExpression(Left); TPasImplWithDo(El).AddExpression(Expr);
Left.Parent:=El; Expr.Parent:=El;
Engine.BeginScope(stWithExpr,Left); Engine.BeginScope(stWithExpr,Expr);
Left:=nil;
CreateBlock(TPasImplWithDo(El)); CreateBlock(TPasImplWithDo(El));
El:=nil; El:=nil;
repeat repeat
@ -5842,11 +5840,10 @@ begin
if CurToken<>tkComma then if CurToken<>tkComma then
ParseExcTokenError(TokenInfos[tkdo]); ParseExcTokenError(TokenInfos[tkdo]);
NextToken; NextToken;
Left:=DoParseExpression(CurBlock); Expr:=DoParseExpression(CurBlock);
//writeln(i,'WITH ...,Expr="',Expr,'" Token=',CurTokenText); //writeln(i,'WITH ...,Expr="',Expr,'" Token=',CurTokenText);
TPasImplWithDo(CurBlock).AddExpression(Left); TPasImplWithDo(CurBlock).AddExpression(Expr);
Engine.BeginScope(stWithExpr,Left); Engine.BeginScope(stWithExpr,Expr);
Left:=nil;
until false; until false;
end; end;
tkcase: tkcase:

View File

@ -256,6 +256,7 @@ type
// enums and sets // enums and sets
Procedure TestEnums; Procedure TestEnums;
Procedure TestEnumRangeFail; Procedure TestEnumRangeFail;
Procedure TestEnumDotValueFail;
Procedure TestSets; Procedure TestSets;
Procedure TestSetOperators; Procedure TestSetOperators;
Procedure TestEnumParams; Procedure TestEnumParams;
@ -884,6 +885,7 @@ type
Procedure TestClassHelper_NestedInheritedParentFail; Procedure TestClassHelper_NestedInheritedParentFail;
Procedure TestClassHelper_AccessFields; Procedure TestClassHelper_AccessFields;
Procedure TestClassHelper_CallClassMethodFail; Procedure TestClassHelper_CallClassMethodFail;
Procedure TestClassHelper_WithHelperFail;
Procedure TestClassHelper_AsTypeFail; Procedure TestClassHelper_AsTypeFail;
Procedure TestClassHelper_Enumerator; Procedure TestClassHelper_Enumerator;
Procedure TestClassHelper_FromUnitInterface; Procedure TestClassHelper_FromUnitInterface;
@ -898,6 +900,8 @@ type
Procedure TestTypeHelper_HelperForProcTypeFail; Procedure TestTypeHelper_HelperForProcTypeFail;
Procedure TestTypeHelper_DefaultPropertyFail; Procedure TestTypeHelper_DefaultPropertyFail;
Procedure TestTypeHelper_Enum; Procedure TestTypeHelper_Enum;
Procedure TestTypeHelper_EnumDotValueFail;
Procedure TestTypeHelper_EnumHelperDotProcFail;
Procedure TestTypeHelper_Enumerator; Procedure TestTypeHelper_Enumerator;
Procedure TestTypeHelper_Constructor_NewInstance; Procedure TestTypeHelper_Constructor_NewInstance;
@ -3548,6 +3552,17 @@ begin
CheckParserException('Const ranges are not allowed',nParserNoConstRangeAllowed); CheckParserException('Const ranges are not allowed',nParserNoConstRangeAllowed);
end; end;
procedure TTestResolver.TestEnumDotValueFail;
begin
StartProgram(false);
Add([
'type TFlag = (a,b,c);',
'var f: TFlag;',
'begin',
' f:=f.a;']);
CheckResolverException('illegal qualifier "." after "f:TFlag"',nIllegalQualifierAfter);
end;
procedure TTestResolver.TestSets; procedure TTestResolver.TestSets;
begin begin
StartProgram(false); StartProgram(false);
@ -16102,6 +16117,20 @@ begin
CheckResolverException(sHelpersCannotBeUsedAsTypes,nHelpersCannotBeUsedAsTypes); CheckResolverException(sHelpersCannotBeUsedAsTypes,nHelpersCannotBeUsedAsTypes);
end; end;
procedure TTestResolver.TestClassHelper_WithHelperFail;
begin
StartProgram(false);
Add([
'type',
' TObject = class end;',
' THelper = class helper for TObject',
' end;',
'begin',
' with THelper do ;',
'']);
CheckResolverException(sHelpersCannotBeUsedAsTypes,nHelpersCannotBeUsedAsTypes);
end;
procedure TTestResolver.TestClassHelper_AsTypeFail; procedure TTestResolver.TestClassHelper_AsTypeFail;
begin begin
StartProgram(false); StartProgram(false);
@ -16559,6 +16588,7 @@ begin
' TFlag = (Red, Green, Blue);', ' TFlag = (Red, Green, Blue);',
' THelper = type helper for TFlag', ' THelper = type helper for TFlag',
' function toString: string;', ' function toString: string;',
' class procedure Fly;',
' end;', ' end;',
'function THelper.toString: string;', 'function THelper.toString: string;',
'begin', 'begin',
@ -16566,14 +16596,54 @@ begin
' if Self=TFlag.Blue then ;', ' if Self=TFlag.Blue then ;',
' Result:=str(Self);', ' Result:=str(Self);',
'end;', 'end;',
'class procedure THelper.Fly;',
'begin',
'end;',
'var', 'var',
' f: TFlag;', ' f: TFlag;',
'begin', 'begin',
' f.toString;', ' f.toString;',
' TFlag.Fly;',
'']); '']);
ParseProgram; ParseProgram;
end; end;
procedure TTestResolver.TestTypeHelper_EnumDotValueFail;
begin
StartProgram(false);
Add([
'{$modeswitch typehelpers}',
'type',
' TFlag = (Red, Green, Blue);',
' THelper = type helper for TFlag',
' end;',
'var',
' f: TFlag;',
'begin',
' f:=f.red;',
'']);
CheckResolverException('identifier not found "red"',nIdentifierNotFound);
end;
procedure TTestResolver.TestTypeHelper_EnumHelperDotProcFail;
begin
StartProgram(false);
Add([
'{$modeswitch typehelpers}',
'type',
' TFlag = (Red, Green, Blue);',
' THelper = type helper for TFlag',
' procedure Fly;',
' end;',
'procedure THelper.Fly;',
'begin',
'end;',
'begin',
' TFlag.Fly;',
'']);
CheckResolverException('Cannot access this member from a type helper',nCannotAccessThisMemberFromAX);
end;
procedure TTestResolver.TestTypeHelper_Enumerator; procedure TTestResolver.TestTypeHelper_Enumerator;
begin begin
StartProgram(false); StartProgram(false);