|
@@ -465,9 +465,14 @@ unit FPPas2Js;
|
|
interface
|
|
interface
|
|
|
|
|
|
uses
|
|
uses
|
|
|
|
+ {$ifdef pas2js}
|
|
|
|
+ js,
|
|
|
|
+ {$else}
|
|
|
|
+ AVL_Tree,
|
|
|
|
+ {$endif}
|
|
Classes, SysUtils, math, contnrs,
|
|
Classes, SysUtils, math, contnrs,
|
|
jsbase, jstree, jswriter,
|
|
jsbase, jstree, jswriter,
|
|
- PasTree, PScanner, PasResolveEval, PasResolver;
|
|
|
|
|
|
+ PasTree, PScanner, PasResolveEval, PasResolver, PasUseAnalyzer;
|
|
|
|
|
|
// message numbers
|
|
// message numbers
|
|
const
|
|
const
|
|
@@ -1372,6 +1377,15 @@ type
|
|
{ TPas2JSResolverHub }
|
|
{ TPas2JSResolverHub }
|
|
|
|
|
|
TPas2JSResolverHub = class(TPasResolverHub)
|
|
TPas2JSResolverHub = class(TPasResolverHub)
|
|
|
|
+ private
|
|
|
|
+ FJSSpecialized: TPasAnalyzerKeySet; // set of TPasGenericType
|
|
|
|
+ public
|
|
|
|
+ constructor Create(TheOwner: TObject); override;
|
|
|
|
+ destructor Destroy; override;
|
|
|
|
+ procedure Reset; override;
|
|
|
|
+ // delayed type specialization
|
|
|
|
+ procedure AddJSSpecialized(SpecType: TPasGenericType);
|
|
|
|
+ function IsJSSpecialized(SpecType: TPasGenericType): boolean;
|
|
end;
|
|
end;
|
|
|
|
|
|
{ TPas2JSResolver }
|
|
{ TPas2JSResolver }
|
|
@@ -1908,6 +1922,7 @@ type
|
|
Function CreateVarStatement(const aName: String; Init: TJSElement;
|
|
Function CreateVarStatement(const aName: String; Init: TJSElement;
|
|
El: TPasElement): TJSVariableStatement; virtual;
|
|
El: TPasElement): TJSVariableStatement; virtual;
|
|
Function CreateVarDecl(const aName: String; Init: TJSElement; El: TPasElement): TJSVarDeclaration; virtual;
|
|
Function CreateVarDecl(const aName: String; Init: TJSElement; El: TPasElement): TJSVarDeclaration; virtual;
|
|
|
|
+ Procedure InitJSSpecialization(aType: TPasType; AContext: TConvertContext; ErrorEl: TPasElement); virtual;
|
|
// JS literals
|
|
// JS literals
|
|
Function CreateLiteralNumber(El: TPasElement; const n: TJSNumber): TJSLiteral; virtual;
|
|
Function CreateLiteralNumber(El: TPasElement; const n: TJSNumber): TJSLiteral; virtual;
|
|
Function CreateLiteralHexNumber(El: TPasElement; const n: TMaxPrecInt; Digits: byte): TJSLiteral; virtual;
|
|
Function CreateLiteralHexNumber(El: TPasElement; const n: TMaxPrecInt; Digits: byte): TJSLiteral; virtual;
|
|
@@ -2317,6 +2332,36 @@ begin
|
|
Result:='['+Result+']';
|
|
Result:='['+Result+']';
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+{ TPas2JSResolverHub }
|
|
|
|
+
|
|
|
|
+constructor TPas2JSResolverHub.Create(TheOwner: TObject);
|
|
|
|
+begin
|
|
|
|
+ inherited Create(TheOwner);
|
|
|
|
+ FJSSpecialized:=CreatePasElementSet;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+destructor TPas2JSResolverHub.Destroy;
|
|
|
|
+begin
|
|
|
|
+ FreeAndNil(FJSSpecialized);
|
|
|
|
+ inherited Destroy;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TPas2JSResolverHub.Reset;
|
|
|
|
+begin
|
|
|
|
+ inherited Reset;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TPas2JSResolverHub.AddJSSpecialized(SpecType: TPasGenericType);
|
|
|
|
+begin
|
|
|
|
+ if FJSSpecialized.FindItem(SpecType)=nil then
|
|
|
|
+ FJSSpecialized.Add(SpecType,false);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TPas2JSResolverHub.IsJSSpecialized(SpecType: TPasGenericType): boolean;
|
|
|
|
+begin
|
|
|
|
+ Result:=FJSSpecialized.FindItem(SpecType)<>nil;
|
|
|
|
+end;
|
|
|
|
+
|
|
{ TPas2JSModuleScope }
|
|
{ TPas2JSModuleScope }
|
|
|
|
|
|
procedure TPas2JSModuleScope.SetJSPromiseClass(const AValue: TPasClassType);
|
|
procedure TPas2JSModuleScope.SetJSPromiseClass(const AValue: TPasClassType);
|
|
@@ -4918,32 +4963,44 @@ var
|
|
Param: TPasType;
|
|
Param: TPasType;
|
|
i: Integer;
|
|
i: Integer;
|
|
GenSection, ParamSection: TPasSection;
|
|
GenSection, ParamSection: TPasSection;
|
|
|
|
+ ParamResolver, GenResolver: TPasResolver;
|
|
begin
|
|
begin
|
|
Result:=nil;
|
|
Result:=nil;
|
|
|
|
+ {$IFNDEF EnableDelaySpecialize}
|
|
|
|
+ exit;
|
|
|
|
+ {$ENDIF}
|
|
Gen:=SpecializedItem.GenericEl;
|
|
Gen:=SpecializedItem.GenericEl;
|
|
GenSection:=GetParentSection(Gen);
|
|
GenSection:=GetParentSection(Gen);
|
|
if not (GenSection is TInterfaceSection) then
|
|
if not (GenSection is TInterfaceSection) then
|
|
- exit; // generic in unit implementation/program/library -> params cannot be defined a later section
|
|
|
|
- GenMod:=GenSection.GetModule;
|
|
|
|
|
|
+ exit; // generic in unit implementation/program/library -> params cannot be defined in a later section -> no delay needed
|
|
|
|
+ GenMod:=nil;
|
|
|
|
+ GenResolver:=nil;
|
|
|
|
|
|
Params:=SpecializedItem.Params;
|
|
Params:=SpecializedItem.Params;
|
|
for i:=0 to length(Params)-1 do
|
|
for i:=0 to length(Params)-1 do
|
|
begin
|
|
begin
|
|
Param:=ResolveAliasType(Params[i],false);
|
|
Param:=ResolveAliasType(Params[i],false);
|
|
if Param.ClassType=TPasUnresolvedSymbolRef then
|
|
if Param.ClassType=TPasUnresolvedSymbolRef then
|
|
- continue; // built-in type
|
|
|
|
|
|
+ continue; // built-in type -> no delay needed
|
|
ParamSection:=GetParentSection(Param);
|
|
ParamSection:=GetParentSection(Param);
|
|
- if ParamSection=GenSection then continue;
|
|
|
|
|
|
+ if ParamSection=GenSection then
|
|
|
|
+ continue; // same section -> no delay needed
|
|
// not in same section
|
|
// not in same section
|
|
ParamMod:=ParamSection.GetModule;
|
|
ParamMod:=ParamSection.GetModule;
|
|
|
|
+ if GenMod=nil then
|
|
|
|
+ GenMod:=GenSection.GetModule;
|
|
if ParamMod=GenMod then
|
|
if ParamMod=GenMod then
|
|
- exit(Param); // generic in unit interface, specialize in implementation
|
|
|
|
|
|
+ exit(Param); // generic in unit interface, param in implementation
|
|
// param in another unit
|
|
// param in another unit
|
|
if ParamSection is TImplementationSection then
|
|
if ParamSection is TImplementationSection then
|
|
- exit(Param); // generic in unit interface, specialize in another(later) implementation
|
|
|
|
|
|
+ exit(Param); // generic in unit interface, param in another implementation
|
|
// param in another unit interface
|
|
// param in another unit interface
|
|
-
|
|
|
|
- //xxx
|
|
|
|
|
|
+ if GenResolver=nil then
|
|
|
|
+ GenResolver:=GetResolver(GenMod);
|
|
|
|
+ ParamResolver:=GetResolver(ParamMod);
|
|
|
|
+ if ParamResolver.FinishedInterfaceIndex<GenResolver.FinishedInterfaceIndex then
|
|
|
|
+ exit(Param); // param in a later unit interface
|
|
|
|
+ // generic in a later unit interface -> no delay needed
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -14422,7 +14479,7 @@ begin
|
|
continue;
|
|
continue;
|
|
end
|
|
end
|
|
else if C=TPasAttributes then
|
|
else if C=TPasAttributes then
|
|
- // ToDo
|
|
|
|
|
|
+ continue
|
|
else
|
|
else
|
|
RaiseNotSupported(P as TPasElement,AContext,20161024191434);
|
|
RaiseNotSupported(P as TPasElement,AContext,20161024191434);
|
|
Add(E,P);
|
|
Add(E,P);
|
|
@@ -22545,6 +22602,53 @@ begin
|
|
Result.Init:=Init;
|
|
Result.Init:=Init;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+procedure TPasToJSConverter.InitJSSpecialization(aType: TPasType;
|
|
|
|
+ AContext: TConvertContext; ErrorEl: TPasElement);
|
|
|
|
+var
|
|
|
|
+ aResolver: TPas2JSResolver;
|
|
|
|
+ SpecTypeData: TPasSpecializeTypeData;
|
|
|
|
+ Hub: TPas2JSResolverHub;
|
|
|
|
+ SpecType: TPasGenericType;
|
|
|
|
+ C: TClass;
|
|
|
|
+ FuncCtx: TFunctionContext;
|
|
|
|
+ SrcEl: TJSSourceElements;
|
|
|
|
+begin
|
|
|
|
+ while aType<>nil do
|
|
|
|
+ begin
|
|
|
|
+ C:=aType.ClassType;
|
|
|
|
+ if C=TPasAliasType then
|
|
|
|
+ aType:=TPasAliasType(aType).DestType
|
|
|
|
+ else if C=TPasSpecializeType then
|
|
|
|
+ begin
|
|
|
|
+ // specialized type
|
|
|
|
+ SpecTypeData:=aType.CustomData as TPasSpecializeTypeData;
|
|
|
|
+ if SpecTypeData=nil then
|
|
|
|
+ RaiseNotSupported(aType,AContext,20200815210904);
|
|
|
|
+ aResolver:=AContext.Resolver;
|
|
|
|
+ Hub:=TPas2JSResolverHub(aResolver.Hub);
|
|
|
|
+ SpecType:=SpecTypeData.SpecializedType;
|
|
|
|
+ if Hub.IsJSSpecialized(SpecType) then exit;
|
|
|
|
+ Hub.AddJSSpecialized(SpecType);
|
|
|
|
+ FuncCtx:=AContext.GetGlobalFunc;
|
|
|
|
+ SrcEl:=FuncCtx.JSElement as TJSSourceElements;
|
|
|
|
+
|
|
|
|
+ if SrcEl=nil then ;
|
|
|
|
+
|
|
|
|
+ if SpecType is TPasRecordType then
|
|
|
|
+ begin
|
|
|
|
+ // add $mod.TAnt$G1();
|
|
|
|
+ //CreateReferencePath();
|
|
|
|
+ RaiseNotSupported(ErrorEl,AContext,20200815215652);
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ RaiseNotSupported(ErrorEl,AContext,20200815215338);
|
|
|
|
+ exit;
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ exit;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
function TPasToJSConverter.CreateLiteralNumber(El: TPasElement;
|
|
function TPasToJSConverter.CreateLiteralNumber(El: TPasElement;
|
|
const n: TJSNumber): TJSLiteral;
|
|
const n: TJSNumber): TJSLiteral;
|
|
begin
|
|
begin
|
|
@@ -24639,6 +24743,7 @@ var
|
|
ok, IsFull: Boolean;
|
|
ok, IsFull: Boolean;
|
|
VarSt: TJSVariableStatement;
|
|
VarSt: TJSVariableStatement;
|
|
bifn: TPas2JSBuiltInName;
|
|
bifn: TPas2JSBuiltInName;
|
|
|
|
+ RecScope: TPas2JSRecordScope;
|
|
begin
|
|
begin
|
|
Result:=nil;
|
|
Result:=nil;
|
|
if El.Name='' then
|
|
if El.Name='' then
|
|
@@ -24657,14 +24762,14 @@ begin
|
|
// rtl.recNewT()
|
|
// rtl.recNewT()
|
|
Call:=CreateCallExpression(El);
|
|
Call:=CreateCallExpression(El);
|
|
bifn:=pbifnRecordCreateType;
|
|
bifn:=pbifnRecordCreateType;
|
|
- {$IFDEF EnableDelaySpecialize}
|
|
|
|
|
|
+
|
|
RecScope:=TPas2JSRecordScope(El.CustomData);
|
|
RecScope:=TPas2JSRecordScope(El.CustomData);
|
|
if RecScope.SpecializedFromItem<>nil then
|
|
if RecScope.SpecializedFromItem<>nil then
|
|
begin
|
|
begin
|
|
- if RecScope.SpecializedFromItem.FirstSpecialize.GetModule<>EL.GetModule then
|
|
|
|
- bifn:=pbifnRecordCreateSpecializeType;
|
|
|
|
|
|
+ // ToDo
|
|
|
|
+ //if aResolver.SpecializeNeedsDelay(RecScope.SpecializedFromItem)<>nil then
|
|
|
|
+ //bifn:=pbifnRecordCreateSpecializeType;
|
|
end;
|
|
end;
|
|
- {$ENDIF}
|
|
|
|
|
|
|
|
Call.Expr:=CreateMemberExpression([GetBIName(pbivnRTL),GetBIName(bifn)]);
|
|
Call.Expr:=CreateMemberExpression([GetBIName(pbivnRTL),GetBIName(bifn)]);
|
|
|
|
|