mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-14 02:59:33 +02:00
pastojs: added option -JoCheckVersion
git-svn-id: trunk@39851 -
This commit is contained in:
parent
a32a6bca90
commit
cec7188704
@ -916,7 +916,9 @@ procedure TCustomTestResolver.TearDown;
|
|||||||
{$IFDEF CheckPasTreeRefCount}
|
{$IFDEF CheckPasTreeRefCount}
|
||||||
var El: TPasElement;
|
var El: TPasElement;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
{$IF defined(VerbosePasResolver) or defined(VerbosePasResolverMem)}
|
||||||
var i: Integer;
|
var i: Integer;
|
||||||
|
{$ENDIF}
|
||||||
begin
|
begin
|
||||||
FResolverMsgs.Clear;
|
FResolverMsgs.Clear;
|
||||||
FResolverGoodMsgs.Clear;
|
FResolverGoodMsgs.Clear;
|
||||||
|
@ -361,6 +361,7 @@ ToDos:
|
|||||||
v:=a[0] gives Local variable "a" is assigned but never used
|
v:=a[0] gives Local variable "a" is assigned but never used
|
||||||
- bug:
|
- bug:
|
||||||
exit(something) gives function result not set
|
exit(something) gives function result not set
|
||||||
|
- double utf8bom at start must give error pscanner 4259
|
||||||
- setlength(dynarray) modeswitch to not create a copy
|
- setlength(dynarray) modeswitch to not create a copy
|
||||||
- check rtl.js version
|
- check rtl.js version
|
||||||
- 'new', 'Function' -> class var use .prototype
|
- 'new', 'Function' -> class var use .prototype
|
||||||
@ -521,6 +522,7 @@ type
|
|||||||
pbifnAs,
|
pbifnAs,
|
||||||
pbifnAsExt,
|
pbifnAsExt,
|
||||||
pbifnCheckMethodCall,
|
pbifnCheckMethodCall,
|
||||||
|
pbifnCheckVersion,
|
||||||
pbifnClassInstanceFree,
|
pbifnClassInstanceFree,
|
||||||
pbifnClassInstanceNew,
|
pbifnClassInstanceNew,
|
||||||
pbifnCreateClass,
|
pbifnCreateClass,
|
||||||
@ -666,6 +668,7 @@ const
|
|||||||
'as', // rtl.as
|
'as', // rtl.as
|
||||||
'asExt', // rtl.asExt
|
'asExt', // rtl.asExt
|
||||||
'checkMethodCall',
|
'checkMethodCall',
|
||||||
|
'checkVersion',
|
||||||
'$destroy',
|
'$destroy',
|
||||||
'$create',
|
'$create',
|
||||||
'createClass', // rtl.createClass
|
'createClass', // rtl.createClass
|
||||||
@ -1404,7 +1407,10 @@ type
|
|||||||
coUseStrict, // insert 'use strict'
|
coUseStrict, // insert 'use strict'
|
||||||
coNoTypeInfo, // do not generate RTTI
|
coNoTypeInfo, // do not generate RTTI
|
||||||
coEliminateDeadCode, // skip code that is never executed
|
coEliminateDeadCode, // skip code that is never executed
|
||||||
coStoreImplJS // store references to JS code in procscopes
|
coStoreImplJS, // store references to JS code in procscopes
|
||||||
|
coRTLVersionCheckMain, // insert rtl version check into main
|
||||||
|
coRTLVersionCheckSystem, // insert rtl version check into system unit init
|
||||||
|
coRTLVersionCheckUnit // insert rtl version check into every unit init
|
||||||
);
|
);
|
||||||
TPasToJsConverterOptions = set of TPasToJsConverterOption;
|
TPasToJsConverterOptions = set of TPasToJsConverterOption;
|
||||||
const
|
const
|
||||||
@ -1470,6 +1476,7 @@ type
|
|||||||
FOnIsTypeInfoUsed: TPas2JSIsElementUsedEvent;
|
FOnIsTypeInfoUsed: TPas2JSIsElementUsedEvent;
|
||||||
FOptions: TPasToJsConverterOptions;
|
FOptions: TPasToJsConverterOptions;
|
||||||
FReservedWords: TJSReservedWordList; // sorted with CompareStr
|
FReservedWords: TJSReservedWordList; // sorted with CompareStr
|
||||||
|
FRTLVersion: TJSNumber;
|
||||||
FTargetPlatform: TPasToJsPlatform;
|
FTargetPlatform: TPasToJsPlatform;
|
||||||
FTargetProcessor: TPasToJsProcessor;
|
FTargetProcessor: TPasToJsProcessor;
|
||||||
Function CreatePrimitiveDotExpr(AName: string; Src: TPasElement): TJSElement;
|
Function CreatePrimitiveDotExpr(AName: string; Src: TPasElement): TJSElement;
|
||||||
@ -1643,6 +1650,7 @@ type
|
|||||||
Procedure AddInFrontOfFunctionTry(NewEl: TJSElement; PosEl: TPasElement;
|
Procedure AddInFrontOfFunctionTry(NewEl: TJSElement; PosEl: TPasElement;
|
||||||
FuncContext: TFunctionContext);
|
FuncContext: TFunctionContext);
|
||||||
Procedure AddInterfaceReleases(FuncContext: TFunctionContext; PosEl: TPasElement);
|
Procedure AddInterfaceReleases(FuncContext: TFunctionContext; PosEl: TPasElement);
|
||||||
|
Procedure AddRTLVersionCheck(FuncContext: TFunctionContext; PosEl: TPasElement);
|
||||||
// Statements
|
// Statements
|
||||||
Function ConvertImplBlockElements(El: TPasImplBlock; AContext: TConvertContext; NilIfEmpty: boolean): TJSElement; virtual;
|
Function ConvertImplBlockElements(El: TPasImplBlock; AContext: TConvertContext; NilIfEmpty: boolean): TJSElement; virtual;
|
||||||
Function ConvertBeginEndStatement(El: TPasImplBeginBlock; AContext: TConvertContext; NilIfEmpty: boolean): TJSElement; virtual;
|
Function ConvertBeginEndStatement(El: TPasImplBeginBlock; AContext: TConvertContext; NilIfEmpty: boolean): TJSElement; virtual;
|
||||||
@ -1783,6 +1791,7 @@ type
|
|||||||
Function ConvertPasElement(El: TPasElement; Resolver: TPas2JSResolver) : TJSElement;
|
Function ConvertPasElement(El: TPasElement; Resolver: TPas2JSResolver) : TJSElement;
|
||||||
// options
|
// options
|
||||||
Property Options: TPasToJsConverterOptions read FOptions write FOptions default DefaultPasToJSOptions;
|
Property Options: TPasToJsConverterOptions read FOptions write FOptions default DefaultPasToJSOptions;
|
||||||
|
Property RTLVersion: TJSNumber read FRTLVersion write FRTLVersion;
|
||||||
Property TargetPlatform: TPasToJsPlatform read FTargetPlatform write FTargetPlatform;
|
Property TargetPlatform: TPasToJsPlatform read FTargetPlatform write FTargetPlatform;
|
||||||
Property TargetProcessor: TPasToJsProcessor read FTargetProcessor write FTargetProcessor;
|
Property TargetProcessor: TPasToJsProcessor read FTargetProcessor write FTargetProcessor;
|
||||||
Property UseLowerCase: boolean read GetUseLowerCase write SetUseLowerCase default true;
|
Property UseLowerCase: boolean read GetUseLowerCase write SetUseLowerCase default true;
|
||||||
@ -5146,14 +5155,14 @@ Unit:
|
|||||||
*)
|
*)
|
||||||
Var
|
Var
|
||||||
OuterSrc , Src: TJSSourceElements;
|
OuterSrc , Src: TJSSourceElements;
|
||||||
RegModuleCall: TJSCallExpression;
|
RegModuleCall, Call: TJSCallExpression;
|
||||||
ArgArray: TJSArguments;
|
ArgArray: TJSArguments;
|
||||||
FunDecl, ImplFunc: TJSFunctionDeclarationStatement;
|
FunDecl, ImplFunc: TJSFunctionDeclarationStatement;
|
||||||
UsesSection: TPasSection;
|
UsesSection: TPasSection;
|
||||||
ModuleName, ModVarName: String;
|
ModuleName, ModVarName: String;
|
||||||
IntfContext: TSectionContext;
|
IntfContext: TSectionContext;
|
||||||
ImplVarSt: TJSVariableStatement;
|
ImplVarSt: TJSVariableStatement;
|
||||||
HasImplUsesClause, ok: Boolean;
|
HasImplUsesClause, ok, NeedRTLCheckVersion: Boolean;
|
||||||
UsesClause: TPasUsesClause;
|
UsesClause: TPasUsesClause;
|
||||||
begin
|
begin
|
||||||
Result:=Nil;
|
Result:=Nil;
|
||||||
@ -5191,6 +5200,16 @@ begin
|
|||||||
// "use strict" must be the first statement in a function
|
// "use strict" must be the first statement in a function
|
||||||
AddToSourceElements(Src,CreateLiteralString(El,'use strict'));
|
AddToSourceElements(Src,CreateLiteralString(El,'use strict'));
|
||||||
|
|
||||||
|
NeedRTLCheckVersion:=(coRTLVersionCheckUnit in Options)
|
||||||
|
or ((coRTLVersionCheckSystem in Options) and IsSystemUnit(El));
|
||||||
|
if NeedRTLCheckVersion then
|
||||||
|
begin
|
||||||
|
Call:=CreateCallExpression(El);
|
||||||
|
Call.Expr:=CreateMemberExpression([FBuiltInNames[pbivnRTL],FBuiltInNames[pbifnCheckVersion]]);
|
||||||
|
Call.AddArg(CreateLiteralNumber(El,RTLVersion));
|
||||||
|
AddToSourceElements(Src,Call);
|
||||||
|
end;
|
||||||
|
|
||||||
ImplVarSt:=nil;
|
ImplVarSt:=nil;
|
||||||
HasImplUsesClause:=false;
|
HasImplUsesClause:=false;
|
||||||
|
|
||||||
@ -12654,7 +12673,7 @@ function TPasToJSConverter.ConvertInitializationSection(
|
|||||||
var
|
var
|
||||||
FDS: TJSFunctionDeclarationStatement;
|
FDS: TJSFunctionDeclarationStatement;
|
||||||
FunName: String;
|
FunName: String;
|
||||||
IsMain: Boolean;
|
IsMain, NeedRTLCheckVersion: Boolean;
|
||||||
AssignSt: TJSSimpleAssignStatement;
|
AssignSt: TJSSimpleAssignStatement;
|
||||||
FuncContext: TFunctionContext;
|
FuncContext: TFunctionContext;
|
||||||
Body: TJSFunctionBody;
|
Body: TJSFunctionBody;
|
||||||
@ -12681,13 +12700,17 @@ begin
|
|||||||
FunName:=FBuiltInNames[pbifnProgramMain]
|
FunName:=FBuiltInNames[pbifnProgramMain]
|
||||||
else
|
else
|
||||||
FunName:=FBuiltInNames[pbifnUnitInit];
|
FunName:=FBuiltInNames[pbifnUnitInit];
|
||||||
|
NeedRTLCheckVersion:=IsMain and (coRTLVersionCheckMain in Options);
|
||||||
|
|
||||||
FuncContext:=nil;
|
FuncContext:=nil;
|
||||||
AssignSt:=TJSSimpleAssignStatement(CreateElement(TJSSimpleAssignStatement,El));
|
AssignSt:=TJSSimpleAssignStatement(CreateElement(TJSSimpleAssignStatement,El));
|
||||||
try
|
try
|
||||||
|
// $mod.$init =
|
||||||
AssignSt.LHS:=CreateMemberExpression([FBuiltInNames[pbivnModule],FunName]);
|
AssignSt.LHS:=CreateMemberExpression([FBuiltInNames[pbivnModule],FunName]);
|
||||||
FDS:=CreateFunctionSt(El,El.Elements.Count>0);
|
// = function(){...}
|
||||||
|
FDS:=CreateFunctionSt(El,(El.Elements.Count>0) or NeedRTLCheckVersion);
|
||||||
AssignSt.Expr:=FDS;
|
AssignSt.Expr:=FDS;
|
||||||
|
|
||||||
if El.Elements.Count>0 then
|
if El.Elements.Count>0 then
|
||||||
begin
|
begin
|
||||||
Body:=FDS.AFunction.Body;
|
Body:=FDS.AFunction.Body;
|
||||||
@ -12700,6 +12723,16 @@ begin
|
|||||||
AddInterfaceReleases(FuncContext,El);
|
AddInterfaceReleases(FuncContext,El);
|
||||||
Body.A:=FuncContext.BodySt;
|
Body.A:=FuncContext.BodySt;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
if NeedRTLCheckVersion then
|
||||||
|
begin
|
||||||
|
// prepend rtl.versionCheck
|
||||||
|
Body:=FDS.AFunction.Body;
|
||||||
|
if FuncContext=nil then
|
||||||
|
FuncContext:=TFunctionContext.Create(El,Body,AContext);
|
||||||
|
AddRTLVersionCheck(FuncContext,El);
|
||||||
|
Body.A:=FuncContext.BodySt;
|
||||||
|
end;
|
||||||
Result:=AssignSt;
|
Result:=AssignSt;
|
||||||
finally
|
finally
|
||||||
FuncContext.Free;
|
FuncContext.Free;
|
||||||
@ -14900,6 +14933,41 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TPasToJSConverter.AddRTLVersionCheck(FuncContext: TFunctionContext;
|
||||||
|
PosEl: TPasElement);
|
||||||
|
var
|
||||||
|
St: TJSElement;
|
||||||
|
Call: TJSCallExpression;
|
||||||
|
NewSt: TJSStatementList;
|
||||||
|
begin
|
||||||
|
St:=FuncContext.BodySt;
|
||||||
|
// rtl.checkVersion(RTLVersion)
|
||||||
|
Call:=CreateCallExpression(PosEl);
|
||||||
|
Call.Expr:=CreateMemberExpression([FBuiltInNames[pbivnRTL],FBuiltInNames[pbifnCheckVersion]]);
|
||||||
|
Call.AddArg(CreateLiteralNumber(PosEl,RTLVersion));
|
||||||
|
if St=nil then
|
||||||
|
FuncContext.BodySt:=Call
|
||||||
|
else if St is TJSEmptyBlockStatement then
|
||||||
|
begin
|
||||||
|
St.Free;
|
||||||
|
FuncContext.BodySt:=Call;
|
||||||
|
end
|
||||||
|
else if St is TJSStatementList then
|
||||||
|
begin
|
||||||
|
NewSt:=TJSStatementList(CreateElement(TJSStatementList,PosEl));
|
||||||
|
NewSt.A:=Call;
|
||||||
|
NewSt.B:=St;
|
||||||
|
FuncContext.BodySt:=NewSt;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
{$IFDEF VerbosePas2JS}
|
||||||
|
writeln('TPasToJSConverter.AddRTLVersionCheck St=',GetObjName(St));
|
||||||
|
{$ENDIF}
|
||||||
|
RaiseNotSupported(PosEl,FuncContext,20181002154026,GetObjName(St));
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function TPasToJSConverter.ConvertImplBlock(El: TPasImplBlock;
|
function TPasToJSConverter.ConvertImplBlock(El: TPasImplBlock;
|
||||||
AContext: TConvertContext): TJSElement;
|
AContext: TConvertContext): TJSElement;
|
||||||
begin
|
begin
|
||||||
@ -16285,7 +16353,7 @@ end;
|
|||||||
|
|
||||||
function TPasToJSConverter.IsSystemUnit(aModule: TPasModule): boolean;
|
function TPasToJSConverter.IsSystemUnit(aModule: TPasModule): boolean;
|
||||||
begin
|
begin
|
||||||
Result:=CompareText(aModule.Name,'system')=0;
|
Result:=(CompareText(aModule.Name,'system')=0) and (aModule.ClassType=TPasModule);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TPasToJSConverter.HasTypeInfo(El: TPasType; AContext: TConvertContext
|
function TPasToJSConverter.HasTypeInfo(El: TPasType; AContext: TConvertContext
|
||||||
|
@ -116,8 +116,15 @@ type
|
|||||||
);
|
);
|
||||||
TP2jsCompilerOptions = set of TP2jsCompilerOption;
|
TP2jsCompilerOptions = set of TP2jsCompilerOption;
|
||||||
TP2jsOptimization = coEnumValuesAsNumbers..coKeepNotUsedDeclarationsWPO;
|
TP2jsOptimization = coEnumValuesAsNumbers..coKeepNotUsedDeclarationsWPO;
|
||||||
|
TP2jsRTLVersionCheck = (
|
||||||
|
rvcNone,
|
||||||
|
rvcMain,
|
||||||
|
rvcSystem,
|
||||||
|
rvcUnit
|
||||||
|
);
|
||||||
const
|
const
|
||||||
DefaultP2jsCompilerOptions = [coShowErrors,coSourceMapXSSIHeader,coUseStrict];
|
DefaultP2jsCompilerOptions = [coShowErrors,coSourceMapXSSIHeader,coUseStrict];
|
||||||
|
DefaultP2jsRTLVersionCheck = rvcNone;
|
||||||
coShowAll = [coShowErrors..coShowDebug];
|
coShowAll = [coShowErrors..coShowDebug];
|
||||||
coO1Enable = [coEnumValuesAsNumbers];
|
coO1Enable = [coEnumValuesAsNumbers];
|
||||||
coO1Disable = [coKeepNotUsedPrivates,coKeepNotUsedDeclarationsWPO];
|
coO1Disable = [coKeepNotUsedPrivates,coKeepNotUsedDeclarationsWPO];
|
||||||
@ -418,6 +425,7 @@ type
|
|||||||
private
|
private
|
||||||
FInterfaceType: TPasClassInterfaceType;
|
FInterfaceType: TPasClassInterfaceType;
|
||||||
FPrecompileInitialFlags: TPCUInitialFlags;
|
FPrecompileInitialFlags: TPCUInitialFlags;
|
||||||
|
FRTLVersionCheck: TP2jsRTLVersionCheck;
|
||||||
procedure AddDefinesForTargetPlatform;
|
procedure AddDefinesForTargetPlatform;
|
||||||
procedure AddDefinesForTargetProcessor;
|
procedure AddDefinesForTargetProcessor;
|
||||||
procedure AddReadingModule(aFile: TPas2jsCompilerFile);
|
procedure AddReadingModule(aFile: TPas2jsCompilerFile);
|
||||||
@ -507,6 +515,7 @@ type
|
|||||||
property ParamMacros: TPas2jsMacroEngine read FParamMacros;
|
property ParamMacros: TPas2jsMacroEngine read FParamMacros;
|
||||||
property PrecompileGUID: TGUID read FPrecompileGUID write FPrecompileGUID;
|
property PrecompileGUID: TGUID read FPrecompileGUID write FPrecompileGUID;
|
||||||
property PrecompileInitialFlags: TPCUInitialFlags read FPrecompileInitialFlags;
|
property PrecompileInitialFlags: TPCUInitialFlags read FPrecompileInitialFlags;
|
||||||
|
property RTLVersionCheck: TP2jsRTLVersionCheck read FRTLVersionCheck write FRTLVersionCheck;
|
||||||
property SrcMapEnable: boolean read GetSrcMapEnable write SetSrcMapEnable;
|
property SrcMapEnable: boolean read GetSrcMapEnable write SetSrcMapEnable;
|
||||||
property SrcMapSourceRoot: string read FSrcMapSourceRoot write FSrcMapSourceRoot;
|
property SrcMapSourceRoot: string read FSrcMapSourceRoot write FSrcMapSourceRoot;
|
||||||
property SrcMapBaseDir: string read GetSrcMapBaseDir write SetSrcMapBaseDir;
|
property SrcMapBaseDir: string read GetSrcMapBaseDir write SetSrcMapBaseDir;
|
||||||
@ -828,6 +837,13 @@ begin
|
|||||||
Include(Result,fppas2js.coLowerCase)
|
Include(Result,fppas2js.coLowerCase)
|
||||||
else
|
else
|
||||||
Exclude(Result,fppas2js.coLowerCase);
|
Exclude(Result,fppas2js.coLowerCase);
|
||||||
|
|
||||||
|
case Compiler.RTLVersionCheck of
|
||||||
|
rvcNone: ;
|
||||||
|
rvcMain: Include(Result,fppas2js.coRTLVersionCheckMain);
|
||||||
|
rvcSystem: Include(Result,fppas2js.coRTLVersionCheckSystem);
|
||||||
|
rvcUnit: Include(Result,fppas2js.coRTLVersionCheckUnit);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TPas2jsCompilerFile.CreateScannerAndParser(aFileResolver: TPas2jsFileResolver);
|
procedure TPas2jsCompilerFile.CreateScannerAndParser(aFileResolver: TPas2jsFileResolver);
|
||||||
@ -920,6 +936,7 @@ procedure TPas2jsCompilerFile.CreateConverter;
|
|||||||
begin
|
begin
|
||||||
if FConverter<>nil then exit;
|
if FConverter<>nil then exit;
|
||||||
FConverter:=TPasToJSConverter.Create;
|
FConverter:=TPasToJSConverter.Create;
|
||||||
|
FConverter.RTLVersion:=(VersionMajor*100+VersionMinor)*100+VersionRelease;
|
||||||
FConverter.Options:=GetInitialConverterOptions;
|
FConverter.Options:=GetInitialConverterOptions;
|
||||||
FConverter.TargetPlatform:=Compiler.TargetPlatform;
|
FConverter.TargetPlatform:=Compiler.TargetPlatform;
|
||||||
FConverter.TargetProcessor:=Compiler.TargetProcessor;
|
FConverter.TargetProcessor:=Compiler.TargetProcessor;
|
||||||
@ -3280,6 +3297,12 @@ begin
|
|||||||
FileCache.SearchLikeFPC:=Enable
|
FileCache.SearchLikeFPC:=Enable
|
||||||
else if SameText(Identifier,'UseStrict') then
|
else if SameText(Identifier,'UseStrict') then
|
||||||
SetOption(coUseStrict,Enable)
|
SetOption(coUseStrict,Enable)
|
||||||
|
else if Enable and SameText(Identifier,'CheckVersion=main') then
|
||||||
|
RTLVersionCheck:=rvcMain
|
||||||
|
else if Enable and SameText(Identifier,'CheckVersion=system') then
|
||||||
|
RTLVersionCheck:=rvcSystem
|
||||||
|
else if Enable and SameText(Identifier,'CheckVersion=unit') then
|
||||||
|
RTLVersionCheck:=rvcUnit
|
||||||
else
|
else
|
||||||
UnknownParam;
|
UnknownParam;
|
||||||
end;
|
end;
|
||||||
@ -3837,6 +3860,7 @@ begin
|
|||||||
|
|
||||||
FCompilerExe:='';
|
FCompilerExe:='';
|
||||||
FOptions:=DefaultP2jsCompilerOptions;
|
FOptions:=DefaultP2jsCompilerOptions;
|
||||||
|
FRTLVersionCheck:=DefaultP2jsRTLVersionCheck;
|
||||||
FMode:=p2jmObjFPC;
|
FMode:=p2jmObjFPC;
|
||||||
FTargetPlatform:=PlatformBrowser;
|
FTargetPlatform:=PlatformBrowser;
|
||||||
FTargetProcessor:=ProcessorECMAScript5;
|
FTargetProcessor:=ProcessorECMAScript5;
|
||||||
@ -4063,6 +4087,10 @@ begin
|
|||||||
l(' -Jo<x> : Enable or disable extra option. The x is case insensitive:');
|
l(' -Jo<x> : Enable or disable extra option. The x is case insensitive:');
|
||||||
l(' -JoSearchLikeFPC : search source files like FPC, default: search case insensitive.');
|
l(' -JoSearchLikeFPC : search source files like FPC, default: search case insensitive.');
|
||||||
l(' -JoUseStrict : add "use strict" to modules, default.');
|
l(' -JoUseStrict : add "use strict" to modules, default.');
|
||||||
|
l(' -JoCheckVersion- : do not add rtl version check, default.');
|
||||||
|
l(' -JoCheckVersion=main : insert rtl version check into main.');
|
||||||
|
l(' -JoCheckVersion=system : insert rtl version check into system unit init.');
|
||||||
|
l(' -JoCheckVersion=unit : insert rtl version check into every unit init.');
|
||||||
l(' -Ju<x> : Add <x> to foreign unit paths. Foreign units are not compiled.');
|
l(' -Ju<x> : Add <x> to foreign unit paths. Foreign units are not compiled.');
|
||||||
if PrecompileFormats.Count>0 then
|
if PrecompileFormats.Count>0 then
|
||||||
begin
|
begin
|
||||||
|
@ -211,7 +211,10 @@ const
|
|||||||
'UseStrict',
|
'UseStrict',
|
||||||
'NoTypeInfo',
|
'NoTypeInfo',
|
||||||
'EliminateDeadCode',
|
'EliminateDeadCode',
|
||||||
'StoreImplJS'
|
'StoreImplJS',
|
||||||
|
'RTLVersionCheckMain',
|
||||||
|
'RTLVersionCheckSystem',
|
||||||
|
'RTLVersionCheckUnit'
|
||||||
);
|
);
|
||||||
|
|
||||||
PCUDefaultTargetPlatform = PlatformBrowser;
|
PCUDefaultTargetPlatform = PlatformBrowser;
|
||||||
|
@ -25,7 +25,7 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils,
|
Classes, SysUtils,
|
||||||
fpcunit, testregistry, Pas2jsFileUtils, Pas2JsFiler,
|
fpcunit, testregistry, Pas2jsFileUtils, Pas2JsFiler, Pas2jsCompiler,
|
||||||
tcunitsearch, tcmodules;
|
tcunitsearch, tcmodules;
|
||||||
|
|
||||||
type
|
type
|
||||||
@ -42,6 +42,7 @@ type
|
|||||||
SharedParams: TStringList = nil;
|
SharedParams: TStringList = nil;
|
||||||
FirstRunParams: TStringList = nil;
|
FirstRunParams: TStringList = nil;
|
||||||
SecondRunParams: TStringList = nil; ExpExitCode: integer = 0);
|
SecondRunParams: TStringList = nil; ExpExitCode: integer = 0);
|
||||||
|
function GetJSFilename(ModuleName: string): string; virtual;
|
||||||
public
|
public
|
||||||
constructor Create; override;
|
constructor Create; override;
|
||||||
property PCUFormat: TPas2JSPrecompileFormat read FPCUFormat write FPCUFormat;
|
property PCUFormat: TPas2JSPrecompileFormat read FPCUFormat write FPCUFormat;
|
||||||
@ -62,6 +63,9 @@ type
|
|||||||
procedure TestPCU_ClassConstructor;
|
procedure TestPCU_ClassConstructor;
|
||||||
procedure TestPCU_ClassInterface;
|
procedure TestPCU_ClassInterface;
|
||||||
procedure TestPCU_Namespace;
|
procedure TestPCU_Namespace;
|
||||||
|
procedure TestPCU_CheckVersionMain;
|
||||||
|
procedure TestPCU_CheckVersionMain2;
|
||||||
|
procedure TestPCU_CheckVersionSystem;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function LinesToList(const Lines: array of string): TStringList;
|
function LinesToList(const Lines: array of string): TStringList;
|
||||||
@ -98,13 +102,15 @@ begin
|
|||||||
writeln('TTestCLI_Precompile.CheckPrecompile create pcu files=========================');
|
writeln('TTestCLI_Precompile.CheckPrecompile create pcu files=========================');
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
Params.Clear;
|
Params.Clear;
|
||||||
|
Params.Add('-Jminclude');
|
||||||
|
Params.Add('-Jc');
|
||||||
if SharedParams<>nil then
|
if SharedParams<>nil then
|
||||||
Params.Assign(SharedParams);
|
Params.AddStrings(SharedParams);
|
||||||
if FirstRunParams<>nil then
|
if FirstRunParams<>nil then
|
||||||
Params.AddStrings(FirstRunParams);
|
Params.AddStrings(FirstRunParams);
|
||||||
Compile([MainFile,'-Jc','-Fu'+UnitPaths,'-JU'+PCUFormat.Ext,'-FU'+UnitOutputDir,'-Jminclude']);
|
Compile([MainFile,'-Fu'+UnitPaths,'-JU'+PCUFormat.Ext,'-FU'+UnitOutputDir]);
|
||||||
AssertFileExists(UnitOutputDir+'/system.'+PCUFormat.Ext);
|
AssertFileExists(UnitOutputDir+'/system.'+PCUFormat.Ext);
|
||||||
JSFilename:=UnitOutputDir+PathDelim+ExtractFilenameOnly(MainFile)+'.js';
|
JSFilename:=GetJSFilename(MainFile);
|
||||||
AssertFileExists(JSFilename);
|
AssertFileExists(JSFilename);
|
||||||
JSFile:=FindFile(JSFilename);
|
JSFile:=FindFile(JSFilename);
|
||||||
OrigSrc:=JSFile.Source;
|
OrigSrc:=JSFile.Source;
|
||||||
@ -115,19 +121,21 @@ begin
|
|||||||
JSFile.Source:='';
|
JSFile.Source:='';
|
||||||
Compiler.Reset;
|
Compiler.Reset;
|
||||||
Params.Clear;
|
Params.Clear;
|
||||||
|
Params.Add('-Jminclude');
|
||||||
|
Params.Add('-Jc');
|
||||||
if SharedParams<>nil then
|
if SharedParams<>nil then
|
||||||
Params.Assign(SharedParams);
|
Params.AddStrings(SharedParams);
|
||||||
if SecondRunParams<>nil then
|
if SecondRunParams<>nil then
|
||||||
Params.AddStrings(SecondRunParams);
|
Params.AddStrings(SecondRunParams);
|
||||||
Compile([MainFile,'-Jc','-FU'+UnitOutputDir,'-Jminclude'],ExpExitCode);
|
Compile([MainFile,'-FU'+UnitOutputDir],ExpExitCode);
|
||||||
if ExpExitCode=0 then
|
if ExpExitCode=0 then
|
||||||
begin
|
begin
|
||||||
NewSrc:=JSFile.Source;
|
NewSrc:=JSFile.Source;
|
||||||
if not CheckSrcDiff(OrigSrc,NewSrc,s) then
|
if not CheckSrcDiff(OrigSrc,NewSrc,s) then
|
||||||
begin
|
begin
|
||||||
WriteSources;
|
WriteSources;
|
||||||
Fail('test1.js: '+s);
|
Fail('test1.js: '+s);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
finally
|
finally
|
||||||
SharedParams.Free;
|
SharedParams.Free;
|
||||||
@ -136,6 +144,11 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TCustomTestCLI_Precompile.GetJSFilename(ModuleName: string): string;
|
||||||
|
begin
|
||||||
|
Result:=UnitOutputDir+PathDelim+ExtractFilenameOnly(ModuleName)+'.js';
|
||||||
|
end;
|
||||||
|
|
||||||
constructor TCustomTestCLI_Precompile.Create;
|
constructor TCustomTestCLI_Precompile.Create;
|
||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
@ -461,6 +474,89 @@ begin
|
|||||||
AssertFileExists(UnitOutputDir+'/Web.Unit1.'+PCUFormat.Ext);
|
AssertFileExists(UnitOutputDir+'/Web.Unit1.'+PCUFormat.Ext);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestCLI_Precompile.TestPCU_CheckVersionMain;
|
||||||
|
var
|
||||||
|
aFile: TCLIFile;
|
||||||
|
s, JSFilename, ExpectedSrc: string;
|
||||||
|
begin
|
||||||
|
AddUnit('src/system.pp',[
|
||||||
|
'type integer = longint;'],
|
||||||
|
['']);
|
||||||
|
AddFile('test1.pas',[
|
||||||
|
'begin',
|
||||||
|
'end.']);
|
||||||
|
CheckPrecompile('test1.pas','src',LinesToList(['-JoCheckVersion=Main','-Jm-','-Jc-']));
|
||||||
|
JSFilename:=GetJSFilename('test1.js');
|
||||||
|
aFile:=FindFile(JSFilename);
|
||||||
|
AssertNotNull('File not found '+JSFilename,aFile);
|
||||||
|
ExpectedSrc:=LinesToStr([
|
||||||
|
UTF8BOM+'rtl.module("program",["system"],function () {',
|
||||||
|
' "use strict";',
|
||||||
|
' var $mod = this;',
|
||||||
|
' $mod.$main = function () {',
|
||||||
|
' rtl.checkVersion('+IntToStr((VersionMajor*100+VersionMinor)*100+VersionRelease)+');',
|
||||||
|
' };',
|
||||||
|
'});']);
|
||||||
|
if not CheckSrcDiff(ExpectedSrc,aFile.Source,s) then
|
||||||
|
Fail('TTestCLI_Precompile.TestPCU_CheckVersionMain src diff: '+s);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestCLI_Precompile.TestPCU_CheckVersionMain2;
|
||||||
|
var
|
||||||
|
aFile: TCLIFile;
|
||||||
|
s, JSFilename, ExpectedSrc: string;
|
||||||
|
begin
|
||||||
|
AddUnit('src/system.pp',[
|
||||||
|
'type integer = longint;',
|
||||||
|
'procedure Writeln; varargs;'],
|
||||||
|
['procedure Writeln; begin end;']);
|
||||||
|
AddFile('test1.pas',[
|
||||||
|
'begin',
|
||||||
|
' Writeln;',
|
||||||
|
'end.']);
|
||||||
|
CheckPrecompile('test1.pas','src',LinesToList(['-JoCheckVersion=Main','-Jm-','-Jc-']));
|
||||||
|
JSFilename:=GetJSFilename('test1.js');
|
||||||
|
aFile:=FindFile(JSFilename);
|
||||||
|
AssertNotNull('File not found '+JSFilename,aFile);
|
||||||
|
ExpectedSrc:=LinesToStr([
|
||||||
|
UTF8BOM+'rtl.module("program",["system"],function () {',
|
||||||
|
' "use strict";',
|
||||||
|
' var $mod = this;',
|
||||||
|
' $mod.$main = function () {',
|
||||||
|
' rtl.checkVersion('+IntToStr((VersionMajor*100+VersionMinor)*100+VersionRelease)+');',
|
||||||
|
' pas.system.Writeln();',
|
||||||
|
' };',
|
||||||
|
'});']);
|
||||||
|
if not CheckSrcDiff(ExpectedSrc,aFile.Source,s) then
|
||||||
|
Fail('TTestCLI_Precompile.TestPCU_CheckVersionMain src diff: '+s);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestCLI_Precompile.TestPCU_CheckVersionSystem;
|
||||||
|
var
|
||||||
|
aFile: TCLIFile;
|
||||||
|
s, JSFilename, ExpectedSrc: string;
|
||||||
|
begin
|
||||||
|
AddUnit('src/system.pp',[
|
||||||
|
'type integer = longint;'],
|
||||||
|
['']);
|
||||||
|
AddFile('test1.pas',[
|
||||||
|
'begin',
|
||||||
|
'end.']);
|
||||||
|
CheckPrecompile('test1.pas','src',LinesToList(['-JoCheckVersion=system','-Jm-','-Jc-']));
|
||||||
|
JSFilename:=GetJSFilename('system.js');
|
||||||
|
aFile:=FindFile(JSFilename);
|
||||||
|
AssertNotNull('File not found '+JSFilename,aFile);
|
||||||
|
writeln('TTestCLI_Precompile.TestPCU_CheckVersionMain ',aFile.Source);
|
||||||
|
ExpectedSrc:=LinesToStr([
|
||||||
|
UTF8BOM+'rtl.module("system",[],function () {',
|
||||||
|
' "use strict";',
|
||||||
|
' rtl.checkVersion(10101);',
|
||||||
|
' var $mod = this;',
|
||||||
|
'});']);
|
||||||
|
if not CheckSrcDiff(ExpectedSrc,aFile.Source,s) then
|
||||||
|
Fail('TTestCLI_Precompile.TestPCU_CheckVersionMain src diff: '+s);
|
||||||
|
end;
|
||||||
|
|
||||||
Initialization
|
Initialization
|
||||||
{$IFDEF EnablePas2jsPrecompiled}
|
{$IFDEF EnablePas2jsPrecompiled}
|
||||||
RegisterTests([TTestCLI_Precompile]);
|
RegisterTests([TTestCLI_Precompile]);
|
||||||
|
6
utils/pas2js/dist/rtl.js
vendored
6
utils/pas2js/dist/rtl.js
vendored
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
var rtl = {
|
var rtl = {
|
||||||
|
|
||||||
|
version: 10101,
|
||||||
|
|
||||||
quiet: false,
|
quiet: false,
|
||||||
debug_load_units: false,
|
debug_load_units: false,
|
||||||
debug_rtti: false,
|
debug_rtti: false,
|
||||||
@ -20,6 +22,10 @@ var rtl = {
|
|||||||
rtl.debug('Warn: ',s);
|
rtl.debug('Warn: ',s);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
checkVersion: function(v){
|
||||||
|
if (rtl.version != v) throw "expected rtl version "+v+", but found "+rtl.version;
|
||||||
|
},
|
||||||
|
|
||||||
hasString: function(s){
|
hasString: function(s){
|
||||||
return rtl.isString(s) && (s.length>0);
|
return rtl.isString(s) && (s.length>0);
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user