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
- array
- class
- Assert(bool[,string])
- without sysutils: if(bool) throw string
- with sysutils: if(bool) throw pas.sysutils.EAssertionFailed.$create("Create",[string])
ToDos:
- remove hasOwnProperty from rtl set functions
@ -3924,18 +3927,18 @@ var
FunName: String;
begin
Result:=nil;
//writeln('TPasToJSConverter.CreateNewInstanceStatement Ref.Declaration=',GetObjName(Ref.Declaration));
//writeln('TPasToJSConverter.CreateFreeOrNewInstanceExpr Ref.Declaration=',GetObjName(Ref.Declaration));
Proc:=Ref.Declaration as TPasProcedure;
if Proc.Name='' then
RaiseInconsistency(20170125191914);
//writeln('TPasToJSConverter.CreateNewInstanceStatement Proc.Name=',Proc.Name);
//writeln('TPasToJSConverter.CreateFreeOrNewInstanceExpr Proc.Name=',Proc.Name);
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;
aClass:=ClassScope.Element;
if aClass.Name='' then
RaiseInconsistency(20170125191923);
//writeln('TPasToJSConverter.CreateNewInstanceStatement aClass.Name=',aClass.Name);
//writeln('TPasToJSConverter.CreateFreeOrNewInstanceExpr aClass.Name=',aClass.Name);
C:=CreateCallExpression(Ref.Element);
ok:=false;
try
@ -7593,10 +7596,19 @@ var
ProcScope: TPasProcedureScope;
IfSt: TJSIfStatement;
ThrowSt: TJSThrowStatement;
ModScope: TPasModuleScope;
aConstructor: TPasConstructor;
Ref: TResolvedReference;
ArrLit: TJSArrayLiteral;
Call: TJSCallExpression;
FunName: String;
PosEl: TPasExpr;
Enabled: Boolean;
begin
Result:=nil;
// check if assertions are enabled
Enabled:=false;
CtxEl:=El;
while CtxEl<>nil do
begin
@ -7604,26 +7616,71 @@ begin
begin
ProcScope:=CtxEl.CustomData as TPasProcedureScope;
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;
end;
CtxEl:=CtxEl.Parent;
end;
if not Enabled then exit;
Ref:=nil;
IfSt:=TJSIfStatement(CreateElement(TJSIfStatement,El));
try
PosEl:=El.Params[0];
IfSt.Cond:=ConvertExpression(El.Params[0],AContext);
ThrowSt:=TJSThrowStatement(CreateElement(TJSThrowStatement,El.Params[0]));
ThrowSt:=TJSThrowStatement(CreateElement(TJSThrowStatement,PosEl));
IfSt.BTrue:=ThrowSt;
// ToDo: find sysutils.EAssertionFailed
if length(El.Params)>1 then
begin
ThrowSt.A:=ConvertExpression(El.Params[1],AContext);
end
else
ThrowSt.A:=CreateLiteralJSString(El.Params[0],'assert failed');
// 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
begin
// add [msg]
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
ThrowSt.A:=CreateLiteralJSString(El.Params[0],'assert failed');
end;
Result:=IfSt;
finally
Ref.Free;
if Result=nil then
IfSt.Free;
end;

View File

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

View File

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

View File

@ -15889,6 +15889,7 @@ begin
'begin',
' {$Assertions on}',
' Assert(b);',
' Assert(b,''msg'');',
'end;',
'begin',
' DoIt;',
@ -15899,7 +15900,8 @@ begin
'this.DoIt = function () {',
' var b = false;',
' 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