tcuseanalyzer.pas 46 KB

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