mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-11 21:29:42 +02:00
fcl-passrc: useanalyzer: mark parents of nested elements
git-svn-id: trunk@41297 -
This commit is contained in:
parent
a12ca1c1a0
commit
739723bc54
@ -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;
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user