tcwebidl2wasmjob.pas 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179
  1. unit tcwebidl2wasmjob;
  2. {$mode ObjFPC}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils, fpcunit, testregistry, webidlscanner, webidltowasmjob, pascodegen;
  6. type
  7. { TCustomTestWebIDL2WasmJob }
  8. TCustomTestWebIDL2WasmJob = Class(TTestCase)
  9. private
  10. FHeaderSrc: TIDLString;
  11. FWebIDLToPas: TWebIDLToPasWasmJob;
  12. procedure OnLog(Sender: TObject; LogType: TCodegenLogType; const Msg: String
  13. );
  14. protected
  15. procedure Setup; override;
  16. procedure TearDown; override;
  17. public
  18. procedure TestWebIDL(const WebIDLSrc, ExpectedPascalSrc: array of string); virtual;
  19. procedure CheckDiff(Msg, Expected, Actual: string); virtual;
  20. property WebIDLToPas: TWebIDLToPasWasmJob read FWebIDLToPas;
  21. property HeaderSrc: TIDLString read FHeaderSrc write FHeaderSrc;
  22. end;
  23. { TTestWebIDL2WasmJob }
  24. TTestWebIDL2WasmJob = Class(TCustomTestWebIDL2WasmJob)
  25. published
  26. procedure TestWJ_Empty;
  27. // typedefs
  28. procedure TestWJ_Typedef_Boolean;
  29. procedure TestWJ_Typedef_Sequence;
  30. procedure TestWJ_Typedef_Aliased;
  31. // attributes
  32. procedure TestWJ_IntfAttribute_Boolean;
  33. procedure TestWJ_IntfStringifier;
  34. procedure TestWJ_IntfAttribute_ArrayBuffer;
  35. procedure TestWJ_IntfAttribute_ArrayBufferView;
  36. // todo procedure TestWJ_IntfAttribute_Any;
  37. // functions
  38. procedure TestWJ_IntfFunction_Void;
  39. procedure TestWJ_IntfFunction_SetEventHandler;
  40. procedure TestWJ_IntfFunction_Promise;
  41. procedure TestWJ_IntfFunction_ArgAny;
  42. procedure TestWJ_IntfFunction_EnumResult;
  43. procedure TestWJ_IntfFunction_SequenceArg;
  44. procedure TestWJ_IntfFunction_Constructor;
  45. procedure TestWJ_IntfFunction_ArrayBufferArg;
  46. procedure TestWJ_IntfFunction_ArrayBufferViewArg;
  47. // Namespace attribute
  48. procedure TestWJ_NamespaceAttribute_Boolean;
  49. // maplike
  50. procedure TestWJ_MaplikeInterface;
  51. end;
  52. function LinesToStr(Args: array of const): TIDLString;
  53. function CheckSrcDiff(Expected, Actual: string; out Msg: string): boolean;
  54. implementation
  55. function LinesToStr(Args: array of const): TIDLString;
  56. var
  57. s,a: TIDLString;
  58. U : UnicodeString;
  59. i: Integer;
  60. begin
  61. s:='';
  62. for i:=Low(Args) to High(Args) do
  63. begin
  64. case Args[i].VType of
  65. vtChar: A:=Args[i].VChar;
  66. vtString: A:=Args[i].VString^;
  67. vtPChar: A:=Args[i].VPChar;
  68. vtWideChar: begin
  69. U:=Args[i].VWideChar;
  70. A:=U;
  71. end;
  72. vtPWideChar: begin
  73. U:=Args[i].VPWideChar;
  74. A:=U;
  75. end;
  76. vtAnsiString: begin
  77. A:=AnsiString(Args[i].VAnsiString);
  78. end;
  79. vtWidestring: begin
  80. U:=WideString(Args[i].VWideString);
  81. A:=U;
  82. end;
  83. vtUnicodeString: begin
  84. U:=UnicodeString(Args[i].VUnicodeString);
  85. A:=U;
  86. end;
  87. end;
  88. S:=S+A+LineEnding;
  89. end;
  90. // Writeln('LinesToStr : ',S);
  91. Result:=s;
  92. end;
  93. function CheckSrcDiff(Expected, Actual: string; out Msg: string): boolean;
  94. // search diff, ignore changes in spaces
  95. const
  96. SpaceChars = [#9,#10,#13,' '];
  97. var
  98. ExpectedP, ActualP: PChar;
  99. function FindLineEnd(p: PChar): PChar;
  100. begin
  101. Result:=p;
  102. while not (Result^ in [#0,#10,#13]) do inc(Result);
  103. end;
  104. function FindLineStart(p, MinP: PChar): PChar;
  105. begin
  106. while (p>MinP) and not (p[-1] in [#10,#13]) do dec(p);
  107. Result:=p;
  108. end;
  109. procedure SkipLineEnd(var p: PChar);
  110. begin
  111. if p^ in [#10,#13] then
  112. begin
  113. if (p[1] in [#10,#13]) and (p^<>p[1]) then
  114. inc(p,2)
  115. else
  116. inc(p);
  117. end;
  118. end;
  119. function HasSpecialChar(s: string): boolean;
  120. var
  121. i: Integer;
  122. begin
  123. for i:=1 to length(s) do
  124. if s[i] in [#0..#31,#127..#255] then
  125. exit(true);
  126. Result:=false;
  127. end;
  128. function HashSpecialChars(s: string): string;
  129. var
  130. i: Integer;
  131. begin
  132. Result:='';
  133. for i:=1 to length(s) do
  134. if s[i] in [#0..#31,#127..#255] then
  135. Result:=Result+'#'+hexstr(ord(s[i]),2)
  136. else
  137. Result:=Result+s[i];
  138. end;
  139. procedure DiffFound;
  140. var
  141. ActLineStartP, ActLineEndP, p, StartPos: PChar;
  142. ExpLine, ActLine: String;
  143. i, LineNo, DiffLineNo: Integer;
  144. begin
  145. writeln('Diff found "',Msg,'". Lines:');
  146. // write correct lines
  147. p:=PChar(Expected);
  148. LineNo:=0;
  149. DiffLineNo:=0;
  150. repeat
  151. StartPos:=p;
  152. while not (p^ in [#0,#10,#13]) do inc(p);
  153. ExpLine:=copy(Expected,StartPos-PChar(Expected)+1,p-StartPos);
  154. SkipLineEnd(p);
  155. inc(LineNo);
  156. if (p<=ExpectedP) and (p^<>#0) then
  157. begin
  158. writeln('= ',ExpLine);
  159. end else begin
  160. // diff line
  161. if DiffLineNo=0 then DiffLineNo:=LineNo;
  162. // write actual line
  163. ActLineStartP:=FindLineStart(ActualP,PChar(Actual));
  164. ActLineEndP:=FindLineEnd(ActualP);
  165. ActLine:=copy(Actual,ActLineStartP-PChar(Actual)+1,ActLineEndP-ActLineStartP);
  166. writeln('- ',ActLine);
  167. if HasSpecialChar(ActLine) then
  168. writeln('- ',HashSpecialChars(ActLine));
  169. // write expected line
  170. writeln('+ ',ExpLine);
  171. if HasSpecialChar(ExpLine) then
  172. writeln('- ',HashSpecialChars(ExpLine));
  173. // write empty line with pointer ^
  174. for i:=1 to 2+ExpectedP-StartPos do write(' ');
  175. writeln('^');
  176. Msg:='expected "'+ExpLine+'", but got "'+ActLine+'".';
  177. CheckSrcDiff:=false;
  178. // write up to ten following actual lines to get some context
  179. for i:=1 to 10 do begin
  180. ActLineStartP:=ActLineEndP;
  181. SkipLineEnd(ActLineStartP);
  182. if ActLineStartP^=#0 then break;
  183. ActLineEndP:=FindLineEnd(ActLineStartP);
  184. ActLine:=copy(Actual,ActLineStartP-PChar(Actual)+1,ActLineEndP-ActLineStartP);
  185. writeln('~ ',ActLine);
  186. end;
  187. exit;
  188. end;
  189. until p^=#0;
  190. // internal error:
  191. writeln('DiffFound Actual:-----------------------');
  192. writeln(Actual);
  193. writeln('DiffFound Expected:---------------------');
  194. writeln(Expected);
  195. writeln('DiffFound ------------------------------');
  196. Msg:='diff found, but lines are the same, internal error';
  197. CheckSrcDiff:=false;
  198. end;
  199. var
  200. IsSpaceNeeded: Boolean;
  201. LastChar, Quote: Char;
  202. begin
  203. Result:=true;
  204. Msg:='';
  205. if Expected='' then Expected:=' ';
  206. if Actual='' then Actual:=' ';
  207. ExpectedP:=PChar(Expected);
  208. ActualP:=PChar(Actual);
  209. repeat
  210. //writeln('TTestModule.CheckDiff Exp="',ExpectedP^,'" Act="',ActualP^,'"');
  211. case ExpectedP^ of
  212. #0:
  213. begin
  214. // check that rest of Actual has only spaces
  215. while ActualP^ in SpaceChars do inc(ActualP);
  216. if ActualP^<>#0 then
  217. begin
  218. DiffFound;
  219. exit;
  220. end;
  221. exit(true);
  222. end;
  223. ' ',#9,#10,#13:
  224. begin
  225. // skip space in Expected
  226. IsSpaceNeeded:=false;
  227. if ExpectedP>PChar(Expected) then
  228. LastChar:=ExpectedP[-1]
  229. else
  230. LastChar:=#0;
  231. while ExpectedP^ in SpaceChars do inc(ExpectedP);
  232. if (LastChar in ['a'..'z','A'..'Z','0'..'9','_','$'])
  233. and (ExpectedP^ in ['a'..'z','A'..'Z','0'..'9','_','$']) then
  234. IsSpaceNeeded:=true;
  235. if IsSpaceNeeded and (not (ActualP^ in SpaceChars)) then
  236. begin
  237. DiffFound;
  238. exit;
  239. end;
  240. while ActualP^ in SpaceChars do inc(ActualP);
  241. end;
  242. '''','"':
  243. begin
  244. while ActualP^ in SpaceChars do inc(ActualP);
  245. if ExpectedP^<>ActualP^ then
  246. begin
  247. DiffFound;
  248. exit;
  249. end;
  250. Quote:=ExpectedP^;
  251. repeat
  252. inc(ExpectedP);
  253. inc(ActualP);
  254. if ExpectedP^<>ActualP^ then
  255. begin
  256. DiffFound;
  257. exit;
  258. end;
  259. if (ExpectedP^ in [#0,#10,#13]) then
  260. break
  261. else if (ExpectedP^=Quote) then
  262. begin
  263. inc(ExpectedP);
  264. inc(ActualP);
  265. break;
  266. end;
  267. until false;
  268. end;
  269. else
  270. while ActualP^ in SpaceChars do inc(ActualP);
  271. if ExpectedP^<>ActualP^ then
  272. begin
  273. DiffFound;
  274. exit;
  275. end;
  276. inc(ExpectedP);
  277. inc(ActualP);
  278. end;
  279. until false;
  280. end;
  281. { TCustomTestWebIDL2WasmJob }
  282. procedure TCustomTestWebIDL2WasmJob.OnLog(Sender: TObject;
  283. LogType: TCodegenLogType; const Msg: String);
  284. begin
  285. if LogType=cltInfo then ;
  286. if Sender=nil then ;
  287. writeln('TCustomTestWebIDL2WasmJob.OnLog ',Msg);
  288. end;
  289. procedure TCustomTestWebIDL2WasmJob.Setup;
  290. begin
  291. inherited Setup;
  292. FWebIDLToPas:=TWebIDLToPasWasmJob.Create(nil);
  293. WebIDLToPas.OnLog:=@OnLog;
  294. WebIDLToPas.InputFileName:='test1.webidl';
  295. WebIDLToPas.OutputFileName:='test1.pas';
  296. WebIDLToPas.OutputStream:=TMemoryStream.Create;
  297. HeaderSrc:=LinesToStr([
  298. 'Unit test1;',
  299. '',
  300. '{$MODE ObjFPC}',
  301. '{$H+}',
  302. 'interface',
  303. '',
  304. 'uses SysUtils, JOB_JS;',
  305. '']);
  306. end;
  307. procedure TCustomTestWebIDL2WasmJob.TearDown;
  308. begin
  309. WebIDLToPas.InputStream.Free;
  310. WebIDLToPas.InputStream:=nil;
  311. WebIDLToPas.OutputStream.Free;
  312. WebIDLToPas.OutputStream:=nil;
  313. FreeAndNil(FWebIDLToPas);
  314. inherited TearDown;
  315. end;
  316. procedure TCustomTestWebIDL2WasmJob.TestWebIDL(const WebIDLSrc,
  317. ExpectedPascalSrc: array of string);
  318. var
  319. i: Integer;
  320. Line, ExpectedSrc, InputSrc, OutputSrc: String;
  321. InputMS: TMemoryStream;
  322. begin
  323. {$IFDEF VerboseWebidl2WasmJob}
  324. writeln('TCustomTestWebIDL2WasmJob.TestWebIDL WebIDL:----------------------');
  325. {$ENDIF}
  326. InputSrc:='';
  327. for i:=0 to high(WebIDLSrc) do
  328. begin
  329. Line:=WebIDLSrc[i]+sLineBreak;
  330. InputSrc:=InputSrc+Line;
  331. {$IFDEF VerboseWebidl2WasmJob}
  332. write(Line);
  333. {$ENDIF}
  334. end;
  335. WebIDLToPas.InputStream:=TStringStream.Create(InputSrc);
  336. {$IFDEF VerboseWebidl2WasmJob}
  337. writeln('TCustomTestWebIDL2WasmJob.TestWebIDL ExpectedPascal: BEGIN--------');
  338. {$ENDIF}
  339. ExpectedSrc:=HeaderSrc;
  340. for i:=0 to high(ExpectedPascalSrc) do
  341. ExpectedSrc:=ExpectedSrc+ExpectedPascalSrc[i]+sLineBreak;
  342. {$IFDEF VerboseWebidl2WasmJob}
  343. writeln(ExpectedSrc);
  344. writeln('TCustomTestWebIDL2WasmJob.TestWebIDL ExpectedPascal END-----------');
  345. {$ENDIF}
  346. WebIDLToPas.Execute;
  347. OutputSrc:=WebIDLToPas.Source.Text;
  348. {$IFDEF VerboseWebidl2WasmJob}
  349. writeln('TCustomTestWebIDL2WasmJob.TestWebIDL ActualPascal: BEGIN----------');
  350. writeln(OutputSrc);
  351. writeln('TCustomTestWebIDL2WasmJob.TestWebIDL ActualPascal: END------------');
  352. {$ENDIF}
  353. CheckDiff('TCustomTestWebIDL2WasmJob.TestWebIDL',ExpectedSrc,OutputSrc);
  354. end;
  355. procedure TCustomTestWebIDL2WasmJob.CheckDiff(Msg, Expected, Actual: string);
  356. // search diff, ignore changes in spaces
  357. var
  358. s: string;
  359. begin
  360. if CheckSrcDiff(Expected,Actual,s) then exit;
  361. Fail(Msg+': '+s);
  362. end;
  363. { TTestWebIDL2WasmJob }
  364. procedure TTestWebIDL2WasmJob.TestWJ_Empty;
  365. begin
  366. TestWebIDL([
  367. ''],
  368. ['Type',
  369. ' // Forward class definitions',
  370. 'implementation',
  371. 'end.',
  372. '']);
  373. end;
  374. procedure TTestWebIDL2WasmJob.TestWJ_Typedef_Boolean;
  375. begin
  376. TestWebIDL([
  377. 'typedef boolean PerformanceEntry;',
  378. ''],
  379. ['Type',
  380. ' // Forward class definitions',
  381. ' TPerformanceEntry = Boolean;',
  382. 'implementation',
  383. 'end.',
  384. '']);
  385. end;
  386. procedure TTestWebIDL2WasmJob.TestWJ_Typedef_Sequence;
  387. begin
  388. TestWebIDL([
  389. 'typedef boolean PerformanceEntry;',
  390. 'typedef sequence <PerformanceEntry> PerformanceEntryList;',
  391. ''],
  392. ['Type',
  393. ' // Forward class definitions',
  394. ' TPerformanceEntry = Boolean;',
  395. ' TPerformanceEntryList = IJSArray; // array of TPerformanceEntry',
  396. 'implementation',
  397. 'end.',
  398. '']);
  399. end;
  400. procedure TTestWebIDL2WasmJob.TestWJ_Typedef_Aliased;
  401. begin
  402. WebIDLToPas.TypeAliases.Add('Float32List=IJSFloat32Array');
  403. TestWebIDL([
  404. ' typedef ([AllowShared] Float32Array or sequence<GLfloat>) Float32List;',
  405. ''],
  406. ['',
  407. 'Type',
  408. ' // Forward class definitions',
  409. 'implementation',
  410. '',
  411. 'end.',
  412. ''
  413. ]);
  414. end;
  415. procedure TTestWebIDL2WasmJob.TestWJ_IntfAttribute_Boolean;
  416. begin
  417. TestWebIDL([
  418. 'interface Attr {',
  419. ' attribute boolean aBoolean;',
  420. '};',
  421. ''],
  422. ['Type',
  423. ' // Forward class definitions',
  424. ' IJSAttr = interface;',
  425. ' TJSAttr = class;',
  426. ' { --------------------------------------------------------------------',
  427. ' TJSAttr',
  428. ' --------------------------------------------------------------------}',
  429. '',
  430. ' IJSAttr = interface(IJSObject)',
  431. ' [''{AA94F48A-7955-3EBA-B086-85B24440AF2A}'']',
  432. ' function _GetaBoolean: Boolean;',
  433. ' procedure _SetaBoolean(const aValue: Boolean);',
  434. ' property aBoolean: Boolean read _GetaBoolean write _SetaBoolean;',
  435. ' end;',
  436. '',
  437. ' TJSAttr = class(TJSObject,IJSAttr)',
  438. ' Private',
  439. ' function _GetaBoolean: Boolean;',
  440. ' procedure _SetaBoolean(const aValue: Boolean);',
  441. ' Public',
  442. ' class function Cast(const Intf: IJSObject): IJSAttr;',
  443. ' property aBoolean: Boolean read _GetaBoolean write _SetaBoolean;',
  444. ' end;',
  445. '',
  446. 'implementation',
  447. '',
  448. 'function TJSAttr._GetaBoolean: Boolean;',
  449. 'begin',
  450. ' Result:=ReadJSPropertyBoolean(''aBoolean'');',
  451. 'end;',
  452. '',
  453. 'procedure TJSAttr._SetaBoolean(const aValue: Boolean);',
  454. 'begin',
  455. ' WriteJSPropertyBoolean(''aBoolean'',aValue);',
  456. 'end;',
  457. '',
  458. 'class function TJSAttr.Cast(const Intf: IJSObject): IJSAttr;',
  459. 'begin',
  460. ' Result:=TJSAttr.JOBCast(Intf);',
  461. 'end;',
  462. '',
  463. 'end.',
  464. '']);
  465. end;
  466. procedure TTestWebIDL2WasmJob.TestWJ_IntfStringifier;
  467. begin
  468. TestWebIDL([
  469. 'interface Attr {',
  470. ' stringifier;',
  471. '};',
  472. ''],
  473. ['Type',
  474. ' // Forward class definitions',
  475. ' IJSAttr = interface;',
  476. ' TJSAttr = class;',
  477. ' { --------------------------------------------------------------------',
  478. ' TJSAttr',
  479. ' --------------------------------------------------------------------}',
  480. '',
  481. ' IJSAttr = interface(IJSObject)',
  482. ' [''{AA94F45E-60F0-381A-A2A6-208CA4B2AF2A}'']',
  483. ' end;',
  484. '',
  485. ' TJSAttr = class(TJSObject,IJSAttr)',
  486. ' Private',
  487. ' Public',
  488. ' class function Cast(const Intf: IJSObject): IJSAttr;',
  489. ' end;',
  490. '',
  491. 'implementation',
  492. '',
  493. 'class function TJSAttr.Cast(const Intf: IJSObject): IJSAttr;',
  494. 'begin',
  495. ' Result:=TJSAttr.JOBCast(Intf);',
  496. 'end;',
  497. '',
  498. 'end.',
  499. '']);
  500. end;
  501. procedure TTestWebIDL2WasmJob.TestWJ_IntfAttribute_ArrayBuffer;
  502. begin
  503. TestWebIDL([
  504. 'interface Attr {',
  505. ' [SameObject, Throws] readonly attribute ArrayBuffer signature;',
  506. '};',
  507. ''],
  508. [
  509. 'Type',
  510. ' // Forward class definitions',
  511. ' IJSAttr = interface;',
  512. ' TJSAttr = class;',
  513. ' { --------------------------------------------------------------------',
  514. ' TJSAttr',
  515. ' --------------------------------------------------------------------}',
  516. '',
  517. ' IJSAttr = interface(IJSObject)',
  518. ' [''{2D39068A-1305-3879-B4DC-37563664D5F5}'']',
  519. ' function _Getsignature: IJSArrayBuffer;',
  520. ' property signature: IJSArrayBuffer read _Getsignature;',
  521. ' end;',
  522. '',
  523. ' TJSAttr = class(TJSObject,IJSAttr)',
  524. ' Private',
  525. ' function _Getsignature: IJSArrayBuffer;',
  526. ' Public',
  527. ' class function Cast(const Intf: IJSObject): IJSAttr;',
  528. ' property signature: IJSArrayBuffer read _Getsignature;',
  529. ' end;',
  530. '',
  531. 'implementation',
  532. '',
  533. 'function TJSAttr._Getsignature: IJSArrayBuffer;',
  534. 'begin',
  535. ' Result:=ReadJSPropertyObject(''signature'',TJSArrayBuffer) as IJSArrayBuffer;',
  536. 'end;',
  537. '',
  538. 'class function TJSAttr.Cast(const Intf: IJSObject): IJSAttr;',
  539. 'begin',
  540. ' Result:=TJSAttr.JOBCast(Intf);',
  541. 'end;',
  542. '',
  543. 'end.',
  544. ''
  545. ]);
  546. end;
  547. procedure TTestWebIDL2WasmJob.TestWJ_IntfAttribute_ArrayBufferView;
  548. begin
  549. TestWebIDL([
  550. 'interface Attr {',
  551. ' [SameObject, Throws] readonly attribute ArrayBufferView signature;',
  552. '};',
  553. ''],
  554. [
  555. 'Type',
  556. ' // Forward class definitions',
  557. ' IJSAttr = interface;',
  558. ' TJSAttr = class;',
  559. ' { --------------------------------------------------------------------',
  560. ' TJSAttr',
  561. ' --------------------------------------------------------------------}',
  562. '',
  563. ' IJSAttr = interface(IJSObject)',
  564. ' [''{2D390654-2475-3879-B4DC-37563664D5F5}'']',
  565. ' function _Getsignature: IJSArrayBufferView;',
  566. ' property signature: IJSArrayBufferView read _Getsignature;',
  567. ' end;',
  568. '',
  569. ' TJSAttr = class(TJSObject,IJSAttr)',
  570. ' Private',
  571. ' function _Getsignature: IJSArrayBufferView;',
  572. ' Public',
  573. ' class function Cast(const Intf: IJSObject): IJSAttr;',
  574. ' property signature: IJSArrayBufferView read _Getsignature;',
  575. ' end;',
  576. '',
  577. 'implementation',
  578. '',
  579. 'function TJSAttr._Getsignature: IJSArrayBufferView;',
  580. 'begin',
  581. ' Result:=ReadJSPropertyObject(''signature'',TJSArrayBufferView) as IJSArrayBufferView;',
  582. 'end;',
  583. '',
  584. 'class function TJSAttr.Cast(const Intf: IJSObject): IJSAttr;',
  585. 'begin',
  586. ' Result:=TJSAttr.JOBCast(Intf);',
  587. 'end;',
  588. '',
  589. 'end.',
  590. ''
  591. ]);
  592. end;
  593. procedure TTestWebIDL2WasmJob.TestWJ_IntfFunction_Void;
  594. begin
  595. TestWebIDL([
  596. 'interface Attr {',
  597. ' void append(Attr node);',
  598. '};',
  599. ''],
  600. ['Type',
  601. ' // Forward class definitions',
  602. ' IJSAttr = interface;',
  603. ' TJSAttr = class;',
  604. ' { --------------------------------------------------------------------',
  605. ' TJSAttr',
  606. ' --------------------------------------------------------------------}',
  607. '',
  608. ' IJSAttr = interface(IJSObject)',
  609. ' [''{AA94F48A-84D7-3FAA-A2A6-208CA4B2AF2A}'']',
  610. ' procedure append(aNode: IJSAttr);',
  611. ' end;',
  612. '',
  613. ' TJSAttr = class(TJSObject,IJSAttr)',
  614. ' Private',
  615. ' Public',
  616. ' procedure append(aNode: IJSAttr);',
  617. ' class function Cast(const Intf: IJSObject): IJSAttr;',
  618. ' end;',
  619. '',
  620. 'implementation',
  621. '',
  622. 'procedure TJSAttr.append(aNode: IJSAttr);',
  623. 'begin',
  624. ' InvokeJSNoResult(''append'',[aNode]);',
  625. 'end;',
  626. '',
  627. 'class function TJSAttr.Cast(const Intf: IJSObject): IJSAttr;',
  628. 'begin',
  629. ' Result:=TJSAttr.JOBCast(Intf);',
  630. 'end;',
  631. '',
  632. 'end.',
  633. '']);
  634. end;
  635. procedure TTestWebIDL2WasmJob.TestWJ_IntfFunction_SetEventHandler;
  636. begin
  637. TestWebIDL([
  638. '[LegacyTreatNonObjectAsNull]',
  639. 'callback EventHandlerNonNull = any (long event);',
  640. 'typedef EventHandlerNonNull? EventHandler;',
  641. '',
  642. 'interface Attr {',
  643. ' void setEventHandler([TreatNonCallableAsNull] EventHandler handler);',
  644. '};',
  645. ''],
  646. ['Type',
  647. ' // Forward class definitions',
  648. ' IJSAttr = interface;',
  649. ' TJSAttr = class;',
  650. ' TEventHandlerNonNull = function (event: Integer): Variant of object;',
  651. ' TEventHandler = TEventHandlerNonNull;',
  652. '',
  653. ' { --------------------------------------------------------------------',
  654. ' TJSAttr',
  655. ' --------------------------------------------------------------------}',
  656. '',
  657. ' IJSAttr = interface(IJSObject)',
  658. ' [''{AA94F48A-121D-33BC-96FE-420246F2AF2A}'']',
  659. ' procedure setEventHandler(const aHandler: TEventHandler);',
  660. ' end;',
  661. '',
  662. ' TJSAttr = class(TJSObject,IJSAttr)',
  663. ' Private',
  664. ' Public',
  665. ' procedure setEventHandler(const aHandler: TEventHandler);',
  666. ' class function Cast(const Intf: IJSObject): IJSAttr;',
  667. ' end;',
  668. '',
  669. 'implementation',
  670. '',
  671. 'function JOBCallTEventHandlerNonNull(const aMethod: TMethod; var H: TJOBCallbackHelper): PByte;',
  672. 'var',
  673. ' event: Integer;',
  674. 'begin',
  675. ' event:=H.GetLongInt;',
  676. ' Result:=H.AllocVariant(TEventHandlerNonNull(aMethod)(event));',
  677. 'end;',
  678. '',
  679. 'procedure TJSAttr.setEventHandler(const aHandler: TEventHandler);',
  680. 'var',
  681. ' m: TJOB_Method;',
  682. 'begin',
  683. ' m:=TJOB_Method.Create(TMethod(aHandler),@JOBCallTEventHandlerNonNull);',
  684. ' try',
  685. ' InvokeJSNoResult(''setEventHandler'',[m]);',
  686. ' finally',
  687. ' m.free;',
  688. ' end;',
  689. 'end;',
  690. '',
  691. 'class function TJSAttr.Cast(const Intf: IJSObject): IJSAttr;',
  692. 'begin',
  693. ' Result:=TJSAttr.JOBCast(Intf);',
  694. 'end;',
  695. '',
  696. 'end.',
  697. '']);
  698. end;
  699. procedure TTestWebIDL2WasmJob.TestWJ_IntfFunction_Promise;
  700. begin
  701. // Promise<void> exitFullscreen();
  702. TestWebIDL([
  703. 'interface Attr {',
  704. ' Promise<void> exitFullscreen();',
  705. ' Promise<any> addCertException(boolean isTemporary);',
  706. ' Promise<Attr> fly();',
  707. '};',
  708. ''],
  709. ['Type',
  710. ' // Forward class definitions',
  711. ' IJSAttr = interface;',
  712. ' TJSAttr = class;',
  713. ' { --------------------------------------------------------------------',
  714. ' TJSAttr',
  715. ' --------------------------------------------------------------------}',
  716. '',
  717. ' IJSAttr = interface(IJSObject)',
  718. ' [''{74BB0007-0E0F-3C5D-B270-B1C656002861}'']',
  719. ' function exitFullscreen: IJSPromise; // Promise<void>',
  720. ' function addCertException(aIsTemporary: Boolean): IJSPromise; // Promise<any>',
  721. ' function fly: IJSPromise; // Promise<Attr>',
  722. ' end;',
  723. '',
  724. ' TJSAttr = class(TJSObject,IJSAttr)',
  725. ' Private',
  726. ' Public',
  727. ' function exitFullscreen: IJSPromise; // Promise<void>',
  728. ' function addCertException(aIsTemporary: Boolean): IJSPromise; // Promise<any>',
  729. ' function fly: IJSPromise; // Promise<Attr>',
  730. ' class function Cast(const Intf: IJSObject): IJSAttr;',
  731. ' end;',
  732. '',
  733. 'implementation',
  734. '',
  735. 'function TJSAttr.exitFullscreen: IJSPromise; // Promise<void>',
  736. 'begin',
  737. ' Result:=InvokeJSObjectResult(''exitFullscreen'',[],TJSPromise) as IJSPromise;',
  738. 'end;',
  739. '',
  740. 'function TJSAttr.addCertException(aIsTemporary: Boolean): IJSPromise; // Promise<any>',
  741. 'begin',
  742. ' Result:=InvokeJSObjectResult(''addCertException'',[aIsTemporary],TJSPromise) as IJSPromise;',
  743. 'end;',
  744. '',
  745. 'function TJSAttr.fly: IJSPromise; // Promise<Attr>',
  746. 'begin',
  747. ' Result:=InvokeJSObjectResult(''fly'',[],TJSPromise) as IJSPromise;',
  748. 'end;',
  749. '',
  750. 'class function TJSAttr.Cast(const Intf: IJSObject): IJSAttr;',
  751. 'begin',
  752. ' Result:=TJSAttr.JOBCast(Intf);',
  753. 'end;',
  754. '',
  755. 'end.',
  756. '']);
  757. end;
  758. procedure TTestWebIDL2WasmJob.TestWJ_IntfFunction_ArgAny;
  759. begin
  760. TestWebIDL([
  761. 'interface Attr {',
  762. ' void append(any node);',
  763. '};',
  764. ''],
  765. ['Type',
  766. ' // Forward class definitions',
  767. ' IJSAttr = interface;',
  768. ' TJSAttr = class;',
  769. ' { --------------------------------------------------------------------',
  770. ' TJSAttr',
  771. ' --------------------------------------------------------------------}',
  772. '',
  773. ' IJSAttr = interface(IJSObject)',
  774. ' [''{AA94F48A-84D7-3FAA-A2A6-208CA4B2AF2A}'']',
  775. ' procedure append(const aNode: Variant);',
  776. ' end;',
  777. '',
  778. ' TJSAttr = class(TJSObject,IJSAttr)',
  779. ' Private',
  780. ' Public',
  781. ' procedure append(const aNode: Variant);',
  782. ' class function Cast(const Intf: IJSObject): IJSAttr;',
  783. ' end;',
  784. '',
  785. 'implementation',
  786. '',
  787. 'procedure TJSAttr.append(const aNode: Variant);',
  788. 'begin',
  789. ' InvokeJSNoResult(''append'',[aNode]);',
  790. 'end;',
  791. '',
  792. 'class function TJSAttr.Cast(const Intf: IJSObject): IJSAttr;',
  793. 'begin',
  794. ' Result:=TJSAttr.JOBCast(Intf);',
  795. 'end;',
  796. '',
  797. 'end.',
  798. '']);
  799. end;
  800. procedure TTestWebIDL2WasmJob.TestWJ_IntfFunction_EnumResult;
  801. begin
  802. TestWebIDL([
  803. 'enum E { ',
  804. ' "allowed", ',
  805. ' "disallowed" ',
  806. '}; ',
  807. 'interface IE { ',
  808. ' E get(long a); ',
  809. '};'
  810. ],[
  811. 'Type',
  812. ' // Forward class definitions',
  813. ' IJSIE = interface;',
  814. ' TJSIE = class;',
  815. ' TE = UnicodeString;',
  816. ' { --------------------------------------------------------------------',
  817. ' TJSIE',
  818. ' --------------------------------------------------------------------}',
  819. ' IJSIE = interface(IJSObject)',
  820. ' [''{04D06E4C-6063-3E89-A483-3296C9C8AA41}'']',
  821. ' function get(a: Integer) : TE;',
  822. ' end;',
  823. '',
  824. ' TJSIE = class(TJSObject,IJSIE)',
  825. ' Private',
  826. ' Public',
  827. ' function get(a: Integer) : TE;',
  828. ' class function Cast(const Intf: IJSObject): IJSIE;',
  829. ' end;',
  830. '',
  831. 'implementation',
  832. '',
  833. 'function TJSIE.get(a: Integer) : TE;',
  834. 'begin',
  835. ' Result:=InvokeJSUnicodeStringResult(''get'',[a]);',
  836. 'end;',
  837. '',
  838. 'class function TJSIE.Cast(const Intf: IJSObject): IJSIE;',
  839. 'begin',
  840. ' Result:=TJSIE.JOBCast(Intf);',
  841. 'end;',
  842. '',
  843. 'end.'
  844. ]);
  845. end;
  846. procedure TTestWebIDL2WasmJob.TestWJ_IntfFunction_SequenceArg;
  847. begin
  848. TestWebIDL([
  849. 'namespace Attr {',
  850. ' boolean vibrate(sequence<long> pattern);',
  851. '};',
  852. ''],
  853. []);
  854. end;
  855. procedure TTestWebIDL2WasmJob.TestWJ_IntfFunction_Constructor;
  856. begin
  857. TestWebIDL([
  858. 'interface Attr {',
  859. ' constructor(long options); ',
  860. '};'
  861. ],
  862. ['Type',
  863. ' // Forward class definitions',
  864. ' IJSAttr = interface;',
  865. ' TJSAttr = class;',
  866. ' { --------------------------------------------------------------------',
  867. ' TJSAttr',
  868. ' --------------------------------------------------------------------}',
  869. '',
  870. ' IJSAttr = interface(IJSObject)',
  871. ' [''{AA94F48A-EA1E-381A-A2A6-208CA4B2AF2A}'']',
  872. ' end;',
  873. '',
  874. ' TJSAttr = class(TJSObject,IJSAttr)',
  875. ' Private',
  876. ' Public',
  877. ' class function Create(aOptions : Integer) : TJSAttr;',
  878. ' class function Cast(const Intf: IJSObject): IJSAttr;',
  879. ' end;',
  880. '',
  881. 'implementation',
  882. '',
  883. 'class function TJSAttr.Create(aOptions: Integer) : TJSAttr;',
  884. 'begin',
  885. ' Result:=InvokeJSObjectResult(''Attr'',[aOptions],TJSAttr) as TJSAttr;',
  886. 'end;',
  887. '',
  888. 'class function TJSAttr.Cast(const Intf: IJSObject): IJSAttr;',
  889. 'begin',
  890. ' Result:=TJSAttr.JOBCast(Intf);',
  891. 'end;',
  892. '',
  893. 'end.',
  894. '']);
  895. end;
  896. procedure TTestWebIDL2WasmJob.TestWJ_IntfFunction_ArrayBufferArg;
  897. begin
  898. TestWebIDL([
  899. 'interface Attr {',
  900. ' undefined appendBuffer(ArrayBuffer data);',
  901. '};'
  902. ],[
  903. 'Type',
  904. ' // Forward class definitions',
  905. ' IJSAttr = interface;',
  906. ' TJSAttr = class;',
  907. ' { --------------------------------------------------------------------',
  908. ' TJSAttr',
  909. ' --------------------------------------------------------------------}',
  910. '',
  911. ' IJSAttr = interface(IJSObject)',
  912. ' [''{AA94F48A-84D7-3FB2-97EF-71ACA4B2AF2A}'']',
  913. ' procedure appendBuffer(aData: IJSArrayBuffer);',
  914. ' end;',
  915. '',
  916. ' TJSAttr = class(TJSObject,IJSAttr)',
  917. ' Private',
  918. ' Public',
  919. ' procedure appendBuffer(aData: IJSArrayBuffer);',
  920. ' class function Cast(const Intf: IJSObject): IJSAttr;',
  921. ' end;',
  922. '',
  923. 'implementation',
  924. '',
  925. 'procedure TJSAttr.appendBuffer(aData: IJSArrayBuffer);',
  926. 'begin',
  927. ' InvokeJSNoResult(''appendBuffer'',[aData]);',
  928. 'end;',
  929. '',
  930. 'class function TJSAttr.Cast(const Intf: IJSObject): IJSAttr;',
  931. 'begin',
  932. ' Result:=TJSAttr.JOBCast(Intf);',
  933. 'end;',
  934. '',
  935. 'end.',
  936. '' ]);
  937. end;
  938. procedure TTestWebIDL2WasmJob.TestWJ_IntfFunction_ArrayBufferViewArg;
  939. begin
  940. TestWebIDL([
  941. 'interface Attr {',
  942. ' undefined appendBuffer(ArrayBufferView data);',
  943. '};'
  944. ],[
  945. 'Type',
  946. ' // Forward class definitions',
  947. ' IJSAttr = interface;',
  948. ' TJSAttr = class;',
  949. ' { --------------------------------------------------------------------',
  950. ' TJSAttr',
  951. ' --------------------------------------------------------------------}',
  952. '',
  953. ' IJSAttr = interface(IJSObject)',
  954. ' [''{AA94F48A-84D7-3FB2-97EF-71ACA4B2AF2A}'']',
  955. ' procedure appendBuffer(aData: IJSArrayBufferView);',
  956. ' end;',
  957. '',
  958. ' TJSAttr = class(TJSObject,IJSAttr)',
  959. ' Private',
  960. ' Public',
  961. ' procedure appendBuffer(aData: IJSArrayBufferView);',
  962. ' class function Cast(const Intf: IJSObject): IJSAttr;',
  963. ' end;',
  964. '',
  965. 'implementation',
  966. '',
  967. 'procedure TJSAttr.appendBuffer(aData: IJSArrayBufferView);',
  968. 'begin',
  969. ' InvokeJSNoResult(''appendBuffer'',[aData]);',
  970. 'end;',
  971. '',
  972. 'class function TJSAttr.Cast(const Intf: IJSObject): IJSAttr;',
  973. 'begin',
  974. ' Result:=TJSAttr.JOBCast(Intf);',
  975. 'end;',
  976. '',
  977. 'end.',
  978. '' ]);
  979. end;
  980. procedure TTestWebIDL2WasmJob.TestWJ_NamespaceAttribute_Boolean;
  981. begin
  982. TestWebIDL([
  983. 'namespace Attr {',
  984. ' readonly attribute boolean aBoolean;',
  985. '};',
  986. ''],
  987. ['Type',
  988. ' // Forward class definitions',
  989. ' IJSAttr = interface;',
  990. ' TJSAttr = class;',
  991. ' { --------------------------------------------------------------------',
  992. ' TJSAttr',
  993. ' --------------------------------------------------------------------}',
  994. '',
  995. ' IJSAttr = interface(IJSObject)',
  996. ' [''{AA94F48A-7955-3EBA-B086-85B24440AF2A}'']',
  997. ' function _GetaBoolean: Boolean;',
  998. ' property aBoolean: Boolean read _GetaBoolean;',
  999. ' end;',
  1000. '',
  1001. ' TJSAttr = class(TJSObject,IJSAttr)',
  1002. ' Private',
  1003. ' function _GetaBoolean: Boolean;',
  1004. ' Public',
  1005. ' class function Cast(const Intf: IJSObject): IJSAttr;',
  1006. ' property aBoolean: Boolean read _GetaBoolean;',
  1007. ' end;',
  1008. '',
  1009. 'var ',
  1010. ' Attr : IJSAttr;',
  1011. '',
  1012. 'implementation',
  1013. '',
  1014. 'function TJSAttr._GetaBoolean: Boolean;',
  1015. 'begin',
  1016. ' Result:=ReadJSPropertyBoolean(''aBoolean'');',
  1017. 'end;',
  1018. '',
  1019. 'class function TJSAttr.Cast(const Intf: IJSObject): IJSAttr;',
  1020. 'begin',
  1021. ' Result:=TJSAttr.JOBCast(Intf);',
  1022. 'end;',
  1023. '',
  1024. 'initialization',
  1025. ' Attr:=TJSAttr.JOBCreateGlobal(''Attr'');',
  1026. '',
  1027. 'finalization',
  1028. ' Attr:=Nil;',
  1029. '',
  1030. 'end.',
  1031. '']);
  1032. end;
  1033. procedure TTestWebIDL2WasmJob.TestWJ_MaplikeInterface;
  1034. begin
  1035. TestWebIDL([
  1036. ' interface PM {',
  1037. ' readonly maplike<DOMString, boolean>;',
  1038. ' };'
  1039. ],[
  1040. 'Type',
  1041. ' // Forward class definitions',
  1042. ' IJSPM = interface;',
  1043. ' TJSPM = class;',
  1044. ' { --------------------------------------------------------------------',
  1045. ' TJSPM',
  1046. ' --------------------------------------------------------------------}',
  1047. '',
  1048. ' IJSPM = interface(IJSObject)',
  1049. ' [''{04D12607-C063-3E89-A483-3296C9C8AA41}'']',
  1050. ' function _Getsize: LongInt;',
  1051. ' function get(key: UnicodeString) : Boolean;',
  1052. ' function has(key: UnicodeString) : Boolean;',
  1053. ' function entries : IJSIterator;',
  1054. ' function keys : IJSIterator;',
  1055. ' function values : IJSIterator;',
  1056. ' property size : LongInt read _Getsize;',
  1057. ' end;',
  1058. '',
  1059. ' TJSPM = class(TJSObject,IJSPM)',
  1060. ' Private',
  1061. ' function _Getsize: LongInt;',
  1062. ' Public',
  1063. ' function get(key: UnicodeString) : Boolean;',
  1064. ' function has(key: UnicodeString) : Boolean;',
  1065. ' function entries : IJSIterator;',
  1066. ' function keys : IJSIterator;',
  1067. ' function values : IJSIterator;',
  1068. ' class function Cast(const Intf: IJSObject): IJSPM;',
  1069. ' property size : LongInt read _Getsize;',
  1070. ' end;',
  1071. '',
  1072. 'implementation',
  1073. '',
  1074. 'function TJSPM._Getsize: LongInt;',
  1075. 'begin',
  1076. ' Result:=ReadJSPropertyLongInt(''size'');',
  1077. 'end;',
  1078. '',
  1079. 'function TJSPM.get(key: UnicodeString) : Boolean;',
  1080. 'begin',
  1081. ' Result:=InvokeJSBooleanResult(''get'',[key]);',
  1082. 'end;',
  1083. '',
  1084. 'function TJSPM.has(key: UnicodeString) : Boolean;',
  1085. 'begin',
  1086. ' Result:=InvokeJSBooleanResult(''has'',[key]);',
  1087. 'end;',
  1088. '',
  1089. 'function TJSPM.entries : IJSIterator;',
  1090. 'begin',
  1091. ' Result:=InvokeJSObjectResult(''entries'',[],TJSIterator) as IJSIterator;',
  1092. 'end;',
  1093. '',
  1094. 'function TJSPM.keys : IJSIterator;',
  1095. 'begin',
  1096. ' Result:=InvokeJSObjectResult(''keys'',[],TJSIterator) as IJSIterator;',
  1097. 'end;',
  1098. '',
  1099. 'function TJSPM.values : IJSIterator;',
  1100. 'begin',
  1101. ' Result:=InvokeJSObjectResult(''values'',[],TJSIterator) as IJSIterator;',
  1102. 'end;',
  1103. '',
  1104. 'class function TJSPM.Cast(const Intf: IJSObject): IJSPM;',
  1105. 'begin',
  1106. ' Result:=TJSPM.JOBCast(Intf);',
  1107. 'end;',
  1108. '',
  1109. 'end.',
  1110. ''
  1111. ]);
  1112. end;
  1113. initialization
  1114. RegisterTests([TTestWebIDL2Wasmjob]);
  1115. end.