fcl-passrc: useanalyzer: mark parents of nested elements

git-svn-id: trunk@41297 -
This commit is contained in:
Mattias Gaertner 2019-02-11 12:15:22 +00:00
parent a12ca1c1a0
commit 739723bc54
3 changed files with 55 additions and 25 deletions

View File

@ -8861,6 +8861,12 @@ end;
procedure TPasResolver.ResolveSubIdent(El: TBinaryExpr; procedure TPasResolver.ResolveSubIdent(El: TBinaryExpr;
Access: TResolvedRefAccess); Access: TResolvedRefAccess);
procedure ResolveRight; inline;
begin
ResolveExpr(El.right,Access);
PopScope;
end;
function SearchInTypeHelpers(aType: TPasType; IdentEl: TPasElement): boolean; function SearchInTypeHelpers(aType: TPasType; IdentEl: TPasElement): boolean;
var var
DotScope: TPasDotBaseScope; DotScope: TPasDotBaseScope;
@ -8871,8 +8877,7 @@ procedure TPasResolver.ResolveSubIdent(El: TBinaryExpr;
if IdentEl is TPasType then if IdentEl is TPasType then
// e.g. TFlag.HelperProc // e.g. TFlag.HelperProc
DotScope.OnlyTypeMembers:=true; DotScope.OnlyTypeMembers:=true;
ResolveExpr(El.right,Access); ResolveRight;
PopScope;
Result:=true; Result:=true;
end; end;
@ -8901,8 +8906,7 @@ begin
// => search in interface and if this is our module in the implementation // => search in interface and if this is our module in the implementation
aModule:=NoNil(LeftResolved.IdentEl) as TPasModule; aModule:=NoNil(LeftResolved.IdentEl) as TPasModule;
PushModuleDotScope(aModule); PushModuleDotScope(aModule);
ResolveExpr(El.right,Access); ResolveRight;
PopScope;
exit; exit;
end end
else if LeftResolved.LoTypeEl=nil then else if LeftResolved.LoTypeEl=nil then
@ -8934,8 +8938,7 @@ begin
else else
// e.g. Image.Width // e.g. Image.Width
ClassScope.OnlyTypeMembers:=false; ClassScope.OnlyTypeMembers:=false;
ResolveExpr(El.right,Access); ResolveRight;
PopScope;
exit; exit;
end end
else if LTypeEl.ClassType=TPasClassOfType then else if LTypeEl.ClassType=TPasClassOfType then
@ -8945,8 +8948,7 @@ begin
ClassScope:=PushClassDotScope(ClassEl); ClassScope:=PushClassDotScope(ClassEl);
ClassScope.OnlyTypeMembers:=true; ClassScope.OnlyTypeMembers:=true;
ClassScope.IsClassOf:=true; ClassScope.IsClassOf:=true;
ResolveExpr(El.right,Access); ResolveRight;
PopScope;
exit; exit;
end end
else if LTypeEl.ClassType=TPasRecordType then else if LTypeEl.ClassType=TPasRecordType then
@ -8963,8 +8965,7 @@ begin
AccessExpr(El.left,Access); AccessExpr(El.left,Access);
RecordScope.OnlyTypeMembers:=false; RecordScope.OnlyTypeMembers:=false;
end; end;
ResolveExpr(El.right,Access); ResolveRight;
PopScope;
exit; exit;
end end
else if LTypeEl.ClassType=TPasEnumType then else if LTypeEl.ClassType=TPasEnumType then
@ -8974,8 +8975,7 @@ begin
// e.g. TShiftState.ssAlt // e.g. TShiftState.ssAlt
DotScope:=PushEnumDotScope(TPasEnumType(LTypeEl)); DotScope:=PushEnumDotScope(TPasEnumType(LTypeEl));
DotScope.OnlyTypeMembers:=true; DotScope.OnlyTypeMembers:=true;
ResolveExpr(El.right,Access); ResolveRight;
PopScope;
exit; exit;
end; end;
end; end;

View File

@ -260,7 +260,7 @@ type
procedure UseInheritedExpr(El: TInheritedExpr); virtual; procedure UseInheritedExpr(El: TInheritedExpr); virtual;
procedure UseScopeReferences(Refs: TPasScopeReferences); virtual; procedure UseScopeReferences(Refs: TPasScopeReferences); virtual;
procedure UseProcedure(Proc: TPasProcedure); virtual; procedure UseProcedure(Proc: TPasProcedure); virtual;
procedure UseProcedureType(ProcType: TPasProcedureType; Mark: boolean); virtual; procedure UseProcedureType(ProcType: TPasProcedureType); virtual;
procedure UseType(El: TPasType; Mode: TPAUseMode); virtual; procedure UseType(El: TPasType; Mode: TPAUseMode); virtual;
procedure UseClassOrRecType(El: TPasMembersType; Mode: TPAUseMode); virtual; procedure UseClassOrRecType(El: TPasMembersType; Mode: TPAUseMode); virtual;
procedure UseVariable(El: TPasVariable; Access: TResolvedRefAccess; procedure UseVariable(El: TPasVariable; Access: TResolvedRefAccess;
@ -1010,19 +1010,18 @@ begin
else if C.InheritsFrom(TPasExpr) then else if C.InheritsFrom(TPasExpr) then
UseExpr(TPasExpr(El)) UseExpr(TPasExpr(El))
else if C=TPasEnumValue then else if C=TPasEnumValue then
begin UseExpr(TPasEnumValue(El).Value)
UseExpr(TPasEnumValue(El).Value);
repeat
MarkElementAsUsed(El);
El:=El.Parent;
until not (El is TPasType);
end
else if C=TPasMethodResolution then else if C=TPasMethodResolution then
// nothing to do // nothing to do
else if (C.InheritsFrom(TPasModule)) or (C=TPasUsesUnit) then else if (C.InheritsFrom(TPasModule)) or (C=TPasUsesUnit) then
// e.g. unitname.identifier -> the module is used by the identifier // e.g. unitname.identifier -> the module is used by the identifier
else else
RaiseNotSupported(20170307090947,El); RaiseNotSupported(20170307090947,El);
repeat
El:=El.Parent;
if not (El is TPasType) then break;
MarkElementAsUsed(El);
until false;
end; end;
procedure TPasAnalyzer.UseTypeInfo(El: TPasElement); procedure TPasAnalyzer.UseTypeInfo(El: TPasElement);
@ -1729,7 +1728,7 @@ begin
{$ENDIF} {$ENDIF}
UseScopeReferences(ProcScope.References); UseScopeReferences(ProcScope.References);
UseProcedureType(Proc.ProcType,false); UseProcedureType(Proc.ProcType);
ImplProc:=Proc; ImplProc:=Proc;
if ProcScope.ImplProc<>nil then if ProcScope.ImplProc<>nil then
@ -1778,8 +1777,7 @@ begin
end; end;
end; end;
procedure TPasAnalyzer.UseProcedureType(ProcType: TPasProcedureType; procedure TPasAnalyzer.UseProcedureType(ProcType: TPasProcedureType);
Mark: boolean);
var var
i: Integer; i: Integer;
Arg: TPasArgument; Arg: TPasArgument;
@ -1787,7 +1785,7 @@ begin
{$IFDEF VerbosePasAnalyzer} {$IFDEF VerbosePasAnalyzer}
writeln('TPasAnalyzer.UseProcedureType ',GetElModName(ProcType)); writeln('TPasAnalyzer.UseProcedureType ',GetElModName(ProcType));
{$ENDIF} {$ENDIF}
if Mark and not MarkElementAsUsed(ProcType) then exit; if not MarkElementAsUsed(ProcType) then exit;
for i:=0 to ProcType.Args.Count-1 do for i:=0 to ProcType.Args.Count-1 do
begin begin
@ -1869,7 +1867,7 @@ begin
UseElType(El,TPasSetType(El).EnumType,Mode); UseElType(El,TPasSetType(El).EnumType,Mode);
end end
else if C.InheritsFrom(TPasProcedureType) then else if C.InheritsFrom(TPasProcedureType) then
UseProcedureType(TPasProcedureType(El),true) UseProcedureType(TPasProcedureType(El))
else else
RaiseNotSupported(20170306170315,El); RaiseNotSupported(20170306170315,El);

View File

@ -164,6 +164,7 @@ type
procedure TestWP_ClassInterface_COM_Unit; procedure TestWP_ClassInterface_COM_Unit;
procedure TestWP_ClassInterface_Typeinfo; procedure TestWP_ClassInterface_Typeinfo;
procedure TestWP_ClassInterface_TGUID; procedure TestWP_ClassInterface_TGUID;
procedure TestWP_ClassHelper;
// scope references // scope references
procedure TestSR_Proc_UnitVar; procedure TestSR_Proc_UnitVar;
@ -3061,6 +3062,37 @@ begin
AnalyzeWholeProgram; AnalyzeWholeProgram;
end; end;
procedure TTestUseAnalyzer.TestWP_ClassHelper;
begin
StartProgram(false);
Add([
'type',
' {#TObject_used}TObject = class',
' end;',
' {#TBird_used}TBird = class',
' {#TBird_A_notused}A: word;',
' end;',
' {#TAnt_used}TAnt = class',
' {#TAnt_B_notused}B: word;',
' type',
' {#TMouth_used}TMouth = class',
' {#TMouth_C_notused}C: word;',
' type',
' {#TBirdHelper_used}TBirdHelper = class helper for TBird',
' procedure {#TBirdHelper_Fly_used}Fly;',
' end;',
' end;',
' end;',
'procedure TAnt.TMouth.TBirdHelper.Fly;',
'begin',
'end;',
'var b: TBird;',
'begin',
' b.Fly;;',
'']);
AnalyzeWholeProgram;
end;
procedure TTestUseAnalyzer.TestSR_Proc_UnitVar; procedure TTestUseAnalyzer.TestSR_Proc_UnitVar;
begin begin
StartUnit(false); StartUnit(false);