mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-14 13:29:14 +02:00
pastojs: shortrefglobals: proc var of generic method
git-svn-id: trunk@47277 -
This commit is contained in:
parent
8fe5a1e894
commit
088aacfb26
@ -18723,8 +18723,7 @@ begin
|
|||||||
aResolver:=AContext.Resolver;
|
aResolver:=AContext.Resolver;
|
||||||
|
|
||||||
Proc:=TPasProcedure(ResolvedEl.IdentEl);
|
Proc:=TPasProcedure(ResolvedEl.IdentEl);
|
||||||
if (not (Proc.Parent is TPasMembersType))
|
if not aResolver.ProcHasSelf(Proc) then
|
||||||
or (ptmStatic in Proc.ProcType.Modifiers) then
|
|
||||||
begin
|
begin
|
||||||
// not an "of object" method -> simply use the function
|
// not an "of object" method -> simply use the function
|
||||||
Result:=CreateReferencePathExpr(Proc,AContext);
|
Result:=CreateReferencePathExpr(Proc,AContext);
|
||||||
@ -18735,6 +18734,9 @@ begin
|
|||||||
IsHelper:=aResolver.IsHelperMethod(Proc);
|
IsHelper:=aResolver.IsHelperMethod(Proc);
|
||||||
NeedClass:=aResolver.IsClassMethod(Proc) and not aResolver.MethodIsStatic(Proc);
|
NeedClass:=aResolver.IsClassMethod(Proc) and not aResolver.MethodIsStatic(Proc);
|
||||||
|
|
||||||
|
if Expr is TInlineSpecializeExpr then
|
||||||
|
Expr:=TInlineSpecializeExpr(Expr).NameExpr;
|
||||||
|
|
||||||
// an of-object method -> create "rtl.createCallback(Target,func)"
|
// an of-object method -> create "rtl.createCallback(Target,func)"
|
||||||
TargetJS:=nil;
|
TargetJS:=nil;
|
||||||
Call:=nil;
|
Call:=nil;
|
||||||
@ -18819,8 +18821,17 @@ begin
|
|||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
// create rtl.createCallback(target, "FunName")
|
// create rtl.createCallback(target, "FunName")
|
||||||
FunName:=TransformElToJSName(Proc,AContext);
|
if (coShortRefGlobals in Options)
|
||||||
Call.AddArg(CreateLiteralString(Expr,FunName));
|
and (TPas2JSProcedureScope(Proc.CustomData).SpecializedFromItem<>nil) then
|
||||||
|
begin
|
||||||
|
FunName:=CreateStaticProcPath(Proc,AContext);
|
||||||
|
Call.AddArg(CreatePrimitiveDotExpr(FunName,Expr));
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
FunName:=TransformElToJSName(Proc,AContext);
|
||||||
|
Call.AddArg(CreateLiteralString(Expr,FunName));
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Result:=Call;
|
Result:=Call;
|
||||||
|
@ -66,6 +66,8 @@ type
|
|||||||
procedure TestOptShortRefGlobals_GenericStaticMethod_Call;
|
procedure TestOptShortRefGlobals_GenericStaticMethod_Call;
|
||||||
// ToDo: GenericMethod_CallInherited ObjFPC+Delphi
|
// ToDo: GenericMethod_CallInherited ObjFPC+Delphi
|
||||||
// ToDo: procedure TestOptShortRefGlobals_GenericHelperMethod_Call_Delphi;
|
// ToDo: procedure TestOptShortRefGlobals_GenericHelperMethod_Call_Delphi;
|
||||||
|
procedure TestOptShortRefGlobals_GenericMethod_ProcVar;
|
||||||
|
procedure TestOptShortRefGlobals_GenericStaticMethod_ProcVar;
|
||||||
// ToDo: proc var
|
// ToDo: proc var
|
||||||
procedure TestOptShortRefGlobals_SameUnit_EnumType;
|
procedure TestOptShortRefGlobals_SameUnit_EnumType;
|
||||||
procedure TestOptShortRefGlobals_SameUnit_ClassType;
|
procedure TestOptShortRefGlobals_SameUnit_ClassType;
|
||||||
@ -733,7 +735,6 @@ begin
|
|||||||
'interface',
|
'interface',
|
||||||
'uses unita;',
|
'uses unita;',
|
||||||
'type',
|
'type',
|
||||||
' TFunc = function(a: word): word;',
|
|
||||||
' TEagle = class(TBird)',
|
' TEagle = class(TBird)',
|
||||||
' procedure Test;',
|
' procedure Test;',
|
||||||
' generic class function Run<T>(c: word = 25): T; static;',
|
' generic class function Run<T>(c: word = 25): T; static;',
|
||||||
@ -741,7 +742,6 @@ begin
|
|||||||
' end;',
|
' end;',
|
||||||
'implementation',
|
'implementation',
|
||||||
'procedure TEagle.Test;',
|
'procedure TEagle.Test;',
|
||||||
'var f: TFunc;',
|
|
||||||
'begin',
|
'begin',
|
||||||
' specialize Fly<Word>;',
|
' specialize Fly<Word>;',
|
||||||
' specialize Fly<Word>(31);',
|
' specialize Fly<Word>(31);',
|
||||||
@ -838,6 +838,207 @@ begin
|
|||||||
'']));
|
'']));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestOptimizations.TestOptShortRefGlobals_GenericMethod_ProcVar;
|
||||||
|
begin
|
||||||
|
AddModuleWithIntfImplSrc('UnitA.pas',
|
||||||
|
LinesToStr([
|
||||||
|
'{$mode delphi}',
|
||||||
|
'type',
|
||||||
|
' TBird = class',
|
||||||
|
' function Fly<T>(a: word = 13): T;',
|
||||||
|
' class function Jump<T>(b: word = 14): T;',
|
||||||
|
' end;',
|
||||||
|
'']),
|
||||||
|
LinesToStr([
|
||||||
|
'function TBird.Fly<T>(a: word): T;',
|
||||||
|
'begin',
|
||||||
|
'end;',
|
||||||
|
'class function TBird.Jump<T>(b: word): T;',
|
||||||
|
'begin',
|
||||||
|
'end;',
|
||||||
|
'']));
|
||||||
|
StartUnit(true,[supTObject]);
|
||||||
|
Add([
|
||||||
|
'{$mode delphi}',
|
||||||
|
'{$optimization JSShortRefGlobals}',
|
||||||
|
'interface',
|
||||||
|
'uses unita;',
|
||||||
|
'type',
|
||||||
|
' TFunc<T> = function(a: word): T of object;',
|
||||||
|
' TEagle = class(TBird)',
|
||||||
|
' procedure Test;',
|
||||||
|
' function Run<T>(c: word = 25): T;',
|
||||||
|
' class function Sing<T>(d: word = 26): T;',
|
||||||
|
' end;',
|
||||||
|
'implementation',
|
||||||
|
'procedure TEagle.Test;',
|
||||||
|
'var f: TFunc<word>;',
|
||||||
|
'begin',
|
||||||
|
' f:=@Run<Word>;',
|
||||||
|
' f:=@Sing<Word>;',
|
||||||
|
' f:=@Fly<Word>;',
|
||||||
|
' f:=@Jump<Word>;',
|
||||||
|
' f:=@Self.Fly<Word>;',
|
||||||
|
' f:=@Self.Jump<Word>;',
|
||||||
|
' with Self do begin',
|
||||||
|
' f:=@Fly<Word>;',
|
||||||
|
' f:=@Jump<Word>;',
|
||||||
|
' end;',
|
||||||
|
'end;',
|
||||||
|
'function TEagle.Run<T>(c: word): T;',
|
||||||
|
'begin',
|
||||||
|
'end;',
|
||||||
|
'class function TEagle.Sing<T>(d: word): T;',
|
||||||
|
'var f: TFunc<T>;',
|
||||||
|
'begin',
|
||||||
|
' f:=@Jump<T>;',
|
||||||
|
'end;',
|
||||||
|
'']);
|
||||||
|
ConvertUnit;
|
||||||
|
CheckSource('TestOptShortRefGlobals_GenericMethod_ProcVar',
|
||||||
|
LinesToStr([
|
||||||
|
'var $lt = null;',
|
||||||
|
'var $lp = null;',
|
||||||
|
'var $lp1 = null;',
|
||||||
|
'var $lm = pas.UnitA;',
|
||||||
|
'var $lt1 = $lm.TBird;',
|
||||||
|
'var $lp2 = $lt1.Fly$G1;',
|
||||||
|
'var $lp3 = $lt1.Jump$G1;',
|
||||||
|
'rtl.createClass(this, "TEagle", $lt1, function () {',
|
||||||
|
' $lt = this;',
|
||||||
|
' this.Test = function () {',
|
||||||
|
' var f = null;',
|
||||||
|
' f = rtl.createCallback(this, $lp);',
|
||||||
|
' f = rtl.createCallback(this.$class, $lp1);',
|
||||||
|
' f = rtl.createCallback(this, $lp2);',
|
||||||
|
' f = rtl.createCallback(this.$class, $lp3);',
|
||||||
|
' f = rtl.createCallback(this, $lp2);',
|
||||||
|
' f = rtl.createCallback(this.$class, $lp3);',
|
||||||
|
' f = rtl.createCallback(this, $lp2);',
|
||||||
|
' f = rtl.createCallback(this.$class, $lp3);',
|
||||||
|
' };',
|
||||||
|
' this.Run$G1 = $lp = function (c) {',
|
||||||
|
' var Result = 0;',
|
||||||
|
' return Result;',
|
||||||
|
' };',
|
||||||
|
' this.Sing$G1 = $lp1 = function (d) {',
|
||||||
|
' var Result = 0;',
|
||||||
|
' var f = null;',
|
||||||
|
' f = rtl.createCallback(this, $lp3);',
|
||||||
|
' return Result;',
|
||||||
|
' };',
|
||||||
|
'});',
|
||||||
|
'']),
|
||||||
|
LinesToStr([
|
||||||
|
'']),
|
||||||
|
LinesToStr([
|
||||||
|
'']));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestOptimizations.TestOptShortRefGlobals_GenericStaticMethod_ProcVar;
|
||||||
|
begin
|
||||||
|
AddModuleWithIntfImplSrc('UnitA.pas',
|
||||||
|
LinesToStr([
|
||||||
|
'type',
|
||||||
|
' TBird = class',
|
||||||
|
' generic class function Fly<T>(a: word = 13): T; static;',
|
||||||
|
' class function Say(a: word = 13): word; static;',
|
||||||
|
' end;',
|
||||||
|
'']),
|
||||||
|
LinesToStr([
|
||||||
|
'generic class function TBird.Fly<T>(a: word): T;',
|
||||||
|
'begin',
|
||||||
|
'end;',
|
||||||
|
'class function TBird.Say(a: word): word;',
|
||||||
|
'begin',
|
||||||
|
'end;',
|
||||||
|
'']));
|
||||||
|
StartUnit(true,[supTObject]);
|
||||||
|
Add([
|
||||||
|
'{$optimization JSShortRefGlobals}',
|
||||||
|
'interface',
|
||||||
|
'uses unita;',
|
||||||
|
'type',
|
||||||
|
' TFunc = function(a: word): word;',
|
||||||
|
' TEagle = class(TBird)',
|
||||||
|
' procedure Test;',
|
||||||
|
' generic class function Run<T>(c: word = 25): T; static;',
|
||||||
|
' class function Lay(c: word = 25): word; static;',
|
||||||
|
' end;',
|
||||||
|
'implementation',
|
||||||
|
'procedure TEagle.Test;',
|
||||||
|
'var f: TFunc;',
|
||||||
|
'begin',
|
||||||
|
' F:=@specialize Fly<Word>;',
|
||||||
|
' F:=@Say;',
|
||||||
|
' F:=@specialize Run<Word>;',
|
||||||
|
' F:=@Lay;',
|
||||||
|
' F:=@self.specialize Fly<Word>;',
|
||||||
|
' F:=@self.Say;',
|
||||||
|
' F:=@self.specialize Run<Word>;',
|
||||||
|
' with Self do begin',
|
||||||
|
' F:=@specialize Fly<Word>;',
|
||||||
|
' F:=@Say;',
|
||||||
|
' F:=@specialize Run<Word>;',
|
||||||
|
' end;',
|
||||||
|
'end;',
|
||||||
|
'generic class function TEagle.Run<T>(c: word): T;',
|
||||||
|
'begin',
|
||||||
|
'end;',
|
||||||
|
'class function TEagle.Lay(c: word): word;',
|
||||||
|
'var f: TFunc;',
|
||||||
|
'begin',
|
||||||
|
' f:=@TEagle.specialize Fly<Word>;',
|
||||||
|
' f:=@TEagle.Say;',
|
||||||
|
' f:=@TEagle.specialize Run<Word>;',
|
||||||
|
' f:=@Lay;',
|
||||||
|
'end;',
|
||||||
|
'']);
|
||||||
|
ConvertUnit;
|
||||||
|
CheckSource('TestOptShortRefGlobals_GenericStaticMethod_ProcVar',
|
||||||
|
LinesToStr([
|
||||||
|
'var $lt = null;',
|
||||||
|
'var $lp = null;',
|
||||||
|
'var $lm = pas.UnitA;',
|
||||||
|
'var $lt1 = $lm.TBird;',
|
||||||
|
'var $lp1 = $lt1.Fly$G1;',
|
||||||
|
'var $lp2 = $lt1.Say;',
|
||||||
|
'rtl.createClass(this, "TEagle", $lt1, function () {',
|
||||||
|
' $lt = this;',
|
||||||
|
' this.Test = function () {',
|
||||||
|
' var f = null;',
|
||||||
|
' f = $lp1;',
|
||||||
|
' f = $lp2;',
|
||||||
|
' f = $lp;',
|
||||||
|
' f = $lt.Lay;',
|
||||||
|
' f = $lp1;',
|
||||||
|
' f = $lp2;',
|
||||||
|
' f = $lp;',
|
||||||
|
' f = $lp1;',
|
||||||
|
' f = $lp2;',
|
||||||
|
' f = $lp;',
|
||||||
|
' };',
|
||||||
|
' this.Lay = function (c) {',
|
||||||
|
' var Result = 0;',
|
||||||
|
' var f = null;',
|
||||||
|
' f = $lp1;',
|
||||||
|
' f = $lp2;',
|
||||||
|
' f = $lp;',
|
||||||
|
' f = $lt.Lay;',
|
||||||
|
' return Result;',
|
||||||
|
' };',
|
||||||
|
' this.Run$G1 = $lp = function (c) {',
|
||||||
|
' var Result = 0;',
|
||||||
|
' return Result;',
|
||||||
|
' };',
|
||||||
|
'});',
|
||||||
|
'']),
|
||||||
|
LinesToStr([
|
||||||
|
'']),
|
||||||
|
LinesToStr([
|
||||||
|
'']));
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TTestOptimizations.TestOptShortRefGlobals_SameUnit_EnumType;
|
procedure TTestOptimizations.TestOptShortRefGlobals_SameUnit_EnumType;
|
||||||
begin
|
begin
|
||||||
StartUnit(true,[supTObject]);
|
StartUnit(true,[supTObject]);
|
||||||
|
Loading…
Reference in New Issue
Block a user