mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-09 10:48:30 +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;
|
||||
Public
|
||||
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 NameSpaceExport : TJSString Read FNameSpaceExport Write FNameSpaceExport;
|
||||
Property ModuleName : TJSString Read FModuleName Write FModuleName;
|
||||
|
@ -282,6 +282,7 @@ type
|
||||
procedure UseVariable(El: TPasVariable; Access: TResolvedRefAccess;
|
||||
UseFull: boolean); virtual;
|
||||
procedure UseResourcestring(El: TPasResString); virtual;
|
||||
procedure UseExportSymbol(El: TPasExportSymbol); virtual;
|
||||
procedure UseArgument(El: TPasArgument; Access: TResolvedRefAccess); virtual;
|
||||
procedure UseResultElement(El: TPasResultElement; Access: TResolvedRefAccess); virtual;
|
||||
// create hints for a unit, program or library
|
||||
@ -1467,6 +1468,8 @@ begin
|
||||
end
|
||||
else if C=TPasAttributes then
|
||||
// attributes are never used directly
|
||||
else if C=TPasExportSymbol then
|
||||
UseExportSymbol(TPasExportSymbol(Decl))
|
||||
else
|
||||
RaiseNotSupported(20170306165213,Decl);
|
||||
end;
|
||||
@ -2622,6 +2625,24 @@ begin
|
||||
UseExpr(El.Expr);
|
||||
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
|
||||
);
|
||||
var
|
||||
|
@ -2097,6 +2097,7 @@ type
|
||||
Function CreateImplementationSection(El: TPasModule; IntfContext: TInterfaceSectionContext): TJSFunctionDeclarationStatement; virtual;
|
||||
Procedure CreateInitSection(El: TPasModule; 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 AddImplHeaderStatement(JS: TJSElement; PosEl: TPasElement; aContext: TConvertContext); virtual;
|
||||
function AddDelayedInits(El: TPasModule; Src: TJSSourceElements; AContext: TConvertContext): boolean; virtual;
|
||||
@ -8207,7 +8208,10 @@ Library:
|
||||
<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:
|
||||
rtl.module('<unitname>',
|
||||
@ -8337,7 +8341,6 @@ begin
|
||||
if Assigned(Lib.LibrarySection) then
|
||||
AddToSourceElements(Src,ConvertDeclarations(Lib.LibrarySection,IntfContext));
|
||||
HasImplCode:=AddDelayedInits(Lib,Src,IntfContext);
|
||||
CreateExportsSection(Lib,Src,IntfContext);
|
||||
CreateInitSection(Lib,Src,IntfContext);
|
||||
end
|
||||
else
|
||||
@ -8387,6 +8390,14 @@ begin
|
||||
|
||||
if (ModScope<>nil) and (coStoreImplJS in Options) then
|
||||
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;
|
||||
finally
|
||||
IntfContext.Free;
|
||||
@ -18096,6 +18107,24 @@ begin
|
||||
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;
|
||||
PosEl: TPasElement; aContext: TConvertContext);
|
||||
var
|
||||
|
@ -179,6 +179,7 @@ type
|
||||
function GetDottedIdentifier(El: TJSElement): string;
|
||||
procedure CheckSource(Msg,Statements: String; InitStatements: string = '';
|
||||
ImplStatements: string = ''); virtual;
|
||||
procedure CheckFullSource(Msg,ExpectedSrc: String); virtual;
|
||||
procedure CheckDiff(Msg, Expected, Actual: string); virtual;
|
||||
procedure CheckUnit(Filename, ExpectedSrc: string); virtual;
|
||||
procedure CheckHint(MsgType: TMessageType; MsgNumber: integer;
|
||||
@ -919,9 +920,9 @@ type
|
||||
Procedure TestLibrary_Export_Index_Fail;
|
||||
Procedure TestLibrary_ExportVar;
|
||||
Procedure TestLibrary_ExportUnitFunc;
|
||||
// todo: test fail on export overloaded function
|
||||
// ToDo: test delayed specialization init
|
||||
// ToDo: analyzer
|
||||
// ToDo: shortrefoptimization
|
||||
end;
|
||||
|
||||
function LinesToStr(Args: array of const): string;
|
||||
@ -1989,7 +1990,7 @@ var
|
||||
InitFunction: TJSFunctionDeclarationStatement;
|
||||
InitAssign: TJSSimpleAssignStatement;
|
||||
InitName: String;
|
||||
LastNode: TJSElement;
|
||||
LastNode, FirstNode: TJSElement;
|
||||
Arg: TJSArrayLiteralElement;
|
||||
IsProg, IsLib: Boolean;
|
||||
begin
|
||||
@ -2020,10 +2021,12 @@ begin
|
||||
{$ENDIF}
|
||||
|
||||
// rtl.module(...
|
||||
AssertEquals('jsmodule has one statement - the call',1,JSModule.Statements.Count);
|
||||
AssertNotNull('register module call',JSModule.Statements.Nodes[0].Node);
|
||||
AssertEquals('register module call',TJSCallExpression,JSModule.Statements.Nodes[0].Node.ClassType);
|
||||
FJSRegModuleCall:=JSModule.Statements.Nodes[0].Node as TJSCallExpression;
|
||||
if JSModule.Statements.Count<1 then
|
||||
AssertEquals('jsmodule has at least one statement - the call',1,JSModule.Statements.Count);
|
||||
FirstNode:=JSModule.Statements.Nodes[0].Node;
|
||||
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 args',JSRegModuleCall.Args);
|
||||
AssertEquals('rtl.module args',TJSArguments,JSRegModuleCall.Args.ClassType);
|
||||
@ -2037,11 +2040,17 @@ begin
|
||||
ModuleNameExpr:=Arg.Expr as TJSLiteral;
|
||||
AssertEquals('module name param is string',ord(jstString),ord(ModuleNameExpr.Value.ValueType));
|
||||
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
|
||||
AssertEquals('module name','library',String(ModuleNameExpr.Value.AsString))
|
||||
else
|
||||
begin
|
||||
AssertEquals('module name',Module.Name,String(ModuleNameExpr.Value.AsString));
|
||||
AssertEquals('jsmodule has one statement - the call',1,JSModule.Statements.Count);
|
||||
end;
|
||||
|
||||
// main uses section
|
||||
if JSModuleCallArgs.Elements.Count<2 then
|
||||
@ -2187,6 +2196,14 @@ begin
|
||||
CheckDiff(Msg,ExpectedSrc,ActualSrc);
|
||||
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);
|
||||
// search diff, ignore changes in spaces
|
||||
var
|
||||
@ -34134,10 +34151,14 @@ begin
|
||||
Add([
|
||||
'']);
|
||||
ConvertLibrary;
|
||||
CheckSource('TestLibrary_Empty',
|
||||
CheckFullSource('TestLibrary_Empty',
|
||||
LinesToStr([ // statements
|
||||
'']),
|
||||
LinesToStr([
|
||||
'rtl.module("library", [], function () {',
|
||||
' var $mod = this;',
|
||||
' $mod.$main = function () {',
|
||||
' };',
|
||||
'});',
|
||||
'rtl.run("library");',
|
||||
'']));
|
||||
CheckResolverUnexpectedHints();
|
||||
end;
|
||||
@ -34155,13 +34176,17 @@ begin
|
||||
' test1.run name ''Test1Run'';',
|
||||
'']);
|
||||
ConvertLibrary;
|
||||
CheckSource('TestLibrary_ExportFunc',
|
||||
CheckFullSource('TestLibrary_ExportFunc',
|
||||
LinesToStr([ // statements
|
||||
'this.Run = function (w) {',
|
||||
'};',
|
||||
'export { this.Run as Run, this.Run as Foo, this.Run as Test1Run };',
|
||||
'']),
|
||||
LinesToStr([
|
||||
'rtl.module("library", [], function () {',
|
||||
' var $mod = this;',
|
||||
' this.Run = function (w) {',
|
||||
' };',
|
||||
' $mod.$main = function () {',
|
||||
' };',
|
||||
'});',
|
||||
'rtl.run("library");',
|
||||
'export { pas.library.Run as Run, pas.library.Run as Foo, pas.library.Run as Test1Run };',
|
||||
'']));
|
||||
CheckResolverUnexpectedHints();
|
||||
end;
|
||||
@ -34207,12 +34232,16 @@ begin
|
||||
' Wing;',
|
||||
'']);
|
||||
ConvertLibrary;
|
||||
CheckSource('TestLibrary_ExportVar',
|
||||
CheckFullSource('TestLibrary_ExportVar',
|
||||
LinesToStr([ // statements
|
||||
'this.Wing = 0;',
|
||||
'export { this.Wing as Wing };',
|
||||
'']),
|
||||
LinesToStr([
|
||||
'rtl.module("library", [], function () {',
|
||||
' var $mod = this;',
|
||||
' this.Wing = 0;',
|
||||
' $mod.$main = function () {',
|
||||
' };',
|
||||
'});',
|
||||
'rtl.run("library");',
|
||||
'export { pas.library.Wing as Wing };',
|
||||
'']));
|
||||
CheckResolverUnexpectedHints();
|
||||
end;
|
||||
@ -34244,11 +34273,15 @@ begin
|
||||
' TAnt.Crawl;',
|
||||
'']);
|
||||
ConvertLibrary;
|
||||
CheckSource('TestLibrary_ExportUnitFunc',
|
||||
CheckFullSource('TestLibrary_ExportUnitFunc',
|
||||
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 };',
|
||||
'']),
|
||||
LinesToStr([
|
||||
'']));
|
||||
CheckResolverUnexpectedHints();
|
||||
end;
|
||||
|
Loading…
Reference in New Issue
Block a user