Browse Source

Allow an asynchronous procedure to be a promise.

Henrique Gottardi Werlang 2 years ago
parent
commit
b1d8c20a16
2 changed files with 40 additions and 7 deletions
  1. 12 1
      packages/fcl-passrc/src/pasresolver.pp
  2. 28 6
      packages/pastojs/src/fppas2js.pp

+ 12 - 1
packages/fcl-passrc/src/pasresolver.pp

@@ -2239,7 +2239,7 @@ type
     procedure WriteScopesShort(Title: string);
     // find value and type of an element
     procedure ComputeElement(El: TPasElement; out ResolvedEl: TPasResolverResult;
-      Flags: TPasResolverComputeFlags; StartEl: TPasElement = nil);
+      Flags: TPasResolverComputeFlags; StartEl: TPasElement = nil); virtual;
     procedure ComputeResultElement(El: TPasResultElement; out ResolvedEl: TPasResolverResult;
       Flags: TPasResolverComputeFlags; StartEl: TPasElement = nil); virtual;
     function Eval(Expr: TPasExpr; Flags: TResEvalFlags; Store: boolean = true): TResEvalValue; overload;
@@ -14233,6 +14233,11 @@ begin
         // function call => return result
         ComputeResultElement(TPasFunctionType(Proc.ProcType).ResultEl,ResolvedEl,
           Flags+[rcCall],StartEl)
+      else if Proc.IsAsync then
+        begin
+        // async proc => return promise
+        ComputeElement(Proc,ResolvedEl,Flags+[rcCall],StartEl);
+        end
       else if (Proc.ClassType=TPasConstructor) then
         begin
         // constructor -> return value of type class
@@ -27828,6 +27833,12 @@ procedure TPasResolver.ComputeElement(El: TPasElement; out
             ComputeResultElement(TPasFunction(ResolvedEl.IdentEl).FuncType.ResultEl,
               ResolvedEl,Flags+[rcCall],StartEl);
             end
+          else if (ResolvedEl.IdentEl is TPasProcedure)
+              and TPasProcedure(ResolvedEl.IdentEl).IsAsync then
+            begin
+            // async proc => return promise
+            ComputeElement(ResolvedEl.IdentEl,ResolvedEl,Flags+[rcCall],StartEl);
+            end
           else if (ResolvedEl.IdentEl.ClassType=TPasConstructor) then
             begin
             // constructor -> return value of type class

+ 28 - 6
packages/pastojs/src/fppas2js.pp

@@ -1696,6 +1696,8 @@ type
     procedure CheckDispatchField(Proc: TPasProcedure; Switch: TValueSwitch);
     procedure AddMessageStr(var MsgToProc: TMessageIdToProc_List; const S: string; Proc: TPasProcedure);
     procedure AddMessageIdToClassScope(Proc: TPasProcedure; EmitHints: boolean); virtual;
+    procedure ComputeElement(El: TPasElement; out ResolvedEl: TPasResolverResult;
+      Flags: TPasResolverComputeFlags; StartEl: TPasElement = nil); override;
     procedure ComputeResultElement(El: TPasResultElement; out
       ResolvedEl: TPasResolverResult; Flags: TPasResolverComputeFlags;
       StartEl: TPasElement = nil); override;
@@ -7302,13 +7304,36 @@ begin
   end;
 end;
 
+procedure TPas2JSResolver.ComputeElement(El: TPasElement; out
+  ResolvedEl: TPasResolverResult; Flags: TPasResolverComputeFlags;
+  StartEl: TPasElement);
+var
+  Proc: TPasProcedure;
+  JSPromiseClass: TPasClassType;
+begin
+  if (rcCall in Flags) and (El is TPasProcedure) then
+    begin
+    Proc:=TPasProcedure(El);
+    if Proc.IsAsync then
+      begin
+      // an async function call returns a TJSPromise
+      JSPromiseClass:=FindTJSPromise(StartEl);
+
+      SetResolverIdentifier(ResolvedEl, btContext, El, JSPromiseClass,
+        JSPromiseClass, [rrfReadable, rrfWritable]);
+
+      Exit;
+      end;
+    end;
+  inherited ComputeElement(El,ResolvedEl,Flags,StartEl);
+end;
+
 procedure TPas2JSResolver.ComputeResultElement(El: TPasResultElement; out
   ResolvedEl: TPasResolverResult; Flags: TPasResolverComputeFlags;
   StartEl: TPasElement);
 var
   FuncType: TPasFunctionType;
   Proc: TPasProcedure;
-  JSPromiseClass: TPasClassType;
 begin
   if (rcCall in Flags) and (El.Parent is TPasFunctionType) then
     begin
@@ -7318,11 +7343,8 @@ begin
       Proc:=TPasProcedure(FuncType.Parent);
       if Proc.IsAsync then
         begin
-        // an async function call returns a TJSPromise
-        JSPromiseClass:=FindTJSPromise(StartEl);
-        SetResolverIdentifier(ResolvedEl,btContext,El,
-                       JSPromiseClass,JSPromiseClass,[rrfReadable,rrfWritable]);
-        exit;
+        ComputeElement(Proc, ResolvedEl, Flags, StartEl);
+        Exit;
         end;
       end;
     end;