mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-25 06:30:09 +02:00
fcl-passrc: typecast generic template type to generic template type
git-svn-id: trunk@47836 -
This commit is contained in:
parent
01691e9ecb
commit
ed3741f06e
@ -16652,8 +16652,28 @@ end;
|
|||||||
|
|
||||||
function TPasResolver.CreateSpecializedTypeName(Item: TPRSpecializedItem): string;
|
function TPasResolver.CreateSpecializedTypeName(Item: TPRSpecializedItem): string;
|
||||||
|
|
||||||
|
function Get_ProcName(aProc: TPasProcedure): string; forward;
|
||||||
function GetTypeName(aType: TPasType): string; forward;
|
function GetTypeName(aType: TPasType): string; forward;
|
||||||
|
|
||||||
|
function GetParentName(El: TPasElement): string;
|
||||||
|
begin
|
||||||
|
if El.Parent is TPasType then
|
||||||
|
Result:=GetTypeName(TPasType(El.Parent))
|
||||||
|
else if El is TPasUnresolvedSymbolRef then
|
||||||
|
Result:='System'
|
||||||
|
else if El.Parent is TPasProcedure then
|
||||||
|
Result:=Get_ProcName(TPasProcedure(El.Parent))
|
||||||
|
else
|
||||||
|
Result:=El.GetModule.Name;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function Get_ProcName(aProc: TPasProcedure): string;
|
||||||
|
begin
|
||||||
|
Result:=GetParentName(aProc);
|
||||||
|
if aProc.Name<>'' then
|
||||||
|
Result:=Result+'.'+aProc.Name;
|
||||||
|
end;
|
||||||
|
|
||||||
function GetSpecParams(Item: TPRSpecializedItem): string;
|
function GetSpecParams(Item: TPRSpecializedItem): string;
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
@ -16692,13 +16712,7 @@ function TPasResolver.CreateSpecializedTypeName(Item: TPRSpecializedItem): strin
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
if aType.Parent is TPasType then
|
Result:=GetParentName(aType)+'.'+aType.Name;
|
||||||
Result:=GetTypeName(TPasType(aType.Parent))
|
|
||||||
else if aType is TPasUnresolvedSymbolRef then
|
|
||||||
Result:='System'
|
|
||||||
else
|
|
||||||
Result:=aType.GetModule.Name;
|
|
||||||
Result:=Result+'.'+aType.Name;
|
|
||||||
if (aType.CustomData is TPasGenericScope) and (Pos('<',aType.Name)<1) then
|
if (aType.CustomData is TPasGenericScope) and (Pos('<',aType.Name)<1) then
|
||||||
begin
|
begin
|
||||||
ChildItem:=TPasGenericScope(aType.CustomData).SpecializedFromItem;
|
ChildItem:=TPasGenericScope(aType.CustomData).SpecializedFromItem;
|
||||||
@ -26738,7 +26752,7 @@ function TPasResolver.CheckTypeCastRes(const FromResolved,
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
ToTypeEl, ToType, FromType, FromTypeEl: TPasType;
|
ToTypeEl, FromTypeEl: TPasType;
|
||||||
ToTypeBaseType: TResolverBaseType;
|
ToTypeBaseType: TResolverBaseType;
|
||||||
C: TClass;
|
C: TClass;
|
||||||
ToProcType, FromProcType: TPasProcedureType;
|
ToProcType, FromProcType: TPasProcedureType;
|
||||||
@ -26763,9 +26777,12 @@ begin
|
|||||||
begin
|
begin
|
||||||
if ToTypeEl.CustomData is TResElDataBaseType then
|
if ToTypeEl.CustomData is TResElDataBaseType then
|
||||||
begin
|
begin
|
||||||
// base type cast, e.g. double(aninteger)
|
// type cast to base type, e.g. double(aninteger)
|
||||||
if ToTypeEl=FromResolved.LoTypeEl then
|
if ToTypeEl=FromResolved.LoTypeEl then
|
||||||
exit(cExact);
|
exit(cExact);
|
||||||
|
if (FromResolved.BaseType=btContext)
|
||||||
|
and (FromResolved.LoTypeEl.ClassType=TPasGenericTemplateType) then
|
||||||
|
exit(cExact); // e.g. double(T) -> will be checked when specialized
|
||||||
ToTypeBaseType:=(ToTypeEl.CustomData as TResElDataBaseType).BaseType;
|
ToTypeBaseType:=(ToTypeEl.CustomData as TResElDataBaseType).BaseType;
|
||||||
if ToTypeBaseType=FromResolved.BaseType then
|
if ToTypeBaseType=FromResolved.BaseType then
|
||||||
Result:=cExact
|
Result:=cExact
|
||||||
@ -26950,6 +26967,9 @@ begin
|
|||||||
// e.g. T(var)
|
// e.g. T(var)
|
||||||
TemplType:=TPasGenericTemplateType(ToTypeEl);
|
TemplType:=TPasGenericTemplateType(ToTypeEl);
|
||||||
FromTypeEl:=FromResolved.LoTypeEl;
|
FromTypeEl:=FromResolved.LoTypeEl;
|
||||||
|
if (FromTypeEl<>nil)
|
||||||
|
and (FromTypeEl.ClassType=TPasGenericTemplateType) then
|
||||||
|
exit(cExact); // e.g. T(S) -> will be checked when specialized
|
||||||
for i:=0 to length(TemplType.Constraints)-1 do
|
for i:=0 to length(TemplType.Constraints)-1 do
|
||||||
begin
|
begin
|
||||||
ConEl:=TemplType.Constraints[i];
|
ConEl:=TemplType.Constraints[i];
|
||||||
@ -26984,9 +27004,9 @@ begin
|
|||||||
if (FromResolved.IdentEl is TPasType) then
|
if (FromResolved.IdentEl is TPasType) then
|
||||||
RaiseMsg(20170404162604,nCannotTypecastAType,sCannotTypecastAType,[],ErrorEl);
|
RaiseMsg(20170404162604,nCannotTypecastAType,sCannotTypecastAType,[],ErrorEl);
|
||||||
// type cast classof(classof-var) upwards or downwards
|
// type cast classof(classof-var) upwards or downwards
|
||||||
ToType:=TPasClassOfType(ToTypeEl).DestType;
|
ToTypeEl:=TPasClassOfType(ToTypeEl).DestType;
|
||||||
FromType:=TPasClassOfType(FromResolved.LoTypeEl).DestType;
|
FromTypeEl:=TPasClassOfType(FromResolved.LoTypeEl).DestType;
|
||||||
Result:=CheckClassesAreRelated(ToType,FromType);
|
Result:=CheckClassesAreRelated(ToTypeEl,FromTypeEl);
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
else if FromResolved.BaseType=btPointer then
|
else if FromResolved.BaseType=btPointer then
|
||||||
@ -27171,9 +27191,8 @@ begin
|
|||||||
and (ToTypeEl=ToResolved.IdentEl) then
|
and (ToTypeEl=ToResolved.IdentEl) then
|
||||||
begin
|
begin
|
||||||
// for example class-of(Self) in a class function
|
// for example class-of(Self) in a class function
|
||||||
ToType:=TPasClassOfType(ToTypeEl).DestType;
|
ToTypeEl:=TPasClassOfType(ToTypeEl).DestType;
|
||||||
FromType:=TPasClassType(FromTypeEl);
|
Result:=CheckClassesAreRelated(ToTypeEl,FromTypeEl);
|
||||||
Result:=CheckClassesAreRelated(ToType,FromType);
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
@ -185,6 +185,7 @@ type
|
|||||||
procedure TestGenMethod_OverloadTypeParamCntObjFPC;
|
procedure TestGenMethod_OverloadTypeParamCntObjFPC;
|
||||||
procedure TestGenMethod_OverloadTypeParamCntDelphi;
|
procedure TestGenMethod_OverloadTypeParamCntDelphi;
|
||||||
procedure TestGenMethod_OverloadArgs;
|
procedure TestGenMethod_OverloadArgs;
|
||||||
|
procedure TestGenMethod_TypeCastParam;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
@ -2982,6 +2983,29 @@ begin
|
|||||||
ParseProgram;
|
ParseProgram;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestResolveGenerics.TestGenMethod_TypeCastParam;
|
||||||
|
begin
|
||||||
|
StartUnit(false);
|
||||||
|
Add([
|
||||||
|
'{$mode delphi}',
|
||||||
|
'interface',
|
||||||
|
'type',
|
||||||
|
' TObject = class end;',
|
||||||
|
' TArray<T> = array of T;',
|
||||||
|
' TBird = class',
|
||||||
|
' F: TArray<TObject>;',
|
||||||
|
' procedure Run<S>(a: TArray<S>);',
|
||||||
|
' end;',
|
||||||
|
'implementation',
|
||||||
|
'procedure TBird.Run<S>(a: TArray<S>);',
|
||||||
|
'begin',
|
||||||
|
' a:=TArray<S>(a);',
|
||||||
|
//' F:=TArray<TObject>(a);',
|
||||||
|
'end;',
|
||||||
|
'']);
|
||||||
|
ParseUnit;
|
||||||
|
end;
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
RegisterTests([TTestResolveGenerics]);
|
RegisterTests([TTestResolveGenerics]);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user