rtti.pas 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089
  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 RTTI;
  11. {$mode objfpc}
  12. {$ModeSwitch advancedrecords}
  13. interface
  14. uses
  15. JS, RTLConsts, Types, SysUtils, TypInfo;
  16. resourcestring
  17. SErrInvokeInvalidCodeAddr = 'CodeAddress is not a function';
  18. SErrTypeIsNotEnumerated = 'Type %s is not an enumerated type';
  19. type
  20. { TValue }
  21. TValue = record
  22. private
  23. FTypeInfo: TTypeInfo;
  24. FData: JSValue;
  25. FReferenceVariableData: Boolean;
  26. function GetData: JSValue;
  27. function GetIsEmpty: boolean;
  28. function GetTypeKind: TTypeKind;
  29. procedure SetData(const Value: JSValue);
  30. public
  31. class function Empty: TValue; static;
  32. generic class function From<T>(const Value: T): TValue; static;
  33. class function FromArray(TypeInfo: TTypeInfo; const Values: specialize TArray<TValue>): TValue; static;
  34. class function FromJSValue(v: JSValue): TValue; static;
  35. class function FromOrdinal(ATypeInfo: TTypeInfo; AValue: JSValue): TValue; static;
  36. class procedure Make(const ABuffer: JSValue; const ATypeInfo: PTypeInfo; var Result: TValue); overload; static;
  37. generic class procedure Make<T>(const Value: T; var Result: TValue); overload; static;
  38. function AsBoolean: boolean;
  39. function AsClass: TClass;
  40. //ToDo: function AsCurrency: Currency;
  41. function AsExtended: Extended;
  42. function AsInteger: Integer;
  43. function AsInterface: IInterface;
  44. function AsJSValue: JSValue;
  45. function AsNativeInt: NativeInt;
  46. function AsObject: TObject;
  47. function AsOrdinal: NativeInt;
  48. function AsString: string;
  49. generic function AsType<T>: T;
  50. function AsUnicodeString: UnicodeString;
  51. function Cast(ATypeInfo: TTypeInfo; const EmptyAsAnyType: Boolean = True): TValue; overload;
  52. generic function Cast<T>(const EmptyAsAnyType: Boolean = True): TValue; overload;
  53. function IsType(ATypeInfo: TTypeInfo; const EmptyAsAnyType: Boolean = True): Boolean; overload;
  54. generic function IsType<T>(const EmptyAsAnyType: Boolean = True): Boolean; overload;
  55. function GetArrayElement(aIndex: SizeInt): TValue;
  56. function GetArrayLength: SizeInt;
  57. function IsArray: boolean;
  58. function IsClass: boolean;
  59. function IsObject: boolean;
  60. function IsObjectInstance: boolean;
  61. function IsOrdinal: boolean;
  62. function IsType(ATypeInfo: TTypeInfo): boolean;
  63. function ToString: String;
  64. function TryCast(ATypeInfo: TTypeInfo; out AResult: TValue; const EmptyAsAnyType: Boolean = True): Boolean;
  65. procedure SetArrayElement(aIndex: SizeInt; const AValue: TValue);
  66. procedure SetArrayLength(const Size: SizeInt);
  67. property IsEmpty: boolean read GetIsEmpty; // check if nil or undefined
  68. property Kind: TTypeKind read GetTypeKind;
  69. property TypeInfo: TTypeInfo read FTypeInfo;
  70. end;
  71. TRttiType = class;
  72. TRttiInstanceType = class;
  73. TRttiInstanceExternalType = class;
  74. { TRTTIContext }
  75. TRTTIContext = record
  76. public
  77. class function Create: TRTTIContext; static;
  78. procedure Free;
  79. function FindType(const AQualifiedName: String): TRttiType;
  80. function GetType(aTypeInfo: PTypeInfo): TRTTIType; overload;
  81. function GetType(aClass: TClass): TRTTIType; overload;
  82. function GetTypes: specialize TArray<TRttiType>;
  83. end;
  84. { TRttiObject }
  85. TRttiObject = class abstract
  86. private
  87. FAttributesLoaded: Boolean;
  88. FAttributes: TCustomAttributeArray;
  89. FParent: TRttiObject;
  90. FHandle: Pointer;
  91. protected
  92. function LoadCustomAttributes: TCustomAttributeArray; virtual;
  93. public
  94. constructor Create(AParent: TRttiObject; AHandle: Pointer); virtual;
  95. destructor Destroy; override;
  96. function GetAttributes: TCustomAttributeArray;
  97. property Attributes: TCustomAttributeArray read GetAttributes;
  98. property Handle: Pointer read FHandle;
  99. property Parent: TRttiObject read FParent;
  100. end;
  101. { TRttiNamedObject }
  102. TRttiNamedObject = class(TRttiObject)
  103. protected
  104. function GetName: string; virtual;
  105. public
  106. property Name: string read GetName;
  107. end;
  108. { TRttiMember }
  109. TMemberVisibility=(
  110. mvPrivate,
  111. mvProtected,
  112. mvPublic,
  113. mvPublished);
  114. TRttiMember = class(TRttiNamedObject)
  115. protected
  116. function GetMemberTypeInfo: TTypeMember;
  117. function GetName: String; override;
  118. function GetParent: TRttiType;
  119. function GetVisibility: TMemberVisibility; virtual;
  120. function LoadCustomAttributes: TCustomAttributeArray; override;
  121. public
  122. constructor Create(AParent: TRttiType; ATypeInfo: TTypeMember);
  123. property MemberTypeInfo: TTypeMember read GetMemberTypeInfo;
  124. property Parent: TRttiType read GetParent;
  125. property Visibility: TMemberVisibility read GetVisibility;
  126. end;
  127. { TRttiField }
  128. TRttiField = class(TRttiMember)
  129. private
  130. function GetFieldType: TRttiType;
  131. function GetFieldTypeInfo: TTypeMemberField;
  132. public
  133. constructor Create(AParent: TRttiType; ATypeInfo: TTypeMember);
  134. function GetValue(Instance: JSValue): TValue;
  135. procedure SetValue(Instance: JSValue; const AValue: TValue);
  136. property FieldType: TRttiType read GetFieldType;
  137. property FieldTypeInfo: TTypeMemberField read GetFieldTypeInfo;
  138. end;
  139. TRttiFieldArray = specialize TArray<TRttiField>;
  140. { TRttiParameter }
  141. TRttiParameter = class(TRttiNamedObject)
  142. private
  143. FParamType: TRttiType;
  144. FFlags: TParamFlags;
  145. FName: String;
  146. protected
  147. function GetName: string; override;
  148. public
  149. property Flags: TParamFlags read FFlags;
  150. property ParamType: TRttiType read FParamType;
  151. end;
  152. TRttiParameterArray = specialize TArray<TRttiParameter>;
  153. { TRttiMethod }
  154. TRttiMethod = class(TRttiMember)
  155. private
  156. FParameters: TRttiParameterArray;
  157. FParametersLoaded: Boolean;
  158. function GetIsAsyncCall: Boolean;
  159. function GetIsClassMethod: Boolean;
  160. function GetIsConstructor: Boolean;
  161. function GetIsDestructor: Boolean;
  162. function GetIsExternal: Boolean;
  163. function GetIsSafeCall: Boolean;
  164. function GetIsStatic: Boolean;
  165. function GetIsVarArgs: Boolean;
  166. function GetMethodKind: TMethodKind;
  167. function GetMethodTypeInfo: TTypeMemberMethod;
  168. function GetProcedureFlags: TProcedureFlags;
  169. function GetReturnType: TRttiType;
  170. procedure LoadParameters;
  171. public
  172. function GetParameters: TRttiParameterArray;
  173. function Invoke(const Instance: TValue; const Args: array of TValue): TValue;
  174. property IsAsyncCall: Boolean read GetIsAsyncCall;
  175. property IsClassMethod: Boolean read GetIsClassMethod;
  176. property IsConstructor: Boolean read GetIsConstructor;
  177. property IsDestructor: Boolean read GetIsDestructor;
  178. property IsExternal: Boolean read GetIsExternal;
  179. property IsSafeCall: Boolean read GetIsSafeCall;
  180. property IsStatic: Boolean read GetIsStatic;
  181. property MethodKind: TMethodKind read GetMethodKind;
  182. property MethodTypeInfo: TTypeMemberMethod read GetMethodTypeInfo;
  183. property ReturnType: TRttiType read GetReturnType;
  184. end;
  185. TRttiMethodArray = specialize TArray<TRttiMethod>;
  186. { TRttiProperty }
  187. TRttiProperty = class(TRttiMember)
  188. private
  189. function GetPropertyTypeInfo: TTypeMemberProperty;
  190. function GetPropertyType: TRttiType;
  191. function GetIsWritable: boolean;
  192. function GetIsReadable: boolean;
  193. protected
  194. function GetVisibility: TMemberVisibility; override;
  195. public
  196. constructor Create(AParent: TRttiType; ATypeInfo: TTypeMember);
  197. function GetValue(Instance: JSValue): TValue;
  198. procedure SetValue(Instance: JSValue; const AValue: TValue);
  199. property PropertyTypeInfo: TTypeMemberProperty read GetPropertyTypeInfo;
  200. property PropertyType: TRttiType read GetPropertyType;
  201. property IsReadable: boolean read GetIsReadable;
  202. property IsWritable: boolean read GetIsWritable;
  203. property Visibility: TMemberVisibility read GetVisibility;
  204. end;
  205. TRttiInstanceProperty = class(TRttiProperty)
  206. end;
  207. TRttiPropertyArray = specialize TArray<TRttiProperty>;
  208. { TRttiType }
  209. TRttiType = class(TRttiNamedObject)
  210. private
  211. //FMethods: specialize TArray<TRttiMethod>;
  212. function GetAsInstance: TRttiInstanceType;
  213. function GetAsInstanceExternal: TRttiInstanceExternalType;
  214. function GetHandle: TTypeInfo;
  215. function GetQualifiedName: String;
  216. protected
  217. function GetName: string; override;
  218. //function GetHandle: Pointer; override;
  219. function GetIsInstance: Boolean;
  220. function GetIsInstanceExternal: Boolean;
  221. //function GetIsManaged: Boolean; virtual;
  222. function GetIsOrdinal: Boolean; virtual;
  223. function GetIsRecord: Boolean; virtual;
  224. function GetIsSet: Boolean; virtual;
  225. function GetTypeKind: TTypeKind; virtual;
  226. //function GetTypeSize: integer; virtual;
  227. function GetBaseType: TRttiType; virtual;
  228. function LoadCustomAttributes: TCustomAttributeArray; override;
  229. public
  230. function GetField(const AName: string): TRttiField; virtual;
  231. function GetFields: TRttiFieldArray; virtual;
  232. function GetMethods: TRttiMethodArray; virtual;
  233. function GetMethods(const aName: String): TRttiMethodArray; virtual;
  234. function GetMethod(const aName: String): TRttiMethod; virtual;
  235. function GetProperty(const AName: string): TRttiProperty; virtual;
  236. //function GetIndexedProperty(const AName: string): TRttiIndexedProperty; virtual;
  237. function GetProperties: TRttiPropertyArray; virtual;
  238. function GetDeclaredProperties: TRttiPropertyArray; virtual;
  239. //function GetDeclaredIndexedProperties: TRttiIndexedPropertyArray; virtual;
  240. function GetDeclaredMethods: TRttiMethodArray; virtual;
  241. function GetDeclaredFields: TRttiFieldArray; virtual;
  242. property Handle: TTypeInfo read GetHandle;
  243. property IsInstance: Boolean read GetIsInstance;
  244. property IsInstanceExternal: Boolean read GetIsInstanceExternal;
  245. //property isManaged: Boolean read GetIsManaged;
  246. property IsOrdinal: Boolean read GetIsOrdinal;
  247. property IsRecord: Boolean read GetIsRecord;
  248. property IsSet: Boolean read GetIsSet;
  249. property BaseType: TRttiType read GetBaseType;
  250. property AsInstance: TRttiInstanceType read GetAsInstance;
  251. property AsInstanceExternal: TRttiInstanceExternalType read GetAsInstanceExternal;
  252. property TypeKind: TTypeKind read GetTypeKind;
  253. //property TypeSize: integer read GetTypeSize;
  254. property QualifiedName: String read GetQualifiedName;
  255. end;
  256. TRttiTypeClass = class of TRttiType;
  257. { TRttiStructuredType }
  258. TRttiStructuredType = class abstract(TRttiType)
  259. private
  260. FFields: TRttiFieldArray;
  261. FMethods: TRttiMethodArray;
  262. FProperties: TRttiPropertyArray;
  263. protected
  264. function GetAncestor: TRttiStructuredType; virtual;
  265. function GetStructTypeInfo: TTypeInfoStruct;
  266. public
  267. constructor Create(AParent: TRttiObject; ATypeInfo: PTypeInfo); override;
  268. destructor Destroy; override;
  269. function GetDeclaredFields: TRttiFieldArray; override;
  270. function GetDeclaredMethods: TRttiMethodArray; override;
  271. function GetDeclaredProperties: TRttiPropertyArray; override;
  272. function GetFields: TRttiFieldArray; override;
  273. function GetMethod(const aName: String): TRttiMethod; override;
  274. function GetMethods: TRttiMethodArray; override;
  275. function GetMethods(const aName: String): TRttiMethodArray; override;
  276. function GetProperties: TRttiPropertyArray; override;
  277. function GetProperty(const AName: string): TRttiProperty; override;
  278. property StructTypeInfo: TTypeInfoStruct read GetStructTypeInfo;
  279. end;
  280. { TRttiInstanceType }
  281. TRttiInstanceType = class(TRttiStructuredType)
  282. private
  283. function GetAncestorType: TRttiInstanceType;
  284. function GetClassTypeInfo: TTypeInfoClass;
  285. function GetMetaClassType: TClass;
  286. protected
  287. function GetAncestor: TRttiStructuredType; override;
  288. function GetBaseType : TRttiType; override;
  289. public
  290. constructor Create(AParent: TRttiObject; ATypeInfo: PTypeInfo); override;
  291. property BaseType : TRttiInstanceType read GetAncestorType;
  292. property Ancestor: TRttiInstanceType read GetAncestorType;
  293. property ClassTypeInfo: TTypeInfoClass read GetClassTypeInfo;
  294. property MetaClassType: TClass read GetMetaClassType;
  295. end;
  296. { TRttiInterfaceType }
  297. TRttiInterfaceType = class(TRttiStructuredType)
  298. private
  299. function GetAncestorType: TRttiInterfaceType;
  300. function GetGUID: TGUID;
  301. function GetInterfaceTypeInfo: TTypeInfoInterface;
  302. protected
  303. function GetAncestor: TRttiStructuredType; override;
  304. function GetBaseType : TRttiType; override;
  305. public
  306. constructor Create(AParent: TRttiObject; ATypeInfo: PTypeInfo); override;
  307. property BaseType : TRttiInterfaceType read GetAncestorType;
  308. property Ancestor: TRttiInterfaceType read GetAncestorType;
  309. property GUID: TGUID read GetGUID;
  310. property InterfaceTypeInfo: TTypeInfoInterface read GetInterfaceTypeInfo;
  311. end;
  312. { TRttiRecordType }
  313. TRttiRecordType = class(TRttiStructuredType)
  314. private
  315. function GetRecordTypeInfo: TTypeInfoRecord;
  316. protected
  317. function GetIsRecord: Boolean; override;
  318. public
  319. constructor Create(AParent: TRttiObject; ATypeInfo: PTypeInfo); override;
  320. property RecordTypeInfo: TTypeInfoRecord read GetRecordTypeInfo;
  321. end;
  322. { TRttiClassRefType }
  323. TRttiClassRefType = class(TRttiType)
  324. private
  325. function GetClassRefTypeInfo: TTypeInfoClassRef;
  326. function GetInstanceType: TRttiInstanceType;
  327. function GetMetaclassType: TClass;
  328. public
  329. constructor Create(AParent: TRttiObject; ATypeInfo: PTypeInfo); override;
  330. property ClassRefTypeInfo: TTypeInfoClassRef read GetClassRefTypeInfo;
  331. property InstanceType: TRttiInstanceType read GetInstanceType;
  332. property MetaclassType: TClass read GetMetaclassType;
  333. end;
  334. { TRttiInstanceExternalType }
  335. TRttiInstanceExternalType = class(TRttiType)
  336. private
  337. function GetAncestor: TRttiInstanceExternalType;
  338. function GetExternalName: String;
  339. function GetExternalClassTypeInfo: TTypeInfoExtClass;
  340. public
  341. constructor Create(AParent: TRttiObject; ATypeInfo: PTypeInfo); override;
  342. property Ancestor: TRttiInstanceExternalType read GetAncestor;
  343. property ExternalClassTypeInfo: TTypeInfoExtClass read GetExternalClassTypeInfo;
  344. property ExternalName: String read GetExternalName;
  345. end;
  346. { TRttiOrdinalType }
  347. TRttiOrdinalType = class(TRttiType)
  348. private
  349. function GetMaxValue: Integer; virtual;
  350. function GetMinValue: Integer; virtual;
  351. function GetOrdType: TOrdType;
  352. function GetOrdinalTypeInfo: TTypeInfoInteger;
  353. public
  354. constructor Create(AParent: TRttiObject; ATypeInfo: PTypeInfo); override;
  355. property OrdType: TOrdType read GetOrdType;
  356. property MinValue: Integer read GetMinValue;
  357. property MaxValue: Integer read GetMaxValue;
  358. property OrdinalTypeInfo: TTypeInfoInteger read GetOrdinalTypeInfo;
  359. end;
  360. { TRttiEnumerationType }
  361. TRttiEnumerationType = class(TRttiOrdinalType)
  362. private
  363. function GetEnumerationTypeInfo: TTypeInfoEnum;
  364. public
  365. constructor Create(AParent: TRttiObject; ATypeInfo: PTypeInfo); override;
  366. property EnumerationTypeInfo: TTypeInfoEnum read GetEnumerationTypeInfo;
  367. function GetNames: TStringArray;
  368. generic class function GetName<T>(AValue: T): String; reintroduce;
  369. generic class function GetValue<T>(const AValue: String): T;
  370. end;
  371. { TRttiDynamicArrayType }
  372. TRttiDynamicArrayType = class(TRttiType)
  373. private
  374. function GetDynArrayTypeInfo: TTypeInfoDynArray;
  375. function GetElementType: TRttiType;
  376. public
  377. constructor Create(AParent: TRttiObject; ATypeInfo: PTypeInfo); override;
  378. property DynArrayTypeInfo: TTypeInfoDynArray read GetDynArrayTypeInfo;
  379. property ElementType: TRttiType read GetElementType;
  380. end;
  381. EInvoke = EJS;
  382. TVirtualInterfaceInvokeEvent = function(const aMethodName: string;
  383. const Args: TJSValueDynArray): JSValue of object;
  384. { TVirtualInterface: A class that can implement any IInterface. Any method
  385. call is handled by the OnInvoke event. }
  386. TVirtualInterface = class(TInterfacedObject, IInterface)
  387. private
  388. FOnInvoke: TVirtualInterfaceInvokeEvent;
  389. public
  390. constructor Create(InterfaceTypeInfo: Pointer); overload; assembler;
  391. constructor Create(InterfaceTypeInfo: Pointer;
  392. const InvokeEvent: TVirtualInterfaceInvokeEvent); overload;
  393. function QueryInterface(const iid: TGuid; out obj): Integer; override;
  394. property OnInvoke: TVirtualInterfaceInvokeEvent read FOnInvoke write FOnInvoke;
  395. end;
  396. procedure CreateVirtualCorbaInterface(InterfaceTypeInfo: Pointer;
  397. const MethodImplementation: TVirtualInterfaceInvokeEvent; out IntfVar); assembler;
  398. function Invoke(ACodeAddress: Pointer; const AArgs: TJSValueDynArray;
  399. ACallConv: TCallConv; AResultType: PTypeInfo; AIsStatic: Boolean;
  400. AIsConstructor: Boolean): TValue;
  401. implementation
  402. type
  403. TRttiPoolTypes = class
  404. private
  405. FReferenceCount: Integer;
  406. FTypes: TJSObject; // maps 'modulename.typename' to TRTTIType
  407. public
  408. constructor Create;
  409. destructor Destroy; override;
  410. function FindType(const AQualifiedName: String): TRttiType;
  411. function GetType(const ATypeInfo: PTypeInfo): TRTTIType; overload;
  412. function GetType(const AClass: TClass): TRTTIType; overload;
  413. class function AcquireContext: TJSObject; static;
  414. class procedure ReleaseContext; static;
  415. end;
  416. var
  417. Pool: TRttiPoolTypes;
  418. pas: TJSObject; external name 'pas';
  419. procedure CreateVirtualCorbaInterface(InterfaceTypeInfo: Pointer;
  420. const MethodImplementation: TVirtualInterfaceInvokeEvent; out IntfVar); assembler;
  421. asm
  422. var IntfType = InterfaceTypeInfo.interface;
  423. var i = Object.create(IntfType);
  424. var o = { $name: "virtual", $fullname: "virtual" };
  425. i.$o = o;
  426. do {
  427. var names = IntfType.$names;
  428. if (!names) break;
  429. for (var j=0; j<names.length; j++){
  430. let fnname = names[j];
  431. i[fnname] = function(){ return MethodImplementation(fnname,arguments); };
  432. }
  433. IntfType = Object.getPrototypeOf(IntfType);
  434. } while(IntfType!=null);
  435. IntfVar.set(i);
  436. end;
  437. { TRttiPoolTypes }
  438. constructor TRttiPoolTypes.Create;
  439. begin
  440. inherited;
  441. FTypes := TJSObject.new;
  442. end;
  443. destructor TRttiPoolTypes.Destroy;
  444. var
  445. Key: String;
  446. RttiObject: TRttiType;
  447. begin
  448. for key in FTypes do
  449. if FTypes.hasOwnProperty(key) then
  450. begin
  451. RttiObject := TRttiType(FTypes[key]);
  452. RttiObject.Free;
  453. end;
  454. end;
  455. function TRttiPoolTypes.FindType(const AQualifiedName: String): TRttiType;
  456. var
  457. ModuleName, TypeName: String;
  458. Module: TTypeInfoModule;
  459. TypeFound: PTypeInfo;
  460. begin
  461. if FTypes.hasOwnProperty(AQualifiedName) then
  462. Result := TRttiType(FTypes[AQualifiedName])
  463. else
  464. begin
  465. Result := nil;
  466. for ModuleName in TJSObject.Keys(pas) do
  467. if AQualifiedName.StartsWith(ModuleName + '.') then
  468. begin
  469. Module := TTypeInfoModule(pas[ModuleName]);
  470. TypeName := Copy(AQualifiedName, Length(ModuleName) + 2, Length(AQualifiedName));
  471. if Module.RTTI.HasOwnProperty(TypeName) then
  472. begin
  473. TypeFound := PTypeInfo(Module.RTTI[TypeName]);
  474. Exit(GetType(TypeFound));
  475. end;
  476. end;
  477. end;
  478. end;
  479. function TRttiPoolTypes.GetType(const ATypeInfo: PTypeInfo): TRTTIType;
  480. var
  481. RttiTypeClass: array[TTypeKind] of TRttiTypeClass = (
  482. nil, // tkUnknown
  483. TRttiOrdinalType, // tkInteger
  484. TRttiOrdinalType, // tkChar
  485. TRttiType, // tkString
  486. TRttiEnumerationType, // tkEnumeration
  487. TRttiType, // tkSet
  488. TRttiType, // tkDouble
  489. TRttiType, // tkBool
  490. TRttiType, // tkProcVar
  491. TRttiType, // tkMethod
  492. TRttiType, // tkArray
  493. TRttiDynamicArrayType, // tkDynArray
  494. TRttiRecordType, // tkRecord
  495. TRttiInstanceType, // tkClass
  496. TRttiClassRefType, // tkClassRef
  497. TRttiType, // tkPointer
  498. TRttiType, // tkJSValue
  499. TRttiType, // tkRefToProcVar
  500. TRttiInterfaceType, // tkInterface
  501. TRttiType, // tkHelper
  502. TRttiInstanceExternalType // tkExtClass
  503. );
  504. TheType: TTypeInfo absolute ATypeInfo;
  505. Name: String;
  506. Parent: TRttiObject;
  507. begin
  508. if IsNull(ATypeInfo) or IsUndefined(ATypeInfo) then
  509. Exit(nil);
  510. Name := TheType.Name;
  511. if isModule(TheType.Module) then
  512. Name := TheType.Module.Name + '.' + Name;
  513. if FTypes.hasOwnProperty(Name) then
  514. Result := TRttiType(FTypes[Name])
  515. else
  516. begin
  517. if (TheType.Kind in [tkClass, tkInterface, tkHelper, tkExtClass]) and TJSObject(TheType).hasOwnProperty('ancestor') then
  518. Parent := GetType(PTypeInfo(TJSObject(TheType)['ancestor']))
  519. else
  520. Parent := nil;
  521. Result := RttiTypeClass[TheType.Kind].Create(Parent, ATypeInfo);
  522. FTypes[Name] := Result;
  523. end;
  524. end;
  525. function TRttiPoolTypes.GetType(const AClass: TClass): TRTTIType;
  526. begin
  527. if AClass = nil then
  528. Exit(nil);
  529. Result := GetType(TypeInfo(AClass));
  530. end;
  531. class function TRttiPoolTypes.AcquireContext: TJSObject;
  532. begin
  533. if not Assigned(Pool) then
  534. Pool := TRttiPoolTypes.Create;
  535. Result := Pool.FTypes;
  536. Inc(Pool.FReferenceCount);
  537. end;
  538. class procedure TRttiPoolTypes.ReleaseContext;
  539. var
  540. Key: String;
  541. RttiObject: TRttiType;
  542. begin
  543. Dec(Pool.FReferenceCount);
  544. if Pool.FReferenceCount = 0 then
  545. FreeAndNil(Pool);
  546. end;
  547. { TRttiDynamicArrayType }
  548. function TRttiDynamicArrayType.GetDynArrayTypeInfo: TTypeInfoDynArray;
  549. begin
  550. Result := TTypeInfoDynArray(inherited Handle);
  551. end;
  552. function TRttiDynamicArrayType.GetElementType: TRttiType;
  553. begin
  554. Result := Pool.GetType(DynArrayTypeInfo.ElType);
  555. end;
  556. constructor TRttiDynamicArrayType.Create(AParent: TRttiObject; ATypeInfo: PTypeInfo);
  557. begin
  558. if not (TTypeInfo(ATypeInfo) is TTypeInfoDynArray) then
  559. raise EInvalidCast.Create('');
  560. inherited;
  561. end;
  562. { TRttiOrdinalType }
  563. function TRttiOrdinalType.GetMaxValue: Integer;
  564. begin
  565. Result := OrdinalTypeInfo.MaxValue;
  566. end;
  567. function TRttiOrdinalType.GetMinValue: Integer;
  568. begin
  569. Result := OrdinalTypeInfo.MinValue;
  570. end;
  571. function TRttiOrdinalType.GetOrdType: TOrdType;
  572. begin
  573. Result := OrdinalTypeInfo.OrdType;
  574. end;
  575. function TRttiOrdinalType.GetOrdinalTypeInfo: TTypeInfoInteger;
  576. begin
  577. Result := TTypeInfoInteger(inherited Handle);
  578. end;
  579. constructor TRttiOrdinalType.Create(AParent: TRttiObject; ATypeInfo: PTypeInfo);
  580. begin
  581. if not (TTypeInfo(ATypeInfo) is TTypeInfoInteger) then
  582. raise EInvalidCast.Create('');
  583. inherited;
  584. end;
  585. { TRttiEnumerationType }
  586. function TRttiEnumerationType.GetEnumerationTypeInfo: TTypeInfoEnum;
  587. begin
  588. Result := TTypeInfoEnum(inherited Handle);
  589. end;
  590. function TRttiEnumerationType.GetNames: TStringArray;
  591. var
  592. A, NamesSize: Integer;
  593. begin
  594. NamesSize := GetEnumNameCount(EnumerationTypeInfo);
  595. SetLength(Result, NamesSize);
  596. for A := 0 to Pred(NamesSize) do
  597. Result[A] := EnumerationTypeInfo.EnumType.IntToName[A + MinValue];
  598. end;
  599. generic class function TRttiEnumerationType.GetName<T>(AValue: T): String;
  600. Var
  601. P : PTypeInfo;
  602. begin
  603. P:=TypeInfo(T);
  604. if not (TTypeInfo(P).kind=tkEnumeration) then
  605. raise EInvalidCast.CreateFmt(SErrTypeIsNotEnumerated,[TTypeInfo(P).Name]);
  606. Result := GetEnumName(TTypeInfoEnum(P), Integer(JSValue(AValue)));
  607. end;
  608. generic class function TRttiEnumerationType.GetValue<T>(const AValue: String): T;
  609. Var
  610. P : PTypeInfo;
  611. begin
  612. P:=TypeInfo(T);
  613. if not (TTypeInfo(P).kind=tkEnumeration) then
  614. raise EInvalidCast.CreateFmt(SErrTypeIsNotEnumerated,[TTypeInfo(P).Name]);
  615. Result := T(JSValue(GetEnumValue(TTypeInfoEnum(TypeInfo(T)), AValue)));
  616. end;
  617. constructor TRttiEnumerationType.Create(AParent: TRttiObject; ATypeInfo: PTypeInfo);
  618. begin
  619. if not (TTypeInfo(ATypeInfo) is TTypeInfoEnum) then
  620. raise EInvalidCast.Create('');
  621. inherited;
  622. end;
  623. { TValue }
  624. function TValue.GetTypeKind: TTypeKind;
  625. begin
  626. if TypeInfo=nil then
  627. Result:=tkUnknown
  628. else
  629. Result:=FTypeInfo.Kind;
  630. end;
  631. generic function TValue.AsType<T>: T;
  632. begin
  633. if IsEmpty then
  634. Result := Default(T)
  635. else
  636. Result := T(AsJSValue)
  637. end;
  638. generic class function TValue.From<T>(const Value: T): TValue;
  639. begin
  640. Make(Value, System.TypeInfo(T), Result);
  641. end;
  642. class procedure TValue.Make(const ABuffer: JSValue; const ATypeInfo: PTypeInfo; var Result: TValue);
  643. begin
  644. Result.FData := ABuffer;
  645. Result.FTypeInfo := ATypeInfo;
  646. end;
  647. generic class procedure TValue.Make<T>(const Value: T; var Result: TValue);
  648. begin
  649. TValue.Make(Value, System.TypeInfo(T), Result);
  650. end;
  651. function TValue.Cast(ATypeInfo: TTypeInfo; const EmptyAsAnyType: Boolean): TValue;
  652. begin
  653. if not TryCast(ATypeInfo, Result, EmptyAsAnyType) then
  654. raise EInvalidCast.Create('');
  655. end;
  656. generic function TValue.Cast<T>(const EmptyAsAnyType: Boolean): TValue;
  657. begin
  658. Result := Cast(System.TypeInfo(T), EmptyAsAnyType);
  659. end;
  660. function TValue.IsType(ATypeInfo: TTypeInfo; const EmptyAsAnyType: Boolean): Boolean;
  661. var
  662. AnyValue: TValue;
  663. begin
  664. Result := TryCast(ATypeInfo, AnyValue, EmptyAsAnyType);
  665. end;
  666. generic function TValue.IsType<T>(const EmptyAsAnyType: Boolean): Boolean;
  667. begin
  668. Result := IsType(System.TypeInfo(T), EmptyAsAnyType);
  669. end;
  670. function TValue.TryCast(ATypeInfo: TTypeInfo; out AResult: TValue; const EmptyAsAnyType: Boolean): Boolean;
  671. function ConversionAccepted: TTypeKinds;
  672. begin
  673. case TypeInfo.Kind of
  674. tkString: Exit([tkChar, tkString]);
  675. tkDouble: Exit([tkInteger, tkDouble]);
  676. tkEnumeration: Exit([tkInteger, tkEnumeration]);
  677. else Exit([TypeInfo.Kind]);
  678. end;
  679. end;
  680. begin
  681. if EmptyAsAnyType and IsEmpty then
  682. begin
  683. AResult := TValue.Empty;
  684. if ATypeInfo <> nil then
  685. begin
  686. AResult.FTypeInfo := ATypeInfo;
  687. case ATypeInfo.Kind of
  688. tkBool: AResult.SetData(False);
  689. tkChar: AResult.SetData(#0);
  690. tkString: AResult.SetData(EmptyStr);
  691. tkDouble,
  692. tkEnumeration,
  693. tkInteger: AResult.SetData(0);
  694. end;
  695. Exit(True);
  696. end;
  697. end;
  698. if not EmptyAsAnyType and (FTypeInfo = nil) then
  699. Exit(False);
  700. if FTypeInfo = ATypeInfo then
  701. begin
  702. AResult := Self;
  703. Exit(True);
  704. end;
  705. if ATypeInfo = nil then
  706. Exit(False);
  707. if ATypeInfo = System.TypeInfo(TValue) then
  708. begin
  709. TValue.Make(Self, System.TypeInfo(TValue), AResult);
  710. Exit(True);
  711. end;
  712. Result := ATypeInfo.Kind in ConversionAccepted;
  713. if Result then
  714. begin
  715. AResult.SetData(FData);
  716. AResult.FTypeInfo := ATypeInfo;
  717. end;
  718. end;
  719. class function TValue.FromJSValue(v: JSValue): TValue;
  720. var
  721. i: NativeInt;
  722. TypeOfValue: TTypeInfo;
  723. begin
  724. case jsTypeOf(v) of
  725. 'number':
  726. if JS.isInteger(v) then
  727. begin
  728. i:=NativeInt(v);
  729. if (i>=low(integer)) and (i<=high(integer)) then
  730. TypeOfValue:=System.TypeInfo(Integer)
  731. else
  732. TypeOfValue:=System.TypeInfo(NativeInt);
  733. end
  734. else
  735. TypeOfValue:=system.TypeInfo(Double);
  736. 'string': TypeOfValue:=System.TypeInfo(String);
  737. 'boolean': TypeOfValue:=System.TypeInfo(Boolean);
  738. 'object':
  739. if v=nil then
  740. Exit(TValue.Empty)
  741. else if JS.isClass(v) and JS.isExt(v,TObject) then
  742. TypeOfValue:=System.TypeInfo(TClass(v))
  743. else if JS.isObject(v) and JS.isExt(v,TObject) then
  744. TypeOfValue:=System.TypeInfo(TObject(v))
  745. else if isRecord(v) then
  746. TypeOfValue:=System.TypeInfo(TObject(v))
  747. else if TJSArray.IsArray(V) then
  748. TypeOfValue:=System.TypeInfo(TObject(v))
  749. else
  750. raise EInvalidCast.Create('Type not recognized in FromJSValue!');
  751. else
  752. TypeOfValue:=System.TypeInfo(JSValue);
  753. end;
  754. Make(v, TypeOfValue, Result);
  755. end;
  756. class function TValue.FromArray(TypeInfo: TTypeInfo; const Values: specialize TArray<TValue>): TValue;
  757. var
  758. A: Integer;
  759. DynTypeInfo: TTypeInfoDynArray absolute TypeInfo;
  760. NewArray: TJSArray;
  761. ElementType: TTypeInfo;
  762. begin
  763. if TypeInfo.Kind <> tkDynArray then
  764. raise EInvalidCast.Create('Type not an array in FromArray!');
  765. ElementType := DynTypeInfo.ElType;
  766. NewArray := TJSArray.new;
  767. NewArray.Length := Length(Values);
  768. for A := 0 to High(Values) do
  769. NewArray[A] := Values[A].Cast(ElementType).AsJSValue;
  770. Result.SetData(NewArray);
  771. Result.FTypeInfo := TypeInfo;
  772. end;
  773. class function TValue.FromOrdinal(ATypeInfo: TTypeInfo; AValue: JSValue): TValue;
  774. begin
  775. if (ATypeInfo = nil) or not (ATypeInfo.Kind in [tkBool, tkEnumeration, tkInteger]) then
  776. raise EInvalidCast.Create('Invalid type in FromOrdinal');
  777. if ATypeInfo.Kind = tkBool then
  778. TValue.Make(AValue = True, ATypeInfo, Result)
  779. else
  780. TValue.Make(NativeInt(AValue), ATypeInfo, Result);
  781. end;
  782. function TValue.IsObject: boolean;
  783. begin
  784. Result:=IsEmpty or (TypeInfo.Kind=tkClass);
  785. end;
  786. function TValue.AsObject: TObject;
  787. begin
  788. if IsObject or (IsClass and not JS.IsObject(GetData)) then
  789. Result := TObject(GetData)
  790. else
  791. raise EInvalidCast.Create(SErrInvalidTypecast);
  792. end;
  793. function TValue.IsObjectInstance: boolean;
  794. begin
  795. Result:=(TypeInfo<>nil) and (TypeInfo.Kind=tkClass);
  796. end;
  797. function TValue.IsArray: boolean;
  798. begin
  799. case Kind of
  800. tkDynArray: Exit(True);
  801. tkArray: Exit(Length(TTypeInfoStaticArray(FTypeInfo).Dims) = 1);
  802. else Result := False;
  803. end;
  804. end;
  805. function TValue.IsClass: boolean;
  806. var
  807. k: TTypeKind;
  808. begin
  809. k:=Kind;
  810. Result := (k = tkClassRef) or ((k in [tkClass,tkUnknown]) and not JS.IsObject(GetData));
  811. end;
  812. function TValue.AsClass: TClass;
  813. begin
  814. if IsClass then
  815. Result := TClass(GetData)
  816. else
  817. raise EInvalidCast.Create(SErrInvalidTypecast);
  818. end;
  819. function TValue.IsOrdinal: boolean;
  820. begin
  821. Result := IsEmpty or (Kind in [tkBool, tkInteger, tkChar, tkEnumeration]);
  822. end;
  823. function TValue.AsOrdinal: NativeInt;
  824. begin
  825. if IsOrdinal then
  826. Result:=NativeInt(GetData)
  827. else
  828. raise EInvalidCast.Create(SErrInvalidTypecast);
  829. end;
  830. function TValue.AsBoolean: boolean;
  831. begin
  832. if (Kind = tkBool) then
  833. Result:=boolean(GetData)
  834. else
  835. raise EInvalidCast.Create(SErrInvalidTypecast);
  836. end;
  837. function TValue.AsInteger: Integer;
  838. begin
  839. if JS.isInteger(GetData) then
  840. Result:=NativeInt(GetData)
  841. else
  842. raise EInvalidCast.Create(SErrInvalidTypecast);
  843. end;
  844. function TValue.AsNativeInt: NativeInt;
  845. begin
  846. if JS.isInteger(GetData) then
  847. Result:=NativeInt(GetData)
  848. else
  849. raise EInvalidCast.Create(SErrInvalidTypecast);
  850. end;
  851. function TValue.AsInterface: IInterface;
  852. var
  853. k: TTypeKind;
  854. begin
  855. k:=Kind;
  856. if k = tkInterface then
  857. Result := IInterface(GetData)// ToDo
  858. else if (k in [tkClass, tkClassRef, tkUnknown]) and not JS.isObject(GetData) then
  859. Result := Nil
  860. else
  861. raise EInvalidCast.Create(SErrInvalidTypecast);
  862. end;
  863. function TValue.AsString: string;
  864. begin
  865. if js.isString(GetData) then
  866. Result:=String(GetData)
  867. else
  868. raise EInvalidCast.Create(SErrInvalidTypecast);
  869. end;
  870. function TValue.AsUnicodeString: UnicodeString;
  871. begin
  872. Result:=AsString;
  873. end;
  874. function TValue.AsExtended: Extended;
  875. begin
  876. if js.isNumber(GetData) then
  877. Result:=Double(GetData)
  878. else
  879. raise EInvalidCast.Create(SErrInvalidTypecast);
  880. end;
  881. function TValue.ToString: String;
  882. begin
  883. case Kind of
  884. tkString: Result := AsString;
  885. tkInteger: Result := IntToStr(AsNativeInt);
  886. tkBool: Result := BoolToStr(AsBoolean, True);
  887. else
  888. Result := '';
  889. end;
  890. end;
  891. function TValue.GetArrayLength: SizeInt;
  892. begin
  893. if IsArray then
  894. Exit(Length(TJSValueDynArray(GetData)));
  895. raise EInvalidCast.Create(SErrInvalidTypecast);
  896. end;
  897. function TValue.GetArrayElement(aIndex: SizeInt): TValue;
  898. begin
  899. if IsArray then
  900. begin
  901. case Kind of
  902. tkArray: Result.FTypeInfo:=TTypeInfoStaticArray(FTypeInfo).ElType;
  903. tkDynArray: Result.FTypeInfo:=TTypeInfoDynArray(FTypeInfo).ElType;
  904. end;
  905. Result.SetData(TJSValueDynArray(GetData)[aIndex]);
  906. end
  907. else
  908. raise EInvalidCast.Create(SErrInvalidTypecast);
  909. end;
  910. procedure TValue.SetArrayLength(const Size: SizeInt);
  911. var
  912. NewArray: TJSValueDynArray;
  913. begin
  914. NewArray := TJSValueDynArray(GetData);
  915. SetLength(NewArray, Size);
  916. SetData(NewArray);
  917. end;
  918. procedure TValue.SetArrayElement(aIndex: SizeInt; const AValue: TValue);
  919. begin
  920. if IsArray then
  921. TJSValueDynArray(GetData)[aIndex] := AValue.AsJSValue
  922. else
  923. raise EInvalidCast.Create(SErrInvalidTypecast);
  924. end;
  925. function TValue.IsType(ATypeInfo: TTypeInfo): boolean;
  926. begin
  927. Result := ATypeInfo = TypeInfo;
  928. end;
  929. function TValue.GetData: JSValue;
  930. begin
  931. if FReferenceVariableData then
  932. Result := TReferenceVariable(FData).Get
  933. else
  934. Result := FData;
  935. end;
  936. procedure TValue.SetData(const Value: JSValue);
  937. begin
  938. if FReferenceVariableData then
  939. TReferenceVariable(FData).&Set(Value)
  940. else
  941. FData := Value;
  942. end;
  943. function TValue.GetIsEmpty: boolean;
  944. begin
  945. if (TypeInfo=nil) or (GetData=Undefined) or (GetData=nil) then
  946. exit(true);
  947. case TypeInfo.Kind of
  948. tkDynArray:
  949. Result:=GetArrayLength=0;
  950. else
  951. Result:=false;
  952. end;
  953. end;
  954. function TValue.AsJSValue: JSValue;
  955. begin
  956. Result := GetData;
  957. end;
  958. class function TValue.Empty: TValue;
  959. begin
  960. Result.SetData(nil);
  961. Result.FTypeInfo := nil;
  962. end;
  963. { TRttiStructuredType }
  964. function TRttiStructuredType.GetMethods: TRttiMethodArray;
  965. var
  966. A, Start: Integer;
  967. BaseClass: TRttiStructuredType;
  968. Declared: TRttiMethodArray;
  969. begin
  970. BaseClass := Self;
  971. Result := nil;
  972. while Assigned(BaseClass) do
  973. begin
  974. Declared := BaseClass.GetDeclaredMethods;
  975. Start := Length(Result);
  976. SetLength(Result, Start + Length(Declared));
  977. for A := Low(Declared) to High(Declared) do
  978. Result[Start + A] := Declared[A];
  979. BaseClass := BaseClass.GetAncestor;
  980. end;
  981. end;
  982. function TRttiStructuredType.GetMethods(const aName: String): TRttiMethodArray;
  983. var
  984. Method: TRttiMethod;
  985. MethodCount: Integer;
  986. begin
  987. MethodCount := 0;
  988. for Method in GetMethods do
  989. if aName = Method.Name then
  990. Inc(MethodCount);
  991. SetLength(Result, MethodCount);
  992. for Method in GetMethods do
  993. if aName = Method.Name then
  994. begin
  995. Dec(MethodCount);
  996. Result[MethodCount] := Method;
  997. end;
  998. end;
  999. function TRttiStructuredType.GetProperties: TRttiPropertyArray;
  1000. var
  1001. A, Start: Integer;
  1002. BaseClass: TRttiStructuredType;
  1003. Declared: TRttiPropertyArray;
  1004. begin
  1005. BaseClass := Self;
  1006. Result := nil;
  1007. while Assigned(BaseClass) do
  1008. begin
  1009. Declared := BaseClass.GetDeclaredProperties;
  1010. Start := Length(Result);
  1011. SetLength(Result, Start + Length(Declared));
  1012. for A := Low(Declared) to High(Declared) do
  1013. Result[Start + A] := Declared[A];
  1014. BaseClass := BaseClass.GetAncestor;
  1015. end;
  1016. end;
  1017. function TRttiStructuredType.GetMethod(const aName: String): TRttiMethod;
  1018. var
  1019. Method: TRttiMethod;
  1020. begin
  1021. for Method in GetMethods do
  1022. if aName = Method.Name then
  1023. Exit(Method);
  1024. end;
  1025. function TRttiStructuredType.GetProperty(const AName: string): TRttiProperty;
  1026. var
  1027. Prop: TRttiProperty;
  1028. lName: String;
  1029. begin
  1030. lName := LowerCase(AName);
  1031. for Prop in GetProperties do
  1032. if lowercase(Prop.Name) = lName then
  1033. Exit(Prop);
  1034. Result:=nil;
  1035. end;
  1036. function TRttiStructuredType.GetDeclaredProperties: TRttiPropertyArray;
  1037. var
  1038. A, PropCount: Integer;
  1039. begin
  1040. if not Assigned(FProperties) then
  1041. begin
  1042. PropCount := StructTypeInfo.PropCount;
  1043. SetLength(FProperties, PropCount);
  1044. for A := 0 to Pred(PropCount) do
  1045. FProperties[A] := TRttiProperty.Create(Self, StructTypeInfo.GetProp(A));
  1046. end;
  1047. Result := FProperties;
  1048. end;
  1049. function TRttiStructuredType.GetAncestor: TRttiStructuredType;
  1050. begin
  1051. Result := nil;
  1052. end;
  1053. function TRttiStructuredType.GetStructTypeInfo: TTypeInfoStruct;
  1054. begin
  1055. Result:=TTypeInfoStruct(inherited Handle);
  1056. end;
  1057. constructor TRttiStructuredType.Create(AParent: TRttiObject; ATypeInfo: PTypeInfo);
  1058. begin
  1059. if not (TTypeInfo(ATypeInfo) is TTypeInfoStruct) then
  1060. raise EInvalidCast.Create('');
  1061. inherited;
  1062. end;
  1063. destructor TRttiStructuredType.Destroy;
  1064. var
  1065. Method: TRttiMethod;
  1066. Prop: TRttiProperty;
  1067. begin
  1068. for Method in FMethods do
  1069. Method.Free;
  1070. for Prop in FProperties do
  1071. Prop.Free;
  1072. inherited Destroy;
  1073. end;
  1074. function TRttiStructuredType.GetDeclaredMethods: TRttiMethodArray;
  1075. var
  1076. A, MethodCount: Integer;
  1077. begin
  1078. if not Assigned(FMethods) then
  1079. begin
  1080. MethodCount := StructTypeInfo.MethodCount;
  1081. SetLength(FMethods, MethodCount);
  1082. for A := 0 to Pred(MethodCount) do
  1083. FMethods[A] := TRttiMethod.Create(Self, StructTypeInfo.GetMethod(A));
  1084. end;
  1085. Result := FMethods;
  1086. end;
  1087. function TRttiStructuredType.GetDeclaredFields: TRttiFieldArray;
  1088. var
  1089. A, FieldCount: Integer;
  1090. begin
  1091. if not Assigned(FFields) then
  1092. begin
  1093. FieldCount := StructTypeInfo.FieldCount;
  1094. SetLength(FFields, FieldCount);
  1095. for A := 0 to Pred(FieldCount) do
  1096. FFields[A] := TRttiField.Create(Self, StructTypeInfo.GetField(A));
  1097. end;
  1098. Result := FFields;
  1099. end;
  1100. function TRttiStructuredType.GetFields: TRttiFieldArray;
  1101. var
  1102. A, Start: Integer;
  1103. BaseClass: TRttiStructuredType;
  1104. Declared: TRttiFieldArray;
  1105. begin
  1106. BaseClass := Self;
  1107. Result := nil;
  1108. while Assigned(BaseClass) do
  1109. begin
  1110. Declared := BaseClass.GetDeclaredFields;
  1111. Start := Length(Result);
  1112. SetLength(Result, Start + Length(Declared));
  1113. for A := Low(Declared) to High(Declared) do
  1114. Result[Start + A] := Declared[A];
  1115. BaseClass := BaseClass.GetAncestor;
  1116. end;
  1117. end;
  1118. { TRttiInstanceType }
  1119. function TRttiInstanceType.GetClassTypeInfo: TTypeInfoClass;
  1120. begin
  1121. Result:=TTypeInfoClass(inherited Handle);
  1122. end;
  1123. function TRttiInstanceType.GetMetaClassType: TClass;
  1124. begin
  1125. Result:=ClassTypeInfo.ClassType;
  1126. end;
  1127. function TRttiInstanceType.GetAncestor: TRttiStructuredType;
  1128. begin
  1129. Result := GetAncestorType;
  1130. end;
  1131. function TRttiInstanceType.GetBaseType: TRttiType;
  1132. begin
  1133. Result:=GetAncestorType;
  1134. end;
  1135. function TRttiInstanceType.GetAncestorType: TRttiInstanceType;
  1136. begin
  1137. Result := inherited Parent as TRttiInstanceType;
  1138. end;
  1139. constructor TRttiInstanceType.Create(AParent: TRttiObject; ATypeInfo: PTypeInfo);
  1140. begin
  1141. if not (TTypeInfo(ATypeInfo) is TTypeInfoClass) then
  1142. raise EInvalidCast.Create('');
  1143. inherited;
  1144. end;
  1145. { TRttiInterfaceType }
  1146. constructor TRttiInterfaceType.Create(AParent: TRttiObject; ATypeInfo: PTypeInfo);
  1147. begin
  1148. if not (TTypeInfo(ATypeInfo) is TTypeInfoInterface) then
  1149. raise EInvalidCast.Create('');
  1150. inherited;
  1151. end;
  1152. function TRttiInterfaceType.GetGUID: TGUID;
  1153. var
  1154. Guid: String;
  1155. begin
  1156. Guid := String(InterfaceTypeInfo.InterfaceType['$guid']);
  1157. TryStringToGUID(Guid, Result);
  1158. end;
  1159. function TRttiInterfaceType.GetInterfaceTypeInfo: TTypeInfoInterface;
  1160. begin
  1161. Result := TTypeInfoInterface(inherited Handle);
  1162. end;
  1163. function TRttiInterfaceType.GetAncestor: TRttiStructuredType;
  1164. begin
  1165. Result := GetAncestorType;
  1166. end;
  1167. function TRttiInterfaceType.GetBaseType: TRttiType;
  1168. begin
  1169. Result:=GetAncestorType;
  1170. end;
  1171. function TRttiInterfaceType.GetAncestorType: TRttiInterfaceType;
  1172. begin
  1173. Result := Pool.GetType(InterfaceTypeInfo.Ancestor) as TRttiInterfaceType;
  1174. end;
  1175. { TRttiRecordType }
  1176. function TRttiRecordType.GetRecordTypeInfo: TTypeInfoRecord;
  1177. begin
  1178. Result := TTypeInfoRecord(inherited Handle);
  1179. end;
  1180. function TRttiRecordType.GetIsRecord: Boolean;
  1181. begin
  1182. Result := True;
  1183. end;
  1184. constructor TRttiRecordType.Create(AParent: TRttiObject; ATypeInfo: PTypeInfo);
  1185. begin
  1186. if not (TTypeInfo(ATypeInfo) is TTypeInfoRecord) then
  1187. raise EInvalidCast.Create('');
  1188. inherited;
  1189. end;
  1190. { TRttiClassRefType }
  1191. constructor TRttiClassRefType.Create(AParent: TRttiObject; ATypeInfo: PTypeInfo);
  1192. begin
  1193. if not (TTypeInfo(ATypeInfo) is TTypeInfoClassRef) then
  1194. raise EInvalidCast.Create('');
  1195. inherited;
  1196. end;
  1197. function TRttiClassRefType.GetClassRefTypeInfo: TTypeInfoClassRef;
  1198. begin
  1199. Result := TTypeInfoClassRef(inherited Handle);
  1200. end;
  1201. function TRttiClassRefType.GetInstanceType: TRttiInstanceType;
  1202. begin
  1203. Result := Pool.GetType(ClassRefTypeInfo.InstanceType) as TRttiInstanceType;
  1204. end;
  1205. function TRttiClassRefType.GetMetaclassType: TClass;
  1206. begin
  1207. Result := InstanceType.MetaClassType;
  1208. end;
  1209. { TRttiInstanceExternalType }
  1210. function TRttiInstanceExternalType.GetAncestor: TRttiInstanceExternalType;
  1211. begin
  1212. Result := Pool.GetType(ExternalClassTypeInfo.Ancestor) as TRttiInstanceExternalType;
  1213. end;
  1214. function TRttiInstanceExternalType.GetExternalClassTypeInfo: TTypeInfoExtClass;
  1215. begin
  1216. Result := TTypeInfoExtClass(inherited Handle);
  1217. end;
  1218. function TRttiInstanceExternalType.GetExternalName: String;
  1219. begin
  1220. Result := ExternalClassTypeInfo.JSClassName;
  1221. end;
  1222. constructor TRttiInstanceExternalType.Create(AParent: TRttiObject; ATypeInfo: PTypeInfo);
  1223. begin
  1224. if not (TTypeInfo(ATypeInfo) is TTypeInfoExtClass) then
  1225. raise EInvalidCast.Create('');
  1226. inherited;
  1227. end;
  1228. { TRTTIContext }
  1229. class function TRTTIContext.Create: TRTTIContext;
  1230. begin
  1231. Pool.AcquireContext;
  1232. end;
  1233. procedure TRTTIContext.Free;
  1234. begin
  1235. Pool.ReleaseContext;
  1236. end;
  1237. function TRTTIContext.GetType(aTypeInfo: PTypeInfo): TRttiType;
  1238. begin
  1239. Result := Pool.GetType(aTypeInfo);
  1240. end;
  1241. function TRTTIContext.GetType(aClass: TClass): TRTTIType;
  1242. begin
  1243. Result := Pool.GetType(aClass);
  1244. end;
  1245. function TRTTIContext.FindType(const AQualifiedName: String): TRttiType;
  1246. begin
  1247. Result := Pool.FindType(AQualifiedName);
  1248. end;
  1249. function TRTTIContext.GetTypes: specialize TArray<TRttiType>;
  1250. var
  1251. ModuleName, ClassName: String;
  1252. ModuleTypes: TJSObject;
  1253. begin
  1254. for ModuleName in TJSObject.Keys(pas) do
  1255. begin
  1256. ModuleTypes := TTypeInfoModule(pas[ModuleName]).RTTI;
  1257. for ClassName in ModuleTypes do
  1258. if TJSObject(ModuleTypes[ClassName]).HasOwnProperty('name') and (ClassName[1] <> '$') then
  1259. GetType(PTypeInfo(ModuleTypes[ClassName]));
  1260. end;
  1261. Result := specialize TArray<TRttiType>(TJSObject.Values(Pool.FTypes));
  1262. end;
  1263. { TRttiObject }
  1264. constructor TRttiObject.Create(AParent: TRttiObject; AHandle: Pointer);
  1265. begin
  1266. FParent := AParent;
  1267. FHandle := AHandle;
  1268. end;
  1269. destructor TRttiObject.Destroy;
  1270. var
  1271. Attribute: TCustomAttribute;
  1272. begin
  1273. for Attribute in FAttributes do
  1274. Attribute.Free;
  1275. FAttributes := nil;
  1276. inherited Destroy;
  1277. end;
  1278. function TRttiObject.LoadCustomAttributes: TCustomAttributeArray;
  1279. begin
  1280. Result := nil;
  1281. end;
  1282. function TRttiObject.GetAttributes: TCustomAttributeArray;
  1283. begin
  1284. if not FAttributesLoaded then
  1285. begin
  1286. FAttributes := LoadCustomAttributes;
  1287. FAttributesLoaded := True;
  1288. end;
  1289. Result := FAttributes;
  1290. end;
  1291. { TRttiNamedObject }
  1292. function TRttiNamedObject.GetName: string;
  1293. begin
  1294. Result:='';
  1295. end;
  1296. { TRttiMember }
  1297. function TRttiMember.GetName: string;
  1298. begin
  1299. Result := MemberTypeInfo.Name;
  1300. end;
  1301. function TRttiMember.GetParent: TRttiType;
  1302. begin
  1303. Result := TRttiType(inherited Parent);
  1304. end;
  1305. function TRttiMember.GetVisibility: TMemberVisibility;
  1306. begin
  1307. Result := mvPublished;
  1308. end;
  1309. constructor TRttiMember.Create(AParent: TRttiType; ATypeInfo: TTypeMember);
  1310. begin
  1311. if not (ATypeInfo is TTypeMember) then
  1312. raise EInvalidCast.Create('');
  1313. inherited Create(AParent, ATypeInfo);
  1314. end;
  1315. function TRttiMember.LoadCustomAttributes: TCustomAttributeArray;
  1316. begin
  1317. Result := GetRTTIAttributes(MemberTypeInfo.Attributes);
  1318. end;
  1319. function TRttiMember.GetMemberTypeInfo: TTypeMember;
  1320. begin
  1321. Result := TTypeMember(inherited Handle);
  1322. end;
  1323. { TRttiField }
  1324. constructor TRttiField.Create(AParent: TRttiType; ATypeInfo: TTypeMember);
  1325. begin
  1326. if not (ATypeInfo is TTypeMemberField) then
  1327. raise EInvalidCast.Create('');
  1328. inherited;
  1329. end;
  1330. function TRttiField.GetFieldType: TRttiType;
  1331. begin
  1332. Result := Pool.GetType(FieldTypeInfo.TypeInfo);
  1333. end;
  1334. function TRttiField.GetFieldTypeInfo: TTypeMemberField;
  1335. begin
  1336. Result := TTypeMemberField(inherited Handle);
  1337. end;
  1338. function TRttiField.GetValue(Instance: JSValue): TValue;
  1339. var
  1340. JSInstance: TJSObject absolute Instance;
  1341. begin
  1342. Result := TValue.FromJSValue(JSInstance[Name]);
  1343. end;
  1344. procedure TRttiField.SetValue(Instance: JSValue; const AValue: TValue);
  1345. var
  1346. JSInstance: TJSObject absolute Instance;
  1347. begin
  1348. JSInstance[Name] := AValue.Cast(FieldType.Handle, True).ASJSValue;
  1349. end;
  1350. { TRttiParameter }
  1351. function TRttiParameter.GetName: String;
  1352. begin
  1353. Result := FName;
  1354. end;
  1355. { TRttiMethod }
  1356. function TRttiMethod.GetMethodTypeInfo: TTypeMemberMethod;
  1357. begin
  1358. Result := TTypeMemberMethod(inherited Handle);
  1359. end;
  1360. function TRttiMethod.GetIsClassMethod: Boolean;
  1361. begin
  1362. Result:=MethodTypeInfo.MethodKind in [mkClassFunction,mkClassProcedure];
  1363. end;
  1364. function TRttiMethod.GetIsConstructor: Boolean;
  1365. begin
  1366. Result:=MethodTypeInfo.MethodKind=mkConstructor;
  1367. end;
  1368. function TRttiMethod.GetIsDestructor: Boolean;
  1369. begin
  1370. Result:=MethodTypeInfo.MethodKind=mkDestructor;
  1371. end;
  1372. function TRttiMethod.GetIsExternal: Boolean;
  1373. begin
  1374. Result := pfExternal in GetProcedureFlags;
  1375. end;
  1376. function TRttiMethod.GetIsStatic: Boolean;
  1377. begin
  1378. Result := pfStatic in GetProcedureFlags;
  1379. end;
  1380. function TRttiMethod.GetIsVarArgs: Boolean;
  1381. begin
  1382. Result := pfVarargs in GetProcedureFlags;
  1383. end;
  1384. function TRttiMethod.GetIsAsyncCall: Boolean;
  1385. begin
  1386. Result := (pfAsync in GetProcedureFlags) or Assigned(ReturnType) and ReturnType.IsInstanceExternal and (ReturnType.AsInstanceExternal.ExternalName = 'Promise');
  1387. end;
  1388. function TRttiMethod.GetIsSafeCall: Boolean;
  1389. begin
  1390. Result := pfSafeCall in GetProcedureFlags;
  1391. end;
  1392. function TRttiMethod.GetMethodKind: TMethodKind;
  1393. begin
  1394. Result:=MethodTypeInfo.MethodKind;;
  1395. end;
  1396. function TRttiMethod.GetProcedureFlags: TProcedureFlags;
  1397. const
  1398. PROCEDURE_FLAGS: array[TProcedureFlag] of NativeInt = (1, 2, 4, 8, 16);
  1399. var
  1400. Flag: TProcedureFlag;
  1401. ProcedureFlags: NativeInt;
  1402. begin
  1403. ProcedureFlags := MethodTypeInfo.ProcSig.Flags;
  1404. Result := [];
  1405. for Flag := Low(PROCEDURE_FLAGS) to High(PROCEDURE_FLAGS) do
  1406. if PROCEDURE_FLAGS[Flag] and ProcedureFlags > 0 then
  1407. Result := Result + [Flag];
  1408. end;
  1409. function TRttiMethod.GetReturnType: TRttiType;
  1410. begin
  1411. Result := Pool.GetType(MethodTypeInfo.ProcSig.ResultType);
  1412. end;
  1413. procedure TRttiMethod.LoadParameters;
  1414. const
  1415. FLAGS_CONVERSION: array[TParamFlag] of NativeInt = (1, 2, 4, 8, 16, 32);
  1416. var
  1417. A: Integer;
  1418. Flag: TParamFlag;
  1419. Param: TProcedureParam;
  1420. RttiParam: TRttiParameter;
  1421. MethodParams: TProcedureParams;
  1422. begin
  1423. FParametersLoaded := True;
  1424. MethodParams := MethodTypeInfo.ProcSig.Params;
  1425. SetLength(FParameters, Length(MethodParams));
  1426. for A := Low(FParameters) to High(FParameters) do
  1427. begin
  1428. Param := MethodParams[A];
  1429. RttiParam := TRttiParameter.Create;
  1430. RttiParam.FName := Param.Name;
  1431. RttiParam.FParamType := Pool.GetType(Param.TypeInfo);
  1432. for Flag := Low(FLAGS_CONVERSION) to High(FLAGS_CONVERSION) do
  1433. if FLAGS_CONVERSION[Flag] and Param.Flags > 0 then
  1434. RttiParam.FFlags := RttiParam.FFlags + [Flag];
  1435. FParameters[A] := RttiParam;
  1436. end;
  1437. end;
  1438. function TRttiMethod.GetParameters: TRttiParameterArray;
  1439. begin
  1440. if not FParametersLoaded then
  1441. LoadParameters;
  1442. Result := FParameters;
  1443. end;
  1444. function TRttiMethod.Invoke(const Instance: TValue; const Args: array of TValue): TValue;
  1445. var
  1446. A: Integer;
  1447. ReturnHandle: PTypeInfo;
  1448. AArgs: TJSValueDynArray;
  1449. begin
  1450. if Assigned(ReturnType) then
  1451. Result.FTypeInfo := ReturnType.Handle;
  1452. SetLength(AArgs, Length(Args));
  1453. for A := Low(Args) to High(Args) do
  1454. AArgs[A] := Args[A].AsJSValue;
  1455. Result.SetData(TJSFunction(TJSObject(Instance.AsJSValue)[Name]).apply(TJSObject(Instance.AsJSValue), AArgs));
  1456. end;
  1457. { TRttiProperty }
  1458. constructor TRttiProperty.Create(AParent: TRttiType; ATypeInfo: TTypeMember);
  1459. begin
  1460. if not (ATypeInfo is TTypeMemberProperty) then
  1461. raise EInvalidCast.Create('');
  1462. inherited;
  1463. end;
  1464. function TRttiProperty.GetPropertyTypeInfo: TTypeMemberProperty;
  1465. begin
  1466. Result := TTypeMemberProperty(inherited Handle);
  1467. end;
  1468. function TRttiProperty.GetValue(Instance: JSValue): TValue;
  1469. var
  1470. JSObject: TJSObject absolute Instance;
  1471. begin
  1472. TValue.Make(GetJSValueProp(JSObject, PropertyTypeInfo), PropertyType.Handle, Result);
  1473. end;
  1474. procedure TRttiProperty.SetValue(Instance: JSValue; const AValue: TValue);
  1475. var
  1476. JSInstance: TJSObject absolute Instance;
  1477. begin
  1478. SetJSValueProp(JSInstance, PropertyTypeInfo, AValue.Cast(PropertyType.Handle, True).AsJSValue);
  1479. end;
  1480. function TRttiProperty.GetPropertyType: TRttiType;
  1481. begin
  1482. Result := Pool.GetType(PropertyTypeInfo.TypeInfo);
  1483. end;
  1484. function TRttiProperty.GetIsWritable: boolean;
  1485. begin
  1486. Result := PropertyTypeInfo.Setter<>'';
  1487. end;
  1488. function TRttiProperty.GetIsReadable: boolean;
  1489. begin
  1490. Result := PropertyTypeInfo.Getter<>'';
  1491. end;
  1492. function TRttiProperty.GetVisibility: TMemberVisibility;
  1493. begin
  1494. // At this moment only published rtti-property-info is supported by pas2js
  1495. Result := mvPublished;
  1496. end;
  1497. { TRttiType }
  1498. function TRttiType.GetName: string;
  1499. begin
  1500. Result := Handle.Name;
  1501. end;
  1502. function TRttiType.GetIsInstance: boolean;
  1503. begin
  1504. Result:=Self is TRttiInstanceType;
  1505. end;
  1506. function TRttiType.GetIsInstanceExternal: boolean;
  1507. begin
  1508. Result:=Self is TRttiInstanceExternalType;
  1509. end;
  1510. function TRttiType.GetIsOrdinal: boolean;
  1511. begin
  1512. Result:=false;
  1513. end;
  1514. function TRttiType.GetIsRecord: boolean;
  1515. begin
  1516. Result:=false;
  1517. end;
  1518. function TRttiType.GetIsSet: boolean;
  1519. begin
  1520. Result:=false;
  1521. end;
  1522. function TRttiType.GetTypeKind: TTypeKind;
  1523. begin
  1524. Result:=Handle.Kind;
  1525. end;
  1526. function TRttiType.GetHandle: TTypeInfo;
  1527. begin
  1528. Result := TTypeInfo(inherited Handle);
  1529. end;
  1530. function TRttiType.GetBaseType: TRttiType;
  1531. begin
  1532. Result:=Nil;
  1533. end;
  1534. function TRttiType.GetAsInstance: TRttiInstanceType;
  1535. begin
  1536. Result := Self as TRttiInstanceType;
  1537. end;
  1538. function TRttiType.GetAsInstanceExternal: TRttiInstanceExternalType;
  1539. begin
  1540. Result := Self as TRttiInstanceExternalType;
  1541. end;
  1542. function TRttiType.LoadCustomAttributes: TCustomAttributeArray;
  1543. begin
  1544. Result:=GetRTTIAttributes(Handle.Attributes);
  1545. end;
  1546. function TRttiType.GetDeclaredProperties: TRttiPropertyArray;
  1547. begin
  1548. Result:=nil;
  1549. end;
  1550. function TRttiType.GetProperties: TRttiPropertyArray;
  1551. begin
  1552. Result:=nil;
  1553. end;
  1554. function TRttiType.GetProperty(const AName: string): TRttiProperty;
  1555. begin
  1556. Result:=nil;
  1557. if AName='' then ;
  1558. end;
  1559. function TRttiType.GetMethods: TRttiMethodArray;
  1560. begin
  1561. Result:=nil;
  1562. end;
  1563. function TRttiType.GetMethods(const aName: String): TRttiMethodArray;
  1564. begin
  1565. Result:=nil;
  1566. end;
  1567. function TRttiType.GetMethod(const aName: String): TRttiMethod;
  1568. begin
  1569. Result:=nil;
  1570. if aName='' then ;
  1571. end;
  1572. function TRttiType.GetDeclaredMethods: TRttiMethodArray;
  1573. begin
  1574. Result:=nil;
  1575. end;
  1576. function TRttiType.GetDeclaredFields: TRttiFieldArray;
  1577. begin
  1578. Result:=nil;
  1579. end;
  1580. function TRttiType.GetField(const AName: string): TRttiField;
  1581. var
  1582. AField: TRttiField;
  1583. begin
  1584. Result:=nil;
  1585. for AField in GetFields do
  1586. if AField.Name = AName then
  1587. Exit(AField);
  1588. end;
  1589. function TRttiType.GetFields: TRttiFieldArray;
  1590. begin
  1591. Result := nil;
  1592. end;
  1593. function TRttiType.GetQualifiedName: String;
  1594. begin
  1595. Result := Format('%s.%s', [Handle.Module.Name, Name]);
  1596. end;
  1597. { TVirtualInterface }
  1598. constructor TVirtualInterface.Create(InterfaceTypeInfo: Pointer); assembler;
  1599. asm
  1600. var IntfType = InterfaceTypeInfo.interface;
  1601. if (IntfType.$kind !== 'com') rtl.raiseE('EInvalidCast');
  1602. var guid = IntfType.$guid;
  1603. var i = Object.create(IntfType); // needed by IntfVar is IntfType
  1604. i.$o = this;
  1605. // copy IInterface methods: _AddRef, _Release, QueryInterface
  1606. var iinterfaceguid = '{00000000-0000-0000-C000-000000000046}';
  1607. var map = this.$intfmaps[iinterfaceguid];
  1608. for (var key in map){
  1609. var v = map[key];
  1610. if (typeof(v)!=='function') continue;
  1611. i[key] = map[key];
  1612. }
  1613. // all other methods call OnInvoke
  1614. do {
  1615. var names = IntfType.$names;
  1616. if (!names) break;
  1617. for (var j=0; j<names.length; j++){
  1618. let fnname = names[j];
  1619. if (i[fnname]) continue;
  1620. i[fnname] = function(){ return this.$o.FOnInvoke(fnname,arguments); };
  1621. }
  1622. IntfType = Object.getPrototypeOf(IntfType);
  1623. } while(IntfType!=null);
  1624. // create a new list of interface map, supporting IInterface and IntfType
  1625. this.$intfmaps = {};
  1626. this.$intfmaps[iinterfaceguid] = map;
  1627. this.$intfmaps[guid] = {};
  1628. // store the implementation of IntfType (used by the as-operator)
  1629. this.$interfaces = {};
  1630. this.$interfaces[guid] = i;
  1631. end;
  1632. constructor TVirtualInterface.Create(InterfaceTypeInfo: Pointer;
  1633. const InvokeEvent: TVirtualInterfaceInvokeEvent);
  1634. begin
  1635. Create(InterfaceTypeInfo);
  1636. OnInvoke:=InvokeEvent;
  1637. end;
  1638. function TVirtualInterface.QueryInterface(const iid: TGuid; out obj): Integer;
  1639. begin
  1640. Result := inherited QueryInterface(iid, obj);
  1641. end;
  1642. function Invoke(ACodeAddress: Pointer; const AArgs: TJSValueDynArray;
  1643. ACallConv: TCallConv; AResultType: PTypeInfo; AIsStatic: Boolean;
  1644. AIsConstructor: Boolean): TValue;
  1645. begin
  1646. if ACallConv=ccReg then ;
  1647. if AIsStatic then ;
  1648. if AIsConstructor then
  1649. raise EInvoke.Create('not supported');
  1650. if isFunction(ACodeAddress) then
  1651. begin
  1652. Result.FData := TJSFunction(ACodeAddress).apply(nil, AArgs);
  1653. if AResultType<>nil then
  1654. Result.FTypeInfo:=AResultType
  1655. else
  1656. Result.FTypeInfo:=TypeInfo(JSValue);
  1657. end
  1658. else
  1659. raise EInvoke.Create(SErrInvokeInvalidCodeAddr);
  1660. end;
  1661. end.