瀏覽代碼

fcl-passrc: pasanalyzer: fixed enumtype, mark typeinfo param as published

git-svn-id: trunk@35798 -
Mattias Gaertner 8 年之前
父節點
當前提交
17f6a4aacd
共有 2 個文件被更改,包括 125 次插入7 次删除
  1. 27 7
      packages/fcl-passrc/src/pasuseanalyzer.pas
  2. 98 0
      packages/fcl-passrc/tests/tcuseanalyzer.pas

+ 27 - 7
packages/fcl-passrc/src/pasuseanalyzer.pas

@@ -651,6 +651,7 @@ begin
     end
   else if (C=TPasAliasType) or (C=TPasTypeAliasType) then
     UsePublished(TPasAliasType(El).DestType)
+  else if C=TPasEnumType then
   else if C=TPasSetType then
     UsePublished(TPasSetType(El).EnumType)
   else if C=TPasArrayType then
@@ -673,7 +674,8 @@ begin
     Members:=TPasRecordType(El).Members;
     for i:=0 to Members.Count-1 do
       begin
-      UsePublished(TPasElement(Members[i]));
+      Member:=TPasElement(Members[i]);
+      UsePublished(Member);
       UseElement(Member,rraNone,true);
       end;
     end
@@ -953,18 +955,22 @@ var
   C: TClass;
   Params: TPasExprArray;
   i: Integer;
+  BuiltInProc: TResElDataBuiltInProc;
+  ParamResolved: TPasResolverResult;
+  Decl: TPasElement;
 begin
   if El=nil then exit;
   // expressions are not marked
 
+  Ref:=nil;
   if El.CustomData is TResolvedReference then
     begin
     // this is a reference -> mark target
     Ref:=TResolvedReference(El.CustomData);
-    UseElement(Ref.Declaration,Ref.Access,false);
+    Decl:=Ref.Declaration;
+    UseElement(Decl,Ref.Access,false);
 
-    if (El.ClassType=TSelfExpr)
-        or ((El.ClassType=TPrimitiveExpr) and (TPrimitiveExpr(El).Kind=pekIdent)) then
+    if Resolver.IsNameExpr(El) then
       begin
       if Ref.WithExprScope<>nil then
         begin
@@ -975,12 +981,12 @@ begin
           exit;
           end;
         end;
-      if (Ref.Declaration is TPasVariable)
+      if (Decl is TPasVariable)
           and (El.Parent is TBinaryExpr)
           and (TBinaryExpr(El.Parent).right=El) then
         begin
-        if ((Ref.Declaration.Parent is TPasRecordType)
-              or (Ref.Declaration.Parent is TPasVariant)) then
+        if ((Decl.Parent is TPasRecordType)
+              or (Decl.Parent is TPasVariant)) then
           begin
           // a record member was accessed -> access the record too
           UseExprRef(TBinaryExpr(El.Parent).left,Ref.Access,false);
@@ -988,6 +994,20 @@ begin
         end;
       end;
 
+    if Decl is TPasUnresolvedSymbolRef then
+      begin
+      if Decl.CustomData is TResElDataBuiltInProc then
+        begin
+        BuiltInProc:=TResElDataBuiltInProc(Decl.CustomData);
+        if BuiltInProc.BuiltIn=bfTypeInfo then
+          begin
+          Params:=(El.Parent as TParamsExpr).Params;
+          Resolver.ComputeElement(Params[0],ParamResolved,[]);
+          UsePublished(ParamResolved.IdentEl);
+          end;
+        end;
+      end;
+
     end;
   UseExpr(El.format1);
   UseExpr(El.format2);

+ 98 - 0
packages/fcl-passrc/tests/tcuseanalyzer.pas

@@ -107,6 +107,11 @@ type
     procedure TestWP_ProgramPublicDeclarations;
     procedure TestWP_ClassDefaultProperty;
     procedure TestWP_Published;
+    procedure TestWP_PublishedSetType;
+    procedure TestWP_PublishedArrayType;
+    procedure TestWP_PublishedClassOfType;
+    procedure TestWP_PublishedRecordType;
+    procedure TestWP_PublishedProcType;
     procedure TestWP_PublishedProperty;
   end;
 
@@ -1424,6 +1429,99 @@ begin
   AnalyzeWholeProgram;
 end;
 
+procedure TTestUseAnalyzer.TestWP_PublishedSetType;
+begin
+  StartProgram(false);
+  Add('type');
+  Add('  {#tflag_used}TFlag = (red, green);');
+  Add('  {#tflags_used}TFlags = set of TFlag;');
+  Add('  {#tobject_used}TObject = class');
+  Add('  published');
+  Add('    {#fielda_used}FieldA: TFlag;');
+  Add('    {#fieldb_used}FieldB: TFlags;');
+  Add('  end;');
+  Add('var');
+  Add('  {#o_used}o: TObject;');
+  Add('begin');
+  Add('  o:=nil;');
+  AnalyzeWholeProgram;
+end;
+
+procedure TTestUseAnalyzer.TestWP_PublishedArrayType;
+begin
+  StartProgram(false);
+  Add('type');
+  Add('  {#tdynarr_used}TDynArr = array of longint;');
+  Add('  {#tstatarr_used}TStatArr = array[boolean] of longint;');
+  Add('  {#tobject_used}TObject = class');
+  Add('  published');
+  Add('    {#fielda_used}FieldA: TDynArr;');
+  Add('    {#fieldb_used}FieldB: TStatArr;');
+  Add('  end;');
+  Add('var');
+  Add('  {#o_used}o: TObject;');
+  Add('begin');
+  Add('  o:=nil;');
+  AnalyzeWholeProgram;
+end;
+
+procedure TTestUseAnalyzer.TestWP_PublishedClassOfType;
+begin
+  StartProgram(false);
+  Add('type');
+  Add('  {#tobjectclass_used}TObjectClass = class of TObject;');
+  Add('  {#tobject_used}TObject = class');
+  Add('  published');
+  Add('    {#fielda_used}FieldA: TObjectClass;');
+  Add('  end;');
+  Add('  {#tclass_used}TClass = class of TObject;');
+  Add('var');
+  Add('  {#c_used}c: TClass;');
+  Add('begin');
+  Add('  c:=nil;');
+  AnalyzeWholeProgram;
+end;
+
+procedure TTestUseAnalyzer.TestWP_PublishedRecordType;
+begin
+  StartProgram(false);
+  Add('type');
+  Add('  {#trec_used}TRec = record');
+  Add('    {treci_used}i: longint;');
+  Add('  end;');
+  Add('  {#tobject_used}TObject = class');
+  Add('  published');
+  Add('    {#fielda_used}FieldA: TRec;');
+  Add('  end;');
+  Add('var');
+  Add('  {#o_used}o: TObject;');
+  Add('begin');
+  Add('  o:=nil;');
+  AnalyzeWholeProgram;
+end;
+
+procedure TTestUseAnalyzer.TestWP_PublishedProcType;
+begin
+  StartProgram(false);
+  Add('type');
+  Add('  {#ta_used}ta = array of longint;');
+  Add('  {#tb_used}tb = array of longint;');
+  Add('  {#tproca_used}TProcA = procedure;');
+  Add('  {#tfunca_used}TFuncA = function: ta;');
+  Add('  {#tprocb_used}TProcB = procedure(a: tb);');
+  Add('  {#tobject_used}TObject = class');
+  Add('  published');
+  Add('    {#fielda_used}FieldA: TProcA;');
+  Add('    {#fieldb_used}FieldB: TFuncA;');
+  Add('    {#fieldc_used}FieldC: TProcB;');
+  Add('  end;');
+  Add('var');
+  Add('  {#o_used}o: TObject;');
+  Add('begin');
+  Add('  o:=nil;');
+  AnalyzeWholeProgram;
+end;
+
 procedure TTestUseAnalyzer.TestWP_PublishedProperty;
 begin
   StartProgram(false);