소스 검색

* Fix bug #31283, parsing of Self as identifier

git-svn-id: trunk@35562 -
michael 8 년 전
부모
커밋
da88f7d217
3개의 변경된 파일64개의 추가작업 그리고 27개의 파일을 삭제
  1. 45 25
      packages/fcl-passrc/src/pparser.pp
  2. 11 1
      packages/fcl-passrc/src/pscanner.pp
  3. 8 1
      packages/fcl-passrc/tests/tcscanner.pas

+ 45 - 25
packages/fcl-passrc/src/pparser.pp

@@ -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

+ 11 - 1
packages/fcl-passrc/src/pscanner.pp

@@ -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;

+ 8 - 1
packages/fcl-passrc/tests/tcscanner.pas

@@ -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;