Browse Source

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

git-svn-id: trunk@47440 -
Mattias Gaertner 4 years ago
parent
commit
97d4d635c8
2 changed files with 46 additions and 6 deletions
  1. 29 5
      packages/pastojs/src/fppas2js.pp
  2. 17 1
      packages/pastojs/tests/tcmodules.pas

+ 29 - 5
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

+ 17 - 1
packages/pastojs/tests/tcmodules.pas

@@ -32232,6 +32232,7 @@ begin
   '  Run;',
   '  Run(3);',
   '']);
+  CheckResolverUnexpectedHints();
   ConvertProgram;
   CheckSource('TestAsync_Proc',
     LinesToStr([ // statements
@@ -32296,6 +32297,7 @@ begin
   '    if Fly()=p then ;',
   '  end;',
   '']);
+  CheckResolverUnexpectedHints();
   ConvertProgram;
   CheckSource('TestAsync_CallResultIsPromise',
     LinesToStr([ // statements
@@ -32454,6 +32456,7 @@ begin
     LinesToStr([
     '$mod.Run(1);'
     ]));
+  SetExpectedPasResolverError('Await without promise',nAwaitWithoutPromise);
 end;
 
 procedure TTestModule.TestAWait_ExternalClassPromise;
@@ -32502,17 +32505,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;',
@@ -32544,6 +32548,7 @@ begin
     '$mod.Func = async function (c) {',
     '};',
     '']));
+  CheckResolverUnexpectedHints();
 end;
 
 procedure TTestModule.TestAsync_ProcType;
@@ -32561,6 +32566,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;',
@@ -32581,6 +32591,7 @@ begin
   '  if Proc=ProcB then ;',
   '  ']);
   ConvertProgram;
+  CheckResolverUnexpectedHints();
   CheckSource('TestAsync_ProcType',
     LinesToStr([ // statements
     'this.Crawl = async function (d) {',
@@ -32589,6 +32600,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;',
@@ -32697,6 +32712,7 @@ begin
     '']),
     LinesToStr([
     '']));
+  CheckResolverUnexpectedHints();
 end;