|
@@ -21,6 +21,7 @@ type
|
|
|
private
|
|
|
FAnalyzer: TPasAnalyzer;
|
|
|
FPAMessages: TFPList; // list of TPAMessage
|
|
|
+ FPAGoodMessages: TFPList;
|
|
|
function GetPAMessages(Index: integer): TPAMessage;
|
|
|
procedure OnAnalyzerMessage(Sender: TObject; Msg: TPAMessage);
|
|
|
protected
|
|
@@ -32,8 +33,9 @@ type
|
|
|
procedure AnalyzeWholeProgram; virtual;
|
|
|
procedure CheckUsedMarkers; virtual;
|
|
|
procedure CheckHasHint(MsgType: TMessageType; MsgNumber: integer;
|
|
|
- const MsgText: string; Has: boolean = true); virtual;
|
|
|
- procedure CheckUnitUsed(const aFilename: string; Used: boolean);
|
|
|
+ const MsgText: string); virtual;
|
|
|
+ procedure CheckUnexpectedMessages; virtual;
|
|
|
+ procedure CheckUnitUsed(const aFilename: string; Used: boolean); virtual;
|
|
|
public
|
|
|
property Analyzer: TPasAnalyzer read FAnalyzer;
|
|
|
function PAMessageCount: integer;
|
|
@@ -85,6 +87,7 @@ type
|
|
|
procedure TestM_Hint_PrivateFieldIsNeverUsed;
|
|
|
procedure TestM_Hint_PrivateFieldIsAssignedButNeverUsed;
|
|
|
procedure TestM_Hint_PrivateMethodIsNeverUsed;
|
|
|
+ procedure TestM_Hint_LocalDestructor_No_IsNeverUsed;
|
|
|
procedure TestM_Hint_PrivateTypeNeverUsed;
|
|
|
procedure TestM_Hint_PrivateConstNeverUsed;
|
|
|
procedure TestM_Hint_PrivatePropertyNeverUsed;
|
|
@@ -135,6 +138,7 @@ procedure TCustomTestUseAnalyzer.SetUp;
|
|
|
begin
|
|
|
inherited SetUp;
|
|
|
FPAMessages:=TFPList.Create;
|
|
|
+ FPAGoodMessages:=TFPList.Create;
|
|
|
FAnalyzer:=TPasAnalyzer.Create;
|
|
|
FAnalyzer.Resolver:=ResolverEngine;
|
|
|
Analyzer.OnMessage:=@OnAnalyzerMessage;
|
|
@@ -144,6 +148,7 @@ procedure TCustomTestUseAnalyzer.TearDown;
|
|
|
var
|
|
|
i: Integer;
|
|
|
begin
|
|
|
+ FreeAndNil(FPAGoodMessages);
|
|
|
for i:=0 to FPAMessages.Count-1 do
|
|
|
TPAMessage(FPAMessages[i]).Release;
|
|
|
FreeAndNil(FPAMessages);
|
|
@@ -234,7 +239,7 @@ begin
|
|
|
end;
|
|
|
|
|
|
procedure TCustomTestUseAnalyzer.CheckHasHint(MsgType: TMessageType;
|
|
|
- MsgNumber: integer; const MsgText: string; Has: boolean);
|
|
|
+ MsgNumber: integer; const MsgText: string);
|
|
|
var
|
|
|
i: Integer;
|
|
|
Msg: TPAMessage;
|
|
@@ -246,22 +251,14 @@ begin
|
|
|
Msg:=PAMessages[i];
|
|
|
if (Msg.MsgNumber=MsgNumber) then
|
|
|
begin
|
|
|
- if Has then
|
|
|
+ if (Msg.MsgType=MsgType) and (Msg.MsgText=MsgText) then
|
|
|
begin
|
|
|
- // must have -> message type and text must match exactly
|
|
|
- if (Msg.MsgType=MsgType) and (Msg.MsgText=MsgText) then
|
|
|
- exit;
|
|
|
- end
|
|
|
- else
|
|
|
- begin
|
|
|
- // must not have -> matching number is enough
|
|
|
- break;
|
|
|
+ FPAGoodMessages.Add(Msg);
|
|
|
+ exit;
|
|
|
end;
|
|
|
end;
|
|
|
dec(i);
|
|
|
end;
|
|
|
- if (not Has) and (i<0) then exit;
|
|
|
-
|
|
|
// mismatch
|
|
|
writeln('TCustomTestUseAnalyzer.CheckHasHint: ');
|
|
|
for i:=0 to PAMessageCount-1 do
|
|
@@ -271,7 +268,23 @@ begin
|
|
|
end;
|
|
|
s:='';
|
|
|
str(MsgType,s);
|
|
|
- Fail('Analyzer Message '+BoolToStr(Has,'not ','')+'found: '+s+': ('+IntToStr(MsgNumber)+') {'+MsgText+'}');
|
|
|
+ Fail('Analyzer Message not found: '+s+': ('+IntToStr(MsgNumber)+') {'+MsgText+'}');
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TCustomTestUseAnalyzer.CheckUnexpectedMessages;
|
|
|
+var
|
|
|
+ i: Integer;
|
|
|
+ Msg: TPAMessage;
|
|
|
+ s: String;
|
|
|
+begin
|
|
|
+ for i:=0 to PAMessageCount-1 do
|
|
|
+ begin
|
|
|
+ Msg:=PAMessages[i];
|
|
|
+ if FPAGoodMessages.IndexOf(Msg)>=0 then continue;
|
|
|
+ s:='';
|
|
|
+ str(Msg.MsgType,s);
|
|
|
+ Fail('Analyzer Message found ['+IntToStr(Msg.Id)+'] '+s+': ('+IntToStr(Msg.MsgNumber)+') {'+Msg.MsgText+'}');
|
|
|
+ end;
|
|
|
end;
|
|
|
|
|
|
procedure TCustomTestUseAnalyzer.CheckUnitUsed(const aFilename: string;
|
|
@@ -756,7 +769,7 @@ begin
|
|
|
Add(' {tmobile_used}TMobile = class(TObject)');
|
|
|
Add(' constructor {#mob_create_used}Create;');
|
|
|
Add(' procedure {#mob_doa_used}DoA; override;');
|
|
|
- Add(' procedure {#mob_dob_notused}DoB; override;');
|
|
|
+ Add(' procedure {#mob_dob_used}DoB; override;');
|
|
|
Add(' end;');
|
|
|
Add('constructor TMobile.Create; begin end;');
|
|
|
Add('procedure TMobile.DoA; begin end;');
|
|
@@ -838,6 +851,7 @@ begin
|
|
|
Add('begin');
|
|
|
AnalyzeProgram;
|
|
|
CheckHasHint(mtHint,nPAUnitNotUsed,'Unit "unit2" not used in afile');
|
|
|
+ CheckUnexpectedMessages;
|
|
|
end;
|
|
|
|
|
|
procedure TTestUseAnalyzer.TestM_Hint_UnitNotUsed_No_OnlyExternal;
|
|
@@ -858,7 +872,7 @@ begin
|
|
|
AnalyzeProgram;
|
|
|
|
|
|
// unit hints: no hint, even though no code is actually used
|
|
|
- CheckHasHint(mtHint,nPAUnitNotUsed,'Unit "unit2" not used in afile',false);
|
|
|
+ CheckUnexpectedMessages;
|
|
|
end;
|
|
|
|
|
|
procedure TTestUseAnalyzer.TestM_Hint_ParameterNotUsed;
|
|
@@ -870,6 +884,7 @@ begin
|
|
|
Add(' DoIt(1);');
|
|
|
AnalyzeProgram;
|
|
|
CheckHasHint(mtHint,nPAParameterNotUsed,'Parameter "i" not used');
|
|
|
+ CheckUnexpectedMessages;
|
|
|
end;
|
|
|
|
|
|
procedure TTestUseAnalyzer.TestM_Hint_ParameterNotUsed_Abstract;
|
|
@@ -882,8 +897,7 @@ begin
|
|
|
Add('begin');
|
|
|
Add(' TObject.DoIt(3);');
|
|
|
AnalyzeProgram;
|
|
|
- CheckHasHint(mtHint,nPAParameterNotUsed,
|
|
|
- sPAParameterNotUsed,false);
|
|
|
+ CheckUnexpectedMessages;
|
|
|
end;
|
|
|
|
|
|
procedure TTestUseAnalyzer.TestM_Hint_LocalVariableNotUsed;
|
|
@@ -904,6 +918,7 @@ begin
|
|
|
CheckHasHint(mtHint,nPALocalXYNotUsed,'Local constant "b" not used');
|
|
|
CheckHasHint(mtHint,nPALocalVariableNotUsed,'Local variable "c" not used');
|
|
|
CheckHasHint(mtHint,nPALocalVariableNotUsed,'Local variable "d" not used');
|
|
|
+ CheckUnexpectedMessages;
|
|
|
end;
|
|
|
|
|
|
procedure TTestUseAnalyzer.TestM_Hint_InterfaceUnitVariableUsed;
|
|
@@ -928,8 +943,14 @@ begin
|
|
|
Add(' {#ImpTFlags_notused}ImpTFlags = set of TFlag;');
|
|
|
Add(' {#ImpTArrInt_notused}ImpTArrInt = array of integer;');
|
|
|
AnalyzeUnit;
|
|
|
- CheckHasHint(mtHint,nPALocalVariableIsAssignedButNeverUsed,
|
|
|
- 'Local variable "a" is assigned but never used',false);
|
|
|
+ CheckHasHint(mtHint,nPALocalXYNotUsed,'Local constant "d" not used');
|
|
|
+ CheckHasHint(mtHint,nPALocalXYNotUsed,'Local constant "e" not used');
|
|
|
+ CheckHasHint(mtHint,nPALocalVariableNotUsed,'Local variable "f" not used');
|
|
|
+ CheckHasHint(mtHint,nPALocalXYNotUsed,'Local alias type "ImpTColor" not used');
|
|
|
+ CheckHasHint(mtHint,nPALocalXYNotUsed,'Local enumeration type "ImpTFlag" not used');
|
|
|
+ CheckHasHint(mtHint,nPALocalXYNotUsed,'Local set type "ImpTFlags" not used');
|
|
|
+ CheckHasHint(mtHint,nPALocalXYNotUsed,'Local array type "ImpTArrInt" not used');
|
|
|
+ CheckUnexpectedMessages;
|
|
|
end;
|
|
|
|
|
|
procedure TTestUseAnalyzer.TestM_Hint_ValueParameterIsAssignedButNeverUsed;
|
|
@@ -944,6 +965,7 @@ begin
|
|
|
AnalyzeProgram;
|
|
|
CheckHasHint(mtHint,nPAValueParameterIsAssignedButNeverUsed,
|
|
|
'Value parameter "i" is assigned but never used');
|
|
|
+ CheckUnexpectedMessages;
|
|
|
end;
|
|
|
|
|
|
procedure TTestUseAnalyzer.TestM_Hint_LocalVariableIsAssignedButNeverUsed;
|
|
@@ -969,6 +991,7 @@ begin
|
|
|
'Local variable "b" is assigned but never used');
|
|
|
CheckHasHint(mtHint,nPALocalVariableIsAssignedButNeverUsed,
|
|
|
'Local variable "c" is assigned but never used');
|
|
|
+ CheckUnexpectedMessages;
|
|
|
end;
|
|
|
|
|
|
procedure TTestUseAnalyzer.TestM_Hint_LocalXYNotUsed;
|
|
@@ -991,6 +1014,7 @@ begin
|
|
|
CheckHasHint(mtHint,nPALocalXYNotUsed,'Local set type "TFlags" not used');
|
|
|
CheckHasHint(mtHint,nPALocalXYNotUsed,'Local array type "TArrInt" not used');
|
|
|
CheckHasHint(mtHint,nPALocalXYNotUsed,'Local procedure "Sub" not used');
|
|
|
+ CheckUnexpectedMessages;
|
|
|
end;
|
|
|
|
|
|
procedure TTestUseAnalyzer.TestM_Hint_PrivateFieldIsNeverUsed;
|
|
@@ -1005,7 +1029,11 @@ begin
|
|
|
Add('begin');
|
|
|
Add(' m:=nil;');
|
|
|
AnalyzeProgram;
|
|
|
- CheckHasHint(mtHint,nPAPrivateFieldIsNeverUsed,'Private field "TMobile.a" is never used');
|
|
|
+ CheckHasHint(mtHint,nPAPrivateFieldIsNeverUsed,
|
|
|
+ 'Private field "TMobile.a" is never used');
|
|
|
+ CheckHasHint(mtHint,nPALocalVariableIsAssignedButNeverUsed,
|
|
|
+ 'Local variable "m" is assigned but never used');
|
|
|
+ CheckUnexpectedMessages;
|
|
|
end;
|
|
|
|
|
|
procedure TTestUseAnalyzer.TestM_Hint_PrivateFieldIsAssignedButNeverUsed;
|
|
@@ -1027,6 +1055,7 @@ begin
|
|
|
AnalyzeProgram;
|
|
|
CheckHasHint(mtHint,nPAPrivateFieldIsAssignedButNeverUsed,
|
|
|
'Private field "TMobile.a" is assigned but never used');
|
|
|
+ CheckUnexpectedMessages;
|
|
|
end;
|
|
|
|
|
|
procedure TTestUseAnalyzer.TestM_Hint_PrivateMethodIsNeverUsed;
|
|
@@ -1047,6 +1076,34 @@ begin
|
|
|
AnalyzeProgram;
|
|
|
CheckHasHint(mtHint,nPAPrivateMethodIsNeverUsed,
|
|
|
'Private method "TMobile.DoSome" is never used');
|
|
|
+ CheckUnexpectedMessages;
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TTestUseAnalyzer.TestM_Hint_LocalDestructor_No_IsNeverUsed;
|
|
|
+begin
|
|
|
+ StartProgram(true,[supTObject]);
|
|
|
+ Add('type');
|
|
|
+ Add(' TMobile = class');
|
|
|
+ Add(' private');
|
|
|
+ Add(' public');
|
|
|
+ Add(' constructor Create;');
|
|
|
+ Add(' destructor Destroy; override;');
|
|
|
+ Add(' end;');
|
|
|
+ Add('var DestroyCount: longint = 0;');
|
|
|
+ Add('constructor TMobile.Create;');
|
|
|
+ Add('begin');
|
|
|
+ Add('end;');
|
|
|
+ Add('destructor TMobile.Destroy;');
|
|
|
+ Add('begin');
|
|
|
+ Add(' inc(DestroyCount);');
|
|
|
+ Add(' inherited;');
|
|
|
+ Add('end;');
|
|
|
+ Add('var o: TObject;');
|
|
|
+ Add('begin');
|
|
|
+ Add(' o:=TMobile.Create;');
|
|
|
+ Add(' o.Destroy;');
|
|
|
+ AnalyzeProgram;
|
|
|
+ CheckUnexpectedMessages;
|
|
|
end;
|
|
|
|
|
|
procedure TTestUseAnalyzer.TestM_Hint_PrivateTypeNeverUsed;
|
|
@@ -1067,6 +1124,7 @@ begin
|
|
|
AnalyzeProgram;
|
|
|
CheckHasHint(mtHint,nPAPrivateTypeXNeverUsed,
|
|
|
'Private type "TMobile.t" never used');
|
|
|
+ CheckUnexpectedMessages;
|
|
|
end;
|
|
|
|
|
|
procedure TTestUseAnalyzer.TestM_Hint_PrivateConstNeverUsed;
|
|
@@ -1087,6 +1145,7 @@ begin
|
|
|
AnalyzeProgram;
|
|
|
CheckHasHint(mtHint,nPAPrivateConstXNeverUsed,
|
|
|
'Private const "TMobile.c" never used');
|
|
|
+ CheckUnexpectedMessages;
|
|
|
end;
|
|
|
|
|
|
procedure TTestUseAnalyzer.TestM_Hint_PrivatePropertyNeverUsed;
|
|
@@ -1108,6 +1167,9 @@ begin
|
|
|
AnalyzeProgram;
|
|
|
CheckHasHint(mtHint,nPAPrivatePropertyXNeverUsed,
|
|
|
'Private property "TMobile.A" never used');
|
|
|
+ CheckHasHint(mtHint,nPAPrivateFieldIsNeverUsed,
|
|
|
+ 'Private field "TMobile.FA" is never used');
|
|
|
+ CheckUnexpectedMessages;
|
|
|
end;
|
|
|
|
|
|
procedure TTestUseAnalyzer.TestM_Hint_LocalClassInProgramNotUsed;
|
|
@@ -1127,6 +1189,7 @@ begin
|
|
|
AnalyzeProgram;
|
|
|
CheckHasHint(mtHint,nPALocalXYNotUsed,'Local class "TMobile" not used');
|
|
|
CheckHasHint(mtHint,nPALocalVariableNotUsed,'Local variable "m" not used');
|
|
|
+ CheckUnexpectedMessages;
|
|
|
end;
|
|
|
|
|
|
procedure TTestUseAnalyzer.TestM_Hint_LocalMethodInProgramNotUsed;
|
|
@@ -1146,6 +1209,7 @@ begin
|
|
|
Add(' if m=nil then ;');
|
|
|
AnalyzeProgram;
|
|
|
CheckHasHint(mtHint,nPALocalXYNotUsed,'Local constructor "Create" not used');
|
|
|
+ CheckUnexpectedMessages;
|
|
|
end;
|
|
|
|
|
|
procedure TTestUseAnalyzer.TestM_Hint_AssemblerParameterIgnored;
|
|
@@ -1168,8 +1232,7 @@ begin
|
|
|
Add('begin');
|
|
|
Add(' DoIt(1);');
|
|
|
AnalyzeProgram;
|
|
|
- CheckHasHint(mtHint,nPAParameterNotUsed,'Parameter "i" not used',false);
|
|
|
- AssertEquals('no hints for assembler proc',0,PAMessageCount);
|
|
|
+ CheckUnexpectedMessages;
|
|
|
end;
|
|
|
|
|
|
procedure TTestUseAnalyzer.TestM_Hint_FunctionResultDoesNotSeemToBeSet;
|
|
@@ -1182,6 +1245,7 @@ begin
|
|
|
AnalyzeProgram;
|
|
|
CheckHasHint(mtHint,nPAFunctionResultDoesNotSeemToBeSet,
|
|
|
sPAFunctionResultDoesNotSeemToBeSet);
|
|
|
+ CheckUnexpectedMessages;
|
|
|
end;
|
|
|
|
|
|
procedure TTestUseAnalyzer.TestM_Hint_FunctionResultDoesNotSeemToBeSet_Abstract;
|
|
@@ -1194,8 +1258,7 @@ begin
|
|
|
Add('begin');
|
|
|
Add(' TObject.DoIt;');
|
|
|
AnalyzeProgram;
|
|
|
- CheckHasHint(mtHint,nPAFunctionResultDoesNotSeemToBeSet,
|
|
|
- sPAFunctionResultDoesNotSeemToBeSet,false);
|
|
|
+ CheckUnexpectedMessages;
|
|
|
end;
|
|
|
|
|
|
procedure TTestUseAnalyzer.TestM_Hint_FunctionResultRecord;
|
|
@@ -1203,15 +1266,17 @@ begin
|
|
|
StartProgram(true);
|
|
|
Add('type');
|
|
|
Add(' TPoint = record X,Y:longint; end;');
|
|
|
- Add('function Point(Left,Top: longint): TPoint;');
|
|
|
+ Add('function Point(Left: longint): TPoint;');
|
|
|
Add('begin');
|
|
|
Add(' Result.X:=Left;');
|
|
|
Add('end;');
|
|
|
Add('begin');
|
|
|
- Add(' Point(1,2);');
|
|
|
+ Add(' Point(1);');
|
|
|
AnalyzeProgram;
|
|
|
- CheckHasHint(mtHint,nPAFunctionResultDoesNotSeemToBeSet,
|
|
|
- sPAFunctionResultDoesNotSeemToBeSet,false);
|
|
|
+ CheckHasHint(mtHint,nPALocalVariableIsAssignedButNeverUsed,
|
|
|
+ 'Local variable "X" is assigned but never used');
|
|
|
+ CheckHasHint(mtHint,nPALocalVariableNotUsed,'Local variable "Y" not used');
|
|
|
+ CheckUnexpectedMessages;
|
|
|
end;
|
|
|
|
|
|
procedure TTestUseAnalyzer.TestM_Hint_FunctionResultPassRecordElement;
|
|
@@ -1223,15 +1288,15 @@ begin
|
|
|
Add('begin');
|
|
|
Add(' x:=3;');
|
|
|
Add('end;');
|
|
|
- Add('function Point(Left,Top: longint): TPoint;');
|
|
|
+ Add('function Point(): TPoint;');
|
|
|
Add('begin');
|
|
|
Add(' Three(Result.X)');
|
|
|
Add('end;');
|
|
|
Add('begin');
|
|
|
- Add(' Point(1,2);');
|
|
|
+ Add(' Point();');
|
|
|
AnalyzeProgram;
|
|
|
- CheckHasHint(mtHint,nPAFunctionResultDoesNotSeemToBeSet,
|
|
|
- sPAFunctionResultDoesNotSeemToBeSet,false);
|
|
|
+ CheckHasHint(mtHint,nPALocalVariableNotUsed,'Local variable "Y" not used');
|
|
|
+ CheckUnexpectedMessages;
|
|
|
end;
|
|
|
|
|
|
procedure TTestUseAnalyzer.TestM_Hint_OutParam_No_AssignedButNeverUsed;
|
|
@@ -1245,8 +1310,7 @@ begin
|
|
|
Add('begin');
|
|
|
Add(' DoIt(i);');
|
|
|
AnalyzeProgram;
|
|
|
- CheckHasHint(mtHint,nPAValueParameterIsAssignedButNeverUsed,
|
|
|
- sPAValueParameterIsAssignedButNeverUsed,false);
|
|
|
+ CheckUnexpectedMessages;
|
|
|
end;
|
|
|
|
|
|
procedure TTestUseAnalyzer.TestWP_LocalVar;
|