webidltopas.pp 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401
  1. {
  2. This file is part of the Free Component Library
  3. WEBIDL to pascal code converter
  4. Copyright (c) 2018 by Michael Van Canneyt [email protected]
  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. unit webidltopas;
  12. {$mode objfpc}{$H+}
  13. interface
  14. uses
  15. Classes, SysUtils, contnrs, WebIDLParser, WebIDLScanner, WebIDLDefs, pascodegen;
  16. Type
  17. { TWebIDLToPas }
  18. { TPasData }
  19. TPasData = Class(TObject)
  20. private
  21. FPasName: String;
  22. Public
  23. Constructor Create(APasName : String);
  24. Property PasName : String read FPasName;
  25. end;
  26. TConversionOption = (coDictionaryAsClass,coUseNativeTypeAliases,coExternalConst,coExpandUnionTypeArgs,coaddOptionsToheader);
  27. TConversionOptions = Set of TConversionOption;
  28. TWebIDLToPas = Class(TPascalCodeGenerator)
  29. private
  30. FClassPrefix: String;
  31. FClassSuffix: String;
  32. FContext: TWebIDLContext;
  33. FDictionaryClassParent: String;
  34. FFieldPrefix: String;
  35. FIncludeImplementationCode: TStrings;
  36. FIncludeInterfaceCode: TStrings;
  37. FInputFileName: String;
  38. FOptions: TConversionOptions;
  39. FOutputFileName: String;
  40. FTypeAliases: TStrings;
  41. FVerbose: Boolean;
  42. FWebIDLVersion: TWebIDLVersion;
  43. FPasNameList : TFPObjectList;
  44. FAutoTypes : TStrings;
  45. procedure SetIncludeImplementationCode(AValue: TStrings);
  46. procedure SetIncludeInterfaceCode(AValue: TStrings);
  47. procedure SetTypeAliases(AValue: TStrings);
  48. Protected
  49. procedure AddOptionsToHeader;
  50. Procedure Parse; virtual;
  51. Procedure WritePascal; virtual;
  52. function CreateParser(aContext: TWebIDLContext; S: TWebIDLScanner): TWebIDLParser; virtual;
  53. function CreateScanner(S: TStream): TWebIDLScanner;virtual;
  54. Function CreateContext : TWebIDLContext; virtual;
  55. Function BaseUnits : String; override;
  56. // Auxiliary routines
  57. procedure Getoptions(L: TStrings); virtual;
  58. procedure ProcessDefinitions; virtual;
  59. function CreatePasName(aName: String): TPasData;virtual;
  60. procedure AllocatePasNames(aList: TIDLDefinitionList; ParentName: String='');virtual;
  61. Function AllocatePasName(D: TIDLDefinition; ParentName: String='') : TPasData;virtual;
  62. procedure EnsureUniqueNames(ML: TIDLDefinitionList);virtual;
  63. function WriteFunctionImplicitTypes(aList: TIDLDefinitionList): Integer;virtual;
  64. function WriteAttributeImplicitTypes(aList: TIDLDefinitionList): Integer;virtual;
  65. function WriteDictionaryMemberImplicitTypes(aList: TIDLDefinitionList): Integer;virtual;
  66. function AddSequenceDef(ST: TIDLSequenceTypeDefDefinition): Boolean; virtual;
  67. function GetName(ADef: TIDLDefinition): String;virtual;
  68. function GetTypeName(Const aTypeName: String; ForTypeDef: Boolean=False): String;virtual;
  69. function GetTypeName(aTypeDef: TIDLTypeDefDefinition; ForTypeDef: Boolean=False): String;virtual;
  70. function CheckUnionTypeDefinition(D: TIDLDefinition): TIDLUnionTypeDefDefinition;virtual;
  71. procedure AddArgumentToOverloads(aList: TFPObjectlist; AName, ATypeName: String);virtual;
  72. procedure AddUnionOverloads(aList: TFPObjectlist; AName: String; UT: TIDLUnionTypeDefDefinition);virtual;
  73. procedure AddArgumentToOverloads(aList: TFPObjectlist; adef: TIDLArgumentDefinition);virtual;
  74. procedure AddOverloads(aList: TFPObjectlist; adef: TIDLFunctionDefinition; aIdx: Integer);virtual;
  75. function CloneNonPartialArgumentList(aList: TFPObjectlist; ADest: TFPObjectlist= Nil; AsPartial: Boolean=True): integer;virtual;
  76. function GetOverloads(aDef: TIDLFunctionDefinition): TFPObjectlist;virtual;
  77. function GetArguments(aList: TIDLDefinitionList; ForceBrackets: Boolean): String;virtual;
  78. function HaveConsts(aList: TIDLDefinitionList): Boolean;virtual;
  79. // Actual code generation routines
  80. // Lists. Return the number of actually written defs.
  81. function WriteCallBackDefs(aList: TIDLDefinitionList): Integer; virtual;
  82. Function WriteDictionaryDefs(aList: TIDLDefinitionList) : Integer;virtual;
  83. Function WriteForwardClassDefs(aList: TIDLDefinitionList) : Integer;virtual;
  84. Function WriteInterfaceDefs(aList: TIDLDefinitionList) : Integer;virtual;
  85. Function WriteMethodDefs(aList: TIDLDefinitionList) : Integer;virtual;
  86. Function WriteTypeDefs(aList: TIDLDefinitionList) : Integer;virtual;
  87. Function WriteEnumDefs(aList: TIDLDefinitionList) : Integer;virtual;
  88. function WriteConsts(aList: TIDLDefinitionList): Integer;virtual;
  89. function WriteProperties(aList: TIDLDefinitionList): Integer;
  90. function WritePlainFields(aList: TIDLDefinitionList): Integer;virtual;
  91. function WriteDictionaryFields(aList: TIDLDefinitionList): Integer;virtual;
  92. function WritePrivateReadOnlyFields(aList: TIDLDefinitionList): Integer;virtual;
  93. // Actual definitions. Return true if a definition was written.
  94. Function WriteForwardClassDef(D: TIDLStructuredDefinition) : Boolean;virtual;
  95. function WriteFunctionTypeDefinition(aDef: TIDLFunctionDefinition): Boolean;virtual;
  96. function WriteFunctionDefinition(aDef: TIDLFunctionDefinition): Boolean;virtual;
  97. function WriteTypeDef(aDef: TIDLTypeDefDefinition): Boolean; virtual;
  98. function WriteRecordDef(aDef: TIDLRecordDefinition): Boolean; virtual;
  99. function WriteEnumDef(aDef: TIDLEnumDefinition): Boolean; virtual;
  100. function WriteDictionaryField(aField: TIDLDictionaryMemberDefinition): Boolean;virtual;
  101. Function WritePrivateReadOnlyField(aAttr: TIDLAttributeDefinition) : Boolean;virtual;
  102. Function WriteField(aAttr: TIDLAttributeDefinition) : Boolean;virtual;
  103. Function WriteReadonlyProperty(aAttr: TIDLAttributeDefinition) : Boolean;virtual;
  104. Function WriteConst(aConst: TIDLConstDefinition) : Boolean ;virtual;
  105. function WriteInterfaceDef(Intf: TIDLInterfaceDefinition): Boolean; virtual;
  106. function WriteDictionaryDef(aDict: TIDLDictionaryDefinition): Boolean; virtual;
  107. // Additional
  108. procedure WriteAliasTypeDef(aDef: TIDLTypeDefDefinition);virtual;
  109. procedure WritePromiseDef(aDef: TIDLPromiseTypeDefDefinition);virtual;
  110. procedure WriteSequenceDef(aDef: TIDLSequenceTypeDefDefinition);virtual;
  111. procedure WriteUnionDef(aDef: TIDLUnionTypeDefDefinition);virtual;
  112. // Extra interface/Implementation code.
  113. procedure WriteImplementation; virtual;
  114. procedure WriteIncludeInterfaceCode; virtual;
  115. Property Context : TWebIDLContext Read FContext;
  116. Public
  117. Constructor Create(Aowner : TComponent); override;
  118. Destructor Destroy; override;
  119. Procedure Execute;
  120. Published
  121. Property InputFileName : String Read FInputFileName Write FInputFileName;
  122. Property OutputFileName : String Read FOutputFileName Write FOutputFileName;
  123. Property Verbose : Boolean Read FVerbose Write FVerbose;
  124. Property FieldPrefix : String Read FFieldPrefix Write FFieldPrefix;
  125. Property ClassPrefix : String Read FClassPrefix Write FClassPrefix;
  126. Property ClassSuffix : String Read FClassSuffix Write FClassSuffix;
  127. Property Options : TConversionOptions Read FOptions Write FOptions;
  128. Property WebIDLVersion : TWebIDLVersion Read FWebIDLVersion Write FWebIDLVersion;
  129. Property TypeAliases : TStrings Read FTypeAliases Write SetTypeAliases;
  130. Property IncludeInterfaceCode : TStrings Read FIncludeInterfaceCode Write SetIncludeInterfaceCode;
  131. Property IncludeImplementationCode : TStrings Read FIncludeImplementationCode Write SetIncludeImplementationCode;
  132. Property DictionaryClassParent : String Read FDictionaryClassParent Write FDictionaryClassParent;
  133. end;
  134. implementation
  135. uses typinfo;
  136. { TPasData }
  137. constructor TPasData.Create(APasName: String);
  138. begin
  139. FPasName:=APasName;
  140. end;
  141. { TWebIDLToPas }
  142. function TWebIDLToPas.CreateContext: TWebIDLContext;
  143. begin
  144. Result:=TWebIDLContext.Create(True);
  145. end;
  146. function TWebIDLToPas.CreateScanner(S : TStream) : TWebIDLScanner;
  147. begin
  148. Result:=TWebIDLScanner.Create(S);
  149. end;
  150. function TWebIDLToPas.CreateParser(aContext : TWebIDLContext;S : TWebIDLScanner) : TWebIDLParser;
  151. begin
  152. Result:=TWebIDLParser.Create(aContext,S);
  153. Result.Version:=FWebIDLVersion;
  154. end;
  155. procedure TWebIDLToPas.Parse;
  156. Var
  157. F : TFileStream;
  158. S : TWebIDLScanner;
  159. P : TWebIDLParser;
  160. begin
  161. P:=Nil;
  162. F:=TFileStream.Create(InputFileName,fmOpenRead or fmShareDenyWrite);
  163. try
  164. S:=CreateScanner(F);
  165. P:=CreateParser(Context,S);
  166. P.Parse;
  167. finally
  168. P.Free;
  169. S.Free;
  170. F.Free;
  171. end;
  172. end;
  173. function TWebIDLToPas.GetName(ADef: TIDLDefinition): String;
  174. begin
  175. If Assigned(ADef) and (TObject(ADef.Data) is TPasData) then
  176. Result:=TPasData(ADef.Data).PasName
  177. else
  178. Result:=ADef.Name;
  179. end;
  180. function TWebIDLToPas.HaveConsts(aList: TIDLDefinitionList): Boolean;
  181. Var
  182. D : TIDLDefinition;
  183. begin
  184. Result:=False;
  185. For D in aList do
  186. if D is TIDLConstDefinition then
  187. Exit(True);
  188. end;
  189. function TWebIDLToPas.WritePrivateReadOnlyFields(aList: TIDLDefinitionList): Integer;
  190. Var
  191. D : TIDLDefinition;
  192. A : TIDLAttributeDefinition absolute D;
  193. begin
  194. Result:=0;
  195. For D in aList do
  196. if (D is TIDLAttributeDefinition) then
  197. if (aoReadOnly in A.Options) then
  198. if WritePrivateReadOnlyField(A) then
  199. Inc(Result);
  200. end;
  201. function TWebIDLToPas.WriteProperties(aList: TIDLDefinitionList): Integer;
  202. Var
  203. D : TIDLDefinition;
  204. A : TIDLAttributeDefinition absolute D;
  205. begin
  206. Result:=0;
  207. For D in aList do
  208. if (D is TIDLAttributeDefinition) then
  209. if (aoReadOnly in A.Options) then
  210. if WriteReadOnlyProperty(A) then
  211. Inc(Result);
  212. end;
  213. function TWebIDLToPas.WriteConst(aConst: TIDLConstDefinition): Boolean;
  214. Const
  215. ConstTypes : Array[TConstType] of String =
  216. ('Double','NativeInt','Boolean','JSValue','JSValue','JSValue','JSValue','String','JSValue','JSValue');
  217. Var
  218. S : String;
  219. begin
  220. Result:=True;
  221. // Consts cannot be strings
  222. if coExternalConst in Options then
  223. begin
  224. S:=ConstTypes[aConst.ConstType];
  225. Addln('%s : %s;',[GetName(aConst),S])
  226. end
  227. else
  228. begin
  229. S:=aConst.Value;
  230. if aConst.ConstType=ctInteger then
  231. S:=StringReplace(S,'0x','$',[]);
  232. Addln('%s = %s;',[GetName(aConst),S])
  233. end;
  234. end;
  235. function TWebIDLToPas.WriteConsts(aList: TIDLDefinitionList): Integer;
  236. Var
  237. D : TIDLDefinition;
  238. begin
  239. EnsureSection(csConst);
  240. Indent;
  241. Result:=0;
  242. For D in aList do
  243. if D is TIDLConstDefinition then
  244. if WriteConst(D as TIDLConstDefinition) then
  245. Inc(Result);
  246. Undent;
  247. end;
  248. function TWebIDLToPas.WritePlainFields(aList: TIDLDefinitionList): Integer;
  249. Var
  250. D : TIDLDefinition;
  251. A : TIDLAttributeDefinition absolute D;
  252. begin
  253. EnsureSection(csDeclaration);
  254. Indent;
  255. Result:=0;
  256. For D in aList do
  257. if D is TIDLAttributeDefinition then
  258. if Not (aoReadOnly in A.Options) then
  259. if WriteField(A) then
  260. Inc(Result);
  261. Undent;
  262. end;
  263. function TWebIDLToPas.WriteDictionaryField(
  264. aField: TIDLDictionaryMemberDefinition): Boolean;
  265. Var
  266. Def,N,TN : String;
  267. begin
  268. Result:=True;
  269. N:=GetName(aField);
  270. TN:=GetTypeName(aField.MemberType);
  271. if TN='record' then
  272. TN:='TJSObject';
  273. if SameText(N,TN) then
  274. N:='_'+N;
  275. Def:=Format('%s : %s;',[N,TN]);
  276. if (N<>aField.Name) then
  277. Def:=Def+Format('external name ''%s'';',[aField.Name]);
  278. AddLn(Def);
  279. end;
  280. function TWebIDLToPas.WriteDictionaryFields(aList: TIDLDefinitionList): Integer;
  281. Var
  282. D : TIDLDefinition;
  283. M : TIDLDictionaryMemberDefinition absolute D;
  284. begin
  285. Indent;
  286. Result:=0;
  287. For D in aList do
  288. if D is TIDLDictionaryMemberDefinition then
  289. if WriteDictionaryField(M) then
  290. Inc(Result);
  291. Undent;
  292. end;
  293. function TWebIDLToPas.WriteMethodDefs(aList: TIDLDefinitionList): Integer;
  294. Var
  295. D : TIDLDefinition;
  296. FD : TIDLFunctionDefinition absolute D;
  297. begin
  298. Result:=0;
  299. for D in aList do
  300. if D is TIDLFunctionDefinition then
  301. if Not (foCallBack in FD.Options) then
  302. if WriteFunctionDefinition(FD) then
  303. Inc(Result);
  304. end;
  305. function TWebIDLToPas.AddSequenceDef(ST: TIDLSequenceTypeDefDefinition
  306. ): Boolean;
  307. var
  308. TN : String;
  309. begin
  310. TN:=GetTypeName(ST);
  311. Result:=FAutoTypes.IndexOf(TN)=-1;
  312. if Result then
  313. begin
  314. FAutoTypes.Add(TN);
  315. DoLog('Automatically adding %s sequence definition.',[TN]);
  316. AddLn('%s = Array of %s;',[TN,GetTypeName(ST.ElementType)]);
  317. ST.Data:=CreatePasName(TN);
  318. end;
  319. end;
  320. function TWebIDLToPas.WriteFunctionImplicitTypes(aList: TIDLDefinitionList): Integer;
  321. Var
  322. D,D2,D3 : TIDLDefinition;
  323. FD : TIDLFunctionDefinition absolute D;
  324. DA : TIDLArgumentDefinition absolute D2;
  325. UT : TIDLUnionTypeDefDefinition;
  326. begin
  327. Result:=0;
  328. for D in aList do
  329. if D is TIDLFunctionDefinition then
  330. if Not (foCallBack in FD.Options) then
  331. begin
  332. if (FD.ReturnType is TIDLSequenceTypeDefDefinition) then
  333. if AddSequenceDef(FD.ReturnType as TIDLSequenceTypeDefDefinition) then
  334. Inc(Result);
  335. For D2 in FD.Arguments do
  336. if (DA.ArgumentType is TIDLSequenceTypeDefDefinition) then
  337. begin
  338. if AddSequenceDef(DA.ArgumentType as TIDLSequenceTypeDefDefinition) then
  339. Inc(Result);
  340. end
  341. else
  342. begin
  343. UT:=CheckUnionTypeDefinition(DA.ArgumentType);
  344. if Assigned(UT) then
  345. For D3 in UT.Union do
  346. if (D3 is TIDLSequenceTypeDefDefinition) then
  347. if AddSequenceDef(D3 as TIDLSequenceTypeDefDefinition) then
  348. Inc(Result);
  349. end;
  350. end;
  351. if Result>0 then
  352. AddLn('');
  353. end;
  354. function TWebIDLToPas.WriteAttributeImplicitTypes(aList: TIDLDefinitionList
  355. ): Integer;
  356. Var
  357. D : TIDLDefinition;
  358. FA : TIDLAttributeDefinition absolute D;
  359. begin
  360. Result:=0;
  361. for D in aList do
  362. if D is TIDLAttributeDefinition then
  363. if (FA.AttributeType is TIDLSequenceTypeDefDefinition) then
  364. if AddSequenceDef(FA.AttributeType as TIDLSequenceTypeDefDefinition) then
  365. Inc(Result);
  366. end;
  367. function TWebIDLToPas.WriteDictionaryMemberImplicitTypes(
  368. aList: TIDLDefinitionList): Integer;
  369. Var
  370. D : TIDLDefinition;
  371. FD : TIDLDictionaryMemberDefinition absolute D;
  372. begin
  373. Result:=0;
  374. for D in aList do
  375. if D is TIDLDictionaryMemberDefinition then
  376. if (FD.MemberType is TIDLSequenceTypeDefDefinition) then
  377. if AddSequenceDef(FD.MemberType as TIDLSequenceTypeDefDefinition) then
  378. Inc(Result);
  379. end;
  380. procedure TWebIDLToPas.EnsureUniqueNames(ML : TIDLDefinitionList);
  381. Var
  382. L : TFPObjectHashTable;
  383. Procedure CheckRename(aD : TIDLDefinition);
  384. var
  385. I : integer;
  386. NOrig,N,N2 : String;
  387. isDup : Boolean;
  388. D2 : TIDLDefinition;
  389. begin
  390. NOrig:=GetName(aD);
  391. N:=LowerCase(NOrig);
  392. N2:=N;
  393. I:=0;
  394. isDup:=False;
  395. Repeat
  396. D2:=TIDLDefinition(L.Items[N2]);
  397. if (D2<>Nil) then
  398. // Overloads
  399. begin
  400. isDup:=((D2 is TIDLFunctionDefinition) and (ad is TIDLFunctionDefinition));
  401. if IsDup then
  402. D2:=Nil
  403. else
  404. begin
  405. inc(I);
  406. N2:=KeywordPrefix+N+KeywordSuffix;
  407. Norig:=KeywordPrefix+NOrig+KeywordSuffix;
  408. end;
  409. end;
  410. Until (D2=Nil);
  411. if (N<>N2) then
  412. begin
  413. N:=GetName(aD);
  414. DoLog('Renaming duplicate identifier (%s) %s to %s',[aD.ClassName,N,Norig]);
  415. // Original TPasName is in list, will be freed automatically
  416. aD.Data:=CreatePasName(NOrig);
  417. end;
  418. if not IsDup then
  419. L.Add(N2,aD);
  420. end;
  421. var
  422. D : TIDLDefinition;
  423. begin
  424. L:=TFPObjectHashTable.Create(False);
  425. try
  426. For D in ML Do
  427. if not (D is TIDLConstDefinition) then
  428. CheckRename(D);
  429. For D in ML Do
  430. if (D is TIDLConstDefinition) then
  431. CheckRename(D);
  432. finally
  433. L.Free;
  434. end;
  435. end;
  436. function TWebIDLToPas.WriteInterfaceDef(Intf: TIDLInterfaceDefinition): Boolean;
  437. Var
  438. CN,PN : String;
  439. Decl : String;
  440. ML : TIDLDefinitionList;
  441. begin
  442. Result:=True;
  443. ML:=TIDLDefinitionList.Create(Nil,False);
  444. try
  445. Intf.GetFullMemberList(ML);
  446. EnsureUniqueNames(ML);
  447. CN:=GetName(Intf);
  448. ClassHeader(CN);
  449. WriteFunctionImplicitTypes(ML);
  450. WriteAttributeImplicitTypes(ML);
  451. Decl:=Format('%s = class external name %s ',[CN,MakePascalString(Intf.Name,True)]);
  452. if Assigned(Intf.ParentInterface) then
  453. PN:=GetName(Intf.ParentInterface)
  454. else
  455. PN:=GetTypeName(Intf.ParentName);
  456. if PN<>'' then
  457. Decl:=Decl+Format(' (%s)',[PN]);
  458. AddLn(Decl);
  459. AddLn('Private');
  460. Indent;
  461. WritePrivateReadOnlyFields(ML);
  462. Undent;
  463. AddLn('Public');
  464. if HaveConsts(ML) then
  465. begin
  466. Indent;
  467. PushSection(csUnknown);
  468. WriteConsts(ML);
  469. PopSection;
  470. Undent;
  471. AddLn('Public');
  472. end;
  473. Indent;
  474. WritePlainFields(ML);
  475. WriteMethodDefs(ML);
  476. WriteProperties(ML);
  477. Undent;
  478. AddLn('end;');
  479. finally
  480. ML.Free;
  481. end;
  482. end;
  483. function TWebIDLToPas.WriteDictionaryDef(aDict: TIDLDictionaryDefinition
  484. ): Boolean;
  485. Var
  486. CN,CP : String;
  487. ML : TIDLDefinitionList;
  488. PD: TIDLDictionaryDefinition;
  489. begin
  490. Result:=True;
  491. ML:=TIDLDefinitionList.Create(Nil,False);
  492. try
  493. PD:=aDict;
  494. While PD<>Nil do
  495. begin
  496. PD.GetFullMemberList(ML);
  497. PD:=PD.ParentDictionary;
  498. end;
  499. CN:=GetName(aDict);
  500. CP:=DictionaryClassParent;
  501. if CP='' then
  502. CP:='TJSObject';
  503. ClassHeader(CN);
  504. WriteDictionaryMemberImplicitTypes(ML);
  505. if (coDictionaryAsClass in Options) then
  506. Addln('%s = class(%s)',[CN,CP])
  507. else
  508. Addln('%s = record',[CN]);
  509. WriteDictionaryFields(ML);
  510. AddLn('end;');
  511. finally
  512. ML.Free;
  513. end;
  514. end;
  515. constructor TWebIDLToPas.Create(Aowner: TComponent);
  516. begin
  517. inherited Create(Aowner);
  518. WebIDLVersion:=v2;
  519. FieldPrefix:='F';
  520. ClassPrefix:='T';
  521. ClassSuffix:='';
  522. Switches.Add('modeswitch externalclass');
  523. FTypeAliases:=TStringList.Create;
  524. FPasNameList:=TFPObjectList.Create(True);
  525. FAutoTypes:=TStringList.Create;
  526. FIncludeInterfaceCode:=TStringList.Create;
  527. FIncludeImplementationCode:=TStringList.Create;
  528. end;
  529. destructor TWebIDLToPas.Destroy;
  530. begin
  531. FreeAndNil(FIncludeInterfaceCode);
  532. FreeAndNil(FIncludeImplementationCode);
  533. FreeAndNil(FAutoTypes);
  534. FreeAndNil(FTypeAliases);
  535. FreeAndNil(FPasNameList);
  536. inherited Destroy;
  537. end;
  538. procedure TWebIDLToPas.WriteImplementation;
  539. Var
  540. S : String;
  541. begin
  542. Addln('');
  543. For S in FIncludeImplementationCode do
  544. Addln(S);
  545. Addln('');
  546. end;
  547. function TWebIDLToPas.GetTypeName(aTypeDef : TIDLTypeDefDefinition; ForTypeDef : Boolean = False): String;
  548. begin
  549. if ATypeDef is TIDLSequenceTypeDefDefinition then
  550. begin
  551. if Assigned(aTypeDef.Data) then
  552. Result:=GetName(aTypeDef)
  553. else
  554. begin
  555. Result:=GetTypeName(TIDLSequenceTypeDefDefinition(aTypeDef).ElementType,ForTypeDef);
  556. Result:='T'+Result+'DynArray';
  557. end
  558. end
  559. else
  560. Result:=GetTypeName(aTypeDef.TypeName,ForTypeDef);
  561. end;
  562. function TWebIDLToPas.GetTypeName(const aTypeName: String; ForTypeDef: Boolean
  563. ): String;
  564. Function UsePascalType(Const aPascalType : string) : String;
  565. begin
  566. if (coUseNativeTypeAliases in Options) and ForTypeDef then
  567. Result:=StringReplace(aTypeName,' ','',[rfReplaceAll])
  568. else
  569. Result:=aPascalType;
  570. end;
  571. Var
  572. A,TN : UTF8String;
  573. D : TIDLDefinition;
  574. begin
  575. Case aTypeName of
  576. 'union': TN:='JSValue';
  577. 'short': TN:=UsePascalType('Integer');
  578. 'long': TN:=UsePascalType('Integer');
  579. 'long long': TN:=UsePascalType('NativeInt');
  580. 'unsigned short': TN:=UsePascalType('Cardinal');
  581. 'unrestricted float': TN:=UsePascalType('Double');
  582. 'unrestricted double': TN:=UsePascalType('Double');
  583. 'unsigned long': TN:=UsePascalType('NativeInt');
  584. 'unsigned long long': TN:=UsePascalType('NativeInt');
  585. 'octet': TN:=UsePascalType('Byte');
  586. 'any' : TN:=UsePascalType('JSValue');
  587. 'float' : TN:=UsePascalType('Double');
  588. 'double' : TN:=UsePascalType('Double');
  589. 'DOMString',
  590. 'USVString',
  591. 'ByteString' : TN:=UsePascalType('String');
  592. 'object' : TN:=UsePascalType('TJSObject');
  593. 'Error' : TN:=UsePascalType('TJSError');
  594. 'DOMException' : TN:=UsePascalType('TJSError');
  595. 'ArrayBuffer',
  596. 'DataView',
  597. 'Int8Array',
  598. 'Int16Array',
  599. 'Int32Array',
  600. 'Uint8Array',
  601. 'Uint16Array',
  602. 'Uint32Array',
  603. 'Uint8ClampedArray',
  604. 'Float32Array',
  605. 'Float64Array' : TN:='TJS'+aTypeName;
  606. else
  607. TN:=aTypeName;
  608. D:=FContext.FindDefinition(TN);
  609. if D<>Nil then
  610. TN:=GetName(D)
  611. else
  612. begin
  613. A:=FTypeAliases.Values[TN];
  614. If (A<>'') then
  615. TN:=A;
  616. end;
  617. end;
  618. Result:=TN;
  619. end;
  620. function TWebIDLToPas.WritePrivateReadOnlyField(aAttr: TIDLAttributeDefinition
  621. ): Boolean;
  622. begin
  623. AddLn('%s%s : %s; external name ''%s''; ',[FieldPrefix,GetName(aAttr),GetTypeName(aAttr.AttributeType),aAttr.Name]);
  624. end;
  625. function TWebIDLToPas.WriteField(aAttr: TIDLAttributeDefinition): Boolean;
  626. Var
  627. Def,TN,N : String;
  628. begin
  629. Result:=True;
  630. N:=GetName(aAttr);
  631. TN:=GetTypeName(aAttr.AttributeType);
  632. if TN='record' then
  633. TN:='TJSObject';
  634. if SameText(N,TN) then
  635. N:='_'+N;
  636. Def:=Format('%s : %s;',[N,TN]);
  637. if (N<>aAttr.Name) then
  638. Def:=Def+Format('external name ''%s'';',[aAttr.Name]);
  639. AddLn(Def);
  640. end;
  641. function TWebIDLToPas.WriteReadonlyProperty(aAttr: TIDLAttributeDefinition
  642. ): Boolean;
  643. Var
  644. TN,N,PN : String;
  645. begin
  646. Result:=True;
  647. N:=GetName(aAttr);
  648. PN:=N;
  649. TN:=GetTypeName(aAttr.AttributeType);
  650. if SameText(PN,TN) then
  651. PN:='_'+PN;
  652. AddLn('Property %s : %s Read %s%s; ',[PN,TN,FieldPrefix,N]);
  653. end;
  654. function TWebIDLToPas.WriteForwardClassDef(D: TIDLStructuredDefinition): Boolean;
  655. begin
  656. Result:=not D.IsPartial;
  657. if Result then
  658. AddLn('%s = Class;',[GetName(D)]);
  659. end;
  660. function TWebIDLToPas.WriteForwardClassDefs(aList: TIDLDefinitionList): Integer;
  661. Var
  662. D : TIDLDefinition;
  663. begin
  664. Result:=0;
  665. Comment('Forward class definitions');
  666. For D in aList do
  667. if D is TIDLInterfaceDefinition then
  668. if WriteForwardClassDef(D as TIDLInterfaceDefinition) then
  669. Inc(Result);
  670. if coDictionaryAsClass in Options then
  671. For D in aList do
  672. if D is TIDLDictionaryDefinition then
  673. if WriteForwardClassDef(D as TIDLDictionaryDefinition) then
  674. Inc(Result);
  675. end;
  676. procedure TWebIDLToPas.WriteSequenceDef(aDef : TIDLSequenceTypeDefDefinition);
  677. begin
  678. Addln('%s = array of %s;',[GetName(aDef),GetTypeName(aDef.ElementType)])
  679. end;
  680. procedure TWebIDLToPas.WriteUnionDef(aDef : TIDLUnionTypeDefDefinition);
  681. Var
  682. S : UTF8String;
  683. D : TIDLDefinition;
  684. begin
  685. S:='';
  686. For D in adef.Union do
  687. begin
  688. if (S<>'') then
  689. S:=S+', ';
  690. S:=S+(D as TIDLTypeDefDefinition).TypeName;
  691. end;
  692. Comment('Union of '+S);
  693. AddLn('%s = JSValue; ',[GetName(aDef)])
  694. end;
  695. procedure TWebIDLToPas.WritePromiseDef(aDef : TIDLPromiseTypeDefDefinition);
  696. begin
  697. AddLn('%s = TJSPromise;',[GetName(aDef)]);
  698. end;
  699. procedure TWebIDLToPas.WriteAliasTypeDef(aDef : TIDLTypeDefDefinition);
  700. Var
  701. TN : String;
  702. begin
  703. TN:=GetTypeName(aDef,True);
  704. AddLn('%s = %s;',[GetName(aDef),TN]);
  705. end;
  706. function TWebIDLToPas.WriteTypeDef(aDef: TIDLTypeDefDefinition): Boolean;
  707. begin
  708. Result:=True;
  709. if ADef is TIDLSequenceTypeDefDefinition then
  710. WriteSequenceDef(aDef as TIDLSequenceTypeDefDefinition)
  711. else if ADef is TIDLUnionTypeDefDefinition then
  712. WriteUnionDef(aDef as TIDLUnionTypeDefDefinition)
  713. else if ADef is TIDLPromiseTypeDefDefinition then
  714. WritePromiseDef(aDef as TIDLPromiseTypeDefDefinition)
  715. else if ADef is TIDLRecordDefinition then
  716. WriteRecordDef(aDef as TIDLRecordDefinition)
  717. else
  718. WriteAliasTypeDef(aDef);
  719. end;
  720. function TWebIDLToPas.WriteRecordDef(aDef: TIDLRecordDefinition): Boolean;
  721. Var
  722. KT,VT : String;
  723. begin
  724. Result:=True;
  725. KT:=GetTypeName(aDef.KeyType);
  726. VT:=GetTypeName(aDef.ValueType);
  727. AddLn('%s = Class(TJSObject)',[GetName(aDef)]);
  728. AddLn('private');
  729. Indent;
  730. AddLn('function GetValue(aKey: %s): %s; external name ''[]'';',[KT,VT]);
  731. AddLn('procedure SetValue(aKey: %s; const AValue: %s); external name ''[]'';',[KT,VT]);
  732. undent;
  733. AddLn('public');
  734. Indent;
  735. AddLn('property Values[Name: %s]: %s read GetProperties write SetProperties; default;',[KT,VT]);
  736. undent;
  737. AddLn('end;');
  738. end;
  739. function TWebIDLToPas.WriteTypeDefs(aList: TIDLDefinitionList): Integer;
  740. Var
  741. D : TIDLDefinition;
  742. TD : TIDLTypeDefDefinition absolute D;
  743. begin
  744. Result:=0;
  745. EnsureSection(csType);
  746. for D in aList do
  747. if D is TIDLTypeDefDefinition then
  748. if WriteTypeDef(TD) then
  749. Inc(Result);
  750. end;
  751. function TWebIDLToPas.WriteEnumDef(aDef: TIDLEnumDefinition): Boolean;
  752. begin
  753. Result:=True;
  754. AddLn('%s = String;',[GetName(aDef)]);
  755. end;
  756. function TWebIDLToPas.WriteEnumDefs(aList: TIDLDefinitionList): Integer;
  757. Var
  758. D : TIDLDefinition;
  759. ED : TIDLEnumDefinition absolute D;
  760. begin
  761. Result:=0;
  762. EnsureSection(csType);
  763. for D in aList do
  764. if D is TIDLEnumDefinition then
  765. if WriteEnumDef(ED) then
  766. Inc(Result);
  767. end;
  768. function TWebIDLToPas.GetArguments(aList: TIDLDefinitionList;
  769. ForceBrackets: Boolean): String;
  770. Var
  771. I : TIDLDefinition;
  772. A : TIDLArgumentDefinition absolute I;
  773. Arg : string;
  774. begin
  775. Result:='';
  776. For I in aList do
  777. begin
  778. Arg:=GetName(A);
  779. Arg:=Arg+' : '+GetTypeName(A.ArgumentType);
  780. if Result<>'' then
  781. Result:=Result+'; ';
  782. Result:=Result+Arg;
  783. end;
  784. if (Result<>'') or ForceBrackets then
  785. Result:='('+Result+')';
  786. end;
  787. Type
  788. // A partial argument list is a list which has been generated for a optional argument.
  789. // Additional arguments can never be added to a partial list...
  790. TIDLPartialDefinitionList = Class(TIDLDefinitionList);
  791. function TWebIDLToPas.CloneNonPartialArgumentList(aList: TFPObjectlist;
  792. ADest: TFPObjectlist; AsPartial: Boolean): integer;
  793. Var
  794. I,J : Integer;
  795. CD : TIDLDefinition;
  796. DL,CL : TIDLDefinitionList;
  797. begin
  798. Result:=0;
  799. if ADest=Nil then
  800. ADest:=aList;
  801. I:=aList.Count-1;
  802. While (I>=0) do
  803. begin
  804. DL:=TIDLDefinitionList(alist[i]);
  805. if Not (DL is TIDLPartialDefinitionList) then
  806. begin
  807. Inc(Result);
  808. if AsPartial then
  809. CL:=TIDLPartialDefinitionList.Create(Nil,True)
  810. else
  811. CL:=TIDLDefinitionList.Create(Nil,True);
  812. aDest.Add(CL);
  813. For J:=0 to DL.Count-1 do
  814. begin
  815. CD:=(DL.Definitions[J] as TIDLArgumentDefinition).Clone(Nil);
  816. CL.Add(CD);
  817. AllocatePasName(CD);
  818. end;
  819. end;
  820. Dec(I);
  821. end;
  822. end;
  823. procedure TWebIDLToPas.AddArgumentToOverloads(aList: TFPObjectlist; AName,ATypeName : String);
  824. Var
  825. I : Integer;
  826. CD : TIDLArgumentDefinition;
  827. DL : TIDLDefinitionList;
  828. begin
  829. For I:=0 to aList.Count-1 do
  830. begin
  831. DL:=TIDLDefinitionList(alist[i]);
  832. if Not (DL is TIDLPartialDefinitionList) then
  833. begin
  834. CD:=TIDLArgumentDefinition.Create(Nil,aName);
  835. CD.ArgumentType:=TIDLTypeDefDefinition.Create(CD,'');
  836. CD.ArgumentType.TypeName:=aTypeName;
  837. DL.Add(CD);
  838. AllocatePasName(cd,'');
  839. end;
  840. end;
  841. end;
  842. procedure TWebIDLToPas.AddArgumentToOverloads(aList: TFPObjectlist; adef: TIDLArgumentDefinition);
  843. Var
  844. I : Integer;
  845. CD : TIDLDefinition;
  846. DL : TIDLDefinitionList;
  847. begin
  848. For I:=0 to aList.Count-1 do
  849. begin
  850. DL:=TIDLDefinitionList(alist[i]);
  851. if Not (DL is TIDLPartialDefinitionList) then
  852. begin
  853. CD:=aDef.Clone(Nil);
  854. DL.Add(CD);
  855. if aDef.Data<>Nil then
  856. CD.Data:=CreatePasName(TPasData(aDef.Data).PasName)
  857. else
  858. AllocatePasName(cd,'');
  859. end;
  860. end;
  861. end;
  862. procedure TWebIDLToPas.AddUnionOverloads(aList: TFPObjectlist; AName : String; UT : TIDLUnionTypeDefDefinition);
  863. Var
  864. L,L2 : TFPObjectList;
  865. I,J : Integer;
  866. D : TIDLDefinitionList;
  867. Dups : TStringList;
  868. begin
  869. L2:=Nil;
  870. Dups:=TStringList.Create;
  871. Dups.Sorted:=True;
  872. Dups.Duplicates:=dupIgnore;
  873. L:=TFPObjectList.Create(False);
  874. try
  875. L2:=TFPObjectList.Create(False);
  876. // Collect non partial argument lists
  877. for I:=0 to AList.Count-1 do
  878. begin
  879. D:=TIDLDefinitionList(alist[i]);
  880. if Not (D is TIDLPartialDefinitionList) then
  881. L.Add(D);
  882. end;
  883. // Collect unique pascal types. Note that this can reduce the list to 1 element...
  884. For I:=0 to UT.Union.Count-1 do
  885. Dups.AddObject(GetTypeName(UT.Union[I] as TIDLTypeDefDefinition),UT.Union[I]);
  886. // First, clone list and add argument to cloned lists
  887. For I:=1 to Dups.Count-1 do
  888. begin
  889. // Clone list
  890. CloneNonPartialArgumentList(L,L2,False);
  891. // Add argument to cloned list
  892. AddArgumentToOverloads(L2,aName,Dups[i]);
  893. // Add overloads to original list
  894. For J:=0 to L2.Count-1 do
  895. aList.Add(L2[J]);
  896. L2.Clear;
  897. end;
  898. // Add first Union to original list
  899. AddArgumentToOverloads(L,aName,Dups[0]);
  900. finally
  901. Dups.Free;
  902. L2.Free;
  903. L.Free;
  904. end;
  905. end;
  906. function TWebIDLToPas.CheckUnionTypeDefinition(D: TIDLDefinition
  907. ): TIDLUnionTypeDefDefinition;
  908. begin
  909. Result:=Nil;
  910. If (D is TIDLUnionTypeDefDefinition) then
  911. Result:=D as TIDLUnionTypeDefDefinition
  912. else
  913. begin
  914. D:=Context.FindDefinition((D as TIDLTypeDefDefinition).TypeName);
  915. if (D is TIDLUnionTypeDefDefinition) then
  916. Result:=D as TIDLUnionTypeDefDefinition
  917. end
  918. end;
  919. procedure TWebIDLToPas.AddOverloads(aList: TFPObjectlist;
  920. adef: TIDLFunctionDefinition; aIdx: Integer);
  921. Var
  922. Arg : TIDLArgumentDefinition;
  923. D : TIDLDefinition;
  924. UT : TIDLUnionTypeDefDefinition;
  925. begin
  926. if aIdx>=ADef.Arguments.Count then
  927. exit;
  928. Arg:=ADef.Argument[aIdx];
  929. if Arg.IsOptional then
  930. CloneNonPartialArgumentList(aList);
  931. // Add current to list.
  932. D:=Arg.ArgumentType;
  933. UT:=Nil;
  934. if coExpandUnionTypeArgs in Options then
  935. UT:=CheckUnionTypeDefinition(D);
  936. if UT=Nil then
  937. AddArgumentToOverloads(aList,Arg)
  938. else
  939. AddUnionOverLoads(aList,Arg.Name,UT);
  940. AddOverloads(aList,aDef,aIdx+1);
  941. end;
  942. function TWebIDLToPas.GetOverloads(aDef: TIDLFunctionDefinition): TFPObjectlist;
  943. begin
  944. Result:=TFPObjectList.Create;
  945. try
  946. Result.Add(TIDLDefinitionList.Create(Nil,True));
  947. AddOverloads(Result,adef,0);
  948. except
  949. Result.Free;
  950. Raise;
  951. end;
  952. end;
  953. function TWebIDLToPas.WriteFunctionTypeDefinition(aDef: TIDLFunctionDefinition): Boolean;
  954. Var
  955. FN,RT,Args : String;
  956. begin
  957. Result:=True;
  958. FN:=GetName(aDef);
  959. RT:=GetTypeName(aDef.ReturnType,False);
  960. if (RT='void') then
  961. RT:='';
  962. Args:=GetArguments(aDef.Arguments,False);
  963. if (RT='') then
  964. AddLn('%s = Procedure %s;',[FN,Args])
  965. else
  966. AddLn('%s = function %s: %s;',[FN,Args,RT])
  967. end;
  968. function TWebIDLToPas.WriteFunctionDefinition(aDef: TIDLFunctionDefinition): Boolean;
  969. Var
  970. FN,RT,Suff,Args : String;
  971. Overloads : TFPObjectList;
  972. I : Integer;
  973. begin
  974. Result:=True;
  975. if not (foConstructor in aDef.Options) then
  976. begin
  977. FN:=GetName(aDef);
  978. if FN<>aDef.Name then
  979. Suff:=Format('; external name ''%s''',[aDef.Name]);
  980. RT:=GetTypeName(aDef.ReturnType,False);
  981. if (RT='void') then
  982. RT:='';
  983. end
  984. else
  985. FN:='New';
  986. Overloads:=GetOverloads(ADef);
  987. try
  988. for I:=0 to aDef.Arguments.Count-1 do
  989. if aDef.Argument[i].HasEllipsis then
  990. Suff:='; varargs';
  991. if Overloads.Count>1 then
  992. Suff:=Suff+'; overload';
  993. For I:=0 to Overloads.Count-1 do
  994. begin
  995. Args:=GetArguments(TIDLDefinitionList(Overloads[i]),False);
  996. if (RT='') then
  997. begin
  998. if not (foConstructor in aDef.Options) then
  999. AddLn('Procedure %s%s%s;',[FN,Args,Suff])
  1000. else
  1001. AddLn('constructor %s%s%s;',[FN,Args,Suff]);
  1002. end
  1003. else
  1004. AddLn('function %s%s: %s%s;',[FN,Args,RT,Suff])
  1005. end;
  1006. finally
  1007. Overloads.Free;
  1008. end;
  1009. end;
  1010. function TWebIDLToPas.WriteCallBackDefs(aList: TIDLDefinitionList): Integer;
  1011. Var
  1012. D : TIDLDefinition;
  1013. FD : TIDLFunctionDefinition absolute D;
  1014. begin
  1015. Result:=0;
  1016. EnsureSection(csType);
  1017. for D in aList do
  1018. if D is TIDLFunctionDefinition then
  1019. if (foCallBack in FD.Options) then
  1020. if WriteFunctionTypeDefinition(FD) then
  1021. Inc(Result);
  1022. end;
  1023. function TWebIDLToPas.WriteDictionaryDefs(aList: TIDLDefinitionList): Integer;
  1024. Var
  1025. D : TIDLDefinition;
  1026. DD : TIDLDictionaryDefinition absolute D;
  1027. begin
  1028. Result:=0;
  1029. EnsureSection(csType);
  1030. for D in aList do
  1031. if D is TIDLDictionaryDefinition then
  1032. if not TIDLDictionaryDefinition(D).IsPartial then
  1033. if WriteDictionaryDef(DD) then
  1034. Inc(Result);
  1035. end;
  1036. function TWebIDLToPas.WriteInterfaceDefs(aList: TIDLDefinitionList): Integer;
  1037. Var
  1038. D : TIDLDefinition;
  1039. ID : TIDLInterfaceDefinition absolute D;
  1040. begin
  1041. Result:=0;
  1042. EnsureSection(csType);
  1043. for D in aList do
  1044. if D is TIDLInterfaceDefinition then
  1045. if not TIDLInterfaceDefinition(D).IsPartial then
  1046. if WriteInterfaceDef(ID) then
  1047. Inc(Result);
  1048. end;
  1049. procedure TWebIDLToPas.Getoptions(L : TStrings);
  1050. Var
  1051. S : String;
  1052. I : Integer;
  1053. begin
  1054. L.Add('Automatically generated file by '+ClassName+' on '+FormatDateTime('yyyy-mm-dd hh:nn:ss',Now));
  1055. L.Add('');
  1056. L.Add('Used command-line options : ');
  1057. For I:=1 to ParamCount do
  1058. L.Add(ParamStr(i));
  1059. L.Add('');
  1060. L.Add('Command-line options translate to: ');
  1061. L.Add('');
  1062. S:=SetToString(PtypeInfo(TypeInfo(TConversionOptions)),Integer(OPtions),True);
  1063. L.Add('Options : '+S);
  1064. L.Add('Keyword prefix : '+KeywordPrefix);
  1065. L.Add('Keyword suffix : '+KeywordSuffix);
  1066. L.Add('Class prefix : '+ClassPrefix);
  1067. L.Add('Class suffix : '+ClassSuffix);
  1068. L.Add('Field prefix : '+FieldPrefix);
  1069. Str(WebIDLversion,S);
  1070. L.Add('WEBIDLversion : '+S);
  1071. if TypeAliases.Count>0 then
  1072. begin
  1073. L.Add('Type aliases:');
  1074. L.AddStrings(Self.TypeAliases);
  1075. end;
  1076. end;
  1077. procedure TWebIDLToPas.AddOptionsToHeader;
  1078. Var
  1079. L : TStrings;
  1080. begin
  1081. L:=TStringList.Create;
  1082. try
  1083. GetOptions(L);
  1084. Comment(L);
  1085. finally
  1086. L.Free;
  1087. end;
  1088. end;
  1089. procedure TWebIDLToPas.WriteIncludeInterfaceCode;
  1090. Var
  1091. S : String;
  1092. begin
  1093. For S in IncludeInterfaceCode do
  1094. Addln(S);
  1095. end;
  1096. procedure TWebIDLToPas.WritePascal;
  1097. begin
  1098. CreateUnitClause;
  1099. CreateHeader;
  1100. if coaddOptionsToheader in Options then
  1101. AddOptionsToHeader;
  1102. EnsureSection(csType);
  1103. Indent;
  1104. WriteForwardClassDefs(Context.Definitions);
  1105. WriteEnumDefs(Context.Definitions);
  1106. WriteTypeDefs(Context.Definitions);
  1107. WriteCallbackDefs(Context.Definitions);
  1108. WriteDictionaryDefs(Context.Definitions);
  1109. WriteInterfaceDefs(Context.Definitions);
  1110. Undent;
  1111. WriteIncludeInterfaceCode;
  1112. Addln('');
  1113. AddLn('implementation');
  1114. WriteImplementation;
  1115. AddLn('end.');
  1116. Source.SaveToFile(OutputFileName);
  1117. end;
  1118. function TWebIDLToPas.BaseUnits: String;
  1119. begin
  1120. Result:='SysUtils, JS'
  1121. end;
  1122. function TWebIDLToPas.CreatePasName(aName: String): TPasData;
  1123. begin
  1124. Result:=TPasData.Create(EscapeKeyWord(aName));
  1125. FPasNameList.Add(Result);
  1126. end;
  1127. function TWebIDLToPas.AllocatePasName(D: TIDLDefinition; ParentName: String): TPasData;
  1128. Var
  1129. CN : String;
  1130. begin
  1131. if D Is TIDLInterfaceDefinition then
  1132. begin
  1133. CN:=ClassPrefix+D.Name+ClassSuffix;
  1134. Result:=CreatePasname(CN);
  1135. D.Data:=Result;
  1136. AllocatePasNames((D as TIDLInterfaceDefinition).members,D.Name);
  1137. end
  1138. else if D Is TIDLDictionaryDefinition then
  1139. begin
  1140. CN:=D.Name;
  1141. if coDictionaryAsClass in Options then
  1142. CN:=ClassPrefix+CN+ClassSuffix;
  1143. Result:=CreatePasname(EscapeKeyWord(CN));
  1144. D.Data:=Result;
  1145. AllocatePasNames((D as TIDLDictionaryDefinition).members,D.Name);
  1146. end
  1147. else
  1148. begin
  1149. Result:=CreatePasName(D.Name);
  1150. D.Data:=Result;
  1151. if D Is TIDLFunctionDefinition then
  1152. AllocatePasNames((D as TIDLFunctionDefinition).Arguments,D.Name);
  1153. end;
  1154. if Verbose and (TPasData(D.Data).PasName<>D.Name) then
  1155. begin
  1156. if (ParentName<>'') then
  1157. ParentName:=ParentName+'.';
  1158. DoLog('Renamed %s to %s',[ParentName+D.Name,TPasData(D.Data).PasName]);
  1159. end;
  1160. end;
  1161. procedure TWebIDLToPas.SetTypeAliases(AValue: TStrings);
  1162. begin
  1163. if FTypeAliases=AValue then Exit;
  1164. FTypeAliases.Assign(AValue);
  1165. end;
  1166. procedure TWebIDLToPas.SetIncludeInterfaceCode(AValue: TStrings);
  1167. begin
  1168. if FIncludeInterfaceCode=AValue then Exit;
  1169. FIncludeInterfaceCode.Assign(AValue);
  1170. end;
  1171. procedure TWebIDLToPas.SetIncludeImplementationCode(AValue: TStrings);
  1172. begin
  1173. if FIncludeImplementationCode=AValue then Exit;
  1174. FIncludeImplementationCode.Assign(AValue);
  1175. end;
  1176. procedure TWebIDLToPas.AllocatePasNames(aList : TIDLDefinitionList; ParentName: String = '');
  1177. var
  1178. D : TIDLDefinition;
  1179. begin
  1180. For D in aList do
  1181. AllocatePasName(D,ParentName);
  1182. end;
  1183. procedure TWebIDLToPas.ProcessDefinitions;
  1184. begin
  1185. FContext.AppendPartials;
  1186. FContext.AppendIncludes;
  1187. AllocatePasNames(FContext.Definitions);
  1188. end;
  1189. procedure TWebIDLToPas.Execute;
  1190. begin
  1191. FContext:=CreateContext;
  1192. try
  1193. FContext.Aliases:=Self.TypeAliases;
  1194. Parse;
  1195. if Verbose then
  1196. DoLog('Parsed %d definitions.',[Context.Definitions.Count]);
  1197. ProcessDefinitions;
  1198. WritePascal;
  1199. finally
  1200. FreeAndNil(FContext);
  1201. end;
  1202. end;
  1203. end.