tcoptimizations.pas 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308
  1. {
  2. This file is part of the Free Component Library (FCL)
  3. Copyright (c) 2017 by Michael Van Canneyt
  4. Unit tests for Pascal-to-Javascript converter class.
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************
  11. Examples:
  12. ./testpas2js --suite=TTestOptimizations
  13. ./testpas2js --suite=TTestOptimizations.TestOmitLocalVar
  14. }
  15. unit tcoptimizations;
  16. {$mode objfpc}{$H+}
  17. interface
  18. uses
  19. Classes, SysUtils, testregistry, fppas2js, pastree,
  20. PScanner, Pas2jsUseAnalyzer, PasResolver, PasResolveEval,
  21. tcmodules;
  22. type
  23. { TCustomTestOptimizations }
  24. TCustomTestOptimizations = class(TCustomTestModule)
  25. private
  26. FAnalyzerModule: TPas2JSAnalyzer;
  27. FAnalyzerProgram: TPas2JSAnalyzer;
  28. FWholeProgramOptimization: boolean;
  29. function OnConverterIsElementUsed(Sender: TObject; El: TPasElement): boolean;
  30. function OnConverterIsTypeInfoUsed(Sender: TObject; El: TPasElement): boolean;
  31. protected
  32. procedure SetUp; override;
  33. procedure TearDown; override;
  34. procedure ParseModule; override;
  35. procedure ParseProgram; override;
  36. function CreateConverter: TPasToJSConverter; override;
  37. public
  38. property AnalyzerModule: TPas2JSAnalyzer read FAnalyzerModule;
  39. property AnalyzerProgram: TPas2JSAnalyzer read FAnalyzerProgram;
  40. property WholeProgramOptimization: boolean read FWholeProgramOptimization
  41. write FWholeProgramOptimization;
  42. end;
  43. { TTestOptimizations }
  44. TTestOptimizations = class(TCustomTestOptimizations)
  45. published
  46. // unit optimization: aliasglobals
  47. procedure TestOptAliasGlobals_Program;
  48. procedure TestOptAliasGlobals_Unit; // ToDo
  49. // ToDo: external var, const, class
  50. // ToDo: RTTI
  51. // ToDo: typeinfo(var), typeinfo(type)
  52. // ToDo: resourcestring
  53. // ToDo: Global EnumType, EnumValue, EnumType.Value, unit.EnumType.Value
  54. // ToDo: Nested EnumType: EnumValue, EnumType.Value, unit.aType.EnumType.Value, aType.EnumType.Value, Instance.EnumType.Value
  55. // ToDo: Instance.RecordType, Instance.RecordType.ClassVar
  56. // ToDo: ClassVarRecord
  57. // Whole Program Optimization
  58. procedure TestWPO_OmitLocalVar;
  59. procedure TestWPO_OmitLocalProc;
  60. procedure TestWPO_OmitLocalProcForward;
  61. procedure TestWPO_OmitProcLocalVar;
  62. procedure TestWPO_OmitProcLocalConst;
  63. procedure TestWPO_OmitProcLocalType;
  64. procedure TestWPO_OmitProcLocalProc;
  65. procedure TestWPO_OmitProcLocalForwardProc;
  66. procedure TestWPO_OmitRecordMember;
  67. procedure TestWPO_OmitNotUsedTObject;
  68. procedure TestWPO_TObject;
  69. procedure TestWPO_Class_Property;
  70. procedure TestWPO_Class_OmitField;
  71. procedure TestWPO_Class_OmitMethod;
  72. procedure TestWPO_Class_OmitClassMethod;
  73. procedure TestWPO_Class_OmitPropertyGetter1;
  74. procedure TestWPO_Class_OmitPropertyGetter2;
  75. procedure TestWPO_Class_OmitPropertySetter1;
  76. procedure TestWPO_Class_OmitPropertySetter2;
  77. procedure TestWPO_Class_KeepNewInstance;
  78. procedure TestWPO_CallInherited;
  79. procedure TestWPO_UseUnit;
  80. procedure TestWPO_ArrayOfConst_Use;
  81. procedure TestWPO_ArrayOfConst_NotUsed;
  82. procedure TestWPO_Class_PropertyInOtherUnit;
  83. procedure TestWPO_ProgramPublicDeclaration;
  84. procedure TestWPO_ConstructorDefaultValueConst;
  85. procedure TestWPO_RTTI_PublishedField;
  86. procedure TestWPO_RTTI_TypeInfo;
  87. end;
  88. implementation
  89. { TCustomTestOptimizations }
  90. function TCustomTestOptimizations.OnConverterIsElementUsed(Sender: TObject;
  91. El: TPasElement): boolean;
  92. var
  93. A: TPas2JSAnalyzer;
  94. begin
  95. if WholeProgramOptimization then
  96. A:=AnalyzerProgram
  97. else if Sender=Converter then
  98. A:=AnalyzerModule
  99. else
  100. begin
  101. {$IF defined(VerbosePas2JS) or defined(VerbosePasAnalyzer)}
  102. writeln('TCustomTestOptimizations.OnConverterIsElementUsed El=',GetObjName(El),' WPO=',WholeProgramOptimization,' Sender=',GetObjName(Sender));
  103. {$ENDIF}
  104. Fail('converting other unit without WPO');
  105. end;
  106. Result:=A.IsUsed(El);
  107. {$IF defined(VerbosePas2JS) or defined(VerbosePasAnalyzer)}
  108. writeln('TCustomTestOptimizations.OnConverterIsElementUsed El=',GetObjName(El),' WPO=',WholeProgramOptimization,' Result=',Result);
  109. {$ENDIF}
  110. end;
  111. function TCustomTestOptimizations.OnConverterIsTypeInfoUsed(Sender: TObject;
  112. El: TPasElement): boolean;
  113. var
  114. A: TPas2JSAnalyzer;
  115. begin
  116. if WholeProgramOptimization then
  117. A:=AnalyzerProgram
  118. else if Sender=Converter then
  119. A:=AnalyzerModule
  120. else
  121. begin
  122. {$IF defined(VerbosePas2JS) or defined(VerbosePasAnalyzer)}
  123. writeln('TCustomTestOptimizations.OnConverterIsTypeInfoUsed El=',GetObjName(El),' WPO=',WholeProgramOptimization,' Sender=',GetObjName(Sender));
  124. {$ENDIF}
  125. Fail('converting other unit without WPO');
  126. end;
  127. Result:=A.IsTypeInfoUsed(El);
  128. {$IF defined(VerbosePas2JS) or defined(VerbosePasAnalyzer)}
  129. writeln('TCustomTestOptimizations.OnConverterIsTypeInfoUsed El=',GetObjName(El),' WPO=',WholeProgramOptimization,' Result=',Result);
  130. {$ENDIF}
  131. end;
  132. procedure TCustomTestOptimizations.SetUp;
  133. begin
  134. inherited SetUp;
  135. FWholeProgramOptimization:=false;
  136. FAnalyzerModule:=TPas2JSAnalyzer.Create;
  137. FAnalyzerModule.Resolver:=Engine;
  138. FAnalyzerProgram:=TPas2JSAnalyzer.Create;
  139. FAnalyzerProgram.Resolver:=Engine;
  140. end;
  141. procedure TCustomTestOptimizations.TearDown;
  142. begin
  143. FreeAndNil(FAnalyzerProgram);
  144. FreeAndNil(FAnalyzerModule);
  145. inherited TearDown;
  146. end;
  147. procedure TCustomTestOptimizations.ParseModule;
  148. begin
  149. inherited ParseModule;
  150. {$IF defined(VerbosePas2JS) or defined(VerbosePasAnalyzer)}
  151. writeln('TCustomTestOptimizations.ParseModule START');
  152. {$ENDIF}
  153. AnalyzerModule.AnalyzeModule(Module);
  154. {$IF defined(VerbosePas2JS) or defined(VerbosePasAnalyzer)}
  155. writeln('TCustomTestOptimizations.ParseModule END');
  156. {$ENDIF}
  157. end;
  158. procedure TCustomTestOptimizations.ParseProgram;
  159. begin
  160. WholeProgramOptimization:=true;
  161. inherited ParseProgram;
  162. {$IF defined(VerbosePas2JS) or defined(VerbosePasAnalyzer)}
  163. writeln('TCustomTestOptimizations.ParseProgram START');
  164. {$ENDIF}
  165. AnalyzerProgram.AnalyzeWholeProgram(Module as TPasProgram);
  166. {$IF defined(VerbosePas2JS) or defined(VerbosePasAnalyzer)}
  167. writeln('TCustomTestOptimizations.ParseProgram START');
  168. {$ENDIF}
  169. end;
  170. function TCustomTestOptimizations.CreateConverter: TPasToJSConverter;
  171. begin
  172. Result:=inherited CreateConverter;
  173. Result.OnIsElementUsed:=@OnConverterIsElementUsed;
  174. Result.OnIsTypeInfoUsed:=@OnConverterIsTypeInfoUsed;
  175. end;
  176. { TTestOptimizations }
  177. procedure TTestOptimizations.TestOptAliasGlobals_Program;
  178. begin
  179. AddModuleWithIntfImplSrc('UnitA.pas',
  180. LinesToStr([
  181. 'const',
  182. ' cWidth = 17;',
  183. 'type',
  184. ' TBird = class',
  185. ' public',
  186. ' class var c: word;',
  187. ' class function Run(w: word): word; virtual; abstract;',
  188. ' end;',
  189. ' TRec = record',
  190. ' x: word;',
  191. ' end;',
  192. 'var b: TBird;',
  193. '']),
  194. LinesToStr([
  195. '']));
  196. StartProgram(true,[supTObject]);
  197. Add([
  198. '{$optimization AliasGlobals}',
  199. 'uses unita;',
  200. 'type',
  201. ' TEagle = class(TBird)',
  202. ' class function Run(w: word = 5): word; override;',
  203. ' end;',
  204. 'class function TEagle.Run(w: word): word;',
  205. 'begin',
  206. 'end;',
  207. 'var',
  208. ' e: TEagle;',
  209. ' r: TRec;',
  210. 'begin',
  211. ' e:=TEagle.Create;',
  212. ' b:=TBird.Create;',
  213. ' e.c:=e.c+1;',
  214. ' r.x:=TBird.c;',
  215. ' r.x:=b.c;',
  216. ' r.x:=e.Run;',
  217. ' r.x:=e.Run();',
  218. ' r.x:=e.Run(4);',
  219. '']);
  220. ConvertProgram;
  221. CheckSource('TestOptAliasGlobals_Program',
  222. LinesToStr([
  223. 'var $lmr = pas.UnitA;',
  224. 'var $ltr = $lmr.TBird;',
  225. 'var $ltr1 = $lmr.TRec;',
  226. 'rtl.createClass($mod, "TEagle", $ltr, function () {',
  227. ' this.Run = function (w) {',
  228. ' var Result = 0;',
  229. ' return Result;',
  230. ' };',
  231. '});',
  232. 'this.e = null;',
  233. 'this.r = $ltr1.$new();',
  234. '']),
  235. LinesToStr([
  236. '$mod.e = $mod.TEagle.$create("Create");',
  237. '$lmr.b = $ltr.$create("Create");',
  238. '$ltr.c = $mod.e.c + 1;',
  239. '$mod.r.x = $ltr.c;',
  240. '$mod.r.x = $lmr.b.c;',
  241. '$mod.r.x = $mod.e.$class.Run(5);',
  242. '$mod.r.x = $mod.e.$class.Run(5);',
  243. '$mod.r.x = $mod.e.$class.Run(4);',
  244. '']));
  245. end;
  246. procedure TTestOptimizations.TestOptAliasGlobals_Unit;
  247. begin
  248. exit;
  249. AddModuleWithIntfImplSrc('UnitA.pas',
  250. LinesToStr([
  251. 'const',
  252. ' cWidth = 17;',
  253. 'type',
  254. ' TBird = class',
  255. ' public',
  256. ' class var Span: word;',
  257. ' class procedure Fly(w: word); virtual; abstract;',
  258. ' end;',
  259. ' TRecA = record',
  260. ' x: word;',
  261. ' end;',
  262. 'var Bird: TBird;',
  263. '']),
  264. LinesToStr([
  265. '']));
  266. AddModuleWithIntfImplSrc('UnitB.pas',
  267. LinesToStr([
  268. 'const',
  269. ' cHeight = 23;',
  270. 'type',
  271. ' TAnt = class',
  272. ' public',
  273. ' class var Legs: word;',
  274. ' class procedure Run(w: word); virtual; abstract;',
  275. ' end;',
  276. ' TRecB = record',
  277. ' y: word;',
  278. ' end;',
  279. 'var Ant: TAnt;',
  280. '']),
  281. LinesToStr([
  282. '']));
  283. StartUnit(true,[supTObject]);
  284. Add([
  285. '{$optimization AliasGlobals}',
  286. 'interface',
  287. 'uses unita;',
  288. 'type',
  289. ' TEagle = class(TBird)',
  290. ' class var EagleRec: TRecA;',
  291. ' class procedure Fly(w: word = 5); override;',
  292. ' end;',
  293. 'implementation',
  294. 'uses unitb;',
  295. 'type',
  296. ' TRedAnt = class(TAnt)',
  297. ' class var RedAntRecA: TRecA;',
  298. ' class var RedAntRecB: TRecB;',
  299. ' class procedure Run(w: word = 6); override;',
  300. ' end;',
  301. 'class procedure TEagle.Fly(w: word);',
  302. 'begin',
  303. 'end;',
  304. 'class procedure TRedAnt.Run(w: word);',
  305. 'begin',
  306. 'end;',
  307. 'var',
  308. ' Eagle: TEagle;',
  309. ' RedAnt: TRedAnt;',
  310. 'initialization',
  311. ' Eagle:=TEagle.Create;',
  312. ' RedAnt:=TRedAnt.Create;',
  313. ' Bird:=TBird.Create;',
  314. ' Ant:=TAnt.Create;',
  315. ' TRedAnt.RedAntRecA.x:=TRedAnt.RedAntRecB.y;',
  316. '']);
  317. ConvertUnit;
  318. CheckSource('TestOptAliasGlobals_Unit',
  319. LinesToStr([
  320. '']),
  321. LinesToStr([
  322. '']));
  323. end;
  324. procedure TTestOptimizations.TestWPO_OmitLocalVar;
  325. begin
  326. StartProgram(false);
  327. Add('var');
  328. Add(' a: longint;');
  329. Add(' b: longint;');
  330. Add('begin');
  331. Add(' b:=3;');
  332. ConvertProgram;
  333. CheckSource('TestWPO_OmitLocalVar',
  334. 'this.b = 0;',
  335. '$mod.b = 3;');
  336. end;
  337. procedure TTestOptimizations.TestWPO_OmitLocalProc;
  338. begin
  339. StartProgram(false);
  340. Add('procedure DoIt; begin end;');
  341. Add('procedure NoIt; begin end;');
  342. Add('begin');
  343. Add(' DoIt;');
  344. ConvertProgram;
  345. CheckSource('TestWPO_OmitLocalProc',
  346. LinesToStr([
  347. 'this.DoIt = function () {',
  348. '};',
  349. '']),
  350. LinesToStr([
  351. '$mod.DoIt();',
  352. '']));
  353. end;
  354. procedure TTestOptimizations.TestWPO_OmitLocalProcForward;
  355. begin
  356. StartProgram(false);
  357. Add('procedure DoIt; forward;');
  358. Add('procedure NoIt; forward;');
  359. Add('procedure DoIt; begin end;');
  360. Add('procedure NoIt; begin end;');
  361. Add('begin');
  362. Add(' DoIt;');
  363. ConvertProgram;
  364. CheckSource('TestWPO_OmitLocalProcForward',
  365. LinesToStr([
  366. 'this.DoIt = function () {',
  367. '};',
  368. '']),
  369. LinesToStr([
  370. '$mod.DoIt();',
  371. '']));
  372. end;
  373. procedure TTestOptimizations.TestWPO_OmitProcLocalVar;
  374. begin
  375. StartProgram(false);
  376. Add('function DoIt: longint;');
  377. Add('var');
  378. Add(' a: longint;');
  379. Add(' b: longint;');
  380. Add('begin');
  381. Add(' b:=3;');
  382. Add(' Result:=b;');
  383. Add('end;');
  384. Add('begin');
  385. Add(' DoIt;');
  386. ConvertProgram;
  387. CheckSource('TestWPO_OmitProcLocalVar',
  388. LinesToStr([
  389. 'this.DoIt = function () {',
  390. ' var Result = 0;',
  391. ' var b = 0;',
  392. ' b = 3;',
  393. ' Result = b;',
  394. ' return Result;',
  395. '};',
  396. '']),
  397. LinesToStr([
  398. '$mod.DoIt();',
  399. '']));
  400. end;
  401. procedure TTestOptimizations.TestWPO_OmitProcLocalConst;
  402. begin
  403. StartProgram(false);
  404. Add('function DoIt: longint;');
  405. Add('const');
  406. Add(' a = 3;');
  407. Add(' b = 4;');
  408. Add(' c: longint = 5;');
  409. Add(' d: longint = 6;');
  410. Add('begin');
  411. Add(' Result:=b+d;');
  412. Add('end;');
  413. Add('begin');
  414. Add(' DoIt;');
  415. ConvertProgram;
  416. CheckSource('TestWPO_OmitProcLocalConst',
  417. LinesToStr([
  418. 'var b = 4;',
  419. 'var d = 6;',
  420. 'this.DoIt = function () {',
  421. ' var Result = 0;',
  422. ' Result = 4 + d;',
  423. ' return Result;',
  424. '};',
  425. '']),
  426. LinesToStr([
  427. '$mod.DoIt();',
  428. '']));
  429. end;
  430. procedure TTestOptimizations.TestWPO_OmitProcLocalType;
  431. begin
  432. StartProgram(false);
  433. Add('function DoIt: longint;');
  434. Add('type');
  435. Add(' TEnum = (red, green);');
  436. Add(' TEnums = set of TEnum;');
  437. Add('begin');
  438. Add(' Result:=3;');
  439. Add('end;');
  440. Add('begin');
  441. Add(' DoIt;');
  442. ConvertProgram;
  443. CheckSource('TestWPO_OmitProcLocalType',
  444. LinesToStr([
  445. 'this.DoIt = function () {',
  446. ' var Result = 0;',
  447. ' Result = 3;',
  448. ' return Result;',
  449. '};',
  450. '']),
  451. LinesToStr([
  452. '$mod.DoIt();',
  453. '']));
  454. end;
  455. procedure TTestOptimizations.TestWPO_OmitProcLocalProc;
  456. begin
  457. StartProgram(false);
  458. Add('procedure DoIt;');
  459. Add(' procedure SubProcA; begin end;');
  460. Add(' procedure SubProcB; begin end;');
  461. Add('begin');
  462. Add(' SubProcB;');
  463. Add('end;');
  464. Add('begin');
  465. Add(' DoIt;');
  466. ConvertProgram;
  467. CheckSource('TestWPO_OmitProcLocalProc',
  468. LinesToStr([
  469. 'this.DoIt = function () {',
  470. ' function SubProcB() {',
  471. ' };',
  472. ' SubProcB();',
  473. '};',
  474. '']),
  475. LinesToStr([
  476. '$mod.DoIt();',
  477. '']));
  478. end;
  479. procedure TTestOptimizations.TestWPO_OmitProcLocalForwardProc;
  480. begin
  481. StartProgram(false);
  482. Add('procedure DoIt;');
  483. Add(' procedure SubProcA; forward;');
  484. Add(' procedure SubProcB; forward;');
  485. Add(' procedure SubProcA; begin end;');
  486. Add(' procedure SubProcB; begin end;');
  487. Add('begin');
  488. Add(' SubProcB;');
  489. Add('end;');
  490. Add('begin');
  491. Add(' DoIt;');
  492. ConvertProgram;
  493. CheckSource('TestWPO_OmitProcLocalForwardProc',
  494. LinesToStr([
  495. 'this.DoIt = function () {',
  496. ' function SubProcB() {',
  497. ' };',
  498. ' SubProcB();',
  499. '};',
  500. '']),
  501. LinesToStr([
  502. '$mod.DoIt();',
  503. '']));
  504. end;
  505. procedure TTestOptimizations.TestWPO_OmitRecordMember;
  506. begin
  507. StartProgram(false);
  508. Add('type');
  509. Add(' TRec = record');
  510. Add(' a: longint;');
  511. Add(' b: longint;');
  512. Add(' end;');
  513. Add('var r: TRec;');
  514. Add('begin');
  515. Add(' r.a:=3;');
  516. ConvertProgram;
  517. CheckSource('TestWPO_OmitRecordMember',
  518. LinesToStr([
  519. 'rtl.recNewT($mod, "TRec", function () {',
  520. ' this.a = 0;',
  521. ' this.$eq = function (b) {',
  522. ' return this.a === b.a;',
  523. ' };',
  524. ' this.$assign = function (s) {',
  525. ' this.a = s.a;',
  526. ' return this;',
  527. ' };',
  528. '});',
  529. 'this.r = $mod.TRec.$new();',
  530. '']),
  531. LinesToStr([
  532. '$mod.r.a = 3;',
  533. '']));
  534. end;
  535. procedure TTestOptimizations.TestWPO_OmitNotUsedTObject;
  536. begin
  537. StartProgram(false);
  538. Add('type');
  539. Add(' TObject = class end;');
  540. Add('var o: TObject;');
  541. Add('begin');
  542. ConvertProgram;
  543. CheckSource('TestWPO_OmitNotUsedTObject',
  544. LinesToStr([
  545. '']),
  546. LinesToStr([
  547. '']));
  548. end;
  549. procedure TTestOptimizations.TestWPO_TObject;
  550. begin
  551. StartProgram(false);
  552. Add('type');
  553. Add(' TObject = class');
  554. Add(' procedure AfterConstruction; virtual;');
  555. Add(' procedure BeforeDestruction; virtual;');
  556. Add(' end;');
  557. Add('procedure TObject.AfterConstruction; begin end;');
  558. Add('procedure TObject.BeforeDestruction; begin end;');
  559. Add('var o: TObject;');
  560. Add('begin');
  561. Add(' o:=nil;');
  562. ConvertProgram;
  563. CheckSource('TestWPO_TObject',
  564. LinesToStr([
  565. 'rtl.createClass($mod, "TObject", null, function () {',
  566. ' this.$init = function () {',
  567. ' };',
  568. ' this.$final = function () {',
  569. ' };',
  570. ' this.AfterConstruction = function () {',
  571. ' };',
  572. ' this.BeforeDestruction = function () {',
  573. ' };',
  574. '});',
  575. 'this.o = null;',
  576. '']),
  577. LinesToStr([
  578. '$mod.o = null;']));
  579. end;
  580. procedure TTestOptimizations.TestWPO_Class_Property;
  581. begin
  582. StartProgram(false);
  583. Add([
  584. 'type',
  585. ' TObject = class',
  586. ' private',
  587. ' const CA = 3;',
  588. ' private',
  589. ' FA: longint;',
  590. ' function GetA: longint;',
  591. ' procedure SetA(Value: longint);',
  592. ' function IsStoredA: boolean;',
  593. ' property A: longint read GetA write SetA stored IsStoredA default CA;',
  594. ' end;',
  595. 'function tobject.geta: longint; begin end;',
  596. 'procedure tobject.seta(value: longint); begin end;',
  597. 'function tobject.isstoreda: boolean; begin end;',
  598. 'var o: TObject;',
  599. 'begin',
  600. ' o.A:=o.A;']);
  601. ConvertProgram;
  602. CheckSource('TestWPO_Class_TObject',
  603. LinesToStr([
  604. 'rtl.createClass($mod, "TObject", null, function () {',
  605. ' this.$init = function () {',
  606. ' };',
  607. ' this.$final = function () {',
  608. ' };',
  609. ' this.GetA = function () {',
  610. ' var Result = 0;',
  611. ' return Result;',
  612. ' };',
  613. ' this.SetA = function (Value) {',
  614. ' };',
  615. '});',
  616. 'this.o = null;',
  617. '']),
  618. LinesToStr([
  619. '$mod.o.SetA($mod.o.GetA());']));
  620. end;
  621. procedure TTestOptimizations.TestWPO_Class_OmitField;
  622. begin
  623. StartProgram(false);
  624. Add('type');
  625. Add(' TObject = class');
  626. Add(' a: longint;');
  627. Add(' b: longint;');
  628. Add(' end;');
  629. Add('var o: TObject;');
  630. Add('begin');
  631. Add(' o.a:=3;');
  632. ConvertProgram;
  633. CheckSource('TestWPO_OmitClassField',
  634. LinesToStr([
  635. 'rtl.createClass($mod, "TObject", null, function () {',
  636. ' this.$init = function () {',
  637. ' this.a = 0;',
  638. ' };',
  639. ' this.$final = function () {',
  640. ' };',
  641. '});',
  642. 'this.o = null;',
  643. '']),
  644. LinesToStr([
  645. '$mod.o.a = 3;']));
  646. end;
  647. procedure TTestOptimizations.TestWPO_Class_OmitMethod;
  648. begin
  649. StartProgram(false);
  650. Add('type');
  651. Add(' TObject = class');
  652. Add(' procedure ProcA;');
  653. Add(' procedure ProcB;');
  654. Add(' end;');
  655. Add('procedure TObject.ProcA; begin end;');
  656. Add('procedure TObject.ProcB; begin end;');
  657. Add('var o: TObject;');
  658. Add('begin');
  659. Add(' o.ProcB;');
  660. ConvertProgram;
  661. CheckSource('TestWPO_OmitClassMethod',
  662. LinesToStr([
  663. 'rtl.createClass($mod, "TObject", null, function () {',
  664. ' this.$init = function () {',
  665. ' };',
  666. ' this.$final = function () {',
  667. ' };',
  668. ' this.ProcB = function () {',
  669. ' };',
  670. '});',
  671. 'this.o = null;',
  672. '']),
  673. LinesToStr([
  674. '$mod.o.ProcB();']));
  675. end;
  676. procedure TTestOptimizations.TestWPO_Class_OmitClassMethod;
  677. begin
  678. StartProgram(false);
  679. Add('type');
  680. Add(' TObject = class');
  681. Add(' class procedure ProcA;');
  682. Add(' class procedure ProcB;');
  683. Add(' end;');
  684. Add('class procedure TObject.ProcA; begin end;');
  685. Add('class procedure TObject.ProcB; begin end;');
  686. Add('var o: TObject;');
  687. Add('begin');
  688. Add(' o.ProcB;');
  689. ConvertProgram;
  690. CheckSource('TestWPO_OmitClassMethod',
  691. LinesToStr([
  692. 'rtl.createClass($mod, "TObject", null, function () {',
  693. ' this.$init = function () {',
  694. ' };',
  695. ' this.$final = function () {',
  696. ' };',
  697. ' this.ProcB = function () {',
  698. ' };',
  699. '});',
  700. 'this.o = null;',
  701. '']),
  702. LinesToStr([
  703. '$mod.o.$class.ProcB();']));
  704. end;
  705. procedure TTestOptimizations.TestWPO_Class_OmitPropertyGetter1;
  706. begin
  707. StartProgram(false);
  708. Add('type');
  709. Add(' TObject = class');
  710. Add(' FFoo: boolean;');
  711. Add(' function GetFoo: boolean;');
  712. Add(' property Foo: boolean read FFoo;');
  713. Add(' property Foo2: boolean read GetFoo;');
  714. Add(' FBar: boolean;');
  715. Add(' function GetBar: boolean;');
  716. Add(' property Bar: boolean read FBar;');
  717. Add(' property Bar2: boolean read GetBar;');
  718. Add(' end;');
  719. Add('function TObject.GetFoo: boolean; begin Result:=FFoo; end;');
  720. Add('function TObject.GetBar: boolean; begin Result:=FBar; end;');
  721. Add('var o: TObject;');
  722. Add('begin');
  723. Add(' if o.Foo then;');
  724. ConvertProgram;
  725. CheckSource('TestWPO_OmitClassPropertyGetter1',
  726. LinesToStr([
  727. 'rtl.createClass($mod, "TObject", null, function () {',
  728. ' this.$init = function () {',
  729. ' this.FFoo = false;',
  730. ' };',
  731. ' this.$final = function () {',
  732. ' };',
  733. '});',
  734. 'this.o = null;',
  735. '']),
  736. LinesToStr([
  737. 'if ($mod.o.FFoo);',
  738. '']));
  739. end;
  740. procedure TTestOptimizations.TestWPO_Class_OmitPropertyGetter2;
  741. begin
  742. StartProgram(false);
  743. Add('type');
  744. Add(' TObject = class');
  745. Add(' FFoo: boolean;');
  746. Add(' function GetFoo: boolean;');
  747. Add(' property Foo: boolean read FFoo;');
  748. Add(' property Foo2: boolean read GetFoo;');
  749. Add(' end;');
  750. Add('function TObject.GetFoo: boolean; begin Result:=FFoo; end;');
  751. Add('var o: TObject;');
  752. Add('begin');
  753. Add(' if o.Foo2 then;');
  754. ConvertProgram;
  755. CheckSource('TestWPO_OmitClassPropertyGetter2',
  756. LinesToStr([
  757. 'rtl.createClass($mod, "TObject", null, function () {',
  758. ' this.$init = function () {',
  759. ' this.FFoo = false;',
  760. ' };',
  761. ' this.$final = function () {',
  762. ' };',
  763. ' this.GetFoo = function () {',
  764. ' var Result = false;',
  765. ' Result = this.FFoo;',
  766. ' return Result;',
  767. ' };',
  768. '});',
  769. 'this.o = null;',
  770. '']),
  771. LinesToStr([
  772. 'if ($mod.o.GetFoo()) ;',
  773. '']));
  774. end;
  775. procedure TTestOptimizations.TestWPO_Class_OmitPropertySetter1;
  776. begin
  777. StartProgram(false);
  778. Add('type');
  779. Add(' TObject = class');
  780. Add(' FFoo: boolean;');
  781. Add(' procedure SetFoo(Value: boolean);');
  782. Add(' property Foo: boolean write FFoo;');
  783. Add(' property Foo2: boolean write SetFoo;');
  784. Add(' FBar: boolean;');
  785. Add(' procedure SetBar(Value: boolean);');
  786. Add(' property Bar: boolean write FBar;');
  787. Add(' property Bar2: boolean write SetBar;');
  788. Add(' end;');
  789. Add('procedure TObject.SetFoo(Value: boolean); begin FFoo:=Value; end;');
  790. Add('procedure TObject.SetBar(Value: boolean); begin FBar:=Value; end;');
  791. Add('var o: TObject;');
  792. Add('begin');
  793. Add(' o.Foo:=true;');
  794. ConvertProgram;
  795. CheckSource('TestWPO_OmitClassPropertySetter1',
  796. LinesToStr([
  797. 'rtl.createClass($mod, "TObject", null, function () {',
  798. ' this.$init = function () {',
  799. ' this.FFoo = false;',
  800. ' };',
  801. ' this.$final = function () {',
  802. ' };',
  803. '});',
  804. 'this.o = null;',
  805. '']),
  806. LinesToStr([
  807. '$mod.o.FFoo = true;',
  808. '']));
  809. end;
  810. procedure TTestOptimizations.TestWPO_Class_OmitPropertySetter2;
  811. begin
  812. StartProgram(false);
  813. Add('type');
  814. Add(' TObject = class');
  815. Add(' FFoo: boolean;');
  816. Add(' procedure SetFoo(Value: boolean);');
  817. Add(' property Foo: boolean write FFoo;');
  818. Add(' property Foo2: boolean write SetFoo;');
  819. Add(' end;');
  820. Add('procedure TObject.SetFoo(Value: boolean); begin FFoo:=Value; end;');
  821. Add('var o: TObject;');
  822. Add('begin');
  823. Add(' o.Foo2:=true;');
  824. ConvertProgram;
  825. CheckSource('TestWPO_OmitClassPropertySetter2',
  826. LinesToStr([
  827. 'rtl.createClass($mod, "TObject", null, function () {',
  828. ' this.$init = function () {',
  829. ' this.FFoo = false;',
  830. ' };',
  831. ' this.$final = function () {',
  832. ' };',
  833. ' this.SetFoo = function (Value) {',
  834. ' this.FFoo = Value;',
  835. ' };',
  836. '});',
  837. 'this.o = null;',
  838. '']),
  839. LinesToStr([
  840. '$mod.o.SetFoo(true);',
  841. '']));
  842. end;
  843. procedure TTestOptimizations.TestWPO_Class_KeepNewInstance;
  844. begin
  845. StartProgram(false);
  846. Add([
  847. '{$modeswitch externalclass}',
  848. 'type',
  849. ' TExt = class external name ''Object''',
  850. ' end;',
  851. ' TBird = class(TExt)',
  852. ' protected',
  853. ' class function NewInstance(fnname: string; const paramarray): TBird; virtual;',
  854. ' public',
  855. ' constructor Create;',
  856. ' end;',
  857. 'class function TBird.NewInstance(fnname: string; const paramarray): TBird;',
  858. 'begin',
  859. ' asm',
  860. ' Result = Object.create();',
  861. ' end;',
  862. 'end;',
  863. 'constructor TBird.Create;',
  864. 'begin',
  865. ' inherited;',
  866. 'end;',
  867. 'begin',
  868. ' TBird.Create;',
  869. '']);
  870. ConvertProgram;
  871. CheckSource('TestWPO_Class_KeepNewInstance',
  872. LinesToStr([
  873. 'rtl.createClassExt($mod, "TBird", Object, "NewInstance", function () {',
  874. ' this.$init = function () {',
  875. ' };',
  876. ' this.$final = function () {',
  877. ' };',
  878. ' this.NewInstance = function (fnname, paramarray) {',
  879. ' var Result = null;',
  880. ' Result = Object.create();',
  881. ' return Result;',
  882. ' };',
  883. ' this.Create = function () {',
  884. ' return this;',
  885. ' };',
  886. '});',
  887. '']),
  888. LinesToStr([
  889. '$mod.TBird.$create("Create");',
  890. '']));
  891. end;
  892. procedure TTestOptimizations.TestWPO_CallInherited;
  893. begin
  894. StartProgram(false);
  895. Add('type');
  896. Add(' TObject = class');
  897. Add(' procedure DoA;');
  898. Add(' procedure DoB;');
  899. Add(' end;');
  900. Add(' TMobile = class');
  901. Add(' procedure DoA;');
  902. Add(' procedure DoC;');
  903. Add(' end;');
  904. Add('procedure TObject.DoA; begin end;');
  905. Add('procedure TObject.DoB; begin end;');
  906. Add('procedure TMobile.DoA;');
  907. Add('begin');
  908. Add(' inherited;');
  909. Add('end;');
  910. Add('procedure TMobile.DoC;');
  911. Add('begin');
  912. Add(' inherited DoB;');
  913. Add('end;');
  914. Add('var o: TMobile;');
  915. Add('begin');
  916. Add(' o.DoA;');
  917. Add(' o.DoC;');
  918. ConvertProgram;
  919. CheckSource('TestWPO_CallInherited',
  920. LinesToStr([
  921. 'rtl.createClass($mod, "TObject", null, function () {',
  922. ' this.$init = function () {',
  923. ' };',
  924. ' this.$final = function () {',
  925. ' };',
  926. ' this.DoA = function () {',
  927. ' };',
  928. ' this.DoB = function () {',
  929. ' };',
  930. '});',
  931. ' rtl.createClass($mod, "TMobile", $mod.TObject, function () {',
  932. ' this.DoA$1 = function () {',
  933. ' $mod.TObject.DoA.call(this);',
  934. ' };',
  935. ' this.DoC = function () {',
  936. ' $mod.TObject.DoB.call(this);',
  937. ' };',
  938. '});',
  939. 'this.o = null;',
  940. '']),
  941. LinesToStr([
  942. '$mod.o.DoA$1();',
  943. '$mod.o.DoC();',
  944. '']));
  945. end;
  946. procedure TTestOptimizations.TestWPO_UseUnit;
  947. var
  948. ActualSrc, ExpectedSrc: String;
  949. begin
  950. AddModuleWithIntfImplSrc('unit1.pp',
  951. LinesToStr([
  952. 'var i: longint;',
  953. 'procedure DoIt;',
  954. '']),
  955. LinesToStr([
  956. 'procedure DoIt; begin end;']));
  957. AddModuleWithIntfImplSrc('unit2.pp',
  958. LinesToStr([
  959. 'var j: longint;',
  960. 'procedure DoMore;',
  961. '']),
  962. LinesToStr([
  963. 'procedure DoMore; begin end;']));
  964. StartProgram(true);
  965. Add('uses unit2;');
  966. Add('begin');
  967. Add(' j:=3;');
  968. ConvertProgram;
  969. ActualSrc:=ConvertJSModuleToString(JSModule);
  970. ExpectedSrc:=LinesToStr([
  971. 'rtl.module("program", ["system", "unit2"], function () {',
  972. ' var $mod = this;',
  973. ' $mod.$main = function () {',
  974. ' pas.unit2.j = 3;',
  975. ' };',
  976. '});',
  977. '']);
  978. CheckDiff('TestWPO_UseUnit',ExpectedSrc,ActualSrc);
  979. end;
  980. procedure TTestOptimizations.TestWPO_ArrayOfConst_Use;
  981. begin
  982. StartProgram(true,[supTVarRec]);
  983. Add([
  984. 'procedure Say(arr: array of const);',
  985. 'begin',
  986. 'end;',
  987. 'begin',
  988. ' Say([true]);']);
  989. ConvertProgram;
  990. CheckUnit('system.pp',
  991. LinesToStr([
  992. 'rtl.module("system", [], function () {',
  993. ' var $mod = this;',
  994. ' rtl.recNewT($mod, "TVarRec", function () {',
  995. ' this.VType = 0;',
  996. ' this.VJSValue = undefined;',
  997. ' this.$eq = function (b) {',
  998. ' return (this.VType === b.VType) && (this.VJSValue === b.VJSValue);',
  999. ' };',
  1000. ' this.$assign = function (s) {',
  1001. ' this.VType = s.VType;',
  1002. ' this.VJSValue = s.VJSValue;',
  1003. ' return this;',
  1004. ' };',
  1005. ' });',
  1006. ' this.VarRecs = function () {',
  1007. ' var Result = [];',
  1008. ' var v = null;',
  1009. ' v.VType = 1;',
  1010. ' v.VJSValue = 2;',
  1011. ' return Result;',
  1012. ' };',
  1013. '});',
  1014. '']));
  1015. end;
  1016. procedure TTestOptimizations.TestWPO_ArrayOfConst_NotUsed;
  1017. begin
  1018. StartProgram(true,[supTVarRec]);
  1019. Add([
  1020. 'procedure Say(arr: array of const);',
  1021. 'begin',
  1022. 'end;',
  1023. 'begin']);
  1024. ConvertProgram;
  1025. CheckUnit('system.pp',
  1026. LinesToStr([
  1027. 'rtl.module("system", [], function () {',
  1028. ' var $mod = this;',
  1029. '});',
  1030. '']));
  1031. end;
  1032. procedure TTestOptimizations.TestWPO_Class_PropertyInOtherUnit;
  1033. begin
  1034. AddModuleWithIntfImplSrc('unit1.pp',
  1035. LinesToStr([
  1036. 'type',
  1037. ' TObject = class',
  1038. ' private',
  1039. ' const CA = 3;',
  1040. ' private',
  1041. ' FOther: string;',
  1042. ' FA: longint;',
  1043. ' function GetA: longint;',
  1044. ' procedure SetA(Value: longint);',
  1045. ' function IsStoredA: boolean;',
  1046. ' public',
  1047. ' property A: longint read GetA write SetA stored IsStoredA default CA;',
  1048. ' end;',
  1049. '']),
  1050. LinesToStr([
  1051. 'function TObject.geta: longint;',
  1052. 'begin',
  1053. 'end;',
  1054. 'procedure TObject.seta(value: longint);',
  1055. 'begin',
  1056. ' FA:=Value;',
  1057. 'end;',
  1058. 'function TObject.isstoreda: boolean; begin end;',
  1059. '']));
  1060. StartProgram(true);
  1061. Add([
  1062. 'uses unit1;',
  1063. 'var o: TObject;',
  1064. 'begin',
  1065. ' o.A:=o.A;']);
  1066. ConvertProgram;
  1067. CheckUnit('unit1.pp',
  1068. LinesToStr([
  1069. 'rtl.module("unit1", ["system"], function () {',
  1070. ' var $mod = this;',
  1071. ' rtl.createClass($mod, "TObject", null, function () {',
  1072. ' this.$init = function () {',
  1073. ' this.FA = 0;',
  1074. ' };',
  1075. ' this.$final = function () {',
  1076. ' };',
  1077. ' this.GetA = function () {',
  1078. ' var Result = 0;',
  1079. ' return Result;',
  1080. ' };',
  1081. ' this.SetA = function (Value) {',
  1082. ' this.FA = Value;',
  1083. ' };',
  1084. ' });',
  1085. '});',
  1086. '']));
  1087. end;
  1088. procedure TTestOptimizations.TestWPO_ProgramPublicDeclaration;
  1089. var
  1090. ActualSrc, ExpectedSrc: String;
  1091. begin
  1092. StartProgram(true);
  1093. Add('var');
  1094. Add(' vPublic: longint; public;');
  1095. Add(' vPrivate: longint;');
  1096. Add('procedure DoPublic; public; begin end;');
  1097. Add('procedure DoPrivate; begin end;');
  1098. Add('begin');
  1099. ConvertProgram;
  1100. ActualSrc:=ConvertJSModuleToString(JSModule);
  1101. ExpectedSrc:=LinesToStr([
  1102. 'rtl.module("program", ["system"], function () {',
  1103. ' var $mod = this;',
  1104. ' this.vPublic = 0;',
  1105. ' this.DoPublic =function(){',
  1106. ' };',
  1107. ' $mod.$main = function () {',
  1108. ' };',
  1109. '});',
  1110. '']);
  1111. CheckDiff('TestWPO_ProgramPublicDeclaration',ExpectedSrc,ActualSrc);
  1112. end;
  1113. procedure TTestOptimizations.TestWPO_ConstructorDefaultValueConst;
  1114. var
  1115. ActualSrc, ExpectedSrc: String;
  1116. begin
  1117. Converter.Options:=Converter.Options-[coNoTypeInfo];
  1118. StartProgram(true);
  1119. Add([
  1120. 'const gcBlack = 0;',
  1121. 'type',
  1122. ' TColor = longint;',
  1123. ' TObject = class',
  1124. ' private',
  1125. ' FColor: TColor;',
  1126. ' public',
  1127. ' property Color: TColor read FColor write FColor;',
  1128. ' constructor Create(const AColor: TColor = gcBlack);',
  1129. ' end;',
  1130. 'constructor TObject.Create(const AColor: TColor = gcBlack);',
  1131. 'begin',
  1132. ' FColor := AColor;',
  1133. 'end;',
  1134. 'var T: TObject;',
  1135. 'begin',
  1136. ' T := TObject.Create;',
  1137. '']);
  1138. ConvertProgram;
  1139. ActualSrc:=ConvertJSModuleToString(JSModule);
  1140. ExpectedSrc:=LinesToStr([
  1141. 'rtl.module("program",["system"],function () {',
  1142. ' var $mod = this;',
  1143. ' this.gcBlack = 0;',
  1144. ' rtl.createClass($mod,"TObject",null,function () {',
  1145. ' this.$init = function () {',
  1146. ' this.FColor = 0;',
  1147. ' };',
  1148. ' this.$final = function () {',
  1149. ' };',
  1150. ' this.Create = function (AColor) {',
  1151. ' this.FColor = AColor;',
  1152. ' return this;',
  1153. ' };',
  1154. ' });',
  1155. ' this.T = null;',
  1156. ' $mod.$main = function () {',
  1157. ' $mod.T = $mod.TObject.$create("Create",[0]);',
  1158. ' };',
  1159. '});',
  1160. '']);
  1161. CheckDiff('TestWPO_ConstructorDefaultValueConst',ExpectedSrc,ActualSrc);
  1162. end;
  1163. procedure TTestOptimizations.TestWPO_RTTI_PublishedField;
  1164. var
  1165. ActualSrc, ExpectedSrc: String;
  1166. begin
  1167. Converter.Options:=Converter.Options-[coNoTypeInfo];
  1168. StartProgram(true);
  1169. Add('type');
  1170. Add(' TArrA = array of char;');
  1171. Add(' TArrB = array of string;');
  1172. Add(' TObject = class');
  1173. Add(' public');
  1174. Add(' PublicA: TArrA;');
  1175. Add(' published');
  1176. Add(' PublishedB: TArrB;');
  1177. Add(' end;');
  1178. Add('var');
  1179. Add(' C: TObject;');
  1180. Add('begin');
  1181. Add(' C.PublicA:=nil;');
  1182. ConvertProgram;
  1183. ActualSrc:=ConvertJSModuleToString(JSModule);
  1184. ExpectedSrc:=LinesToStr([
  1185. 'rtl.module("program", ["system"], function () {',
  1186. ' var $mod = this;',
  1187. ' $mod.$rtti.$DynArray("TArrB", {',
  1188. ' eltype: rtl.string',
  1189. ' });',
  1190. ' rtl.createClass($mod, "TObject", null, function () {',
  1191. ' this.$init = function () {',
  1192. ' this.PublicA = [];',
  1193. ' this.PublishedB = [];',
  1194. ' };',
  1195. ' this.$final = function () {',
  1196. ' this.PublicA = undefined;',
  1197. ' this.PublishedB = undefined;',
  1198. ' };',
  1199. ' var $r = this.$rtti;',
  1200. ' $r.addField("PublishedB", $mod.$rtti["TArrB"]);',
  1201. ' });',
  1202. ' this.C = null;',
  1203. ' $mod.$main = function () {',
  1204. ' $mod.C.PublicA = [];',
  1205. ' };',
  1206. '});',
  1207. '']);
  1208. CheckDiff('TestWPO_RTTI_PublishedField',ExpectedSrc,ActualSrc);
  1209. end;
  1210. procedure TTestOptimizations.TestWPO_RTTI_TypeInfo;
  1211. var
  1212. ActualSrc, ExpectedSrc: String;
  1213. begin
  1214. Converter.Options:=Converter.Options-[coNoTypeInfo];
  1215. StartProgram(true);
  1216. Add('type');
  1217. Add(' TArrA = array of char;');
  1218. Add(' TArrB = array of string;');
  1219. Add('var');
  1220. Add(' A: TArrA;');
  1221. Add(' B: TArrB;');
  1222. Add(' p: pointer;');
  1223. Add('begin');
  1224. Add(' A:=nil;');
  1225. Add(' p:=typeinfo(B);');
  1226. ConvertProgram;
  1227. ActualSrc:=ConvertJSModuleToString(JSModule);
  1228. ExpectedSrc:=LinesToStr([
  1229. 'rtl.module("program", ["system"], function () {',
  1230. ' var $mod = this;',
  1231. ' $mod.$rtti.$DynArray("TArrB", {',
  1232. ' eltype: rtl.string',
  1233. ' });',
  1234. ' this.A = [];',
  1235. ' this.B = [];',
  1236. ' this.p = null;',
  1237. ' $mod.$main = function () {',
  1238. ' $mod.A = [];',
  1239. ' $mod.p = $mod.$rtti["TArrB"];',
  1240. ' };',
  1241. '});',
  1242. '']);
  1243. CheckDiff('TestWPO_RTTI_TypeInfo',ExpectedSrc,ActualSrc);
  1244. end;
  1245. Initialization
  1246. RegisterTests([TTestOptimizations]);
  1247. end.