mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-11 09:26:15 +02:00
pastojs: override scope class array and proctype
git-svn-id: trunk@46768 -
This commit is contained in:
parent
9140e9414d
commit
fc4c48a11c
@ -1166,6 +1166,7 @@ type
|
|||||||
|
|
||||||
TPas2JSClassScope = class(TPasClassScope)
|
TPas2JSClassScope = class(TPasClassScope)
|
||||||
public
|
public
|
||||||
|
LongName: string;
|
||||||
NewInstanceFunction: TPasClassFunction;
|
NewInstanceFunction: TPasClassFunction;
|
||||||
GUID: string;
|
GUID: string;
|
||||||
ElevatedLocals: TPas2jsElevatedLocals;
|
ElevatedLocals: TPas2jsElevatedLocals;
|
||||||
@ -1183,6 +1184,7 @@ type
|
|||||||
|
|
||||||
TPas2JSRecordScope = class(TPasRecordScope)
|
TPas2JSRecordScope = class(TPasRecordScope)
|
||||||
public
|
public
|
||||||
|
LongName: string;
|
||||||
MemberOverloadsRenamed: boolean;
|
MemberOverloadsRenamed: boolean;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1191,6 +1193,7 @@ type
|
|||||||
TPas2JSProcedureScope = class(TPasProcedureScope)
|
TPas2JSProcedureScope = class(TPasProcedureScope)
|
||||||
public
|
public
|
||||||
OverloadName: string;
|
OverloadName: string;
|
||||||
|
LongName: string;
|
||||||
ResultVarName: string; // valid in implementation ProcScope, empty means use ResolverResultVar
|
ResultVarName: string; // valid in implementation ProcScope, empty means use ResolverResultVar
|
||||||
BodyOverloadsRenamed: boolean;
|
BodyOverloadsRenamed: boolean;
|
||||||
BodyJS: string; // Option coStoreProcJS: stored in ImplScope
|
BodyJS: string; // Option coStoreProcJS: stored in ImplScope
|
||||||
@ -1200,6 +1203,20 @@ type
|
|||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TPas2JSArrayScope }
|
||||||
|
|
||||||
|
TPas2JSArrayScope = Class(TPasArrayScope)
|
||||||
|
public
|
||||||
|
LongName: string;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TPas2JSProcTypeScope }
|
||||||
|
|
||||||
|
TPas2JSProcTypeScope = Class(TPasProcTypeScope)
|
||||||
|
public
|
||||||
|
LongName: string;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TPas2JSWithExprScope }
|
{ TPas2JSWithExprScope }
|
||||||
|
|
||||||
TPas2JSWithExprScope = class(TPasWithExprScope)
|
TPas2JSWithExprScope = class(TPasWithExprScope)
|
||||||
@ -1495,9 +1512,12 @@ type
|
|||||||
function GenerateGUID(El: TPasClassType): string; virtual;
|
function GenerateGUID(El: TPasClassType): string; virtual;
|
||||||
protected
|
protected
|
||||||
// generic/specialize
|
// generic/specialize
|
||||||
|
procedure SpecializeGenericIntf(SpecializedItem: TPRSpecializedItem);
|
||||||
|
override;
|
||||||
procedure SpecializeGenericImpl(SpecializedItem: TPRSpecializedItem);
|
procedure SpecializeGenericImpl(SpecializedItem: TPRSpecializedItem);
|
||||||
override;
|
override;
|
||||||
function SpecializeNeedsDelay(SpecializedItem: TPRSpecializedItem): TPasElement; virtual;
|
function SpecializeNeedsDelay(SpecializedItem: TPRSpecializedItem): TPasElement; virtual;
|
||||||
|
function CreateLongName(SpecializedItem: TPRSpecializedItem): string; virtual;
|
||||||
protected
|
protected
|
||||||
const
|
const
|
||||||
cJSValueConversion = 2*cTypeConversion;
|
cJSValueConversion = 2*cTypeConversion;
|
||||||
@ -4955,6 +4975,49 @@ begin
|
|||||||
Result:=Result+'}';
|
Result:=Result+'}';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TPas2JSResolver.SpecializeGenericIntf(
|
||||||
|
SpecializedItem: TPRSpecializedItem);
|
||||||
|
{$IFDEF EnableLongNames}
|
||||||
|
var
|
||||||
|
El: TPasElement;
|
||||||
|
C: TClass;
|
||||||
|
RecScope: TPas2JSRecordScope;
|
||||||
|
ClassScope: TPas2JSClassScope;
|
||||||
|
ArrayScope: TPas2JSArrayScope;
|
||||||
|
ProcTypeScope: TPas2JSProcTypeScope;
|
||||||
|
LongName: String;
|
||||||
|
{$ENDIF}
|
||||||
|
begin
|
||||||
|
{$IFDEF EnableLongNames}
|
||||||
|
El:=SpecializedItem.SpecializedEl;
|
||||||
|
C:=El.ClassType;
|
||||||
|
LongName:=CreateLongName(SpecializedItem);
|
||||||
|
if C=TPasRecordType then
|
||||||
|
begin
|
||||||
|
RecScope:=TPas2JSRecordScope(El.CustomData);
|
||||||
|
RecScope.LongName:=LongName;
|
||||||
|
end
|
||||||
|
else if C=TPasClassType then
|
||||||
|
begin
|
||||||
|
ClassScope:=TPas2JSClassScope(El.CustomData);
|
||||||
|
ClassScope.LongName:=LongName;
|
||||||
|
end
|
||||||
|
else if C=TPasArrayType then
|
||||||
|
begin
|
||||||
|
ArrayScope:=TPas2JSArrayScope(El.CustomData);
|
||||||
|
ArrayScope.LongName:=LongName;
|
||||||
|
end
|
||||||
|
else if (C=TPasProcedureType) or (C=TPasFunctionType) then
|
||||||
|
begin
|
||||||
|
ProcTypeScope:=TPas2JSProcTypeScope(El.CustomData);
|
||||||
|
ProcTypeScope.LongName:=LongName;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
RaiseNotYetImplemented(20200904132908,El);
|
||||||
|
{$ENDIF}
|
||||||
|
inherited SpecializeGenericIntf(SpecializedItem);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TPas2JSResolver.SpecializeGenericImpl(
|
procedure TPas2JSResolver.SpecializeGenericImpl(
|
||||||
SpecializedItem: TPRSpecializedItem);
|
SpecializedItem: TPRSpecializedItem);
|
||||||
var
|
var
|
||||||
@ -5037,6 +5100,24 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TPas2JSResolver.CreateLongName(SpecializedItem: TPRSpecializedItem
|
||||||
|
): string;
|
||||||
|
var
|
||||||
|
GenEl: TPasElement;
|
||||||
|
i: Integer;
|
||||||
|
Param: TPasType;
|
||||||
|
begin
|
||||||
|
GenEl:=SpecializedItem.GenericEl;
|
||||||
|
Result:=GenEl.Name+'<';
|
||||||
|
for i:=0 to length(SpecializedItem.Params)-1 do
|
||||||
|
begin
|
||||||
|
Param:=ResolveAliasType(SpecializedItem.Params[i],false);
|
||||||
|
// ToDo move to resolver
|
||||||
|
if Param=nil then ;
|
||||||
|
end;
|
||||||
|
Result:=Result+'>';
|
||||||
|
end;
|
||||||
|
|
||||||
function TPas2JSResolver.AddJSBaseType(const aName: string; Typ: TPas2jsBaseType
|
function TPas2JSResolver.AddJSBaseType(const aName: string; Typ: TPas2jsBaseType
|
||||||
): TResElDataPas2JSBaseType;
|
): TResElDataPas2JSBaseType;
|
||||||
var
|
var
|
||||||
@ -5827,6 +5908,8 @@ begin
|
|||||||
ScopeClass_Module:=TPas2JSModuleScope;
|
ScopeClass_Module:=TPas2JSModuleScope;
|
||||||
ScopeClass_Procedure:=TPas2JSProcedureScope;
|
ScopeClass_Procedure:=TPas2JSProcedureScope;
|
||||||
ScopeClass_Record:=TPas2JSRecordScope;
|
ScopeClass_Record:=TPas2JSRecordScope;
|
||||||
|
ScopeClass_Array:=TPas2JSArrayScope;
|
||||||
|
ScopeClass_ProcType:=TPas2JSProcTypeScope;
|
||||||
ScopeClass_Section:=TPas2JSSectionScope;
|
ScopeClass_Section:=TPas2JSSectionScope;
|
||||||
ScopeClass_WithExpr:=TPas2JSWithExprScope;
|
ScopeClass_WithExpr:=TPas2JSWithExprScope;
|
||||||
for bt in [pbtJSValue] do
|
for bt in [pbtJSValue] do
|
||||||
@ -15400,7 +15483,7 @@ var
|
|||||||
Obj: TJSObjectLiteral;
|
Obj: TJSObjectLiteral;
|
||||||
Prop: TJSObjectLiteralElement;
|
Prop: TJSObjectLiteralElement;
|
||||||
aResolver: TPas2JSResolver;
|
aResolver: TPas2JSResolver;
|
||||||
Scope: TPasProcTypeScope;
|
Scope: TPas2JSProcTypeScope;
|
||||||
SpecializeNeedsDelay: Boolean;
|
SpecializeNeedsDelay: Boolean;
|
||||||
FuncSt: TJSFunctionDeclarationStatement;
|
FuncSt: TJSFunctionDeclarationStatement;
|
||||||
AssignSt: TJSSimpleAssignStatement;
|
AssignSt: TJSSimpleAssignStatement;
|
||||||
@ -15420,7 +15503,7 @@ begin
|
|||||||
if El.Parent is TProcedureBody then
|
if El.Parent is TProcedureBody then
|
||||||
RaiseNotSupported(El,AContext,20181231112029);
|
RaiseNotSupported(El,AContext,20181231112029);
|
||||||
|
|
||||||
Scope:=El.CustomData as TPasProcTypeScope;
|
Scope:=El.CustomData as TPas2JSProcTypeScope;
|
||||||
SpecializeNeedsDelay:=(Scope<>nil)
|
SpecializeNeedsDelay:=(Scope<>nil)
|
||||||
and (aResolver.SpecializeNeedsDelay(Scope.SpecializedFromItem)<>nil);
|
and (aResolver.SpecializeNeedsDelay(Scope.SpecializedFromItem)<>nil);
|
||||||
|
|
||||||
@ -15532,7 +15615,7 @@ var
|
|||||||
|
|
||||||
var
|
var
|
||||||
aResolver: TPas2JSResolver;
|
aResolver: TPas2JSResolver;
|
||||||
Scope: TPasArrayScope;
|
Scope: TPas2JSArrayScope;
|
||||||
SpecializeNeedsDelay: Boolean;
|
SpecializeNeedsDelay: Boolean;
|
||||||
AssignSt: TJSSimpleAssignStatement;
|
AssignSt: TJSSimpleAssignStatement;
|
||||||
CallName, ArrName: String;
|
CallName, ArrName: String;
|
||||||
@ -15566,7 +15649,7 @@ begin
|
|||||||
writeln('TPasToJSConverter.ConvertArrayType ',GetObjName(El));
|
writeln('TPasToJSConverter.ConvertArrayType ',GetObjName(El));
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
Scope:=El.CustomData as TPasArrayScope;
|
Scope:=El.CustomData as TPas2JSArrayScope;
|
||||||
SpecializeNeedsDelay:=(Scope<>nil)
|
SpecializeNeedsDelay:=(Scope<>nil)
|
||||||
and (aResolver.SpecializeNeedsDelay(Scope.SpecializedFromItem)<>nil);
|
and (aResolver.SpecializeNeedsDelay(Scope.SpecializedFromItem)<>nil);
|
||||||
|
|
||||||
@ -16750,6 +16833,7 @@ begin
|
|||||||
if (C=TPasRecordType)
|
if (C=TPasRecordType)
|
||||||
or (C=TPasClassType) then
|
or (C=TPasClassType) then
|
||||||
begin
|
begin
|
||||||
|
if (C=TPasClassType) and TPasClassType(El).IsExternal then exit;
|
||||||
// pas.unitname.recordtype.$initSpec();
|
// pas.unitname.recordtype.$initSpec();
|
||||||
Path:=CreateReferencePath(El,AContext,rpkPathAndName)+'.'+GetBIName(pbifnClassInitSpecialize);
|
Path:=CreateReferencePath(El,AContext,rpkPathAndName)+'.'+GetBIName(pbifnClassInitSpecialize);
|
||||||
Call:=CreateCallExpression(El);
|
Call:=CreateCallExpression(El);
|
||||||
|
@ -47,6 +47,7 @@ type
|
|||||||
procedure TestGen_ExtClass_GenJSValueAssign;
|
procedure TestGen_ExtClass_GenJSValueAssign;
|
||||||
procedure TestGen_ExtClass_AliasMemberType;
|
procedure TestGen_ExtClass_AliasMemberType;
|
||||||
Procedure TestGen_ExtClass_RTTI;
|
Procedure TestGen_ExtClass_RTTI;
|
||||||
|
procedure TestGen_ExtClass_UnitImplRec;
|
||||||
|
|
||||||
// class interfaces
|
// class interfaces
|
||||||
procedure TestGen_ClassInterface_Corba;
|
procedure TestGen_ClassInterface_Corba;
|
||||||
@ -79,6 +80,8 @@ type
|
|||||||
procedure TestGen_ArrayOfUnitImplRec;
|
procedure TestGen_ArrayOfUnitImplRec;
|
||||||
|
|
||||||
// generic procedure type
|
// generic procedure type
|
||||||
|
procedure TestGen_ProcType_ProcLocal;
|
||||||
|
procedure TestGen_ProcType_ProcLocal_RTTI;
|
||||||
procedure TestGen_ProcType_ParamUnitImpl;
|
procedure TestGen_ProcType_ParamUnitImpl;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1324,6 +1327,70 @@ begin
|
|||||||
'']));
|
'']));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestGenerics.TestGen_ExtClass_UnitImplRec;
|
||||||
|
begin
|
||||||
|
WithTypeInfo:=true;
|
||||||
|
StartProgram(true,[supTObject]);
|
||||||
|
AddModuleWithIntfImplSrc('UnitA.pas',
|
||||||
|
LinesToStr([
|
||||||
|
'{$mode objfpc}',
|
||||||
|
'{$modeswitch externalclass}',
|
||||||
|
'type',
|
||||||
|
' generic TAnt<T> = class external name ''SET''',
|
||||||
|
' x: T;',
|
||||||
|
' end;',
|
||||||
|
'']),
|
||||||
|
LinesToStr([
|
||||||
|
'type',
|
||||||
|
' TBird = record',
|
||||||
|
' b: word;',
|
||||||
|
' end;',
|
||||||
|
'var',
|
||||||
|
' f: specialize TAnt<TBird>;',
|
||||||
|
'begin',
|
||||||
|
' f.x.b:=f.x.b+10;',
|
||||||
|
'']));
|
||||||
|
Add([
|
||||||
|
'uses UnitA;',
|
||||||
|
'begin',
|
||||||
|
'end.']);
|
||||||
|
ConvertProgram;
|
||||||
|
CheckUnit('UnitA.pas',
|
||||||
|
LinesToStr([ // statements
|
||||||
|
'rtl.module("UnitA", ["system"], function () {',
|
||||||
|
' var $mod = this;',
|
||||||
|
' var $impl = $mod.$impl;',
|
||||||
|
' $mod.$rtti.$ExtClass("TAnt$G1", {',
|
||||||
|
' jsclass: "SET"',
|
||||||
|
' });',
|
||||||
|
' $mod.$init = function () {',
|
||||||
|
' $impl.f.x.b = $impl.f.x.b + 10;',
|
||||||
|
' };',
|
||||||
|
'}, null, function () {',
|
||||||
|
' var $mod = this;',
|
||||||
|
' var $impl = $mod.$impl;',
|
||||||
|
' rtl.recNewT($impl, "TBird", function () {',
|
||||||
|
' this.b = 0;',
|
||||||
|
' this.$eq = function (b) {',
|
||||||
|
' return this.b === b.b;',
|
||||||
|
' };',
|
||||||
|
' this.$assign = function (s) {',
|
||||||
|
' this.b = s.b;',
|
||||||
|
' return this;',
|
||||||
|
' };',
|
||||||
|
' var $r = $mod.$rtti.$Record("TBird", {});',
|
||||||
|
' $r.addField("b", rtl.word);',
|
||||||
|
' });',
|
||||||
|
' $impl.f = null;',
|
||||||
|
'});']));
|
||||||
|
CheckSource('TestGen_Class_ClassVarRecord_UnitImpl',
|
||||||
|
LinesToStr([ // statements
|
||||||
|
//'pas.UnitA.TAnt$G1.$initSpec();',
|
||||||
|
'']),
|
||||||
|
LinesToStr([ // $mod.$main
|
||||||
|
'']));
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TTestGenerics.TestGen_ClassInterface_Corba;
|
procedure TTestGenerics.TestGen_ClassInterface_Corba;
|
||||||
begin
|
begin
|
||||||
StartProgram(false);
|
StartProgram(false);
|
||||||
@ -2044,6 +2111,61 @@ begin
|
|||||||
'']));
|
'']));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestGenerics.TestGen_ProcType_ProcLocal;
|
||||||
|
begin
|
||||||
|
StartProgram(false);
|
||||||
|
Add([
|
||||||
|
'procedure Fly(w: word);',
|
||||||
|
'begin',
|
||||||
|
'end;',
|
||||||
|
'procedure Run(w: word);',
|
||||||
|
'type generic TProc<T> = procedure(a: T);',
|
||||||
|
'var p: specialize TProc<word>;',
|
||||||
|
'begin',
|
||||||
|
' p:=@Fly;',
|
||||||
|
' p(w);',
|
||||||
|
'end;',
|
||||||
|
'begin',
|
||||||
|
'end.']);
|
||||||
|
ConvertProgram;
|
||||||
|
CheckSource('TestGen_ProcType_ProcLocal',
|
||||||
|
LinesToStr([ // statements
|
||||||
|
'this.Fly = function (w) {',
|
||||||
|
'};',
|
||||||
|
'this.Run = function (w) {',
|
||||||
|
' var p = null;',
|
||||||
|
' p = $mod.Fly;',
|
||||||
|
' p(w);',
|
||||||
|
'};',
|
||||||
|
'']),
|
||||||
|
LinesToStr([ // $mod.$main
|
||||||
|
'']));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestGenerics.TestGen_ProcType_ProcLocal_RTTI;
|
||||||
|
begin
|
||||||
|
WithTypeInfo:=true;
|
||||||
|
StartProgram(false);
|
||||||
|
Add([
|
||||||
|
'procedure Fly(w: word);',
|
||||||
|
'begin',
|
||||||
|
'end;',
|
||||||
|
'procedure Run(w: word);',
|
||||||
|
'type generic TProc<T> = procedure(a: T);',
|
||||||
|
'var',
|
||||||
|
' p: specialize TProc<word>;',
|
||||||
|
' t: Pointer;',
|
||||||
|
'begin',
|
||||||
|
' p:=@Fly;',
|
||||||
|
' p(w);',
|
||||||
|
' t:=typeinfo(p);',
|
||||||
|
'end;',
|
||||||
|
'begin',
|
||||||
|
'end.']);
|
||||||
|
SetExpectedPasResolverError(sSymbolCannotBePublished,nSymbolCannotBePublished);
|
||||||
|
ConvertProgram;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TTestGenerics.TestGen_ProcType_ParamUnitImpl;
|
procedure TTestGenerics.TestGen_ProcType_ParamUnitImpl;
|
||||||
begin
|
begin
|
||||||
WithTypeInfo:=true;
|
WithTypeInfo:=true;
|
||||||
|
Loading…
Reference in New Issue
Block a user