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 -
This commit is contained in:
svenbarth 2014-12-12 17:25:15 +00:00
parent 27f398851b
commit 77df68b2d9

View File

@ -243,6 +243,9 @@ interface
tprocdef = class;
tabstractrecorddef= class(tstoreddef)
private
rttistring : string;
public
objname,
objrealname : PShortString;
{ for C++ classes: name of the library this class is imported from }
@ -3766,8 +3769,104 @@ implementation
end;
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
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;
function tabstractrecorddef.search_enumerator_get: tprocdef;