mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-13 12:39:09 +02:00
pastojs: library added rtl.run, moved exports behind rtl.run, fixed export unit symbols
This commit is contained in:
parent
568d4de77e
commit
621dcbeaf2
@ -1014,7 +1014,7 @@ Type
|
|||||||
function GetNamedExports: TJSExportNameElements;
|
function GetNamedExports: TJSExportNameElements;
|
||||||
Public
|
Public
|
||||||
Destructor Destroy; override;
|
Destructor Destroy; override;
|
||||||
Property IsDefault : Boolean Read FIsDefault Write FIsDefault;
|
Property IsDefault : Boolean Read FIsDefault Write FIsDefault; // write *
|
||||||
Property Declaration : TJSElement Read FDeclaration Write FDeclaration;
|
Property Declaration : TJSElement Read FDeclaration Write FDeclaration;
|
||||||
Property NameSpaceExport : TJSString Read FNameSpaceExport Write FNameSpaceExport;
|
Property NameSpaceExport : TJSString Read FNameSpaceExport Write FNameSpaceExport;
|
||||||
Property ModuleName : TJSString Read FModuleName Write FModuleName;
|
Property ModuleName : TJSString Read FModuleName Write FModuleName;
|
||||||
|
@ -282,6 +282,7 @@ type
|
|||||||
procedure UseVariable(El: TPasVariable; Access: TResolvedRefAccess;
|
procedure UseVariable(El: TPasVariable; Access: TResolvedRefAccess;
|
||||||
UseFull: boolean); virtual;
|
UseFull: boolean); virtual;
|
||||||
procedure UseResourcestring(El: TPasResString); virtual;
|
procedure UseResourcestring(El: TPasResString); virtual;
|
||||||
|
procedure UseExportSymbol(El: TPasExportSymbol); virtual;
|
||||||
procedure UseArgument(El: TPasArgument; Access: TResolvedRefAccess); virtual;
|
procedure UseArgument(El: TPasArgument; Access: TResolvedRefAccess); virtual;
|
||||||
procedure UseResultElement(El: TPasResultElement; Access: TResolvedRefAccess); virtual;
|
procedure UseResultElement(El: TPasResultElement; Access: TResolvedRefAccess); virtual;
|
||||||
// create hints for a unit, program or library
|
// create hints for a unit, program or library
|
||||||
@ -1467,6 +1468,8 @@ begin
|
|||||||
end
|
end
|
||||||
else if C=TPasAttributes then
|
else if C=TPasAttributes then
|
||||||
// attributes are never used directly
|
// attributes are never used directly
|
||||||
|
else if C=TPasExportSymbol then
|
||||||
|
UseExportSymbol(TPasExportSymbol(Decl))
|
||||||
else
|
else
|
||||||
RaiseNotSupported(20170306165213,Decl);
|
RaiseNotSupported(20170306165213,Decl);
|
||||||
end;
|
end;
|
||||||
@ -2622,6 +2625,24 @@ begin
|
|||||||
UseExpr(El.Expr);
|
UseExpr(El.Expr);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TPasAnalyzer.UseExportSymbol(El: TPasExportSymbol);
|
||||||
|
var
|
||||||
|
Ref: TResolvedReference;
|
||||||
|
Decl: TPasElement;
|
||||||
|
begin
|
||||||
|
if not MarkElementAsUsed(El) then exit;
|
||||||
|
if El.CustomData is TResolvedReference then
|
||||||
|
begin
|
||||||
|
Ref:=TResolvedReference(El.CustomData);
|
||||||
|
Decl:=Ref.Declaration;
|
||||||
|
if Decl<>nil then
|
||||||
|
UseElement(Decl,Ref.Access,false);
|
||||||
|
end;
|
||||||
|
UseExpr(El.NameExpr);
|
||||||
|
UseExpr(El.ExportName);
|
||||||
|
UseExpr(El.ExportIndex);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TPasAnalyzer.UseArgument(El: TPasArgument; Access: TResolvedRefAccess
|
procedure TPasAnalyzer.UseArgument(El: TPasArgument; Access: TResolvedRefAccess
|
||||||
);
|
);
|
||||||
var
|
var
|
||||||
|
@ -2097,6 +2097,7 @@ type
|
|||||||
Function CreateImplementationSection(El: TPasModule; IntfContext: TInterfaceSectionContext): TJSFunctionDeclarationStatement; virtual;
|
Function CreateImplementationSection(El: TPasModule; IntfContext: TInterfaceSectionContext): TJSFunctionDeclarationStatement; virtual;
|
||||||
Procedure CreateInitSection(El: TPasModule; Src: TJSSourceElements; AContext: TConvertContext); virtual;
|
Procedure CreateInitSection(El: TPasModule; Src: TJSSourceElements; AContext: TConvertContext); virtual;
|
||||||
Procedure CreateExportsSection(El: TPasLibrary; Src: TJSSourceElements; AContext: TConvertContext); virtual;
|
Procedure CreateExportsSection(El: TPasLibrary; Src: TJSSourceElements; AContext: TConvertContext); virtual;
|
||||||
|
Function AddLibraryRun(El: TPasLibrary; ModuleName: string; Src: TJSSourceElements; AContext: TConvertContext): TJSCallExpression; 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 AddImplHeaderStatement(JS: TJSElement; PosEl: TPasElement; aContext: TConvertContext); virtual;
|
||||||
function AddDelayedInits(El: TPasModule; Src: TJSSourceElements; AContext: TConvertContext): boolean; virtual;
|
function AddDelayedInits(El: TPasModule; Src: TJSSourceElements; AContext: TConvertContext): boolean; virtual;
|
||||||
@ -8207,7 +8208,10 @@ Library:
|
|||||||
<initialization>
|
<initialization>
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
export1 = pas.unit1.func1;
|
rtl.run('library');
|
||||||
|
var li = pas['library'];
|
||||||
|
export const func1 = pas.unit1.func1;
|
||||||
|
export const var1 = li.var1;
|
||||||
|
|
||||||
Unit without implementation:
|
Unit without implementation:
|
||||||
rtl.module('<unitname>',
|
rtl.module('<unitname>',
|
||||||
@ -8337,7 +8341,6 @@ begin
|
|||||||
if Assigned(Lib.LibrarySection) then
|
if Assigned(Lib.LibrarySection) then
|
||||||
AddToSourceElements(Src,ConvertDeclarations(Lib.LibrarySection,IntfContext));
|
AddToSourceElements(Src,ConvertDeclarations(Lib.LibrarySection,IntfContext));
|
||||||
HasImplCode:=AddDelayedInits(Lib,Src,IntfContext);
|
HasImplCode:=AddDelayedInits(Lib,Src,IntfContext);
|
||||||
CreateExportsSection(Lib,Src,IntfContext);
|
|
||||||
CreateInitSection(Lib,Src,IntfContext);
|
CreateInitSection(Lib,Src,IntfContext);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -8387,6 +8390,14 @@ begin
|
|||||||
|
|
||||||
if (ModScope<>nil) and (coStoreImplJS in Options) then
|
if (ModScope<>nil) and (coStoreImplJS in Options) then
|
||||||
StoreImplJSLocals(ModScope,IntfContext);
|
StoreImplJSLocals(ModScope,IntfContext);
|
||||||
|
|
||||||
|
if El is TPasLibrary then
|
||||||
|
begin // library
|
||||||
|
Lib:=TPasLibrary(El);
|
||||||
|
AddLibraryRun(Lib,ModuleName,OuterSrc,AContext);
|
||||||
|
CreateExportsSection(Lib,OuterSrc,AContext);
|
||||||
|
end;
|
||||||
|
|
||||||
ok:=true;
|
ok:=true;
|
||||||
finally
|
finally
|
||||||
IntfContext.Free;
|
IntfContext.Free;
|
||||||
@ -18096,6 +18107,24 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TPasToJSConverter.AddLibraryRun(El: TPasLibrary; ModuleName: string;
|
||||||
|
Src: TJSSourceElements; AContext: TConvertContext): TJSCallExpression;
|
||||||
|
var
|
||||||
|
Call: TJSCallExpression;
|
||||||
|
begin
|
||||||
|
if AContext=nil then ;
|
||||||
|
|
||||||
|
// add rtl.run('library');
|
||||||
|
Call:=CreateCallExpression(El);
|
||||||
|
AddToSourceElements(Src,Call);
|
||||||
|
Call.Expr:=CreateMemberExpression([GetBIName(pbivnRTL),'run']);
|
||||||
|
|
||||||
|
// add module name parameter
|
||||||
|
Call.AddArg(CreateLiteralString(El,ModuleName));
|
||||||
|
|
||||||
|
Result:=Call;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TPasToJSConverter.AddHeaderStatement(JS: TJSElement;
|
procedure TPasToJSConverter.AddHeaderStatement(JS: TJSElement;
|
||||||
PosEl: TPasElement; aContext: TConvertContext);
|
PosEl: TPasElement; aContext: TConvertContext);
|
||||||
var
|
var
|
||||||
|
@ -179,6 +179,7 @@ type
|
|||||||
function GetDottedIdentifier(El: TJSElement): string;
|
function GetDottedIdentifier(El: TJSElement): string;
|
||||||
procedure CheckSource(Msg,Statements: String; InitStatements: string = '';
|
procedure CheckSource(Msg,Statements: String; InitStatements: string = '';
|
||||||
ImplStatements: string = ''); virtual;
|
ImplStatements: string = ''); virtual;
|
||||||
|
procedure CheckFullSource(Msg,ExpectedSrc: String); virtual;
|
||||||
procedure CheckDiff(Msg, Expected, Actual: string); virtual;
|
procedure CheckDiff(Msg, Expected, Actual: string); virtual;
|
||||||
procedure CheckUnit(Filename, ExpectedSrc: string); virtual;
|
procedure CheckUnit(Filename, ExpectedSrc: string); virtual;
|
||||||
procedure CheckHint(MsgType: TMessageType; MsgNumber: integer;
|
procedure CheckHint(MsgType: TMessageType; MsgNumber: integer;
|
||||||
@ -919,9 +920,9 @@ type
|
|||||||
Procedure TestLibrary_Export_Index_Fail;
|
Procedure TestLibrary_Export_Index_Fail;
|
||||||
Procedure TestLibrary_ExportVar;
|
Procedure TestLibrary_ExportVar;
|
||||||
Procedure TestLibrary_ExportUnitFunc;
|
Procedure TestLibrary_ExportUnitFunc;
|
||||||
// todo: test fail on export overloaded function
|
|
||||||
// ToDo: test delayed specialization init
|
// ToDo: test delayed specialization init
|
||||||
// ToDo: analyzer
|
// ToDo: analyzer
|
||||||
|
// ToDo: shortrefoptimization
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function LinesToStr(Args: array of const): string;
|
function LinesToStr(Args: array of const): string;
|
||||||
@ -1989,7 +1990,7 @@ var
|
|||||||
InitFunction: TJSFunctionDeclarationStatement;
|
InitFunction: TJSFunctionDeclarationStatement;
|
||||||
InitAssign: TJSSimpleAssignStatement;
|
InitAssign: TJSSimpleAssignStatement;
|
||||||
InitName: String;
|
InitName: String;
|
||||||
LastNode: TJSElement;
|
LastNode, FirstNode: TJSElement;
|
||||||
Arg: TJSArrayLiteralElement;
|
Arg: TJSArrayLiteralElement;
|
||||||
IsProg, IsLib: Boolean;
|
IsProg, IsLib: Boolean;
|
||||||
begin
|
begin
|
||||||
@ -2020,10 +2021,12 @@ begin
|
|||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
// rtl.module(...
|
// rtl.module(...
|
||||||
AssertEquals('jsmodule has one statement - the call',1,JSModule.Statements.Count);
|
if JSModule.Statements.Count<1 then
|
||||||
AssertNotNull('register module call',JSModule.Statements.Nodes[0].Node);
|
AssertEquals('jsmodule has at least one statement - the call',1,JSModule.Statements.Count);
|
||||||
AssertEquals('register module call',TJSCallExpression,JSModule.Statements.Nodes[0].Node.ClassType);
|
FirstNode:=JSModule.Statements.Nodes[0].Node;
|
||||||
FJSRegModuleCall:=JSModule.Statements.Nodes[0].Node as TJSCallExpression;
|
AssertNotNull('register module call',FirstNode);
|
||||||
|
AssertEquals('register module call',TJSCallExpression,FirstNode.ClassType);
|
||||||
|
FJSRegModuleCall:=FirstNode as TJSCallExpression;
|
||||||
AssertNotNull('register module rtl.module expr',JSRegModuleCall.Expr);
|
AssertNotNull('register module rtl.module expr',JSRegModuleCall.Expr);
|
||||||
AssertNotNull('register module rtl.module args',JSRegModuleCall.Args);
|
AssertNotNull('register module rtl.module args',JSRegModuleCall.Args);
|
||||||
AssertEquals('rtl.module args',TJSArguments,JSRegModuleCall.Args.ClassType);
|
AssertEquals('rtl.module args',TJSArguments,JSRegModuleCall.Args.ClassType);
|
||||||
@ -2037,11 +2040,17 @@ begin
|
|||||||
ModuleNameExpr:=Arg.Expr as TJSLiteral;
|
ModuleNameExpr:=Arg.Expr as TJSLiteral;
|
||||||
AssertEquals('module name param is string',ord(jstString),ord(ModuleNameExpr.Value.ValueType));
|
AssertEquals('module name param is string',ord(jstString),ord(ModuleNameExpr.Value.ValueType));
|
||||||
if IsProg then
|
if IsProg then
|
||||||
AssertEquals('module name','program',String(ModuleNameExpr.Value.AsString))
|
begin
|
||||||
|
AssertEquals('module name','program',String(ModuleNameExpr.Value.AsString));
|
||||||
|
AssertEquals('jsmodule has one statement - the call',1,JSModule.Statements.Count);
|
||||||
|
end
|
||||||
else if IsLib then
|
else if IsLib then
|
||||||
AssertEquals('module name','library',String(ModuleNameExpr.Value.AsString))
|
AssertEquals('module name','library',String(ModuleNameExpr.Value.AsString))
|
||||||
else
|
else
|
||||||
|
begin
|
||||||
AssertEquals('module name',Module.Name,String(ModuleNameExpr.Value.AsString));
|
AssertEquals('module name',Module.Name,String(ModuleNameExpr.Value.AsString));
|
||||||
|
AssertEquals('jsmodule has one statement - the call',1,JSModule.Statements.Count);
|
||||||
|
end;
|
||||||
|
|
||||||
// main uses section
|
// main uses section
|
||||||
if JSModuleCallArgs.Elements.Count<2 then
|
if JSModuleCallArgs.Elements.Count<2 then
|
||||||
@ -2187,6 +2196,14 @@ begin
|
|||||||
CheckDiff(Msg,ExpectedSrc,ActualSrc);
|
CheckDiff(Msg,ExpectedSrc,ActualSrc);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TCustomTestModule.CheckFullSource(Msg, ExpectedSrc: String);
|
||||||
|
var
|
||||||
|
ActualSrc: String;
|
||||||
|
begin
|
||||||
|
ActualSrc:=JSToStr(JSModule);
|
||||||
|
CheckDiff(Msg,ExpectedSrc,ActualSrc);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TCustomTestModule.CheckDiff(Msg, Expected, Actual: string);
|
procedure TCustomTestModule.CheckDiff(Msg, Expected, Actual: string);
|
||||||
// search diff, ignore changes in spaces
|
// search diff, ignore changes in spaces
|
||||||
var
|
var
|
||||||
@ -34134,10 +34151,14 @@ begin
|
|||||||
Add([
|
Add([
|
||||||
'']);
|
'']);
|
||||||
ConvertLibrary;
|
ConvertLibrary;
|
||||||
CheckSource('TestLibrary_Empty',
|
CheckFullSource('TestLibrary_Empty',
|
||||||
LinesToStr([ // statements
|
LinesToStr([ // statements
|
||||||
'']),
|
'rtl.module("library", [], function () {',
|
||||||
LinesToStr([
|
' var $mod = this;',
|
||||||
|
' $mod.$main = function () {',
|
||||||
|
' };',
|
||||||
|
'});',
|
||||||
|
'rtl.run("library");',
|
||||||
'']));
|
'']));
|
||||||
CheckResolverUnexpectedHints();
|
CheckResolverUnexpectedHints();
|
||||||
end;
|
end;
|
||||||
@ -34155,13 +34176,17 @@ begin
|
|||||||
' test1.run name ''Test1Run'';',
|
' test1.run name ''Test1Run'';',
|
||||||
'']);
|
'']);
|
||||||
ConvertLibrary;
|
ConvertLibrary;
|
||||||
CheckSource('TestLibrary_ExportFunc',
|
CheckFullSource('TestLibrary_ExportFunc',
|
||||||
LinesToStr([ // statements
|
LinesToStr([ // statements
|
||||||
'this.Run = function (w) {',
|
'rtl.module("library", [], function () {',
|
||||||
'};',
|
' var $mod = this;',
|
||||||
'export { this.Run as Run, this.Run as Foo, this.Run as Test1Run };',
|
' this.Run = function (w) {',
|
||||||
'']),
|
' };',
|
||||||
LinesToStr([
|
' $mod.$main = function () {',
|
||||||
|
' };',
|
||||||
|
'});',
|
||||||
|
'rtl.run("library");',
|
||||||
|
'export { pas.library.Run as Run, pas.library.Run as Foo, pas.library.Run as Test1Run };',
|
||||||
'']));
|
'']));
|
||||||
CheckResolverUnexpectedHints();
|
CheckResolverUnexpectedHints();
|
||||||
end;
|
end;
|
||||||
@ -34207,12 +34232,16 @@ begin
|
|||||||
' Wing;',
|
' Wing;',
|
||||||
'']);
|
'']);
|
||||||
ConvertLibrary;
|
ConvertLibrary;
|
||||||
CheckSource('TestLibrary_ExportVar',
|
CheckFullSource('TestLibrary_ExportVar',
|
||||||
LinesToStr([ // statements
|
LinesToStr([ // statements
|
||||||
'this.Wing = 0;',
|
'rtl.module("library", [], function () {',
|
||||||
'export { this.Wing as Wing };',
|
' var $mod = this;',
|
||||||
'']),
|
' this.Wing = 0;',
|
||||||
LinesToStr([
|
' $mod.$main = function () {',
|
||||||
|
' };',
|
||||||
|
'});',
|
||||||
|
'rtl.run("library");',
|
||||||
|
'export { pas.library.Wing as Wing };',
|
||||||
'']));
|
'']));
|
||||||
CheckResolverUnexpectedHints();
|
CheckResolverUnexpectedHints();
|
||||||
end;
|
end;
|
||||||
@ -34244,11 +34273,15 @@ begin
|
|||||||
' TAnt.Crawl;',
|
' TAnt.Crawl;',
|
||||||
'']);
|
'']);
|
||||||
ConvertLibrary;
|
ConvertLibrary;
|
||||||
CheckSource('TestLibrary_ExportUnitFunc',
|
CheckFullSource('TestLibrary_ExportUnitFunc',
|
||||||
LinesToStr([ // statements
|
LinesToStr([ // statements
|
||||||
|
'rtl.module("library", ["system", "Unit1"], function () {',
|
||||||
|
' var $mod = this;',
|
||||||
|
' $mod.$main = function () {',
|
||||||
|
' };',
|
||||||
|
'});',
|
||||||
|
'rtl.run("library");',
|
||||||
'export { pas.Unit1.Fly as Fly, pas.Unit1.TAnt.Crawl as Crawl };',
|
'export { pas.Unit1.Fly as Fly, pas.Unit1.TAnt.Crawl as Crawl };',
|
||||||
'']),
|
|
||||||
LinesToStr([
|
|
||||||
'']));
|
'']));
|
||||||
CheckResolverUnexpectedHints();
|
CheckResolverUnexpectedHints();
|
||||||
end;
|
end;
|
||||||
|
Loading…
Reference in New Issue
Block a user