* Fix bug #31283, parsing of Self as identifier

git-svn-id: trunk@35562 -
This commit is contained in:
michael 2017-03-11 13:28:22 +00:00
parent ea7f7c1d2a
commit da88f7d217
3 changed files with 64 additions and 27 deletions

View File

@ -932,7 +932,7 @@ function TPasParser.CheckHint(Element: TPasElement; ExpectSemiColon: Boolean
Var
Found : Boolean;
h : TPasMemberHint;
begin
Result:=[];
Repeat
@ -1423,7 +1423,7 @@ begin
NextToken;
If CurToken=tkOf then
Result.ElType := ParseType(Result,Scanner.CurSourcePos)
else
else
ungettoken;
end;
@ -1516,7 +1516,7 @@ begin
tkLessEqualThan : Result:=eopLessthanEqual;
tkGreaterEqualThan : Result:=eopGreaterThanEqual;
tkPower : Result:=eopPower;
tkSymmetricalDifference : Result:=eopSymmetricalDifference;
tkSymmetricalDifference : Result:=eopSymmetricalDifference;
tkIs : Result:=eopIs;
tkAs : Result:=eopAs;
tkSHR : Result:=eopSHR;
@ -1534,7 +1534,7 @@ begin
ParseExc(nParserNotAnOperand,SParserNotAnOperand,[AToken,TokenInfos[AToken]]);
end;
end;
function TPasParser.ParseExpIdent(AParent: TPasElement): TPasExpr;
Function IsWriteOrstr(P : TPasExpr) : boolean;
@ -1550,6 +1550,30 @@ function TPasParser.ParseExpIdent(AParent: TPasElement): TPasExpr;
Result:=(N='write') or (N='str') or (N='writeln');
end;
end;
Procedure HandleSelf(Var Last: TPasExpr);
Var
b : TBinaryExpr;
optk : TToken;
begin
NextToken;
if CurToken = tkDot then
begin // self.Write(EscapeText(AText));
optk:=CurToken;
NextToken;
b:=CreateBinaryExpr(AParent,Last, ParseExpIdent(AParent), TokenToExprOp(optk));
if not Assigned(b.right) then
begin
b.Release;
ParseExcExpectedIdentifier;
end;
Last:=b;
end;
UngetToken;
end;
var
Last , Expr: TPasExpr;
prm : TParamsExpr;
@ -1563,7 +1587,16 @@ begin
tkString: Last:=CreatePrimitiveExpr(AParent,pekString,CurTokenString);
tkChar: Last:=CreatePrimitiveExpr(AParent,pekString, CurTokenText);
tkNumber: Last:=CreatePrimitiveExpr(AParent,pekNumber, CurTokenString);
tkIdentifier: Last:=CreatePrimitiveExpr(AParent,pekIdent, CurTokenText);
tkIdentifier:
begin
if CompareText(CurTokenText,'self')=0 then
begin
Last:=CreateSelfExpr(AParent);
HandleSelf(Last)
end
Else
Last:=CreatePrimitiveExpr(AParent,pekIdent, CurTokenText)
end;
tkfalse, tktrue: Last:=CreateBoolConstExpr(Aparent,pekBoolConst, CurToken=tktrue);
tknil: Last:=CreateNilExpr(AParent);
tkSquaredBraceOpen: Last:=ParseParams(AParent,pekSet);
@ -1587,20 +1620,7 @@ begin
tkself:
begin
Last:=CreateSelfExpr(AParent);
NextToken;
if CurToken = tkDot then
begin // self.Write(EscapeText(AText));
optk:=CurToken;
NextToken;
b:=CreateBinaryExpr(AParent,Last, ParseExpIdent(AParent), TokenToExprOp(optk));
if not Assigned(b.right) then
begin
b.Release;
ParseExcExpectedIdentifier;
end;
Last:=b;
end;
UngetToken;
HandleSelf(Last);
end;
tkAt:
begin
@ -1724,7 +1744,7 @@ var
i : Integer;
tempop : TToken;
NotBinary : Boolean;
const
PrefixSym = [tkPlus, tkMinus, tknot, tkAt]; // + - not @
BinaryOP = [tkMul, tkDivision, tkdiv, tkmod, tkDotDot,
@ -2372,6 +2392,7 @@ var
if CurBlock=declType then
Engine.FinishScope(stTypeSection,Declarations);
CurBlock:=NewBlock;
Scanner.SetForceCaret(NewBlock=declType);
end;
var
@ -2492,7 +2513,6 @@ begin
end;
declType:
begin
Scanner.SetForceCaret(True);
TypeEl := ParseTypeDecl(Declarations);
// Scanner.SetForceCaret(OldForceCaret); // It may have been switched off
if Assigned(TypeEl) then // !!!
@ -2933,7 +2953,7 @@ var
TypeName: String;
NamePos: TPasSourcePos;
OldForceCaret : Boolean;
begin
TypeName := CurTokenString;
NamePos:=Scanner.CurSourcePos;
@ -3605,7 +3625,7 @@ begin
begin
ExpectToken(tkObject);
Element.IsOfObject := True;
end
end
else if (curToken = tkIs) then
begin
expectToken(tkIdentifier);
@ -3614,8 +3634,8 @@ begin
Element.IsNested:=True;
end
else
UnGetToken;
end;
UnGetToken;
end;
NextToken;
if CurToken = tkEqual then
begin

View File

@ -383,7 +383,8 @@ type
po_asmwhole, // store whole text between asm..end in TPasImplAsmStatement.Tokens
po_nooverloadedprocs, // do not create TPasOverloadedProc for procs with same name
po_keepclassforward, // disabled: delete class fowards when there is a class declaration
po_arrayrangeexpr // enable: create TPasArrayType.IndexRange, disable: create TPasArrayType.Ranges
po_arrayrangeexpr, // enable: create TPasArrayType.IndexRange, disable: create TPasArrayType.Ranges
po_selftoken // Self is a token. For backward compatibility.
);
TPOptions = set of TPOption;
@ -1301,6 +1302,15 @@ begin
tkComment:
if not (FSkipComments or PPIsSkipping) then
Break;
tkSelf:
begin
if Not (po_selftoken in Options) then
begin
FCurToken:=tkIdentifier;
Result:=FCurToken;
end;
Break;
end;
else
if not PPIsSkipping then
break;

View File

@ -82,6 +82,8 @@ type
procedure TestNestedComment3;
procedure TestNestedComment4;
procedure TestIdentifier;
procedure TestSelf;
procedure TestSelfNoToken;
procedure TestString;
procedure TestNumber;
procedure TestChar;
@ -170,7 +172,6 @@ type
procedure TestRecord;
procedure TestRepeat;
procedure TestResourceString;
procedure TestSelf;
procedure TestSet;
procedure TestShl;
procedure TestShr;
@ -1161,9 +1162,15 @@ end;
procedure TTestScanner.TestSelf;
begin
FScanner.Options:=FScanner.Options + [po_selftoken];
TestToken(tkself,'self');
end;
procedure TTestScanner.TestSelfNoToken;
begin
TestToken(tkIdentifier,'self');
end;
procedure TTestScanner.TestSet;