webidltowasmjob.pp 78 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492
  1. {
  2. This file is part of the Free Component Library
  3. WEBIDL to pascal code converter
  4. Copyright (c) 2022 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. {$IFNDEF FPC_DOTTEDUNITS}
  12. unit webidltowasmjob;
  13. {$ENDIF FPC_DOTTEDUNITS}
  14. {$mode ObjFPC}{$H+}
  15. interface
  16. {$IFDEF FPC_DOTTEDUNITS}
  17. uses
  18. System.Classes, System.SysUtils, WebIdl.Defs, WebIdl.ToPascal, WebIdl.Scanner, WebIdl.Parser, System.Contnrs;
  19. {$ELSE FPC_DOTTEDUNITS}
  20. uses
  21. Classes, SysUtils, webidldefs, webidltopas, webidlscanner, webidlparser, Contnrs;
  22. {$ENDIF FPC_DOTTEDUNITS}
  23. {
  24. Todo:
  25. - Allocate Aliased types (TIDLUserTypeDefinition) and simple types (TIDLSimpleTypeDefinition) as TIDLTypeDefinition descendants.
  26. (so no more special cases are needed)
  27. - Allocate Interface names so no more pasintfname etc. is needed
  28. }
  29. type
  30. TJOB_JSValueKind = (
  31. jjvkUndefined,
  32. jjvkBoolean,
  33. jjvkDouble,
  34. jjvkString,
  35. jjvkObject,
  36. jivkMethod,
  37. jjvkDictionary,
  38. jjvkArray
  39. );
  40. TJOB_JSValueKinds = set of TJOB_JSValueKind;
  41. const
  42. JOB_JSValueKindNames: array[TJOB_JSValueKind] of TIDLString = (
  43. 'Undefined',
  44. 'Boolean',
  45. 'Double',
  46. 'TIDLString',
  47. 'Object',
  48. 'Method',
  49. 'Dictionary',
  50. 'Array'
  51. );
  52. JOB_JSValueTypeNames: array[TJOB_JSValueKind] of TIDLString = (
  53. 'TJOB_JSValue',
  54. 'TJOB_Boolean',
  55. 'TJOB_Double',
  56. 'TJOB_String',
  57. 'TJOB_Object',
  58. 'TJOB_Method',
  59. 'TJOB_Dictionary',
  60. 'TJOB_Array'
  61. );
  62. type
  63. TMethodCallInfo = record
  64. FuncName,
  65. ReturnTypeName,
  66. ResolvedReturnTypeName,
  67. InvokeName,
  68. InvokeClassName : TIDLString;
  69. ReturnDef : TIDLDefinition;
  70. ProcKind : String;
  71. end;
  72. TAccessorInfo = Record
  73. PropType : TIDLDefinition;
  74. NativeType: TPascalNativeType;
  75. NativeTypeName,
  76. ResolvedTypeName,
  77. CallBackName,
  78. FuncName: TIDLString;
  79. end;
  80. TPasDataWasmJob = class(TPasData)
  81. PropertyGetterName : String;
  82. PropertySetterName : String;
  83. end;
  84. { TWebIDLToPasWasmJob }
  85. TWebIDLToPasWasmJob = class(TBaseWebIDLToPas)
  86. private
  87. FPasInterfacePrefix: TIDLString;
  88. FPasInterfaceSuffix: TIDLString;
  89. FGeneratingInterface : Boolean;
  90. procedure AllocatePropertyGetterSetter(aParent: TIDLStructuredDefinition; aAttr: TIDLPropertyDefinition);
  91. procedure AllocatePropertyGetterSetters;
  92. function GetAccessorNames(Attr: TIDLPropertyDefinition; out aGetter, aSetter: TIDLString): Boolean;
  93. function GetArgName(d: TIDLDefinition): string;
  94. function GetFunctionSuffix(aDef: TIDLFunctionDefinition; Overloads: TFPObjectList): String;
  95. function ExtractAliasName(aTypeName: string): String;
  96. function ExtractAliasInvokeClass(aName: String): string;
  97. function ExtractAliasInvokeFunction(aName: String): string;
  98. function GetInvokeClassName(aMethodInfo : TMethodCallInfo; aDef: TIDLFunctionDefinition=nil): TIDLString;
  99. function GetInvokeClassName(aResultDef: TIDLDefinition; aName: TIDLString; aDef: TIDLFunctionDefinition=nil): TIDLString;
  100. function GetInvokeClassNameFromTypeAlias(aName: TIDLString; aDef: TIDLDefinition): TIDLString;
  101. function GetInvokeNameFromAliasName(const aTypeName: TIDLString; aType: TIDLDefinition): string;
  102. function GetInvokeNameFromNativeType(aNativeType: TPascalNativeType): String;
  103. function GetInvokeNameFromTypeName(const aTypeName: TIDLString; aType: TIDLDefinition): String;
  104. Procedure GetInvokeNameFromTypeName(var aInfo: TMethodCallInfo);
  105. function GetKnownArgumentGetter(aDef: TIDLTypeDefinition; ArgTypeName, ArgResolvedTypename: String): string;
  106. function GetKnownResultAllocator(aDef: TIDLTypeDefinition; ArgTypeName, ArgResolvedTypename: String): string;
  107. function GetNativeTypeHelperAllocatorName(aNativeType: TPascalNativeType): string;
  108. function GetNativeTypeHelperGetterName(aNativeType: TPascalNativeType): string;
  109. function OnlyConstants(D: TIDLStructuredDefinition): Boolean;
  110. Protected
  111. function BaseUnits: String; override;
  112. function DottedBaseUnits: String; override;
  113. function IsStub : Boolean; virtual;
  114. function IsKeyWord(const S: String): Boolean; override;
  115. // Auxiliary routines
  116. function DefaultForNativeType(aNativeType: TPascalNativeType; aReturnTypeName: String): String;
  117. function GetAliasPascalType(D: TIDLDefinition; out PascalTypeName : string): TPascalNativeType; override;
  118. function GetPasClassName(const aName: String): String; overload; override; // convert to PasInterfacePrefix+X+FPasInterfaceSuffix
  119. function IntfToPasClassName(const aName: TIDLString): TIDLString; virtual;
  120. function ComputeGUID(const Prefix: TIDLString; aList: TIDLDefinitionList): TIDLString; virtual;
  121. procedure GetOptions(L: TStrings; Full: boolean); override;
  122. function GetPascalTypeName(const aTypeName: String; ForTypeDef: Boolean=False): String; override;
  123. function GetPasIntfName(Intf: TIDLDefinition): TIDLString;
  124. function GetResolvedType(aDef: TIDLTypeDefDefinition; Out PascalNativeType : TPascalNativeType; out aTypeName, aResolvedTypename: String): TIDLTypeDefinition; overload; override;
  125. {$IF SIZEOF(CHAR)=1}
  126. function GetResolvedType(aDef: TIDLTypeDefDefinition; Out PascalNativeType : TPascalNativeType; out aTypeName, aResolvedTypename: TIDLString): TIDLDefinition; overload;
  127. {$ENDIF}
  128. function GetInterfaceDefHead(Intf: TIDLInterfaceDefinition): String; override;
  129. function GetNamespaceDefHead(aNamespace: TIDLNamespaceDefinition): String; override;
  130. function GetDictionaryDefHead(const CurClassName: String; Dict: TIDLDictionaryDefinition): String; override;
  131. function GetDictionaryClassHead(const CurClassName: String; Dict: TIDLDictionaryDefinition): String; virtual;
  132. function GetDictionaryIntfHead(const CurClassName: String; Dict: TIDLDictionaryDefinition): String; virtual;
  133. function WriteOtherImplicitTypes(Intf: TIDLStructuredDefinition; aMemberList: TIDLDefinitionList): Integer; override;
  134. // Code generation routines. Return the number of actually written defs.
  135. function WriteDictionaryPrivateFields(aParent: TIDLStructuredDefinition; aList: TIDLDefinitionList): Integer; virtual;
  136. function WriteGetters(aParent: TIDLStructuredDefinition; aList: TIDLDefinitionList): Integer; override;
  137. function WriteSetters(aParent: TIDLStructuredDefinition; aList: TIDLDefinitionList): Integer; override;
  138. function WriteProperties(aParent: TIDLDefinition; aList: TIDLDefinitionList): Integer; override;
  139. function WriteUtilityMethods(Intf: TIDLStructuredDefinition): Integer; override;
  140. // Maplike
  141. function WriteMapLikeProperties(aParent: TIDLDefinition; aMap: TIDLMapLikeDefinition): Integer; override;
  142. function WriteMapLikePrivateReadOnlyFields(aParent: TIDLDefinition; aMap: TIDLMapLikeDefinition): Integer; override;
  143. function WriteMapLikeGetters(aParent: TIDLStructuredDefinition; aMap: TIDLMapLikeDefinition): Integer; override;
  144. // Definitions. Return true if a definition was written.
  145. function WriteEnumDef(aDef: TIDLEnumDefinition): Boolean; override;
  146. function WriteDictionaryDef(aDict: TIDLDictionaryDefinition): Boolean; override;
  147. function WriteDictionaryField(aDict: TIDLDictionaryDefinition; aField: TIDLDictionaryMemberDefinition): Boolean; override;
  148. function WriteForwardClassDef(D: TIDLStructuredDefinition): Boolean; override;
  149. function WriteFunctionDefinition(aParent: TIDLStructuredDefinition; aDef: TIDLFunctionDefinition): Boolean; override;
  150. function WriteFunctionTypeDefinition(aDef: TIDLFunctionDefinition; aName : string = ''): Boolean; override;
  151. function WritePrivateGetter(aParent: TIDLStructuredDefinition; aProp: TIDLPropertyDefinition): boolean; virtual;
  152. function WritePrivateSetter(aParent: TIDLStructuredDefinition; aProp: TIDLPropertyDefinition): boolean; virtual;
  153. function WriteProperty(aParent: TIDLDefinition; aProp: TIDLPropertyDefinition): boolean; virtual;
  154. function WriteRecordDef(aDef: TIDLRecordDefinition): Boolean; override;
  155. procedure WriteSequenceDef(aDef: TIDLSequenceTypeDefDefinition); override;
  156. // Extra interface/Implementation code.
  157. function GetPrivateGetterInfo(aProp: TIDLPropertyDefinition; out aAccessInfo : TAccessorInfo): Boolean;
  158. function GetPrivateSetterInfo(aProp: TIDLPropertyDefinition; out aAccessInfo : TAccessorInfo): Boolean;
  159. function GetReadPropertyCall(aInfo : TAccessorInfo; aMemberName: String): string;
  160. function GetWritePropertyCall(aInfo : TAccessorInfo; aMemberName: String): string;
  161. function GetFunctionSignature(aDef: TIDLFunctionDefinition; aInfo: TMethodCallInfo; aSuffix: TIDLString; ArgDefList: TIDLDefinitionList; out ProcKind: TIDLString): String;
  162. function GetMethodInfo(aParent: TIDLStructuredDefinition; aDef: TIDLFunctionDefinition; out MethodInfo: TMethodCallInfo): Boolean;
  163. function AllocateAttributePasName(aParent : TIDLStructuredDefinition; D: TIDLAttributeDefinition; ParentName: String; Recurse: Boolean): TPasData; override;
  164. Procedure ProcessDefinitions; override;
  165. // Implementation writing
  166. procedure WriteImplementation; override;
  167. // Implementation, per type
  168. procedure WriteDefinitionImplementation(D: TIDLDefinition); override;
  169. procedure WriteDictionaryImplemention(aDef: TIDLDictionaryDefinition); virtual;
  170. procedure WriteEnumImplementation(aDef: TIDLEnumDefinition); virtual;
  171. procedure WriteInterfaceImplemention(aDef: TIDLInterfaceDefinition); virtual;
  172. procedure WriteNamespaceImplemention(aDef: TIDLNamespaceDefinition); virtual;
  173. procedure WriteTypeDefsAndCallbackImplementations(aList: TIDLDefinitionList); override;
  174. Procedure WriteFunctionTypeCallBackImplementation(aDef: TIDLCallBackDefinition);
  175. // Implementation, per member
  176. procedure WriteMethodImplementations(aDef: TIDLStructuredDefinition; ML: TIDLDefinitionList); virtual;
  177. Procedure WriteFunctionImplementation(aParent: TIDLStructuredDefinition; aDef: TIDLFunctionDefinition); virtual;
  178. Procedure WriteFunctionInvokeCodeStub(aParent: TIDLStructuredDefinition; aDef: TIDLFunctionDefinition; aInfo : TMethodCallInfo); virtual;
  179. procedure WritePrivateGetterImplementations(aDef: TIDLStructuredDefinition; ML: TIDLDefinitionList); virtual;
  180. procedure WritePrivateSetterImplementations(aDef: TIDLStructuredDefinition; ML: TIDLDefinitionList); virtual;
  181. procedure WriteUtilityMethodImplementations(aDef: TIDLStructuredDefinition; ML: TIDLDefinitionList);virtual;
  182. Procedure WritePrivateGetterImplementation(aParent: TIDLStructuredDefinition; aProp: TIDLPropertyDefinition); virtual;
  183. Procedure WritePrivateSetterImplementation(aParent: TIDLStructuredDefinition; aProp: TIDLPropertyDefinition);virtual;
  184. procedure WriteDictionaryConstructor(aDict: TIDLDictionaryDefinition); virtual;
  185. // MapLike
  186. procedure WriteMapLikePrivateSetterImplementation(aParent: TIDLStructuredDefinition; aMap: TIDLMapLikeDefinition); virtual;
  187. procedure WriteMapLikePrivateGetterImplementation(aParent: TIDLStructuredDefinition; aMap: TIDLMapLikeDefinition); virtual;
  188. procedure WriteMapLikeFunctionImplementations(aDef: TIDLStructuredDefinition; MD: TIDLMapLikeDefinition);
  189. procedure WriteMapLikeEntriesFunctionImplementation(aDef: TIDLStructuredDefinition; ML: TIDLMapLikeDefinition);virtual;
  190. procedure WriteMapLikeGetFunctionImplementation(aDef: TIDLStructuredDefinition; ML: TIDLMapLikeDefinition);virtual;
  191. procedure WriteMapLikeSetFunctionImplementation(aDef: TIDLStructuredDefinition; ML: TIDLMapLikeDefinition);virtual;
  192. procedure WriteMapLikeClearFunctionImplementation(aDef: TIDLStructuredDefinition; ML: TIDLMapLikeDefinition);virtual;
  193. procedure WriteMapLikeHasFunctionImplementation(aDef: TIDLStructuredDefinition; ML: TIDLMapLikeDefinition);virtual;
  194. procedure WriteMapLikeDeleteFunctionImplementation(aDef: TIDLStructuredDefinition; ML: TIDLMapLikeDefinition);virtual;
  195. procedure WriteMapLikeKeysFunctionImplementation(aDef: TIDLStructuredDefinition; ML: TIDLMapLikeDefinition);virtual;
  196. procedure WriteMapLikeValuesFunctionImplementation(aDef: TIDLStructuredDefinition; ML: TIDLMapLikeDefinition);virtual;
  197. procedure WriteNamespaceVars; override;
  198. procedure WriteGlobalVar(aDef : String); override;
  199. Public
  200. constructor Create(ThOwner: TComponent); override;
  201. function SplitGlobalVar(Line: TIDLString; out PasVarName, JSClassName, JOBRegisterName: TIDLString): boolean; virtual;
  202. Published
  203. Property BaseOptions;
  204. Property ClassPrefix;
  205. Property ClassSuffix;
  206. Property PasInterfacePrefix: TIDLString read FPasInterfacePrefix write FPasInterfacePrefix;
  207. Property PasInterfaceSuffix: TIDLString read FPasInterfaceSuffix write FPasInterfaceSuffix;
  208. Property DictionaryClassParent;
  209. Property FieldPrefix;
  210. Property GetterPrefix;
  211. Property SetterPrefix;
  212. Property IncludeImplementationCode;
  213. Property IncludeInterfaceCode;
  214. Property InputFileName;
  215. Property OutputFileName;
  216. Property TypeAliases;
  217. Property Verbose;
  218. Property WebIDLVersion;
  219. end;
  220. implementation
  221. { TWebIDLToPasWasmJob }
  222. function TWebIDLToPasWasmJob.BaseUnits: String;
  223. begin
  224. Result:='SysUtils, Job.JS';
  225. end;
  226. function TWebIDLToPasWasmJob.DottedBaseUnits: String;
  227. begin
  228. Result:='System.SysUtils, Wasm.Job.Js';
  229. end;
  230. function TWebIDLToPasWasmJob.IsStub: Boolean;
  231. begin
  232. Result:=False;
  233. end;
  234. function TWebIDLToPasWasmJob.IsKeyWord(const S: String): Boolean;
  235. begin
  236. Result:=inherited IsKeyWord(S);
  237. if not Result then
  238. Result:=SameText(s,'create');
  239. end;
  240. function TWebIDLToPasWasmJob.GetAliasPascalType(D: TIDLDefinition; out PascalTypeName: string): TPascalNativeType;
  241. var
  242. S : String;
  243. begin
  244. Result:=inherited GetAliasPascalType(D,PascalTypeName);
  245. if Result<>ntUnknown then
  246. exit;
  247. S:=LowerCase(PascalTypeName);
  248. if pos('array',S)>0 then
  249. Result:=ntArray
  250. else if pos(FPasInterfaceSuffix,S)=1 then
  251. Result:=ntObject
  252. else if pos('string',S)>0 then
  253. Result:=ntUnicodeString;
  254. end;
  255. function TWebIDLToPasWasmJob.GetPasClassName(const aName: String): String;
  256. begin
  257. Result:=aName;
  258. if (LeftStr(Result,length(ClassPrefix))=ClassPrefix)
  259. and (RightStr(Result,length(ClassSuffix))=ClassSuffix)
  260. then
  261. Result:=copy(Result,length(ClassPrefix)+1,length(Result)-length(ClassPrefix)-length(ClassSuffix));
  262. if Result='' then
  263. raise EConvertError.Create('[20220725184518]');
  264. if LeftStr(Result,length(PasInterfacePrefix)) <> PasInterfacePrefix then
  265. Result:=PasInterfacePrefix+Result;
  266. if RightStr(Result,length(PasInterfaceSuffix)) <> PasInterfaceSuffix then
  267. Result:=Result+PasInterfaceSuffix;
  268. end;
  269. function TWebIDLToPasWasmJob.IntfToPasClassName(const aName: TIDLString): TIDLString;
  270. begin
  271. Result:=aName;
  272. if (LeftStr(Result,length(PasInterfacePrefix))=PasInterfacePrefix)
  273. and (RightStr(Result,length(PasInterfaceSuffix))=PasInterfaceSuffix)
  274. then
  275. Result:=copy(Result,length(PasInterfacePrefix)+1,length(Result)-length(PasInterfacePrefix)-length(PasInterfaceSuffix));
  276. if Result='' then
  277. raise EConvertError.Create('[20220725184440] cannot convert interface name '+aName+' to class name');
  278. if LeftStr(Result,Length(ClassPrefix))<>ClassPrefix then
  279. Result:=ClassPrefix+Result+ClassSuffix;
  280. end;
  281. function TWebIDLToPasWasmJob.ComputeGUID(const Prefix: TIDLString;
  282. aList: TIDLDefinitionList): TIDLString;
  283. var
  284. List: TStringList;
  285. D: TIDLDefinition;
  286. Attr: TIDLAttributeDefinition;
  287. i, BytePos, BitPos, v: Integer;
  288. Bytes: array[0..15] of byte;
  289. GUIDSrc, aTypeName: TIDLString;
  290. begin
  291. List:=TStringList.Create;
  292. for D in aList do
  293. begin
  294. GUIDSrc:=D.Name;
  295. if GUIDSrc='' then continue;
  296. if D is TIDLAttributeDefinition then
  297. begin
  298. Attr:=TIDLAttributeDefinition(D);
  299. if Attr.AttributeType<>nil then
  300. aTypeName:=GetJSTypeName(Attr.AttributeType);
  301. GUIDSrc:=GUIDSrc+':'+aTypeName;
  302. end;
  303. List.Add(GUIDSrc);
  304. end;
  305. List.Sort;
  306. GUIDSrc:=Prefix+',';
  307. for i:=0 to List.Count-1 do
  308. GUIDSrc:=GUIDSrc+','+List[i];
  309. List.Free;
  310. BytePos:=0;
  311. BitPos:=0;
  312. {$IFDEF fpc}
  313. FillByte({%H-}Bytes[0],16,0);
  314. {$ENDIF}
  315. for i:=1 to length(GUIDSrc) do
  316. begin
  317. // read 16-bit
  318. v:=(Bytes[BytePos] shl 8)+Bytes[(BytePos+1) and 15];
  319. // change some bits
  320. v:=v+integer((ord(GUIDSrc[i]) shl (11-BitPos)));
  321. // write 16 bit
  322. Bytes[BytePos]:=(v shr 8) and $ff;
  323. Bytes[(BytePos+1) and 15]:=v and $ff;
  324. inc(BitPos,5);
  325. if BitPos>7 then
  326. begin
  327. dec(BitPos,8);
  328. BytePos:=(BytePos+1) and 15;
  329. end;
  330. end;
  331. // set version 3
  332. Bytes[6]:=(Bytes[6] and $f)+(3 shl 4);
  333. // set variant 2
  334. Bytes[8]:=(Bytes[8] and $3f)+(2 shl 6);
  335. Result:='{';
  336. for i:=0 to 3 do Result:=Result+HexStr(Bytes[i],2);
  337. Result:=Result+'-';
  338. for i:=4 to 5 do Result:=Result+HexStr(Bytes[i],2);
  339. Result:=Result+'-';
  340. for i:=6 to 7 do Result:=Result+HexStr(Bytes[i],2);
  341. Result:=Result+'-';
  342. for i:=8 to 9 do Result:=Result+HexStr(Bytes[i],2);
  343. Result:=Result+'-';
  344. for i:=10 to 15 do Result:=Result+HexStr(Bytes[i],2);
  345. Result:=Result+'}';
  346. end;
  347. procedure TWebIDLToPasWasmJob.GetOptions(L: TStrings; Full: boolean);
  348. begin
  349. inherited GetOptions(L, Full);
  350. end;
  351. function TWebIDLToPasWasmJob.GetPascalTypeName(const aTypeName: String; ForTypeDef: Boolean): String;
  352. begin
  353. Case aTypeName of
  354. 'union',
  355. 'any': Result:='Variant';
  356. 'void',
  357. 'undefined': Result:=aTypeName;
  358. else
  359. //writeln('TWebIDLToPasWasmJob.GetJSTypeName ',aTypeName,' ',Def<>nil);
  360. Result:=inherited GetPascalTypeName(aTypeName,ForTypeDef);
  361. if (Result=aTypeName)
  362. and (LeftStr(Result,length(PasInterfacePrefix))<>PasInterfacePrefix)
  363. and (RightStr(Result,length(PasInterfaceSuffix))<>PasInterfaceSuffix)
  364. then
  365. begin
  366. if Result='' then
  367. raise EConvertError.Create('[20220725184536]');
  368. Result:=PasInterfacePrefix+Result+PasInterfaceSuffix;
  369. end;
  370. end;
  371. end;
  372. function TWebIDLToPasWasmJob.GetPasIntfName(Intf: TIDLDefinition): TIDLString;
  373. begin
  374. Result:=GetPasName(Intf);
  375. if Result='' then
  376. raise EConvertError.Create('[20220725184653] missing name at '+GetDefPos(Intf));
  377. Result:=GetPasClassName(Result);
  378. end;
  379. {$IF SIZEOF(CHAR)=1}
  380. function TWebIDLToPasWasmJob.GetResolvedType(aDef: TIDLTypeDefDefinition; out PascalNativeType: TPascalNativeType; out aTypeName,
  381. aResolvedTypename: TIDLString): TIDLDefinition;
  382. Var
  383. TN,RTN : String;
  384. begin
  385. Result:=GetResolvedType(aDef,PascalNativeType,TN,RTN);
  386. aTypeName:=TN;
  387. aResolvedTypeName:=RTN;
  388. end;
  389. {$ENDIF}
  390. function TWebIDLToPasWasmJob.GetResolvedType(aDef: TIDLTypeDefDefinition; out PascalNativeType: TPascalNativeType; out aTypeName,
  391. aResolvedTypename: String): TIDLTypeDefinition;
  392. begin
  393. Result:=inherited GetResolvedType(aDef, PascalNativeType, aTypeName, aResolvedTypename);
  394. if Result is TIDLInterfaceDefinition then
  395. aTypeName:=GetPasIntfName(Result)
  396. else if Result is TIDLDictionaryDefinition then
  397. aTypeName:=GetPasIntfName(Result)
  398. else if Result is TIDLPromiseTypeDefDefinition then
  399. aTypeName:=PasInterfacePrefix+'Promise'+PasInterfaceSuffix;
  400. end;
  401. function TWebIDLToPasWasmJob.GetInterfaceDefHead(Intf: TIDLInterfaceDefinition
  402. ): String;
  403. var
  404. aParentName, aPasIntfName: TIDLString;
  405. begin
  406. Result:='class(';
  407. if Assigned(Intf.ParentInterface) then
  408. aParentName:=GetPasName(Intf.ParentInterface)
  409. else
  410. aParentName:=GetPascalTypeName(Intf.ParentName);
  411. if aParentName='' then
  412. aParentName:=ClassPrefix+'Object'+ClassSuffix;
  413. if aParentName<>'' then
  414. Result:=Result+aParentName;
  415. aPasIntfName:=GetPasIntfName(Intf);
  416. Result:=Result+','+aPasIntfName+')';
  417. end;
  418. function TWebIDLToPasWasmJob.GetNamespaceDefHead(aNamespace: TIDLNamespaceDefinition): String;
  419. var
  420. aPasIntfName: TIDLString;
  421. begin
  422. Result:='class('+ClassPrefix+'Object'+ClassSuffix;
  423. aPasIntfName:=GetPasIntfName(aNameSpace);
  424. Result:=Result+','+aPasIntfName+')';
  425. end;
  426. function TWebIDLToPasWasmJob.GetDictionaryIntfHead(const CurClassName: String; Dict: TIDLDictionaryDefinition): String;
  427. var
  428. CurParent: String;
  429. begin
  430. if CurClassName='' then ; // Silence compiler warning
  431. CurParent:='';
  432. if Assigned(Dict.ParentDictionary) then
  433. CurParent:= GetPasIntfName(Dict.ParentDictionary);
  434. if CurParent='' then
  435. CurParent:='IJSObject';
  436. Result:='Interface ('+CurParent+')';
  437. Result:=GetPasIntfName(Dict)+' = '+Result;
  438. end;
  439. function TWebIDLToPasWasmJob.GetDictionaryClassHead(const CurClassName: String; Dict: TIDLDictionaryDefinition): String;
  440. var
  441. CurParent: String;
  442. begin
  443. CurParent:='';
  444. if Assigned(Dict.ParentDictionary) then
  445. CurParent:=GetPasName(Dict.ParentDictionary);
  446. if CurParent='' then
  447. CurParent:='TJSObject';
  448. Result:='class('+CurParent+','+GetPasIntfName(Dict)+')';
  449. Result:=CurClassName+' = '+Result;
  450. end;
  451. function TWebIDLToPasWasmJob.GetDictionaryDefHead(const CurClassName: String; Dict: TIDLDictionaryDefinition): String;
  452. begin
  453. Result:='';
  454. if Dict<>nil then
  455. Result:=CurClassName+'Rec = record'
  456. end;
  457. function TWebIDLToPasWasmJob.WriteOtherImplicitTypes(Intf: TIDLStructuredDefinition; aMemberList: TIDLDefinitionList): Integer;
  458. var
  459. iIntf : TIDLInterfaceDefinition absolute Intf;
  460. dDict : TIDLDictionaryDefinition absolute Intf;
  461. aPasIntfName, Decl, ParentName: TIDLString;
  462. StructType : TStructuredDefinitionType;
  463. begin
  464. Result:=1;
  465. ParentName:='';
  466. // Pascal interface and ancestor
  467. aPasIntfName:=GetPasIntfName(Intf);
  468. StructType:=Intf.StructuredType;
  469. FGeneratingInterface:=True;
  470. try
  471. Decl:=aPasIntfName+' = interface';
  472. Case StructType of
  473. sdInterface:
  474. if Assigned(iIntf.ParentInterface) then
  475. ParentName:=GetPasIntfName(iIntf.ParentInterface as TIDLInterfaceDefinition)
  476. else
  477. ParentName:=GetPascalTypeName(Intf.ParentName);
  478. sdDictionary:
  479. if Assigned(dDict.ParentDictionary) then
  480. ParentName:=GetPasIntfName(dDict.ParentDictionary as TIDLDictionaryDefinition)
  481. else
  482. ParentName:=GetPascalTypeName(dDict.ParentName);
  483. else
  484. ParentName:='';
  485. end;
  486. if ParentName='' then
  487. ParentName:=PasInterfacePrefix+'Object'+PasInterfaceSuffix;
  488. if ParentName<>'' then
  489. Decl:=Decl+'('+ParentName+')';
  490. AddLn(Decl);
  491. Indent;
  492. // GUID
  493. AddLn('['''+ComputeGUID(Decl,aMemberList)+''']');
  494. // private members
  495. WriteGetters(Intf,aMemberList);
  496. WriteSetters(Intf,aMemberList);
  497. // public members
  498. if StructType<>sdDictionary then
  499. WriteMethodDefs(Intf,aMemberList);
  500. WriteProperties(Intf,aMemberList);
  501. Undent;
  502. AddLn('end;');
  503. AddLn('');
  504. finally
  505. FGeneratingInterface:=False;
  506. end;
  507. end;
  508. function TWebIDLToPasWasmJob.WriteDictionaryPrivateFields(aParent: TIDLStructuredDefinition; aList: TIDLDefinitionList): Integer;
  509. begin
  510. Result:=0;
  511. if Aparent=Nil then;
  512. if Alist=Nil then;
  513. // Do nothing, used in stub
  514. end;
  515. function TWebIDLToPasWasmJob.WriteGetters(aParent: TIDLStructuredDefinition;
  516. aList: TIDLDefinitionList): Integer;
  517. var
  518. D: TIDLDefinition;
  519. begin
  520. Result:=Inherited WriteGetters(aParent,aList);
  521. for D in aList do
  522. if D is TIDLPropertyDefinition then
  523. if ConvertDef(D) then
  524. if WritePrivateGetter(aParent,TIDLPropertyDefinition(D)) then
  525. inc(Result);
  526. end;
  527. function TWebIDLToPasWasmJob.WriteSetters(
  528. aParent: TIDLStructuredDefinition; aList: TIDLDefinitionList): Integer;
  529. var
  530. D: TIDLDefinition;
  531. begin
  532. Result:=Inherited WriteSetters(aParent,aList);
  533. for D in aList do
  534. if D is TIDLPropertyDefinition then
  535. if ConvertDef(D) then
  536. if WritePrivateSetter(aParent,TIDLPropertyDefinition(D)) then
  537. inc(Result);
  538. end;
  539. function TWebIDLToPasWasmJob.WriteProperties(aParent: TIDLDefinition;
  540. aList: TIDLDefinitionList): Integer;
  541. var
  542. D: TIDLDefinition;
  543. begin
  544. Result:=Inherited WriteProperties(aParent,aList);
  545. Result:=0;
  546. for D in aList do
  547. if D is TIDLPropertyDefinition then
  548. if ConvertDef(D) then
  549. if WriteProperty(aParent,TIDLPropertyDefinition(D)) then
  550. inc(Result);
  551. end;
  552. function TWebIDLToPasWasmJob.WriteUtilityMethods(Intf: TIDLStructuredDefinition
  553. ): Integer;
  554. var
  555. CurrClassName,aPasIntfName: TIDLString;
  556. begin
  557. Result:=0;
  558. aPasIntfName:=GetPasIntfName(Intf);
  559. if Intf is TIDLDictionaryDefinition then
  560. begin
  561. CurrClassName:=GetPasName(TIDLDictionaryDefinition(Intf));
  562. AddLn('constructor create(const aDict : '+CurrClassName+'Rec); overload;');
  563. end;
  564. AddLn('class function JSClassName: UnicodeString; override;');
  565. AddLn('class function Cast(const Intf: IJSObject): '+aPasIntfName+';');
  566. end;
  567. function TWebIDLToPasWasmJob.WriteMapLikeProperties(aParent: TIDLDefinition; aMap: TIDLMapLikeDefinition): Integer;
  568. begin
  569. if (aParent=Nil) and (aMap=Nil) then ; // Silence compiler warning
  570. AddLn('property size : LongInt read _Getsize;');
  571. Result:=1;
  572. end;
  573. function TWebIDLToPasWasmJob.WriteMapLikePrivateReadOnlyFields(aParent: TIDLDefinition; aMap: TIDLMapLikeDefinition): Integer;
  574. begin
  575. if (aParent=Nil) and (aMap=Nil) then ; // Silence compiler warning
  576. Result:=0;
  577. end;
  578. function TWebIDLToPasWasmJob.WriteMapLikeGetters(aParent: TIDLStructuredDefinition; aMap: TIDLMapLikeDefinition): Integer;
  579. begin
  580. if (aParent=Nil) and (aMap=Nil) then ; // Silence compiler warning
  581. Result:=1;
  582. AddLn('function _Getsize : LongInt;');
  583. end;
  584. function TWebIDLToPasWasmJob.WriteEnumDef(aDef: TIDLEnumDefinition): Boolean;
  585. begin
  586. Result:=True;
  587. AddLn(GetPasName(aDef)+' = UnicodeString;');
  588. end;
  589. function TWebIDLToPasWasmJob.WriteDictionaryDef(aDict: TIDLDictionaryDefinition): Boolean;
  590. Var
  591. CurClassName, Decl: String;
  592. DefList: TIDLDefinitionList;
  593. begin
  594. // Write record;
  595. Result:=inherited WriteDictionaryDef(aDict);
  596. AddLn('');
  597. DefList:=GetFullMemberList(aDict);
  598. WriteOtherImplicitTypes(aDict,DefList);
  599. CurClassName:=GetPasName(aDict);
  600. // class and ancestor
  601. Decl:=GetDictionaryClassHead(CurClassName,aDict);
  602. AddLn(Decl);
  603. AddLn('Private');
  604. Indent;
  605. WriteDictionaryPrivateFields(aDict,DefList);
  606. if not (coPrivateMethods in BaseOptions) then
  607. begin
  608. Undent;
  609. AddLn('Protected');
  610. Indent;
  611. end;
  612. WriteGetters(aDict,DefList);
  613. WriteSetters(aDict,DefList);
  614. Undent;
  615. AddLn('Public');
  616. Indent;
  617. WriteUtilityMethods(aDict);
  618. WriteProperties(aDict,DefList);
  619. Undent;
  620. AddLn('end;');
  621. end;
  622. function TWebIDLToPasWasmJob.WriteDictionaryField(aDict: TIDLDictionaryDefinition; aField: TIDLDictionaryMemberDefinition): Boolean;
  623. var
  624. aDef, N, TN: TIDLString;
  625. begin
  626. if (aDict=Nil) then ; // Silence compiler warning
  627. Result:=True;
  628. N:=GetPasName(aField);
  629. TN:=GetPasName(aField.MemberType);
  630. if SameText(N,TN) then
  631. N:='_'+N;
  632. aDef:=N+': '+TN+';';
  633. if aField.IsRequired then
  634. aDef:=aDef+' // required';
  635. AddLn(aDef);
  636. end;
  637. function TWebIDLToPasWasmJob.WriteForwardClassDef(D: TIDLStructuredDefinition
  638. ): Boolean;
  639. begin
  640. if D.IsPartial then
  641. exit;
  642. if D is TIDLDictionaryDefinition then
  643. begin
  644. AddLn(GetPasIntfName(D)+' = interface;');
  645. Result:=inherited WriteForwardClassDef(D);
  646. end
  647. else
  648. begin
  649. if ((D is TIDLInterfaceDefinition) or (D is TIDLNamespaceDefinition)) then
  650. AddLn(GetPasIntfName(D)+' = interface;');
  651. Result:=inherited WriteForwardClassDef(D);
  652. end;
  653. end;
  654. function TWebIDLToPasWasmJob.GetInvokeNameFromAliasName(const aTypeName : TIDLString; aType : TIDLDefinition) : string;
  655. // Heuristic to determine what the base type of an aliased type is.
  656. var
  657. aLower : String;
  658. begin
  659. if aType=nil then ; // Silence compiler warning;
  660. Result:=ExtractAliasInvokeFunction(aTypeName);
  661. if Result<>'' then
  662. exit;
  663. aLower:=LowerCase(aTypeName);
  664. if Pos('bool',aLower)>0 then
  665. Result:='InvokeJSBooleanResult'
  666. else if Pos('array',aLower)>0 then
  667. Result:='InvokeJSObjectResult'
  668. else if Pos('string',aLower)>0 then
  669. Result:='InvokeJSUnicodeStringResult'
  670. else if Pos(LowerCase(PasInterfacePrefix),aLower)=1 then
  671. Result:='InvokeJSObjectResult'
  672. else
  673. Result:='';
  674. end;
  675. function TWebIDLToPasWasmJob.GetInvokeNameFromNativeType(aNativeType : TPascalNativeType) : String;
  676. begin
  677. case aNativeType of
  678. ntBoolean : Result:='InvokeJSBooleanResult';
  679. ntShortInt,
  680. ntByte,
  681. ntSmallInt,
  682. ntWord,
  683. ntCardinal,
  684. ntLongint: Result:='InvokeJSLongIntResult';
  685. ntInt64,
  686. ntQWord : Result:='InvokeJSMaxIntResult';
  687. ntSingle,
  688. ntDouble : Result:='InvokeJSDoubleResult';
  689. ntUTF8String : Result:='InvokeJSUTF8StringResult';
  690. ntUnicodeString : Result:='InvokeJSUnicodeStringResult';
  691. ntVariant: Result:='InvokeJSVariantResult';
  692. ntNone: Result:='InvokeJSNoResult';
  693. else
  694. Result:='';
  695. end;
  696. end;
  697. procedure TWebIDLToPasWasmJob.GetInvokeNameFromTypeName(var aInfo: TMethodCallInfo);
  698. begin
  699. aInfo.InvokeName:=GetInvokeNameFromTypeName(aInfo.ResolvedReturnTypeName,aInfo.ReturnDef);
  700. end;
  701. function TWebIDLToPasWasmJob.GetInvokeNameFromTypeName(const aTypeName : TIDLString; aType : TIDLDefinition): String;
  702. var
  703. aPascaltypeName : String;
  704. NT : TPascalNativeType;
  705. begin
  706. NT:=GetPasNativeTypeAndName(aType,aPascaltypeName);
  707. Result:=GetInvokeNameFromNativeType(NT);
  708. if Result<>'' then
  709. Exit;
  710. if (aPascalTypeName='TJOB_JSValue') then
  711. Result:='InvokeJSValueResult'
  712. else if (aTypeName='undefined') then
  713. Result:='InvokeJSNoResult'
  714. else if (aType is TIDLTypeDefDefinition) then
  715. begin
  716. if (TypeAliases.IndexOfName(aTypeName)<>-1) then
  717. Result:=GetInvokeNameFromAliasName(aTypeName,aType);
  718. if (Result='') and (TypeAliases.IndexOfName((aType as TIDLTypeDefDefinition).TypeName)<>-1) then
  719. Result:=GetInvokeNameFromAliasName((aType as TIDLTypeDefDefinition).TypeName,aType);
  720. if (Result='') and (TypeAliases.IndexOfName(GetPasName(aType))<>-1) then
  721. Result:=GetInvokeNameFromAliasName(GetPasName(aType),aType)
  722. else if Result='' then
  723. Result:='InvokeJSObjectResult';
  724. if Result='' then
  725. Raise EConvertError.CreateFmt('Unable to determine invoke name from alias type %s',[aTypeName]);
  726. end
  727. else if aType is TIDLEnumDefinition then
  728. Result:='InvokeJSUnicodeStringResult'
  729. else
  730. Result:='InvokeJSObjectResult';
  731. end;
  732. function TWebIDLToPasWasmJob.ExtractAliasInvokeClass(aName :String) : string;
  733. // Alias is encoded as:
  734. // aType=aAlias[,InvokeClass[:InvokeFunctionName]]
  735. var
  736. P : Integer;
  737. begin
  738. Result:=TypeAliases.Values[aName];
  739. P:=Pos(',',Result);
  740. if P>0 then
  741. begin
  742. Result:=Copy(Result,P+1);
  743. P:=Pos(':',Result);
  744. if P>0 then
  745. Result:=Copy(Result,1,P-1);
  746. end
  747. else
  748. // if it is an interface, we can simply assume the class is the same but with IJS -> TJS
  749. if (LeftStr(Result,length(PasInterfacePrefix))=PasInterfacePrefix) then
  750. Result:=IntfToPasClassName(Result)
  751. else
  752. Result:='';
  753. end;
  754. function TWebIDLToPasWasmJob.ExtractAliasInvokeFunction(aName: String): string;
  755. // Alias is encoded as:
  756. // aType=aAlias[,InvokeClass[:InvokeFunctionName]]
  757. var
  758. P : Integer;
  759. begin
  760. Result:=TypeAliases.Values[aName];
  761. P:=Pos(',',Result);
  762. if P>0 then
  763. begin
  764. Result:=Copy(Result,P+1);
  765. P:=Pos(':',Result);
  766. if P>0 then
  767. Result:=Copy(Result,P+1);
  768. end
  769. else
  770. // if it is an interface, we can simply assume 'InvokeJSObjectResult'
  771. if (LeftStr(Result,length(PasInterfacePrefix))=PasInterfacePrefix) then
  772. Result:='InvokeJSObjectResult'
  773. else
  774. Result:='';
  775. end;
  776. function TWebIDLToPasWasmJob.GetInvokeClassNameFromTypeAlias(aName : TIDLString; aDef : TIDLDefinition): TIDLString;
  777. // Heuristic to determine what the base type of an aliased type is.
  778. var
  779. aLower : String;
  780. begin
  781. if aDef<>Nil then ; // Silence compiler warning
  782. Result:=ExtractAliasInvokeClass(aName);
  783. if Result<>'' then
  784. exit;
  785. aLower:=LowerCase(aName);
  786. if Pos('array',aLower)>0 then
  787. Result:='TJSArray'
  788. else if Pos(PasInterfacePrefix,aLower)=1 then
  789. Result:='TJSObject'
  790. else
  791. Result:='';
  792. end;
  793. function TWebIDLToPasWasmJob.GetInvokeClassName(aMethodInfo: TMethodCallInfo; aDef: TIDLFunctionDefinition): TIDLString;
  794. begin
  795. Result:=GetInvokeClassName(aMethodInfo.ReturnDef,aMethodInfo.ResolvedReturnTypeName,aDef);
  796. end;
  797. function TWebIDLToPasWasmJob.GetInvokeClassName(aResultDef: TIDLDefinition; aName: TIDLString; aDef: TIDLFunctionDefinition=nil): TIDLString;
  798. Procedure UnsupportedReturnType;
  799. var
  800. Msg : string;
  801. begin
  802. Msg:=GetPasName(aDef);
  803. Msg:='[20220725172242] not yet supported: function "'+Msg+'" return type: '+aName;
  804. if assigned(aDef) then
  805. Msg:=Msg+' at '+GetDefPos(aDef);
  806. raise EConvertError.Create(Msg);
  807. end;
  808. var
  809. aTypeName : String;
  810. sDef : TIDLDefinition;
  811. begin
  812. Result:='';
  813. if aResultDef is TIDLSequenceTypeDefDefinition then
  814. Result:=ClassPrefix+'Array'+ClassSuffix
  815. else if aResultDef is TIDLPromiseTypeDefDefinition then
  816. Result:=ClassPrefix+'Promise'+ClassSuffix
  817. else if aResultDef is TIDLInterfaceDefinition then
  818. Result:=GetPasName(aResultDef)
  819. else if aResultDef is TIDLDictionaryDefinition then
  820. Result:=GetPasName(aResultDef)
  821. else if aName=PasInterfacePrefix+'Object'+PasInterfaceSuffix then
  822. begin
  823. Result:=ClassPrefix+'Object'+ClassSuffix;
  824. end
  825. else if aResultDef is TIDLTypeDefDefinition then
  826. begin
  827. aTypeName:=GetJSTypeName(TIDLTypeDefDefinition(aResultDef));
  828. sDef:=FindGlobalDef(aTypeName);
  829. if assigned(sDef) then
  830. Result:=GetPasName(sDef)
  831. else
  832. begin
  833. if TypeAliases.IndexOfName(aTypeName)=-1 then
  834. UnsupportedReturnType
  835. else
  836. Result:=GetInvokeClassNameFromTypeAlias(aTypeName,aResultDef);
  837. end;
  838. end
  839. else
  840. UnsupportedReturnType
  841. end;
  842. function TWebIDLToPasWasmJob.GetMethodInfo(aParent: TIDLStructuredDefinition; aDef: TIDLFunctionDefinition; out MethodInfo : TMethodCallInfo): Boolean;
  843. var
  844. RNT : TPascalNativeType;
  845. begin
  846. if (aParent=Nil) then ; // Silence compiler warning
  847. Result:=True;
  848. MethodInfo.ReturnDef:=GetResolvedType(aDef.ReturnType,RNT,MethodInfo.ReturnTypeName,MethodInfo.ResolvedReturnTypeName);
  849. MethodInfo.InvokeName:='';
  850. MethodInfo.InvokeClassName:='';
  851. if (foConstructor in aDef.Options) then
  852. begin
  853. MethodInfo.FuncName:='New';
  854. MethodInfo.InvokeName:= 'JOBCreate';
  855. MethodInfo.ResolvedReturnTypeName:='';
  856. MethodInfo.ReturnTypeName:='';
  857. MethodInfo.InvokeClassName:='';
  858. MethodInfo.ReturnDef:=Nil;
  859. end
  860. else
  861. begin
  862. MethodInfo.FuncName:=GetPasName(aDef);
  863. GetInvokeNameFromTypeName(MethodInfo);
  864. case MethodInfo.InvokeName of
  865. 'InvokeJSNoResult' :
  866. begin
  867. MethodInfo.ReturnTypeName:='';
  868. MethodInfo.ResolvedReturnTypeName:='';
  869. end;
  870. 'InvokeJSObjectResult':
  871. MethodInfo.InvokeClassName:=GetInvokeClassName(MethodInfo,aDef);
  872. else
  873. ;
  874. end;
  875. end;
  876. end;
  877. function TWebIDLToPasWasmJob.AllocateAttributePasName(aParent: TIDLStructuredDefinition; D: TIDLAttributeDefinition;
  878. ParentName: String; Recurse: Boolean): TPasData;
  879. begin
  880. Result:=inherited AllocateAttributePasName(aParent, D, ParentName, Recurse);
  881. end;
  882. procedure TWebIDLToPasWasmJob.AllocatePropertyGetterSetter(aParent : TIDLStructuredDefinition; aAttr : TIDLPropertyDefinition);
  883. var
  884. Full : TIDLDefinitionList;
  885. aDef : TIDLDefinition;
  886. aCount : integer;
  887. DJob : TPasDataWasmJob;
  888. BaseName : string;
  889. begin
  890. if not (aAttr.Data is TPasDataWasmJob) then
  891. Raise EWebIDLError.CreateFmt('No data assigned for attribute %s of %s',[aAttr.Name,aParent.Name]);
  892. DJob:=TPasDataWasmJob(aAttr.Data);
  893. Full:=GetParentsMemberList(aParent);
  894. aCount:=1;
  895. BaseName:=GetPasName(aAttr);
  896. For aDef in Full do
  897. if (aDef is TIDLAttributeDefinition) and ConvertDef(aDef) then
  898. if (aAttr<>aDef) and (BaseName=GetPasName(aDef)) then
  899. inc(aCount);
  900. if aCount>1 then
  901. BaseName:=BaseName+IntToStr(aCount);
  902. DJob.PropertyGetterName:=GetterPrefix+BaseName;
  903. DJob.PropertySetterName:=SetterPrefix+BaseName;
  904. end;
  905. procedure TWebIDLToPasWasmJob.AllocatePropertyGetterSetters;
  906. var
  907. D,MD : TIDLDefinition;
  908. SD : TIDLStructuredDefinition absolute D;
  909. AD : TIDLPropertyDefinition absolute MD;
  910. begin
  911. DoLog('Allocating property getters and setters');
  912. For D in Context.Definitions do
  913. if D is TIDLStructuredDefinition then
  914. For MD in GetFullMemberList(SD) do
  915. if MD is TIDLPropertyDefinition then
  916. AllocatePropertyGetterSetter(SD,AD);
  917. DoLog('Done allocating property getters and setters');
  918. end;
  919. procedure TWebIDLToPasWasmJob.ProcessDefinitions;
  920. begin
  921. Inherited ProcessDefinitions;
  922. AllocatePropertyGetterSetters;
  923. end;
  924. function TWebIDLToPasWasmJob.GetFunctionSignature(aDef: TIDLFunctionDefinition; aInfo : TMethodCallInfo; aSuffix: TIDLString; ArgDefList: TIDLDefinitionList; out ProcKind: TIDLString): String;
  925. var
  926. Args : String;
  927. begin
  928. Result:='';
  929. Args:=GetArguments(ArgDefList,False);
  930. if (foConstructor in aDef.Options) then
  931. begin
  932. ProcKind:='constructor';
  933. Result:='Create'+Args;
  934. end
  935. else if (aInfo.ReturnTypeName='') then
  936. begin
  937. ProcKind:='procedure';
  938. Result:=aInfo.FuncName+Args;
  939. end
  940. else
  941. begin
  942. ProcKind:='function';
  943. Result:=aInfo.FuncName+Args+': '+aInfo.ReturnTypeName;
  944. end;
  945. Result:=Result+aSuffix+';';
  946. if aInfo.ReturnDef is TIDLPromiseTypeDefDefinition then
  947. Result:=Result+' // Promise<'+TIDLPromiseTypeDefDefinition(aInfo.ReturnDef).ReturnType.TypeName+'>';
  948. end;
  949. function TWebIDLToPasWasmJob.GetArgName(d : TIDLDefinition) : string;
  950. begin
  951. Result:=GetPasName(d);
  952. if IsKeyWord(Result) then
  953. Result:=Result+'_';
  954. end;
  955. procedure TWebIDLToPasWasmJob.WriteFunctionImplementation(aParent: TIDLStructuredDefinition; aDef: TIDLFunctionDefinition);
  956. var
  957. ArgNames: TStringList;
  958. function CreateLocal(aName: TIDLString): TIDLString;
  959. var
  960. i: Integer;
  961. begin
  962. Result:=aName;
  963. if ArgNames.IndexOf(Result)>=0 then
  964. begin
  965. i:=2;
  966. while ArgNames.IndexOf(Result+IntToStr(i))>=0 do inc(i);
  967. Result:=Result+IntToStr(i);
  968. end;
  969. ArgNames.Add(Result);
  970. end;
  971. Var
  972. Data: TPasDataWasmJob;
  973. MethodInfo : TMethodCallInfo;
  974. Suff, Args, ProcKind, Sig, aClassName,
  975. InvokeCode, LocalName, WrapperFn,
  976. ArgName, ArgTypeName,ArgResolvedTypeName: TIDLString;
  977. Overloads: TFPObjectList;
  978. I: Integer;
  979. ArgDefList: TIDLDefinitionList;
  980. CurDef, ArgType : TIDLDefinition;
  981. ArgDef: TIDLArgumentDefinition absolute CurDef;
  982. FinallyCode, TryCode,VarSection : Array of string;
  983. ANT : TPascalNativeType;
  984. begin
  985. Data:=aDef.Data as TPasDataWasmJob;
  986. if Data.PasName='' then
  987. begin
  988. DoLog('Note: skipping Getter of '+aDef.Parent.Name+' at '+GetDefPos(aDef));
  989. exit;
  990. end;
  991. Suff:='';
  992. GetMethodInfo(aParent,aDef,MethodInfo);
  993. aClassName:=GetPasName(aParent);
  994. Overloads:=GetOverloads(ADef);
  995. try
  996. Suff:=GetFunctionSuffix(aDef,Overloads);
  997. For I:=0 to Overloads.Count-1 do
  998. begin
  999. ArgDefList:=TIDLDefinitionList(Overloads[i]);
  1000. Sig:=GetFunctionSignature(aDef,MethodInfo,Suff,ArgDefList,ProcKind);
  1001. ArgNames:=TStringList.Create;
  1002. try
  1003. for CurDef in ArgDefList do
  1004. ArgNames.Add(GetArgName(ArgDef));
  1005. AddLn(ProcKind+' '+aClassName+'.'+Sig);
  1006. InvokeCode:='';
  1007. if MethodInfo.ReturnTypeName<>'' then
  1008. InvokeCode:='Result:=';
  1009. VarSection:=[];
  1010. TryCode:=[];
  1011. FinallyCode:=[];
  1012. Args:='';
  1013. for CurDef in ArgDefList do
  1014. begin
  1015. if Args<>'' then
  1016. Args:=Args+',';
  1017. ArgName:=GetArgName(ArgDef);
  1018. ArgType:=GetResolvedType(ArgDef.ArgumentType,ANT,ArgTypeName,ArgResolvedTypeName);
  1019. if (ArgType is TIDLCallbackDefinition) then
  1020. begin
  1021. if not (Assigned(TIDLCallbackDefinition(ArgType).FunctionDef)) then
  1022. Raise EWebIDLParser.Create('[20220725181726] callback definition in '+GetPasName(aDef)+'without function signature type '+GetDefPos(ArgType));
  1023. LocalName:=CreateLocal('m');
  1024. VarSection:=Concat(VarSection,[ (LocalName+': '+JOB_JSValueTypeNames[jivkMethod]+';')]);
  1025. WrapperFn:='JOBCall'+GetPasName(TIDLCallbackDefinition(ArgType).FunctionDef);
  1026. TryCode:=Concat(TryCode,[LocalName+':='+JOB_JSValueTypeNames[jivkMethod]+'.Create(TMethod('+ArgName+'),@'+WrapperFn+');']);
  1027. FinallyCode:=Concat(FinallyCode,[LocalName+'.free;']);
  1028. ArgName:=LocalName;
  1029. end;
  1030. Args:=Args+ArgName;
  1031. end;
  1032. if foConstructor in aDef.Options then
  1033. InvokeCode:=InvokeCode+MethodInfo.InvokeName+'(['+Args+'])'
  1034. else
  1035. begin
  1036. Args:=',['+Args+']';
  1037. InvokeCode:=InvokeCode+MethodInfo.InvokeName+'('''+aDef.Name+''''+Args;
  1038. if MethodInfo.InvokeClassName<>'' then
  1039. InvokeCode:=InvokeCode+','+MethodInfo.InvokeClassName+') as '+MethodInfo.ReturnTypeName
  1040. else
  1041. InvokeCode:=InvokeCode+')';
  1042. end;
  1043. if Length(VarSection)>0 then
  1044. begin
  1045. AddLn('var');
  1046. Indent;
  1047. AddLn(VarSection);
  1048. undent;
  1049. end;
  1050. AddLn('begin');
  1051. Indent;
  1052. if IsStub then
  1053. WriteFunctionInvokeCodeStub(aParent,aDef,MethodInfo)
  1054. else
  1055. begin
  1056. if Length(TryCode)=0 then
  1057. AddLn(InvokeCode+';')
  1058. else
  1059. begin
  1060. AddLn(TryCode);
  1061. AddLn('try');
  1062. Indent;
  1063. AddLn(InvokeCode+';');
  1064. Undent;
  1065. AddLn('finally');
  1066. Indent;
  1067. AddLn(FinallyCode);
  1068. Undent;
  1069. AddLn('end;');
  1070. end;
  1071. end;
  1072. Undent;
  1073. AddLn('end;');
  1074. AddLn('');
  1075. finally
  1076. ArgNames.Free;
  1077. end;
  1078. end;
  1079. finally
  1080. Overloads.Free;
  1081. end;
  1082. end;
  1083. procedure TWebIDLToPasWasmJob.WriteFunctionInvokeCodeStub(aParent: TIDLStructuredDefinition; aDef: TIDLFunctionDefinition; aInfo : TMethodCallInfo);
  1084. begin
  1085. //
  1086. end;
  1087. function TWebIDLToPasWasmJob.GetFunctionSuffix(aDef: TIDLFunctionDefinition; Overloads : TFPObjectList): String;
  1088. begin
  1089. Result:='';
  1090. if (aDef.Arguments.Count>0)
  1091. and aDef.Argument[aDef.Arguments.Count-1].HasEllipsis then
  1092. Result:='{; ToDo:varargs}';
  1093. if not (FGeneratingInterface or GeneratingImplementation) then
  1094. Result:=Result+'; overload';
  1095. end;
  1096. function TWebIDLToPasWasmJob.WriteFunctionDefinition(aParent: TIDLStructuredDefinition; aDef: TIDLFunctionDefinition): Boolean;
  1097. Var
  1098. Data: TPasDataWasmJob;
  1099. Suff, ProcKind, Sig : TIDLString;
  1100. Overloads: TFPObjectList;
  1101. I: Integer;
  1102. ArgDefList: TIDLDefinitionList;
  1103. MethodInfo : TMethodCallInfo;
  1104. begin
  1105. Result:=True;
  1106. Data:=aDef.Data as TPasDataWasmJob;
  1107. if Data.PasName='' then
  1108. begin
  1109. DoLog('Note: skipping Getter of '+aDef.Parent.Name+' at '+GetDefPos(aDef));
  1110. exit(false);
  1111. end;
  1112. if FGeneratingInterface and (([foConstructor, foStatic] * aDef.Options)<>[]) then
  1113. exit;
  1114. Suff:='';
  1115. GetMethodInfo(aParent,aDef,MethodInfo);
  1116. Overloads:=GetOverloads(ADef);
  1117. try
  1118. Suff:=GetFunctionSuffix(aDef,Overloads);
  1119. For I:=0 to Overloads.Count-1 do
  1120. begin
  1121. ArgDefList:=TIDLDefinitionList(Overloads[i]);
  1122. Sig:=GetFunctionSignature(aDef,MethodInfo,Suff,ArgDefList,ProcKind);
  1123. AddLn(ProcKind+' '+Sig);
  1124. end;
  1125. finally
  1126. Overloads.Free;
  1127. end;
  1128. end;
  1129. function TWebIDLToPasWasmJob.WriteFunctionTypeDefinition(aDef: TIDLFunctionDefinition; aName: string): Boolean;
  1130. var
  1131. FuncName, ReturnTypeName, ResolvedReturnTypeName: TIDLString;
  1132. Params: TIDLString;
  1133. ReturnDef: TIDLDefinition;
  1134. ANT : TPascalNativeType;
  1135. begin
  1136. Result:=True;
  1137. FuncName:=aName;
  1138. if FuncName='' then
  1139. FuncName:=GetPasName(aDef);
  1140. ReturnDef:=GetResolvedType(aDef.ReturnType,ANT,ReturnTypeName,ResolvedReturnTypeName);
  1141. if ANT in [ntNone,ntUnknown] then
  1142. begin
  1143. ReturnTypeName:='';
  1144. ResolvedReturnTypeName:='';
  1145. end;
  1146. if ReturnDef is TIDLSequenceTypeDefDefinition then
  1147. ReturnTypeName:=PasInterfacePrefix+'Array'+PasInterfaceSuffix
  1148. else if ReturnDef is TIDLPromiseTypeDefDefinition then
  1149. ReturnTypeName:=PasInterfacePrefix+'Promise'+PasInterfaceSuffix;
  1150. Params:=GetArguments(aDef.Arguments,False);
  1151. if (ResolvedReturnTypeName='') then
  1152. AddLn(FuncName+' = procedure '+Params+' of object;')
  1153. else
  1154. AddLn(FuncName+' = function '+Params+': '+ReturnTypeName+' of object;');
  1155. end;
  1156. procedure TWebIDLToPasWasmJob.WriteTypeDefsAndCallbackImplementations(aList: TIDLDefinitionList);
  1157. Var
  1158. D: TIDLDefinition;
  1159. CD: TIDLCallbackDefinition absolute D;
  1160. cnt,total : integer;
  1161. OK : Boolean;
  1162. Msg : string;
  1163. begin
  1164. Msg:='';
  1165. Total:=0;
  1166. for D in aList do
  1167. if D is TIDLCallbackDefinition then
  1168. if ConvertDef(D) then
  1169. inc(Total);
  1170. try
  1171. OK:=False;
  1172. Cnt:=0;
  1173. for D in aList do
  1174. if D is TIDLCallbackDefinition then
  1175. if ConvertDef(D) then
  1176. begin
  1177. Inc(Cnt);
  1178. WriteFunctionTypeCallbackImplementation(CD);
  1179. end;
  1180. OK:=True;
  1181. finally
  1182. if not OK then
  1183. Msg:=SErrBeforeException;
  1184. DoLog('Wrote %d of %d callback implementations%s.',[Cnt,Total,Msg]);
  1185. end;
  1186. end;
  1187. function TWebIDLToPasWasmJob.GetKnownArgumentGetter(aDef : TIDLTypeDefinition; ArgTypeName, ArgResolvedTypename : String) : string;
  1188. begin
  1189. if ArgResolvedTypeName='' then ; // Silence compiler warning;
  1190. Result:='';
  1191. if Pos('IJS',ArgTypeName)=1 then
  1192. Result:='GetObject('+GetPasName(aDef)+') as '+ArgTypeName
  1193. else if Pos('Array',ArgTypeName)>0 then
  1194. Result:='GetObject('+GetPasName(aDef)+') as IJSArray';
  1195. end;
  1196. function TWebIDLToPasWasmJob.GetKnownResultAllocator(aDef : TIDLTypeDefinition; ArgTypeName, ArgResolvedTypename : String) : string;
  1197. begin
  1198. if ArgResolvedTypeName='' then ; // Silence compiler warning;
  1199. Result:='';
  1200. if Pos('IJS',ArgTypeName)=1 then
  1201. Result:='Result:=AllocIntf('+GetPasName(aDef)+' as '+ArgTypeName
  1202. else if Pos('Array',ArgTypeName)>0 then
  1203. Result:='Result:=AllocIntf('+GetPasName(aDef)+' as IJSArray';
  1204. end;
  1205. function TWebIDLToPasWasmJob.GetNativeTypeHelperGetterName(aNativeType : TPascalNativeType) : string;
  1206. begin
  1207. Result:='';
  1208. case aNativeType of
  1209. ntBoolean: Result:='GetBoolean';
  1210. ntShortInt,
  1211. ntByte,
  1212. ntSmallInt,
  1213. ntWord,
  1214. ntLongInt: Result:='GetLongInt';
  1215. ntCardinal,
  1216. ntInt64,
  1217. ntQWord: Result:='GetMaxInt';
  1218. ntSingle,
  1219. ntDouble: Result:='GetDouble';
  1220. ntUTF8String,
  1221. ntUnicodeString: Result:='GetString';
  1222. ntObject,
  1223. ntArray : Result:='GetObject';
  1224. ntVariant: Result:='GetVariant';
  1225. else
  1226. Result:='';
  1227. end;
  1228. end;
  1229. function TWebIDLToPasWasmJob.GetNativeTypeHelperAllocatorName(aNativeType : TPascalNativeType) : string;
  1230. begin
  1231. Result:='';
  1232. case aNativeType of
  1233. ntNone : Result:='AllocUndefined';
  1234. ntBoolean: Result:='AllocBool';
  1235. ntShortInt,
  1236. ntByte,
  1237. ntSmallInt,
  1238. ntWord,
  1239. ntLongInt: Result:='AllocLongInt';
  1240. ntCardinal,
  1241. ntInt64,
  1242. ntQWord,
  1243. ntSingle,
  1244. ntDouble: Result:='AllocDouble';
  1245. ntUTF8String,
  1246. ntUnicodeString: Result:='AllocString';
  1247. ntObject,
  1248. ntArray : Result:='AllocIntf';
  1249. ntVariant: Result:='AllocVariant';
  1250. else
  1251. Result:='';
  1252. end;
  1253. end;
  1254. procedure TWebIDLToPasWasmJob.WriteFunctionTypeCallBackImplementation(aDef: TIDLCallBackDefinition);
  1255. var
  1256. CallbackTypeName,FuncName, ReturnTypeName, ResolvedReturnTypeName: TIDLString;
  1257. ArgName, ArgTypeName, ArgResolvedTypename: TIDLString;
  1258. Params, Call, GetFunc: TIDLString;
  1259. FetchArgs, VarSection : Array of string;
  1260. Msg : String;
  1261. Args: TIDLDefinitionList;
  1262. ArgDef: TIDLArgumentDefinition;
  1263. ArgNames: TStringList;
  1264. j, i: Integer;
  1265. ReturnDef, ArgType: TIDLDefinition;
  1266. RNT,ANT : TPascalNativeType;
  1267. FD : TIDLFunctionDefinition;
  1268. begin
  1269. FD:=aDef.FunctionDef;
  1270. FuncName:=GetPasName(FD);
  1271. CallbackTypeName:=GetPasName(aDef);
  1272. ReturnDef:=GetResolvedType(FD.ReturnType,RNT,ReturnTypeName,ResolvedReturnTypeName);
  1273. if RNT in [ntNone,ntUnknown] then
  1274. begin
  1275. ReturnTypeName:='';
  1276. ResolvedReturnTypeName:='';
  1277. end;
  1278. if ReturnDef is TIDLSequenceTypeDefDefinition then
  1279. ReturnTypeName:=PasInterfacePrefix+'Array'+PasInterfaceSuffix
  1280. else if ReturnDef is TIDLPromiseTypeDefDefinition then
  1281. ReturnTypeName:=PasInterfacePrefix+'Promise'+PasInterfaceSuffix;
  1282. Args:=FD.Arguments;
  1283. Params:=GetArguments(Args,False);
  1284. ArgNames:=TStringList.Create;
  1285. try
  1286. // create wrapper callback
  1287. AddLn('function JOBCall%s(const aMethod: TMethod; var H: TJOBCallbackHelper): PByte;',[FuncName]);
  1288. ArgNames.Add('aMethod');
  1289. ArgNames.Add('h');
  1290. VarSection:=[];
  1291. FetchArgs:=[];
  1292. Params:='';
  1293. for i:=0 to Args.Count-1 do
  1294. begin
  1295. ArgDef:=Args[i] as TIDLArgumentDefinition;
  1296. ArgName:=GetPasName(ArgDef);
  1297. if ArgNames.IndexOf(ArgName)>=0 then
  1298. begin
  1299. j:=2;
  1300. while ArgNames.IndexOf(ArgName+IntToStr(j))>=0 do inc(j);
  1301. ArgName:=ArgName+IntToStr(j);
  1302. end;
  1303. ArgType:=GetResolvedType(ArgDef.ArgumentType,aNT,ArgTypeName,ArgResolvedTypename);
  1304. GetFunc:=GetNativeTypeHelperGetterName(ANT);
  1305. if aNt=ntObject then
  1306. begin
  1307. ArgResolvedTypename:=IntfToPasClassName(ArgResolvedTypename);
  1308. GetFunc:='GetObject('+ArgResolvedTypename+') as '+ArgTypeName
  1309. end
  1310. else if aNt=ntArray then
  1311. GetFunc:='GetObject(TJSArray) as IJSArray'
  1312. else if GetFunc='' then
  1313. begin
  1314. if argResolvedTypeName='TJOB_JSValue' then
  1315. GetFunc:='GetValue'
  1316. else if (ArgType is TIDLEnumDefinition) then
  1317. GetFunc:='GetString'
  1318. else if (ArgType is TIDLSequenceTypeDefDefinition) then
  1319. GetFunc:='GetArray'
  1320. else if argType is TIDLTypeDefinition then
  1321. begin
  1322. GetFunc:=GetKnownArgumentGetter(argType as TIDLTypeDefinition, ArgTypeName, ArgResolvedTypename);
  1323. if GetFunc='' then
  1324. begin
  1325. if ArgType<>nil then
  1326. Msg:=Format('%s (%s)',[ArgDef.ArgumentType.TypeName,ArgType.ClassName])
  1327. else
  1328. Msg:='No type';
  1329. raise EWebIDLParser.Create('[20220725181732] not yet supported: function type arg['+IntToStr(I)+'] type '+Msg+' at '+GetDefPos(ArgDef));
  1330. end;
  1331. end
  1332. else
  1333. begin
  1334. if ArgType<>nil then
  1335. Msg:=Format('%s (%s)',[ArgDef.ArgumentType.TypeName,ArgType.ClassName])
  1336. else
  1337. Msg:='No type';
  1338. raise EWebIDLParser.Create('[20220725181732] not yet supported: function type arg['+IntToStr(I)+'] type '+Msg+' at '+GetDefPos(ArgDef));
  1339. end;
  1340. end;
  1341. // declare: var ArgName: ArgTypeName;
  1342. VarSection:=Concat(VarSection,[ArgName+': '+ArgTypeName+';']);
  1343. // get: ArgName:=H.GetX;
  1344. FetchArgs:=Concat(FetchArgs,[ArgName+':=H.'+GetFunc+';']);
  1345. // pass: ArgName
  1346. if Params<>'' then
  1347. Params:=Params+',';
  1348. Params:=Params+ArgName;
  1349. end;
  1350. if Length(VarSection)>0 then
  1351. begin
  1352. AddLn('var');
  1353. Indent;
  1354. AddLn(VarSection);
  1355. Undent;
  1356. end;
  1357. AddLn('begin');
  1358. Indent;
  1359. if Length(FetchArgs)>0 then
  1360. AddLn(FetchArgs);
  1361. Call:=CallBackTypeName+'(aMethod)('+Params+')';
  1362. GetFunc:=GetNativeTypeHelperAllocatorName(RNT);
  1363. if RNT=ntNone then
  1364. begin
  1365. AddLn(Call+';');
  1366. GetFunc:='Result:=H.'+GetFunc+';';
  1367. end
  1368. else if GetFunc<>'' then
  1369. GetFunc:='Result:=H.'+GetFunc+'('+Call+');'
  1370. else
  1371. if ReturnDef is TIDLInterfaceDefinition then
  1372. GetFunc:='Result:=H.AllocIntf('+Call+');'
  1373. else if ReturnDef is TIDLTypeDefinition then
  1374. begin
  1375. GetFunc:=GetKnownResultAllocator(ReturnDef as TIDLTypeDefinition,ReturnTypeName,ResolvedReturnTypeName);
  1376. if GetFunc='' then
  1377. raise EWebIDLParser.Create('[20220725181735] not yet supported: function type result type "'+ResolvedReturnTypeName+'" at '+GetDefPos(aDef));
  1378. end
  1379. else
  1380. raise EWebIDLParser.Create('[20220725181735] not yet supported: function type result type "'+ResolvedReturnTypeName+'" at '+GetDefPos(aDef));
  1381. AddLn(GetFunc);
  1382. undent;
  1383. AddLn('end;');
  1384. AddLn('');
  1385. finally
  1386. ArgNames.Free;
  1387. end;
  1388. end;
  1389. function TWebIDLToPasWasmJob.ExtractAliasName(aTypeName : string) : String;
  1390. var
  1391. P : Integer;
  1392. begin
  1393. Result:=TypeAliases.Values[aTypeName];
  1394. P:=Pos(',',Result);
  1395. if P>0 then
  1396. Result:=Copy(Result,1,P-1);
  1397. end;
  1398. function TWebIDLToPasWasmJob.GetReadPropertyCall(aInfo : TAccessorInfo; aMemberName: String): string;
  1399. var
  1400. TypeName,
  1401. ObjClassName,
  1402. ReadFuncName : string;
  1403. begin
  1404. Result:='';
  1405. Case aInfo.NativeType of
  1406. ntBoolean: ReadFuncName:='ReadJSPropertyBoolean';
  1407. ntShortInt,
  1408. ntByte,
  1409. ntSmallInt,
  1410. ntWord,
  1411. ntLongInt: ReadFuncName:='ReadJSPropertyLongInt';
  1412. ntCardinal,
  1413. ntInt64,
  1414. ntQWord: ReadFuncName:='ReadJSPropertyInt64';
  1415. ntSingle,
  1416. ntDouble: ReadFuncName:='ReadJSPropertyDouble';
  1417. ntUTF8String: ReadFuncName:='ReadJSPropertyUTF8String';
  1418. ntUnicodeString: ReadFuncName:='ReadJSPropertyUnicodeString';
  1419. ntVariant: ReadFuncName:='ReadJSPropertyVariant';
  1420. ntMethod: Result:='('+aInfo.ResolvedTypeName+'(ReadJSPropertyMethod('''+aMemberName+''')))';
  1421. else
  1422. if aInfo.ResolvedTypeName = 'TJOB_JSValue' then
  1423. ReadFuncName:='ReadJSPropertyValue'
  1424. else if aInfo.PropType is TIDLSequenceTypeDefDefinition then
  1425. ObjClassName:=ClassPrefix+'Array'+ClassSuffix
  1426. else if aInfo.PropType is TIDLPromiseTypeDefDefinition then
  1427. ObjClassName:=ClassPrefix+'Promise'+ClassSuffix
  1428. else
  1429. begin
  1430. ObjClassName:=GetPasName(aInfo.PropType);
  1431. if (ObjClassName='') or (Pos(PasInterfacePrefix,ObjClassName)=1) then
  1432. ObjClassName:=IntfToPasClassName(ObjClassName)
  1433. else if (aInfo.PropType is TIDLTypeDefDefinition) then
  1434. begin
  1435. // Check if we have a typedef for an aliased type. Example: BigInteger = Uint8Array
  1436. // must result in TJSUint8Array.
  1437. TypeName:=TIDLTypeDefDefinition(aInfo.PropType).TypeName;
  1438. TypeName:=ExtractAliasName(TypeName);
  1439. if TypeName<>'' then
  1440. ObjClassName:=IntfToPasClassName(TypeName)
  1441. end;
  1442. end;
  1443. Result:='ReadJSPropertyObject('''+aMemberName+''','+ObjClassName+') as '+aInfo.NativeTypeName;
  1444. end;
  1445. if Result='' then
  1446. Result:=ReadFuncName+'('''+aMemberName+''')';
  1447. end;
  1448. function TWebIDLToPasWasmJob.GetPrivateGetterInfo(aProp: TIDLPropertyDefinition; out aAccessInfo : TAccessorInfo): Boolean;
  1449. var
  1450. D : TIDLString;
  1451. aType : TIDLDefinition;
  1452. begin
  1453. Result:=False;
  1454. aAccessInfo:=Default(TAccessorInfo);
  1455. if aProp.PropertyType=nil then
  1456. exit;
  1457. GetAccessorNames(aProp,aAccessinfo.FuncName,D);
  1458. aType:=GetResolvedType(aProp.PropertyType,aAccessinfo.NativeType, aAccessinfo.NativeTypeName,aAccessinfo.ResolvedTypeName);
  1459. aAccessInfo.PropType:=aType;
  1460. if aType is TIDLInterfaceDefinition then
  1461. aAccessInfo.NativeTypeName:=GetPasIntfName(aType)
  1462. else if aType is TIDLDictionaryDefinition then
  1463. aAccessInfo.NativeTypeName:=GetPasIntfName(aType)
  1464. else if aType is TIDLFunctionDefinition then
  1465. // exit // not supported yet
  1466. else if aType is TIDLEnumDefinition then
  1467. aAccessInfo.ResolvedTypeName:='UnicodeString';
  1468. Result:=True;
  1469. end;
  1470. procedure TWebIDLToPasWasmJob.WritePrivateGetterImplementation(aParent: TIDLStructuredDefinition; aProp: TIDLPropertyDefinition);
  1471. var
  1472. aClassName, Call : String;
  1473. Info : TAccessorInfo;
  1474. begin
  1475. aClassName:=GetPasName(aParent);
  1476. // case
  1477. // stringifier ;
  1478. // is equivalent to toString : DOMString
  1479. // no n
  1480. if aProp.PropertyType=nil then
  1481. Exit;
  1482. if (aProp.Name='') and (paStringifier in aProp.PropertyAccess) then
  1483. Exit;
  1484. if not GetPrivateGetterInfo(aProp,Info) then
  1485. exit;
  1486. Call:=GetReadPropertyCall(Info,aProp.Name);
  1487. Addln('function '+aClassName+'.'+info.FuncName+': '+Info.NativeTypeName+';');
  1488. Addln('begin');
  1489. Indent;
  1490. Addln('Result:='+Call+';');
  1491. Undent;
  1492. Addln('end;');
  1493. AddLn('');
  1494. end;
  1495. function TWebIDLToPasWasmJob.WritePrivateGetter(aParent: TIDLStructuredDefinition; aProp: TIDLPropertyDefinition): boolean;
  1496. var
  1497. Info : TAccessorInfo;
  1498. begin
  1499. if (aParent=Nil) then ; // Silence compiler warning
  1500. Result:=true;
  1501. if (aProp.Name='') and not (paWrite in aProp.PropertyAccess) then
  1502. Exit;
  1503. if aProp.PropertyType=nil then
  1504. exit;
  1505. GetPrivateGetterInfo(aProp,Info);
  1506. AddLn('function '+Info.FuncName+': '+Info.NativeTypeName+'; '{overload;'});
  1507. end;
  1508. function TWebIDLToPasWasmJob.GetAccessorNames(Attr: TIDLPropertyDefinition; out aGetter, aSetter: TIDLString): Boolean;
  1509. var
  1510. D : TPasDataWasmJob;
  1511. begin
  1512. Result:=Attr.Data is TPasDataWasmJob;
  1513. if Result then
  1514. begin
  1515. D:=Attr.Data as TPasDataWasmJob;
  1516. aGetter:=D.PropertyGetterName;
  1517. aSetter:=D.PropertySetterName;
  1518. end;
  1519. end;
  1520. function TWebIDLToPasWasmJob.GetPrivateSetterInfo(aProp: TIDLPropertyDefinition; out aAccessInfo: TAccessorInfo): Boolean;
  1521. var
  1522. D : TIDLString;
  1523. aType : TIDLDefinition;
  1524. begin
  1525. Result:=False;
  1526. if (aProp.PropertyType=nil) then
  1527. exit;
  1528. if (aProp.Name='') and not (paWrite in aProp.PropertyAccess) then
  1529. Exit;
  1530. GetAccessorNames(aProp,D,aAccessInfo.FuncName);
  1531. aType:=GetResolvedType(aProp.PropertyType,aAccessInfo.NativeType,aAccessInfo.NativeTypeName,aAccessInfo.ResolvedTypeName);
  1532. aAccessInfo.PropType:=aType;
  1533. if aType is TIDLInterfaceDefinition then
  1534. aAccessInfo.NativeTypeName:=GetPasIntfName(aType)
  1535. else if aType is TIDLDictionaryDefinition then
  1536. aAccessInfo.NativeTypeName:=GetPasIntfName(aType)
  1537. else if aType is TIDLFunctionDefinition then
  1538. aAccessInfo.ResolvedTypeName:=GetPasName(aType)
  1539. else if aType is TIDLCallbackDefinition then
  1540. aAccessInfo.CallBackName:='JobCall'+GetPasName(TIDLCallbackDefinition(aType).FunctionDef) // callback
  1541. else if aType is TIDLEnumDefinition then
  1542. aAccessInfo.ResolvedTypeName:='UnicodeString';
  1543. Result:=True;
  1544. end;
  1545. function TWebIDLToPasWasmJob.GetWritePropertyCall(aInfo: TAccessorInfo; aMemberName: String): string;
  1546. var
  1547. WriteFuncName : String;
  1548. begin
  1549. Result:='';
  1550. case aInfo.NativeType of
  1551. ntBoolean: WriteFuncName:='WriteJSPropertyBoolean';
  1552. ntShortInt,
  1553. ntByte,
  1554. ntSmallInt,
  1555. ntWord,
  1556. ntLongInt: WriteFuncName:='WriteJSPropertyLongInt';
  1557. ntCardinal,
  1558. ntInt64,
  1559. ntQWord: WriteFuncName:='WriteJSPropertyDouble';
  1560. ntSingle,
  1561. ntDouble: WriteFuncName:='WriteJSPropertyDouble';
  1562. ntUTF8String: WriteFuncName:='WriteJSPropertyUTF8String';
  1563. ntUnicodeString: WriteFuncName:='WriteJSPropertyUnicodeString';
  1564. ntVariant: WriteFuncName:='WriteJSPropertyVariant';
  1565. ntMethod: Result:='WriteJSPropertyMethod('''+aMemberName+''',TMethod(aValue))';
  1566. else
  1567. if aInfo.ResolvedTypeName='TJOB_JSValue' then
  1568. WriteFuncName:='WriteJSPropertyValue'
  1569. else
  1570. WriteFuncName:='WriteJSPropertyObject';
  1571. end;
  1572. if Result='' then
  1573. Result:=Format('%s(''%s'',aValue)',[WriteFuncName,aMemberName]);
  1574. end;
  1575. procedure TWebIDLToPasWasmJob.WritePrivateSetterImplementation(aParent: TIDLStructuredDefinition; aProp: TIDLPropertyDefinition);
  1576. var
  1577. aClassName, Call : String;
  1578. Info : TAccessorInfo;
  1579. begin
  1580. if Not (paWrite in aProp.PropertyAccess) then
  1581. exit;
  1582. if aProp.PropertyType=nil then
  1583. exit;
  1584. aClassName:=GetPasName(aParent);
  1585. if not GetPrivateSetterInfo(aProp,Info) then
  1586. exit;
  1587. Addln('procedure %s.%s(const aValue : %s);',[aClassName,info.FuncName,Info.NativeTypeName]);
  1588. if Info.PropType is TIDLCallbackDefinition then
  1589. begin
  1590. Addln('var');
  1591. Indent;
  1592. AddLn('m : TJOB_Method;');
  1593. Undent;
  1594. Addln('begin');
  1595. indent;
  1596. Addln('m:=TJOB_Method.create(TMethod(aValue),@%s);',[Info.CallBackName]);
  1597. Addln('try');
  1598. indent;
  1599. Addln('InvokeJSNoResult(''%s'',[m],jiSet);',[aProp.Name]);
  1600. undent;
  1601. Addln('finally');
  1602. indent;
  1603. Addln('m.free');
  1604. undent;
  1605. Addln('end;');
  1606. end
  1607. else
  1608. begin
  1609. Call:=GetWritePropertyCall(Info, aProp.Name);
  1610. Addln('begin');
  1611. indent;
  1612. Addln(Call+';');
  1613. end;
  1614. undent;
  1615. Addln('end;');
  1616. Addln('');
  1617. end;
  1618. procedure TWebIDLToPasWasmJob.WriteMapLikePrivateSetterImplementation(aParent: TIDLStructuredDefinition; aMap: TIDLMapLikeDefinition
  1619. );
  1620. begin
  1621. if (aMap=Nil) and (aParent=Nil) then ; // Silence compiler warning
  1622. // None
  1623. end;
  1624. procedure TWebIDLToPasWasmJob.WriteMapLikePrivateGetterImplementation(aParent: TIDLStructuredDefinition; aMap: TIDLMapLikeDefinition
  1625. );
  1626. var
  1627. call, aClassName : string;
  1628. Info : TAccessorInfo;
  1629. begin
  1630. if (aMap=Nil) and (aParent=Nil) then ; // Silence compiler warning
  1631. aClassName:=GetPasName(aParent);
  1632. Info:=Default(TAccessorInfo);
  1633. Info.NativeTypeName:='Integer';
  1634. Info.ResolvedTypeName:='LongInt';
  1635. Info.NativeType:=ntLongint;
  1636. Addln('function '+aClassName+'._Getsize: LongInt;');
  1637. Addln('begin');
  1638. Addln(' Result:=0;');
  1639. Addln('end;');
  1640. end;
  1641. function TWebIDLToPasWasmJob.WritePrivateSetter(aParent: TIDLStructuredDefinition; aProp: TIDLPropertyDefinition): boolean;
  1642. var
  1643. Info : TAccessorInfo;
  1644. begin
  1645. if (aParent=Nil) then ; // Silence compiler warning
  1646. if aProp.PropertyType=nil then
  1647. exit;
  1648. if not (paWrite in aProp.PropertyAccess) then
  1649. exit(false);
  1650. if not GetPrivateSetterInfo(aProp,Info) then exit;
  1651. AddLn('procedure '+Info.FuncName+'(const aValue: '+Info.NativeTypeName+');' {overload;'});
  1652. end;
  1653. function TWebIDLToPasWasmJob.WriteProperty(aParent: TIDLDefinition; aProp: TIDLPropertyDefinition): boolean;
  1654. var
  1655. PropName, Code, aTypeName, aResolvedTypeName: TIDLString;
  1656. aType: TIDLDefinition;
  1657. ANT : TPascalNativeType;
  1658. GetterName,SetterName : TIDLString;
  1659. begin
  1660. if aParent=nil then ;
  1661. if (aProp.PropertyType=nil) then
  1662. begin
  1663. if not (paStringifier in aProp.PropertyAccess) then
  1664. DoLog('Note: skipping field "'+AProp.Name+'" without type at '+GetDefPos(aProp));
  1665. exit;
  1666. end;
  1667. PropName:=GetPasName(aProp);
  1668. aType:=GetResolvedType(aProp.PropertyType,ANT,aTypeName,aResolvedTypeName);
  1669. if aType is TIDLInterfaceDefinition then
  1670. aTypeName:=GetPasIntfName(aType)
  1671. else if aType is TIDLDictionaryDefinition then
  1672. aTypeName:=GetPasIntfName(aType);
  1673. GetAccessorNames(aProp,GetterName,SetterName);
  1674. Code:='property '+PropName+': '+aTypeName+' read '+GetterName;
  1675. if (paWrite in aProp.PropertyAccess) then
  1676. Code:=Code+' write '+SetterName;
  1677. Code:=Code+';';
  1678. if aType is TIDLFunctionDefinition then
  1679. Code:='// '+Code;
  1680. if (aProp is TIDLDictionaryMemberDefinition) then
  1681. if TIDLDictionaryMemberDefinition(aProp).IsRequired then
  1682. Code:=Code+' // required';
  1683. AddLn(Code);
  1684. Result:=true;
  1685. end;
  1686. function TWebIDLToPasWasmJob.WriteRecordDef(aDef: TIDLRecordDefinition): Boolean;
  1687. begin
  1688. Result:=true;
  1689. AddLn(GetPasName(aDef)+' = '+ClassPrefix+'Object'+ClassSuffix+';');
  1690. end;
  1691. procedure TWebIDLToPasWasmJob.WriteSequenceDef(
  1692. aDef: TIDLSequenceTypeDefDefinition);
  1693. var
  1694. N,aLine : String;
  1695. begin
  1696. N:=GetPasName(aDef);
  1697. aLine:=N+' = '+PasInterfacePrefix+'Array'+PasInterfaceSuffix+'; // array of '+GetJSTypeName(aDef.ElementType);
  1698. Addln(aLine);
  1699. end;
  1700. procedure TWebIDLToPasWasmJob.WriteNamespaceVars;
  1701. var
  1702. i: Integer;
  1703. VarName, VarType: String;
  1704. NS : TIDLNamespaceDefinition;
  1705. HaveNamespaces : Boolean;
  1706. begin
  1707. HaveNameSpaces:=False;
  1708. I:=0;
  1709. While (Not HaveNameSpaces) and (I<Context.Definitions.Count) do
  1710. begin
  1711. HaveNameSpaces:=Context.Definitions[i] is TIDLNamespaceDefinition;
  1712. Inc(I);
  1713. end;
  1714. if HaveNameSpaces then
  1715. Comment('Namespaces');
  1716. for I:=0 to Context.Definitions.Count-1 do
  1717. if Context.Definitions[i] is TIDLNamespaceDefinition then
  1718. begin
  1719. NS:=Context.Definitions[i] as TIDLNamespaceDefinition;
  1720. if (not NS.IsPartial) and ConvertDef(NS) then
  1721. begin
  1722. VarName:=Context.Definitions[i].Name;
  1723. VarType:=GetPasIntfName(Context.Definitions[i]);
  1724. AddLn(VarName+': '+VarType+';');
  1725. end;
  1726. end;
  1727. end;
  1728. procedure TWebIDLToPasWasmJob.WriteGlobalVar(aDef : String);
  1729. var
  1730. PasVarName, JSClassName, JOBRegisterName: TIDLString;
  1731. iDef: TIDLDefinition;
  1732. begin
  1733. if not SplitGlobalVar(aDef,PasVarName,JSClassName,JOBRegisterName) then
  1734. raise EConvertError.Create('invalid global var "'+aDef+'"');
  1735. iDef:=FindGlobalDef(JSClassName);
  1736. if iDef=nil then
  1737. raise EConvertError.Create('missing global var "'+PasVarName+'" type "'+JSClassName+'"');
  1738. if ConvertDef(iDef) then
  1739. AddLn(PasVarName+': '+GetPasName(iDef)+';');
  1740. end;
  1741. procedure TWebIDLToPasWasmJob.WriteEnumImplementation(aDef : TIDLEnumDefinition);
  1742. begin
  1743. if (aDef=Nil) then ; // Silence compiler warning
  1744. end;
  1745. procedure TWebIDLToPasWasmJob.WriteDictionaryImplemention(aDef : TIDLDictionaryDefinition);
  1746. Var
  1747. ML: TIDLDefinitionList;
  1748. begin
  1749. ML:=TIDLDefinitionList.Create(Nil,False);
  1750. try
  1751. Adef.GetFullMemberList(ML);
  1752. WritePrivateGetterImplementations(aDef,ML);
  1753. WritePrivateSetterImplementations(aDef,ML);
  1754. WriteUtilityMethodImplementations(aDef,ML);
  1755. finally
  1756. ML.Free;
  1757. end;
  1758. end;
  1759. procedure TWebIDLToPasWasmJob.WritePrivateGetterImplementations(aDef : TIDLStructuredDefinition; ML : TIDLDefinitionList);
  1760. var
  1761. D : TIDLDefinition;
  1762. PD : TIDLPropertyDefinition absolute D;
  1763. MD : TIDLMapLikeDefinition absolute D;
  1764. begin
  1765. for D in ML do
  1766. if ConvertDef(D) then
  1767. begin
  1768. if D is TIDLPropertyDefinition then
  1769. WritePrivateGetterImplementation(aDef,PD)
  1770. else if D is TIDLMapLikeDefinition then
  1771. WriteMapLikePrivateGetterImplementation(aDef,MD);
  1772. end;
  1773. end;
  1774. procedure TWebIDLToPasWasmJob.WritePrivateSetterImplementations(aDef : TIDLStructuredDefinition; ML : TIDLDefinitionList);
  1775. var
  1776. D : TIDLDefinition;
  1777. PD : TIDLPropertyDefinition absolute D;
  1778. MD : TIDLMapLikeDefinition absolute D;
  1779. begin
  1780. for D in ML do
  1781. if ConvertDef(D) then
  1782. begin
  1783. if D is TIDLPropertyDefinition then
  1784. WritePrivateSetterImplementation(aDef,PD)
  1785. else if D is TIDLMapLikeDefinition then
  1786. WriteMapLikePrivateSetterImplementation(aDef,MD);
  1787. end;
  1788. end;
  1789. procedure TWebIDLToPasWasmJob.WriteMethodImplementations(aDef : TIDLStructuredDefinition; ML : TIDLDefinitionList);
  1790. var
  1791. D : TIDLDefinition;
  1792. DF : TIDLFunctionDefinition absolute D;
  1793. DM : TIDLMapLikeDefinition absolute D;
  1794. begin
  1795. For D in ML do
  1796. if ConvertDef(D) then
  1797. if D Is TIDLFunctionDefinition then
  1798. WriteFunctionImplementation(aDef,DF)
  1799. else If D Is TIDLMapLikeDefinition then
  1800. WriteMapLikeFunctionImplementations(aDef,DM);
  1801. end;
  1802. function TWebIDLToPasWasmJob.DefaultForNativeType(aNativeType : TPascalNativeType; aReturnTypeName: String) : String;
  1803. var
  1804. S,N : string;
  1805. begin
  1806. Case aNativeType of
  1807. ntUnknown, // unknown
  1808. ntNone, // None -> void
  1809. ntError : Result:=''; // Special : error condition
  1810. ntBoolean : Result:='False';
  1811. ntShortInt,
  1812. ntByte,
  1813. ntSmallInt,
  1814. ntWord,
  1815. ntLongint,
  1816. ntCardinal,
  1817. ntInt64,
  1818. ntQWord : Result:='0';
  1819. ntSingle,
  1820. ntDouble : Result:='0.0';
  1821. ntUnicodeString,
  1822. ntUTF8String : Result:='''''';
  1823. ntVariant: Result:='null';
  1824. ntObject :
  1825. Result:=StringReplace(aReturnTypeName,'IJS','TJS',[])+'.CreateEmpty()';
  1826. ntInterface : Result:='nil';
  1827. ntArray :
  1828. begin
  1829. S:=Copy(aReturnTypeName,1,Length(PasInterfacePrefix));
  1830. N:=Copy(aReturnTypeName,Length(PasInterfacePrefix)+1);
  1831. if (S=PasInterfacePrefix) and (TypeAliases.Values[N]<>'') then
  1832. Result:=IntfToPasClassName(aReturnTypeName)+'.CreateEmpty()'
  1833. else
  1834. Result:='TJSArray.CreateEmpty()';
  1835. end;
  1836. ntMethod : Result:='Nil';
  1837. end;
  1838. end;
  1839. procedure TWebIDLToPasWasmJob.WriteMapLikeGetFunctionImplementation(aDef : TIDLStructuredDefinition; ML : TIDLMapLikeDefinition);
  1840. var
  1841. D,aResolvedKeyTypeName,aResolvedValueTypeName: String;
  1842. Func,InvokeClass,aClassName : string;
  1843. KNT,VNT : TPascalNativeTYpe;
  1844. begin
  1845. aClassName:=GetPasName(aDef);
  1846. GetResolvedType(ML.KeyType,KNT,D,aResolvedKeyTypeName);
  1847. GetResolvedType(ML.ValueType,VNT,D,aResolvedValueTypeName);
  1848. Func:=GetInvokeNameFromTypeName(aResolvedValueTypeName,ML.ValueType);
  1849. if VNT=ntObject then
  1850. InvokeClass:=GetInvokeClassName(ML.ValueType,aResolvedValueTypeName,Nil);
  1851. AddLn('function %s.get(key: %s) : %s;',[aClassName,aResolvedKeyTypeName,aResolvedValueTypeName]);
  1852. AddLn('begin');
  1853. Indent;
  1854. if IsStub then
  1855. AddLn('Result:='+DefaultForNativeType(vnt,InvokeClass)+';')
  1856. else if VNT=ntObject then
  1857. AddLn('Result:='+Func+'(''get'',[key],'+InvokeClass+') as '+aResolvedValueTypeName+';')
  1858. else
  1859. AddLn('Result:='+Func+'(''get'',[key]);');
  1860. Undent;
  1861. AddLn('end;');
  1862. end;
  1863. procedure TWebIDLToPasWasmJob.WriteMapLikeDeleteFunctionImplementation(aDef : TIDLStructuredDefinition; ML : TIDLMapLikeDefinition);
  1864. var
  1865. D,aResolvedKeyTypeName,aResolvedValueTypeName: String;
  1866. aClassName : string;
  1867. KNT,VNT : TPascalNativeTYpe;
  1868. begin
  1869. aClassName:=GetPasName(aDef);
  1870. GetResolvedType(ML.KeyType,KNT,D,aResolvedKeyTypeName);
  1871. GetResolvedType(ML.ValueType,VNT,D,aResolvedValueTypeName);
  1872. AddLn('Procedure %s.delete(key: %s);',[aClassName,aResolvedKeyTypeName]);
  1873. AddLn('begin');
  1874. Indent;
  1875. if not IsStub then
  1876. AddLn('InvokeJSNoResult(''delete'',[key]);');
  1877. Undent;
  1878. AddLn('end;');
  1879. end;
  1880. procedure TWebIDLToPasWasmJob.WriteMapLikeSetFunctionImplementation(aDef: TIDLStructuredDefinition; ML: TIDLMapLikeDefinition);
  1881. var
  1882. D,aResolvedKeyTypeName,aResolvedValueTypeName: String;
  1883. aClassName : string;
  1884. KNT,VNT : TPascalNativeTYpe;
  1885. begin
  1886. aClassName:=GetPasName(aDef);
  1887. GetResolvedType(ML.KeyType,KNT,D,aResolvedKeyTypeName);
  1888. GetResolvedType(ML.ValueType,VNT,D,aResolvedValueTypeName);
  1889. AddLn('Procedure %s.set_(key: %s; value : %s);',[aClassName,aResolvedKeyTypeName,aResolvedValueTypeName]);
  1890. AddLn('begin');
  1891. Indent;
  1892. if not IsStub then
  1893. AddLn('InvokeJSNoResult(''set'',[key,Value]);');
  1894. Undent;
  1895. AddLn('end;');
  1896. end;
  1897. procedure TWebIDLToPasWasmJob.WriteMapLikeClearFunctionImplementation(aDef: TIDLStructuredDefinition; ML: TIDLMapLikeDefinition);
  1898. var
  1899. aClassName : string;
  1900. begin
  1901. if (ML=Nil) then ; // Silence compiler warning
  1902. aClassName:=GetPasName(aDef);
  1903. AddLn('Procedure %s.clear;',[aClassName]);
  1904. AddLn('begin');
  1905. Indent;
  1906. if not IsStub then
  1907. AddLn('InvokeJSNoResult(''clear'',[]);');
  1908. Undent;
  1909. AddLn('end;');
  1910. end;
  1911. procedure TWebIDLToPasWasmJob.WriteMapLikeHasFunctionImplementation(aDef : TIDLStructuredDefinition; ML : TIDLMapLikeDefinition);
  1912. var
  1913. D,aResolvedKeyTypeName: String;
  1914. aClassName : string;
  1915. KNT : TPascalNativeTYpe;
  1916. begin
  1917. aClassName:=GetPasName(aDef);
  1918. GetResolvedType(ML.KeyType,KNT,D,aResolvedKeyTypeName);
  1919. AddLn('function %s.has(key: %s) : Boolean;',[aClassName,aResolvedKeyTypeName]);
  1920. AddLn('begin');
  1921. Indent;
  1922. if IsStub then
  1923. AddLn('Result:=False;')
  1924. else
  1925. AddLn('Result:=InvokeJSBooleanResult(''has'',[key]);');
  1926. Undent;
  1927. AddLn('end;');
  1928. end;
  1929. procedure TWebIDLToPasWasmJob.WriteMapLikeEntriesFunctionImplementation(aDef : TIDLStructuredDefinition; ML : TIDLMapLikeDefinition);
  1930. var
  1931. aClassName : string;
  1932. begin
  1933. if (ML=Nil) then ; // Silence compiler warning
  1934. aClassName:=GetPasName(aDef);
  1935. AddLn('function %s.entries : IJSIterator;',[aClassName]);
  1936. AddLn('begin');
  1937. Indent;
  1938. if IsStub then
  1939. AddLn('Result:=TJSIterator.CreateEmpty;')
  1940. else
  1941. AddLn('Result:=InvokeJSObjectResult(''entries'',[],TJSIterator) as IJSIterator;');
  1942. Undent;
  1943. AddLn('end;');
  1944. end;
  1945. procedure TWebIDLToPasWasmJob.WriteMapLikeKeysFunctionImplementation(aDef : TIDLStructuredDefinition; ML : TIDLMapLikeDefinition);
  1946. var
  1947. aClassName : string;
  1948. begin
  1949. if (ML=Nil) then ; // Silence compiler warning
  1950. aClassName:=GetPasName(aDef);
  1951. AddLn('function %s.keys : IJSIterator;',[aClassName]);
  1952. AddLn('begin');
  1953. Indent;
  1954. if IsStub then
  1955. AddLn('Result:=TJSIterator.CreateEmpty;')
  1956. else
  1957. AddLn('Result:=InvokeJSObjectResult(''keys'',[],TJSIterator) as IJSIterator;');
  1958. Undent;
  1959. AddLn('end;');
  1960. end;
  1961. procedure TWebIDLToPasWasmJob.WriteMapLikeValuesFunctionImplementation(aDef : TIDLStructuredDefinition; ML : TIDLMapLikeDefinition);
  1962. var
  1963. aClassName : string;
  1964. begin
  1965. if (ML=Nil) then ; // Silence compiler warning
  1966. aClassName:=GetPasName(aDef);
  1967. AddLn('function %s.values : IJSIterator;',[aClassName]);
  1968. AddLn('begin');
  1969. Indent;
  1970. if IsStub then
  1971. AddLn('Result:=TJSIterator.CreateEmpty;')
  1972. else
  1973. AddLn('Result:=InvokeJSObjectResult(''values'',[],TJSIterator) as IJSIterator;');
  1974. Undent;
  1975. AddLn('end;');
  1976. end;
  1977. procedure TWebIDLToPasWasmJob.WriteMapLikeFunctionImplementations(aDef : TIDLStructuredDefinition; MD : TIDLMapLikeDefinition);
  1978. Var
  1979. L : TIDLDefinitionList;
  1980. lReadOnly : Boolean;
  1981. begin
  1982. lReadOnly:=MD.IsReadonly;
  1983. L:=TIDLDefinitionList.Create(Nil,False);
  1984. try
  1985. aDef.GetFullMemberList(L);
  1986. if not L.HasName('get') then
  1987. WriteMapLikeGetFunctionImplementation(aDef,MD);
  1988. if not L.HasName('has') then
  1989. WriteMapLikeHasFunctionImplementation(aDef,MD);
  1990. if not L.HasName('entries') then
  1991. WriteMapLikeEntriesFunctionImplementation(aDef,MD);
  1992. if not L.HasName('keys') then
  1993. WriteMapLikeKeysFunctionImplementation(aDef,MD);
  1994. if not L.HasName('values') then
  1995. WriteMapLikeValuesFunctionImplementation(aDef,MD);
  1996. if not lReadOnly then
  1997. begin
  1998. if Not L.HasName('set') then
  1999. WriteMapLikeSetFunctionImplementation(aDef,MD);
  2000. if Not L.HasName('clear') then
  2001. WriteMapLikeClearFunctionImplementation(aDef,MD);
  2002. if Not L.HasName('delete') then
  2003. WriteMapLikeDeleteFunctionImplementation(aDef,MD);
  2004. end;
  2005. finally
  2006. L.Free;
  2007. end;
  2008. end;
  2009. procedure TWebIDLToPasWasmJob.WriteDictionaryConstructor(aDict: TIDLDictionaryDefinition);
  2010. var
  2011. CurrClassName: TIDLString;
  2012. IDL : TIDLDefinition;
  2013. MD : TIDLDictionaryMemberDefinition absolute IDL;
  2014. aName : string;
  2015. begin
  2016. CurrClassName:=GetPasName(aDict);
  2017. AddLn('constructor %s.create(const aDict : %sRec); overload;',[CurrClassName,CurrClassName]);
  2018. Addln('begin');
  2019. Indent;
  2020. For IDl in aDict.Members do
  2021. if IDL is TIDLDictionaryMemberDefinition then
  2022. if convertDef(Idl) then
  2023. begin
  2024. aName:=GetPasName(MD);
  2025. AddLn('Self.%s:=aDict.%s;',[aName,aName]);
  2026. end;
  2027. Undent;
  2028. AddLn('end;');
  2029. AddLn('');
  2030. end;
  2031. procedure TWebIDLToPasWasmJob.WriteUtilityMethodImplementations(aDef : TIDLStructuredDefinition; ML : TIDLDefinitionList);
  2032. var
  2033. aJSClassName,aClassName, aPasIntfName: TIDLString;
  2034. begin
  2035. if (ML=Nil) then ; // Silence compiler warning
  2036. aClassName:=GetPasName(aDef);
  2037. aPasIntfName:=GetPasIntfName(aDef);
  2038. if aDef.StructuredType=sdDictionary then
  2039. begin
  2040. WriteDictionaryConstructor(aDef as TIDLDictionaryDefinition);
  2041. aJSClassName:='Object'
  2042. end
  2043. else
  2044. aJSClassName:=aDef.Name;
  2045. AddLn('class function %s.JSClassName: UnicodeString;',[aClassName]);
  2046. AddLn('begin');
  2047. Indent;
  2048. AddLn('Result:=''%s'';',[aJSClassName]);
  2049. Undent;
  2050. AddLn('end;');
  2051. AddLn('');
  2052. AddLn('class function %s.Cast(const Intf: IJSObject): %s;',[aClassName,aPasIntfName]);
  2053. AddLn('begin');
  2054. Indent;
  2055. AddLn('Result:=%s.JOBCast(Intf);',[aClassName]);
  2056. Undent;
  2057. AddLn('end;');
  2058. AddLn('');
  2059. end;
  2060. procedure TWebIDLToPasWasmJob.WriteInterfaceImplemention(aDef : TIDLInterfaceDefinition);
  2061. Var
  2062. ML: TIDLDefinitionList;
  2063. begin
  2064. ML:=TIDLDefinitionList.Create(Nil,False);
  2065. try
  2066. Adef.GetFullMemberList(ML);
  2067. WritePrivateGetterImplementations(aDef,ML);
  2068. WritePrivateSetterImplementations(aDef,ML);
  2069. WriteMethodImplementations(aDef,ML);
  2070. WriteUtilityMethodImplementations(aDef,ML);
  2071. finally
  2072. ML.Free;
  2073. end;
  2074. end;
  2075. procedure TWebIDLToPasWasmJob.WriteNamespaceImplemention(aDef : TIDLNamespaceDefinition);
  2076. Var
  2077. ML: TIDLDefinitionList;
  2078. begin
  2079. ML:=TIDLDefinitionList.Create(Nil,False);
  2080. try
  2081. ADef.GetFullMemberList(ML);
  2082. WritePrivateGetterImplementations(aDef,ML);
  2083. WritePrivateSetterImplementations(aDef,ML);
  2084. WriteMethodImplementations(aDef,ML);
  2085. WriteUtilityMethodImplementations(aDef,ML);
  2086. finally
  2087. ML.Free;
  2088. end;
  2089. end;
  2090. procedure TWebIDLToPasWasmJob.WriteDefinitionImplementation(D: TIDLDefinition);
  2091. begin
  2092. if D is TIDLEnumDefinition then
  2093. WriteEnumImplementation(D as TIDLEnumDefinition)
  2094. else if D is TIDLDictionaryDefinition then
  2095. WriteDictionaryImplemention(D as TIDLDictionaryDefinition)
  2096. else if D is TIDLInterfaceDefinition then
  2097. WriteInterfaceImplemention(D as TIDLInterfaceDefinition)
  2098. else if D is TIDLNamespaceDefinition then
  2099. WriteNamespaceImplemention(D as TIDLNamespaceDefinition);
  2100. end;
  2101. function TWebIDLToPasWasmJob.OnlyConstants(D : TIDLStructuredDefinition) : Boolean;
  2102. var
  2103. i,aCount : Integer;
  2104. begin
  2105. Result:=True;
  2106. I:=0;
  2107. aCount:=D.Members.Count;
  2108. While Result and (I<aCount) do
  2109. begin
  2110. Result:=D.Members[i] is TIDLConstDefinition;
  2111. Inc(I);
  2112. end;
  2113. end;
  2114. procedure TWebIDLToPasWasmJob.WriteImplementation;
  2115. var
  2116. i: Integer;
  2117. aDef: TIDLDefinition;
  2118. nsDef : TIDLNamespaceDefinition absolute aDef;
  2119. PasVarName, JSClassName, JOBRegisterName: TIDLString;
  2120. begin
  2121. inherited WriteImplementation;
  2122. if (GlobalVars.Count>0) or Context.HaveNameSpaces then
  2123. begin
  2124. AddLn('initialization');
  2125. Indent;
  2126. for i:=0 to GlobalVars.Count-1 do
  2127. begin
  2128. SplitGlobalVar(GlobalVars[i],PasVarName,JSClassName,JOBRegisterName);
  2129. aDef:=FindGlobalDef(JSClassName);
  2130. if IsStub then
  2131. AddLn(PasVarName+':='+GetPasName(aDef)+'.Create();')
  2132. else if ConvertDef(aDef) then
  2133. AddLn(PasVarName+':='+GetPasName(aDef)+'.JOBCreateGlobal('''+JOBRegisterName+''');');
  2134. end;
  2135. for I:=0 to Context.Definitions.Count-1 do
  2136. begin
  2137. aDef:=Context.Definitions[i];
  2138. if aDef is TIDLNamespaceDefinition then
  2139. if not NSDef.IsPartial and ConvertDef(aDef) then
  2140. if not (OnlyConstants(NSDef) or NSDef.HasPrefAttribute) then
  2141. begin
  2142. PasVarName:=Context.Definitions[i].Name;
  2143. if IsStub then
  2144. AddLn(PasVarName+':='+GetPasName(aDef)+'.Create();')
  2145. else if ConvertDef(aDef) then
  2146. AddLn(PasVarName+':='+GetPasName(aDef)+'.JOBCreateGlobal('''+PasVarName+''');');
  2147. end;
  2148. end;
  2149. Undent;
  2150. AddLn('finalization');
  2151. Indent;
  2152. for i:=0 to GlobalVars.Count-1 do
  2153. begin
  2154. SplitGlobalVar(GlobalVars[i],PasVarName,JSClassName,JOBRegisterName);
  2155. aDef:=FindGlobalDef(JSClassName);
  2156. if ConvertDef(aDef) then
  2157. AddLn(PasVarName+'.Free;');
  2158. end;
  2159. for I:=0 to Context.Definitions.Count-1 do
  2160. begin
  2161. aDef:=Context.Definitions[i];
  2162. if aDef is TIDLNamespaceDefinition then
  2163. if not NSDef.IsPartial and ConvertDef(aDef) then
  2164. if not (OnlyConstants(NSDef) or NSDef.HasPrefAttribute) then
  2165. begin
  2166. PasVarName:=Context.Definitions[i].Name;
  2167. AddLn(PasVarName+':=Nil;');
  2168. end;
  2169. end;
  2170. Undent;
  2171. end;
  2172. end;
  2173. constructor TWebIDLToPasWasmJob.Create(ThOwner: TComponent);
  2174. begin
  2175. inherited Create(ThOwner);
  2176. // Switches.Add('modeswitch FunctionReferences');
  2177. PasDataClass:=TPasDataWasmJob;
  2178. ClassPrefix:='TJS';
  2179. PasInterfacePrefix:='IJS';
  2180. GetterPrefix:='_Get';
  2181. SetterPrefix:='_Set';
  2182. KeywordSuffix:='_';
  2183. BaseOptions:=BaseOptions+[coExpandUnionTypeArgs,coDictionaryAsClass];
  2184. end;
  2185. function TWebIDLToPasWasmJob.SplitGlobalVar(Line: TIDLString; out PasVarName,
  2186. JSClassName, JOBRegisterName: TIDLString): boolean;
  2187. var
  2188. p: SizeInt;
  2189. begin
  2190. PasVarName:='';
  2191. JSClassName:='';
  2192. JOBRegisterName:='';
  2193. p:=Pos('=',Line);
  2194. PasVarName:=LeftStr(Line,p-1);
  2195. if not IsValidIdent(PasVarName) then exit(false);
  2196. System.Delete(Line,1,p);
  2197. p:=Pos(',',Line);
  2198. JSClassName:=LeftStr(Line,p-1);
  2199. if not IsValidIdent(JSClassName) then exit(false);
  2200. JOBRegisterName:=copy(Line,p+1,length(Line));
  2201. Result:=IsValidIdent(JOBRegisterName);
  2202. end;
  2203. end.