diff --git a/packages/fcl-passrc/src/pasuseanalyzer.pas b/packages/fcl-passrc/src/pasuseanalyzer.pas index 9f914c7193..2b10b000b3 100644 --- a/packages/fcl-passrc/src/pasuseanalyzer.pas +++ b/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); diff --git a/packages/fcl-passrc/tests/tcuseanalyzer.pas b/packages/fcl-passrc/tests/tcuseanalyzer.pas index d032ae5151..aba1eff1ea 100644 --- a/packages/fcl-passrc/tests/tcuseanalyzer.pas +++ b/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);