typinfo.pas 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286
  1. {
  2. This file is part of the Pas2JS run time library.
  3. Copyright (c) 2018 by Mattias Gaertner
  4. See the file COPYING.FPC, included in this distribution,
  5. for details about the copyright.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. **********************************************************************}
  10. unit TypInfo;
  11. {$mode objfpc}
  12. {$modeswitch externalclass}
  13. interface
  14. uses
  15. SysUtils, Types, RTLConsts, JS;
  16. type
  17. // if you change the following enumeration type in any way
  18. // you also have to change the rtl.js in an appropriate way !
  19. TTypeKind = (
  20. tkUnknown, // 0
  21. tkInteger, // 1
  22. tkChar, // 2 in Delphi/FPC tkWChar, tkUChar
  23. tkString, // 3 in Delphi/FPC tkSString, tkWString or tkUString
  24. tkEnumeration, // 4
  25. tkSet, // 5
  26. tkDouble, // 6
  27. tkBool, // 7
  28. tkProcVar, // 8
  29. tkMethod, // 9 proc var of object
  30. tkArray, // 10 static array
  31. tkDynArray, // 11
  32. tkRecord, // 12
  33. tkClass, // 13
  34. tkClassRef, // 14
  35. tkPointer, // 15
  36. tkJSValue, // 16
  37. tkRefToProcVar, // 17
  38. tkInterface // 18
  39. //tkObject,
  40. //tkSString,tkLString,tkAString,tkWString,
  41. //tkVariant,
  42. //tkWChar,
  43. //tkInt64,
  44. //tkQWord,
  45. //tkInterfaceRaw,
  46. //tkUString,tkUChar,
  47. //tkHelper,
  48. //tkFile,
  49. );
  50. TTypeKinds = set of TTypeKind;
  51. const
  52. tkFloat = tkDouble; // for compatibility with Delphi/FPC
  53. tkProcedure = tkProcVar; // for compatibility with Delphi
  54. tkAny = [Low(TTypeKind)..High(TTypeKind)];
  55. tkMethods = [tkMethod];
  56. tkProperties = tkAny-tkMethods-[tkUnknown];
  57. type
  58. { TTypeInfo }
  59. TTypeInfo = class external name 'rtl.tTypeInfo'
  60. public
  61. Name: String external name 'name';
  62. Kind: TTypeKind external name 'kind';
  63. end;
  64. TTypeInfoClassOf = class of TTypeInfo;
  65. TOrdType = (
  66. otSByte, // 0
  67. otUByte, // 1
  68. otSWord, // 2
  69. otUWord, // 3
  70. otSLong, // 4
  71. otULong, // 5
  72. otSIntDouble, // 6 NativeInt
  73. otUIntDouble // 7 NativeUInt
  74. );
  75. { TTypeInfoInteger - Kind = tkInteger }
  76. TTypeInfoInteger = class external name 'rtl.tTypeInfoInteger'(TTypeInfo)
  77. public
  78. MinValue: NativeInt external name 'minvalue';
  79. MaxValue: NativeInt external name 'maxvalue';
  80. OrdType : TOrdType external name 'ordtype';
  81. end;
  82. { TEnumType }
  83. TEnumType = class external name 'anonymous'
  84. private
  85. function GetIntToName(Index: NativeInt): String; external name '[]';
  86. function GetNameToInt(Name: String): NativeInt; external name '[]';
  87. public
  88. property IntToName[Index: NativeInt]: String read GetIntToName;
  89. property NameToInt[Name: String]: NativeInt read GetNameToInt;
  90. end;
  91. { TTypeInfoEnum - Kind = tkEnumeration }
  92. TTypeInfoEnum = class external name 'rtl.tTypeInfoEnum'(TTypeInfoInteger)
  93. public
  94. // not supported: BaseType: TTypeInfo
  95. EnumType: TEnumType external name 'enumtype';
  96. end;
  97. { TTypeInfoSet - Kind = tkSet }
  98. TTypeInfoSet = class external name 'rtl.tTypeInfoSet'(TTypeInfo)
  99. public
  100. // not supported: BaseType: TTypeInfo
  101. CompType: TTypeInfo external name 'comptype';
  102. end;
  103. { TTypeInfoStaticArray - Kind = tkArray }
  104. TTypeInfoStaticArray = class external name 'rtl.tTypeInfoStaticArray'(TTypeInfo)
  105. public
  106. Dims: TIntegerDynArray;
  107. ElType: TTypeInfo external name 'eltype';
  108. end;
  109. { TTypeInfoDynArray - Kind = tkDynArray }
  110. TTypeInfoDynArray = class external name 'rtl.tTypeInfoDynArray'(TTypeInfo)
  111. public
  112. DimCount: NativeInt external name 'dimcount';
  113. ElType: TTypeInfo external name 'eltype';
  114. end;
  115. TParamFlag = (
  116. pfVar, // 2^0 = 1
  117. pfConst, // 2^1 = 2
  118. pfOut, // 2^2 = 4
  119. pfArray // 2^3 = 8
  120. //pfAddress,pfReference,
  121. );
  122. TParamFlags = set of TParamFlag;
  123. { TProcedureParam }
  124. TProcedureParam = class external name 'anonymous'
  125. public
  126. Name: String external name 'name';
  127. TypeInfo: TTypeInfo external name 'typeinfo';
  128. Flags: NativeInt external name 'flags'; // TParamFlags as bit vector
  129. end;
  130. TProcedureParams = array of TProcedureParam;
  131. TProcedureFlag = (
  132. pfStatic, // 2^0 = 1
  133. pfVarargs, // 2^1 = 2
  134. pfExternal // 2^2 = 4 name may be an expression
  135. );
  136. TProcedureFlags = set of TProcedureFlag;
  137. { TProcedureSignature }
  138. TProcedureSignature = class external name 'anonymous'
  139. public
  140. Params: TProcedureParams external name 'params'; // can be null
  141. ResultType: TTypeInfo external name 'resulttype'; // can be null
  142. Flags: NativeInt external name 'flags'; // TProcedureFlags as bit vector
  143. end;
  144. { TTypeInfoProcVar - Kind = tkProcVar }
  145. TTypeInfoProcVar = class external name 'rtl.tTypeInfoProcVar'(TTypeInfo)
  146. public
  147. ProcSig: TProcedureSignature external name 'procsig';
  148. end;
  149. { TTypeInfoRefToProcVar - Kind = tkRefToProcVar }
  150. TTypeInfoRefToProcVar = class external name 'rtl.tTypeInfoRefToProcVar'(TTypeInfoProcVar)
  151. end;
  152. TMethodKind = (
  153. mkProcedure, // 0 default
  154. mkFunction, // 1
  155. mkConstructor, // 2
  156. mkDestructor, // 3
  157. mkClassProcedure,// 4
  158. mkClassFunction // 5
  159. //mkClassConstructor,mkClassDestructor,mkOperatorOverload
  160. );
  161. TMethodKinds = set of TMethodKind;
  162. { TTypeInfoMethodVar - Kind = tkMethod }
  163. TTypeInfoMethodVar = class external name 'rtl.tTypeInfoMethodVar'(TTypeInfoProcVar)
  164. public
  165. MethodKind: TMethodKind external name 'methodkind';
  166. end;
  167. TTypeMemberKind = (
  168. tmkUnknown, // 0
  169. tmkField, // 1
  170. tmkMethod, // 2
  171. tmkProperty // 3
  172. );
  173. TTypeMemberKinds = set of TTypeMemberKind;
  174. { TTypeMember }
  175. TTypeMember = class external name 'rtl.tTypeMember'
  176. public
  177. Name: String external name 'name';
  178. Kind: TTypeMemberKind external name 'kind';
  179. end;
  180. TTypeMemberDynArray = array of TTypeMember;
  181. { TTypeMemberField - Kind = tmkField }
  182. TTypeMemberField = class external name 'rtl.tTypeMemberField'(TTypeMember)
  183. public
  184. TypeInfo: TTypeInfo external name 'typeinfo';
  185. end;
  186. { TTypeMemberMethod - Kind = tmkMethod }
  187. TTypeMemberMethod = class external name 'rtl.tTypeMemberMethod'(TTypeMember)
  188. public
  189. MethodKind: TMethodKind external name 'methodkind';
  190. ProcSig: TProcedureSignature external name 'procsig';
  191. end;
  192. TTypeMemberMethodDynArray = array of TTypeMemberMethod;
  193. const
  194. pfGetFunction = 1; // getter is a function
  195. pfSetProcedure = 2; // setter is a procedure
  196. // stored is a 2-bit vector:
  197. pfStoredFalse = 4; // stored false, never
  198. pfStoredField = 8; // stored field, field name is in Stored
  199. pfStoredFunction = 12; // stored function, function name is in Stored
  200. pfHasIndex = 16; { if getter is function, append Index as last param
  201. if setter is function, append Index as second last param }
  202. type
  203. { TTypeMemberProperty - Kind = tmkProperty }
  204. TTypeMemberProperty = class external name 'rtl.tTypeMemberProperty'(TTypeMember)
  205. public
  206. TypeInfo: TTypeInfo external name 'typeinfo';
  207. Flags: NativeInt external name 'flags'; // bit vector, see pf constants above
  208. Params: TProcedureParams external name 'params'; // can be null or undefined
  209. Index: JSValue external name 'index'; // can be undefined
  210. Getter: String external name 'getter'; // name of field or function
  211. Setter: String external name 'setter'; // name of field or function
  212. Stored: String external name 'stored'; // name of field or function, can be undefined
  213. Default: JSValue external name 'Default'; // can be undefined
  214. end;
  215. TTypeMemberPropertyDynArray = array of TTypeMemberProperty;
  216. { TTypeMembers }
  217. TTypeMembers = class external name 'rtl.tTypeMembers'
  218. private
  219. function GetItems(Name: String): TTypeMember; external name '[]';
  220. procedure SetItems(Name: String; const AValue: TTypeMember); external name '[]';
  221. public
  222. property Members[Name: String]: TTypeMember read GetItems write SetItems; default;
  223. end;
  224. { TTypeInfoStruct }
  225. TTypeInfoStruct = class external name 'rtl.tTypeInfoStruct'(TTypeInfo)
  226. private
  227. FFieldCount: NativeInt external name 'fields.length';
  228. FMethodCount: NativeInt external name 'methods.length';
  229. FPropCount: NativeInt external name 'properties.length';
  230. public
  231. Members: TTypeMembers external name 'members';
  232. Names: TStringDynArray external name 'names'; // all member names with TTypeInfo
  233. Fields: TStringDynArray external name 'fields';
  234. Methods: TStringDynArray external name 'methods';
  235. Properties: TStringDynArray external name 'properties';
  236. property FieldCount: NativeInt read FFieldCount;
  237. function GetField(Index: NativeInt): TTypeMemberField; external name 'getField';
  238. function AddField(aName: String; aType: TTypeInfo; Options: TJSObject = nil
  239. ): TTypeMemberField; external name 'addField';
  240. property MethodCount: NativeInt read FMethodCount;
  241. function GetMethod(Index: NativeInt): TTypeMemberMethod; external name 'getMethod';
  242. function AddMethod(aName: String; MethodKind: TMethodKind = mkProcedure;
  243. Params: TJSArray = nil; ResultType: TTypeInfo = nil;
  244. Options: TJSObject = nil): TTypeMemberMethod; external name 'addMethod';
  245. property PropCount: NativeInt read FPropCount;
  246. function GetProp(Index: NativeInt): TTypeMemberProperty; external name 'getProperty';
  247. function AddProperty(aName: String; Flags: NativeInt; ResultType: TTypeInfo;
  248. Getter, Setter: String; Options: TJSObject = nil): TTypeMemberProperty; external name 'addProperty';
  249. end;
  250. { TTypeInfoRecord - Kind = tkRecord }
  251. TTypeInfoRecord = class external name 'rtl.tTypeInfoRecord'(TTypeInfoStruct)
  252. public
  253. RecordType: TJSObject external name 'record';
  254. end;
  255. { TTypeInfoClass - Kind = tkClass }
  256. TTypeInfoClass = class external name 'rtl.tTypeInfoClass'(TTypeInfoStruct)
  257. public
  258. ClassType: TClass external name 'class';
  259. Ancestor: TTypeInfoClass external name 'ancestor';
  260. end;
  261. { TTypeInfoClassRef - class-of, Kind = tkClassRef }
  262. TTypeInfoClassRef = class external name 'rtl.tTypeInfoClassRef'(TTypeInfo)
  263. public
  264. InstanceType: TTypeInfo external name 'instancetype';
  265. end;
  266. { TTypeInfoPointer - Kind = tkPointer }
  267. TTypeInfoPointer = class external name 'rtl.tTypeInfoPointer'(TTypeInfo)
  268. public
  269. RefType: TTypeInfo external name 'reftype'; // can be null
  270. end;
  271. { TTypeInfoInterface - Kind = tkInterface }
  272. TTypeInfoInterface = class external name 'rtl.tTypeInfoInterface'(TTypeInfoStruct)
  273. public
  274. InterfaceType: TJSObject external name 'interface';
  275. Ancestor: TTypeInfoInterface external name 'ancestor';
  276. end;
  277. EPropertyError = class(Exception);
  278. function GetClassMembers(aTIClass: TTypeInfoClass): TTypeMemberDynArray;
  279. function GetClassMember(aTIClass: TTypeInfoClass; const aName: String): TTypeMember;
  280. function GetInstanceMethod(Instance: TObject; const aName: String): Pointer;
  281. function GetClassMethods(aTIClass: TTypeInfoClass): TTypeMemberMethodDynArray;
  282. function CreateMethod(Instance: TObject; FuncName: String): Pointer; external name 'rtl.createCallback';
  283. function GetInterfaceMembers(aTIInterface: TTypeInfoInterface): TTypeMemberDynArray;
  284. function GetInterfaceMember(aTIInterface: TTypeInfoInterface; const aName: String): TTypeMember;
  285. function GetInterfaceMethods(aTIInterface: TTypeInfoInterface): TTypeMemberMethodDynArray;
  286. function GetPropInfos(aTIClass: TTypeInfoClass): TTypeMemberPropertyDynArray;
  287. function GetPropList(aTIClass: TTypeInfoClass; TypeKinds: TTypeKinds; Sorted: boolean = true): TTypeMemberPropertyDynArray;
  288. function GetPropList(aTIClass: TTypeInfoClass): TTypeMemberPropertyDynArray;
  289. function GetPropList(AClass: TClass): TTypeMemberPropertyDynArray;
  290. function GetPropList(Instance: TObject): TTypeMemberPropertyDynArray;
  291. function GetPropInfo(TI: TTypeInfoClass; const PropName: String): TTypeMemberProperty;
  292. function GetPropInfo(TI: TTypeInfoClass; const PropName: String; const Kinds: TTypeKinds): TTypeMemberProperty;
  293. function GetPropInfo(Instance: TObject; const PropName: String): TTypeMemberProperty;
  294. function GetPropInfo(Instance: TObject; const PropName: String; const Kinds: TTypeKinds): TTypeMemberProperty;
  295. function GetPropInfo(aClass: TClass; const PropName: String): TTypeMemberProperty;
  296. function GetPropInfo(aClass: TClass; const PropName: String; const Kinds: TTypeKinds): TTypeMemberProperty;
  297. function FindPropInfo(Instance: TObject; const PropName: String): TTypeMemberProperty;
  298. function FindPropInfo(Instance: TObject; const PropName: String; const Kinds: TTypeKinds): TTypeMemberProperty;
  299. function FindPropInfo(aClass: TClass; const PropName: String): TTypeMemberProperty;
  300. function FindPropInfo(aClass: TClass; const PropName: String; const Kinds: TTypeKinds): TTypeMemberProperty;
  301. // Property information routines.
  302. Function IsStoredProp(Instance: TObject; const PropInfo: TTypeMemberProperty): Boolean;
  303. Function IsStoredProp(Instance: TObject; const PropName: string): Boolean;
  304. function IsPublishedProp(Instance: TObject; const PropName: String): Boolean;
  305. function IsPublishedProp(aClass: TClass; const PropName: String): Boolean;
  306. function PropType(Instance: TObject; const PropName: string): TTypeKind;
  307. function PropType(aClass: TClass; const PropName: string): TTypeKind;
  308. function PropIsType(Instance: TObject; const PropName: string; const TypeKind: TTypeKind): Boolean;
  309. function PropIsType(aClass: TClass; const PropName: string; const TypeKind: TTypeKind): Boolean;
  310. function GetJSValueProp(Instance: TObject; const PropName: String): JSValue;
  311. function GetJSValueProp(Instance: TObject; const PropInfo: TTypeMemberProperty): JSValue;
  312. procedure SetJSValueProp(Instance: TObject; const PropName: String; Value: JSValue);
  313. procedure SetJSValueProp(Instance: TObject; const PropInfo: TTypeMemberProperty; Value: JSValue);
  314. function GetNativeIntProp(Instance: TObject; const PropName: String): NativeInt;
  315. function GetNativeIntProp(Instance: TObject; const PropInfo: TTypeMemberProperty): NativeInt;
  316. procedure SetNativeIntProp(Instance: TObject; const PropName: String; Value: NativeInt);
  317. procedure SetNativeIntProp(Instance: TObject; const PropInfo: TTypeMemberProperty; Value: NativeInt);
  318. function GetOrdProp(Instance: TObject; const PropName: String): longint;
  319. function GetOrdProp(Instance: TObject; const PropInfo: TTypeMemberProperty): longint;
  320. procedure SetOrdProp(Instance: TObject; const PropName: String; Value: longint);
  321. procedure SetOrdProp(Instance: TObject; const PropInfo: TTypeMemberProperty; Value: longint);
  322. function GetEnumProp(Instance: TObject; const PropName: String): String;
  323. function GetEnumProp(Instance: TObject; const PropInfo: TTypeMemberProperty): String;
  324. procedure SetEnumProp(Instance: TObject; const PropName: String; const Value: String);
  325. procedure SetEnumProp(Instance: TObject; const PropInfo: TTypeMemberProperty; const Value: String);
  326. // Auxiliary routines, which may be useful
  327. function GetEnumName(TypeInfo: TTypeInfoEnum; Value: Integer): String;
  328. function GetEnumValue(TypeInfo: TTypeInfoEnum; const Name: string): Longint;
  329. function GetEnumNameCount(TypeInfo: TTypeInfoEnum): Longint;
  330. function GetSetProp(Instance: TObject; const PropName: String): String; overload;
  331. function GetSetProp(Instance: TObject; const PropInfo: TTypeMemberProperty): String; overload;
  332. function GetSetPropArray(Instance: TObject; const PropName: String): TIntegerDynArray; overload;
  333. function GetSetPropArray(Instance: TObject; const PropInfo: TTypeMemberProperty): TIntegerDynArray; overload;
  334. procedure SetSetPropArray(Instance: TObject; const PropName: String; const Arr: TIntegerDynArray); overload;
  335. procedure SetSetPropArray(Instance: TObject; const PropInfo: TTypeMemberProperty; const Arr: TIntegerDynArray); overload;
  336. function GetStrProp(Instance: TObject; const PropName: String): String;
  337. function GetStrProp(Instance: TObject; const PropInfo: TTypeMemberProperty): String;
  338. procedure SetStrProp(Instance: TObject; const PropName: String; Value: String);
  339. procedure SetStrProp(Instance: TObject; const PropInfo: TTypeMemberProperty; Value: String);
  340. function GetStringProp(Instance: TObject; const PropName: String): String; deprecated; // use GetStrProp
  341. function GetStringProp(Instance: TObject; const PropInfo: TTypeMemberProperty): String; deprecated; // use GetStrProp
  342. procedure SetStringProp(Instance: TObject; const PropName: String; Value: String); deprecated; // use GetStrProp
  343. procedure SetStringProp(Instance: TObject; const PropInfo: TTypeMemberProperty; Value: String); deprecated; // use GetStrProp
  344. function GetBoolProp(Instance: TObject; const PropName: String): boolean;
  345. function GetBoolProp(Instance: TObject; const PropInfo: TTypeMemberProperty): boolean;
  346. procedure SetBoolProp(Instance: TObject; const PropName: String; Value: boolean);
  347. procedure SetBoolProp(Instance: TObject; const PropInfo: TTypeMemberProperty; Value: boolean);
  348. function GetObjectProp(Instance: TObject; const PropName: String): TObject;
  349. function GetObjectProp(Instance: TObject; const PropName: String; MinClass : TClass): TObject;
  350. function GetObjectProp(Instance: TObject; const PropInfo: TTypeMemberProperty): TObject;
  351. function GetObjectProp(Instance: TObject; const PropInfo: TTypeMemberProperty; MinClass : TClass): TObject;
  352. procedure SetObjectProp(Instance: TObject; const PropName: String; Value: TObject) ;
  353. procedure SetObjectProp(Instance: TObject; const PropInfo: TTypeMemberProperty; Value: TObject);
  354. Function GetFloatProp(Instance: TObject; const PropName: string): Double;
  355. Function GetFloatProp(Instance: TObject; PropInfo : TTypeMemberProperty) : Double;
  356. Procedure SetFloatProp(Instance: TObject; const PropName: string; Value: Double);
  357. Procedure SetFloatProp(Instance: TObject; PropInfo : TTypeMemberProperty; Value : Double);
  358. implementation
  359. function GetClassMembers(aTIClass: TTypeInfoClass): TTypeMemberDynArray;
  360. var
  361. C: TTypeInfoClass;
  362. i: Integer;
  363. PropName: String;
  364. Names: TJSObject;
  365. begin
  366. Result:=nil;
  367. Names:=TJSObject.new;
  368. C:=aTIClass;
  369. while C<>nil do
  370. begin
  371. for i:=0 to length(C.Names)-1 do
  372. begin
  373. PropName:=C.Names[i];
  374. if Names.hasOwnProperty(PropName) then continue;
  375. TJSArray(Result).push(C.Members[PropName]);
  376. Names[PropName]:=true;
  377. end;
  378. C:=C.Ancestor;
  379. end;
  380. end;
  381. function GetClassMember(aTIClass: TTypeInfoClass; const aName: String): TTypeMember;
  382. var
  383. C: TTypeInfoClass;
  384. i: Integer;
  385. begin
  386. // quick search: case sensitive
  387. C:=aTIClass;
  388. while C<>nil do
  389. begin
  390. if TJSObject(C.Members).hasOwnProperty(aName) then
  391. exit(C.Members[aName]);
  392. C:=C.Ancestor;
  393. end;
  394. // slow search: case insensitive
  395. C:=aTIClass;
  396. while C<>nil do
  397. begin
  398. for i:=0 to length(C.Names)-1 do
  399. if CompareText(C.Names[i],aName)=0 then
  400. exit(C.Members[C.Names[i]]);
  401. C:=C.Ancestor;
  402. end;
  403. Result:=nil;
  404. end;
  405. function GetInstanceMethod(Instance: TObject; const aName: String): Pointer;
  406. var
  407. TI: TTypeMember;
  408. begin
  409. if Instance=nil then exit(nil);
  410. TI:=GetClassMember(TypeInfo(Instance),aName);
  411. if not (TI is TTypeMemberMethod) then exit(nil);
  412. Result:=CreateMethod(Instance,TI.Name); // Note: use TI.Name for the correct case!
  413. end;
  414. function GetClassMethods(aTIClass: TTypeInfoClass): TTypeMemberMethodDynArray;
  415. var
  416. C: TTypeInfoClass;
  417. i, Cnt, j: Integer;
  418. begin
  419. Cnt:=0;
  420. C:=aTIClass;
  421. while C<>nil do
  422. begin
  423. inc(Cnt,C.MethodCount);
  424. C:=C.Ancestor;
  425. end;
  426. SetLength(Result,Cnt);
  427. C:=aTIClass;
  428. i:=0;
  429. while C<>nil do
  430. begin
  431. for j:=0 to C.MethodCount-1 do
  432. begin
  433. Result[i]:=TTypeMemberMethod(C.Members[C.Methods[j]]);
  434. inc(i);
  435. end;
  436. C:=C.Ancestor;
  437. end;
  438. end;
  439. function GetInterfaceMembers(aTIInterface: TTypeInfoInterface
  440. ): TTypeMemberDynArray;
  441. var
  442. Intf: TTypeInfoInterface;
  443. i, Cnt, j: Integer;
  444. begin
  445. Cnt:=0;
  446. Intf:=aTIInterface;
  447. while Intf<>nil do
  448. begin
  449. inc(Cnt,length(Intf.Names));
  450. Intf:=Intf.Ancestor;
  451. end;
  452. SetLength(Result,Cnt);
  453. Intf:=aTIInterface;
  454. i:=0;
  455. while Intf<>nil do
  456. begin
  457. for j:=0 to length(Intf.Names)-1 do
  458. begin
  459. Result[i]:=Intf.Members[Intf.Names[j]];
  460. inc(i);
  461. end;
  462. Intf:=Intf.Ancestor;
  463. end;
  464. end;
  465. function GetInterfaceMember(aTIInterface: TTypeInfoInterface;
  466. const aName: String): TTypeMember;
  467. var
  468. Intf: TTypeInfoInterface;
  469. i: Integer;
  470. begin
  471. // quick search: case sensitive
  472. Intf:=aTIInterface;
  473. while Intf<>nil do
  474. begin
  475. if TJSObject(Intf.Members).hasOwnProperty(aName) then
  476. exit(Intf.Members[aName]);
  477. Intf:=Intf.Ancestor;
  478. end;
  479. // slow search: case insensitive
  480. Intf:=aTIInterface;
  481. while Intf<>nil do
  482. begin
  483. for i:=0 to length(Intf.Names)-1 do
  484. if CompareText(Intf.Names[i],aName)=0 then
  485. exit(Intf.Members[Intf.Names[i]]);
  486. Intf:=Intf.Ancestor;
  487. end;
  488. Result:=nil;
  489. end;
  490. function GetInterfaceMethods(aTIInterface: TTypeInfoInterface
  491. ): TTypeMemberMethodDynArray;
  492. var
  493. Intf: TTypeInfoInterface;
  494. i, Cnt, j: Integer;
  495. begin
  496. Cnt:=0;
  497. Intf:=aTIInterface;
  498. while Intf<>nil do
  499. begin
  500. inc(Cnt,Intf.MethodCount);
  501. Intf:=Intf.Ancestor;
  502. end;
  503. SetLength(Result,Cnt);
  504. Intf:=aTIInterface;
  505. i:=0;
  506. while Intf<>nil do
  507. begin
  508. for j:=0 to Intf.MethodCount-1 do
  509. begin
  510. Result[i]:=TTypeMemberMethod(Intf.Members[Intf.Methods[j]]);
  511. inc(i);
  512. end;
  513. Intf:=Intf.Ancestor;
  514. end;
  515. end;
  516. function GetPropInfos(aTIClass: TTypeInfoClass): TTypeMemberPropertyDynArray;
  517. var
  518. C: TTypeInfoClass;
  519. i: Integer;
  520. Names: TJSObject;
  521. PropName: String;
  522. begin
  523. Result:=nil;
  524. C:=aTIClass;
  525. Names:=TJSObject.new;
  526. while C<>nil do
  527. begin
  528. for i:=0 to C.PropCount-1 do
  529. begin
  530. PropName:=C.Properties[i];
  531. if Names.hasOwnProperty(PropName) then continue;
  532. TJSArray(Result).push(TTypeMemberProperty(C.Members[PropName]));
  533. Names[PropName]:=true;
  534. end;
  535. C:=C.Ancestor;
  536. end;
  537. end;
  538. function GetPropList(aTIClass: TTypeInfoClass; TypeKinds: TTypeKinds;
  539. Sorted: boolean): TTypeMemberPropertyDynArray;
  540. function NameSort(a,b: JSValue): NativeInt;
  541. begin
  542. if TTypeMemberProperty(a).Name<TTypeMemberProperty(b).Name then
  543. Result:=-1
  544. else if TTypeMemberProperty(a).Name>TTypeMemberProperty(b).Name then
  545. Result:=1
  546. else
  547. Result:=0;
  548. end;
  549. var
  550. C: TTypeInfoClass;
  551. i: Integer;
  552. Names: TJSObject;
  553. PropName: String;
  554. Prop: TTypeMemberProperty;
  555. begin
  556. Result:=nil;
  557. C:=aTIClass;
  558. Names:=TJSObject.new;
  559. while C<>nil do
  560. begin
  561. for i:=0 to C.PropCount-1 do
  562. begin
  563. PropName:=C.Properties[i];
  564. if Names.hasOwnProperty(PropName) then continue;
  565. Prop:=TTypeMemberProperty(C.Members[PropName]);
  566. if not (Prop.TypeInfo.Kind in TypeKinds) then continue;
  567. TJSArray(Result).push(Prop);
  568. Names[PropName]:=true;
  569. end;
  570. C:=C.Ancestor;
  571. end;
  572. if Sorted then
  573. TJSArray(Result).sort(@NameSort);
  574. end;
  575. function GetPropList(aTIClass: TTypeInfoClass): TTypeMemberPropertyDynArray;
  576. begin
  577. Result:=GetPropInfos(aTIClass);
  578. end;
  579. function GetPropList(AClass: TClass): TTypeMemberPropertyDynArray;
  580. begin
  581. Result:=GetPropInfos(TypeInfo(AClass));
  582. end;
  583. function GetPropList(Instance: TObject): TTypeMemberPropertyDynArray;
  584. begin
  585. Result:=GetPropList(Instance.ClassType);
  586. end;
  587. function GetPropInfo(TI: TTypeInfoClass; const PropName: String
  588. ): TTypeMemberProperty;
  589. var
  590. m: TTypeMember;
  591. i: Integer;
  592. C: TTypeInfoClass;
  593. begin
  594. // quick search case sensitive
  595. C:=TI;
  596. while C<>nil do
  597. begin
  598. m:=C.Members[PropName];
  599. if m is TTypeMemberProperty then
  600. exit(TTypeMemberProperty(m));
  601. C:=C.Ancestor;
  602. end;
  603. // slow search case insensitive
  604. Result:=nil;
  605. repeat
  606. for i:=0 to TI.PropCount-1 do
  607. if CompareText(PropName,TI.Properties[i])=0 then
  608. begin
  609. m:=TI.Members[TI.Properties[i]];
  610. if m is TTypeMemberProperty then
  611. Result:=TTypeMemberProperty(m);
  612. exit;
  613. end;
  614. TI:=TI.Ancestor;
  615. until TI=nil;
  616. end;
  617. function GetPropInfo(TI: TTypeInfoClass; const PropName: String;
  618. const Kinds: TTypeKinds): TTypeMemberProperty;
  619. begin
  620. Result:=GetPropInfo(TI,PropName);
  621. if (Kinds<>[]) and (Result<>nil) and not (Result.TypeInfo.Kind in Kinds) then
  622. Result:=nil;
  623. end;
  624. function GetPropInfo(Instance: TObject; const PropName: String
  625. ): TTypeMemberProperty;
  626. begin
  627. Result:=GetPropInfo(TypeInfo(Instance),PropName,[]);
  628. end;
  629. function GetPropInfo(Instance: TObject; const PropName: String;
  630. const Kinds: TTypeKinds): TTypeMemberProperty;
  631. begin
  632. Result:=GetPropInfo(TypeInfo(Instance),PropName,Kinds);
  633. end;
  634. function GetPropInfo(aClass: TClass; const PropName: String
  635. ): TTypeMemberProperty;
  636. begin
  637. Result:=GetPropInfo(TypeInfo(AClass),PropName,[]);
  638. end;
  639. function GetPropInfo(aClass: TClass; const PropName: String;
  640. const Kinds: TTypeKinds): TTypeMemberProperty;
  641. begin
  642. Result:=GetPropInfo(TypeInfo(AClass),PropName,Kinds);
  643. end;
  644. function FindPropInfo(Instance: TObject; const PropName: String
  645. ): TTypeMemberProperty;
  646. begin
  647. Result:=GetPropInfo(TypeInfo(Instance), PropName);
  648. if Result=nil then
  649. raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  650. end;
  651. function FindPropInfo(Instance: TObject; const PropName: String;
  652. const Kinds: TTypeKinds): TTypeMemberProperty;
  653. begin
  654. Result:=GetPropInfo(TypeInfo(Instance), PropName, Kinds);
  655. if Result=nil then
  656. raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  657. end;
  658. function FindPropInfo(aClass: TClass; const PropName: String
  659. ): TTypeMemberProperty;
  660. begin
  661. Result:=GetPropInfo(TypeInfo(aClass), PropName);
  662. if Result=nil then
  663. raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  664. end;
  665. function FindPropInfo(aClass: TClass; const PropName: String;
  666. const Kinds: TTypeKinds): TTypeMemberProperty;
  667. begin
  668. Result:=GetPropInfo(TypeInfo(aClass), PropName, Kinds);
  669. if Result=nil then
  670. raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  671. end;
  672. function IsStoredProp(Instance: TObject; const PropInfo: TTypeMemberProperty
  673. ): Boolean;
  674. type
  675. TIsStored = function: Boolean of object;
  676. begin
  677. case PropInfo.Flags and 12 of
  678. 0: Result:=true;
  679. 4: Result:=false;
  680. 8: Result:=Boolean(TJSObject(Instance)[PropInfo.Stored]);
  681. else Result:=TIsStored(TJSObject(Instance)[PropInfo.Stored])();
  682. end;
  683. end;
  684. function IsStoredProp(Instance: TObject; const PropName: string): Boolean;
  685. begin
  686. Result:=IsStoredProp(Instance,FindPropInfo(Instance,PropName));
  687. end;
  688. function IsPublishedProp(Instance: TObject; const PropName: String): Boolean;
  689. begin
  690. Result:=GetPropInfo(Instance,PropName)<>nil;
  691. end;
  692. function IsPublishedProp(aClass: TClass; const PropName: String): Boolean;
  693. begin
  694. Result:=GetPropInfo(aClass,PropName)<>nil;
  695. end;
  696. function PropType(Instance: TObject; const PropName: string): TTypeKind;
  697. begin
  698. Result:=FindPropInfo(Instance,PropName).TypeInfo.Kind;
  699. end;
  700. function PropType(aClass: TClass; const PropName: string): TTypeKind;
  701. begin
  702. Result:=FindPropInfo(aClass,PropName).TypeInfo.Kind;
  703. end;
  704. function PropIsType(Instance: TObject; const PropName: string;
  705. const TypeKind: TTypeKind): Boolean;
  706. begin
  707. Result:=PropType(Instance,PropName)=TypeKind;
  708. end;
  709. function PropIsType(aClass: TClass; const PropName: string;
  710. const TypeKind: TTypeKind): Boolean;
  711. begin
  712. Result:=PropType(aClass,PropName)=TypeKind;
  713. end;
  714. type
  715. TGetterKind = (
  716. gkNone,
  717. gkField,
  718. gkFunction,
  719. gkFunctionWithParams
  720. );
  721. function GetPropGetterKind(const PropInfo: TTypeMemberProperty): TGetterKind;
  722. begin
  723. if PropInfo.Getter='' then
  724. Result:=gkNone
  725. else if (pfGetFunction and PropInfo.Flags)>0 then
  726. begin
  727. if length(PropInfo.Params)>0 then
  728. Result:=gkFunctionWithParams
  729. else
  730. Result:=gkFunction;
  731. end
  732. else
  733. Result:=gkField;
  734. end;
  735. type
  736. TSetterKind = (
  737. skNone,
  738. skField,
  739. skProcedure,
  740. skProcedureWithParams
  741. );
  742. function GetPropSetterKind(const PropInfo: TTypeMemberProperty): TSetterKind;
  743. begin
  744. if PropInfo.Setter='' then
  745. Result:=skNone
  746. else if (pfSetProcedure and PropInfo.Flags)>0 then
  747. begin
  748. if length(PropInfo.Params)>0 then
  749. Result:=skProcedureWithParams
  750. else
  751. Result:=skProcedure;
  752. end
  753. else
  754. Result:=skField;
  755. end;
  756. function GetJSValueProp(Instance: TObject; const PropName: String): JSValue;
  757. begin
  758. Result:=GetJSValueProp(Instance,FindPropInfo(Instance,PropName));
  759. end;
  760. function GetJSValueProp(Instance: TObject; const PropInfo: TTypeMemberProperty
  761. ): JSValue;
  762. type
  763. TGetter = function: JSValue of object;
  764. TGetterWithIndex = function(Index: JSValue): JSValue of object;
  765. var
  766. gk: TGetterKind;
  767. begin
  768. gk:=GetPropGetterKind(PropInfo);
  769. case gk of
  770. gkNone:
  771. raise EPropertyError.CreateFmt(SCantReadPropertyS, [PropInfo.Name]);
  772. gkField:
  773. Result:=TJSObject(Instance)[PropInfo.Getter];
  774. gkFunction:
  775. if (pfHasIndex and PropInfo.Flags)>0 then
  776. Result:=TGetterWithIndex(TJSObject(Instance)[PropInfo.Getter])(PropInfo.Index)
  777. else
  778. Result:=TGetter(TJSObject(Instance)[PropInfo.Getter])();
  779. gkFunctionWithParams:
  780. raise EPropertyError.CreateFmt(SIndexedPropertyNeedsParams, [PropInfo.Name]);
  781. end;
  782. end;
  783. procedure SetJSValueProp(Instance: TObject; const PropName: String;
  784. Value: JSValue);
  785. begin
  786. SetJSValueProp(Instance,FindPropInfo(Instance,PropName),Value);
  787. end;
  788. procedure SetJSValueProp(Instance: TObject;
  789. const PropInfo: TTypeMemberProperty; Value: JSValue);
  790. type
  791. TSetter = procedure(Value: JSValue) of object;
  792. TSetterWithIndex = procedure(Index, Value: JSValue) of object;
  793. var
  794. sk: TSetterKind;
  795. begin
  796. sk:=GetPropSetterKind(PropInfo);
  797. case sk of
  798. skNone:
  799. raise EPropertyError.CreateFmt(SCantWritePropertyS, [PropInfo.Name]);
  800. skField:
  801. TJSObject(Instance)[PropInfo.Setter]:=Value;
  802. skProcedure:
  803. if (pfHasIndex and PropInfo.Flags)>0 then
  804. TSetterWithIndex(TJSObject(Instance)[PropInfo.Setter])(PropInfo.Index,Value)
  805. else
  806. TSetter(TJSObject(Instance)[PropInfo.Setter])(Value);
  807. skProcedureWithParams:
  808. raise EPropertyError.CreateFmt(SIndexedPropertyNeedsParams, [PropInfo.Name]);
  809. end;
  810. end;
  811. function GetNativeIntProp(Instance: TObject; const PropName: String): NativeInt;
  812. begin
  813. Result:=GetNativeIntProp(Instance,FindPropInfo(Instance,PropName));
  814. end;
  815. function GetNativeIntProp(Instance: TObject; const PropInfo: TTypeMemberProperty
  816. ): NativeInt;
  817. begin
  818. Result:=NativeInt(GetJSValueProp(Instance,PropInfo));
  819. end;
  820. procedure SetNativeIntProp(Instance: TObject; const PropName: String;
  821. Value: NativeInt);
  822. begin
  823. SetJSValueProp(Instance,FindPropInfo(Instance,PropName),Value);
  824. end;
  825. procedure SetNativeIntProp(Instance: TObject;
  826. const PropInfo: TTypeMemberProperty; Value: NativeInt);
  827. begin
  828. SetJSValueProp(Instance,PropInfo,Value);
  829. end;
  830. function GetOrdProp(Instance: TObject; const PropName: String): longint;
  831. begin
  832. Result:=GetOrdProp(Instance,FindPropInfo(Instance,PropName));
  833. end;
  834. function GetOrdProp(Instance: TObject; const PropInfo: TTypeMemberProperty
  835. ): longint;
  836. var
  837. o: TJSObject;
  838. Key: String;
  839. n: NativeInt;
  840. begin
  841. if PropInfo.TypeInfo.Kind=tkSet then
  842. begin
  843. // a set is a JS object, with the following property: o[ElementDecimal]=true
  844. o:=TJSObject(GetJSValueProp(Instance,PropInfo));
  845. Result:=0;
  846. for Key in o do
  847. begin
  848. n:=parseInt(Key,10);
  849. if n<32 then
  850. Result:=Result+(1 shl n);
  851. end;
  852. end else
  853. Result:=longint(GetJSValueProp(Instance,PropInfo));
  854. end;
  855. procedure SetOrdProp(Instance: TObject; const PropName: String; Value: longint);
  856. begin
  857. SetOrdProp(Instance,FindPropInfo(Instance,PropName),Value);
  858. end;
  859. procedure SetOrdProp(Instance: TObject; const PropInfo: TTypeMemberProperty;
  860. Value: longint);
  861. var
  862. o: TJSObject;
  863. i: Integer;
  864. begin
  865. if PropInfo.TypeInfo.Kind=tkSet then
  866. begin
  867. o:=TJSObject.new;
  868. for i:=0 to 31 do
  869. if (1 shl i) and Value>0 then
  870. o[str(i)]:=true;
  871. SetJSValueProp(Instance,PropInfo,o);
  872. end else
  873. SetJSValueProp(Instance,PropInfo,Value);
  874. end;
  875. function GetEnumProp(Instance: TObject; const PropName: String): String;
  876. begin
  877. Result:=GetEnumProp(Instance,FindPropInfo(Instance,PropName));
  878. end;
  879. function GetEnumProp(Instance: TObject; const PropInfo: TTypeMemberProperty): String;
  880. var
  881. n: NativeInt;
  882. TIEnum: TTypeInfoEnum;
  883. begin
  884. TIEnum:=PropInfo.TypeInfo as TTypeInfoEnum;
  885. n:=NativeInt(GetJSValueProp(Instance,PropInfo));
  886. if (n>=TIEnum.MinValue) and (n<=TIEnum.MaxValue) then
  887. Result:=TIEnum.EnumType.IntToName[n]
  888. else
  889. Result:=str(n);
  890. end;
  891. procedure SetEnumProp(Instance: TObject; const PropName: String;
  892. const Value: String);
  893. begin
  894. SetEnumProp(Instance,FindPropInfo(Instance,PropName),Value);
  895. end;
  896. procedure SetEnumProp(Instance: TObject; const PropInfo: TTypeMemberProperty;
  897. const Value: String);
  898. var
  899. TIEnum: TTypeInfoEnum;
  900. n: NativeInt;
  901. begin
  902. TIEnum:=PropInfo.TypeInfo as TTypeInfoEnum;
  903. n:=TIEnum.EnumType.NameToInt[Value];
  904. if not isUndefined(n) then
  905. SetJSValueProp(Instance,PropInfo,n);
  906. end;
  907. function GetEnumName(TypeInfo: TTypeInfoEnum; Value: Integer): String;
  908. begin
  909. Result:=TypeInfo.EnumType.IntToName[Value];
  910. end;
  911. function GetEnumValue(TypeInfo: TTypeInfoEnum; const Name: string): Longint;
  912. begin
  913. Result:=TypeInfo.EnumType.NameToInt[Name];
  914. end;
  915. function GetEnumNameCount(TypeInfo: TTypeInfoEnum): Longint;
  916. var
  917. o: TJSObject;
  918. l, r: LongInt;
  919. begin
  920. o:=TJSObject(TypeInfo.EnumType);
  921. // as of pas2js 1.0 the RTTI does not contain a min/max value
  922. // -> use exponential search
  923. // ToDo: adapt this once enums with gaps are supported
  924. Result:=1;
  925. while o.hasOwnProperty(String(JSValue(Result))) do
  926. Result:=Result*2;
  927. l:=Result div 2;
  928. r:=Result;
  929. while l<=r do
  930. begin
  931. Result:=(l+r) div 2;
  932. if o.hasOwnProperty(String(JSValue(Result))) then
  933. l:=Result+1
  934. else
  935. r:=Result-1;
  936. end;
  937. if o.hasOwnProperty(String(JSValue(Result))) then
  938. inc(Result);
  939. end;
  940. function GetSetProp(Instance: TObject; const PropName: String): String;
  941. begin
  942. Result:=GetSetProp(Instance,FindPropInfo(Instance,PropName));
  943. end;
  944. function GetSetProp(Instance: TObject; const PropInfo: TTypeMemberProperty
  945. ): String;
  946. var
  947. o: TJSObject;
  948. key, Value: String;
  949. n: NativeInt;
  950. TIEnum: TTypeInfoEnum;
  951. TISet: TTypeInfoSet;
  952. begin
  953. Result:='';
  954. // get enum type if available
  955. TISet:=PropInfo.TypeInfo as TTypeInfoSet;
  956. TIEnum:=nil;
  957. if TISet.CompType is TTypeInfoEnum then
  958. TIEnum:=TTypeInfoEnum(TISet.CompType);
  959. // read value
  960. o:=TJSObject(GetJSValueProp(Instance,PropInfo));
  961. // a set is a JS object, where included element is stored as: o[ElementDecimal]=true
  962. for Key in o do
  963. begin
  964. n:=parseInt(Key,10);
  965. if (TIEnum<>nil) and (n>=TIEnum.MinValue) and (n<=TIEnum.MaxValue) then
  966. Value:=TIEnum.EnumType.IntToName[n]
  967. else
  968. Value:=str(n);
  969. if Result<>'' then Result:=Result+',';
  970. Result:=Result+Value;
  971. end;
  972. Result:='['+Result+']';
  973. end;
  974. function GetSetPropArray(Instance: TObject; const PropName: String
  975. ): TIntegerDynArray;
  976. begin
  977. Result:=GetSetPropArray(Instance,FindPropInfo(Instance,PropName));
  978. end;
  979. function GetSetPropArray(Instance: TObject; const PropInfo: TTypeMemberProperty
  980. ): TIntegerDynArray;
  981. var
  982. o: TJSObject;
  983. Key: string;
  984. begin
  985. Result:=[];
  986. // read value
  987. o:=TJSObject(GetJSValueProp(Instance,PropInfo));
  988. // a set is a JS object, where included element is stored as: o[ElementDecimal]=true
  989. for Key in o do
  990. TJSArray(Result).push(parseInt(Key,10));
  991. end;
  992. procedure SetSetPropArray(Instance: TObject; const PropName: String;
  993. const Arr: TIntegerDynArray);
  994. begin
  995. SetSetPropArray(Instance,FindPropInfo(Instance,PropName),Arr);
  996. end;
  997. procedure SetSetPropArray(Instance: TObject;
  998. const PropInfo: TTypeMemberProperty; const Arr: TIntegerDynArray);
  999. var
  1000. o: TJSObject;
  1001. i: integer;
  1002. begin
  1003. o:=TJSObject.new;
  1004. for i in Arr do
  1005. o[str(i)]:=true;
  1006. SetJSValueProp(Instance,PropInfo,o);
  1007. end;
  1008. function GetStrProp(Instance: TObject; const PropName: String): String;
  1009. begin
  1010. Result:=GetStrProp(Instance,FindPropInfo(Instance,PropName));
  1011. end;
  1012. function GetStrProp(Instance: TObject; const PropInfo: TTypeMemberProperty
  1013. ): String;
  1014. begin
  1015. Result:=String(GetJSValueProp(Instance,PropInfo));
  1016. end;
  1017. procedure SetStrProp(Instance: TObject; const PropName: String; Value: String
  1018. );
  1019. begin
  1020. SetStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  1021. end;
  1022. procedure SetStrProp(Instance: TObject; const PropInfo: TTypeMemberProperty;
  1023. Value: String);
  1024. begin
  1025. SetJSValueProp(Instance,PropInfo,Value);
  1026. end;
  1027. function GetStringProp(Instance: TObject; const PropName: String): String;
  1028. begin
  1029. Result:=GetStrProp(Instance,PropName);
  1030. end;
  1031. function GetStringProp(Instance: TObject; const PropInfo: TTypeMemberProperty
  1032. ): String;
  1033. begin
  1034. Result:=GetStrProp(Instance,PropInfo);
  1035. end;
  1036. procedure SetStringProp(Instance: TObject; const PropName: String; Value: String
  1037. );
  1038. begin
  1039. SetStrProp(Instance,PropName,Value);
  1040. end;
  1041. procedure SetStringProp(Instance: TObject; const PropInfo: TTypeMemberProperty;
  1042. Value: String);
  1043. begin
  1044. SetStrProp(Instance,PropInfo,Value);
  1045. end;
  1046. function GetBoolProp(Instance: TObject; const PropName: String): boolean;
  1047. begin
  1048. Result:=GetBoolProp(Instance,FindPropInfo(Instance,PropName));
  1049. end;
  1050. function GetBoolProp(Instance: TObject; const PropInfo: TTypeMemberProperty
  1051. ): boolean;
  1052. begin
  1053. Result:=Boolean(GetJSValueProp(Instance,PropInfo));
  1054. end;
  1055. procedure SetBoolProp(Instance: TObject; const PropName: String; Value: boolean
  1056. );
  1057. begin
  1058. SetBoolProp(Instance,FindPropInfo(Instance,PropName),Value);
  1059. end;
  1060. procedure SetBoolProp(Instance: TObject; const PropInfo: TTypeMemberProperty;
  1061. Value: boolean);
  1062. begin
  1063. SetJSValueProp(Instance,PropInfo,Value);
  1064. end;
  1065. function GetObjectProp(Instance: TObject; const PropName: String): TObject;
  1066. begin
  1067. Result:=GetObjectProp(Instance,FindPropInfo(Instance,PropName));
  1068. end;
  1069. function GetObjectProp(Instance: TObject; const PropName: String; MinClass : TClass): TObject;
  1070. begin
  1071. Result:=GetObjectProp(Instance,FindPropInfo(Instance,PropName));
  1072. if (MinClass<>Nil) and (Result<>Nil) Then
  1073. if not Result.InheritsFrom(MinClass) then
  1074. Result:=Nil;
  1075. end;
  1076. function GetObjectProp(Instance: TObject; const PropInfo: TTypeMemberProperty): TObject;
  1077. begin
  1078. Result:=GetObjectProp(Instance,PropInfo,Nil);
  1079. end;
  1080. function GetObjectProp(Instance: TObject; const PropInfo: TTypeMemberProperty; MinClass : TClass): TObject;
  1081. Var
  1082. O : TObject;
  1083. begin
  1084. O:=TObject(GetJSValueProp(Instance,PropInfo));
  1085. if (MinClass<>Nil) and not O.InheritsFrom(MinClass) then
  1086. Result:=Nil
  1087. else
  1088. Result:=O;
  1089. end;
  1090. procedure SetObjectProp(Instance: TObject; const PropName: String; Value: TObject) ;
  1091. begin
  1092. SetObjectProp(Instance,FindPropInfo(Instance,PropName),Value);
  1093. end;
  1094. procedure SetObjectProp(Instance: TObject; const PropInfo: TTypeMemberProperty; Value: TObject);
  1095. begin
  1096. SetJSValueProp(Instance,PropInfo,Value);
  1097. end;
  1098. Function GetFloatProp(Instance: TObject; PropInfo : TTypeMemberProperty) : Double;
  1099. begin
  1100. Result:=Double(GetJSValueProp(Instance,PropInfo));
  1101. end;
  1102. Function GetFloatProp(Instance: TObject; const PropName: string): Double;
  1103. begin
  1104. Result:=GetFloatProp(Instance,FindPropInfo(Instance,PropName));
  1105. end;
  1106. Procedure SetFloatProp(Instance: TObject; const PropName: string; Value: Double);
  1107. begin
  1108. SetFloatProp(Instance,FindPropInfo(Instance,PropName),Value);
  1109. end;
  1110. Procedure SetFloatProp(Instance: TObject; PropInfo : TTypeMemberProperty; Value : Double);
  1111. begin
  1112. SetJSValueProp(Instance,PropInfo,Value);
  1113. end;
  1114. end.