Browse Source

* Merging revisions r46282 from trunk:
------------------------------------------------------------------------
r46282 | michael | 2020-08-06 09:21:22 +0200 (Thu, 06 Aug 2020) | 1 line

* Escape keywords when writing
------------------------------------------------------------------------

git-svn-id: branches/fixes_3_2@46608 -

michael 5 years ago
parent
commit
70cf4d95d7
2 changed files with 83 additions and 49 deletions
  1. 66 32
      packages/fcl-passrc/src/pastree.pp
  2. 17 17
      packages/fcl-passrc/src/paswrite.pp

+ 66 - 32
packages/fcl-passrc/src/pastree.pp

@@ -162,12 +162,15 @@ type
     {$ENDIF}
     constructor Create(const AName: string; AParent: TPasElement); virtual;
     destructor Destroy; override;
+    Class Function IsKeyWord(Const S : String) : Boolean;
+    Class Function EscapeKeyWord(Const S : String) : String;
     procedure AddRef{$IFDEF CheckPasTreeRefCount}(const aId: string){$ENDIF};
     procedure Release{$IFDEF CheckPasTreeRefCount}(const aId: string){$ENDIF};
     procedure ForEachCall(const aMethodCall: TOnForEachPasElement;
       const Arg: Pointer); virtual;
     procedure ForEachChildCall(const aMethodCall: TOnForEachPasElement;
       const Arg: Pointer; Child: TPasElement; CheckParent: boolean); virtual;
+    Function SafeName : String;                 // Name but with & prepended if name is a keyword.
     function FullPath: string;                  // parent's names, until parent is not TPasDeclarations
     function ParentPath: string;                // parent's names
     function FullName: string; virtual;         // FullPath + Name
@@ -2551,7 +2554,7 @@ function TPasType.FixTypeDecl(aDecl: String): String;
 begin
   Result:=aDecl;
   if (Name<>'') then
-    Result:=Name+' = '+Result;
+    Result:=SafeName+' = '+Result;
   ProcessHints(false,Result);
 end;
 
@@ -2829,6 +2832,30 @@ begin
   inherited Destroy;
 end;
 
+class function TPasElement.IsKeyWord(const S: String): Boolean;
+
+Const
+   KW=';absolute;and;array;asm;begin;case;const;constructor;destructor;div;do;'+
+       'downto;else;end;file;for;function;goto;if;implementation;in;inherited;'+
+       'inline;interface;label;mod;nil;not;object;of;on;operator;or;packed;'+
+       'procedure;program;record;reintroduce;repeat;self;set;shl;shr;string;then;'+
+       'to;type;unit;until;uses;var;while;with;xor;dispose;exit;false;new;true;'+
+       'as;class;dispinterface;except;exports;finalization;finally;initialization;'+
+       'inline;is;library;on;out;packed;property;raise;resourcestring;threadvar;try;'+
+       'private;published;length;setlength;';
+
+begin
+  Result:=Pos(';'+lowercase(S)+';',KW)<>0;
+end;
+
+class function TPasElement.EscapeKeyWord(const S: String): String;
+begin
+  Result:=S;
+  If IsKeyWord(Result) then
+    Result:='&'+Result
+
+end;
+
 procedure TPasElement.AddRef{$IFDEF CheckPasTreeRefCount}(const aId: string){$ENDIF};
 begin
   {$ifdef EnablePasTreeGlobalRefCount}
@@ -2918,6 +2945,13 @@ begin
   Child.ForEachCall(aMethodCall,Arg);
 end;
 
+function TPasElement.SafeName: String;
+begin
+  Result:=Name;
+  if IsKeyWord(Result) then
+    Result:='&'+Result;
+end;
+
 function TPasElement.FullPath: string;
 
 var
@@ -2996,7 +3030,7 @@ function TPasElement.GetDeclaration(full: Boolean): string;
 
 begin
   if Full then
-    Result := Name
+    Result := SafeName
   else
     Result := '';
 end;
@@ -4016,7 +4050,7 @@ end;
 
 function TPasModule.GetDeclaration(full : boolean): string;
 begin
-  Result := 'Unit ' + Name;
+  Result := 'Unit ' + SafeName;
   if full then ;
 end;
 
@@ -4043,7 +4077,7 @@ begin
   Result:=Expr.GetDeclaration(true);
   If Full Then
     begin
-    Result:=Name+' = '+Result;
+    Result:=SafeName+' = '+Result;
     ProcessHints(False,Result);
     end;
 end;
@@ -4063,10 +4097,10 @@ end;
 
 function TPasPointerType.GetDeclaration(full: Boolean): string;
 begin
-  Result:='^'+DestType.Name;
+  Result:='^'+DestType.SafeName;
   If Full then
     begin
-    Result:=Name+' = '+Result;
+    Result:=SafeName+' = '+Result;
     ProcessHints(False,Result);
     end;
 end;
@@ -4086,7 +4120,7 @@ end;
 
 function TPasAliasType.GetDeclaration(full: Boolean): string;
 begin
-  Result:=DestType.Name;
+  Result:=DestType.SafeName;
   If Full then
     Result:=FixTypeDecl(Result);
 end;
@@ -4107,7 +4141,7 @@ end;
 
 function TPasClassOfType.GetDeclaration (full : boolean) : string;
 begin
-  Result:='Class of '+DestType.Name;
+  Result:='Class of '+DestType.SafeName;
   If Full then
     Result:=FixTypeDecl(Result);
 end;
@@ -4158,7 +4192,7 @@ begin
   If IsPacked then
     Result := 'packed '+Result;      // 12/04/04 Dave - Added
   If Assigned(Eltype) then
-    Result:=Result+ElType.Name
+    Result:=Result+ElType.SafeName
   else
     Result:=Result+'const';
 end;
@@ -4186,7 +4220,7 @@ function TPasFileType.GetDeclaration (full : boolean) : string;
 begin
   Result:='File';
   If Assigned(Eltype) then
-    Result:=Result+' of '+ElType.Name;
+    Result:=Result+' of '+ElType.SafeName;
   If Full Then
     Result:=FixTypeDecl(Result);
 end;
@@ -4207,13 +4241,13 @@ begin
   S:=TStringList.Create;
   Try
     If Full and (Name<>'') then
-      S.Add(Name+' = (')
+      S.Add(SafeName+' = (')
     else
       S.Add('(');
     GetEnumNames(S);
     S[S.Count-1]:=S[S.Count-1]+')';
     If Full then
-      Result:=IndentStrings(S,Length(Name)+4)
+      Result:=IndentStrings(S,Length(SafeName)+4)
     else
       Result:=IndentStrings(S,1);
     if Full then
@@ -4241,7 +4275,7 @@ begin
     S:=TStringList.Create;
     Try
       If Full and (Name<>'') then
-        S.Add(Name+'= Set of (')
+        S.Add(SafeName+'= Set of (')
       else
         S.Add('Set of (');
       TPasEnumType(EnumType).GetEnumNames(S);
@@ -4254,9 +4288,9 @@ begin
     end
   else
     begin
-    Result:='Set of '+EnumType.Name;
+    Result:='Set of '+EnumType.SafeName;
     If Full then
-      Result:=Name+' = '+Result;
+      Result:=SafeName+' = '+Result;
     end;
   If Full then
     ProcessHints(False,Result);
@@ -4393,9 +4427,9 @@ begin
     If Full and (Name<>'') then
       begin
       if GenericTemplateTypes.Count>0 then
-        Temp:=Name+GenericTemplateTypesAsString(GenericTemplateTypes)+' = '+Temp
+        Temp:=SafeName+GenericTemplateTypesAsString(GenericTemplateTypes)+' = '+Temp
       else
-        Temp:=Name+' = '+Temp;
+        Temp:=SafeName+' = '+Temp;
       end;
     S.Add(Temp);
     GetMembers(S);
@@ -4467,7 +4501,7 @@ begin
   S:=TStringList.Create;
   Try
     If Full then
-      S.Add(Format('%s = ',[Name]));
+      S.Add(Format('%s = ',[SafeName]));
     S.Add(TypeName);
     GetArguments(S);
     If IsOfObject then
@@ -4493,14 +4527,14 @@ begin
   S:=TStringList.Create;
   Try
     If Full then
-      S.Add(Format('%s = ',[Name]));
+      S.Add(Format('%s = ',[SafeName]));
     S.Add(TypeName);
     GetArguments(S);
     If Assigned(ResultEl) then
       begin
       T:=' : ';
       If (ResultEl.ResultType.Name<>'') then
-        T:=T+ResultEl.ResultType.Name
+        T:=T+ResultEl.ResultType.SafeName
       else
         T:=T+ResultEl.ResultType.GetDeclaration(False);
       S.Add(T);
@@ -4534,7 +4568,7 @@ begin
     If VarType.Name='' then
       Result:=VarType.GetDeclaration(False)
     else
-      Result:=VarType.Name;
+      Result:=VarType.SafeName;
     Result:=Result+Modifiers;
     if (Value<>'') then
       Result:=Result+' = '+Value;
@@ -4543,7 +4577,7 @@ begin
     Result:=Value;
   If Full then
     begin
-    Result:=Name+' '+Seps[Assigned(VarType)]+' '+Result;
+    Result:=SafeName+' '+Seps[Assigned(VarType)]+' '+Result;
     Result:=Result+HintsString;
     end;
 end;
@@ -4584,7 +4618,7 @@ begin
     If VarType.Name='' then
       Result:=VarType.GetDeclaration(False)
     else
-      Result:=VarType.Name;
+      Result:=VarType.SafeName;
     end
   else if Assigned(Expr) then
     Result:=Expr.GetDeclaration(True);
@@ -4604,9 +4638,9 @@ begin
     S:=' ';
   If Full then
     begin
-    Result:=Name+S+': '+Result;
+    Result:=SafeName+S+': '+Result;
     If (ImplementsName<>'') then
-       Result:=Result+' implements '+ImplementsName;
+       Result:=Result+' implements '+EscapeKeyWord(ImplementsName);
     end;   
   If IsDefault then
     Result:=Result+'; default';
@@ -4836,7 +4870,7 @@ begin
           end;
         end
       else if Name<>'' then
-        T:=T+' '+Name;
+        T:=T+' '+SafeName;
       S.Add(T);
       end;
     ProcType.GetArguments(S);
@@ -4846,7 +4880,7 @@ begin
         begin
         T:=' : ';
         If (Name<>'') then
-          T:=T+Name
+          T:=T+SafeName
         else
           T:=T+GetDeclaration(False);
         S.Add(T);
@@ -4902,7 +4936,7 @@ begin
         begin
         T:=' : ';
         If (Name<>'') then
-          T:=T+Name
+          T:=T+SafeName
         else
           T:=T+GetDeclaration(False);
         S.Add(T);
@@ -4970,14 +5004,14 @@ begin
   If Assigned(ArgType) then
     begin
     If ArgType.Name<>'' then
-      Result:=ArgType.Name
+      Result:=ArgType.SafeName
     else
       Result:=ArgType.GetDeclaration(False);
     If Full and (Name<>'') then
-      Result:=Name+': '+Result;
+      Result:=SafeName+': '+Result;
     end
   else If Full then
-    Result:=Name
+    Result:=SafeName
   else
     Result:='';
 end;
@@ -5637,7 +5671,7 @@ begin
     begin
     If Result<>'' then
       Result:=Result+'; ';
-    Result:=Result+Fields[I].Name+': '+Fields[i].ValueExp.getDeclaration(Full);
+    Result:=Result+EscapeKeyWord(Fields[I].Name)+': '+Fields[i].ValueExp.getDeclaration(Full);
     end;
   Result:='('+Result+')';
 end;

+ 17 - 17
packages/fcl-passrc/src/paswrite.pp

@@ -305,7 +305,7 @@ Var
 begin
   S:='';
   if aModule.Name<>'' then
-    S:=Format('program %s',[aModule.Name]);
+    S:=Format('program %s',[aModule.SafeName]);
   if (S<>'') then
     begin
     If AModule.InputFile<>'' then
@@ -346,7 +346,7 @@ Var
 begin
   S:='';
   if aModule.Name<>'' then
-    S:=Format('library %s',[aModule.Name]);
+    S:=Format('library %s',[aModule.SafeName]);
   if (S<>'') then
     begin
     If AModule.InputFile<>'' then
@@ -434,7 +434,7 @@ begin
         For J:=0 to C.Members.Count-1 do
           begin
           M:=TPasElement(C.members[J]);
-          DoCheckElement(M,True,C.Name+'.');
+          DoCheckElement(M,True,C.SafeName+'.');
           end;
       end;
     end;
@@ -455,7 +455,7 @@ begin
   PrepareDeclSection('type');
   For I:=0 to aSection.Classes.Count-1 do
     begin
-    CN:=TPasElement(aSection.Classes[i]).Name;
+    CN:=TPasElement(aSection.Classes[i]).SafeName;
     if (FForwardClasses.Count=0) or (ForwardClasses.IndexOf(CN)<>-1) then
       Addln('%s = class;',[CN]);
     end;
@@ -464,7 +464,7 @@ end;
 procedure TPasWriter.WriteUnit(aModule: TPasModule);
 
 begin
-  AddLn('unit ' + AModule.Name + ';');
+  AddLn('unit ' + AModule.SafeName + ';');
   if Assigned(AModule.GlobalDirectivesSection) then
     begin
     AddLn;
@@ -621,7 +621,7 @@ begin
   PrepareDeclSection('type');
   Addln;
   MaybeSetLineElement(AClass);
-  Add(AClass.Name + ' = ');
+  Add(AClass.SafeName + ' = ');
   if AClass.IsPacked then
      Add('packed ');                      // 12/04/04 - Dave - Added
   case AClass.ObjKind of
@@ -636,16 +636,16 @@ begin
   if (AClass.ObjKind=okClass) and (ACLass.ExternalName<>'') and NotOption(woNoExternalClass) then
     Add(' external name ''%s'' ',[AClass.ExternalName]);
   if Assigned(AClass.AncestorType) then
-    Add('(' + AClass.AncestorType.Name);
+    Add('(' + AClass.AncestorType.SafeName);
   if AClass.Interfaces.Count > 0 then
   begin
     if Assigned(AClass.AncestorType) then
       InterfacesListPrefix:=', '
     else
       InterfacesListPrefix:='(';
-    Add(InterfacesListPrefix + TPasType(AClass.Interfaces[0]).Name);
+    Add(InterfacesListPrefix + TPasType(AClass.Interfaces[0]).SafeName);
     for i := 1 to AClass.Interfaces.Count - 1 do
-      Add(', ' + TPasType(AClass.Interfaces[i]).Name);
+      Add(', ' + TPasType(AClass.Interfaces[i]).SafeName);
   end;
   if Assigned(AClass.AncestorType) or (AClass.Interfaces.Count > 0) then
     AddLn(')')
@@ -706,9 +706,9 @@ begin
     PrepareDeclSectionInStruct('class var')
   else if CurDeclSection<>'' then
     PrepareDeclSectionInStruct('var');
-  Add(aVar.Name + ': ');
+  Add(aVar.SafeName + ': ');
   if Not Assigned(aVar.VarType) then
-    Raise EWriteError.CreateFmt('No type for variable %s',[aVar.Name]);
+    Raise EWriteError.CreateFmt('No type for variable %s',[aVar.SafeName]);
   WriteType(aVar.VarType,False);
   if (aVar.AbsoluteExpr<>nil) then
     Add(' absolute %s',[aVar.AbsoluteExpr.ClassName])
@@ -738,7 +738,7 @@ procedure TPasWriter.WriteArgument(aArg: TPasArgument);
 begin
   if (aArg.Access<>argDefault) then
     Add(AccessNames[aArg.Access]+' ');
-  Add(aArg.Name+' : ');
+  Add(aArg.SafeName+' : ');
   WriteType(aArg.ArgType,False);
 end;
 
@@ -809,7 +809,7 @@ begin
     PrepareDeclSection('');
   if Not IsImpl then
     IsImpl:=FInImplementation;
-  Add(AProc.TypeName + ' ' + NamePrefix+AProc.Name);
+  Add(AProc.TypeName + ' ' + NamePrefix+AProc.SafeName);
   if Assigned(AProc.ProcType) and (AProc.ProcType.Args.Count > 0) then
     AddProcArgs(AProc.ProcType.Args) ;
   if Assigned(AProc.ProcType) and
@@ -912,8 +912,8 @@ begin
     Add('class ');
   Add(AProc.TypeName + ' ');
   if AProc.Parent.ClassType = TPasClassType then
-    Add(AProc.Parent.Name + '.');
-  Add(AProc.Name);
+    Add(AProc.Parent.SafeName + '.');
+  Add(AProc.SafeName);
   if Assigned(AProc.ProcType) and (AProc.ProcType.Args.Count > 0) then
     AddProcArgs(AProc.ProcType.Args);
   if Assigned(AProc.ProcType) and
@@ -997,7 +997,7 @@ var
 begin
   if AProp.IsClass then
     Add('class ');
-  Add('property ' + AProp.Name);
+  Add('property ' + AProp.SafeName);
   if AProp.Args.Count > 0 then
   begin
     Add('[');
@@ -1238,7 +1238,7 @@ end;
 
 procedure TPasWriter.WriteImplExceptOn(aOn: TPasImplExceptOn);
 begin
-  Addln('On %s : %s do',[aOn.VarEl.Name,aOn.TypeEl.Name]);
+  Addln('On %s : %s do',[aOn.VarEl.SafeName,aOn.TypeEl.SafeName]);
   if Assigned(aOn.Body) then
     WriteImplElement(aOn.Body,True);
 end;