pastojs: Assert with EAssertFailed

git-svn-id: trunk@37992 -
This commit is contained in:
Mattias Gaertner 2018-01-18 12:30:44 +00:00
parent 8adf783350
commit e7f6808c9f
4 changed files with 89 additions and 25 deletions

View File

@ -265,6 +265,9 @@ Works:
- char, char range, set of char, set of char range - char, char range, set of char, set of char range
- array - array
- class - class
- Assert(bool[,string])
- without sysutils: if(bool) throw string
- with sysutils: if(bool) throw pas.sysutils.EAssertionFailed.$create("Create",[string])
ToDos: ToDos:
- remove hasOwnProperty from rtl set functions - remove hasOwnProperty from rtl set functions
@ -3924,18 +3927,18 @@ var
FunName: String; FunName: String;
begin begin
Result:=nil; Result:=nil;
//writeln('TPasToJSConverter.CreateNewInstanceStatement Ref.Declaration=',GetObjName(Ref.Declaration)); //writeln('TPasToJSConverter.CreateFreeOrNewInstanceExpr Ref.Declaration=',GetObjName(Ref.Declaration));
Proc:=Ref.Declaration as TPasProcedure; Proc:=Ref.Declaration as TPasProcedure;
if Proc.Name='' then if Proc.Name='' then
RaiseInconsistency(20170125191914); RaiseInconsistency(20170125191914);
//writeln('TPasToJSConverter.CreateNewInstanceStatement Proc.Name=',Proc.Name); //writeln('TPasToJSConverter.CreateFreeOrNewInstanceExpr Proc.Name=',Proc.Name);
ProcScope:=Proc.CustomData as TPasProcedureScope; ProcScope:=Proc.CustomData as TPasProcedureScope;
//writeln('TPasToJSConverter.CreateNewInstanceStatement ProcScope.Element=',GetObjName(ProcScope.Element),' ProcScope.ClassScope=',GetObjName(ProcScope.ClassScope),' ProcScope.DeclarationProc=',GetObjName(ProcScope.DeclarationProc),' ProcScope.ImplProc=',GetObjName(ProcScope.ImplProc),' ProcScope.CustomData=',GetObjName(ProcScope.CustomData)); //writeln('TPasToJSConverter.CreateFreeOrNewInstanceExpr ProcScope.Element=',GetObjName(ProcScope.Element),' ProcScope.ClassScope=',GetObjName(ProcScope.ClassScope),' ProcScope.DeclarationProc=',GetObjName(ProcScope.DeclarationProc),' ProcScope.ImplProc=',GetObjName(ProcScope.ImplProc),' ProcScope.CustomData=',GetObjName(ProcScope.CustomData));
ClassScope:=ProcScope.ClassScope; ClassScope:=ProcScope.ClassScope;
aClass:=ClassScope.Element; aClass:=ClassScope.Element;
if aClass.Name='' then if aClass.Name='' then
RaiseInconsistency(20170125191923); RaiseInconsistency(20170125191923);
//writeln('TPasToJSConverter.CreateNewInstanceStatement aClass.Name=',aClass.Name); //writeln('TPasToJSConverter.CreateFreeOrNewInstanceExpr aClass.Name=',aClass.Name);
C:=CreateCallExpression(Ref.Element); C:=CreateCallExpression(Ref.Element);
ok:=false; ok:=false;
try try
@ -7593,10 +7596,19 @@ var
ProcScope: TPasProcedureScope; ProcScope: TPasProcedureScope;
IfSt: TJSIfStatement; IfSt: TJSIfStatement;
ThrowSt: TJSThrowStatement; ThrowSt: TJSThrowStatement;
ModScope: TPasModuleScope;
aConstructor: TPasConstructor;
Ref: TResolvedReference;
ArrLit: TJSArrayLiteral;
Call: TJSCallExpression;
FunName: String;
PosEl: TPasExpr;
Enabled: Boolean;
begin begin
Result:=nil; Result:=nil;
// check if assertions are enabled // check if assertions are enabled
Enabled:=false;
CtxEl:=El; CtxEl:=El;
while CtxEl<>nil do while CtxEl<>nil do
begin begin
@ -7604,26 +7616,71 @@ begin
begin begin
ProcScope:=CtxEl.CustomData as TPasProcedureScope; ProcScope:=CtxEl.CustomData as TPasProcedureScope;
if not (ppsfAssertions in ProcScope.Flags) then exit; if not (ppsfAssertions in ProcScope.Flags) then exit;
Enabled:=true;
break;
end
else if CtxEl is TPasModule then
begin
ModScope:=CtxEl.CustomData as TPasModuleScope;
if not (pmsfAssertions in ModScope.Flags) then exit;
Enabled:=true;
break; break;
end; end;
CtxEl:=CtxEl.Parent; CtxEl:=CtxEl.Parent;
end; end;
if not Enabled then exit;
Ref:=nil;
IfSt:=TJSIfStatement(CreateElement(TJSIfStatement,El)); IfSt:=TJSIfStatement(CreateElement(TJSIfStatement,El));
try try
PosEl:=El.Params[0];
IfSt.Cond:=ConvertExpression(El.Params[0],AContext); IfSt.Cond:=ConvertExpression(El.Params[0],AContext);
ThrowSt:=TJSThrowStatement(CreateElement(TJSThrowStatement,El.Params[0])); ThrowSt:=TJSThrowStatement(CreateElement(TJSThrowStatement,PosEl));
IfSt.BTrue:=ThrowSt; IfSt.BTrue:=ThrowSt;
// ToDo: find sysutils.EAssertionFailed
// using sysutils.EAssertionFailed if available
aConstructor:=nil;
if El.CustomData is TResolvedReference then
begin
Ref:=TResolvedReference(El.CustomData);
if Ref.Declaration is TPasConstructor then
aConstructor:=TPasConstructor(Ref.Declaration);
Ref:=nil;
end;
//writeln('TPasToJSConverter.ConvertBuiltIn_Assert ',GetObjName(aConstructor));
if aConstructor<>nil then
begin
Ref:=TResolvedReference.Create;
ModScope:=El.GetModule.CustomData as TPasModuleScope;
Ref.Declaration:=ModScope.AssertClass;
// pas.sysutils.EAssertionFailed
FunName:=CreateReferencePath(ModScope.AssertClass,AContext,rpkPathAndName,true,Ref);
// append .$create('Create')
FunName:=FunName+'.'+FBuiltInNames[pbifnClassInstanceNew];
Call:=CreateCallExpression(PosEl);
Call.Expr:=CreatePrimitiveDotExpr(FunName,PosEl);
// parameter: "Create"
Call.AddArg(CreateLiteralString(PosEl,TransformVariableName(aConstructor,AContext)));
ThrowSt.A:=Call;
if length(El.Params)>1 then if length(El.Params)>1 then
begin begin
ThrowSt.A:=ConvertExpression(El.Params[1],AContext); // add [msg]
end ArrLit:=TJSArrayLiteral(CreateElement(TJSArrayLiteral,El.Params[1]));
Call.AddArg(ArrLit);
ArrLit.AddElement(ConvertExpression(El.Params[1],AContext));
end;
end;
if ThrowSt.A=nil then
begin
// fallback: throw msg
if length(El.Params)>1 then
ThrowSt.A:=ConvertExpression(El.Params[1],AContext)
else else
ThrowSt.A:=CreateLiteralJSString(El.Params[0],'assert failed'); ThrowSt.A:=CreateLiteralJSString(El.Params[0],'assert failed');
end;
Result:=IfSt; Result:=IfSt;
finally finally
Ref.Free;
if Result=nil then if Result=nil then
IfSt.Free; IfSt.Free;
end; end;

View File

@ -89,6 +89,7 @@ type
coShowUsedTools, coShowUsedTools,
coShowMessageNumbers, // not in "show all" coShowMessageNumbers, // not in "show all"
coShowDebug, // not in "show all" coShowDebug, // not in "show all"
coAssertions,
coAllowCAssignments, coAllowCAssignments,
coLowerCase, coLowerCase,
coEnumValuesAsNumbers, coEnumValuesAsNumbers,
@ -119,6 +120,7 @@ const
'Show used tools', 'Show used tools',
'Show message numbers', 'Show message numbers',
'Show debug', 'Show debug',
'Assertions',
'Allow C assignments', 'Allow C assignments',
'Lowercase identifiers', 'Lowercase identifiers',
'Enum values as numbers', 'Enum values as numbers',
@ -708,14 +710,17 @@ begin
Scanner.AllowedModeSwitches:=msAllPas2jsModeSwitches; Scanner.AllowedModeSwitches:=msAllPas2jsModeSwitches;
Scanner.ReadOnlyModeSwitches:=msAllPas2jsModeSwitchesReadOnly; Scanner.ReadOnlyModeSwitches:=msAllPas2jsModeSwitchesReadOnly;
Scanner.CurrentModeSwitches:=p2jsMode_SwitchSets[Compiler.Mode]; Scanner.CurrentModeSwitches:=p2jsMode_SwitchSets[Compiler.Mode];
bs:=msAllPas2jsBoolSwitches; Scanner.AllowedBoolSwitches:=msAllPas2jsBoolSwitches;
if not (coShowHints in Compiler.Options) then bs:=[];
Exclude(bs,bsHints); if coAssertions in Compiler.Options then
if not (coShowNotes in Compiler.Options) then Include(bs,bsAssertions);
Exclude(bs,bsNotes); if coShowHints in Compiler.Options then
if not (coShowWarnings in Compiler.Options) then Include(bs,bsHints);
Exclude(bs,bsWarnings); if coShowNotes in Compiler.Options then
Scanner.AllowedBoolSwitches:=bs; Include(bs,bsNotes);
if coShowWarnings in Compiler.Options then
Include(bs,bsWarnings);
Scanner.CurrentBoolSwitches:=bs;
// Note: some Scanner.Options are set by TPasResolver // Note: some Scanner.Options are set by TPasResolver
for i:=0 to Compiler.Defines.Count-1 do for i:=0 to Compiler.Defines.Count-1 do
begin begin
@ -2592,9 +2597,10 @@ var
Enabled, Disabled: string; Enabled, Disabled: string;
i: Integer; i: Integer;
begin begin
ReadSingleLetterOptions(Param,p,'c',Enabled,Disabled); ReadSingleLetterOptions(Param,p,'a2cd',Enabled,Disabled);
for i:=1 to length(Enabled) do begin for i:=1 to length(Enabled) do begin
case Enabled[i] of case Enabled[i] of
'a': Options:=Options+[coAssertions];
'2': Mode:=p2jmObjFPC; '2': Mode:=p2jmObjFPC;
'c': Options:=Options+[coAllowCAssignments]; 'c': Options:=Options+[coAllowCAssignments];
'd': Mode:=p2jmDelphi; 'd': Mode:=p2jmDelphi;
@ -2602,6 +2608,7 @@ begin
end; end;
for i:=1 to length(Disabled) do begin for i:=1 to length(Disabled) do begin
case Disabled[i] of case Disabled[i] of
'a': Options:=Options-[coAssertions];
'2': ; '2': ;
'c': Options:=Options-[coAllowCAssignments]; 'c': Options:=Options-[coAllowCAssignments];
'd': ; 'd': ;
@ -3140,6 +3147,7 @@ begin
l(' -Pecmascript5 : default'); l(' -Pecmascript5 : default');
l(' -Pecmascript6'); l(' -Pecmascript6');
l(' -S<x> : Syntax options. <x> is a combination of the following letters:'); l(' -S<x> : Syntax options. <x> is a combination of the following letters:');
l(' a : Turn on assertions');
l(' c : Support operators like C (*=,+=,/= and -=)'); l(' c : Support operators like C (*=,+=,/= and -=)');
l(' d : Same as -Mdelphi'); l(' d : Same as -Mdelphi');
l(' 2 : Same as -Mobjfpc (default)'); l(' 2 : Same as -Mobjfpc (default)');

View File

@ -922,9 +922,6 @@ begin
{$IFDEF VerbosePas2JSDirCache} {$IFDEF VerbosePas2JSDirCache}
writeln('TPas2jsCachedDirectories.GetDirectory "',Dir,'"'); writeln('TPas2jsCachedDirectories.GetDirectory "',Dir,'"');
{$ENDIF} {$ENDIF}
{$IFDEF CaseInsensitiveFilenames}
Dir:=IncludeTrailingPathDelimiter(FindDiskFilename(ChompPathDelim(Dir)));
{$ENDIF}
Result:=TPas2jsCachedDirectory.Create(Dir,Self); Result:=TPas2jsCachedDirectory.Create(Dir,Self);
FDirectories.Add(Result); FDirectories.Add(Result);
if DoReference then if DoReference then

View File

@ -15889,6 +15889,7 @@ begin
'begin', 'begin',
' {$Assertions on}', ' {$Assertions on}',
' Assert(b);', ' Assert(b);',
' Assert(b,''msg'');',
'end;', 'end;',
'begin', 'begin',
' DoIt;', ' DoIt;',
@ -15899,7 +15900,8 @@ begin
'this.DoIt = function () {', 'this.DoIt = function () {',
' var b = false;', ' var b = false;',
' var s = "";', ' var s = "";',
' if (b) throw "assert failed";', ' if (b) throw pas.SysUtils.EAssertionFailed.$create("Create");',
' if (b) throw pas.SysUtils.EAssertionFailed.$create("Create$1", ["msg"]);',
'};', '};',
'']), '']),
LinesToStr([ // $mod.$main LinesToStr([ // $mod.$main