mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-18 04:49:20 +02:00
pastojs: jsglobalalias: references to elements from implementation uses
git-svn-id: trunk@46847 -
This commit is contained in:
parent
aed1866db9
commit
af7008ee2f
@ -1730,12 +1730,22 @@ type
|
|||||||
|
|
||||||
{ TSectionContext - interface/implementation/program/library
|
{ TSectionContext - interface/implementation/program/library
|
||||||
interface/program/library: PasElement is TPasModule, ThisPas is TPasModule
|
interface/program/library: PasElement is TPasModule, ThisPas is TPasModule
|
||||||
implementation: PasElement is TImplementationSection, ThisPas is TPasModule }
|
implementation: PasElement is TImplementationSection, ThisPas=nil }
|
||||||
|
|
||||||
TSectionContext = Class(TFunctionContext)
|
TSectionContext = Class(TFunctionContext)
|
||||||
public
|
public
|
||||||
|
SrcElements: TJSSourceElements;
|
||||||
HeaderIndex: integer; // index in TJSSourceElements(JSElement).Statements
|
HeaderIndex: integer; // index in TJSSourceElements(JSElement).Statements
|
||||||
constructor Create(PasEl: TPasElement; JSEl: TJSElement; aParent: TConvertContext); override;
|
constructor Create(PasEl: TPasElement; JSEl: TJSElement; aParent: TConvertContext); override;
|
||||||
|
procedure AddHeaderStatement(JS: TJSElement);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TInterfaceSectionContext }
|
||||||
|
|
||||||
|
TInterfaceSectionContext = Class(TSectionContext)
|
||||||
|
public
|
||||||
|
ImplHeaderStatements: TFPList;
|
||||||
|
destructor Destroy; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TDotContext - used for converting eopSubIdent }
|
{ TDotContext - used for converting eopSubIdent }
|
||||||
@ -1984,9 +1994,10 @@ type
|
|||||||
Full: boolean = false; Ref: TResolvedReference = nil): TJSElement; virtual;
|
Full: boolean = false; Ref: TResolvedReference = nil): TJSElement; virtual;
|
||||||
Function CreateGlobalTypePath(El: TPasType; AContext : TConvertContext): string; virtual;
|
Function CreateGlobalTypePath(El: TPasType; AContext : TConvertContext): string; virtual;
|
||||||
// section
|
// section
|
||||||
Function CreateImplementationSection(El: TPasModule; AContext: TConvertContext): TJSFunctionDeclarationStatement; virtual;
|
Function CreateImplementationSection(El: TPasModule; AContext: TInterfaceSectionContext): TJSFunctionDeclarationStatement; virtual;
|
||||||
Procedure CreateInitSection(El: TPasModule; Src: TJSSourceElements; AContext: TConvertContext); virtual;
|
Procedure CreateInitSection(El: TPasModule; Src: TJSSourceElements; AContext: TConvertContext); virtual;
|
||||||
Procedure AddHeaderStatement(JS: TJSElement; PosEl: TPasElement; aContext: TConvertContext); virtual;
|
Procedure AddHeaderStatement(JS: TJSElement; PosEl: TPasElement; aContext: TConvertContext); virtual;
|
||||||
|
Procedure AddImplHeaderStatement(JS: TJSElement; PosEl: TPasElement; aContext: TConvertContext); virtual;
|
||||||
Procedure AddDelayedInits(El: TPasProgram; Src: TJSSourceElements; AContext: TConvertContext); virtual;
|
Procedure AddDelayedInits(El: TPasProgram; Src: TJSSourceElements; AContext: TConvertContext); virtual;
|
||||||
Procedure AddDelaySpecializeInit(El: TPasGenericType; Src: TJSSourceElements; AContext: TConvertContext); virtual;
|
Procedure AddDelaySpecializeInit(El: TPasGenericType; Src: TJSSourceElements; AContext: TConvertContext); virtual;
|
||||||
// set
|
// set
|
||||||
@ -2367,6 +2378,21 @@ begin
|
|||||||
Result:='['+Result+']';
|
Result:='['+Result+']';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TInterfaceSectionContext }
|
||||||
|
|
||||||
|
destructor TInterfaceSectionContext.Destroy;
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
if ImplHeaderStatements<>nil then
|
||||||
|
begin
|
||||||
|
for i:=0 to ImplHeaderStatements.Count-1 do
|
||||||
|
TJSElement(ImplHeaderStatements[i]).Free;
|
||||||
|
FreeAndNil(ImplHeaderStatements);
|
||||||
|
end;
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TPas2JSResolverHub }
|
{ TPas2JSResolverHub }
|
||||||
|
|
||||||
function TPas2JSResolverHub.GetJSDelaySpecializes(Index: integer
|
function TPas2JSResolverHub.GetJSDelaySpecializes(Index: integer
|
||||||
@ -7138,6 +7164,14 @@ constructor TSectionContext.Create(PasEl: TPasElement; JSEl: TJSElement;
|
|||||||
begin
|
begin
|
||||||
inherited;
|
inherited;
|
||||||
IsGlobal:=true;
|
IsGlobal:=true;
|
||||||
|
SrcElements:=JSEl as TJSSourceElements;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSectionContext.AddHeaderStatement(JS: TJSElement);
|
||||||
|
begin
|
||||||
|
if JS=nil then exit;
|
||||||
|
SrcElements.Statements.InsertNode(HeaderIndex).Node:=JS;
|
||||||
|
inc(HeaderIndex);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TFunctionContext }
|
{ TFunctionContext }
|
||||||
@ -7697,6 +7731,9 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
ImplVarSt:=nil;
|
ImplVarSt:=nil;
|
||||||
|
if El.ClassType=TPasModule then
|
||||||
|
IntfContext:=TInterfaceSectionContext.Create(El,Src,AContext)
|
||||||
|
else
|
||||||
IntfContext:=TSectionContext.Create(El,Src,AContext);
|
IntfContext:=TSectionContext.Create(El,Src,AContext);
|
||||||
try
|
try
|
||||||
// add "var $mod = this;"
|
// add "var $mod = this;"
|
||||||
@ -7738,7 +7775,7 @@ begin
|
|||||||
if Assigned(El.InterfaceSection) then
|
if Assigned(El.InterfaceSection) then
|
||||||
AddToSourceElements(Src,ConvertDeclarations(El.InterfaceSection,IntfContext));
|
AddToSourceElements(Src,ConvertDeclarations(El.InterfaceSection,IntfContext));
|
||||||
|
|
||||||
ImplFunc:=CreateImplementationSection(El,IntfContext);
|
ImplFunc:=CreateImplementationSection(El,TInterfaceSectionContext(IntfContext));
|
||||||
if ImplFunc=nil then
|
if ImplFunc=nil then
|
||||||
begin
|
begin
|
||||||
// remove unneeded $impl from interface
|
// remove unneeded $impl from interface
|
||||||
@ -16734,15 +16771,16 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function TPasToJSConverter.CreateImplementationSection(El: TPasModule;
|
function TPasToJSConverter.CreateImplementationSection(El: TPasModule;
|
||||||
AContext: TConvertContext
|
AContext: TInterfaceSectionContext): TJSFunctionDeclarationStatement;
|
||||||
): TJSFunctionDeclarationStatement;
|
|
||||||
var
|
var
|
||||||
Src: TJSSourceElements;
|
Src: TJSSourceElements;
|
||||||
ImplContext: TSectionContext;
|
ImplContext: TSectionContext;
|
||||||
ImplDecl: TJSElement;
|
ImplDecl, JS: TJSElement;
|
||||||
FunDecl: TJSFunctionDeclarationStatement;
|
FunDecl: TJSFunctionDeclarationStatement;
|
||||||
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
Result:=nil;
|
Result:=nil;
|
||||||
|
|
||||||
// create function(){}
|
// create function(){}
|
||||||
FunDecl:=CreateFunctionSt(El.ImplementationSection,true,true);
|
FunDecl:=CreateFunctionSt(El.ImplementationSection,true,true);
|
||||||
Src:=TJSSourceElements(FunDecl.AFunction.Body.A);
|
Src:=TJSSourceElements(FunDecl.AFunction.Body.A);
|
||||||
@ -16750,7 +16788,21 @@ begin
|
|||||||
// create section context (a function)
|
// create section context (a function)
|
||||||
ImplContext:=TSectionContext.Create(El.ImplementationSection,Src,AContext);
|
ImplContext:=TSectionContext.Create(El.ImplementationSection,Src,AContext);
|
||||||
try
|
try
|
||||||
// ToDo: ImplContext.ThisPas:=El;
|
// ToDo: IntfContext.ThisPas:=El;
|
||||||
|
// ToDo: IntfContext.ThisKind:=cctkGlobal;
|
||||||
|
|
||||||
|
// add pending impl header statements
|
||||||
|
if AContext.ImplHeaderStatements<>nil then
|
||||||
|
begin
|
||||||
|
for i:=0 to AContext.ImplHeaderStatements.Count-1 do
|
||||||
|
begin
|
||||||
|
JS:=TJSElement(AContext.ImplHeaderStatements[i]);
|
||||||
|
ImplContext.AddHeaderStatement(JS);
|
||||||
|
AContext.ImplHeaderStatements[i]:=nil;
|
||||||
|
end;
|
||||||
|
FreeAndNil(AContext.ImplHeaderStatements);
|
||||||
|
end;
|
||||||
|
|
||||||
// create implementation declarations
|
// create implementation declarations
|
||||||
ImplDecl:=ConvertDeclarations(El.ImplementationSection,ImplContext);
|
ImplDecl:=ConvertDeclarations(El.ImplementationSection,ImplContext);
|
||||||
if ImplDecl<>nil then
|
if ImplDecl<>nil then
|
||||||
@ -16784,14 +16836,38 @@ procedure TPasToJSConverter.AddHeaderStatement(JS: TJSElement;
|
|||||||
PosEl: TPasElement; aContext: TConvertContext);
|
PosEl: TPasElement; aContext: TConvertContext);
|
||||||
var
|
var
|
||||||
SectionCtx: TSectionContext;
|
SectionCtx: TSectionContext;
|
||||||
Src: TJSSourceElements;
|
|
||||||
begin
|
begin
|
||||||
|
if JS=nil then exit;
|
||||||
SectionCtx:=TSectionContext(aContext.GetContextOfType(TSectionContext));
|
SectionCtx:=TSectionContext(aContext.GetContextOfType(TSectionContext));
|
||||||
if SectionCtx=nil then
|
if SectionCtx=nil then
|
||||||
RaiseNotSupported(PosEl,aContext,20200606142555);
|
RaiseNotSupported(PosEl,aContext,20200606142555);
|
||||||
Src:=SectionCtx.JSElement as TJSSourceElements;
|
if SectionCtx.Parent is TSectionContext then
|
||||||
Src.Statements.InsertNode(SectionCtx.HeaderIndex).Node:=JS;
|
SectionCtx:=TSectionContext(SectionCtx.Parent);
|
||||||
inc(SectionCtx.HeaderIndex);
|
SectionCtx.AddHeaderStatement(JS);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TPasToJSConverter.AddImplHeaderStatement(JS: TJSElement;
|
||||||
|
PosEl: TPasElement; aContext: TConvertContext);
|
||||||
|
var
|
||||||
|
SectionCtx: TSectionContext;
|
||||||
|
IntfSec: TInterfaceSectionContext;
|
||||||
|
begin
|
||||||
|
if JS=nil then exit;
|
||||||
|
SectionCtx:=TSectionContext(aContext.GetContextOfType(TSectionContext));
|
||||||
|
if SectionCtx=nil then
|
||||||
|
RaiseNotSupported(PosEl,aContext,20200606142555);
|
||||||
|
if SectionCtx.PasElement is TImplementationSection then
|
||||||
|
SectionCtx.AddHeaderStatement(JS)
|
||||||
|
else if SectionCtx is TInterfaceSectionContext then
|
||||||
|
begin
|
||||||
|
// add pending impl header statement
|
||||||
|
IntfSec:=TInterfaceSectionContext(SectionCtx);
|
||||||
|
if IntfSec.ImplHeaderStatements=nil then
|
||||||
|
IntfSec.ImplHeaderStatements:=TFPList.Create;
|
||||||
|
IntfSec.ImplHeaderStatements.Add(JS);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
RaiseNotSupported(PosEl,aContext,20200911165632);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TPasToJSConverter.AddDelayedInits(El: TPasProgram;
|
procedure TPasToJSConverter.AddDelayedInits(El: TPasProgram;
|
||||||
@ -25724,6 +25800,7 @@ var
|
|||||||
FuncContext: TFunctionContext;
|
FuncContext: TFunctionContext;
|
||||||
Expr: TJSElement;
|
Expr: TJSElement;
|
||||||
V: TJSVariableStatement;
|
V: TJSVariableStatement;
|
||||||
|
AssignSt: TJSSimpleAssignStatement;
|
||||||
begin
|
begin
|
||||||
Result:=JSPath;
|
Result:=JSPath;
|
||||||
if El is TPasUnresolvedSymbolRef then
|
if El is TPasUnresolvedSymbolRef then
|
||||||
@ -25753,11 +25830,27 @@ begin
|
|||||||
RaiseNotSupported(El,AContext,20200608160225);
|
RaiseNotSupported(El,AContext,20200608160225);
|
||||||
Result:=FuncContext.CreateLocalIdentifier(Result);
|
Result:=FuncContext.CreateLocalIdentifier(Result);
|
||||||
SectionContext.AddLocalVar(Result,El,false);
|
SectionContext.AddLocalVar(Result,El,false);
|
||||||
// insert var $lmr = JSPath;
|
|
||||||
|
// ToDo: check if from a unit used by impl uses section
|
||||||
|
if aResolver.ImplementationUsesUnit(ElModule) then
|
||||||
|
begin
|
||||||
|
// insert var $lm = null;
|
||||||
|
Expr:=CreateLiteralNull(El);
|
||||||
|
V:=CreateVarStatement(Result,Expr,El);
|
||||||
|
AddHeaderStatement(V,El,SectionContext);
|
||||||
|
// insert impl $lm = JSPath;
|
||||||
|
AssignSt:=TJSSimpleAssignStatement(CreateElement(TJSSimpleAssignStatement,El));
|
||||||
|
AssignSt.LHS:=CreatePrimitiveDotExpr(Result,El);
|
||||||
|
AssignSt.Expr:=CreatePrimitiveDotExpr(JSPath,El);
|
||||||
|
AddImplHeaderStatement(AssignSt,El,AContext);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
// insert var $lm = JSPath;
|
||||||
Expr:=CreatePrimitiveDotExpr(JSPath,El);
|
Expr:=CreatePrimitiveDotExpr(JSPath,El);
|
||||||
V:=CreateVarStatement(Result,Expr,El);
|
V:=CreateVarStatement(Result,Expr,El);
|
||||||
AddHeaderStatement(V,El,SectionContext);
|
AddHeaderStatement(V,El,SectionContext);
|
||||||
// ToDo: check if from impl uses section and separate "var $lmr = null;" and "$lmr = JSPath";
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -356,9 +356,9 @@ begin
|
|||||||
'var $impl = $mod.$impl;',
|
'var $impl = $mod.$impl;',
|
||||||
'var $lm = pas.UnitA;',
|
'var $lm = pas.UnitA;',
|
||||||
'var $lt = $lm.TBird;',
|
'var $lt = $lm.TBird;',
|
||||||
'var $lm1 = pas.UnitB;',
|
'var $lm1 = null;',
|
||||||
'var $lt1 = $lm1.TAnt;',
|
'var $lt1 = null;',
|
||||||
'var $lt2 = $lm1.TBear;',
|
'var $lt2 = null;',
|
||||||
'rtl.createClass($mod, "TEagle", $lt, function () {',
|
'rtl.createClass($mod, "TEagle", $lt, function () {',
|
||||||
' this.Fly = function () {',
|
' this.Fly = function () {',
|
||||||
' $impl.TRedAnt.$create("Create");',
|
' $impl.TRedAnt.$create("Create");',
|
||||||
@ -377,6 +377,9 @@ begin
|
|||||||
'$impl.RedAnt.Run();',
|
'$impl.RedAnt.Run();',
|
||||||
'']),
|
'']),
|
||||||
LinesToStr([
|
LinesToStr([
|
||||||
|
'$lm1 = pas.UnitB;',
|
||||||
|
'$lt1 = $lm1.TAnt;',
|
||||||
|
'$lt2 = $lm1.TBear;',
|
||||||
'rtl.createClass($impl, "TRedAnt", $lt1, function () {',
|
'rtl.createClass($impl, "TRedAnt", $lt1, function () {',
|
||||||
' this.Run = function () {',
|
' this.Run = function () {',
|
||||||
' $impl.TRedAnt.$create("Create");',
|
' $impl.TRedAnt.$create("Create");',
|
||||||
|
Loading…
Reference in New Issue
Block a user