tcoptimizations.pas 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866
  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, PasUseAnalyzer, PasResolver, PasResolveEval,
  21. tcmodules;
  22. type
  23. { TCustomTestOptimizations }
  24. TCustomTestOptimizations = class(TCustomTestModule)
  25. private
  26. FAnalyzerModule: TPasAnalyzer;
  27. FAnalyzerProgram: TPasAnalyzer;
  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. public
  37. property AnalyzerModule: TPasAnalyzer read FAnalyzerModule;
  38. property AnalyzerProgram: TPasAnalyzer read FAnalyzerProgram;
  39. property WholeProgramOptimization: boolean read FWholeProgramOptimization
  40. write FWholeProgramOptimization;
  41. end;
  42. { TTestOptimizations }
  43. TTestOptimizations = class(TCustomTestOptimizations)
  44. published
  45. // Whole Program Optimization
  46. procedure TestWPO_OmitLocalVar;
  47. procedure TestWPO_OmitLocalProc;
  48. procedure TestWPO_OmitLocalProcForward;
  49. procedure TestWPO_OmitProcLocalVar;
  50. procedure TestWPO_OmitProcLocalConst;
  51. procedure TestWPO_OmitProcLocalType;
  52. procedure TestWPO_OmitProcLocalProc;
  53. procedure TestWPO_OmitProcLocalForwardProc;
  54. procedure TestWPO_OmitRecordMember;
  55. procedure TestWPO_OmitNotUsedTObject;
  56. procedure TestWPO_TObject;
  57. procedure TestWPO_OmitClassField;
  58. procedure TestWPO_OmitClassMethod;
  59. procedure TestWPO_OmitClassClassMethod;
  60. procedure TestWPO_OmitPropertyGetter1;
  61. procedure TestWPO_OmitPropertyGetter2;
  62. procedure TestWPO_OmitPropertySetter1;
  63. procedure TestWPO_OmitPropertySetter2;
  64. procedure TestWPO_CallInherited;
  65. procedure TestWPO_UseUnit;
  66. procedure TestWPO_ProgramPublicDeclaration;
  67. procedure TestWPO_RTTI_PublishedField;
  68. procedure TestWPO_RTTI_TypeInfo;
  69. end;
  70. implementation
  71. { TCustomTestOptimizations }
  72. function TCustomTestOptimizations.OnConverterIsElementUsed(Sender: TObject;
  73. El: TPasElement): boolean;
  74. var
  75. A: TPasAnalyzer;
  76. begin
  77. if WholeProgramOptimization then
  78. A:=AnalyzerProgram
  79. else
  80. A:=AnalyzerModule;
  81. Result:=A.IsUsed(El);
  82. {$IF defined(VerbosePas2JS) or defined(VerbosePasAnalyzer)}
  83. writeln('TCustomTestOptimizations.OnConverterIsElementUsed El=',GetObjName(El),' WPO=',WholeProgramOptimization,' Result=',Result);
  84. {$ENDIF}
  85. end;
  86. function TCustomTestOptimizations.OnConverterIsTypeInfoUsed(Sender: TObject;
  87. El: TPasElement): boolean;
  88. var
  89. A: TPasAnalyzer;
  90. begin
  91. if WholeProgramOptimization then
  92. A:=AnalyzerProgram
  93. else
  94. A:=AnalyzerModule;
  95. Result:=A.IsTypeInfoUsed(El);
  96. {$IF defined(VerbosePas2JS) or defined(VerbosePasAnalyzer)}
  97. writeln('TCustomTestOptimizations.OnConverterIsTypeInfoUsed El=',GetObjName(El),' WPO=',WholeProgramOptimization,' Result=',Result);
  98. {$ENDIF}
  99. end;
  100. procedure TCustomTestOptimizations.SetUp;
  101. begin
  102. inherited SetUp;
  103. FWholeProgramOptimization:=false;
  104. FAnalyzerModule:=TPasAnalyzer.Create;
  105. FAnalyzerModule.Resolver:=Engine;
  106. FAnalyzerProgram:=TPasAnalyzer.Create;
  107. FAnalyzerProgram.Resolver:=Engine;
  108. Converter.OnIsElementUsed:=@OnConverterIsElementUsed;
  109. Converter.OnIsTypeInfoUsed:=@OnConverterIsTypeInfoUsed;
  110. end;
  111. procedure TCustomTestOptimizations.TearDown;
  112. begin
  113. FreeAndNil(FAnalyzerProgram);
  114. FreeAndNil(FAnalyzerModule);
  115. inherited TearDown;
  116. end;
  117. procedure TCustomTestOptimizations.ParseModule;
  118. begin
  119. inherited ParseModule;
  120. {$IF defined(VerbosePas2JS) or defined(VerbosePasAnalyzer)}
  121. writeln('TCustomTestOptimizations.ParseModule START');
  122. {$ENDIF}
  123. AnalyzerModule.AnalyzeModule(Module);
  124. {$IF defined(VerbosePas2JS) or defined(VerbosePasAnalyzer)}
  125. writeln('TCustomTestOptimizations.ParseModule END');
  126. {$ENDIF}
  127. end;
  128. procedure TCustomTestOptimizations.ParseProgram;
  129. begin
  130. WholeProgramOptimization:=true;
  131. inherited ParseProgram;
  132. {$IF defined(VerbosePas2JS) or defined(VerbosePasAnalyzer)}
  133. writeln('TCustomTestOptimizations.ParseProgram START');
  134. {$ENDIF}
  135. AnalyzerProgram.AnalyzeWholeProgram(Module as TPasProgram);
  136. {$IF defined(VerbosePas2JS) or defined(VerbosePasAnalyzer)}
  137. writeln('TCustomTestOptimizations.ParseProgram START');
  138. {$ENDIF}
  139. end;
  140. { TTestOptimizations }
  141. procedure TTestOptimizations.TestWPO_OmitLocalVar;
  142. begin
  143. StartProgram(false);
  144. Add('var');
  145. Add(' a: longint;');
  146. Add(' b: longint;');
  147. Add('begin');
  148. Add(' b:=3;');
  149. ConvertProgram;
  150. CheckSource('TestWPO_OmitLocalVar',
  151. 'this.b = 0;',
  152. '$mod.b = 3;');
  153. end;
  154. procedure TTestOptimizations.TestWPO_OmitLocalProc;
  155. begin
  156. StartProgram(false);
  157. Add('procedure DoIt; begin end;');
  158. Add('procedure NoIt; begin end;');
  159. Add('begin');
  160. Add(' DoIt;');
  161. ConvertProgram;
  162. CheckSource('TestWPO_OmitLocalProc',
  163. LinesToStr([
  164. 'this.DoIt = function () {',
  165. '};',
  166. '']),
  167. LinesToStr([
  168. '$mod.DoIt();',
  169. '']));
  170. end;
  171. procedure TTestOptimizations.TestWPO_OmitLocalProcForward;
  172. begin
  173. StartProgram(false);
  174. Add('procedure DoIt; forward;');
  175. Add('procedure NoIt; forward;');
  176. Add('procedure DoIt; begin end;');
  177. Add('procedure NoIt; begin end;');
  178. Add('begin');
  179. Add(' DoIt;');
  180. ConvertProgram;
  181. CheckSource('TestWPO_OmitLocalProcForward',
  182. LinesToStr([
  183. 'this.DoIt = function () {',
  184. '};',
  185. '']),
  186. LinesToStr([
  187. '$mod.DoIt();',
  188. '']));
  189. end;
  190. procedure TTestOptimizations.TestWPO_OmitProcLocalVar;
  191. begin
  192. StartProgram(false);
  193. Add('function DoIt: longint;');
  194. Add('var');
  195. Add(' a: longint;');
  196. Add(' b: longint;');
  197. Add('begin');
  198. Add(' b:=3;');
  199. Add(' Result:=b;');
  200. Add('end;');
  201. Add('begin');
  202. Add(' DoIt;');
  203. ConvertProgram;
  204. CheckSource('TestWPO_OmitProcLocalVar',
  205. LinesToStr([
  206. 'this.DoIt = function () {',
  207. ' var Result = 0;',
  208. ' var b = 0;',
  209. ' b = 3;',
  210. ' Result = b;',
  211. ' return Result;',
  212. '};',
  213. '']),
  214. LinesToStr([
  215. '$mod.DoIt();',
  216. '']));
  217. end;
  218. procedure TTestOptimizations.TestWPO_OmitProcLocalConst;
  219. begin
  220. StartProgram(false);
  221. Add('function DoIt: longint;');
  222. Add('const');
  223. Add(' a = 3;');
  224. Add(' b = 4;');
  225. Add(' c: longint = 5;');
  226. Add(' d: longint = 6;');
  227. Add('begin');
  228. Add(' Result:=b+d;');
  229. Add('end;');
  230. Add('begin');
  231. Add(' DoIt;');
  232. ConvertProgram;
  233. CheckSource('TestWPO_OmitProcLocalConst',
  234. LinesToStr([
  235. 'var b = 4;',
  236. 'var d = 6;',
  237. 'this.DoIt = function () {',
  238. ' var Result = 0;',
  239. ' Result = b + d;',
  240. ' return Result;',
  241. '};',
  242. '']),
  243. LinesToStr([
  244. '$mod.DoIt();',
  245. '']));
  246. end;
  247. procedure TTestOptimizations.TestWPO_OmitProcLocalType;
  248. begin
  249. StartProgram(false);
  250. Add('function DoIt: longint;');
  251. Add('type');
  252. Add(' TEnum = (red, green);');
  253. Add(' TEnums = set of TEnum;');
  254. Add('begin');
  255. Add(' Result:=3;');
  256. Add('end;');
  257. Add('begin');
  258. Add(' DoIt;');
  259. ConvertProgram;
  260. CheckSource('TestWPO_OmitProcLocalType',
  261. LinesToStr([
  262. 'this.DoIt = function () {',
  263. ' var Result = 0;',
  264. ' Result = 3;',
  265. ' return Result;',
  266. '};',
  267. '']),
  268. LinesToStr([
  269. '$mod.DoIt();',
  270. '']));
  271. end;
  272. procedure TTestOptimizations.TestWPO_OmitProcLocalProc;
  273. begin
  274. StartProgram(false);
  275. Add('procedure DoIt;');
  276. Add(' procedure SubProcA; begin end;');
  277. Add(' procedure SubProcB; begin end;');
  278. Add('begin');
  279. Add(' SubProcB;');
  280. Add('end;');
  281. Add('begin');
  282. Add(' DoIt;');
  283. ConvertProgram;
  284. CheckSource('TestWPO_OmitProcLocalProc',
  285. LinesToStr([
  286. 'this.DoIt = function () {',
  287. ' function SubProcB() {',
  288. ' };',
  289. ' SubProcB();',
  290. '};',
  291. '']),
  292. LinesToStr([
  293. '$mod.DoIt();',
  294. '']));
  295. end;
  296. procedure TTestOptimizations.TestWPO_OmitProcLocalForwardProc;
  297. begin
  298. StartProgram(false);
  299. Add('procedure DoIt;');
  300. Add(' procedure SubProcA; forward;');
  301. Add(' procedure SubProcB; forward;');
  302. Add(' procedure SubProcA; begin end;');
  303. Add(' procedure SubProcB; begin end;');
  304. Add('begin');
  305. Add(' SubProcB;');
  306. Add('end;');
  307. Add('begin');
  308. Add(' DoIt;');
  309. ConvertProgram;
  310. CheckSource('TestWPO_OmitProcLocalForwardProc',
  311. LinesToStr([
  312. 'this.DoIt = function () {',
  313. ' function SubProcB() {',
  314. ' };',
  315. ' SubProcB();',
  316. '};',
  317. '']),
  318. LinesToStr([
  319. '$mod.DoIt();',
  320. '']));
  321. end;
  322. procedure TTestOptimizations.TestWPO_OmitRecordMember;
  323. begin
  324. StartProgram(false);
  325. Add('type');
  326. Add(' TRec = record');
  327. Add(' a: longint;');
  328. Add(' b: longint;');
  329. Add(' end;');
  330. Add('var r: TRec;');
  331. Add('begin');
  332. Add(' r.a:=3;');
  333. ConvertProgram;
  334. CheckSource('TestWPO_OmitRecordMember',
  335. LinesToStr([
  336. 'this.TRec = function (s) {',
  337. ' if (s) {',
  338. ' this.a = s.a;',
  339. ' } else {',
  340. ' this.a = 0;',
  341. ' };',
  342. ' this.$equal = function (b) {',
  343. ' return this.a == b.a;',
  344. ' };',
  345. '};',
  346. 'this.r = new $mod.TRec();',
  347. '']),
  348. LinesToStr([
  349. '$mod.r.a = 3;',
  350. '']));
  351. end;
  352. procedure TTestOptimizations.TestWPO_OmitNotUsedTObject;
  353. begin
  354. StartProgram(false);
  355. Add('type');
  356. Add(' TObject = class end;');
  357. Add('var o: TObject;');
  358. Add('begin');
  359. ConvertProgram;
  360. CheckSource('TestWPO_OmitNotUsedTObject',
  361. LinesToStr([
  362. '']),
  363. LinesToStr([
  364. '']));
  365. end;
  366. procedure TTestOptimizations.TestWPO_TObject;
  367. begin
  368. StartProgram(false);
  369. Add('type');
  370. Add(' TObject = class');
  371. Add(' procedure AfterConstruction; virtual;');
  372. Add(' procedure BeforeDestruction; virtual;');
  373. Add(' end;');
  374. Add('procedure TObject.AfterConstruction; begin end;');
  375. Add('procedure TObject.BeforeDestruction; begin end;');
  376. Add('var o: TObject;');
  377. Add('begin');
  378. Add(' o:=nil;');
  379. ConvertProgram;
  380. CheckSource('TestWPO_TObject',
  381. LinesToStr([
  382. 'rtl.createClass($mod, "TObject", null, function () {',
  383. ' this.$init = function () {',
  384. ' };',
  385. ' this.$final = function () {',
  386. ' };',
  387. ' this.AfterConstruction = function () {',
  388. ' };',
  389. ' this.BeforeDestruction = function () {',
  390. ' };',
  391. '});',
  392. 'this.o = null;',
  393. '']),
  394. LinesToStr([
  395. '$mod.o = null;']));
  396. end;
  397. procedure TTestOptimizations.TestWPO_OmitClassField;
  398. begin
  399. StartProgram(false);
  400. Add('type');
  401. Add(' TObject = class');
  402. Add(' a: longint;');
  403. Add(' b: longint;');
  404. Add(' end;');
  405. Add('var o: TObject;');
  406. Add('begin');
  407. Add(' o.a:=3;');
  408. ConvertProgram;
  409. CheckSource('TestWPO_OmitClassField',
  410. LinesToStr([
  411. 'rtl.createClass($mod, "TObject", null, function () {',
  412. ' this.$init = function () {',
  413. ' this.a = 0;',
  414. ' };',
  415. ' this.$final = function () {',
  416. ' };',
  417. '});',
  418. 'this.o = null;',
  419. '']),
  420. LinesToStr([
  421. '$mod.o.a = 3;']));
  422. end;
  423. procedure TTestOptimizations.TestWPO_OmitClassMethod;
  424. begin
  425. StartProgram(false);
  426. Add('type');
  427. Add(' TObject = class');
  428. Add(' procedure ProcA;');
  429. Add(' procedure ProcB;');
  430. Add(' end;');
  431. Add('procedure TObject.ProcA; begin end;');
  432. Add('procedure TObject.ProcB; begin end;');
  433. Add('var o: TObject;');
  434. Add('begin');
  435. Add(' o.ProcB;');
  436. ConvertProgram;
  437. CheckSource('TestWPO_OmitClassMethod',
  438. LinesToStr([
  439. 'rtl.createClass($mod, "TObject", null, function () {',
  440. ' this.$init = function () {',
  441. ' };',
  442. ' this.$final = function () {',
  443. ' };',
  444. ' this.ProcB = function () {',
  445. ' };',
  446. '});',
  447. 'this.o = null;',
  448. '']),
  449. LinesToStr([
  450. '$mod.o.ProcB();']));
  451. end;
  452. procedure TTestOptimizations.TestWPO_OmitClassClassMethod;
  453. begin
  454. StartProgram(false);
  455. Add('type');
  456. Add(' TObject = class');
  457. Add(' class procedure ProcA;');
  458. Add(' class procedure ProcB;');
  459. Add(' end;');
  460. Add('class procedure TObject.ProcA; begin end;');
  461. Add('class procedure TObject.ProcB; begin end;');
  462. Add('var o: TObject;');
  463. Add('begin');
  464. Add(' o.ProcB;');
  465. ConvertProgram;
  466. CheckSource('TestWPO_OmitClassMethod',
  467. LinesToStr([
  468. 'rtl.createClass($mod, "TObject", null, function () {',
  469. ' this.$init = function () {',
  470. ' };',
  471. ' this.$final = function () {',
  472. ' };',
  473. ' this.ProcB = function () {',
  474. ' };',
  475. '});',
  476. 'this.o = null;',
  477. '']),
  478. LinesToStr([
  479. '$mod.o.$class.ProcB();']));
  480. end;
  481. procedure TTestOptimizations.TestWPO_OmitPropertyGetter1;
  482. begin
  483. StartProgram(false);
  484. Add('type');
  485. Add(' TObject = class');
  486. Add(' FFoo: boolean;');
  487. Add(' function GetFoo: boolean;');
  488. Add(' property Foo: boolean read FFoo;');
  489. Add(' property Foo2: boolean read GetFoo;');
  490. Add(' FBar: boolean;');
  491. Add(' function GetBar: boolean;');
  492. Add(' property Bar: boolean read FBar;');
  493. Add(' property Bar2: boolean read GetBar;');
  494. Add(' end;');
  495. Add('function TObject.GetFoo: boolean; begin Result:=FFoo; end;');
  496. Add('function TObject.GetBar: boolean; begin Result:=FBar; end;');
  497. Add('var o: TObject;');
  498. Add('begin');
  499. Add(' if o.Foo then;');
  500. ConvertProgram;
  501. CheckSource('TestWPO_OmitClassPropertyGetter1',
  502. LinesToStr([
  503. 'rtl.createClass($mod, "TObject", null, function () {',
  504. ' this.$init = function () {',
  505. ' this.FFoo = false;',
  506. ' };',
  507. ' this.$final = function () {',
  508. ' };',
  509. '});',
  510. 'this.o = null;',
  511. '']),
  512. LinesToStr([
  513. 'if ($mod.o.FFoo);',
  514. '']));
  515. end;
  516. procedure TTestOptimizations.TestWPO_OmitPropertyGetter2;
  517. begin
  518. StartProgram(false);
  519. Add('type');
  520. Add(' TObject = class');
  521. Add(' FFoo: boolean;');
  522. Add(' function GetFoo: boolean;');
  523. Add(' property Foo: boolean read FFoo;');
  524. Add(' property Foo2: boolean read GetFoo;');
  525. Add(' end;');
  526. Add('function TObject.GetFoo: boolean; begin Result:=FFoo; end;');
  527. Add('var o: TObject;');
  528. Add('begin');
  529. Add(' if o.Foo2 then;');
  530. ConvertProgram;
  531. CheckSource('TestWPO_OmitClassPropertyGetter2',
  532. LinesToStr([
  533. 'rtl.createClass($mod, "TObject", null, function () {',
  534. ' this.$init = function () {',
  535. ' this.FFoo = false;',
  536. ' };',
  537. ' this.$final = function () {',
  538. ' };',
  539. ' this.GetFoo = function () {',
  540. ' var Result = false;',
  541. ' Result = this.FFoo;',
  542. ' return Result;',
  543. ' };',
  544. '});',
  545. 'this.o = null;',
  546. '']),
  547. LinesToStr([
  548. 'if ($mod.o.GetFoo()) ;',
  549. '']));
  550. end;
  551. procedure TTestOptimizations.TestWPO_OmitPropertySetter1;
  552. begin
  553. StartProgram(false);
  554. Add('type');
  555. Add(' TObject = class');
  556. Add(' FFoo: boolean;');
  557. Add(' procedure SetFoo(Value: boolean);');
  558. Add(' property Foo: boolean write FFoo;');
  559. Add(' property Foo2: boolean write SetFoo;');
  560. Add(' FBar: boolean;');
  561. Add(' procedure SetBar(Value: boolean);');
  562. Add(' property Bar: boolean write FBar;');
  563. Add(' property Bar2: boolean write SetBar;');
  564. Add(' end;');
  565. Add('procedure TObject.SetFoo(Value: boolean); begin FFoo:=Value; end;');
  566. Add('procedure TObject.SetBar(Value: boolean); begin FBar:=Value; end;');
  567. Add('var o: TObject;');
  568. Add('begin');
  569. Add(' o.Foo:=true;');
  570. ConvertProgram;
  571. CheckSource('TestWPO_OmitClassPropertySetter1',
  572. LinesToStr([
  573. 'rtl.createClass($mod, "TObject", null, function () {',
  574. ' this.$init = function () {',
  575. ' this.FFoo = false;',
  576. ' };',
  577. ' this.$final = function () {',
  578. ' };',
  579. '});',
  580. 'this.o = null;',
  581. '']),
  582. LinesToStr([
  583. '$mod.o.FFoo = true;',
  584. '']));
  585. end;
  586. procedure TTestOptimizations.TestWPO_OmitPropertySetter2;
  587. begin
  588. StartProgram(false);
  589. Add('type');
  590. Add(' TObject = class');
  591. Add(' FFoo: boolean;');
  592. Add(' procedure SetFoo(Value: boolean);');
  593. Add(' property Foo: boolean write FFoo;');
  594. Add(' property Foo2: boolean write SetFoo;');
  595. Add(' end;');
  596. Add('procedure TObject.SetFoo(Value: boolean); begin FFoo:=Value; end;');
  597. Add('var o: TObject;');
  598. Add('begin');
  599. Add(' o.Foo2:=true;');
  600. ConvertProgram;
  601. CheckSource('TestWPO_OmitClassPropertySetter2',
  602. LinesToStr([
  603. 'rtl.createClass($mod, "TObject", null, function () {',
  604. ' this.$init = function () {',
  605. ' this.FFoo = false;',
  606. ' };',
  607. ' this.$final = function () {',
  608. ' };',
  609. ' this.SetFoo = function (Value) {',
  610. ' this.FFoo = Value;',
  611. ' };',
  612. '});',
  613. 'this.o = null;',
  614. '']),
  615. LinesToStr([
  616. '$mod.o.SetFoo(true);',
  617. '']));
  618. end;
  619. procedure TTestOptimizations.TestWPO_CallInherited;
  620. begin
  621. StartProgram(false);
  622. Add('type');
  623. Add(' TObject = class');
  624. Add(' procedure DoA;');
  625. Add(' procedure DoB;');
  626. Add(' end;');
  627. Add(' TMobile = class');
  628. Add(' procedure DoA;');
  629. Add(' procedure DoC;');
  630. Add(' end;');
  631. Add('procedure TObject.DoA; begin end;');
  632. Add('procedure TObject.DoB; begin end;');
  633. Add('procedure TMobile.DoA;');
  634. Add('begin');
  635. Add(' inherited;');
  636. Add('end;');
  637. Add('procedure TMobile.DoC;');
  638. Add('begin');
  639. Add(' inherited DoB;');
  640. Add('end;');
  641. Add('var o: TMobile;');
  642. Add('begin');
  643. Add(' o.DoA;');
  644. Add(' o.DoC;');
  645. ConvertProgram;
  646. CheckSource('TestWPO_CallInherited',
  647. LinesToStr([
  648. 'rtl.createClass($mod, "TObject", null, function () {',
  649. ' this.$init = function () {',
  650. ' };',
  651. ' this.$final = function () {',
  652. ' };',
  653. ' this.DoA = function () {',
  654. ' };',
  655. ' this.DoB = function () {',
  656. ' };',
  657. '});',
  658. ' rtl.createClass($mod, "TMobile", $mod.TObject, function () {',
  659. ' this.DoA$1 = function () {',
  660. ' $mod.TObject.DoA.apply(this, arguments);',
  661. ' };',
  662. ' this.DoC = function () {',
  663. ' $mod.TObject.DoB.call(this);',
  664. ' };',
  665. '});',
  666. 'this.o = null;',
  667. '']),
  668. LinesToStr([
  669. '$mod.o.DoA$1();',
  670. '$mod.o.DoC();',
  671. '']));
  672. end;
  673. procedure TTestOptimizations.TestWPO_UseUnit;
  674. var
  675. ActualSrc, ExpectedSrc: String;
  676. begin
  677. AddModuleWithIntfImplSrc('unit1.pp',
  678. LinesToStr([
  679. 'var i: longint;',
  680. 'procedure DoIt;',
  681. '']),
  682. LinesToStr([
  683. 'procedure DoIt; begin end;']));
  684. AddModuleWithIntfImplSrc('unit2.pp',
  685. LinesToStr([
  686. 'var j: longint;',
  687. 'procedure DoMore;',
  688. '']),
  689. LinesToStr([
  690. 'procedure DoMore; begin end;']));
  691. StartProgram(true);
  692. Add('uses unit2;');
  693. Add('begin');
  694. Add(' j:=3;');
  695. ConvertProgram;
  696. ActualSrc:=JSToStr(JSModule);
  697. ExpectedSrc:=LinesToStr([
  698. 'rtl.module("program", ["system", "unit2"], function () {',
  699. ' var $mod = this;',
  700. ' $mod.$main = function () {',
  701. ' pas.unit2.j = 3;',
  702. ' };',
  703. '});',
  704. '']);
  705. CheckDiff('TestWPO_UseUnit',ExpectedSrc,ActualSrc);
  706. end;
  707. procedure TTestOptimizations.TestWPO_ProgramPublicDeclaration;
  708. var
  709. ActualSrc, ExpectedSrc: String;
  710. begin
  711. StartProgram(true);
  712. Add('var');
  713. Add(' vPublic: longint; public;');
  714. Add(' vPrivate: longint;');
  715. Add('procedure DoPublic; public; begin end;');
  716. Add('procedure DoPrivate; begin end;');
  717. Add('begin');
  718. ConvertProgram;
  719. ActualSrc:=JSToStr(JSModule);
  720. ExpectedSrc:=LinesToStr([
  721. 'rtl.module("program", ["system"], function () {',
  722. ' var $mod = this;',
  723. ' this.vPublic = 0;',
  724. ' this.DoPublic =function(){',
  725. ' };',
  726. ' $mod.$main = function () {',
  727. ' };',
  728. '});',
  729. '']);
  730. CheckDiff('TestWPO_ProgramPublicDeclaration',ExpectedSrc,ActualSrc);
  731. end;
  732. procedure TTestOptimizations.TestWPO_RTTI_PublishedField;
  733. var
  734. ActualSrc, ExpectedSrc: String;
  735. begin
  736. Converter.Options:=Converter.Options-[coNoTypeInfo];
  737. StartProgram(true);
  738. Add('type');
  739. Add(' TArrA = array of char;');
  740. Add(' TArrB = array of string;');
  741. Add(' TObject = class');
  742. Add(' public');
  743. Add(' PublicA: TArrA;');
  744. Add(' published');
  745. Add(' PublishedB: TArrB;');
  746. Add(' end;');
  747. Add('var');
  748. Add(' C: TObject;');
  749. Add('begin');
  750. Add(' C.PublicA:=nil;');
  751. ConvertProgram;
  752. ActualSrc:=JSToStr(JSModule);
  753. ExpectedSrc:=LinesToStr([
  754. 'rtl.module("program", ["system"], function () {',
  755. ' var $mod = this;',
  756. ' $mod.$rtti.$DynArray("TArrB", {',
  757. ' eltype: rtl.string',
  758. ' });',
  759. ' rtl.createClass($mod, "TObject", null, function () {',
  760. ' this.$init = function () {',
  761. ' this.PublicA = [];',
  762. ' this.PublishedB = [];',
  763. ' };',
  764. ' this.$final = function () {',
  765. ' this.PublicA = undefined;',
  766. ' this.PublishedB = undefined;',
  767. ' };',
  768. ' var $r = this.$rtti;',
  769. ' $r.addField("PublishedB", $mod.$rtti["TArrB"]);',
  770. ' });',
  771. ' this.C = null;',
  772. ' $mod.$main = function () {',
  773. ' $mod.C.PublicA = [];',
  774. ' };',
  775. '});',
  776. '']);
  777. CheckDiff('TestWPO_RTTI_PublishedField',ExpectedSrc,ActualSrc);
  778. end;
  779. procedure TTestOptimizations.TestWPO_RTTI_TypeInfo;
  780. var
  781. ActualSrc, ExpectedSrc: String;
  782. begin
  783. Converter.Options:=Converter.Options-[coNoTypeInfo];
  784. StartProgram(true);
  785. Add('type');
  786. Add(' TArrA = array of char;');
  787. Add(' TArrB = array of string;');
  788. Add('var');
  789. Add(' A: TArrA;');
  790. Add(' B: TArrB;');
  791. Add(' p: pointer;');
  792. Add('begin');
  793. Add(' A:=nil;');
  794. Add(' p:=typeinfo(B);');
  795. ConvertProgram;
  796. ActualSrc:=JSToStr(JSModule);
  797. ExpectedSrc:=LinesToStr([
  798. 'rtl.module("program", ["system"], function () {',
  799. ' var $mod = this;',
  800. ' $mod.$rtti.$DynArray("TArrB", {',
  801. ' eltype: rtl.string',
  802. ' });',
  803. ' this.A = [];',
  804. ' this.B = [];',
  805. ' this.p = null;',
  806. ' $mod.$main = function () {',
  807. ' $mod.A = [];',
  808. ' $mod.p = $mod.$rtti["TArrB"];',
  809. ' };',
  810. '});',
  811. '']);
  812. CheckDiff('TestWPO_RTTI_TypeInfo',ExpectedSrc,ActualSrc);
  813. end;
  814. Initialization
  815. RegisterTests([TTestOptimizations]);
  816. end.