Quellcode durchsuchen

pastojs: filer skip not fully specialized

git-svn-id: trunk@47679 -
Mattias Gaertner vor 4 Jahren
Ursprung
Commit
b90504a458

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

@@ -18798,7 +18798,10 @@ begin
     begin
     // inside procedure: first param is function result
     ProcScope:=TPasProcedureScope(Scopes[i]);
-    CtxProc:=TPasProcedure(ProcScope.Element);
+    if ProcScope.DeclarationProc<>nil then
+      CtxProc:=ProcScope.DeclarationProc
+    else
+      CtxProc:=TPasProcedure(ProcScope.Element);
     if not (CtxProc.ProcType is TPasFunctionType) then
       begin
       if RaiseOnError then

+ 19 - 10
packages/fcl-passrc/src/pasuseanalyzer.pas

@@ -1281,7 +1281,7 @@ begin
     if CanSkipGenericType(ProcType) then exit;
     for i:=0 to ProcType.Args.Count-1 do
       UseSubEl(TPasArgument(ProcType.Args[i]).ArgType);
-    if El is TPasFunctionType then
+    if (El is TPasFunctionType) and (TPasFunctionType(El).ResultEl<>nil) then
       UseSubEl(TPasFunctionType(El).ResultEl.ResultType);
     end
   else if C=TPasSpecializeType then
@@ -1543,12 +1543,15 @@ begin
     UseExpr(ForLoop.StartExpr);
     UseExpr(ForLoop.EndExpr);
     ForScope:=ForLoop.CustomData as TPasForLoopScope;
-    MarkImplScopeRef(ForLoop,ForScope.GetEnumerator,psraRead);
-    UseProcedure(ForScope.GetEnumerator);
-    MarkImplScopeRef(ForLoop,ForScope.MoveNext,psraRead);
-    UseProcedure(ForScope.MoveNext);
-    MarkImplScopeRef(ForLoop,ForScope.Current,psraRead);
-    UseVariable(ForScope.Current,rraRead,false);
+    if ForScope<>nil then
+      begin
+      MarkImplScopeRef(ForLoop,ForScope.GetEnumerator,psraRead);
+      UseProcedure(ForScope.GetEnumerator);
+      MarkImplScopeRef(ForLoop,ForScope.MoveNext,psraRead);
+      UseProcedure(ForScope.MoveNext);
+      MarkImplScopeRef(ForLoop,ForScope.Current,psraRead);
+      UseVariable(ForScope.Current,rraRead,false);
+      end;
     UseImplElement(ForLoop.Body);
     end
   else if C=TPasImplIfElse then
@@ -1650,12 +1653,14 @@ procedure TPasAnalyzer.UseExpr(El: TPasExpr);
     UseElement(SubEl,rraAssign,false);
   end;
 
-  procedure UseBuilInFuncTypeInfo;
+  procedure UseBuiltInFuncTypeInfo;
   var
     ParentParams: TPRParentParams;
     ParamResolved: TPasResolverResult;
     SubEl: TPasElement;
     Params: TPasExprArray;
+    ProcScope: TPasProcedureScope;
+    Proc: TPasProcedure;
   begin
     Resolver.GetParamsOfNameExpr(El,ParentParams);
     if ParentParams.Params=nil then
@@ -1672,7 +1677,11 @@ procedure TPasAnalyzer.UseExpr(El: TPasExpr);
     if (ParamResolved.IdentEl is TPasProcedure)
         and (TPasProcedure(ParamResolved.IdentEl).ProcType is TPasFunctionType) then
       begin
-      SubEl:=TPasFunctionType(TPasProcedure(ParamResolved.IdentEl).ProcType).ResultEl.ResultType;
+      Proc:=TPasProcedure(ParamResolved.IdentEl);
+      ProcScope:=Proc.CustomData as TPasProcedureScope;
+      if ProcScope.DeclarationProc<>nil then
+        Proc:=ProcScope.DeclarationProc;
+      SubEl:=TPasFunctionType(Proc.ProcType).ResultEl.ResultType;
       MarkImplScopeRef(El,SubEl,psraTypeInfo);
       UseTypeInfo(SubEl);
       end
@@ -1751,7 +1760,7 @@ begin
           end;
         bfTypeInfo:
           begin
-          UseBuilInFuncTypeInfo;
+          UseBuiltInFuncTypeInfo;
           exit;
           end;
         bfAssert:

+ 30 - 2
packages/pastojs/src/pas2jsfiler.pp

@@ -3461,7 +3461,7 @@ begin
         ParentRef.Obj.Add('Specs',ParentRef.Specs);
         end;
       ParentRef.Specs.Add(Ref.Obj);
-      if Ref.Id=0 then
+      if (Ref.Id=0) then
         CreateElReferenceId(Ref); // every specialization needs an ID
       end
     else
@@ -5658,11 +5658,12 @@ procedure TPCUReader.ResolveSpecializedElements(Complete: boolean);
     OtherPendSpec: TPCUReaderPendingSpecialized;
   begin
     Result:=false;
+    if PendSpec.RefEl=nil then exit;
     for i:=0 to PendSpec.Params.Count-1 do
       begin
       Param:=TPCUReaderPendingSpecializedParam(PendSpec.Params[i]);
       Ref:=GetElReference(Param.Id,PendSpec.GenericEl);
-      if Ref.Element<>nil then continue;
+      if (Ref=nil) or (Ref.Element<>nil) then continue;
       OtherPendSpec:=FPendingSpecialize;
       while OtherPendSpec<>nil do
         begin
@@ -5676,6 +5677,27 @@ procedure TPCUReader.ResolveSpecializedElements(Complete: boolean);
       end;
   end;
 
+  function FreeTemplateSpecialization(PendSpec: TPCUReaderPendingSpecialized): boolean;
+  // checks if PendSpec params are only TPasGenericTemplateType
+  // if yes, frees this PendSpec
+  var
+    i: Integer;
+    Param: TPCUReaderPendingSpecializedParam;
+    Ref: TPCUFilerElementRef;
+  begin
+    Result:=true;
+    for i:=0 to PendSpec.Params.Count-1 do
+      begin
+      Param:=TPCUReaderPendingSpecializedParam(PendSpec.Params[i]);
+      Ref:=GetElReference(Param.Id,PendSpec.GenericEl);
+      if Ref=nil then
+        exit(false);
+      if not (Ref.Element is TPasGenericTemplateType) then
+        exit(false);
+      end;
+    DeletePendingSpecialize(PendSpec);
+  end;
+
 var
   PendSpec, NextPendSpec, UnresolvedSpec: TPCUReaderPendingSpecialized;
   Changed: Boolean;
@@ -5688,6 +5710,7 @@ begin
     while PendSpec<>nil do
       begin
       NextPendSpec:=PendSpec.Next;
+
       if PendSpec.RefEl=nil then
         begin
         // no referrer -> use the first element, waiting for this ID
@@ -5705,6 +5728,11 @@ begin
           Changed:=true
         else
           UnresolvedSpec:=PendSpec;
+        end
+      else if Complete and (PendSpec.RefEl=nil) then
+        begin
+        if FreeTemplateSpecialization(PendSpec) then
+          Changed:=true;
         end;
       PendSpec:=NextPendSpec;
       end;