2
0

tcbaseparser.pas 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641
  1. unit tcbaseparser;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils, fpcunit, pastree, pscanner, pparser, testregistry;
  6. const
  7. DefaultMainFilename = 'afile.pp';
  8. Type
  9. { TTestEngine }
  10. TTestEngine = Class(TPasTreeContainer)
  11. Private
  12. FList : TFPList;
  13. public
  14. Destructor Destroy; override;
  15. function CreateElement(AClass: TPTreeElement; const AName: String;
  16. AParent: TPasElement; AVisibility: TPasMemberVisibility;
  17. const ASourceFilename: String; ASourceLinenumber: Integer): TPasElement;
  18. override;
  19. function FindElement(const AName: String): TPasElement; override;
  20. end;
  21. TTestPasParser = Class(TPasParser);
  22. { TTestParser }
  23. TTestParser = class(TTestCase)
  24. Private
  25. FDeclarations: TPasDeclarations;
  26. FDefinition: TPasElement;
  27. FEngine : TPasTreeContainer;
  28. FMainFilename: string;
  29. FModule: TPasModule;
  30. FParseResult: TPasElement;
  31. FScanner : TPascalScanner;
  32. FResolver : TStreamResolver;
  33. FParser : TTestPasParser;
  34. FSource: TStrings;
  35. FFileName : string;
  36. FIsUnit : Boolean;
  37. FImplementation : Boolean;
  38. FEndSource: Boolean;
  39. FUseImplementation: Boolean;
  40. function GetPL: TPasLibrary;
  41. function GetPP: TPasProgram;
  42. procedure CleanupParser;
  43. procedure SetupParser;
  44. protected
  45. procedure SetUp; override;
  46. procedure TearDown; override;
  47. procedure CreateEngine(var TheEngine: TPasTreeContainer); virtual;
  48. Procedure StartUnit(AUnitName : String);
  49. Procedure StartProgram(AFileName : String; AIn : String = ''; AOut : String = '');
  50. Procedure StartLibrary(AFileName : String);
  51. Procedure UsesClause(Units : Array of string);
  52. Procedure StartImplementation;
  53. Procedure EndSource;
  54. Procedure Add(Const ALine : String);
  55. Procedure Add(Const Lines : array of String);
  56. Procedure StartParsing;
  57. Procedure ParseDeclarations;
  58. Procedure ParseModule; virtual;
  59. procedure ResetParser;
  60. Procedure CheckHint(AHint : TPasMemberHint);
  61. Function AssertExpression(Const Msg: String; AExpr : TPasExpr; aKind : TPasExprKind; AClass : TClass) : TPasExpr;
  62. Function AssertExpression(Const Msg: String; AExpr : TPasExpr; aKind : TPasExprKind; AValue : String) : TPrimitiveExpr;
  63. Function AssertExpression(Const Msg: String; AExpr : TPasExpr; OpCode : TExprOpCode) : TBinaryExpr;
  64. Procedure AssertExportSymbol(Const Msg: String; AIndex : Integer; AName,AExportName : String; AExportIndex : Integer = -1);
  65. Procedure AssertEquals(Const Msg : String; AExpected, AActual: TPasExprKind); overload;
  66. Procedure AssertEquals(Const Msg : String; AExpected, AActual: TLoopType); overload;
  67. Procedure AssertEquals(Const Msg : String; AExpected, AActual: TPasObjKind); overload;
  68. Procedure AssertEquals(Const Msg : String; AExpected, AActual: TExprOpCode); overload;
  69. Procedure AssertEquals(Const Msg : String; AExpected, AActual: TPasMemberHint); overload;
  70. Procedure AssertEquals(Const Msg : String; AExpected, AActual: TCallingConvention); overload;
  71. Procedure AssertEquals(Const Msg : String; AExpected, AActual: TArgumentAccess); overload;
  72. Procedure AssertEquals(Const Msg : String; AExpected, AActual: TVariableModifier); overload;
  73. Procedure AssertEquals(Const Msg : String; AExpected, AActual: TVariableModifiers); overload;
  74. Procedure AssertEquals(Const Msg : String; AExpected, AActual: TPasMemberVisibility); overload;
  75. Procedure AssertEquals(Const Msg : String; AExpected, AActual: TProcedureModifier); overload;
  76. Procedure AssertEquals(Const Msg : String; AExpected, AActual: TProcedureModifiers); overload;
  77. Procedure AssertEquals(Const Msg : String; AExpected, AActual: TProcTypeModifiers); overload;
  78. Procedure AssertEquals(Const Msg : String; AExpected, AActual: TAssignKind); overload;
  79. Procedure AssertEquals(Const Msg : String; AExpected, AActual: TProcedureMessageType); overload;
  80. Procedure AssertEquals(Const Msg : String; AExpected, AActual: TOperatorType); overload;
  81. Procedure AssertSame(Const Msg : String; AExpected, AActual: TPasElement); overload;
  82. Procedure HaveHint(AHint : TPasMemberHint; AHints : TPasMemberHints);
  83. Property Resolver : TStreamResolver Read FResolver;
  84. Property Scanner : TPascalScanner Read FScanner;
  85. Property Engine : TPasTreeContainer read FEngine;
  86. Property Parser : TTestPasParser read FParser ;
  87. Property Source : TStrings Read FSource;
  88. Property Module : TPasModule Read FModule;
  89. Property PasProgram : TPasProgram Read GetPP;
  90. Property PasLibrary : TPasLibrary Read GetPL;
  91. Property Declarations : TPasDeclarations read FDeclarations Write FDeclarations;
  92. Property Definition : TPasElement Read FDefinition Write FDefinition;
  93. // If set, Will be freed in teardown
  94. Property ParseResult : TPasElement Read FParseResult Write FParseResult;
  95. Property UseImplementation : Boolean Read FUseImplementation Write FUseImplementation;
  96. Property MainFilename: string read FMainFilename write FMainFilename;
  97. end;
  98. implementation
  99. uses typinfo;
  100. { TTestEngine }
  101. destructor TTestEngine.Destroy;
  102. begin
  103. FreeAndNil(FList);
  104. inherited Destroy;
  105. end;
  106. function TTestEngine.CreateElement(AClass: TPTreeElement; const AName: String;
  107. AParent: TPasElement; AVisibility: TPasMemberVisibility;
  108. const ASourceFilename: String; ASourceLinenumber: Integer): TPasElement;
  109. begin
  110. //writeln('TTestEngine.CreateElement ',AName,' ',AClass.ClassName);
  111. Result := AClass.Create(AName, AParent);
  112. {$IFDEF CheckPasTreeRefCount}Result.RefIds.Add('CreateElement');{$ENDIF}
  113. Result.Visibility := AVisibility;
  114. Result.SourceFilename := ASourceFilename;
  115. Result.SourceLinenumber := ASourceLinenumber;
  116. if NeedComments and Assigned(CurrentParser) then
  117. begin
  118. // Writeln('Saving comment : ',CurrentParser.SavedComments);
  119. Result.DocComment:=CurrentParser.SavedComments;
  120. end;
  121. if AName<>'' then
  122. begin
  123. If not Assigned(FList) then
  124. FList:=TFPList.Create;
  125. FList.Add(Result);
  126. end;
  127. end;
  128. function TTestEngine.FindElement(const AName: String): TPasElement;
  129. Var
  130. I : Integer;
  131. begin
  132. Result:=Nil;
  133. if Assigned(FList) then
  134. begin
  135. I:=FList.Count-1;
  136. While (Result=Nil) and (I>=0) do
  137. begin
  138. if CompareText(TPasElement(FList[I]).Name,AName)=0 then
  139. Result:=TPasElement(FList[i]);
  140. Dec(i);
  141. end;
  142. end;
  143. end;
  144. function TTestParser.GetPP: TPasProgram;
  145. begin
  146. Result:=Module as TPasProgram;
  147. end;
  148. function TTestParser.GetPL: TPasLibrary;
  149. begin
  150. Result:=Module as TPasLibrary;
  151. end;
  152. procedure TTestParser.SetupParser;
  153. begin
  154. FResolver:=TStreamResolver.Create;
  155. FResolver.OwnsStreams:=True;
  156. FScanner:=TPascalScanner.Create(FResolver);
  157. FScanner.CurrentBoolSwitches:=FScanner.CurrentBoolSwitches+[bsHints,bsNotes,bsWarnings];
  158. CreateEngine(FEngine);
  159. FParser:=TTestPasParser.Create(FScanner,FResolver,FEngine);
  160. FSource:=TStringList.Create;
  161. FModule:=Nil;
  162. FDeclarations:=Nil;
  163. FEndSource:=False;
  164. FImplementation:=False;
  165. FIsUnit:=False;
  166. end;
  167. procedure TTestParser.CleanupParser;
  168. begin
  169. {$IFDEF VerbosePasResolverMem}
  170. writeln('TTestParser.CleanupParser START');
  171. {$ENDIF}
  172. if Not Assigned(FModule) then
  173. FreeAndNil(FDeclarations)
  174. else
  175. FDeclarations:=Nil;
  176. FImplementation:=False;
  177. FEndSource:=False;
  178. FIsUnit:=False;
  179. {$IFDEF VerbosePasResolverMem}
  180. writeln('TTestParser.CleanupParser FModule');
  181. {$ENDIF}
  182. ReleaseAndNil(TPasElement(FModule){$IFDEF CheckPasTreeRefCount},'CreateElement'{$ENDIF});
  183. {$IFDEF VerbosePasResolverMem}
  184. writeln('TTestParser.CleanupParser FSource');
  185. {$ENDIF}
  186. FreeAndNil(FSource);
  187. {$IFDEF VerbosePasResolverMem}
  188. writeln('TTestParser.CleanupParser FParseResult');
  189. {$ENDIF}
  190. FreeAndNil(FParseResult);
  191. {$IFDEF VerbosePasResolverMem}
  192. writeln('TTestParser.CleanupParser FParser');
  193. {$ENDIF}
  194. FreeAndNil(FParser);
  195. {$IFDEF VerbosePasResolverMem}
  196. writeln('TTestParser.CleanupParser FEngine');
  197. {$ENDIF}
  198. FreeAndNil(FEngine);
  199. {$IFDEF VerbosePasResolverMem}
  200. writeln('TTestParser.CleanupParser FScanner');
  201. {$ENDIF}
  202. FreeAndNil(FScanner);
  203. {$IFDEF VerbosePasResolverMem}
  204. writeln('TTestParser.CleanupParser FResolver');
  205. {$ENDIF}
  206. FreeAndNil(FResolver);
  207. {$IFDEF VerbosePasResolverMem}
  208. writeln('TTestParser.CleanupParser END');
  209. {$ENDIF}
  210. end;
  211. procedure TTestParser.ResetParser;
  212. begin
  213. CleanupParser;
  214. SetupParser;
  215. end;
  216. procedure TTestParser.SetUp;
  217. begin
  218. FMainFilename:=DefaultMainFilename;
  219. Inherited;
  220. SetupParser;
  221. end;
  222. procedure TTestParser.TearDown;
  223. begin
  224. {$IFDEF VerbosePasResolverMem}
  225. writeln('TTestParser.TearDown START CleanupParser');
  226. {$ENDIF}
  227. CleanupParser;
  228. {$IFDEF VerbosePasResolverMem}
  229. writeln('TTestParser.TearDown inherited');
  230. {$ENDIF}
  231. Inherited;
  232. {$IFDEF VerbosePasResolverMem}
  233. writeln('TTestParser.TearDown END');
  234. {$ENDIF}
  235. end;
  236. procedure TTestParser.CreateEngine(var TheEngine: TPasTreeContainer);
  237. begin
  238. TheEngine:=TTestEngine.Create;
  239. end;
  240. procedure TTestParser.StartUnit(AUnitName: String);
  241. begin
  242. FIsUnit:=True;
  243. If (AUnitName='') then
  244. AUnitName:=ExtractFileUnitName(MainFilename);
  245. Add('unit '+aUnitName+';');
  246. Add('');
  247. Add('interface');
  248. Add('');
  249. FFileName:=AUnitName+'.pp';
  250. end;
  251. procedure TTestParser.StartProgram(AFileName : String; AIn : String = ''; AOut : String = '');
  252. begin
  253. FIsUnit:=False;
  254. If (AFileName='') then
  255. AFileName:='proga';
  256. FFileName:=AFileName+'.pp';
  257. If (AIn<>'') then
  258. begin
  259. AFileName:=AFileName+'('+AIn;
  260. if (AOut<>'') then
  261. AFileName:=AFileName+','+AOut;
  262. AFileName:=AFileName+')';
  263. end;
  264. Add('program '+AFileName+';');
  265. FImplementation:=True;
  266. end;
  267. procedure TTestParser.StartLibrary(AFileName: String);
  268. begin
  269. FIsUnit:=False;
  270. If (AFileName='') then
  271. AFileName:='liba';
  272. FFileName:=AFileName+'.pp';
  273. Add('library '+AFileName+';');
  274. FImplementation:=True;
  275. end;
  276. procedure TTestParser.UsesClause(Units: array of string);
  277. Var
  278. S : String;
  279. I : integer;
  280. begin
  281. S:='';
  282. For I:=Low(units) to High(units) do
  283. begin
  284. If (S<>'') then
  285. S:=S+', ';
  286. S:=S+Units[i];
  287. end;
  288. Add('uses '+S+';');
  289. Add('');
  290. end;
  291. procedure TTestParser.StartImplementation;
  292. begin
  293. if Not FImplementation then
  294. begin
  295. if UseImplementation then
  296. begin
  297. FSource.Insert(0,'');
  298. FSource.Insert(0,'Implementation');
  299. FSource.Insert(0,'');
  300. end
  301. else
  302. begin
  303. Add('');
  304. Add('Implementation');
  305. Add('');
  306. end;
  307. FImplementation:=True;
  308. end;
  309. end;
  310. procedure TTestParser.EndSource;
  311. begin
  312. if Not FEndSource then
  313. begin
  314. Add('end.');
  315. FEndSource:=True;
  316. end;
  317. end;
  318. procedure TTestParser.Add(const ALine: String);
  319. begin
  320. FSource.Add(ALine);
  321. end;
  322. procedure TTestParser.Add(const Lines: array of String);
  323. var
  324. i: Integer;
  325. begin
  326. for i:=Low(Lines) to High(Lines) do
  327. Add(Lines[i]);
  328. end;
  329. procedure TTestParser.StartParsing;
  330. var
  331. i: Integer;
  332. begin
  333. If FIsUnit then
  334. StartImplementation;
  335. EndSource;
  336. If (FFileName='') then
  337. FFileName:=MainFilename;
  338. FResolver.AddStream(FFileName,TStringStream.Create(FSource.Text));
  339. FScanner.OpenFile(FFileName);
  340. {$ifndef NOCONSOLE} // JC: To get the tests to run with GUI
  341. Writeln('// Test : ',Self.TestName);
  342. for i:=0 to FSource.Count-1 do
  343. Writeln(Format('%:4d: ',[i+1]),FSource[i]);
  344. {$EndIf}
  345. end;
  346. procedure TTestParser.ParseDeclarations;
  347. begin
  348. if UseImplementation then
  349. StartImplementation;
  350. FSource.Insert(0,'');
  351. FSource.Insert(0,'interface');
  352. FSource.Insert(0,'');
  353. FSource.Insert(0,'unit afile;');
  354. if Not UseImplementation then
  355. StartImplementation;
  356. EndSource;
  357. ParseModule;
  358. if UseImplementation then
  359. FDeclarations:=Module.ImplementationSection
  360. else
  361. FDeclarations:=Module.InterfaceSection;
  362. end;
  363. procedure TTestParser.ParseModule;
  364. begin
  365. StartParsing;
  366. FParser.ParseMain(FModule);
  367. AssertNotNull('Module resulted in Module',FModule);
  368. AssertEquals('modulename',ChangeFileExt(FFileName,''),Module.Name);
  369. end;
  370. procedure TTestParser.CheckHint(AHint: TPasMemberHint);
  371. begin
  372. HaveHint(AHint,Definition.Hints);
  373. end;
  374. function TTestParser.AssertExpression(const Msg: String; AExpr: TPasExpr;
  375. aKind: TPasExprKind; AClass: TClass): TPasExpr;
  376. begin
  377. AssertNotNull(AExpr);
  378. AssertEquals(Msg+': Correct expression kind',aKind,AExpr.Kind);
  379. AssertEquals(Msg+': Correct expression class',AClass,AExpr.ClassType);
  380. Result:=AExpr;
  381. end;
  382. function TTestParser.AssertExpression(const Msg: String; AExpr: TPasExpr;
  383. aKind: TPasExprKind; AValue: String): TPrimitiveExpr;
  384. begin
  385. Result:=AssertExpression(Msg,AExpr,aKind,TPrimitiveExpr) as TPrimitiveExpr;
  386. AssertEquals(Msg+': Primitive expression value',AValue,TPrimitiveExpr(AExpr).Value);
  387. end;
  388. function TTestParser.AssertExpression(const Msg: String; AExpr: TPasExpr;
  389. OpCode: TExprOpCode): TBinaryExpr;
  390. begin
  391. Result:=AssertExpression(Msg,AExpr,pekBinary,TBinaryExpr) as TBinaryExpr;
  392. AssertEquals(Msg+': Binary opcode',OpCode,TBinaryExpr(AExpr).OpCode);
  393. end;
  394. procedure TTestParser.AssertExportSymbol(const Msg: String; AIndex: Integer;
  395. AName, AExportName: String; AExportIndex: Integer);
  396. Var
  397. E: TPasExportSymbol;
  398. begin
  399. AssertNotNull(Msg+'Have export symbols list',PasLibrary.LibrarySection.ExportSymbols);
  400. if AIndex>=PasLibrary.LibrarySection.ExportSymbols.Count then
  401. Fail(Format(Msg+'%d not a valid export list symbol',[AIndex]));
  402. AssertNotNull(Msg+'Have export symbol',PasLibrary.LibrarySection.ExportSymbols[Aindex]);
  403. AssertEquals(Msg+'Correct export symbol class',TPasExportSymbol,TObject(PasLibrary.LibrarySection.ExportSymbols[Aindex]).ClassType);
  404. E:=TPasExportSymbol(PasLibrary.LibrarySection.ExportSymbols[Aindex]);
  405. AssertEquals(Msg+'Correct export symbol name',AName,E.Name);
  406. if (AExportName='') then
  407. AssertNull(Msg+'No export name',E.ExportName)
  408. else
  409. begin
  410. AssertNotNull(Msg+'Export name symbol',E.ExportName);
  411. AssertEquals(Msg+'TPrimitiveExpr',TPrimitiveExpr,E.ExportName.CLassType);
  412. AssertEquals(Msg+'Correct export symbol export name ',''''+AExportName+'''',TPrimitiveExpr(E.ExportName).Value);
  413. end;
  414. If AExportIndex=-1 then
  415. AssertNull(Msg+'No export name',E.ExportIndex)
  416. else
  417. begin
  418. AssertNotNull(Msg+'Export name symbol',E.ExportIndex);
  419. AssertEquals(Msg+'TPrimitiveExpr',TPrimitiveExpr,E.ExportIndex.CLassType);
  420. AssertEquals(Msg+'Correct export symbol export index',IntToStr(AExportindex),TPrimitiveExpr(E.ExportIndex).Value);
  421. end;
  422. end;
  423. procedure TTestParser.AssertEquals(const Msg: String; AExpected,
  424. AActual: TPasExprKind);
  425. begin
  426. AssertEquals(Msg,GetEnumName(TypeInfo(TPasExprKind),Ord(AExpected)),
  427. GetEnumName(TypeInfo(TPasExprKind),Ord(AActual)));
  428. end;
  429. procedure TTestParser.AssertEquals(const Msg: String; AExpected,
  430. AActual: TLoopType);
  431. begin
  432. AssertEquals(Msg,GetEnumName(TypeInfo(TLoopType),Ord(AExpected)),
  433. GetEnumName(TypeInfo(TLoopType),Ord(AActual)));
  434. end;
  435. procedure TTestParser.AssertEquals(const Msg: String; AExpected,
  436. AActual: TPasObjKind);
  437. begin
  438. AssertEquals(Msg,GetEnumName(TypeInfo(TPasObjKind),Ord(AExpected)),
  439. GetEnumName(TypeInfo(TPasObjKind),Ord(AActual)));
  440. end;
  441. procedure TTestParser.AssertEquals(const Msg: String; AExpected,
  442. AActual: TExprOpCode);
  443. begin
  444. AssertEquals(Msg,GetEnumName(TypeInfo(TexprOpcode),Ord(AExpected)),
  445. GetEnumName(TypeInfo(TexprOpcode),Ord(AActual)));
  446. end;
  447. procedure TTestParser.AssertEquals(const Msg: String; AExpected,
  448. AActual: TPasMemberHint);
  449. begin
  450. AssertEquals(Msg,GetEnumName(TypeInfo(TPasMemberHint),Ord(AExpected)),
  451. GetEnumName(TypeInfo(TPasMemberHint),Ord(AActual)));
  452. end;
  453. procedure TTestParser.AssertEquals(const Msg: String; AExpected,
  454. AActual: TCallingConvention);
  455. begin
  456. AssertEquals(Msg,GetEnumName(TypeInfo(TCallingConvention),Ord(AExpected)),
  457. GetEnumName(TypeInfo(TCallingConvention),Ord(AActual)));
  458. end;
  459. procedure TTestParser.AssertEquals(const Msg: String; AExpected,
  460. AActual: TArgumentAccess);
  461. begin
  462. AssertEquals(Msg,GetEnumName(TypeInfo(TArgumentAccess),Ord(AExpected)),
  463. GetEnumName(TypeInfo(TArgumentAccess),Ord(AActual)));
  464. end;
  465. procedure TTestParser.AssertEquals(const Msg: String; AExpected,
  466. AActual: TVariableModifier);
  467. begin
  468. AssertEquals(Msg,GetEnumName(TypeInfo(TVariableModifier),Ord(AExpected)),
  469. GetEnumName(TypeInfo(TVariableModifier),Ord(AActual)));
  470. end;
  471. procedure TTestParser.AssertEquals(const Msg: String; AExpected,
  472. AActual: TVariableModifiers);
  473. Function sn (S : TVariableModifiers) : string;
  474. Var
  475. M : TVariableModifier;
  476. begin
  477. Result:='';
  478. For M:=Low(TVariableModifier) to High(TVariableModifier) do
  479. if M in S then
  480. begin
  481. if (Result<>'') then
  482. Result:=Result+',';
  483. end;
  484. Result:='['+Result+']';
  485. end;
  486. begin
  487. AssertEquals(Msg,Sn(AExpected),Sn(AActual));
  488. end;
  489. procedure TTestParser.AssertEquals(const Msg: String; AExpected,
  490. AActual: TPasMemberVisibility);
  491. begin
  492. AssertEquals(Msg,GetEnumName(TypeInfo(TPasMemberVisibility),Ord(AExpected)),
  493. GetEnumName(TypeInfo(TPasMemberVisibility),Ord(AActual)));
  494. end;
  495. procedure TTestParser.AssertEquals(const Msg: String; AExpected,
  496. AActual: TProcedureModifier);
  497. begin
  498. AssertEquals(Msg,GetEnumName(TypeInfo(TProcedureModifier),Ord(AExpected)),
  499. GetEnumName(TypeInfo(TProcedureModifier),Ord(AActual)));
  500. end;
  501. procedure TTestParser.AssertEquals(const Msg: String; AExpected,
  502. AActual: TProcedureModifiers);
  503. Function Sn (S : TProcedureModifiers) : String;
  504. Var
  505. m : TProcedureModifier;
  506. begin
  507. Result:='';
  508. For M:=Low(TProcedureModifier) to High(TProcedureModifier) do
  509. If (m in S) then
  510. begin
  511. If (Result<>'') then
  512. Result:=Result+',';
  513. Result:=Result+GetEnumName(TypeInfo(TProcedureModifier),Ord(m))
  514. end;
  515. end;
  516. begin
  517. AssertEquals(Msg,Sn(AExpected),SN(AActual));
  518. end;
  519. procedure TTestParser.AssertEquals(const Msg: String; AExpected,
  520. AActual: TProcTypeModifiers);
  521. Function Sn (S : TProcTypeModifiers) : String;
  522. Var
  523. m : TProcTypeModifier;
  524. begin
  525. Result:='';
  526. For M:=Low(TProcTypeModifier) to High(TProcTypeModifier) do
  527. If (m in S) then
  528. begin
  529. If (Result<>'') then
  530. Result:=Result+',';
  531. Result:=Result+GetEnumName(TypeInfo(TProcTypeModifier),Ord(m))
  532. end;
  533. end;
  534. begin
  535. AssertEquals(Msg,Sn(AExpected),SN(AActual));
  536. end;
  537. procedure TTestParser.AssertEquals(const Msg: String; AExpected,
  538. AActual: TAssignKind);
  539. begin
  540. AssertEquals(Msg,GetEnumName(TypeInfo(TAssignKind),Ord(AExpected)),
  541. GetEnumName(TypeInfo(TAssignKind),Ord(AActual)));
  542. end;
  543. procedure TTestParser.AssertEquals(const Msg: String; AExpected,
  544. AActual: TProcedureMessageType);
  545. begin
  546. AssertEquals(Msg,GetEnumName(TypeInfo(TProcedureMessageType),Ord(AExpected)),
  547. GetEnumName(TypeInfo(TProcedureMessageType),Ord(AActual)));
  548. end;
  549. procedure TTestParser.AssertEquals(const Msg: String; AExpected,
  550. AActual: TOperatorType);
  551. begin
  552. AssertEquals(Msg,GetEnumName(TypeInfo(TOperatorType),Ord(AExpected)),
  553. GetEnumName(TypeInfo(TOperatorType),Ord(AActual)));
  554. end;
  555. procedure TTestParser.AssertSame(const Msg: String; AExpected,
  556. AActual: TPasElement);
  557. begin
  558. if AExpected=AActual then exit;
  559. AssertEquals(Msg,GetPasElementDesc(AExpected),GetPasElementDesc(AActual));
  560. end;
  561. procedure TTestParser.HaveHint(AHint: TPasMemberHint; AHints: TPasMemberHints);
  562. begin
  563. If not (AHint in AHints) then
  564. Fail(GetEnumName(TypeInfo(TPasMemberHint),Ord(AHint))+'hint expected.');
  565. end;
  566. end.