瀏覽代碼

Fix basically a regression since the reworking of Delphi compatible generics. The typenames of specialization now (again) contains the type names of the parameters. Additionally they are nicely formatted (TypeName<UnitName1.TypeName1[,...]>. If the full string should be longer than 255 characters an ellipsis will be added accordingly instead of the remaining parameters.

symdef.pas, tabstractrecorddef:
  + new private field rttistring to hold the string generated by RttiName
  * instead of generating the RTTI name each time on the fly it is generated only once and additionally contains (symbollically) the amount of type parameters for generics and all type parameters for specializations including their units

git-svn-id: trunk@29275 -
svenbarth 10 年之前
父節點
當前提交
77df68b2d9
共有 1 個文件被更改,包括 100 次插入1 次删除
  1. 100 1
      compiler/symdef.pas

+ 100 - 1
compiler/symdef.pas

@@ -243,6 +243,9 @@ interface
        tprocdef = class;
        tprocdef = class;
 
 
        tabstractrecorddef= class(tstoreddef)
        tabstractrecorddef= class(tstoreddef)
+       private
+          rttistring     : string;
+       public
           objname,
           objname,
           objrealname    : PShortString;
           objrealname    : PShortString;
           { for C++ classes: name of the library this class is imported from }
           { for C++ classes: name of the library this class is imported from }
@@ -3766,8 +3769,104 @@ implementation
       end;
       end;
 
 
     function tabstractrecorddef.RttiName: string;
     function tabstractrecorddef.RttiName: string;
+
+        function generate_full_paramname(maxlength:longint):string;
+          const
+            commacount : array[boolean] of longint = (0,1);
+          var
+            fullparas,
+            paramname : ansistring;
+            module : tmodule;
+            sym : ttypesym;
+            i : longint;
+          begin
+            { we want at least enough space for an ellipsis }
+            if maxlength<3 then
+              internalerror(2014121203);
+            fullparas:='';
+            for i:=0 to genericparas.count-1 do
+              begin
+                sym:=ttypesym(genericparas[i]);
+                module:=find_module_from_symtable(sym.owner);
+                if not assigned(module) then
+                  internalerror(2014121202);
+                paramname:=module.realmodulename^;
+                if sym.typedef.typ in [objectdef,recorddef] then
+                  paramname:=paramname+'.'+tabstractrecorddef(sym.typedef).rttiname
+                else
+                  paramname:=paramname+'.'+sym.typedef.typename;
+                if length(fullparas)+commacount[i>0]+length(paramname)>maxlength then
+                  begin
+                    if i>0 then
+                      fullparas:=fullparas+',...'
+                    else
+                      fullparas:=fullparas+'...';
+                    break;
+                  end;
+                { could we fit an ellipsis after this parameter if it should be too long? }
+                if (maxlength-(length(fullparas)+commacount[i>0]+length(paramname))<4) and (i<genericparas.count-1) then
+                  begin
+                    { then omit already this parameter }
+                    if i>0 then
+                      fullparas:=fullparas+',...'
+                    else
+                      fullparas:=fullparas+'...';
+                    break;
+                  end;
+                if i>0 then
+                  fullparas:=fullparas+',';
+                fullparas:=fullparas+paramname;
+              end;
+            result:=fullparas;
+          end;
+
+      var
+        nongeneric,
+        basename : string;
+        i,
+        remlength,
+        paramcount,
+        crcidx : longint;
       begin
       begin
-        Result:=OwnerHierarchyName+objrealname^;
+        if rttistring='' then
+          begin
+            if is_specialization then
+              begin
+                rttistring:=OwnerHierarchyName;
+                { there should be two $ characters, one before the CRC and one before the count }
+                crcidx:=-1;
+                for i:=length(objrealname^) downto 1 do
+                  if objrealname^[i]='$' then
+                    begin
+                      crcidx:=i;
+                      break;
+                    end;
+                if crcidx<0 then
+                  internalerror(2014121201);
+                basename:=copy(objrealname^,1,crcidx-1);
+                split_generic_name(basename,nongeneric,paramcount);
+                rttistring:=rttistring+nongeneric+'<';
+                remlength:=255-length(rttistring)-1;
+                if remlength<4 then
+                  rttistring:=rttistring+'>'
+                else
+                  rttistring:=rttistring+generate_full_paramname(remlength)+'>';
+              end
+            else
+              if is_generic then
+                begin
+                  rttistring:=OwnerHierarchyName;
+                  split_generic_name(objrealname^,nongeneric,paramcount);
+                  rttistring:=rttistring+nongeneric+'<';
+                  { we don't want any ',' if there is only one parameter }
+                  for i:=0 to paramcount-0 do
+                    rttistring:=rttistring+',';
+                  rttistring:=rttistring+'>';
+                end
+              else
+                rttistring:=OwnerHierarchyName+objrealname^;
+          end;
+        result:=rttistring;
       end;
       end;
 
 
     function tabstractrecorddef.search_enumerator_get: tprocdef;
     function tabstractrecorddef.search_enumerator_get: tprocdef;