pastojs: fixed await(arg) and fixed hint await needs a promise

This commit is contained in:
mattias 2020-11-17 10:05:46 +00:00
parent 79e245988b
commit 0e769ac13d
2 changed files with 46 additions and 6 deletions

View File

@ -6027,9 +6027,10 @@ var
P: TPasExprArray; P: TPasExprArray;
Param, PathEnd: TPasExpr; Param, PathEnd: TPasExpr;
Ref: TResolvedReference; Ref: TResolvedReference;
Decl: TPasElement; Decl, IdentEl, SubEl: TPasElement;
ResolvedEl: TPasResolverResult; ResolvedEl, ParamResolved: TPasResolverResult;
Implicit: Boolean; Implicit, IsPromise: Boolean;
TypeEl: TPasType;
begin begin
if Proc=nil then ; if Proc=nil then ;
P:=Params.Params; P:=Params.Params;
@ -6046,7 +6047,7 @@ begin
Ref:=TResolvedReference(PathEnd.CustomData); Ref:=TResolvedReference(PathEnd.CustomData);
Decl:=Ref.Declaration; Decl:=Ref.Declaration;
Implicit:=false; Implicit:=false;
if Decl is TPasVariable then if (Decl is TPasVariable) or (Decl.ClassType=TPasArgument) then
begin begin
ComputeElement(Decl,ResolvedEl,[rcNoImplicitProcType]); ComputeElement(Decl,ResolvedEl,[rcNoImplicitProcType]);
if IsProcedureType(ResolvedEl,true) then if IsProcedureType(ResolvedEl,true) then
@ -6061,7 +6062,30 @@ begin
end; end;
end end
else 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; end;
if length(P)>1 then if length(P)>1 then

View File

@ -32226,6 +32226,7 @@ begin
' Run;', ' Run;',
' Run(3);', ' Run(3);',
'']); '']);
CheckResolverUnexpectedHints();
ConvertProgram; ConvertProgram;
CheckSource('TestAsync_Proc', CheckSource('TestAsync_Proc',
LinesToStr([ // statements LinesToStr([ // statements
@ -32290,6 +32291,7 @@ begin
' if Fly()=p then ;', ' if Fly()=p then ;',
' end;', ' end;',
'']); '']);
CheckResolverUnexpectedHints();
ConvertProgram; ConvertProgram;
CheckSource('TestAsync_CallResultIsPromise', CheckSource('TestAsync_CallResultIsPromise',
LinesToStr([ // statements LinesToStr([ // statements
@ -32448,6 +32450,7 @@ begin
LinesToStr([ LinesToStr([
'$mod.Run(1);' '$mod.Run(1);'
])); ]));
SetExpectedPasResolverError('Await without promise',nAwaitWithoutPromise);
end; end;
procedure TTestModule.TestAWait_ExternalClassPromise; procedure TTestModule.TestAWait_ExternalClassPromise;
@ -32496,17 +32499,18 @@ begin
'']), '']),
LinesToStr([ LinesToStr([
])); ]));
CheckResolverUnexpectedHints();
end; end;
procedure TTestModule.TestAsync_AnonymousProc; procedure TTestModule.TestAsync_AnonymousProc;
begin begin
StartProgram(false); StartProgram(false);
Add([ Add([
'{$mode objfpc}',
'{$modeswitch externalclass}', '{$modeswitch externalclass}',
'type', 'type',
' TJSPromise = class external name ''Promise''', ' TJSPromise = class external name ''Promise''',
' end;', ' end;',
'{$mode objfpc}',
'type', 'type',
' TFunc = reference to function(x: double): word; async;', ' TFunc = reference to function(x: double): word; async;',
'function Crawl(d: double = 1.3): word; async;', 'function Crawl(d: double = 1.3): word; async;',
@ -32538,6 +32542,7 @@ begin
'$mod.Func = async function (c) {', '$mod.Func = async function (c) {',
'};', '};',
''])); '']));
CheckResolverUnexpectedHints();
end; end;
procedure TTestModule.TestAsync_ProcType; procedure TTestModule.TestAsync_ProcType;
@ -32555,6 +32560,11 @@ begin
'procedure Run(e:longint); async;', 'procedure Run(e:longint); async;',
'begin', 'begin',
'end;', 'end;',
'procedure Fly(p: TProc); async;',
'begin',
' await(p);',
' await(p());',
'end;',
'var', 'var',
' RefFunc: TRefFunc;', ' RefFunc: TRefFunc;',
' Func: TFunc;', ' Func: TFunc;',
@ -32575,6 +32585,7 @@ begin
' if Proc=ProcB then ;', ' if Proc=ProcB then ;',
' ']); ' ']);
ConvertProgram; ConvertProgram;
CheckResolverUnexpectedHints();
CheckSource('TestAsync_ProcType', CheckSource('TestAsync_ProcType',
LinesToStr([ // statements LinesToStr([ // statements
'this.Crawl = async function (d) {', 'this.Crawl = async function (d) {',
@ -32583,6 +32594,10 @@ begin
'};', '};',
'this.Run = async function (e) {', 'this.Run = async function (e) {',
'};', '};',
'this.Fly = async function (p) {',
' await p(7);',
' await p(7);',
'};',
'this.RefFunc = null;', 'this.RefFunc = null;',
'this.Func = null;', 'this.Func = null;',
'this.Proc = null;', 'this.Proc = null;',
@ -32691,6 +32706,7 @@ begin
'']), '']),
LinesToStr([ LinesToStr([
''])); '']));
CheckResolverUnexpectedHints();
end; end;