typinfo.pas 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246
  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. function GetSetProp(Instance: TObject; const PropName: String): String; overload;
  327. function GetSetProp(Instance: TObject; const PropInfo: TTypeMemberProperty): String; overload;
  328. function GetSetPropArray(Instance: TObject; const PropName: String): TIntegerDynArray; overload;
  329. function GetSetPropArray(Instance: TObject; const PropInfo: TTypeMemberProperty): TIntegerDynArray; overload;
  330. procedure SetSetPropArray(Instance: TObject; const PropName: String; const Arr: TIntegerDynArray); overload;
  331. procedure SetSetPropArray(Instance: TObject; const PropInfo: TTypeMemberProperty; const Arr: TIntegerDynArray); overload;
  332. function GetStrProp(Instance: TObject; const PropName: String): String;
  333. function GetStrProp(Instance: TObject; const PropInfo: TTypeMemberProperty): String;
  334. procedure SetStrProp(Instance: TObject; const PropName: String; Value: String);
  335. procedure SetStrProp(Instance: TObject; const PropInfo: TTypeMemberProperty; Value: String);
  336. function GetStringProp(Instance: TObject; const PropName: String): String; deprecated; // use GetStrProp
  337. function GetStringProp(Instance: TObject; const PropInfo: TTypeMemberProperty): String; deprecated; // use GetStrProp
  338. procedure SetStringProp(Instance: TObject; const PropName: String; Value: String); deprecated; // use GetStrProp
  339. procedure SetStringProp(Instance: TObject; const PropInfo: TTypeMemberProperty; Value: String); deprecated; // use GetStrProp
  340. function GetBoolProp(Instance: TObject; const PropName: String): boolean;
  341. function GetBoolProp(Instance: TObject; const PropInfo: TTypeMemberProperty): boolean;
  342. procedure SetBoolProp(Instance: TObject; const PropName: String; Value: boolean);
  343. procedure SetBoolProp(Instance: TObject; const PropInfo: TTypeMemberProperty; Value: boolean);
  344. function GetObjectProp(Instance: TObject; const PropName: String): TObject;
  345. function GetObjectProp(Instance: TObject; const PropName: String; MinClass : TClass): TObject;
  346. function GetObjectProp(Instance: TObject; const PropInfo: TTypeMemberProperty): TObject;
  347. function GetObjectProp(Instance: TObject; const PropInfo: TTypeMemberProperty; MinClass : TClass): TObject;
  348. procedure SetObjectProp(Instance: TObject; const PropName: String; Value: TObject) ;
  349. procedure SetObjectProp(Instance: TObject; const PropInfo: TTypeMemberProperty; Value: TObject);
  350. Function GetFloatProp(Instance: TObject; const PropName: string): Double;
  351. Function GetFloatProp(Instance: TObject; PropInfo : TTypeMemberProperty) : Double;
  352. Procedure SetFloatProp(Instance: TObject; const PropName: string; Value: Double);
  353. Procedure SetFloatProp(Instance: TObject; PropInfo : TTypeMemberProperty; Value : Double);
  354. implementation
  355. function GetClassMembers(aTIClass: TTypeInfoClass): TTypeMemberDynArray;
  356. var
  357. C: TTypeInfoClass;
  358. i: Integer;
  359. PropName: String;
  360. Names: TJSObject;
  361. begin
  362. Result:=nil;
  363. Names:=TJSObject.new;
  364. C:=aTIClass;
  365. while C<>nil do
  366. begin
  367. for i:=0 to length(C.Names)-1 do
  368. begin
  369. PropName:=C.Names[i];
  370. if Names.hasOwnProperty(PropName) then continue;
  371. TJSArray(Result).push(C.Members[PropName]);
  372. Names[PropName]:=true;
  373. end;
  374. C:=C.Ancestor;
  375. end;
  376. end;
  377. function GetClassMember(aTIClass: TTypeInfoClass; const aName: String): TTypeMember;
  378. var
  379. C: TTypeInfoClass;
  380. i: Integer;
  381. begin
  382. // quick search: case sensitive
  383. C:=aTIClass;
  384. while C<>nil do
  385. begin
  386. if TJSObject(C.Members).hasOwnProperty(aName) then
  387. exit(C.Members[aName]);
  388. C:=C.Ancestor;
  389. end;
  390. // slow search: case insensitive
  391. C:=aTIClass;
  392. while C<>nil do
  393. begin
  394. for i:=0 to length(C.Names)-1 do
  395. if CompareText(C.Names[i],aName)=0 then
  396. exit(C.Members[C.Names[i]]);
  397. C:=C.Ancestor;
  398. end;
  399. Result:=nil;
  400. end;
  401. function GetInstanceMethod(Instance: TObject; const aName: String): Pointer;
  402. var
  403. TI: TTypeMember;
  404. begin
  405. if Instance=nil then exit(nil);
  406. TI:=GetClassMember(TypeInfo(Instance),aName);
  407. if not (TI is TTypeMemberMethod) then exit(nil);
  408. Result:=CreateMethod(Instance,TI.Name); // Note: use TI.Name for the correct case!
  409. end;
  410. function GetClassMethods(aTIClass: TTypeInfoClass): TTypeMemberMethodDynArray;
  411. var
  412. C: TTypeInfoClass;
  413. i, Cnt, j: Integer;
  414. begin
  415. Cnt:=0;
  416. C:=aTIClass;
  417. while C<>nil do
  418. begin
  419. inc(Cnt,C.MethodCount);
  420. C:=C.Ancestor;
  421. end;
  422. SetLength(Result,Cnt);
  423. C:=aTIClass;
  424. i:=0;
  425. while C<>nil do
  426. begin
  427. for j:=0 to C.MethodCount-1 do
  428. begin
  429. Result[i]:=TTypeMemberMethod(C.Members[C.Methods[j]]);
  430. inc(i);
  431. end;
  432. C:=C.Ancestor;
  433. end;
  434. end;
  435. function GetInterfaceMembers(aTIInterface: TTypeInfoInterface
  436. ): TTypeMemberDynArray;
  437. var
  438. Intf: TTypeInfoInterface;
  439. i, Cnt, j: Integer;
  440. begin
  441. Cnt:=0;
  442. Intf:=aTIInterface;
  443. while Intf<>nil do
  444. begin
  445. inc(Cnt,length(Intf.Names));
  446. Intf:=Intf.Ancestor;
  447. end;
  448. SetLength(Result,Cnt);
  449. Intf:=aTIInterface;
  450. i:=0;
  451. while Intf<>nil do
  452. begin
  453. for j:=0 to length(Intf.Names)-1 do
  454. begin
  455. Result[i]:=Intf.Members[Intf.Names[j]];
  456. inc(i);
  457. end;
  458. Intf:=Intf.Ancestor;
  459. end;
  460. end;
  461. function GetInterfaceMember(aTIInterface: TTypeInfoInterface;
  462. const aName: String): TTypeMember;
  463. var
  464. Intf: TTypeInfoInterface;
  465. i: Integer;
  466. begin
  467. // quick search: case sensitive
  468. Intf:=aTIInterface;
  469. while Intf<>nil do
  470. begin
  471. if TJSObject(Intf.Members).hasOwnProperty(aName) then
  472. exit(Intf.Members[aName]);
  473. Intf:=Intf.Ancestor;
  474. end;
  475. // slow search: case insensitive
  476. Intf:=aTIInterface;
  477. while Intf<>nil do
  478. begin
  479. for i:=0 to length(Intf.Names)-1 do
  480. if CompareText(Intf.Names[i],aName)=0 then
  481. exit(Intf.Members[Intf.Names[i]]);
  482. Intf:=Intf.Ancestor;
  483. end;
  484. Result:=nil;
  485. end;
  486. function GetInterfaceMethods(aTIInterface: TTypeInfoInterface
  487. ): TTypeMemberMethodDynArray;
  488. var
  489. Intf: TTypeInfoInterface;
  490. i, Cnt, j: Integer;
  491. begin
  492. Cnt:=0;
  493. Intf:=aTIInterface;
  494. while Intf<>nil do
  495. begin
  496. inc(Cnt,Intf.MethodCount);
  497. Intf:=Intf.Ancestor;
  498. end;
  499. SetLength(Result,Cnt);
  500. Intf:=aTIInterface;
  501. i:=0;
  502. while Intf<>nil do
  503. begin
  504. for j:=0 to Intf.MethodCount-1 do
  505. begin
  506. Result[i]:=TTypeMemberMethod(Intf.Members[Intf.Methods[j]]);
  507. inc(i);
  508. end;
  509. Intf:=Intf.Ancestor;
  510. end;
  511. end;
  512. function GetPropInfos(aTIClass: TTypeInfoClass): TTypeMemberPropertyDynArray;
  513. var
  514. C: TTypeInfoClass;
  515. i: Integer;
  516. Names: TJSObject;
  517. PropName: String;
  518. begin
  519. Result:=nil;
  520. C:=aTIClass;
  521. Names:=TJSObject.new;
  522. while C<>nil do
  523. begin
  524. for i:=0 to C.PropCount-1 do
  525. begin
  526. PropName:=C.Properties[i];
  527. if Names.hasOwnProperty(PropName) then continue;
  528. TJSArray(Result).push(TTypeMemberProperty(C.Members[PropName]));
  529. Names[PropName]:=true;
  530. end;
  531. C:=C.Ancestor;
  532. end;
  533. end;
  534. function GetPropList(aTIClass: TTypeInfoClass; TypeKinds: TTypeKinds;
  535. Sorted: boolean): TTypeMemberPropertyDynArray;
  536. function NameSort(a,b: JSValue): NativeInt;
  537. begin
  538. if TTypeMemberProperty(a).Name<TTypeMemberProperty(b).Name then
  539. Result:=-1
  540. else if TTypeMemberProperty(a).Name>TTypeMemberProperty(b).Name then
  541. Result:=1
  542. else
  543. Result:=0;
  544. end;
  545. var
  546. C: TTypeInfoClass;
  547. i: Integer;
  548. Names: TJSObject;
  549. PropName: String;
  550. Prop: TTypeMemberProperty;
  551. begin
  552. Result:=nil;
  553. C:=aTIClass;
  554. Names:=TJSObject.new;
  555. while C<>nil do
  556. begin
  557. for i:=0 to C.PropCount-1 do
  558. begin
  559. PropName:=C.Properties[i];
  560. if Names.hasOwnProperty(PropName) then continue;
  561. Prop:=TTypeMemberProperty(C.Members[PropName]);
  562. if not (Prop.TypeInfo.Kind in TypeKinds) then continue;
  563. TJSArray(Result).push(Prop);
  564. Names[PropName]:=true;
  565. end;
  566. C:=C.Ancestor;
  567. end;
  568. if Sorted then
  569. TJSArray(Result).sort(@NameSort);
  570. end;
  571. function GetPropList(aTIClass: TTypeInfoClass): TTypeMemberPropertyDynArray;
  572. begin
  573. Result:=GetPropInfos(aTIClass);
  574. end;
  575. function GetPropList(AClass: TClass): TTypeMemberPropertyDynArray;
  576. begin
  577. Result:=GetPropInfos(TypeInfo(AClass));
  578. end;
  579. function GetPropList(Instance: TObject): TTypeMemberPropertyDynArray;
  580. begin
  581. Result:=GetPropList(Instance.ClassType);
  582. end;
  583. function GetPropInfo(TI: TTypeInfoClass; const PropName: String
  584. ): TTypeMemberProperty;
  585. var
  586. m: TTypeMember;
  587. i: Integer;
  588. C: TTypeInfoClass;
  589. begin
  590. // quick search case sensitive
  591. C:=TI;
  592. while C<>nil do
  593. begin
  594. m:=C.Members[PropName];
  595. if m is TTypeMemberProperty then
  596. exit(TTypeMemberProperty(m));
  597. C:=C.Ancestor;
  598. end;
  599. // slow search case insensitive
  600. Result:=nil;
  601. repeat
  602. for i:=0 to TI.PropCount-1 do
  603. if CompareText(PropName,TI.Properties[i])=0 then
  604. begin
  605. m:=TI.Members[TI.Properties[i]];
  606. if m is TTypeMemberProperty then
  607. Result:=TTypeMemberProperty(m);
  608. exit;
  609. end;
  610. TI:=TI.Ancestor;
  611. until TI=nil;
  612. end;
  613. function GetPropInfo(TI: TTypeInfoClass; const PropName: String;
  614. const Kinds: TTypeKinds): TTypeMemberProperty;
  615. begin
  616. Result:=GetPropInfo(TI,PropName);
  617. if (Kinds<>[]) and (Result<>nil) and not (Result.TypeInfo.Kind in Kinds) then
  618. Result:=nil;
  619. end;
  620. function GetPropInfo(Instance: TObject; const PropName: String
  621. ): TTypeMemberProperty;
  622. begin
  623. Result:=GetPropInfo(TypeInfo(Instance),PropName,[]);
  624. end;
  625. function GetPropInfo(Instance: TObject; const PropName: String;
  626. const Kinds: TTypeKinds): TTypeMemberProperty;
  627. begin
  628. Result:=GetPropInfo(TypeInfo(Instance),PropName,Kinds);
  629. end;
  630. function GetPropInfo(aClass: TClass; const PropName: String
  631. ): TTypeMemberProperty;
  632. begin
  633. Result:=GetPropInfo(TypeInfo(AClass),PropName,[]);
  634. end;
  635. function GetPropInfo(aClass: TClass; const PropName: String;
  636. const Kinds: TTypeKinds): TTypeMemberProperty;
  637. begin
  638. Result:=GetPropInfo(TypeInfo(AClass),PropName,Kinds);
  639. end;
  640. function FindPropInfo(Instance: TObject; const PropName: String
  641. ): TTypeMemberProperty;
  642. begin
  643. Result:=GetPropInfo(TypeInfo(Instance), PropName);
  644. if Result=nil then
  645. raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  646. end;
  647. function FindPropInfo(Instance: TObject; const PropName: String;
  648. const Kinds: TTypeKinds): TTypeMemberProperty;
  649. begin
  650. Result:=GetPropInfo(TypeInfo(Instance), PropName, Kinds);
  651. if Result=nil then
  652. raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  653. end;
  654. function FindPropInfo(aClass: TClass; const PropName: String
  655. ): TTypeMemberProperty;
  656. begin
  657. Result:=GetPropInfo(TypeInfo(aClass), PropName);
  658. if Result=nil then
  659. raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  660. end;
  661. function FindPropInfo(aClass: TClass; const PropName: String;
  662. const Kinds: TTypeKinds): TTypeMemberProperty;
  663. begin
  664. Result:=GetPropInfo(TypeInfo(aClass), PropName, Kinds);
  665. if Result=nil then
  666. raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  667. end;
  668. function IsStoredProp(Instance: TObject; const PropInfo: TTypeMemberProperty
  669. ): Boolean;
  670. type
  671. TIsStored = function: Boolean of object;
  672. begin
  673. case PropInfo.Flags and 12 of
  674. 0: Result:=true;
  675. 4: Result:=false;
  676. 8: Result:=Boolean(TJSObject(Instance)[PropInfo.Stored]);
  677. else Result:=TIsStored(TJSObject(Instance)[PropInfo.Stored])();
  678. end;
  679. end;
  680. function IsStoredProp(Instance: TObject; const PropName: string): Boolean;
  681. begin
  682. Result:=IsStoredProp(Instance,FindPropInfo(Instance,PropName));
  683. end;
  684. function IsPublishedProp(Instance: TObject; const PropName: String): Boolean;
  685. begin
  686. Result:=GetPropInfo(Instance,PropName)<>nil;
  687. end;
  688. function IsPublishedProp(aClass: TClass; const PropName: String): Boolean;
  689. begin
  690. Result:=GetPropInfo(aClass,PropName)<>nil;
  691. end;
  692. function PropType(Instance: TObject; const PropName: string): TTypeKind;
  693. begin
  694. Result:=FindPropInfo(Instance,PropName).TypeInfo.Kind;
  695. end;
  696. function PropType(aClass: TClass; const PropName: string): TTypeKind;
  697. begin
  698. Result:=FindPropInfo(aClass,PropName).TypeInfo.Kind;
  699. end;
  700. function PropIsType(Instance: TObject; const PropName: string;
  701. const TypeKind: TTypeKind): Boolean;
  702. begin
  703. Result:=PropType(Instance,PropName)=TypeKind;
  704. end;
  705. function PropIsType(aClass: TClass; const PropName: string;
  706. const TypeKind: TTypeKind): Boolean;
  707. begin
  708. Result:=PropType(aClass,PropName)=TypeKind;
  709. end;
  710. type
  711. TGetterKind = (
  712. gkNone,
  713. gkField,
  714. gkFunction,
  715. gkFunctionWithParams
  716. );
  717. function GetPropGetterKind(const PropInfo: TTypeMemberProperty): TGetterKind;
  718. begin
  719. if PropInfo.Getter='' then
  720. Result:=gkNone
  721. else if (pfGetFunction and PropInfo.Flags)>0 then
  722. begin
  723. if length(PropInfo.Params)>0 then
  724. Result:=gkFunctionWithParams
  725. else
  726. Result:=gkFunction;
  727. end
  728. else
  729. Result:=gkField;
  730. end;
  731. type
  732. TSetterKind = (
  733. skNone,
  734. skField,
  735. skProcedure,
  736. skProcedureWithParams
  737. );
  738. function GetPropSetterKind(const PropInfo: TTypeMemberProperty): TSetterKind;
  739. begin
  740. if PropInfo.Setter='' then
  741. Result:=skNone
  742. else if (pfSetProcedure and PropInfo.Flags)>0 then
  743. begin
  744. if length(PropInfo.Params)>0 then
  745. Result:=skProcedureWithParams
  746. else
  747. Result:=skProcedure;
  748. end
  749. else
  750. Result:=skField;
  751. end;
  752. function GetJSValueProp(Instance: TObject; const PropName: String): JSValue;
  753. begin
  754. Result:=GetJSValueProp(Instance,FindPropInfo(Instance,PropName));
  755. end;
  756. function GetJSValueProp(Instance: TObject; const PropInfo: TTypeMemberProperty
  757. ): JSValue;
  758. type
  759. TGetter = function: JSValue of object;
  760. TGetterWithIndex = function(Index: JSValue): JSValue of object;
  761. var
  762. gk: TGetterKind;
  763. begin
  764. gk:=GetPropGetterKind(PropInfo);
  765. case gk of
  766. gkNone:
  767. raise EPropertyError.CreateFmt(SCantReadPropertyS, [PropInfo.Name]);
  768. gkField:
  769. Result:=TJSObject(Instance)[PropInfo.Getter];
  770. gkFunction:
  771. if (pfHasIndex and PropInfo.Flags)>0 then
  772. Result:=TGetterWithIndex(TJSObject(Instance)[PropInfo.Getter])(PropInfo.Index)
  773. else
  774. Result:=TGetter(TJSObject(Instance)[PropInfo.Getter])();
  775. gkFunctionWithParams:
  776. raise EPropertyError.CreateFmt(SIndexedPropertyNeedsParams, [PropInfo.Name]);
  777. end;
  778. end;
  779. procedure SetJSValueProp(Instance: TObject; const PropName: String;
  780. Value: JSValue);
  781. begin
  782. SetJSValueProp(Instance,FindPropInfo(Instance,PropName),Value);
  783. end;
  784. procedure SetJSValueProp(Instance: TObject;
  785. const PropInfo: TTypeMemberProperty; Value: JSValue);
  786. type
  787. TSetter = procedure(Value: JSValue) of object;
  788. TSetterWithIndex = procedure(Index, Value: JSValue) of object;
  789. var
  790. sk: TSetterKind;
  791. begin
  792. sk:=GetPropSetterKind(PropInfo);
  793. case sk of
  794. skNone:
  795. raise EPropertyError.CreateFmt(SCantWritePropertyS, [PropInfo.Name]);
  796. skField:
  797. TJSObject(Instance)[PropInfo.Setter]:=Value;
  798. skProcedure:
  799. if (pfHasIndex and PropInfo.Flags)>0 then
  800. TSetterWithIndex(TJSObject(Instance)[PropInfo.Setter])(PropInfo.Index,Value)
  801. else
  802. TSetter(TJSObject(Instance)[PropInfo.Setter])(Value);
  803. skProcedureWithParams:
  804. raise EPropertyError.CreateFmt(SIndexedPropertyNeedsParams, [PropInfo.Name]);
  805. end;
  806. end;
  807. function GetNativeIntProp(Instance: TObject; const PropName: String): NativeInt;
  808. begin
  809. Result:=GetNativeIntProp(Instance,FindPropInfo(Instance,PropName));
  810. end;
  811. function GetNativeIntProp(Instance: TObject; const PropInfo: TTypeMemberProperty
  812. ): NativeInt;
  813. begin
  814. Result:=NativeInt(GetJSValueProp(Instance,PropInfo));
  815. end;
  816. procedure SetNativeIntProp(Instance: TObject; const PropName: String;
  817. Value: NativeInt);
  818. begin
  819. SetJSValueProp(Instance,FindPropInfo(Instance,PropName),Value);
  820. end;
  821. procedure SetNativeIntProp(Instance: TObject;
  822. const PropInfo: TTypeMemberProperty; Value: NativeInt);
  823. begin
  824. SetJSValueProp(Instance,PropInfo,Value);
  825. end;
  826. function GetOrdProp(Instance: TObject; const PropName: String): longint;
  827. begin
  828. Result:=GetOrdProp(Instance,FindPropInfo(Instance,PropName));
  829. end;
  830. function GetOrdProp(Instance: TObject; const PropInfo: TTypeMemberProperty
  831. ): longint;
  832. var
  833. o: TJSObject;
  834. Key: String;
  835. n: NativeInt;
  836. begin
  837. if PropInfo.TypeInfo.Kind=tkSet then
  838. begin
  839. // a set is a JS object, with the following property: o[ElementDecimal]=true
  840. o:=TJSObject(GetJSValueProp(Instance,PropInfo));
  841. Result:=0;
  842. for Key in o do
  843. begin
  844. n:=parseInt(Key,10);
  845. if n<32 then
  846. Result:=Result+(1 shl n);
  847. end;
  848. end else
  849. Result:=longint(GetJSValueProp(Instance,PropInfo));
  850. end;
  851. procedure SetOrdProp(Instance: TObject; const PropName: String; Value: longint);
  852. begin
  853. SetOrdProp(Instance,FindPropInfo(Instance,PropName),Value);
  854. end;
  855. procedure SetOrdProp(Instance: TObject; const PropInfo: TTypeMemberProperty;
  856. Value: longint);
  857. var
  858. o: TJSObject;
  859. i: Integer;
  860. begin
  861. if PropInfo.TypeInfo.Kind=tkSet then
  862. begin
  863. o:=TJSObject.new;
  864. for i:=0 to 31 do
  865. if (1 shl i) and Value>0 then
  866. o[str(i)]:=true;
  867. SetJSValueProp(Instance,PropInfo,o);
  868. end else
  869. SetJSValueProp(Instance,PropInfo,Value);
  870. end;
  871. function GetEnumProp(Instance: TObject; const PropName: String): String;
  872. begin
  873. Result:=GetEnumProp(Instance,FindPropInfo(Instance,PropName));
  874. end;
  875. function GetEnumProp(Instance: TObject; const PropInfo: TTypeMemberProperty): String;
  876. var
  877. n: NativeInt;
  878. TIEnum: TTypeInfoEnum;
  879. begin
  880. TIEnum:=PropInfo.TypeInfo as TTypeInfoEnum;
  881. n:=NativeInt(GetJSValueProp(Instance,PropInfo));
  882. if (n>=TIEnum.MinValue) and (n<=TIEnum.MaxValue) then
  883. Result:=TIEnum.EnumType.IntToName[n]
  884. else
  885. Result:=str(n);
  886. end;
  887. procedure SetEnumProp(Instance: TObject; const PropName: String;
  888. const Value: String);
  889. begin
  890. SetEnumProp(Instance,FindPropInfo(Instance,PropName),Value);
  891. end;
  892. procedure SetEnumProp(Instance: TObject; const PropInfo: TTypeMemberProperty;
  893. const Value: String);
  894. var
  895. TIEnum: TTypeInfoEnum;
  896. n: NativeInt;
  897. begin
  898. TIEnum:=PropInfo.TypeInfo as TTypeInfoEnum;
  899. n:=TIEnum.EnumType.NameToInt[Value];
  900. if not isUndefined(n) then
  901. SetJSValueProp(Instance,PropInfo,n);
  902. end;
  903. function GetSetProp(Instance: TObject; const PropName: String): String;
  904. begin
  905. Result:=GetSetProp(Instance,FindPropInfo(Instance,PropName));
  906. end;
  907. function GetSetProp(Instance: TObject; const PropInfo: TTypeMemberProperty
  908. ): String;
  909. var
  910. o: TJSObject;
  911. key, Value: String;
  912. n: NativeInt;
  913. TIEnum: TTypeInfoEnum;
  914. TISet: TTypeInfoSet;
  915. begin
  916. Result:='';
  917. // get enum type if available
  918. TISet:=PropInfo.TypeInfo as TTypeInfoSet;
  919. TIEnum:=nil;
  920. if TISet.CompType is TTypeInfoEnum then
  921. TIEnum:=TTypeInfoEnum(TISet.CompType);
  922. // read value
  923. o:=TJSObject(GetJSValueProp(Instance,PropInfo));
  924. // a set is a JS object, where included element is stored as: o[ElementDecimal]=true
  925. for Key in o do
  926. begin
  927. n:=parseInt(Key,10);
  928. if (TIEnum<>nil) and (n>=TIEnum.MinValue) and (n<=TIEnum.MaxValue) then
  929. Value:=TIEnum.EnumType.IntToName[n]
  930. else
  931. Value:=str(n);
  932. if Result<>'' then Result:=Result+',';
  933. Result:=Result+Value;
  934. end;
  935. Result:='['+Result+']';
  936. end;
  937. function GetSetPropArray(Instance: TObject; const PropName: String
  938. ): TIntegerDynArray;
  939. begin
  940. Result:=GetSetPropArray(Instance,FindPropInfo(Instance,PropName));
  941. end;
  942. function GetSetPropArray(Instance: TObject; const PropInfo: TTypeMemberProperty
  943. ): TIntegerDynArray;
  944. var
  945. o: TJSObject;
  946. Key: string;
  947. begin
  948. Result:=[];
  949. // read value
  950. o:=TJSObject(GetJSValueProp(Instance,PropInfo));
  951. // a set is a JS object, where included element is stored as: o[ElementDecimal]=true
  952. for Key in o do
  953. TJSArray(Result).push(parseInt(Key,10));
  954. end;
  955. procedure SetSetPropArray(Instance: TObject; const PropName: String;
  956. const Arr: TIntegerDynArray);
  957. begin
  958. SetSetPropArray(Instance,FindPropInfo(Instance,PropName),Arr);
  959. end;
  960. procedure SetSetPropArray(Instance: TObject;
  961. const PropInfo: TTypeMemberProperty; const Arr: TIntegerDynArray);
  962. var
  963. o: TJSObject;
  964. i: integer;
  965. begin
  966. o:=TJSObject.new;
  967. for i in Arr do
  968. o[str(i)]:=true;
  969. SetJSValueProp(Instance,PropInfo,o);
  970. end;
  971. function GetStrProp(Instance: TObject; const PropName: String): String;
  972. begin
  973. Result:=GetStrProp(Instance,FindPropInfo(Instance,PropName));
  974. end;
  975. function GetStrProp(Instance: TObject; const PropInfo: TTypeMemberProperty
  976. ): String;
  977. begin
  978. Result:=String(GetJSValueProp(Instance,PropInfo));
  979. end;
  980. procedure SetStrProp(Instance: TObject; const PropName: String; Value: String
  981. );
  982. begin
  983. SetStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  984. end;
  985. procedure SetStrProp(Instance: TObject; const PropInfo: TTypeMemberProperty;
  986. Value: String);
  987. begin
  988. SetJSValueProp(Instance,PropInfo,Value);
  989. end;
  990. function GetStringProp(Instance: TObject; const PropName: String): String;
  991. begin
  992. Result:=GetStrProp(Instance,PropName);
  993. end;
  994. function GetStringProp(Instance: TObject; const PropInfo: TTypeMemberProperty
  995. ): String;
  996. begin
  997. Result:=GetStrProp(Instance,PropInfo);
  998. end;
  999. procedure SetStringProp(Instance: TObject; const PropName: String; Value: String
  1000. );
  1001. begin
  1002. SetStrProp(Instance,PropName,Value);
  1003. end;
  1004. procedure SetStringProp(Instance: TObject; const PropInfo: TTypeMemberProperty;
  1005. Value: String);
  1006. begin
  1007. SetStrProp(Instance,PropInfo,Value);
  1008. end;
  1009. function GetBoolProp(Instance: TObject; const PropName: String): boolean;
  1010. begin
  1011. Result:=GetBoolProp(Instance,FindPropInfo(Instance,PropName));
  1012. end;
  1013. function GetBoolProp(Instance: TObject; const PropInfo: TTypeMemberProperty
  1014. ): boolean;
  1015. begin
  1016. Result:=Boolean(GetJSValueProp(Instance,PropInfo));
  1017. end;
  1018. procedure SetBoolProp(Instance: TObject; const PropName: String; Value: boolean
  1019. );
  1020. begin
  1021. SetBoolProp(Instance,FindPropInfo(Instance,PropName),Value);
  1022. end;
  1023. procedure SetBoolProp(Instance: TObject; const PropInfo: TTypeMemberProperty;
  1024. Value: boolean);
  1025. begin
  1026. SetJSValueProp(Instance,PropInfo,Value);
  1027. end;
  1028. function GetObjectProp(Instance: TObject; const PropName: String): TObject;
  1029. begin
  1030. Result:=GetObjectProp(Instance,FindPropInfo(Instance,PropName));
  1031. end;
  1032. function GetObjectProp(Instance: TObject; const PropName: String; MinClass : TClass): TObject;
  1033. begin
  1034. Result:=GetObjectProp(Instance,FindPropInfo(Instance,PropName));
  1035. if (MinClass<>Nil) and (Result<>Nil) Then
  1036. if not Result.InheritsFrom(MinClass) then
  1037. Result:=Nil;
  1038. end;
  1039. function GetObjectProp(Instance: TObject; const PropInfo: TTypeMemberProperty): TObject;
  1040. begin
  1041. Result:=GetObjectProp(Instance,PropInfo,Nil);
  1042. end;
  1043. function GetObjectProp(Instance: TObject; const PropInfo: TTypeMemberProperty; MinClass : TClass): TObject;
  1044. Var
  1045. O : TObject;
  1046. begin
  1047. O:=TObject(GetJSValueProp(Instance,PropInfo));
  1048. if (MinClass<>Nil) and not O.InheritsFrom(MinClass) then
  1049. Result:=Nil
  1050. else
  1051. Result:=O;
  1052. end;
  1053. procedure SetObjectProp(Instance: TObject; const PropName: String; Value: TObject) ;
  1054. begin
  1055. SetObjectProp(Instance,FindPropInfo(Instance,PropName),Value);
  1056. end;
  1057. procedure SetObjectProp(Instance: TObject; const PropInfo: TTypeMemberProperty; Value: TObject);
  1058. begin
  1059. SetJSValueProp(Instance,PropInfo,Value);
  1060. end;
  1061. Function GetFloatProp(Instance: TObject; PropInfo : TTypeMemberProperty) : Double;
  1062. begin
  1063. Result:=Double(GetJSValueProp(Instance,PropInfo));
  1064. end;
  1065. Function GetFloatProp(Instance: TObject; const PropName: string): Double;
  1066. begin
  1067. Result:=GetFloatProp(Instance,FindPropInfo(Instance,PropName));
  1068. end;
  1069. Procedure SetFloatProp(Instance: TObject; const PropName: string; Value: Double);
  1070. begin
  1071. SetFloatProp(Instance,FindPropInfo(Instance,PropName),Value);
  1072. end;
  1073. Procedure SetFloatProp(Instance: TObject; PropInfo : TTypeMemberProperty; Value : Double);
  1074. begin
  1075. SetJSValueProp(Instance,PropInfo,Value);
  1076. end;
  1077. end.