mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-19 13:59:29 +02:00
fcl-passrc: specialize non forward generic procedure
git-svn-id: trunk@43050 -
This commit is contained in:
parent
db5620354e
commit
9ac8abeb4e
@ -193,7 +193,7 @@ const
|
||||
nConstraintXSpecifiedMoreThanOnce = 3127;
|
||||
nConstraintXAndConstraintYCannotBeTogether = 3128;
|
||||
nXIsNotAValidConstraint = 3129;
|
||||
nWrongNumberOfParametersForGenericType = 3130;
|
||||
nWrongNumberOfParametersForGenericX = 3130;
|
||||
nGenericsWithoutSpecializationAsType = 3131;
|
||||
nDeclOfXDiffersFromPrevAtY = 3132;
|
||||
nTypeParamXIsMissingConstraintY = 3133;
|
||||
@ -342,7 +342,7 @@ resourcestring
|
||||
sConstraintXSpecifiedMoreThanOnce = 'Constraint "%s" specified more than once';
|
||||
sConstraintXAndConstraintYCannotBeTogether = '"%s" constraint and "%s" constraint cannot be specified together';
|
||||
sXIsNotAValidConstraint = '"%s" is not a valid constraint';
|
||||
sWrongNumberOfParametersForGenericType = 'wrong number of parameters for generic type %s';
|
||||
sWrongNumberOfParametersForGenericX = 'wrong number of parameters for generic %s';
|
||||
sGenericsWithoutSpecializationAsType = 'Generics without specialization cannot be used as a type for a %s';
|
||||
sDeclOfXDiffersFromPrevAtY = 'Declaration of "%s" differs from previous declaration at %s';
|
||||
sTypeParamXIsMissingConstraintY = 'Type parameter "%s" is missing constraint "%s"';
|
||||
@ -791,7 +791,7 @@ function CodePointToUnicodeString(u: longword): UnicodeString;
|
||||
|
||||
function GetObjName(o: TObject): string;
|
||||
function GetObjPath(o: TObject): string;
|
||||
function GetTypeParamCommas(Cnt: integer): string;
|
||||
function GetGenericParamCommas(Cnt: integer): string;
|
||||
function dbgs(const Flags: TResEvalFlags): string; overload;
|
||||
function dbgs(v: TResEvalValue): string; overload;
|
||||
function LastPos(c: char; const s: string): sizeint;
|
||||
@ -1023,7 +1023,7 @@ begin
|
||||
GenType:=TPasGenericType(o);
|
||||
if (GenType.GenericTemplateTypes<>nil)
|
||||
and (GenType.GenericTemplateTypes.Count>0) then
|
||||
Result:=Result+GetTypeParamCommas(GenType.GenericTemplateTypes.Count);
|
||||
Result:=Result+GetGenericParamCommas(GenType.GenericTemplateTypes.Count);
|
||||
end;
|
||||
Result:=Result+':'+o.ClassName;
|
||||
end
|
||||
@ -1049,7 +1049,7 @@ begin
|
||||
GenType:=TPasGenericType(El);
|
||||
if (GenType.GenericTemplateTypes<>nil)
|
||||
and (GenType.GenericTemplateTypes.Count>0) then
|
||||
Result:=GetTypeParamCommas(GenType.GenericTemplateTypes.Count)+Result;
|
||||
Result:=GetGenericParamCommas(GenType.GenericTemplateTypes.Count)+Result;
|
||||
end;
|
||||
if El.Name<>'' then
|
||||
begin
|
||||
@ -1067,7 +1067,7 @@ begin
|
||||
Result:=GetObjName(o);
|
||||
end;
|
||||
|
||||
function GetTypeParamCommas(Cnt: integer): string;
|
||||
function GetGenericParamCommas(Cnt: integer): string;
|
||||
begin
|
||||
if Cnt<=0 then
|
||||
Result:=''
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1015,17 +1015,17 @@ function TPasAnalyzer.CanSkipGenericType(El: TPasGenericType): boolean;
|
||||
procedure RaiseHalfSpecialized;
|
||||
var
|
||||
GenScope: TPasGenericScope;
|
||||
Item: TPSSpecializedItem;
|
||||
Item: TPRSpecializedItem;
|
||||
begin
|
||||
if (El.GenericTemplateTypes<>nil) and (El.GenericTemplateTypes.Count>0) then
|
||||
RaiseNotSupported(20190817151437,El);
|
||||
if not (El.CustomData is TPasGenericScope) then
|
||||
RaiseNotSupported(20190826141320,El,GetObjName(El.CustomData));
|
||||
GenScope:=TPasGenericScope(El.CustomData);
|
||||
Item:=GenScope.SpecializedItem;
|
||||
Item:=GenScope.SpecializedFromItem;
|
||||
if Item=nil then
|
||||
RaiseNotSupported(20190826141352,El);
|
||||
if Item.SpecializedType=nil then
|
||||
if Item.SpecializedEl=nil then
|
||||
RaiseNotSupported(20190826141516,El);
|
||||
if Item.FirstSpecialize=nil then
|
||||
RaiseNotSupported(20190826141649,El);
|
||||
@ -2740,7 +2740,7 @@ begin
|
||||
else
|
||||
ImplProc:=ProcScope.ImplProc;
|
||||
if (ProcScope.ClassRecScope<>nil)
|
||||
and (ProcScope.ClassRecScope.SpecializedItem<>nil) then
|
||||
and (ProcScope.ClassRecScope.SpecializedFromItem<>nil) then
|
||||
exit; // specialized proc
|
||||
|
||||
if not PAElementExists(DeclProc) then
|
||||
@ -3049,7 +3049,7 @@ begin
|
||||
if El is TPasGenericType then
|
||||
begin
|
||||
GenScope:=El.CustomData as TPasGenericScope;
|
||||
if (GenScope<>nil) and (GenScope.SpecializedItem<>nil) then
|
||||
if (GenScope<>nil) and (GenScope.SpecializedFromItem<>nil) then
|
||||
exit(true);
|
||||
end;
|
||||
Result:=false;
|
||||
|
@ -84,6 +84,7 @@ type
|
||||
procedure TestGen_Class_Self;
|
||||
procedure TestGen_Class_MemberTypeConstructor;
|
||||
procedure TestGen_Class_List;
|
||||
// ToDo: different modeswitches at parse time and specialize time
|
||||
|
||||
// generic external class
|
||||
procedure TestGen_ExtClass_Array;
|
||||
@ -104,6 +105,7 @@ type
|
||||
procedure TestGen_PointerDirectSpecializeFail;
|
||||
|
||||
// ToDo: helpers for generics
|
||||
// ToDo: default class prop array helper: arr<b>[c]
|
||||
|
||||
// generic statements
|
||||
procedure TestGen_LocalVar;
|
||||
@ -114,20 +116,30 @@ type
|
||||
procedure TestGen_TryExcept;
|
||||
procedure TestGen_Call;
|
||||
procedure TestGen_NestedProc;
|
||||
// ToDo: obj<b>[c]
|
||||
|
||||
// generic functions
|
||||
procedure TestGenProc_Function; // ToDo
|
||||
//procedure TestGenProc_Forward; // ToDo
|
||||
procedure TestGenProc_Function;
|
||||
procedure TestGenProc_FunctionDelphi;
|
||||
procedure TestGenProc_OverloadDuplicate;
|
||||
procedure TestGenProc_Forward; // ToDo
|
||||
//procedure TestGenProc_External;
|
||||
//procedure TestGenProc_UnitIntf;
|
||||
procedure TestGenProc_BackRef1Fail;
|
||||
procedure TestGenProc_BackRef2Fail;
|
||||
procedure TestGenProc_BackRef3Fail;
|
||||
//procedure TestGenProc_Inference;
|
||||
// ToDo: forward parametrized impl must not repeat constraints
|
||||
// ToDo: forward parametrized impl overloads
|
||||
// ToDo: parametrized nested proc fail
|
||||
// ToDo: generic class method overload <T> <S,T>
|
||||
// ToDo: procedure TestGenMethod_ClassConstructorFail;
|
||||
// ToDo: procedure TestGenMethod_NestedProc;
|
||||
// ToDo: virtual method cannot have type parameters
|
||||
// ToDo: message method cannot have type parameters
|
||||
// ToDo: interface method cannot have type parameters
|
||||
// ToDo: parametrized method mismatch interface method
|
||||
// ToDo: generic class method overload <T> <S,T>
|
||||
// ToDo: generic class method overload <T>(bool) <T>(word)
|
||||
// ToDo: procedure TestGenMethod_ClassConstructorFail;
|
||||
// ToDo: procedure TestGenMethod_NestedProc;
|
||||
end;
|
||||
|
||||
implementation
|
||||
@ -1689,7 +1701,6 @@ end;
|
||||
|
||||
procedure TTestResolveGenerics.TestGenProc_Function;
|
||||
begin
|
||||
exit;
|
||||
StartProgram(false);
|
||||
Add([
|
||||
'generic function DoIt<T>(a: T): T;',
|
||||
@ -1700,11 +1711,101 @@ begin
|
||||
'end;',
|
||||
'var w: word;',
|
||||
'begin',
|
||||
' w:=specialize DoIt<word>(3);',
|
||||
'']);
|
||||
ParseProgram;
|
||||
end;
|
||||
|
||||
procedure TTestResolveGenerics.TestGenProc_FunctionDelphi;
|
||||
begin
|
||||
StartProgram(false);
|
||||
Add([
|
||||
'{$mode delphi}',
|
||||
'function DoIt<T>(a: T): T;',
|
||||
'var i: T;',
|
||||
'begin',
|
||||
' a:=i;',
|
||||
' Result:=a;',
|
||||
'end;',
|
||||
'var w: word;',
|
||||
'begin',
|
||||
' w:=DoIt<word>(3);',
|
||||
'']);
|
||||
ParseProgram;
|
||||
end;
|
||||
|
||||
procedure TTestResolveGenerics.TestGenProc_OverloadDuplicate;
|
||||
begin
|
||||
StartProgram(false);
|
||||
Add([
|
||||
'generic procedure Fly<T>(a: T);',
|
||||
'begin',
|
||||
'end;',
|
||||
'generic procedure Fly<T>(a: T);',
|
||||
'begin',
|
||||
'end;',
|
||||
'begin',
|
||||
'']);
|
||||
CheckResolverException('Duplicate identifier "Fly" at afile.pp(2,25)',nDuplicateIdentifier);
|
||||
end;
|
||||
|
||||
procedure TTestResolveGenerics.TestGenProc_Forward;
|
||||
begin
|
||||
exit;
|
||||
StartProgram(false);
|
||||
Add([
|
||||
'generic procedure Fly<T>(a: T); forward;',
|
||||
//'generic procedure Run;',
|
||||
//'begin',
|
||||
//' specialize Fly<word>(3);',
|
||||
//'end;',
|
||||
'generic procedure Fly<T>(a: T);',
|
||||
'var i: T;',
|
||||
'begin',
|
||||
' i:=a;',
|
||||
'end;',
|
||||
'begin',
|
||||
' specialize Fly<boolean>(true);',
|
||||
'']);
|
||||
ParseProgram;
|
||||
end;
|
||||
|
||||
procedure TTestResolveGenerics.TestGenProc_BackRef1Fail;
|
||||
begin
|
||||
StartProgram(false);
|
||||
Add([
|
||||
'generic function Fly<T>(a: Fly): T;',
|
||||
'begin',
|
||||
'end;',
|
||||
'begin',
|
||||
'']);
|
||||
CheckResolverException('Wrong number of parameters specified for call to "function Fly<>(untyped)"',nWrongNumberOfParametersForCallTo);
|
||||
end;
|
||||
|
||||
procedure TTestResolveGenerics.TestGenProc_BackRef2Fail;
|
||||
begin
|
||||
StartProgram(false);
|
||||
Add([
|
||||
'generic function Fly<T>(a: Fly<word>): T;',
|
||||
'begin',
|
||||
'end;',
|
||||
'begin',
|
||||
'']);
|
||||
CheckResolverException('Wrong number of parameters specified for call to "function Fly<>(untyped)"',nWrongNumberOfParametersForCallTo);
|
||||
end;
|
||||
|
||||
procedure TTestResolveGenerics.TestGenProc_BackRef3Fail;
|
||||
begin
|
||||
StartProgram(false);
|
||||
Add([
|
||||
'generic function Fly<T>(a: Fly<T>): T;',
|
||||
'begin',
|
||||
'end;',
|
||||
'begin',
|
||||
'']);
|
||||
CheckResolverException('Wrong number of parameters specified for call to "function Fly<>(untyped)"',nWrongNumberOfParametersForCallTo);
|
||||
end;
|
||||
|
||||
initialization
|
||||
RegisterTests([TTestResolveGenerics]);
|
||||
|
||||
|
@ -23,6 +23,7 @@ type
|
||||
Procedure TestGen_Class_TList;
|
||||
Procedure TestGen_ClassAncestor;
|
||||
Procedure TestGen_TypeInfo;
|
||||
// ToDo: TBird, TBird<T>, TBird<S,T>
|
||||
|
||||
// generic external class
|
||||
procedure TestGen_ExtClass_Array;
|
||||
@ -31,6 +32,14 @@ type
|
||||
Procedure TestGen_InlineSpec_Constructor;
|
||||
Procedure TestGen_CallUnitImplProc;
|
||||
Procedure TestGen_IntAssignTemplVar;
|
||||
// ToDo: TBird<word>(o).field:=3;
|
||||
|
||||
// generic helper
|
||||
// ToDo: helper for gen array: TArray<word>.Fly(aword);
|
||||
|
||||
// generic functions
|
||||
// ToDo: Fly<word>(3);
|
||||
// ToDo: inference Fly(3);
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
3
utils/pas2js/dist/rtl.js
vendored
3
utils/pas2js/dist/rtl.js
vendored
@ -176,8 +176,7 @@ var rtl = {
|
||||
|
||||
loaduseslist: function(module,useslist,f){
|
||||
if (useslist==undefined) return;
|
||||
var len = useslist.length;
|
||||
for (var i = 0; i<len; i++) {
|
||||
for (var i in useslist){
|
||||
var unitname=useslist[i];
|
||||
if (rtl.debug_load_units) rtl.debug('loaduseslist of "'+module.$name+'" uses="'+unitname+'"');
|
||||
if (pas[unitname]==undefined)
|
||||
|
Loading…
Reference in New Issue
Block a user