tcuseanalyzer.pas 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763
  1. {
  2. Examples:
  3. ./testpassrc --suite=TTestResolver.TestEmpty
  4. }
  5. unit tcuseanalyzer;
  6. {$mode objfpc}{$H+}
  7. interface
  8. uses
  9. Classes, SysUtils, fpcunit,
  10. PasTree, PScanner, PasResolver,
  11. tcbaseparser, testregistry, strutils, tcresolver, PasUseAnalyzer;
  12. type
  13. { TCustomTestUseAnalyzer }
  14. TCustomTestUseAnalyzer = Class(TCustomTestResolver)
  15. private
  16. FAnalyzer: TPasAnalyzer;
  17. FPAMessages: TFPList; // list of TPAMessage
  18. FPAGoodMessages: TFPList;
  19. function GetPAMessages(Index: integer): TPAMessage;
  20. procedure OnAnalyzerMessage(Sender: TObject; Msg: TPAMessage);
  21. protected
  22. procedure SetUp; override;
  23. procedure TearDown; override;
  24. procedure AnalyzeModule; virtual;
  25. procedure AnalyzeProgram; virtual;
  26. procedure AnalyzeUnit; virtual;
  27. procedure AnalyzeWholeProgram; virtual;
  28. procedure CheckUsedMarkers; virtual;
  29. procedure CheckUseAnalyzerHint(MsgType: TMessageType; MsgNumber: integer;
  30. const MsgText: string); virtual;
  31. procedure CheckUseAnalyzerUnexpectedHints; virtual;
  32. procedure CheckUnitUsed(const aFilename: string; Used: boolean); virtual;
  33. public
  34. property Analyzer: TPasAnalyzer read FAnalyzer;
  35. function PAMessageCount: integer;
  36. property PAMessages[Index: integer]: TPAMessage read GetPAMessages;
  37. end;
  38. { TTestUseAnalyzer }
  39. TTestUseAnalyzer = Class(TCustomTestUseAnalyzer)
  40. published
  41. // single module
  42. procedure TestM_ProgramLocalVar;
  43. procedure TestM_AssignStatement;
  44. procedure TestM_BeginBlock;
  45. procedure TestM_ForLoopStatement;
  46. procedure TestM_AsmStatement;
  47. procedure TestM_CaseOfStatement;
  48. procedure TestM_IfThenElseStatement;
  49. procedure TestM_WhileDoStatement;
  50. procedure TestM_RepeatUntilStatement;
  51. procedure TestM_TryFinallyStatement;
  52. procedure TestM_TypeAlias;
  53. procedure TestM_Unary;
  54. procedure TestM_Const;
  55. procedure TestM_Record;
  56. procedure TestM_Array;
  57. procedure TestM_NestedFuncResult;
  58. procedure TestM_Enums;
  59. procedure TestM_ProcedureType;
  60. procedure TestM_Params;
  61. procedure TestM_Class;
  62. procedure TestM_ClassForward;
  63. procedure TestM_Class_Property;
  64. procedure TestM_Class_PropertyOverride;
  65. procedure TestM_Class_MethodOverride;
  66. procedure TestM_Class_MethodOverride2;
  67. procedure TestM_TryExceptStatement;
  68. // single module hints
  69. procedure TestM_Hint_UnitNotUsed;
  70. procedure TestM_Hint_UnitNotUsed_No_OnlyExternal;
  71. procedure TestM_Hint_ParameterNotUsed;
  72. procedure TestM_Hint_ParameterNotUsed_Abstract;
  73. procedure TestM_Hint_ParameterNotUsedTypecast;
  74. procedure TestM_Hint_LocalVariableNotUsed;
  75. procedure TestM_Hint_ForVar_No_LocalVariableNotUsed;
  76. procedure TestM_Hint_InterfaceUnitVariableUsed;
  77. procedure TestM_Hint_ValueParameterIsAssignedButNeverUsed;
  78. procedure TestM_Hint_LocalVariableIsAssignedButNeverUsed;
  79. procedure TestM_Hint_LocalXYNotUsed;
  80. procedure TestM_Hint_PrivateFieldIsNeverUsed;
  81. procedure TestM_Hint_PrivateFieldIsAssignedButNeverUsed;
  82. procedure TestM_Hint_PrivateMethodIsNeverUsed;
  83. procedure TestM_Hint_LocalDestructor_No_IsNeverUsed;
  84. procedure TestM_Hint_PrivateTypeNeverUsed;
  85. procedure TestM_Hint_PrivateConstNeverUsed;
  86. procedure TestM_Hint_PrivatePropertyNeverUsed;
  87. procedure TestM_Hint_LocalClassInProgramNotUsed;
  88. procedure TestM_Hint_LocalMethodInProgramNotUsed;
  89. procedure TestM_Hint_AssemblerParameterIgnored;
  90. procedure TestM_Hint_AssemblerDelphiParameterIgnored;
  91. procedure TestM_Hint_FunctionResultDoesNotSeemToBeSet;
  92. procedure TestM_Hint_FunctionResultDoesNotSeemToBeSet_Abstract;
  93. procedure TestM_Hint_FunctionResultRecord;
  94. procedure TestM_Hint_FunctionResultPassRecordElement;
  95. procedure TestM_Hint_OutParam_No_AssignedButNeverUsed;
  96. procedure TestM_Hint_ArgPassed_No_ParameterNotUsed;
  97. // whole program optimization
  98. procedure TestWP_LocalVar;
  99. procedure TestWP_UnitUsed;
  100. procedure TestWP_UnitNotUsed;
  101. procedure TestWP_UnitInitialization;
  102. procedure TestWP_UnitFinalization;
  103. procedure TestWP_CallInherited;
  104. procedure TestWP_ProgramPublicDeclarations;
  105. procedure TestWP_ClassDefaultProperty;
  106. procedure TestWP_Published;
  107. procedure TestWP_PublishedSetType;
  108. procedure TestWP_PublishedArrayType;
  109. procedure TestWP_PublishedClassOfType;
  110. procedure TestWP_PublishedRecordType;
  111. procedure TestWP_PublishedProcType;
  112. procedure TestWP_PublishedProperty;
  113. procedure TestWP_BuiltInFunctions;
  114. procedure TestWP_TypeInfo;
  115. end;
  116. implementation
  117. { TCustomTestUseAnalyzer }
  118. procedure TCustomTestUseAnalyzer.OnAnalyzerMessage(Sender: TObject;
  119. Msg: TPAMessage);
  120. begin
  121. Msg.AddRef;
  122. FPAMessages.Add(Msg);
  123. end;
  124. function TCustomTestUseAnalyzer.GetPAMessages(Index: integer): TPAMessage;
  125. begin
  126. Result:=TPAMessage(FPAMessages[Index]);
  127. end;
  128. procedure TCustomTestUseAnalyzer.SetUp;
  129. begin
  130. inherited SetUp;
  131. FPAMessages:=TFPList.Create;
  132. FPAGoodMessages:=TFPList.Create;
  133. FAnalyzer:=TPasAnalyzer.Create;
  134. FAnalyzer.Resolver:=ResolverEngine;
  135. Analyzer.OnMessage:=@OnAnalyzerMessage;
  136. end;
  137. procedure TCustomTestUseAnalyzer.TearDown;
  138. var
  139. i: Integer;
  140. begin
  141. FreeAndNil(FPAGoodMessages);
  142. for i:=0 to FPAMessages.Count-1 do
  143. TPAMessage(FPAMessages[i]).Release;
  144. FreeAndNil(FPAMessages);
  145. FreeAndNil(FAnalyzer);
  146. inherited TearDown;
  147. end;
  148. procedure TCustomTestUseAnalyzer.AnalyzeModule;
  149. begin
  150. Analyzer.AnalyzeModule(Module);
  151. Analyzer.EmitModuleHints(Module);
  152. CheckUsedMarkers;
  153. end;
  154. procedure TCustomTestUseAnalyzer.AnalyzeProgram;
  155. begin
  156. ParseProgram;
  157. AnalyzeModule;
  158. end;
  159. procedure TCustomTestUseAnalyzer.AnalyzeUnit;
  160. begin
  161. ParseUnit;
  162. AnalyzeModule;
  163. end;
  164. procedure TCustomTestUseAnalyzer.AnalyzeWholeProgram;
  165. begin
  166. ParseProgram;
  167. Analyzer.AnalyzeWholeProgram(Module as TPasProgram);
  168. CheckUsedMarkers;
  169. end;
  170. procedure TCustomTestUseAnalyzer.CheckUsedMarkers;
  171. var
  172. aMarker: PSrcMarker;
  173. p: SizeInt;
  174. Postfix: String;
  175. Elements: TFPList;
  176. i: Integer;
  177. El: TPasElement;
  178. ExpectedUsed: Boolean;
  179. FoundEl: TPAElement;
  180. begin
  181. aMarker:=FirstSrcMarker;
  182. while aMarker<>nil do
  183. begin
  184. writeln('TCustomTestUseAnalyzer.CheckUsedMarkers ',aMarker^.Identifier,' Line=',aMarker^.Row,' StartCol=',aMarker^.StartCol,' EndCol=',aMarker^.EndCol);
  185. p:=RPos('_',aMarker^.Identifier);
  186. if p>1 then
  187. begin
  188. Postfix:=copy(aMarker^.Identifier,p+1);
  189. if Postfix='used' then
  190. ExpectedUsed:=true
  191. else if Postfix='notused' then
  192. ExpectedUsed:=false
  193. else
  194. RaiseErrorAtSrcMarker('TCustomTestUseAnalyzer.CheckUsedMarkers unknown postfix "'+Postfix+'"',aMarker);
  195. Elements:=FindElementsAt(aMarker);
  196. try
  197. FoundEl:=nil;
  198. for i:=0 to Elements.Count-1 do
  199. begin
  200. El:=TPasElement(Elements[i]);
  201. writeln('TCustomTestUseAnalyzer.CheckUsedMarkers ',aMarker^.Identifier,' ',i,'/',Elements.Count,' El=',GetObjName(El),' ',GetObjName(El.CustomData));
  202. FoundEl:=Analyzer.FindElement(El);
  203. if FoundEl<>nil then break;
  204. end;
  205. if FoundEl<>nil then
  206. begin
  207. if not ExpectedUsed then
  208. RaiseErrorAtSrcMarker('expected element to be *not* used, but it is marked',aMarker);
  209. end
  210. else
  211. begin
  212. if ExpectedUsed then
  213. RaiseErrorAtSrcMarker('expected element to be used, but it is not marked',aMarker);
  214. end;
  215. finally
  216. Elements.Free;
  217. end;
  218. end;
  219. aMarker:=aMarker^.Next;
  220. end;
  221. end;
  222. procedure TCustomTestUseAnalyzer.CheckUseAnalyzerHint(MsgType: TMessageType;
  223. MsgNumber: integer; const MsgText: string);
  224. var
  225. i: Integer;
  226. Msg: TPAMessage;
  227. s: string;
  228. begin
  229. i:=PAMessageCount-1;
  230. while i>=0 do
  231. begin
  232. Msg:=PAMessages[i];
  233. if (Msg.MsgNumber=MsgNumber) then
  234. begin
  235. if (Msg.MsgType=MsgType) and (Msg.MsgText=MsgText) then
  236. begin
  237. FPAGoodMessages.Add(Msg);
  238. exit;
  239. end;
  240. end;
  241. dec(i);
  242. end;
  243. // mismatch
  244. writeln('TCustomTestUseAnalyzer.CheckHasHint: ');
  245. for i:=0 to PAMessageCount-1 do
  246. begin
  247. Msg:=PAMessages[i];
  248. writeln(' ',i,'/',PAMessageCount,': [',Msg.Id,'] ',Msg.MsgType,': (',Msg.MsgNumber,') {',Msg.MsgText,'}');
  249. end;
  250. s:='';
  251. str(MsgType,s);
  252. Fail('Analyzer Message not found: '+s+': ('+IntToStr(MsgNumber)+') {'+MsgText+'}');
  253. end;
  254. procedure TCustomTestUseAnalyzer.CheckUseAnalyzerUnexpectedHints;
  255. var
  256. i: Integer;
  257. Msg: TPAMessage;
  258. s: String;
  259. begin
  260. for i:=0 to PAMessageCount-1 do
  261. begin
  262. Msg:=PAMessages[i];
  263. if FPAGoodMessages.IndexOf(Msg)>=0 then continue;
  264. s:='';
  265. str(Msg.MsgType,s);
  266. Fail('Unexpected analyzer message found ['+IntToStr(Msg.Id)+'] '+s+': ('+IntToStr(Msg.MsgNumber)+') {'+Msg.MsgText+'}');
  267. end;
  268. end;
  269. procedure TCustomTestUseAnalyzer.CheckUnitUsed(const aFilename: string;
  270. Used: boolean);
  271. var
  272. aResolver: TTestEnginePasResolver;
  273. PAEl: TPAElement;
  274. begin
  275. aResolver:=FindModuleWithFilename(aFilename);
  276. AssertNotNull('unit not found "'+aFilename+'"',aResolver);
  277. AssertNotNull('unit module not found "'+aFilename+'"',aResolver.Module);
  278. PAEl:=Analyzer.FindElement(aResolver.Module);
  279. if PAEl<>nil then
  280. begin
  281. // unit is used
  282. if not Used then
  283. Fail('expected unit "'+aFilename+'" not used, but it is used');
  284. end
  285. else
  286. begin
  287. // unit is not used
  288. if Used then
  289. Fail('expected unit "'+aFilename+'" used, but it is not used');
  290. end;
  291. end;
  292. function TCustomTestUseAnalyzer.PAMessageCount: integer;
  293. begin
  294. Result:=FPAMessages.Count;
  295. end;
  296. { TTestUseAnalyzer }
  297. procedure TTestUseAnalyzer.TestM_ProgramLocalVar;
  298. begin
  299. StartProgram(false);
  300. Add('procedure {#DoIt_used}DoIt;');
  301. Add('var {#l_notused}l: longint;');
  302. Add('begin');
  303. Add('end;');
  304. Add('begin');
  305. Add(' DoIt;');
  306. AnalyzeProgram;
  307. end;
  308. procedure TTestUseAnalyzer.TestM_AssignStatement;
  309. begin
  310. StartProgram(false);
  311. Add('procedure {#DoIt_used}DoIt;');
  312. Add('var');
  313. Add(' {#a_notused}a: longint;');
  314. Add(' {#b_used}b: longint;');
  315. Add(' {#c_used}c: longint;');
  316. Add('begin');
  317. Add(' b:=c;');
  318. Add('end;');
  319. Add('begin');
  320. Add(' DoIt;');
  321. AnalyzeProgram;
  322. end;
  323. procedure TTestUseAnalyzer.TestM_BeginBlock;
  324. begin
  325. StartProgram(false);
  326. Add('procedure {#DoIt_used}DoIt;');
  327. Add('var');
  328. Add(' {#a_used}a: longint;');
  329. Add('begin');
  330. Add(' begin');
  331. Add(' a:=1;');
  332. Add(' end;');
  333. Add('end;');
  334. Add('begin');
  335. Add(' DoIt;');
  336. AnalyzeProgram;
  337. end;
  338. procedure TTestUseAnalyzer.TestM_ForLoopStatement;
  339. begin
  340. StartProgram(false);
  341. Add('procedure {#DoIt_used}DoIt;');
  342. Add('var');
  343. Add(' {#a_used}a: longint;');
  344. Add(' {#b_used}b: longint;');
  345. Add(' {#c_used}c: longint;');
  346. Add(' {#d_used}d: longint;');
  347. Add('begin');
  348. Add(' for a:=b to c do d:=a;');
  349. Add('end;');
  350. Add('begin');
  351. Add(' DoIt;');
  352. AnalyzeProgram;
  353. end;
  354. procedure TTestUseAnalyzer.TestM_AsmStatement;
  355. begin
  356. StartProgram(false);
  357. Add('procedure {#DoIt_used}DoIt;');
  358. Add('begin');
  359. Add(' asm end;');
  360. Add('end;');
  361. Add('begin');
  362. Add(' DoIt;');
  363. AnalyzeProgram;
  364. end;
  365. procedure TTestUseAnalyzer.TestM_CaseOfStatement;
  366. begin
  367. StartProgram(false);
  368. Add('procedure {#DoIt_used}DoIt;');
  369. Add('const');
  370. Add(' {#a_used}a = 1;');
  371. Add(' {#b_used}b = 2;');
  372. Add('var');
  373. Add(' {#c_used}c: longint;');
  374. Add(' {#d_used}d: longint;');
  375. Add('begin');
  376. Add(' case a of');
  377. Add(' b: c:=1;');
  378. Add(' else');
  379. Add(' d:=2;');
  380. Add(' end;');
  381. Add('end;');
  382. Add('begin');
  383. Add(' DoIt;');
  384. AnalyzeProgram;
  385. end;
  386. procedure TTestUseAnalyzer.TestM_IfThenElseStatement;
  387. begin
  388. StartProgram(false);
  389. Add('procedure {#DoIt_used}DoIt;');
  390. Add('var');
  391. Add(' {#a_used}a: longint;');
  392. Add(' {#b_used}b: longint;');
  393. Add(' {#c_used}c: longint;');
  394. Add('begin');
  395. Add(' if a=0 then b:=1 else c:=2;');
  396. Add('end;');
  397. Add('begin');
  398. Add(' DoIt;');
  399. AnalyzeProgram;
  400. end;
  401. procedure TTestUseAnalyzer.TestM_WhileDoStatement;
  402. begin
  403. StartProgram(false);
  404. Add('procedure {#DoIt_used}DoIt;');
  405. Add('var');
  406. Add(' {#a_used}a: longint;');
  407. Add(' {#b_used}b: longint;');
  408. Add('begin');
  409. Add(' while a>0 do b:=1;');
  410. Add('end;');
  411. Add('begin');
  412. Add(' DoIt;');
  413. AnalyzeProgram;
  414. end;
  415. procedure TTestUseAnalyzer.TestM_RepeatUntilStatement;
  416. begin
  417. StartProgram(false);
  418. Add('procedure {#DoIt_used}DoIt;');
  419. Add('var');
  420. Add(' {#a_used}a: longint;');
  421. Add(' {#b_used}b: longint;');
  422. Add('begin');
  423. Add(' repeat a:=1; until b>1;');
  424. Add('end;');
  425. Add('begin');
  426. Add(' DoIt;');
  427. AnalyzeProgram;
  428. end;
  429. procedure TTestUseAnalyzer.TestM_TryFinallyStatement;
  430. begin
  431. StartProgram(false);
  432. Add('procedure {#DoIt_used}DoIt;');
  433. Add('var');
  434. Add(' {#a_used}a: longint;');
  435. Add(' {#b_used}b: longint;');
  436. Add('begin');
  437. Add(' try');
  438. Add(' a:=1;');
  439. Add(' finally');
  440. Add(' b:=2;');
  441. Add(' end;');
  442. Add('end;');
  443. Add('begin');
  444. Add(' DoIt;');
  445. AnalyzeProgram;
  446. end;
  447. procedure TTestUseAnalyzer.TestM_TypeAlias;
  448. begin
  449. StartProgram(false);
  450. Add('procedure {#DoIt_used}DoIt;');
  451. Add('type');
  452. Add(' {#integer_used}integer = longint;');
  453. Add('var');
  454. Add(' {#a_used}a: integer;');
  455. Add(' {#b_used}b: integer;');
  456. Add(' {#c_notused}c: integer;');
  457. Add('begin');
  458. Add(' a:=b;');
  459. Add('end;');
  460. Add('begin');
  461. Add(' DoIt;');
  462. AnalyzeProgram;
  463. end;
  464. procedure TTestUseAnalyzer.TestM_Unary;
  465. begin
  466. StartProgram(false);
  467. Add('procedure {#DoIt_used}DoIt;');
  468. Add('var');
  469. Add(' {#a_used}a: longint;');
  470. Add(' {#b_used}b: longint;');
  471. Add(' {#c_used}c: longint;');
  472. Add(' {#d_used}d: longint;');
  473. Add('begin');
  474. Add(' a:=+b;');
  475. Add(' a:=c+d;');
  476. Add('end;');
  477. Add('begin');
  478. Add(' DoIt;');
  479. AnalyzeProgram;
  480. end;
  481. procedure TTestUseAnalyzer.TestM_Const;
  482. begin
  483. StartProgram(false);
  484. Add('procedure {#DoIt_used}DoIt;');
  485. Add('var');
  486. Add(' {#a_used}a: longint;');
  487. Add(' {#b_used}b: boolean;');
  488. Add(' {#c_used}c: array of longint;');
  489. Add(' {#d_used}d: string;');
  490. Add('begin');
  491. Add(' a:=+1;');
  492. Add(' b:=true;');
  493. Add(' c:=nil;');
  494. Add(' d:=''foo'';');
  495. Add('end;');
  496. Add('begin');
  497. Add(' DoIt;');
  498. AnalyzeProgram;
  499. end;
  500. procedure TTestUseAnalyzer.TestM_Record;
  501. begin
  502. StartProgram(false);
  503. Add('procedure {#DoIt_used}DoIt;');
  504. Add('type');
  505. Add(' {#integer_used}integer = longint;');
  506. Add(' {#trec_used}TRec = record');
  507. Add(' {#a_used}a: integer;');
  508. Add(' {#b_notused}b: integer;');
  509. Add(' {#c_used}c: integer;');
  510. Add(' end;');
  511. Add('var');
  512. Add(' {#r_used}r: TRec;');
  513. Add('begin');
  514. Add(' r.a:=3;');
  515. Add(' with r do c:=4;');
  516. Add('end;');
  517. Add('begin');
  518. Add(' DoIt;');
  519. AnalyzeProgram;
  520. end;
  521. procedure TTestUseAnalyzer.TestM_Array;
  522. begin
  523. StartProgram(false);
  524. Add('procedure {#DoIt_used}DoIt;');
  525. Add('type');
  526. Add(' {#integer_used}integer = longint;');
  527. Add(' {#tarrayint_used}TArrayInt = array of integer;');
  528. Add('var');
  529. Add(' {#a_used}a: TArrayInt;');
  530. Add(' {#b_used}b: integer;');
  531. Add(' {#c_used}c: TArrayInt;');
  532. Add(' {#d_used}d: integer;');
  533. Add(' {#e_used}e: TArrayInt;');
  534. Add(' {#f_used}f: integer;');
  535. Add(' {#g_used}g: TArrayInt;');
  536. Add(' {#h_used}h: TArrayInt;');
  537. Add(' {#i_used}i: TArrayInt;');
  538. Add('begin');
  539. Add(' a[b]:=c[d];');
  540. Add(' SetLength(e,f)');
  541. Add(' if low(g)=high(h)+length(i) then');
  542. Add('end;');
  543. Add('begin');
  544. Add(' DoIt;');
  545. AnalyzeProgram;
  546. end;
  547. procedure TTestUseAnalyzer.TestM_NestedFuncResult;
  548. begin
  549. StartProgram(false);
  550. Add('procedure {#DoIt_used}DoIt;');
  551. Add('type');
  552. Add(' {#integer_used}integer = longint;');
  553. Add(' {#tarrayint_used}TArrayInt = array of integer;');
  554. Add(' function {#nestedfunc_used}NestedFunc({#b_notused}b: longint): TArrayInt;');
  555. Add(' begin');
  556. Add(' end;');
  557. Add('var');
  558. Add(' {#d_used}d: longint;');
  559. Add('begin');
  560. Add(' NestedFunc(d);');
  561. Add('end;');
  562. Add('begin');
  563. Add(' DoIt;');
  564. AnalyzeProgram;
  565. end;
  566. procedure TTestUseAnalyzer.TestM_Enums;
  567. begin
  568. StartProgram(false);
  569. Add('procedure {#DoIt_used}DoIt(const o);');
  570. Add('type');
  571. Add(' {#TEnum_used}TEnum = (red,blue);');
  572. Add(' {#TEnums_used}TEnums = set of TEnum;');
  573. Add('var');
  574. Add(' {#a_used}a: TEnum;');
  575. Add(' {#b_used}b: TEnums;');
  576. Add(' {#c_used}c: TEnum;');
  577. Add(' {#d_used}d: TEnums;');
  578. Add(' {#e_used}e: TEnums;');
  579. Add(' {#f_used}f: TEnums;');
  580. Add(' {#g_used}g: TEnum;');
  581. Add(' {#h_used}h: TEnum;');
  582. Add('begin');
  583. Add(' b:=[a];');
  584. Add(' if c in d then;');
  585. Add(' if low(e)=high(f) then;');
  586. Add(' if pred(g)=succ(h) then;');
  587. Add('end;');
  588. Add('var {#s_used}s: string;');
  589. Add('begin');
  590. Add(' DoIt(s);');
  591. AnalyzeProgram;
  592. end;
  593. procedure TTestUseAnalyzer.TestM_ProcedureType;
  594. begin
  595. StartProgram(false);
  596. Add('procedure {#DoIt_used}DoIt;');
  597. Add('type');
  598. Add(' {#TProc_used}TProc = procedure;');
  599. Add(' {#TFunc_used}TFunc = function(): longint;');
  600. Add('var');
  601. Add(' {#p_used}p: TProc;');
  602. Add(' {#f_used}f: TFunc;');
  603. Add('begin');
  604. Add(' p:=nil;');
  605. Add(' f:=nil;');
  606. Add('end;');
  607. Add('begin');
  608. Add(' DoIt;');
  609. AnalyzeProgram;
  610. end;
  611. procedure TTestUseAnalyzer.TestM_Params;
  612. begin
  613. StartProgram(false);
  614. Add('procedure {#DoIt_used}DoIt(const o);');
  615. Add('type');
  616. Add(' {#TEnum_used}TEnum = (red,blue);');
  617. Add('var');
  618. Add(' {#a_used}a: longint;');
  619. Add(' {#b_used}b: string;');
  620. Add(' {#c_used}c: longint;');
  621. Add(' {#d_used}d: TEnum;');
  622. Add('begin');
  623. Add(' DoIt(a);');
  624. Add(' DoIt(b[c]);');
  625. Add(' DoIt([d]);');
  626. Add(' DoIt(red);');
  627. Add('end;');
  628. Add('var {#s_used}s: string;');
  629. Add('begin');
  630. Add(' DoIt(s);');
  631. AnalyzeProgram;
  632. end;
  633. procedure TTestUseAnalyzer.TestM_Class;
  634. begin
  635. StartProgram(false);
  636. Add('type');
  637. Add(' {#integer_used}integer = longint;');
  638. Add(' {tobject_used}TObject = class');
  639. Add(' {#a_used}a: integer;');
  640. Add(' end;');
  641. Add('var Obj: TObject;');
  642. Add('begin');
  643. Add(' Obj.a:=3;');
  644. AnalyzeProgram;
  645. end;
  646. procedure TTestUseAnalyzer.TestM_ClassForward;
  647. begin
  648. StartProgram(false);
  649. Add('type');
  650. Add(' {#integer_notused}integer = longint;');
  651. Add(' {#TObject_used}TObject = class end;');
  652. Add(' TFelidae = class;');
  653. Add(' {#TCheetah_used}TCheetah = class');
  654. Add(' public');
  655. Add(' {#i_notused}i: integer;');
  656. Add(' {#f_used}f: TFelidae;');
  657. Add(' end;');
  658. Add(' {TFelidae_used}TFelidae = class');
  659. Add(' end;');
  660. Add('var {#c_used}c: TCheetah;');
  661. Add('begin');
  662. Add(' c.f:=nil;');
  663. AnalyzeProgram;
  664. end;
  665. procedure TTestUseAnalyzer.TestM_Class_Property;
  666. begin
  667. StartProgram(false);
  668. Add('type');
  669. Add(' {#integer_used}integer = longint;');
  670. Add(' {tobject_used}TObject = class');
  671. Add(' {#fa_used}Fa: integer;');
  672. Add(' {#fb_used}Fb: integer;');
  673. Add(' {#fc_used}Fc: integer;');
  674. Add(' {#fd_used}Fd: integer;');
  675. Add(' {#fe_notused}Fe: integer;');
  676. Add(' function {#getfc_used}GetFC: integer;');
  677. Add(' procedure {#setfd_used}SetFD({#setfd_value_used}Value: integer);');
  678. Add(' property {#A_used}A: integer read Fa write Fb;');
  679. Add(' property {#C_used}C: integer read GetFC write SetFD;');
  680. Add(' end;');
  681. Add('function TObject.GetFC: integer;');
  682. Add('begin');
  683. Add(' Result:=Fc;');
  684. Add('end;');
  685. Add('procedure TObject.SetFD({#setfd_value_impl_notused}Value: integer);');
  686. Add('begin');
  687. Add(' Fd:=Value;');
  688. Add('end;');
  689. Add('var Obj: TObject;');
  690. Add('begin');
  691. Add(' Obj.A:=Obj.A;');
  692. Add(' Obj.C:=Obj.C;');
  693. AnalyzeProgram;
  694. end;
  695. procedure TTestUseAnalyzer.TestM_Class_PropertyOverride;
  696. begin
  697. StartProgram(false);
  698. Add('type');
  699. Add(' {#integer_used}integer = longint;');
  700. Add(' {tobject_used}TObject = class');
  701. Add(' {#fa_used}FA: integer;');
  702. Add(' {#fb_notused}FB: integer;');
  703. Add(' property {#obj_a_notused}A: integer read FA write FB;');
  704. Add(' end;');
  705. Add(' {tmobile_used}TMobile = class(TObject)');
  706. Add(' {#fc_used}FC: integer;');
  707. Add(' property {#mob_a_used}A write FC;');
  708. Add(' end;');
  709. Add('var {#m_used}M: TMobile;');
  710. Add('begin');
  711. Add(' M.A:=M.A;');
  712. AnalyzeProgram;
  713. end;
  714. procedure TTestUseAnalyzer.TestM_Class_MethodOverride;
  715. begin
  716. StartProgram(false);
  717. Add('type');
  718. Add(' {tobject_used}TObject = class');
  719. Add(' procedure {#obj_doa_used}DoA; virtual; abstract;');
  720. Add(' procedure {#obj_dob_notused}DoB; virtual; abstract;');
  721. Add(' end;');
  722. Add(' {tmobile_used}TMobile = class(TObject)');
  723. Add(' constructor {#mob_create_used}Create;');
  724. Add(' procedure {#mob_doa_used}DoA; override;');
  725. Add(' procedure {#mob_dob_used}DoB; override;');
  726. Add(' end;');
  727. Add('constructor TMobile.Create; begin end;');
  728. Add('procedure TMobile.DoA; begin end;');
  729. Add('procedure TMobile.DoB; begin end;');
  730. Add('var {#o_used}o: TObject;');
  731. Add('begin');
  732. Add(' o:=TMobile.Create;'); // use TMobile before o.DoA
  733. Add(' o.DoA;');
  734. AnalyzeProgram;
  735. end;
  736. procedure TTestUseAnalyzer.TestM_Class_MethodOverride2;
  737. begin
  738. StartProgram(false);
  739. Add('type');
  740. Add(' {tobject_used}TObject = class');
  741. Add(' procedure {#obj_doa_used}DoA; virtual; abstract;');
  742. Add(' end;');
  743. Add(' {tmobile_used}TMobile = class(TObject)');
  744. Add(' constructor {#mob_create_used}Create;');
  745. Add(' procedure {#mob_doa_used}DoA; override;');
  746. Add(' end;');
  747. Add('constructor TMobile.Create; begin end;');
  748. Add('procedure TMobile.DoA; begin end;');
  749. Add('var {#o_used}o: TObject;');
  750. Add('begin');
  751. Add(' o.DoA;');
  752. Add(' o:=TMobile.Create;'); // use TMobile after o.DoA
  753. AnalyzeProgram;
  754. end;
  755. procedure TTestUseAnalyzer.TestM_TryExceptStatement;
  756. begin
  757. StartProgram(false);
  758. Add('type');
  759. Add(' {tobject_used}TObject = class');
  760. Add(' constructor Create; external name ''create'';');
  761. Add(' end;');
  762. Add(' {texception_used}Exception = class(TObject);');
  763. Add(' {tdivbyzero_used}EDivByZero = class(Exception);');
  764. Add('procedure {#DoIt_used}DoIt;');
  765. Add('var');
  766. Add(' {#a_used}a: Exception;');
  767. Add(' {#b_used}b: Exception;');
  768. Add(' {#c_used}c: Exception;');
  769. Add(' {#d_used}d: Exception;');
  770. Add(' {#f_used}f: Exception;');
  771. Add('begin');
  772. Add(' try');
  773. Add(' a:=nil;');
  774. Add(' except');
  775. Add(' raise b;');
  776. Add(' end;');
  777. Add(' try');
  778. Add(' if Assigned(c) then ;');
  779. Add(' except');
  780. Add(' on {#e1_used}E1: Exception do raise;');
  781. Add(' on {#e2_notused}E2: EDivByZero do raise d;');
  782. Add(' else f:=nil;');
  783. Add(' end;');
  784. Add('end;');
  785. Add('begin');
  786. Add(' DoIt;');
  787. AnalyzeProgram;
  788. end;
  789. procedure TTestUseAnalyzer.TestM_Hint_UnitNotUsed;
  790. begin
  791. AddModuleWithIntfImplSrc('unit2.pp',
  792. LinesToStr([
  793. 'var i: longint;',
  794. 'procedure DoIt;',
  795. '']),
  796. LinesToStr([
  797. 'procedure DoIt; begin end;']));
  798. StartProgram(true);
  799. Add('uses unit2;');
  800. Add('begin');
  801. AnalyzeProgram;
  802. CheckUseAnalyzerHint(mtHint,nPAUnitNotUsed,'Unit "unit2" not used in afile');
  803. CheckUseAnalyzerUnexpectedHints;
  804. end;
  805. procedure TTestUseAnalyzer.TestM_Hint_UnitNotUsed_No_OnlyExternal;
  806. begin
  807. AddModuleWithIntfImplSrc('unit2.pp',
  808. LinesToStr([
  809. 'var State: longint; external name ''state'';',
  810. 'procedure DoIt; external name ''doing'';',
  811. '']),
  812. LinesToStr([
  813. ]));
  814. StartProgram(true);
  815. Add('uses unit2;');
  816. Add('begin');
  817. Add(' State:=3;');
  818. Add(' DoIt;');
  819. AnalyzeProgram;
  820. // unit hints: no hint, even though no code is actually used
  821. CheckUseAnalyzerUnexpectedHints;
  822. end;
  823. procedure TTestUseAnalyzer.TestM_Hint_ParameterNotUsed;
  824. begin
  825. StartProgram(true);
  826. Add('procedure DoIt(i: longint);');
  827. Add('begin end;');
  828. Add('begin');
  829. Add(' DoIt(1);');
  830. AnalyzeProgram;
  831. CheckUseAnalyzerHint(mtHint,nPAParameterNotUsed,'Parameter "i" not used');
  832. CheckUseAnalyzerUnexpectedHints;
  833. end;
  834. procedure TTestUseAnalyzer.TestM_Hint_ParameterNotUsed_Abstract;
  835. begin
  836. StartProgram(true);
  837. Add('type');
  838. Add(' TObject = class');
  839. Add(' class procedure DoIt(i: longint); virtual; abstract;');
  840. Add(' end;');
  841. Add('begin');
  842. Add(' TObject.DoIt(3);');
  843. AnalyzeProgram;
  844. CheckUseAnalyzerUnexpectedHints;
  845. end;
  846. procedure TTestUseAnalyzer.TestM_Hint_ParameterNotUsedTypecast;
  847. begin
  848. StartProgram(true);
  849. Add('type');
  850. Add(' TObject = class end;');
  851. Add(' TSortCompare = function(a,b: Pointer): integer;');
  852. Add(' TObjCompare = function(a,b: TObject): integer;');
  853. Add('procedure Sort(const Compare: TSortCompare);');
  854. Add('begin');
  855. Add(' Compare(nil,nil);');
  856. Add('end;');
  857. Add('procedure DoIt(const Compare: TObjCompare);');
  858. Add('begin');
  859. Add(' Sort(TSortCompare(Compare));');
  860. Add('end;');
  861. Add('begin');
  862. Add(' DoIt(nil);');
  863. AnalyzeProgram;
  864. CheckUseAnalyzerUnexpectedHints;
  865. end;
  866. procedure TTestUseAnalyzer.TestM_Hint_LocalVariableNotUsed;
  867. begin
  868. StartProgram(true);
  869. Add('procedure DoIt;');
  870. Add('const');
  871. Add(' a = 13;');
  872. Add(' b: longint = 14;');
  873. Add('var');
  874. Add(' c: char;');
  875. Add(' d: longint = 15;');
  876. Add('begin end;');
  877. Add('begin');
  878. Add(' DoIt;');
  879. AnalyzeProgram;
  880. CheckUseAnalyzerHint(mtHint,nPALocalXYNotUsed,'Local constant "a" not used');
  881. CheckUseAnalyzerHint(mtHint,nPALocalXYNotUsed,'Local constant "b" not used');
  882. CheckUseAnalyzerHint(mtHint,nPALocalVariableNotUsed,'Local variable "c" not used');
  883. CheckUseAnalyzerHint(mtHint,nPALocalVariableNotUsed,'Local variable "d" not used');
  884. CheckUseAnalyzerUnexpectedHints;
  885. end;
  886. procedure TTestUseAnalyzer.TestM_Hint_ForVar_No_LocalVariableNotUsed;
  887. begin
  888. StartProgram(false);
  889. Add([
  890. 'procedure DoIt;',
  891. 'var i: longint;',
  892. 'begin',
  893. ' for i:=1 to 2 do ;',
  894. 'end;',
  895. 'begin',
  896. ' DoIt;',
  897. '']);
  898. AnalyzeProgram;
  899. CheckUseAnalyzerUnexpectedHints;
  900. end;
  901. procedure TTestUseAnalyzer.TestM_Hint_InterfaceUnitVariableUsed;
  902. begin
  903. StartUnit(true);
  904. Add('interface');
  905. Add('const {#a_used}a = 1;');
  906. Add('const {#b_used}b: longint = 2;');
  907. Add('var {#c_used}c: longint = 3;');
  908. Add('type');
  909. Add(' {#TColor_used}TColor = longint;');
  910. Add(' {#TFlag_used}TFlag = (red,green);');
  911. Add(' {#TFlags_used}TFlags = set of TFlag;');
  912. Add(' {#TArrInt_used}TArrInt = array of integer;');
  913. Add('implementation');
  914. Add('const {#d_notused}d = 1;');
  915. Add('const {#e_notused}e: longint = 2;');
  916. Add('var {#f_notused}f: longint = 3;');
  917. Add('type');
  918. Add(' {#ImpTColor_notused}ImpTColor = longint;');
  919. Add(' {#ImpTFlag_notused}ImpTFlag = (red,green);');
  920. Add(' {#ImpTFlags_notused}ImpTFlags = set of TFlag;');
  921. Add(' {#ImpTArrInt_notused}ImpTArrInt = array of integer;');
  922. AnalyzeUnit;
  923. CheckUseAnalyzerHint(mtHint,nPALocalXYNotUsed,'Local constant "d" not used');
  924. CheckUseAnalyzerHint(mtHint,nPALocalXYNotUsed,'Local constant "e" not used');
  925. CheckUseAnalyzerHint(mtHint,nPALocalVariableNotUsed,'Local variable "f" not used');
  926. CheckUseAnalyzerHint(mtHint,nPALocalXYNotUsed,'Local alias type "ImpTColor" not used');
  927. CheckUseAnalyzerHint(mtHint,nPALocalXYNotUsed,'Local enumeration type "ImpTFlag" not used');
  928. CheckUseAnalyzerHint(mtHint,nPALocalXYNotUsed,'Local set type "ImpTFlags" not used');
  929. CheckUseAnalyzerHint(mtHint,nPALocalXYNotUsed,'Local array type "ImpTArrInt" not used');
  930. CheckUseAnalyzerUnexpectedHints;
  931. end;
  932. procedure TTestUseAnalyzer.TestM_Hint_ValueParameterIsAssignedButNeverUsed;
  933. begin
  934. StartProgram(true);
  935. Add('procedure DoIt(i: longint);');
  936. Add('begin');
  937. Add(' i:=3;');
  938. Add('end;');
  939. Add('begin');
  940. Add(' DoIt(1);');
  941. AnalyzeProgram;
  942. CheckUseAnalyzerHint(mtHint,nPAValueParameterIsAssignedButNeverUsed,
  943. 'Value parameter "i" is assigned but never used');
  944. CheckUseAnalyzerUnexpectedHints;
  945. end;
  946. procedure TTestUseAnalyzer.TestM_Hint_LocalVariableIsAssignedButNeverUsed;
  947. begin
  948. StartProgram(true);
  949. Add('procedure DoIt;');
  950. Add('const');
  951. Add(' a: longint = 14;');
  952. Add('var');
  953. Add(' b: char;');
  954. Add(' c: longint = 15;');
  955. Add('begin');
  956. Add(' a:=16;');
  957. Add(' b:=#65;');
  958. Add(' c:=17;');
  959. Add('end;');
  960. Add('begin');
  961. Add(' DoIt;');
  962. AnalyzeProgram;
  963. CheckUseAnalyzerHint(mtHint,nPALocalVariableIsAssignedButNeverUsed,
  964. 'Local variable "a" is assigned but never used');
  965. CheckUseAnalyzerHint(mtHint,nPALocalVariableIsAssignedButNeverUsed,
  966. 'Local variable "b" is assigned but never used');
  967. CheckUseAnalyzerHint(mtHint,nPALocalVariableIsAssignedButNeverUsed,
  968. 'Local variable "c" is assigned but never used');
  969. CheckUseAnalyzerUnexpectedHints;
  970. end;
  971. procedure TTestUseAnalyzer.TestM_Hint_LocalXYNotUsed;
  972. begin
  973. StartProgram(true);
  974. Add('procedure DoIt;');
  975. Add('type');
  976. Add(' TColor = longint;');
  977. Add(' TFlag = (red,green);');
  978. Add(' TFlags = set of TFlag;');
  979. Add(' TArrInt = array of integer;');
  980. Add(' procedure Sub; begin end;');
  981. Add('begin');
  982. Add('end;');
  983. Add('begin');
  984. Add(' DoIt;');
  985. AnalyzeProgram;
  986. CheckUseAnalyzerHint(mtHint,nPALocalXYNotUsed,'Local alias type "TColor" not used');
  987. CheckUseAnalyzerHint(mtHint,nPALocalXYNotUsed,'Local enumeration type "TFlag" not used');
  988. CheckUseAnalyzerHint(mtHint,nPALocalXYNotUsed,'Local set type "TFlags" not used');
  989. CheckUseAnalyzerHint(mtHint,nPALocalXYNotUsed,'Local array type "TArrInt" not used');
  990. CheckUseAnalyzerHint(mtHint,nPALocalXYNotUsed,'Local procedure "Sub" not used');
  991. CheckUseAnalyzerUnexpectedHints;
  992. end;
  993. procedure TTestUseAnalyzer.TestM_Hint_PrivateFieldIsNeverUsed;
  994. begin
  995. StartProgram(true,[supTObject]);
  996. Add('type');
  997. Add(' TMobile = class');
  998. Add(' private');
  999. Add(' a: longint;');
  1000. Add(' end;');
  1001. Add('var m: TMobile;');
  1002. Add('begin');
  1003. Add(' m:=nil;');
  1004. AnalyzeProgram;
  1005. CheckUseAnalyzerHint(mtHint,nPAPrivateFieldIsNeverUsed,
  1006. 'Private field "TMobile.a" is never used');
  1007. CheckUseAnalyzerHint(mtHint,nPALocalVariableIsAssignedButNeverUsed,
  1008. 'Local variable "m" is assigned but never used');
  1009. CheckUseAnalyzerUnexpectedHints;
  1010. end;
  1011. procedure TTestUseAnalyzer.TestM_Hint_PrivateFieldIsAssignedButNeverUsed;
  1012. begin
  1013. StartProgram(true,[supTObject]);
  1014. Add('type');
  1015. Add(' TMobile = class');
  1016. Add(' private');
  1017. Add(' a: longint;');
  1018. Add(' public');
  1019. Add(' constructor Create;');
  1020. Add(' end;');
  1021. Add('constructor TMobile.Create;');
  1022. Add('begin');
  1023. Add(' a:=3;');
  1024. Add('end;');
  1025. Add('begin');
  1026. Add(' TMobile.Create;');
  1027. AnalyzeProgram;
  1028. CheckUseAnalyzerHint(mtHint,nPAPrivateFieldIsAssignedButNeverUsed,
  1029. 'Private field "TMobile.a" is assigned but never used');
  1030. CheckUseAnalyzerUnexpectedHints;
  1031. end;
  1032. procedure TTestUseAnalyzer.TestM_Hint_PrivateMethodIsNeverUsed;
  1033. begin
  1034. StartProgram(true,[supTObject]);
  1035. Add('type');
  1036. Add(' TMobile = class');
  1037. Add(' private');
  1038. Add(' procedure DoSome; external name ''foo'';');
  1039. Add(' public');
  1040. Add(' constructor Create;');
  1041. Add(' end;');
  1042. Add('constructor TMobile.Create;');
  1043. Add('begin');
  1044. Add('end;');
  1045. Add('begin');
  1046. Add(' TMobile.Create;');
  1047. AnalyzeProgram;
  1048. CheckUseAnalyzerHint(mtHint,nPAPrivateMethodIsNeverUsed,
  1049. 'Private method "TMobile.DoSome" is never used');
  1050. CheckUseAnalyzerUnexpectedHints;
  1051. end;
  1052. procedure TTestUseAnalyzer.TestM_Hint_LocalDestructor_No_IsNeverUsed;
  1053. begin
  1054. StartProgram(true,[supTObject]);
  1055. Add('type');
  1056. Add(' TMobile = class');
  1057. Add(' private');
  1058. Add(' public');
  1059. Add(' constructor Create;');
  1060. Add(' destructor Destroy; override;');
  1061. Add(' end;');
  1062. Add('var DestroyCount: longint = 0;');
  1063. Add('constructor TMobile.Create;');
  1064. Add('begin');
  1065. Add('end;');
  1066. Add('destructor TMobile.Destroy;');
  1067. Add('begin');
  1068. Add(' inc(DestroyCount);');
  1069. Add(' inherited;');
  1070. Add('end;');
  1071. Add('var o: TObject;');
  1072. Add('begin');
  1073. Add(' o:=TMobile.Create;');
  1074. Add(' o.Destroy;');
  1075. AnalyzeProgram;
  1076. CheckUseAnalyzerUnexpectedHints;
  1077. end;
  1078. procedure TTestUseAnalyzer.TestM_Hint_PrivateTypeNeverUsed;
  1079. begin
  1080. StartProgram(true,[supTObject]);
  1081. Add('type');
  1082. Add(' TMobile = class');
  1083. Add(' private');
  1084. Add(' type t = longint;');
  1085. Add(' public');
  1086. Add(' constructor Create;');
  1087. Add(' end;');
  1088. Add('constructor TMobile.Create;');
  1089. Add('begin');
  1090. Add('end;');
  1091. Add('begin');
  1092. Add(' TMobile.Create;');
  1093. AnalyzeProgram;
  1094. CheckUseAnalyzerHint(mtHint,nPAPrivateTypeXNeverUsed,
  1095. 'Private type "TMobile.t" never used');
  1096. CheckUseAnalyzerUnexpectedHints;
  1097. end;
  1098. procedure TTestUseAnalyzer.TestM_Hint_PrivateConstNeverUsed;
  1099. begin
  1100. StartProgram(true,[supTObject]);
  1101. Add('type');
  1102. Add(' TMobile = class');
  1103. Add(' private');
  1104. Add(' const c = 3;');
  1105. Add(' public');
  1106. Add(' constructor Create;');
  1107. Add(' end;');
  1108. Add('constructor TMobile.Create;');
  1109. Add('begin');
  1110. Add('end;');
  1111. Add('begin');
  1112. Add(' TMobile.Create;');
  1113. AnalyzeProgram;
  1114. CheckUseAnalyzerHint(mtHint,nPAPrivateConstXNeverUsed,
  1115. 'Private const "TMobile.c" never used');
  1116. CheckUseAnalyzerUnexpectedHints;
  1117. end;
  1118. procedure TTestUseAnalyzer.TestM_Hint_PrivatePropertyNeverUsed;
  1119. begin
  1120. StartProgram(true,[supTObject]);
  1121. Add('type');
  1122. Add(' TMobile = class');
  1123. Add(' private');
  1124. Add(' FA: longint;');
  1125. Add(' property A: longint read FA;');
  1126. Add(' public');
  1127. Add(' constructor Create;');
  1128. Add(' end;');
  1129. Add('constructor TMobile.Create;');
  1130. Add('begin');
  1131. Add('end;');
  1132. Add('begin');
  1133. Add(' TMobile.Create;');
  1134. AnalyzeProgram;
  1135. CheckUseAnalyzerHint(mtHint,nPAPrivatePropertyXNeverUsed,
  1136. 'Private property "TMobile.A" never used');
  1137. CheckUseAnalyzerHint(mtHint,nPAPrivateFieldIsNeverUsed,
  1138. 'Private field "TMobile.FA" is never used');
  1139. CheckUseAnalyzerUnexpectedHints;
  1140. end;
  1141. procedure TTestUseAnalyzer.TestM_Hint_LocalClassInProgramNotUsed;
  1142. begin
  1143. StartProgram(true,[supTObject]);
  1144. Add('type');
  1145. Add(' TMobile = class');
  1146. Add(' public');
  1147. Add(' constructor Create;');
  1148. Add(' end;');
  1149. Add('constructor TMobile.Create;');
  1150. Add('begin');
  1151. Add('end;');
  1152. Add('var');
  1153. Add(' m: TMobile;');
  1154. Add('begin');
  1155. AnalyzeProgram;
  1156. CheckUseAnalyzerHint(mtHint,nPALocalXYNotUsed,'Local class "TMobile" not used');
  1157. CheckUseAnalyzerHint(mtHint,nPALocalVariableNotUsed,'Local variable "m" not used');
  1158. CheckUseAnalyzerUnexpectedHints;
  1159. end;
  1160. procedure TTestUseAnalyzer.TestM_Hint_LocalMethodInProgramNotUsed;
  1161. begin
  1162. StartProgram(true,[supTObject]);
  1163. Add('type');
  1164. Add(' TMobile = class');
  1165. Add(' public');
  1166. Add(' constructor Create;');
  1167. Add(' end;');
  1168. Add('constructor TMobile.Create;');
  1169. Add('begin');
  1170. Add('end;');
  1171. Add('var');
  1172. Add(' m: TMobile;');
  1173. Add('begin');
  1174. Add(' if m=nil then ;');
  1175. AnalyzeProgram;
  1176. CheckUseAnalyzerHint(mtHint,nPALocalXYNotUsed,'Local constructor "Create" not used');
  1177. CheckUseAnalyzerUnexpectedHints;
  1178. end;
  1179. procedure TTestUseAnalyzer.TestM_Hint_AssemblerParameterIgnored;
  1180. begin
  1181. StartProgram(true);
  1182. Add('procedure DoIt(i: longint); assembler;');
  1183. Add('type');
  1184. Add(' {#tcolor_notused}TColor = longint;');
  1185. Add(' {#tflag_notused}TFlag = (red,green);');
  1186. Add(' {#tflags_notused}TFlags = set of TFlag;');
  1187. Add(' {#tarrint_notused}TArrInt = array of integer;');
  1188. Add('const');
  1189. Add(' {#a_notused}a = 13;');
  1190. Add(' {#b_notused}b: longint = 14;');
  1191. Add('var');
  1192. Add(' {#c_notused}c: char;');
  1193. Add(' {#d_notused}d: longint = 15;');
  1194. Add(' procedure {#sub_notused}Sub; begin end;');
  1195. Add('asm end;');
  1196. Add('begin');
  1197. Add(' DoIt(1);');
  1198. AnalyzeProgram;
  1199. CheckUseAnalyzerUnexpectedHints;
  1200. end;
  1201. procedure TTestUseAnalyzer.TestM_Hint_AssemblerDelphiParameterIgnored;
  1202. begin
  1203. StartProgram(true);
  1204. Add([
  1205. '{$mode Delphi}',
  1206. 'procedure DoIt(i: longint);',
  1207. 'type',
  1208. ' {#tcolor_notused}TColor = longint;',
  1209. ' {#tflag_notused}TFlag = (red,green);',
  1210. ' {#tflags_notused}TFlags = set of TFlag;',
  1211. ' {#tarrint_notused}TArrInt = array of integer;',
  1212. 'const',
  1213. ' {#a_notused}a = 13;',
  1214. ' {#b_notused}b: longint = 14;',
  1215. 'var',
  1216. ' {#c_notused}c: char;',
  1217. ' {#d_notused}d: longint = 15;',
  1218. ' procedure {#sub_notused}Sub; begin end;',
  1219. 'asm end;',
  1220. 'begin',
  1221. ' DoIt(1);',
  1222. '']);
  1223. AnalyzeProgram;
  1224. CheckUseAnalyzerUnexpectedHints;
  1225. end;
  1226. procedure TTestUseAnalyzer.TestM_Hint_FunctionResultDoesNotSeemToBeSet;
  1227. begin
  1228. StartProgram(true);
  1229. Add('function DoIt: longint;');
  1230. Add('begin end;');
  1231. Add('begin');
  1232. Add(' DoIt();');
  1233. AnalyzeProgram;
  1234. CheckUseAnalyzerHint(mtHint,nPAFunctionResultDoesNotSeemToBeSet,
  1235. sPAFunctionResultDoesNotSeemToBeSet);
  1236. CheckUseAnalyzerUnexpectedHints;
  1237. end;
  1238. procedure TTestUseAnalyzer.TestM_Hint_FunctionResultDoesNotSeemToBeSet_Abstract;
  1239. begin
  1240. StartProgram(true);
  1241. Add('type');
  1242. Add(' TObject = class');
  1243. Add(' class function DoIt: longint; virtual; abstract;');
  1244. Add(' end;');
  1245. Add('begin');
  1246. Add(' TObject.DoIt;');
  1247. AnalyzeProgram;
  1248. CheckUseAnalyzerUnexpectedHints;
  1249. end;
  1250. procedure TTestUseAnalyzer.TestM_Hint_FunctionResultRecord;
  1251. begin
  1252. StartProgram(true);
  1253. Add('type');
  1254. Add(' TPoint = record X,Y:longint; end;');
  1255. Add('function Point(Left: longint): TPoint;');
  1256. Add('begin');
  1257. Add(' Result.X:=Left;');
  1258. Add('end;');
  1259. Add('begin');
  1260. Add(' Point(1);');
  1261. AnalyzeProgram;
  1262. CheckUseAnalyzerHint(mtHint,nPALocalVariableIsAssignedButNeverUsed,
  1263. 'Local variable "X" is assigned but never used');
  1264. CheckUseAnalyzerHint(mtHint,nPALocalVariableNotUsed,'Local variable "Y" not used');
  1265. CheckUseAnalyzerUnexpectedHints;
  1266. end;
  1267. procedure TTestUseAnalyzer.TestM_Hint_FunctionResultPassRecordElement;
  1268. begin
  1269. StartProgram(true);
  1270. Add('type');
  1271. Add(' TPoint = record X,Y:longint; end;');
  1272. Add('procedure Three(out x: longint);');
  1273. Add('begin');
  1274. Add(' x:=3;');
  1275. Add('end;');
  1276. Add('function Point(): TPoint;');
  1277. Add('begin');
  1278. Add(' Three(Result.X)');
  1279. Add('end;');
  1280. Add('begin');
  1281. Add(' Point();');
  1282. AnalyzeProgram;
  1283. CheckUseAnalyzerHint(mtHint,nPALocalVariableNotUsed,'Local variable "Y" not used');
  1284. CheckUseAnalyzerUnexpectedHints;
  1285. end;
  1286. procedure TTestUseAnalyzer.TestM_Hint_OutParam_No_AssignedButNeverUsed;
  1287. begin
  1288. StartProgram(true);
  1289. Add('procedure DoIt(out x: longint);');
  1290. Add('begin');
  1291. Add(' x:=3;');
  1292. Add('end;');
  1293. Add('var i: longint;');
  1294. Add('begin');
  1295. Add(' DoIt(i);');
  1296. AnalyzeProgram;
  1297. CheckUseAnalyzerUnexpectedHints;
  1298. end;
  1299. procedure TTestUseAnalyzer.TestM_Hint_ArgPassed_No_ParameterNotUsed;
  1300. begin
  1301. StartProgram(false);
  1302. Add([
  1303. 'procedure AssertTrue(b: boolean);',
  1304. 'begin',
  1305. ' if b then ;',
  1306. 'end;',
  1307. 'procedure AssertFalse(b: boolean);',
  1308. 'begin',
  1309. ' AssertTrue(not b);',
  1310. 'end;',
  1311. 'begin',
  1312. ' AssertFalse(true);',
  1313. '']);
  1314. AnalyzeProgram;
  1315. CheckUseAnalyzerUnexpectedHints;
  1316. end;
  1317. procedure TTestUseAnalyzer.TestWP_LocalVar;
  1318. begin
  1319. StartProgram(false);
  1320. Add('var {#a_notused}a: longint;');
  1321. Add('var {#b_used}b: longint;');
  1322. Add('var {#c_used}c: longint;');
  1323. Add('begin');
  1324. Add(' b:=2;');
  1325. Add(' afile.c:=3;');
  1326. AnalyzeWholeProgram;
  1327. end;
  1328. procedure TTestUseAnalyzer.TestWP_UnitUsed;
  1329. begin
  1330. AddModuleWithIntfImplSrc('unit2.pp',
  1331. LinesToStr([
  1332. 'var i: longint;',
  1333. 'procedure DoIt;',
  1334. '']),
  1335. LinesToStr([
  1336. 'procedure DoIt; begin end;']));
  1337. StartProgram(true);
  1338. Add('uses unit2;');
  1339. Add('begin');
  1340. Add(' i:=3;');
  1341. AnalyzeWholeProgram;
  1342. CheckUnitUsed('unit2.pp',true);
  1343. end;
  1344. procedure TTestUseAnalyzer.TestWP_UnitNotUsed;
  1345. begin
  1346. AddModuleWithIntfImplSrc('unit2.pp',
  1347. LinesToStr([
  1348. 'var i: longint;',
  1349. 'procedure DoIt;',
  1350. '']),
  1351. LinesToStr([
  1352. 'procedure DoIt; begin end;']));
  1353. StartProgram(true);
  1354. Add('uses unit2;');
  1355. Add('begin');
  1356. AnalyzeWholeProgram;
  1357. CheckUnitUsed('unit2.pp',false);
  1358. end;
  1359. procedure TTestUseAnalyzer.TestWP_UnitInitialization;
  1360. begin
  1361. AddModuleWithIntfImplSrc('unit1.pp',
  1362. LinesToStr([
  1363. 'uses unit2;',
  1364. '']),
  1365. LinesToStr([
  1366. 'initialization',
  1367. 'i:=2;']));
  1368. AddModuleWithIntfImplSrc('unit2.pp',
  1369. LinesToStr([
  1370. 'var i: longint;',
  1371. '']),
  1372. LinesToStr([
  1373. '']));
  1374. StartProgram(true);
  1375. Add('uses unit1;');
  1376. Add('begin');
  1377. AnalyzeWholeProgram;
  1378. CheckUnitUsed('unit1.pp',true);
  1379. CheckUnitUsed('unit2.pp',true);
  1380. end;
  1381. procedure TTestUseAnalyzer.TestWP_UnitFinalization;
  1382. begin
  1383. AddModuleWithIntfImplSrc('unit1.pp',
  1384. LinesToStr([
  1385. 'uses unit2;',
  1386. '']),
  1387. LinesToStr([
  1388. 'finalization',
  1389. 'i:=2;']));
  1390. AddModuleWithIntfImplSrc('unit2.pp',
  1391. LinesToStr([
  1392. 'var i: longint;',
  1393. '']),
  1394. LinesToStr([
  1395. '']));
  1396. StartProgram(true);
  1397. Add('uses unit1;');
  1398. Add('begin');
  1399. AnalyzeWholeProgram;
  1400. CheckUnitUsed('unit1.pp',true);
  1401. CheckUnitUsed('unit2.pp',true);
  1402. end;
  1403. procedure TTestUseAnalyzer.TestWP_CallInherited;
  1404. begin
  1405. StartProgram(false);
  1406. Add('type');
  1407. Add(' {#TObject_used}TObject = class');
  1408. Add(' procedure {#TObjectDoA_used}DoA;');
  1409. Add(' procedure {#TObjectDoB_used}DoB;');
  1410. Add(' end;');
  1411. Add(' {#TMobile_used}TMobile = class');
  1412. Add(' procedure {#TMobileDoA_used}DoA;');
  1413. Add(' procedure {#TMobileDoC_used}DoC;');
  1414. Add(' end;');
  1415. Add('procedure TObject.DoA; begin end;');
  1416. Add('procedure TObject.DoB; begin end;');
  1417. Add('procedure TMobile.DoA;');
  1418. Add('begin');
  1419. Add(' inherited;');
  1420. Add('end;');
  1421. Add('procedure TMobile.DoC;');
  1422. Add('begin');
  1423. Add(' inherited DoB;');
  1424. Add('end;');
  1425. Add('var o: TMobile;');
  1426. Add('begin');
  1427. Add(' o.DoA;');
  1428. Add(' o.DoC;');
  1429. AnalyzeWholeProgram;
  1430. end;
  1431. procedure TTestUseAnalyzer.TestWP_ProgramPublicDeclarations;
  1432. begin
  1433. StartProgram(false);
  1434. Add('var');
  1435. Add(' {#vPublic_used}vPublic: longint; public;');
  1436. Add(' {#vPrivate_notused}vPrivate: longint;');
  1437. Add('procedure {#DoPublic_used}DoPublic; public; begin end;');
  1438. Add('procedure {#DoPrivate_notused}DoPrivate; begin end;');
  1439. Add('begin');
  1440. AnalyzeWholeProgram;
  1441. end;
  1442. procedure TTestUseAnalyzer.TestWP_ClassDefaultProperty;
  1443. begin
  1444. StartProgram(false);
  1445. Add('type');
  1446. Add(' {#tobject_used}TObject = class');
  1447. Add(' function {#getitems_notused}Getitems(Index: longint): string;');
  1448. Add(' procedure {#setitems_used}Setitems(Index: longint; Value: String);');
  1449. Add(' property {#items_used}Items[Index: longint]: string read GetItems write SetItems; default;');
  1450. Add(' end;');
  1451. Add('function TObject.Getitems(Index: longint): string; begin end;');
  1452. Add('procedure TObject.Setitems(Index: longint; Value: String); begin end;');
  1453. Add('var');
  1454. Add(' {#l_used}L: TObject;');
  1455. Add('begin');
  1456. Add(' L[0]:=''birdy'';');
  1457. AnalyzeWholeProgram;
  1458. end;
  1459. procedure TTestUseAnalyzer.TestWP_Published;
  1460. begin
  1461. StartProgram(false);
  1462. Add('type');
  1463. Add(' {#tobject_used}TObject = class');
  1464. Add(' private');
  1465. Add(' {#fcol_used}FCol: string;');
  1466. Add(' {#fbird_notused}FBird: string;');
  1467. Add(' published');
  1468. Add(' {#fielda_used}FieldA: longint;');
  1469. Add(' procedure {#doit_used}ProcA; virtual; abstract;');
  1470. Add(' property {#col_used}Col: string read FCol;');
  1471. Add(' end;');
  1472. Add('var');
  1473. Add(' {#o_used}o: TObject;');
  1474. Add('begin');
  1475. Add(' o:=nil;');
  1476. AnalyzeWholeProgram;
  1477. end;
  1478. procedure TTestUseAnalyzer.TestWP_PublishedSetType;
  1479. begin
  1480. StartProgram(false);
  1481. Add('type');
  1482. Add(' {#tflag_used}TFlag = (red, green);');
  1483. Add(' {#tflags_used}TFlags = set of TFlag;');
  1484. Add(' {#tobject_used}TObject = class');
  1485. Add(' published');
  1486. Add(' {#fielda_used}FieldA: TFlag;');
  1487. Add(' {#fieldb_used}FieldB: TFlags;');
  1488. Add(' end;');
  1489. Add('var');
  1490. Add(' {#o_used}o: TObject;');
  1491. Add('begin');
  1492. Add(' o:=nil;');
  1493. AnalyzeWholeProgram;
  1494. end;
  1495. procedure TTestUseAnalyzer.TestWP_PublishedArrayType;
  1496. begin
  1497. StartProgram(false);
  1498. Add('type');
  1499. Add(' {#tdynarr_used}TDynArr = array of longint;');
  1500. Add(' {#tstatarr_used}TStatArr = array[boolean] of longint;');
  1501. Add(' {#tobject_used}TObject = class');
  1502. Add(' published');
  1503. Add(' {#fielda_used}FieldA: TDynArr;');
  1504. Add(' {#fieldb_used}FieldB: TStatArr;');
  1505. Add(' end;');
  1506. Add('var');
  1507. Add(' {#o_used}o: TObject;');
  1508. Add('begin');
  1509. Add(' o:=nil;');
  1510. AnalyzeWholeProgram;
  1511. end;
  1512. procedure TTestUseAnalyzer.TestWP_PublishedClassOfType;
  1513. begin
  1514. StartProgram(false);
  1515. Add('type');
  1516. Add(' {#tobjectclass_used}TObjectClass = class of TObject;');
  1517. Add(' {#tobject_used}TObject = class');
  1518. Add(' published');
  1519. Add(' {#fielda_used}FieldA: TObjectClass;');
  1520. Add(' end;');
  1521. Add(' {#tclass_used}TClass = class of TObject;');
  1522. Add('var');
  1523. Add(' {#c_used}c: TClass;');
  1524. Add('begin');
  1525. Add(' c:=nil;');
  1526. AnalyzeWholeProgram;
  1527. end;
  1528. procedure TTestUseAnalyzer.TestWP_PublishedRecordType;
  1529. begin
  1530. StartProgram(false);
  1531. Add('type');
  1532. Add(' {#trec_used}TRec = record');
  1533. Add(' {treci_used}i: longint;');
  1534. Add(' end;');
  1535. Add(' {#tobject_used}TObject = class');
  1536. Add(' published');
  1537. Add(' {#fielda_used}FieldA: TRec;');
  1538. Add(' end;');
  1539. Add('var');
  1540. Add(' {#o_used}o: TObject;');
  1541. Add('begin');
  1542. Add(' o:=nil;');
  1543. AnalyzeWholeProgram;
  1544. end;
  1545. procedure TTestUseAnalyzer.TestWP_PublishedProcType;
  1546. begin
  1547. StartProgram(false);
  1548. Add('type');
  1549. Add(' {#ta_used}ta = array of longint;');
  1550. Add(' {#tb_used}tb = array of longint;');
  1551. Add(' {#tproca_used}TProcA = procedure;');
  1552. Add(' {#tfunca_used}TFuncA = function: ta;');
  1553. Add(' {#tprocb_used}TProcB = procedure(a: tb);');
  1554. Add(' {#tobject_used}TObject = class');
  1555. Add(' published');
  1556. Add(' {#fielda_used}FieldA: TProcA;');
  1557. Add(' {#fieldb_used}FieldB: TFuncA;');
  1558. Add(' {#fieldc_used}FieldC: TProcB;');
  1559. Add(' end;');
  1560. Add('var');
  1561. Add(' {#o_used}o: TObject;');
  1562. Add('begin');
  1563. Add(' o:=nil;');
  1564. AnalyzeWholeProgram;
  1565. end;
  1566. procedure TTestUseAnalyzer.TestWP_PublishedProperty;
  1567. begin
  1568. StartProgram(false);
  1569. Add('const');
  1570. Add(' {#defcol_used}DefCol = 3;');
  1571. Add(' {#defsize_notused}DefSize = 43;');
  1572. Add('type');
  1573. Add(' {#tobject_used}TObject = class');
  1574. Add(' private');
  1575. Add(' {#fcol_used}FCol: longint;');
  1576. Add(' {#fsize_used}FSize: longint;');
  1577. Add(' {#fbird_notused}FBird: string;');
  1578. Add(' {#fcolstored_used}FColStored: boolean;');
  1579. Add(' {#fsizestored_notused}FSizeStored: boolean;');
  1580. Add(' public');
  1581. Add(' property {#size_used}Size: longint read FSize stored FSizeStored default DefSize;');
  1582. Add(' published');
  1583. Add(' property {#col_used}Col: longint read FCol stored FColStored default DefCol;');
  1584. Add(' end;');
  1585. Add('var');
  1586. Add(' {#o_used}o: TObject;');
  1587. Add('begin');
  1588. Add(' if o.Size=13 then ;');
  1589. AnalyzeWholeProgram;
  1590. end;
  1591. procedure TTestUseAnalyzer.TestWP_BuiltInFunctions;
  1592. begin
  1593. StartProgram(false);
  1594. Add([
  1595. 'type',
  1596. ' {#tordenum_used}TOrdEnum = (ordenum1,ordenum2);',
  1597. 'begin',
  1598. ' if ord(ordenum1)=1 then ;',
  1599. '']);
  1600. AnalyzeWholeProgram;
  1601. end;
  1602. procedure TTestUseAnalyzer.TestWP_TypeInfo;
  1603. begin
  1604. StartProgram(false);
  1605. Add([
  1606. 'type',
  1607. ' {#integer_used}integer = longint;',
  1608. ' {#trec_used}TRec = record',
  1609. ' {#trecv_used}v: integer;',
  1610. ' end;',
  1611. ' {#tclass_used}TClass = class of TObject;',
  1612. ' {#tobject_used}TObject = class',
  1613. ' class function {#tobject_classtype_used}ClassType: TClass; virtual; abstract;',
  1614. ' end;',
  1615. ' {#tbirds_used}TBirds = class of TBird;',
  1616. ' {#tbird_used}TBird = class',
  1617. ' end;',
  1618. 'function {#getbirdclass_used}GetBirdClass: TBirds;',
  1619. 'begin',
  1620. ' Result:=nil;',
  1621. 'end;',
  1622. 'var',
  1623. ' {#i_used}i: integer;',
  1624. ' {#s_used}s: string;',
  1625. ' {#p_used}p: pointer;',
  1626. ' {#r_used}r: TRec;',
  1627. ' {#o_used}o: TObject;',
  1628. ' {#c_used}c: TClass;',
  1629. 'begin',
  1630. ' p:=typeinfo(integer);',
  1631. ' p:=typeinfo(longint);',
  1632. ' p:=typeinfo(i);',
  1633. ' p:=typeinfo(s);',
  1634. ' p:=typeinfo(p);',
  1635. ' p:=typeinfo(r.v);',
  1636. ' p:=typeinfo(TObject.ClassType);',
  1637. ' p:=typeinfo(o.ClassType);',
  1638. ' p:=typeinfo(o);',
  1639. ' p:=typeinfo(c);',
  1640. ' p:=typeinfo(c.ClassType);',
  1641. ' p:=typeinfo(GetBirdClass);',
  1642. '']);
  1643. AnalyzeWholeProgram;
  1644. end;
  1645. initialization
  1646. RegisterTests([TTestUseAnalyzer]);
  1647. end.