Browse Source

fcl-passrc: resolver: allow overriding names of base types

git-svn-id: trunk@35868 -
Mattias Gaertner 8 years ago
parent
commit
74899a889a
2 changed files with 205 additions and 195 deletions
  1. 204 194
      packages/fcl-passrc/src/pasresolver.pp
  2. 1 1
      packages/fcl-passrc/tests/tcresolver.pas

+ 204 - 194
packages/fcl-passrc/src/pasresolver.pp

@@ -427,7 +427,7 @@ const
     ];
     ];
   btArrayRangeTypes = btAllChars+[btBoolean]+btAllInteger;
   btArrayRangeTypes = btAllChars+[btBoolean]+btAllInteger;
 
 
-  BaseTypeNames: array[TResolverBaseType] of shortstring =(
+  ResBaseTypeNames: array[TResolverBaseType] of string =(
     'None',
     'None',
     'Custom',
     'Custom',
     'Context',
     'Context',
@@ -505,7 +505,7 @@ type
     );
     );
   TResolverBuiltInProcs = set of TResolverBuiltInProc;
   TResolverBuiltInProcs = set of TResolverBuiltInProc;
 const
 const
-  ResolverBuiltInProcNames: array[TResolverBuiltInProc] of shortstring = (
+  ResolverBuiltInProcNames: array[TResolverBuiltInProc] of string = (
     'Custom',
     'Custom',
     'Length',
     'Length',
     'SetLength',
     'SetLength',
@@ -1002,7 +1002,8 @@ type
   private
   private
     type
     type
       TResolveDataListKind = (lkBuiltIn,lkModule);
       TResolveDataListKind = (lkBuiltIn,lkModule);
-    procedure ClearResolveDataList(Kind: TResolveDataListKind);
+    function GetBaseTypes(bt: TResolverBaseType): TPasUnresolvedSymbolRef; inline;
+    function GetScopes(Index: integer): TPasScope; inline;
   private
   private
     FAnonymousElTypePostfix: String;
     FAnonymousElTypePostfix: String;
     FBaseTypeChar: TResolverBaseType;
     FBaseTypeChar: TResolverBaseType;
@@ -1032,8 +1033,8 @@ type
     FSubScopeCount: integer;
     FSubScopeCount: integer;
     FSubScopes: array of TPasScope; // stack of scopes
     FSubScopes: array of TPasScope; // stack of scopes
     FTopScope: TPasScope;
     FTopScope: TPasScope;
-    function GetBaseTypes(bt: TResolverBaseType): TPasUnresolvedSymbolRef; inline;
-    function GetScopes(Index: integer): TPasScope; inline;
+    procedure ClearResolveDataList(Kind: TResolveDataListKind);
+    function GetBaseTypeNames(bt: TResolverBaseType): string;
   protected
   protected
     const
     const
       cIncompatible = High(integer);
       cIncompatible = High(integer);
@@ -1410,6 +1411,10 @@ type
     function ResolvedElCanBeVarParam(const ResolvedEl: TPasResolverResult): boolean;
     function ResolvedElCanBeVarParam(const ResolvedEl: TPasResolverResult): boolean;
     function ResolvedElIsClassInstance(const ResolvedEl: TPasResolverResult): boolean;
     function ResolvedElIsClassInstance(const ResolvedEl: TPasResolverResult): boolean;
     // uility functions
     // uility functions
+    property BaseTypeNames[bt: TResolverBaseType]: string read GetBaseTypeNames;
+    function GetProcTypeDescription(ProcType: TPasProcedureType; UseName: boolean = true; AddPaths: boolean = false): string;
+    function GetResolverResultDescription(const T: TPasResolverResult; OnlyType: boolean = false): string;
+    function GetTypeDescription(aType: TPasType; AddPath: boolean = false): string;
     function GetTypeDescription(const R: TPasResolverResult; AddPath: boolean = false): string; virtual;
     function GetTypeDescription(const R: TPasResolverResult; AddPath: boolean = false): string; virtual;
     function GetBaseDescription(const R: TPasResolverResult; AddPath: boolean = false): string; virtual;
     function GetBaseDescription(const R: TPasResolverResult; AddPath: boolean = false): string; virtual;
     function GetPasPropertyType(El: TPasProperty): TPasType;
     function GetPasPropertyType(El: TPasProperty): TPasType;
@@ -1475,10 +1480,7 @@ type
   end;
   end;
 
 
 function GetObjName(o: TObject): string;
 function GetObjName(o: TObject): string;
-function GetProcDesc(ProcType: TPasProcedureType; UseName: boolean = true; AddPaths: boolean = false): string;
-function GetTypeDesc(aType: TPasType; AddPath: boolean = false): string;
-function GetTreeDesc(El: TPasElement; Indent: integer = 0): string;
-function GetResolverResultDescription(const T: TPasResolverResult; OnlyType: boolean = false): string;
+function GetTreeDbg(El: TPasElement; Indent: integer = 0): string;
 function GetResolverResultDbg(const T: TPasResolverResult): string;
 function GetResolverResultDbg(const T: TPasResolverResult): string;
 function ResolverResultFlagsToStr(const Flags: TPasResolverResultFlags): string;
 function ResolverResultFlagsToStr(const Flags: TPasResolverResultFlags): string;
 
 
@@ -1511,85 +1513,7 @@ begin
     Result:=o.ClassName;
     Result:=o.ClassName;
 end;
 end;
 
 
-function GetProcDesc(ProcType: TPasProcedureType; UseName: boolean;
-  AddPaths: boolean): string;
-var
-  Args: TFPList;
-  i: Integer;
-  Arg: TPasArgument;
-begin
-  if ProcType=nil then exit('nil');
-  Result:=ProcType.TypeName;
-  if ProcType.IsReferenceTo then
-    Result:=ProcTypeModifiers[ptmReferenceTo]+' '+Result;
-  if UseName and (ProcType.Parent is TPasProcedure) then
-    begin
-    if AddPaths then
-      Result:=Result+' '+ProcType.Parent.FullName
-    else
-      Result:=Result+' '+ProcType.Parent.Name;
-    end;
-  Args:=ProcType.Args;
-  if Args.Count>0 then
-    begin
-    Result:=Result+'(';
-    for i:=0 to Args.Count-1 do
-      begin
-      if i>0 then Result:=Result+';';
-      Arg:=TPasArgument(Args[i]);
-      if AccessNames[Arg.Access]<>'' then
-        Result:=Result+AccessNames[Arg.Access];
-      if Arg.ArgType=nil then
-        Result:=Result+'untyped'
-      else
-        Result:=Result+GetTypeDesc(Arg.ArgType,AddPaths);
-      end;
-    Result:=Result+')';
-    end;
-  if ProcType.IsOfObject then
-    Result:=Result+' '+ProcTypeModifiers[ptmOfObject];
-  if ProcType.IsNested then
-    Result:=Result+' '+ProcTypeModifiers[ptmIsNested];
-  if cCallingConventions[ProcType.CallingConvention]<>'' then
-    Result:=Result+';'+cCallingConventions[ProcType.CallingConvention];
-end;
-
-function GetTypeDesc(aType: TPasType; AddPath: boolean): string;
-
-  function GetName: string;
-  var
-    s: String;
-  begin
-    Result:=aType.Name;
-    if Result='' then
-      Result:=aType.ElementTypeName;
-    if AddPath then
-      begin
-      s:=aType.FullPath;
-      if (s<>'') and (s<>'.') then
-        Result:=s+'.'+Result;
-      end;
-  end;
-
-var
-  C: TClass;
-begin
-  if aType=nil then exit('untyped');
-  C:=aType.ClassType;
-  if (C=TPasUnresolvedSymbolRef) then
-    begin
-    Result:=GetName;
-    if TPasUnresolvedSymbolRef(aType).CustomData is TResElDataBuiltInProc then
-      Result:=Result+'()';
-    exit;
-    end
-  else if (C=TPasUnresolvedTypeRef) then
-    Result:=GetName
-  else
-    Result:=GetName;
-end;
-
-function GetTreeDesc(El: TPasElement; Indent: integer): string;
+function GetTreeDbg(El: TPasElement; Indent: integer): string;
 
 
   procedure LineBreak(SubIndent: integer);
   procedure LineBreak(SubIndent: integer);
   begin
   begin
@@ -1607,11 +1531,11 @@ begin
     if El.ClassType<>TBinaryExpr then
     if El.ClassType<>TBinaryExpr then
       Result:=Result+OpcodeStrings[TPasExpr(El).OpCode];
       Result:=Result+OpcodeStrings[TPasExpr(El).OpCode];
     if El.ClassType=TUnaryExpr then
     if El.ClassType=TUnaryExpr then
-      Result:=Result+GetTreeDesc(TUnaryExpr(El).Operand,Indent)
+      Result:=Result+GetTreeDbg(TUnaryExpr(El).Operand,Indent)
     else if El.ClassType=TBinaryExpr then
     else if El.ClassType=TBinaryExpr then
-      Result:=Result+'Left={'+GetTreeDesc(TBinaryExpr(El).left,Indent)+'}'
+      Result:=Result+'Left={'+GetTreeDbg(TBinaryExpr(El).left,Indent)+'}'
          +OpcodeStrings[TPasExpr(El).OpCode]
          +OpcodeStrings[TPasExpr(El).OpCode]
-         +'Right={'+GetTreeDesc(TBinaryExpr(El).right,Indent)+'}'
+         +'Right={'+GetTreeDbg(TBinaryExpr(El).right,Indent)+'}'
     else if El.ClassType=TPrimitiveExpr then
     else if El.ClassType=TPrimitiveExpr then
       Result:=Result+TPrimitiveExpr(El).Value
       Result:=Result+TPrimitiveExpr(El).Value
     else if El.ClassType=TBoolConstExpr then
     else if El.ClassType=TBoolConstExpr then
@@ -1625,7 +1549,7 @@ begin
     else if El.ClassType=TParamsExpr then
     else if El.ClassType=TParamsExpr then
       begin
       begin
       LineBreak(2);
       LineBreak(2);
-      Result:=Result+GetTreeDesc(TParamsExpr(El).Value,Indent)+'(';
+      Result:=Result+GetTreeDbg(TParamsExpr(El).Value,Indent)+'(';
       l:=length(TParamsExpr(El).Params);
       l:=length(TParamsExpr(El).Params);
       if l>0 then
       if l>0 then
         begin
         begin
@@ -1633,7 +1557,7 @@ begin
         for i:=0 to l-1 do
         for i:=0 to l-1 do
           begin
           begin
           LineBreak(0);
           LineBreak(0);
-          Result:=Result+GetTreeDesc(TParamsExpr(El).Params[i],Indent);
+          Result:=Result+GetTreeDbg(TParamsExpr(El).Params[i],Indent);
           if i<l-1 then
           if i<l-1 then
             Result:=Result+','
             Result:=Result+','
           end;
           end;
@@ -1652,7 +1576,7 @@ begin
           begin
           begin
           LineBreak(0);
           LineBreak(0);
           Result:=Result+TRecordValues(El).Fields[i].Name+':'
           Result:=Result+TRecordValues(El).Fields[i].Name+':'
-            +GetTreeDesc(TRecordValues(El).Fields[i].ValueExp,Indent);
+            +GetTreeDbg(TRecordValues(El).Fields[i].ValueExp,Indent);
           if i<l-1 then
           if i<l-1 then
             Result:=Result+','
             Result:=Result+','
           end;
           end;
@@ -1670,7 +1594,7 @@ begin
         for i:=0 to l-1 do
         for i:=0 to l-1 do
           begin
           begin
           LineBreak(0);
           LineBreak(0);
-          Result:=Result+GetTreeDesc(TArrayValues(El).Values[i],Indent);
+          Result:=Result+GetTreeDbg(TArrayValues(El).Values[i],Indent);
           if i<l-1 then
           if i<l-1 then
             Result:=Result+','
             Result:=Result+','
           end;
           end;
@@ -1681,7 +1605,7 @@ begin
     end
     end
   else if El is TPasProcedure then
   else if El is TPasProcedure then
     begin
     begin
-    Result:=Result+GetTreeDesc(TPasProcedure(El).ProcType,Indent);
+    Result:=Result+GetTreeDbg(TPasProcedure(El).ProcType,Indent);
     end
     end
   else if El is TPasProcedureType then
   else if El is TPasProcedureType then
     begin
     begin
@@ -1695,7 +1619,7 @@ begin
       for i:=0 to l-1 do
       for i:=0 to l-1 do
         begin
         begin
         LineBreak(0);
         LineBreak(0);
-        Result:=Result+GetTreeDesc(TPasArgument(TPasProcedureType(El).Args[i]),Indent);
+        Result:=Result+GetTreeDbg(TPasArgument(TPasProcedureType(El).Args[i]),Indent);
         if i<l-1 then
         if i<l-1 then
           Result:=Result+';'
           Result:=Result+';'
         end;
         end;
@@ -1703,7 +1627,7 @@ begin
       end;
       end;
     Result:=Result+')';
     Result:=Result+')';
     if El is TPasFunction then
     if El is TPasFunction then
-      Result:=Result+':'+GetTreeDesc(TPasFunctionType(TPasFunction(El).ProcType).ResultEl,Indent);
+      Result:=Result+':'+GetTreeDbg(TPasFunctionType(TPasFunction(El).ProcType).ResultEl,Indent);
     if TPasProcedureType(El).IsOfObject then
     if TPasProcedureType(El).IsOfObject then
       Result:=Result+' '+ProcTypeModifiers[ptmOfObject];
       Result:=Result+' '+ProcTypeModifiers[ptmOfObject];
     if TPasProcedureType(El).IsNested then
     if TPasProcedureType(El).IsNested then
@@ -1712,7 +1636,7 @@ begin
       Result:=Result+'; '+cCallingConventions[TPasProcedureType(El).CallingConvention];
       Result:=Result+'; '+cCallingConventions[TPasProcedureType(El).CallingConvention];
     end
     end
   else if El.ClassType=TPasResultElement then
   else if El.ClassType=TPasResultElement then
-    Result:=Result+GetTreeDesc(TPasResultElement(El).ResultType,Indent)
+    Result:=Result+GetTreeDbg(TPasResultElement(El).ResultType,Indent)
   else if El.ClassType=TPasArgument then
   else if El.ClassType=TPasArgument then
     begin
     begin
     if AccessNames[TPasArgument(El).Access]<>'' then
     if AccessNames[TPasArgument(El).Access]<>'' then
@@ -1720,7 +1644,7 @@ begin
     if TPasArgument(El).ArgType=nil then
     if TPasArgument(El).ArgType=nil then
       Result:=Result+'untyped'
       Result:=Result+'untyped'
     else
     else
-      Result:=Result+GetTreeDesc(TPasArgument(El).ArgType,Indent);
+      Result:=Result+GetTreeDbg(TPasArgument(El).ArgType,Indent);
     end
     end
   else if El.ClassType=TPasUnresolvedSymbolRef then
   else if El.ClassType=TPasUnresolvedSymbolRef then
     begin
     begin
@@ -1729,64 +1653,11 @@ begin
     end;
     end;
 end;
 end;
 
 
-function GetResolverResultDescription(const T: TPasResolverResult;
-  OnlyType: boolean): string;
-
-  function GetSubTypeName: string;
-  begin
-    if (T.TypeEl<>nil) and (T.TypeEl.Name<>'') then
-      Result:=T.TypeEl.Name
-    else
-      Result:=BaseTypeNames[T.SubType];
-  end;
-
-var
-  ArrayEl: TPasArrayType;
-begin
-  case T.BaseType of
-  btModule: exit(T.IdentEl.ElementTypeName+' '+T.IdentEl.Name);
-  btNil: exit('nil');
-  btRange:
-    Result:='range of '+GetSubTypeName;
-  btSet:
-    Result:='set/array literal of '+GetSubTypeName;
-  btContext:
-    begin
-    if T.TypeEl.ClassType=TPasClassOfType then
-      Result:='class of '+TPasClassOfType(T.TypeEl).DestType.Name
-    else if T.TypeEl.ClassType=TPasAliasType then
-      Result:=TPasAliasType(T.TypeEl).DestType.Name
-    else if T.TypeEl.ClassType=TPasTypeAliasType then
-      Result:='type '+TPasAliasType(T.TypeEl).DestType.Name
-    else if T.TypeEl.ClassType=TPasArrayType then
-      begin
-      ArrayEl:=TPasArrayType(T.TypeEl);
-      if length(ArrayEl.Ranges)=0 then
-        Result:='array of '+ArrayEl.ElType.Name
-      else
-        Result:='static array[] of '+ArrayEl.ElType.Name;
-      end
-    else if T.TypeEl is TPasProcedureType then
-      Result:=GetProcDesc(TPasProcedureType(T.TypeEl),false)
-    else if T.TypeEl.Name<>'' then
-      Result:=T.TypeEl.Name
-    else
-      Result:=T.TypeEl.ElementTypeName;
-    end;
-  btCustom:
-    Result:=T.TypeEl.Name;
-  else
-    Result:=BaseTypeNames[T.BaseType];
-  end;
-  if (not OnlyType) and (T.TypeEl<>T.IdentEl) and (T.IdentEl<>nil) then
-    Result:=T.IdentEl.Name+':'+Result;
-end;
-
 function GetResolverResultDbg(const T: TPasResolverResult): string;
 function GetResolverResultDbg(const T: TPasResolverResult): string;
 begin
 begin
-  Result:='[bt='+BaseTypeNames[T.BaseType];
+  Result:='[bt='+ResBaseTypeNames[T.BaseType];
   if T.SubType<>btNone then
   if T.SubType<>btNone then
-    Result:=Result+' Sub='+BaseTypeNames[T.SubType];
+    Result:=Result+' Sub='+ResBaseTypeNames[T.SubType];
   Result:=Result
   Result:=Result
          +' Ident='+GetObjName(T.IdentEl)
          +' Ident='+GetObjName(T.IdentEl)
          +' Type='+GetObjName(T.TypeEl)
          +' Type='+GetObjName(T.TypeEl)
@@ -1985,7 +1856,7 @@ end;
 
 
 procedure TPasWithExprScope.WriteIdentifiers(Prefix: string);
 procedure TPasWithExprScope.WriteIdentifiers(Prefix: string);
 begin
 begin
-  writeln(Prefix+'WithExpr: '+GetTreeDesc(Expr,length(Prefix)));
+  writeln(Prefix+'WithExpr: '+GetTreeDbg(Expr,length(Prefix)));
   Scope.WriteIdentifiers(Prefix);
   Scope.WriteIdentifiers(Prefix);
 end;
 end;
 
 
@@ -2448,7 +2319,7 @@ procedure TPasIdentifierScope.InternalAdd(Item: TPasIdentifier);
 var
 var
   Index: Integer;
   Index: Integer;
   OldItem: TPasIdentifier;
   OldItem: TPasIdentifier;
-  LoName: ShortString;
+  LoName: string;
 begin
 begin
   LoName:=lowercase(Item.Identifier);
   LoName:=lowercase(Item.Identifier);
   Index:=FItems.FindIndexOf(LoName);
   Index:=FItems.FindIndexOf(LoName);
@@ -2514,7 +2385,7 @@ end;
 function TPasIdentifierScope.RemoveLocalIdentifier(El: TPasElement): boolean;
 function TPasIdentifierScope.RemoveLocalIdentifier(El: TPasElement): boolean;
 var
 var
   Identifier, PrevIdentifier: TPasIdentifier;
   Identifier, PrevIdentifier: TPasIdentifier;
-  LoName: ShortString;
+  LoName: string;
 begin
 begin
   LoName:=lowercase(El.Name);
   LoName:=lowercase(El.Name);
   Identifier:=TPasIdentifier(FItems.Find(LoName));
   Identifier:=TPasIdentifier(FItems.Find(LoName));
@@ -2640,8 +2511,8 @@ end;
 // inline
 // inline
 function TPasResolver.IsNameExpr(El: TPasExpr): boolean;
 function TPasResolver.IsNameExpr(El: TPasExpr): boolean;
 begin
 begin
-  if El.ClassType=TSelfExpr then exit(true);
-  Result:=(El.ClassType=TPrimitiveExpr) and (TPrimitiveExpr(El).Kind=pekIdent);
+  Result:=(El.ClassType=TSelfExpr)
+      or ((El.ClassType=TPrimitiveExpr) and (TPrimitiveExpr(El).Kind=pekIdent));
 end;
 end;
 
 
 procedure TPasResolver.ClearResolveDataList(Kind: TResolveDataListKind);
 procedure TPasResolver.ClearResolveDataList(Kind: TResolveDataListKind);
@@ -2660,6 +2531,14 @@ begin
     end;
     end;
 end;
 end;
 
 
+function TPasResolver.GetBaseTypeNames(bt: TResolverBaseType): string;
+begin
+  if FBaseTypes[bt]<>nil then
+    Result:=FBaseTypes[bt].Name
+  else
+    Result:=ResBaseTypeNames[bt];
+end;
+
 procedure TPasResolver.OnFindFirstElement(El: TPasElement; ElScope,
 procedure TPasResolver.OnFindFirstElement(El: TPasElement; ElScope,
   StartScope: TPasScope; FindFirstElementData: Pointer; var Abort: boolean);
   StartScope: TPasScope; FindFirstElementData: Pointer; var Abort: boolean);
 var
 var
@@ -2746,7 +2625,7 @@ begin
     {$IFDEF VerbosePasResolver}
     {$IFDEF VerbosePasResolver}
     writeln('TPasResolver.OnFindCallElements Proc Distance=',Distance,
     writeln('TPasResolver.OnFindCallElements Proc Distance=',Distance,
       ' Data^.Found=',Data^.Found<>nil,' Data^.Distance=',ord(Data^.Distance),
       ' Data^.Found=',Data^.Found<>nil,' Data^.Distance=',ord(Data^.Distance),
-      ' Signature={',GetProcDesc(Proc.ProcType,true,true),'}');
+      ' Signature={',GetProcTypeDescription(Proc.ProcType,true,true),'}');
     {$ENDIF}
     {$ENDIF}
     CandidateFound:=true;
     CandidateFound:=true;
     end
     end
@@ -2884,10 +2763,10 @@ begin
       if (Data^.List.IndexOf(El)>=0) then
       if (Data^.List.IndexOf(El)>=0) then
         begin
         begin
         {$IFDEF VerbosePasResolver}
         {$IFDEF VerbosePasResolver}
-        writeln('TPasResolver.OnFindCallElements Found El twice: ',GetTreeDesc(El),
+        writeln('TPasResolver.OnFindCallElements Found El twice: ',GetTreeDbg(El),
           ' ',GetElementSourcePosStr(El),
           ' ',GetElementSourcePosStr(El),
-          ' PrevElScope=',GetObjName(Data^.ElScope),' ',GetTreeDesc(Data^.ElScope.Element),
-          ' ElScope=',GetObjName(ElScope),' ',GetTreeDesc(ElScope.Element)
+          ' PrevElScope=',GetObjName(Data^.ElScope),' ',GetTreeDbg(Data^.ElScope.Element),
+          ' ElScope=',GetObjName(ElScope),' ',GetTreeDbg(ElScope.Element)
           );
           );
         {$ENDIF}
         {$ENDIF}
         RaiseInternalError(20160924230805);
         RaiseInternalError(20160924230805);
@@ -2959,7 +2838,7 @@ begin
     end;
     end;
 
 
   {$IFDEF VerbosePasResolver}
   {$IFDEF VerbosePasResolver}
-  writeln('TPasResolver.OnFindOverloadProc ',GetTreeDesc(El,2));
+  writeln('TPasResolver.OnFindOverloadProc ',GetTreeDbg(El,2));
   {$ENDIF}
   {$ENDIF}
   Proc:=TPasProcedure(El);
   Proc:=TPasProcedure(El);
   if CheckOverloadProcCompatibility(Data^.Proc,Proc) then
   if CheckOverloadProcCompatibility(Data^.Proc,Proc) then
@@ -3439,7 +3318,7 @@ begin
     CheckTopScope(TPasProcedureScope);
     CheckTopScope(TPasProcedureScope);
     Proc:=TPasProcedure(El.Parent);
     Proc:=TPasProcedure(El.Parent);
     {$IFDEF VerbosePasResolver}
     {$IFDEF VerbosePasResolver}
-    writeln('TPasResolver.FinishProcedureHeader El=',GetTreeDesc(El),' ',GetElementSourcePosStr(El),' IsForward=',Proc.IsForward,' Parent=',GetObjName(El.Parent));
+    writeln('TPasResolver.FinishProcedureHeader El=',GetTreeDbg(El),' ',GetElementSourcePosStr(El),' IsForward=',Proc.IsForward,' Parent=',GetObjName(El.Parent));
     {$ENDIF}
     {$ENDIF}
     ProcName:=Proc.Name;
     ProcName:=Proc.Name;
 
 
@@ -3563,7 +3442,7 @@ begin
     // overload found with same signature
     // overload found with same signature
     DeclProc:=FindData.Found;
     DeclProc:=FindData.Found;
     {$IFDEF VerbosePasResolver}
     {$IFDEF VerbosePasResolver}
-    writeln('TPasResolver.FinishProcedureHeader overload found: Proc2=',GetTreeDesc(DeclProc),' ',GetElementSourcePosStr(DeclProc),' IsForward=',DeclProc.IsForward,' Parent=',GetObjName(DeclProc.Parent));
+    writeln('TPasResolver.FinishProcedureHeader overload found: Proc2=',GetTreeDbg(DeclProc),' ',GetElementSourcePosStr(DeclProc),' IsForward=',DeclProc.IsForward,' Parent=',GetObjName(DeclProc.Parent));
     {$ENDIF}
     {$ENDIF}
     if (Proc.Parent=DeclProc.Parent)
     if (Proc.Parent=DeclProc.Parent)
         or ((Proc.Parent is TImplementationSection)
         or ((Proc.Parent is TImplementationSection)
@@ -3637,7 +3516,7 @@ begin
     // no overload
     // no overload
     if Proc.IsOverride then
     if Proc.IsOverride then
       RaiseMsg(20170216151702,nNoMethodInAncestorToOverride,
       RaiseMsg(20170216151702,nNoMethodInAncestorToOverride,
-        sNoMethodInAncestorToOverride,[GetProcDesc(Proc.ProcType)],Proc.ProcType);
+        sNoMethodInAncestorToOverride,[GetProcTypeDescription(Proc.ProcType)],Proc.ProcType);
     end
     end
   else
   else
     begin
     begin
@@ -3653,7 +3532,7 @@ begin
       if (not OverloadProc.IsVirtual) and (not OverloadProc.IsOverride) then
       if (not OverloadProc.IsVirtual) and (not OverloadProc.IsOverride) then
         // the OverloadProc fits the signature, but is not virtual
         // the OverloadProc fits the signature, but is not virtual
         RaiseMsg(20170216151708,nNoMethodInAncestorToOverride,
         RaiseMsg(20170216151708,nNoMethodInAncestorToOverride,
-          sNoMethodInAncestorToOverride,[GetProcDesc(Proc.ProcType)],Proc.ProcType);
+          sNoMethodInAncestorToOverride,[GetProcTypeDescription(Proc.ProcType)],Proc.ProcType);
       // override a virtual method
       // override a virtual method
       CheckProcSignatureMatch(OverloadProc,Proc);
       CheckProcSignatureMatch(OverloadProc,Proc);
       // check visibility
       // check visibility
@@ -4034,8 +3913,8 @@ begin
       // check function result type
       // check function result type
       ResultType:=TPasFunction(Proc).FuncType.ResultEl.ResultType;
       ResultType:=TPasFunction(Proc).FuncType.ResultEl.ResultType;
       if not IsSameType(ResultType,PropType) then
       if not IsSameType(ResultType,PropType) then
-        RaiseXExpectedButYFound(20170216151844,'function result '+GetTypeDesc(PropType,true),
-          GetTypeDesc(ResultType,true),PropEl.ReadAccessor);
+        RaiseXExpectedButYFound(20170216151844,'function result '+GetTypeDescription(PropType,true),
+          GetTypeDescription(ResultType,true),PropEl.ReadAccessor);
       // check args
       // check args
       CheckArgs(Proc,PropEl.ReadAccessor);
       CheckArgs(Proc,PropEl.ReadAccessor);
       if Proc.ProcType.Args.Count<>PropEl.Args.Count then
       if Proc.ProcType.Args.Count<>PropEl.Args.Count then
@@ -4133,7 +4012,7 @@ begin
       ResultType:=TPasFunction(Proc).FuncType.ResultEl.ResultType;
       ResultType:=TPasFunction(Proc).FuncType.ResultEl.ResultType;
       if not IsBaseType(ResultType,btBoolean) then
       if not IsBaseType(ResultType,btBoolean) then
         RaiseXExpectedButYFound(20170216151929,'function: boolean',
         RaiseXExpectedButYFound(20170216151929,'function: boolean',
-          'function:'+GetTypeDesc(ResultType),PropEl.StoredAccessor);
+          'function:'+GetTypeDescription(ResultType),PropEl.StoredAccessor);
       // check arg count
       // check arg count
       if Proc.ProcType.Args.Count<>0 then
       if Proc.ProcType.Args.Count<>0 then
         RaiseMsg(20170216151932,nWrongNumberOfParametersForCallTo,sWrongNumberOfParametersForCallTo,
         RaiseMsg(20170216151932,nWrongNumberOfParametersForCallTo,sWrongNumberOfParametersForCallTo,
@@ -4220,7 +4099,7 @@ begin
       end;
       end;
     end
     end
   else if AncestorType.ClassType<>TPasClassType then
   else if AncestorType.ClassType<>TPasClassType then
-    RaiseXExpectedButYFound(20170216151944,'class type',GetTypeDesc(AncestorType),aClass)
+    RaiseXExpectedButYFound(20170216151944,'class type',GetTypeDescription(AncestorType),aClass)
   else
   else
     begin
     begin
     AncestorEl:=TPasClassType(AncestorType);
     AncestorEl:=TPasClassType(AncestorType);
@@ -4501,7 +4380,7 @@ begin
     end;
     end;
   if not ok then
   if not ok then
     RaiseXExpectedButYFound(20170216151952,'ordinal expression',
     RaiseXExpectedButYFound(20170216151952,'ordinal expression',
-               GetTypeDesc(CaseExprResolved.TypeEl),CaseOf.CaseExpr);
+               GetTypeDescription(CaseExprResolved.TypeEl),CaseOf.CaseExpr);
 
 
   for i:=0 to CaseOf.Elements.Count-1 do
   for i:=0 to CaseOf.Elements.Count-1 do
     begin
     begin
@@ -4885,7 +4764,7 @@ var
   DeclProc, AncestorProc: TPasProcedure;
   DeclProc, AncestorProc: TPasProcedure;
 begin
 begin
   {$IFDEF VerbosePasResolver}
   {$IFDEF VerbosePasResolver}
-  writeln('TPasResolver.ResolveInherited El.Parent=',GetTreeDesc(El.Parent));
+  writeln('TPasResolver.ResolveInherited El.Parent=',GetTreeDbg(El.Parent));
   {$ENDIF}
   {$ENDIF}
   if (El.Parent.ClassType=TBinaryExpr)
   if (El.Parent.ClassType=TBinaryExpr)
   and (TBinaryExpr(El.Parent).OpCode=eopNone) then
   and (TBinaryExpr(El.Parent).OpCode=eopNone) then
@@ -4940,7 +4819,7 @@ var
   InhScope: TPasDotClassScope;
   InhScope: TPasDotClassScope;
 begin
 begin
   {$IFDEF VerbosePasResolver}
   {$IFDEF VerbosePasResolver}
-  writeln('TPasResolver.ResolveInheritedCall El=',GetTreeDesc(El));
+  writeln('TPasResolver.ResolveInheritedCall El=',GetTreeDbg(El));
   {$ENDIF}
   {$ENDIF}
 
 
   CheckTopScope(TPasProcedureScope);
   CheckTopScope(TPasProcedureScope);
@@ -5249,12 +5128,12 @@ begin
           begin
           begin
           El:=TPasElement(FindCallData.List[i]);
           El:=TPasElement(FindCallData.List[i]);
           {$IFDEF VerbosePasResolver}
           {$IFDEF VerbosePasResolver}
-          writeln('TPasResolver.ResolveFuncParamsExpr Overload Candidate: ',GetElementSourcePosStr(El),' ',GetTreeDesc(El));
+          writeln('TPasResolver.ResolveFuncParamsExpr Overload Candidate: ',GetElementSourcePosStr(El),' ',GetTreeDbg(El));
           {$ENDIF}
           {$ENDIF}
           // emit a hint for each candidate
           // emit a hint for each candidate
           if El is TPasProcedure then
           if El is TPasProcedure then
             LogMsg(20170417180320,mtHint,nFoundCallCandidateX,sFoundCallCandidateX,
             LogMsg(20170417180320,mtHint,nFoundCallCandidateX,sFoundCallCandidateX,
-              [GetProcDesc(TPasProcedure(El).ProcType,true,true)],El);
+              [GetProcTypeDescription(TPasProcedure(El).ProcType,true,true)],El);
           Msg:=Msg+', '+GetElementSourcePosStr(El);
           Msg:=Msg+', '+GetElementSourcePosStr(El);
           end;
           end;
         RaiseMsg(20170216152200,nCantDetermineWhichOverloadedFunctionToCall,
         RaiseMsg(20170216152200,nCantDetermineWhichOverloadedFunctionToCall,
@@ -5508,7 +5387,7 @@ procedure TPasResolver.ResolveSetParamsExpr(Params: TParamsExpr);
 // e.g. resolving '[1,2..3]'
 // e.g. resolving '[1,2..3]'
 begin
 begin
   {$IFDEF VerbosePasResolver}
   {$IFDEF VerbosePasResolver}
-  writeln('TPasResolver.ResolveSetParamsExpr ',GetTreeDesc(Params));
+  writeln('TPasResolver.ResolveSetParamsExpr ',GetTreeDbg(Params));
   {$ENDIF}
   {$ENDIF}
   if Params.Value<>nil then
   if Params.Value<>nil then
     RaiseNotYetImplemented(20160930135910,Params);
     RaiseNotYetImplemented(20160930135910,Params);
@@ -8324,7 +8203,7 @@ begin
   then
   then
     // proc needs parameters
     // proc needs parameters
     RaiseMsg(20170216152347,nWrongNumberOfParametersForCallTo,
     RaiseMsg(20170216152347,nWrongNumberOfParametersForCallTo,
-      sWrongNumberOfParametersForCallTo,[GetProcDesc(TPasProcedure(Result).ProcType)],ErrorPosEl);
+      sWrongNumberOfParametersForCallTo,[GetProcTypeDescription(TPasProcedure(Result).ProcType)],ErrorPosEl);
 end;
 end;
 
 
 procedure TPasResolver.IterateElements(const aName: string;
 procedure TPasResolver.IterateElements(const aName: string;
@@ -9170,12 +9049,12 @@ procedure TPasResolver.RaiseIncompatibleType(id: int64; MsgNumber: integer;
 var
 var
   DescA, DescB: String;
   DescA, DescB: String;
 begin
 begin
-  DescA:=GetTypeDesc(GotType);
-  DescB:=GetTypeDesc(ExpType);
+  DescA:=GetTypeDescription(GotType);
+  DescB:=GetTypeDescription(ExpType);
   if DescA=DescB then
   if DescA=DescB then
     begin
     begin
-    DescA:=GetTypeDesc(GotType,true);
-    DescB:=GetTypeDesc(ExpType,true);
+    DescA:=GetTypeDescription(GotType,true);
+    DescB:=GetTypeDescription(ExpType,true);
     end;
     end;
   RaiseIncompatibleTypeDesc(id,MsgNumber,Args,DescA,DescB,ErrorEl);
   RaiseIncompatibleTypeDesc(id,MsgNumber,Args,DescA,DescB,ErrorEl);
 end;
 end;
@@ -9297,7 +9176,7 @@ begin
         // too many arguments
         // too many arguments
         if RaiseOnError then
         if RaiseOnError then
           RaiseMsg(20170216152408,nWrongNumberOfParametersForCallTo,
           RaiseMsg(20170216152408,nWrongNumberOfParametersForCallTo,
-            sWrongNumberOfParametersForCallTo,[GetProcDesc(ProcType)],Param);
+            sWrongNumberOfParametersForCallTo,[GetProcTypeDescription(ProcType)],Param);
         exit(cIncompatible);
         exit(cIncompatible);
         end;
         end;
       end;
       end;
@@ -9311,7 +9190,7 @@ begin
       if RaiseOnError then
       if RaiseOnError then
         // ToDo: position cursor on identifier
         // ToDo: position cursor on identifier
         RaiseMsg(20170216152410,nWrongNumberOfParametersForCallTo,
         RaiseMsg(20170216152410,nWrongNumberOfParametersForCallTo,
-          sWrongNumberOfParametersForCallTo,[GetProcDesc(ProcType)],Params.Value);
+          sWrongNumberOfParametersForCallTo,[GetProcTypeDescription(ProcType)],Params.Value);
       exit(cIncompatible);
       exit(cIncompatible);
       end
       end
     else
     else
@@ -10161,10 +10040,141 @@ begin
     exit(true);
     exit(true);
 end;
 end;
 
 
+function TPasResolver.GetProcTypeDescription(ProcType: TPasProcedureType;
+  UseName: boolean; AddPaths: boolean): string;
+var
+  Args: TFPList;
+  i: Integer;
+  Arg: TPasArgument;
+begin
+  if ProcType=nil then exit('nil');
+  Result:=ProcType.TypeName;
+  if ProcType.IsReferenceTo then
+    Result:=ProcTypeModifiers[ptmReferenceTo]+' '+Result;
+  if UseName and (ProcType.Parent is TPasProcedure) then
+    begin
+    if AddPaths then
+      Result:=Result+' '+ProcType.Parent.FullName
+    else
+      Result:=Result+' '+ProcType.Parent.Name;
+    end;
+  Args:=ProcType.Args;
+  if Args.Count>0 then
+    begin
+    Result:=Result+'(';
+    for i:=0 to Args.Count-1 do
+      begin
+      if i>0 then Result:=Result+';';
+      Arg:=TPasArgument(Args[i]);
+      if AccessNames[Arg.Access]<>'' then
+        Result:=Result+AccessNames[Arg.Access];
+      if Arg.ArgType=nil then
+        Result:=Result+'untyped'
+      else
+        Result:=Result+GetTypeDescription(Arg.ArgType,AddPaths);
+      end;
+    Result:=Result+')';
+    end;
+  if ProcType.IsOfObject then
+    Result:=Result+' '+ProcTypeModifiers[ptmOfObject];
+  if ProcType.IsNested then
+    Result:=Result+' '+ProcTypeModifiers[ptmIsNested];
+  if cCallingConventions[ProcType.CallingConvention]<>'' then
+    Result:=Result+';'+cCallingConventions[ProcType.CallingConvention];
+end;
+
+function TPasResolver.GetResolverResultDescription(const T: TPasResolverResult;
+  OnlyType: boolean): string;
+
+  function GetSubTypeName: string;
+  begin
+    if (T.TypeEl<>nil) and (T.TypeEl.Name<>'') then
+      Result:=T.TypeEl.Name
+    else
+      Result:=BaseTypeNames[T.SubType];
+  end;
+
+var
+  ArrayEl: TPasArrayType;
+begin
+  case T.BaseType of
+  btModule: exit(T.IdentEl.ElementTypeName+' '+T.IdentEl.Name);
+  btNil: exit('nil');
+  btRange:
+    Result:='range of '+GetSubTypeName;
+  btSet:
+    Result:='set/array literal of '+GetSubTypeName;
+  btContext:
+    begin
+    if T.TypeEl.ClassType=TPasClassOfType then
+      Result:='class of '+TPasClassOfType(T.TypeEl).DestType.Name
+    else if T.TypeEl.ClassType=TPasAliasType then
+      Result:=TPasAliasType(T.TypeEl).DestType.Name
+    else if T.TypeEl.ClassType=TPasTypeAliasType then
+      Result:='type '+TPasAliasType(T.TypeEl).DestType.Name
+    else if T.TypeEl.ClassType=TPasArrayType then
+      begin
+      ArrayEl:=TPasArrayType(T.TypeEl);
+      if length(ArrayEl.Ranges)=0 then
+        Result:='array of '+ArrayEl.ElType.Name
+      else
+        Result:='static array[] of '+ArrayEl.ElType.Name;
+      end
+    else if T.TypeEl is TPasProcedureType then
+      Result:=GetProcTypeDescription(TPasProcedureType(T.TypeEl),false)
+    else if T.TypeEl.Name<>'' then
+      Result:=T.TypeEl.Name
+    else
+      Result:=T.TypeEl.ElementTypeName;
+    end;
+  btCustom:
+    Result:=T.TypeEl.Name;
+  else
+    Result:=BaseTypeNames[T.BaseType];
+  end;
+  if (not OnlyType) and (T.TypeEl<>T.IdentEl) and (T.IdentEl<>nil) then
+    Result:=T.IdentEl.Name+':'+Result;
+end;
+
+function TPasResolver.GetTypeDescription(aType: TPasType; AddPath: boolean): string;
+
+  function GetName: string;
+  var
+    s: String;
+  begin
+    Result:=aType.Name;
+    if Result='' then
+      Result:=aType.ElementTypeName;
+    if AddPath then
+      begin
+      s:=aType.FullPath;
+      if (s<>'') and (s<>'.') then
+        Result:=s+'.'+Result;
+      end;
+  end;
+
+var
+  C: TClass;
+begin
+  if aType=nil then exit('untyped');
+  C:=aType.ClassType;
+  if (C=TPasUnresolvedSymbolRef) then
+    begin
+    Result:=GetName;
+    if TPasUnresolvedSymbolRef(aType).CustomData is TResElDataBuiltInProc then
+      Result:=Result+'()';
+    exit;
+    end
+  else if (C=TPasUnresolvedTypeRef) then
+    Result:=GetName
+  else
+    Result:=GetName;
+end;
+
 function TPasResolver.GetTypeDescription(const R: TPasResolverResult;
 function TPasResolver.GetTypeDescription(const R: TPasResolverResult;
   AddPath: boolean): string;
   AddPath: boolean): string;
 begin
 begin
-  Result:=GetTypeDesc(R.TypeEl,AddPath);
+  Result:=GetTypeDescription(R.TypeEl,AddPath);
   if R.IdentEl=R.TypeEl then
   if R.IdentEl=R.TypeEl then
     begin
     begin
     if R.TypeEl.ElementTypeName<>'' then
     if R.TypeEl.ElementTypeName<>'' then
@@ -10269,10 +10279,10 @@ begin
 
 
   ComputeElement(Param,ParamResolved,[]);
   ComputeElement(Param,ParamResolved,[]);
   {$IFDEF VerbosePasResolver}
   {$IFDEF VerbosePasResolver}
-  writeln('TPasResolver.CheckParamCompatibility Param=',GetTreeDesc(Param,2),' ParamResolved=',GetResolverResultDbg(ParamResolved));
+  writeln('TPasResolver.CheckParamCompatibility Param=',GetTreeDbg(Param,2),' ParamResolved=',GetResolverResultDbg(ParamResolved));
   {$ENDIF}
   {$ENDIF}
   if (ParamResolved.TypeEl=nil) and (Param.ArgType<>nil) then
   if (ParamResolved.TypeEl=nil) and (Param.ArgType<>nil) then
-    RaiseInternalError(20160922163628,'GetResolvedType returned TypeEl=nil for '+GetTreeDesc(Param));
+    RaiseInternalError(20160922163628,'GetResolvedType returned TypeEl=nil for '+GetTreeDbg(Param));
   RHSFlags:=[];
   RHSFlags:=[];
   if NeedVar then
   if NeedVar then
     Include(RHSFlags,rcNoImplicitProc)
     Include(RHSFlags,rcNoImplicitProc)
@@ -10301,7 +10311,7 @@ begin
   ComputeElement(Expr,ExprResolved,RHSFlags);
   ComputeElement(Expr,ExprResolved,RHSFlags);
 
 
   {$IFDEF VerbosePasResolver}
   {$IFDEF VerbosePasResolver}
-  writeln('TPasResolver.CheckParamCompatibility Expr=',GetTreeDesc(Expr,2),' ResolvedExpr=',GetResolverResultDbg(ExprResolved),' RHSFlags=',dbgs(RHSFlags));
+  writeln('TPasResolver.CheckParamCompatibility Expr=',GetTreeDbg(Expr,2),' ResolvedExpr=',GetResolverResultDbg(ExprResolved),' RHSFlags=',dbgs(RHSFlags));
   {$ENDIF}
   {$ENDIF}
 
 
   if NeedVar then
   if NeedVar then
@@ -11088,7 +11098,7 @@ var
   StartFromType, StartToType: TPasArrayType;
   StartFromType, StartToType: TPasArrayType;
 begin
 begin
   {$IFDEF VerbosePasResolver}
   {$IFDEF VerbosePasResolver}
-  writeln('TPasResolver.CheckTypeCastArray From=',GetTypeDesc(FromType),' ToType=',GetTypeDesc(ToType));
+  writeln('TPasResolver.CheckTypeCastArray From=',GetTypeDescription(FromType),' ToType=',GetTypeDescription(ToType));
   {$ENDIF}
   {$ENDIF}
   StartFromType:=FromType;
   StartFromType:=FromType;
   StartToType:=ToType;
   StartToType:=ToType;
@@ -11098,7 +11108,7 @@ begin
   ToIndex:=0;
   ToIndex:=0;
   repeat
   repeat
     {$IFDEF VerbosePasResolver}
     {$IFDEF VerbosePasResolver}
-    writeln('TPasResolver.CheckTypeCastArray From=',GetTypeDesc(FromType),' FromIndex=',FromIndex,' ToType=',GetTypeDesc(ToType),' ToIndex=',ToIndex);
+    writeln('TPasResolver.CheckTypeCastArray From=',GetTypeDescription(FromType),' FromIndex=',FromIndex,' ToType=',GetTypeDescription(ToType),' ToIndex=',ToIndex);
     {$ENDIF}
     {$ENDIF}
     if length(ToType.Ranges)=0 then
     if length(ToType.Ranges)=0 then
       // ToType is dynamic/open array -> fits any size
       // ToType is dynamic/open array -> fits any size
@@ -11114,7 +11124,7 @@ begin
       if NextDim(ToType,ToIndex,ToElTypeRes) then
       if NextDim(ToType,ToIndex,ToElTypeRes) then
         begin
         begin
         {$IFDEF VerbosePasResolver}
         {$IFDEF VerbosePasResolver}
-        writeln('TPasResolver.CheckTypeCastArray To has more dims than From: From=',GetTypeDesc(FromType),' FromIndex=',FromIndex,', ToType=',GetTypeDesc(ToType),' ToIndex=',ToIndex);
+        writeln('TPasResolver.CheckTypeCastArray To has more dims than From: From=',GetTypeDescription(FromType),' FromIndex=',FromIndex,', ToType=',GetTypeDescription(ToType),' ToIndex=',ToIndex);
         {$ENDIF}
         {$ENDIF}
         break; // ToType has more dimensions
         break; // ToType has more dimensions
         end;
         end;
@@ -11132,7 +11142,7 @@ begin
       if not NextDim(ToType,ToIndex,ToElTypeRes) then
       if not NextDim(ToType,ToIndex,ToElTypeRes) then
         begin
         begin
         {$IFDEF VerbosePasResolver}
         {$IFDEF VerbosePasResolver}
-        writeln('TPasResolver.CheckTypeCastArray From has more dims than To: From=',GetTypeDesc(FromType),' FromIndex=',FromIndex,', ToType=',GetTypeDesc(ToType),' ToIndex=',ToIndex);
+        writeln('TPasResolver.CheckTypeCastArray From has more dims than To: From=',GetTypeDescription(FromType),' FromIndex=',FromIndex,', ToType=',GetTypeDescription(ToType),' ToIndex=',ToIndex);
         {$ENDIF}
         {$ENDIF}
         break; // ToType has less dimensions
         break; // ToType has less dimensions
         end;
         end;

+ 1 - 1
packages/fcl-passrc/tests/tcresolver.pas

@@ -1634,7 +1634,7 @@ var
   var
   var
     s: String;
     s: String;
   begin
   begin
-    s:='TTestResolver.OnCheckElementParent El='+GetTreeDesc(El)+' '+
+    s:='TTestResolver.OnCheckElementParent El='+GetTreeDbg(El)+' '+
       ResolverEngine.GetElementSourcePosStr(El)+' '+Msg;
       ResolverEngine.GetElementSourcePosStr(El)+' '+Msg;
     writeln('ERROR: ',s);
     writeln('ERROR: ',s);
     Fail(s);
     Fail(s);