From 0e769ac13d5c95b25a8c989f8b611f406460e4e2 Mon Sep 17 00:00:00 2001 From: mattias Date: Tue, 17 Nov 2020 10:05:46 +0000 Subject: [PATCH] pastojs: fixed await(arg) and fixed hint await needs a promise --- compiler/packages/pastojs/src/fppas2js.pp | 34 ++++++++++++++++--- compiler/packages/pastojs/tests/tcmodules.pas | 18 +++++++++- 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/compiler/packages/pastojs/src/fppas2js.pp b/compiler/packages/pastojs/src/fppas2js.pp index 0c103c0..579ff8a 100644 --- a/compiler/packages/pastojs/src/fppas2js.pp +++ b/compiler/packages/pastojs/src/fppas2js.pp @@ -6027,9 +6027,10 @@ var P: TPasExprArray; Param, PathEnd: TPasExpr; Ref: TResolvedReference; - Decl: TPasElement; - ResolvedEl: TPasResolverResult; - Implicit: Boolean; + Decl, IdentEl, SubEl: TPasElement; + ResolvedEl, ParamResolved: TPasResolverResult; + Implicit, IsPromise: Boolean; + TypeEl: TPasType; begin if Proc=nil then ; P:=Params.Params; @@ -6046,7 +6047,7 @@ begin Ref:=TResolvedReference(PathEnd.CustomData); Decl:=Ref.Declaration; Implicit:=false; - if Decl is TPasVariable then + if (Decl is TPasVariable) or (Decl.ClassType=TPasArgument) then begin ComputeElement(Decl,ResolvedEl,[rcNoImplicitProcType]); if IsProcedureType(ResolvedEl,true) then @@ -6061,7 +6062,30 @@ begin end; end else - LogMsg(20201116000324,mtHint,nAwaitWithoutPromise,sAwaitWithoutPromise,[],Param); + begin + ComputeElement(Param,ParamResolved,[]); + IsPromise:=false; + TypeEl:=ParamResolved.LoTypeEl; + IdentEl:=ParamResolved.IdentEl; + if TypeEl.ClassType=TPasClassType then + IsPromise:=IsExternalClass_Name(TPasClassType(TypeEl),'Promise') + else if (ParamResolved.BaseType=btProc) and (IdentEl=nil) + and (TypeEl is TPasProcedureType) then + IsPromise:=TPasProcedureType(TypeEl).IsAsync + else if IdentEl is TPasProcedure then + IsPromise:=TPasProcedure(ParamResolved.IdentEl).IsAsync + else if IdentEl is TPasResultElement then + begin + SubEl:=TPasResultElement(IdentEl).Parent; + if (SubEl is TPasFunctionType) then + IsPromise:=TPasFunctionType(SubEl).IsAsync; + end; + {$IFDEF VerbosePas2JS} + writeln('TPas2JSResolver.BI_AWait_OnFinishParamsExpr Param=',GetObjPath(Param),' ParamResolved=',GetResolverResultDbg(ParamResolved)); + {$ENDIF} + if not IsPromise then + LogMsg(20201116000324,mtHint,nAwaitWithoutPromise,sAwaitWithoutPromise,[],Param); + end; end; if length(P)>1 then diff --git a/compiler/packages/pastojs/tests/tcmodules.pas b/compiler/packages/pastojs/tests/tcmodules.pas index ff0494f..79c8b0a 100644 --- a/compiler/packages/pastojs/tests/tcmodules.pas +++ b/compiler/packages/pastojs/tests/tcmodules.pas @@ -32226,6 +32226,7 @@ begin ' Run;', ' Run(3);', '']); + CheckResolverUnexpectedHints(); ConvertProgram; CheckSource('TestAsync_Proc', LinesToStr([ // statements @@ -32290,6 +32291,7 @@ begin ' if Fly()=p then ;', ' end;', '']); + CheckResolverUnexpectedHints(); ConvertProgram; CheckSource('TestAsync_CallResultIsPromise', LinesToStr([ // statements @@ -32448,6 +32450,7 @@ begin LinesToStr([ '$mod.Run(1);' ])); + SetExpectedPasResolverError('Await without promise',nAwaitWithoutPromise); end; procedure TTestModule.TestAWait_ExternalClassPromise; @@ -32496,17 +32499,18 @@ begin '']), LinesToStr([ ])); + CheckResolverUnexpectedHints(); end; procedure TTestModule.TestAsync_AnonymousProc; begin StartProgram(false); Add([ + '{$mode objfpc}', '{$modeswitch externalclass}', 'type', ' TJSPromise = class external name ''Promise''', ' end;', - '{$mode objfpc}', 'type', ' TFunc = reference to function(x: double): word; async;', 'function Crawl(d: double = 1.3): word; async;', @@ -32538,6 +32542,7 @@ begin '$mod.Func = async function (c) {', '};', ''])); + CheckResolverUnexpectedHints(); end; procedure TTestModule.TestAsync_ProcType; @@ -32555,6 +32560,11 @@ begin 'procedure Run(e:longint); async;', 'begin', 'end;', + 'procedure Fly(p: TProc); async;', + 'begin', + ' await(p);', + ' await(p());', + 'end;', 'var', ' RefFunc: TRefFunc;', ' Func: TFunc;', @@ -32575,6 +32585,7 @@ begin ' if Proc=ProcB then ;', ' ']); ConvertProgram; + CheckResolverUnexpectedHints(); CheckSource('TestAsync_ProcType', LinesToStr([ // statements 'this.Crawl = async function (d) {', @@ -32583,6 +32594,10 @@ begin '};', 'this.Run = async function (e) {', '};', + 'this.Fly = async function (p) {', + ' await p(7);', + ' await p(7);', + '};', 'this.RefFunc = null;', 'this.Func = null;', 'this.Proc = null;', @@ -32691,6 +32706,7 @@ begin '']), LinesToStr([ ''])); + CheckResolverUnexpectedHints(); end;