rtti.pas 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411
  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. function GetIsEmpty: boolean;
  26. function GetTypeKind: TTypeKind;
  27. public
  28. generic class function From<T>(const Value: T): TValue; static;
  29. class function FromJSValue(v: JSValue): TValue; static;
  30. property Kind: TTypeKind read GetTypeKind;
  31. property TypeInfo: TTypeInfo read FTypeInfo;
  32. property IsEmpty: boolean read GetIsEmpty; // check if nil or undefined
  33. function IsObject: boolean;
  34. function AsObject: TObject;
  35. function IsObjectInstance: boolean;
  36. function IsArray: boolean;
  37. function IsClass: boolean;
  38. function AsClass: TClass;
  39. function IsOrdinal: boolean;
  40. function AsOrdinal: NativeInt;
  41. function AsBoolean: boolean;
  42. //ToDo: function AsCurrency: Currency;
  43. function AsInteger: Integer;
  44. function AsNativeInt: NativeInt;
  45. function AsInterface: IInterface;
  46. function AsString: string;
  47. function AsUnicodeString: UnicodeString;
  48. function AsExtended: Extended;
  49. function ToString: String;
  50. function GetArrayLength: SizeInt;
  51. function GetArrayElement(aIndex: SizeInt): TValue;
  52. procedure SetArrayElement(aIndex: SizeInt; const AValue: TValue);
  53. procedure SetArrayLength(const Size: SizeInt);
  54. function IsType(ATypeInfo: PTypeInfo): boolean;
  55. function AsJSValue: JSValue;
  56. class function Empty: TValue; static;
  57. class function Make(TypeInfo: TTypeInfo; const Value: JSValue): TValue; static;
  58. class function Make(const Value: TValue): TValue; static;
  59. end;
  60. TRttiType = class;
  61. { TRTTIContext }
  62. TRTTIContext = record
  63. private
  64. FPool: TJSObject; // maps 'modulename.typename' to TRTTIType
  65. class constructor Init;
  66. public
  67. class function Create: TRTTIContext; static;
  68. procedure Free;
  69. function GetType(aTypeInfo: PTypeInfo): TRTTIType; overload;
  70. function GetType(aClass: TClass): TRTTIType; overload;
  71. end;
  72. { TRttiObject }
  73. TRttiObject = class abstract
  74. public
  75. //property Handle: Pointer read GetHandle; not supported in pas2js
  76. function GetAttributes: TCustomAttributeArray; virtual;
  77. end;
  78. { TRttiNamedObject }
  79. TRttiNamedObject = class(TRttiObject)
  80. protected
  81. function GetName: string; virtual;
  82. public
  83. property Name: string read GetName;
  84. end;
  85. { TRttiMember }
  86. TMemberVisibility=(
  87. mvPrivate,
  88. mvProtected,
  89. mvPublic,
  90. mvPublished);
  91. TRttiMember = class(TRttiNamedObject)
  92. private
  93. FTypeInfo: TTypeMember;
  94. FParent: TRttiType;
  95. protected
  96. function GetMemberTypeInfo: TTypeMember;
  97. function GetName: string; override;
  98. function GetVisibility: TMemberVisibility; virtual;
  99. public
  100. constructor Create(AParent: TRttiType; ATypeInfo: TTypeMember);
  101. function GetAttributes: TCustomAttributeArray; override;
  102. property MemberTypeInfo: TTypeMember read GetMemberTypeInfo;
  103. property Visibility: TMemberVisibility read GetVisibility;
  104. property Parent: TRttiType read FParent;
  105. end;
  106. { TRttiField }
  107. TRttiField = class(TRttiMember)
  108. private
  109. function GetFieldType: TRttiType;
  110. public
  111. property FieldType: TRttiType read GetFieldType;
  112. //function GetValue(Instance: Pointer): TValue;
  113. //procedure SetValue(Instance: Pointer; const AValue: TValue);
  114. //function ToString: string; override;
  115. end;
  116. TRttiFieldArray = array of TRttiField;
  117. { TRttiMethod }
  118. TRttiMethod = class(TRttiMember)
  119. private
  120. function GetMethodTypeInfo: TTypeMemberMethod;
  121. function GetIsClassMethod: boolean;
  122. function GetIsConstructor: boolean;
  123. function GetIsDestructor: boolean;
  124. function GetIsExternal: boolean;
  125. function GetIsStatic: boolean;
  126. function GetIsVarArgs: boolean;
  127. function GetMethodKind: TMethodKind;
  128. function GetReturnType: TRttiType;
  129. public
  130. property MethodTypeInfo: TTypeMemberMethod read GetMethodTypeInfo;
  131. property ReturnType: TRttiType read GetReturnType;
  132. property MethodKind: TMethodKind read GetMethodKind;
  133. property IsConstructor: boolean read GetIsConstructor;
  134. property IsDestructor: boolean read GetIsDestructor;
  135. property IsClassMethod: boolean read GetIsClassMethod;
  136. property IsExternal: boolean read GetIsExternal;
  137. property IsStatic: boolean read GetIsStatic;// true = has Self argument
  138. property IsVarArgs: boolean read GetIsVarArgs;
  139. //function GetParameters:
  140. end;
  141. TRttiMethodArray = specialize TArray<TRttiMethod>;
  142. { TRttiProperty }
  143. TRttiProperty = class(TRttiMember)
  144. private
  145. function GetPropertyTypeInfo: TTypeMemberProperty;
  146. function GetPropertyType: TRttiType;
  147. function GetIsWritable: boolean;
  148. function GetIsReadable: boolean;
  149. protected
  150. function GetVisibility: TMemberVisibility; override;
  151. public
  152. constructor Create(AParent: TRttiType; ATypeInfo: TTypeMember);
  153. function GetValue(Instance: TObject): TValue;
  154. procedure SetValue(Instance: TObject; const AValue: JSValue); overload;
  155. procedure SetValue(Instance: TObject; const AValue: TValue); overload;
  156. property PropertyTypeInfo: TTypeMemberProperty read GetPropertyTypeInfo;
  157. property PropertyType: TRttiType read GetPropertyType;
  158. property IsReadable: boolean read GetIsReadable;
  159. property IsWritable: boolean read GetIsWritable;
  160. property Visibility: TMemberVisibility read GetVisibility;
  161. end;
  162. TRttiPropertyArray = specialize TArray<TRttiProperty>;
  163. { TRttiType }
  164. TRttiType = class(TRttiNamedObject)
  165. private
  166. FAttributes: TCustomAttributeArray;
  167. FTypeInfo: TTypeInfo;
  168. //FMethods: specialize TArray<TRttiMethod>;
  169. //function GetAsInstance: TRttiInstanceType;
  170. protected
  171. function GetName: string; override;
  172. //function GetHandle: Pointer; override;
  173. function GetIsInstance: boolean; virtual;
  174. //function GetIsManaged: boolean; virtual;
  175. function GetIsOrdinal: boolean; virtual;
  176. function GetIsRecord: boolean; virtual;
  177. function GetIsSet: boolean; virtual;
  178. function GetTypeKind: TTypeKind; virtual;
  179. //function GetTypeSize: integer; virtual;
  180. //function GetBaseType: TRttiType; virtual;
  181. public
  182. constructor Create(ATypeInfo : PTypeInfo);
  183. destructor Destroy; override;
  184. function GetAttributes: TCustomAttributeArray; override;
  185. function GetField(const AName: string): TRttiField; virtual;
  186. function GetMethods: TRttiMethodArray; virtual;
  187. function GetMethods(const aName: String): TRttiMethodArray; virtual;
  188. function GetMethod(const aName: String): TRttiMethod; virtual;
  189. function GetProperty(const AName: string): TRttiProperty; virtual;
  190. //function GetIndexedProperty(const AName: string): TRttiIndexedProperty; virtual;
  191. function GetDeclaredProperties: TRttiPropertyArray; virtual;
  192. //function GetDeclaredIndexedProperties: TRttiIndexedPropertyArray; virtual;
  193. function GetDeclaredMethods: TRttiMethodArray; virtual;
  194. function GetDeclaredFields: TRttiFieldArray; virtual;
  195. property Handle: TTypeInfo read FTypeInfo;
  196. property IsInstance: boolean read GetIsInstance;
  197. //property isManaged: boolean read GetIsManaged;
  198. property IsOrdinal: boolean read GetIsOrdinal;
  199. property IsRecord: boolean read GetIsRecord;
  200. property IsSet: boolean read GetIsSet;
  201. //property BaseType: TRttiType read GetBaseType;
  202. //property AsInstance: TRttiInstanceType read GetAsInstance;
  203. property TypeKind: TTypeKind read GetTypeKind;
  204. //property TypeSize: integer read GetTypeSize;
  205. end;
  206. TRttiTypeClass = class of TRttiType;
  207. { TRttiStructuredType }
  208. TRttiStructuredType = class abstract(TRttiType)
  209. private
  210. FMethods: TRttiMethodArray;
  211. FProperties: TRttiPropertyArray;
  212. protected
  213. function GetAncestor: TRttiStructuredType; virtual;
  214. function GetStructTypeInfo: TTypeInfoStruct;
  215. public
  216. constructor Create(ATypeInfo: PTypeInfo);
  217. destructor Destroy; override;
  218. function GetDeclaredMethods: TRttiMethodArray; override;
  219. function GetDeclaredProperties: TRttiPropertyArray; override;
  220. function GetMethod(const aName: String): TRttiMethod; override;
  221. function GetMethods: TRttiMethodArray; override;
  222. function GetMethods(const aName: String): TRttiMethodArray; override;
  223. function GetProperties: TRttiPropertyArray;
  224. function GetProperty(const AName: string): TRttiProperty; override;
  225. property StructTypeInfo: TTypeInfoStruct read GetStructTypeInfo;
  226. end;
  227. { TRttiInstanceType }
  228. TRttiInstanceType = class(TRttiStructuredType)
  229. private
  230. function GetClassTypeInfo: TTypeInfoClass;
  231. function GetMetaClassType: TClass;
  232. protected
  233. function GetAncestor: TRttiStructuredType; override;
  234. function GetIsInstance: boolean; override;
  235. public
  236. constructor Create(ATypeInfo: PTypeInfo);
  237. property ClassTypeInfo: TTypeInfoClass read GetClassTypeInfo;
  238. property MetaClassType: TClass read GetMetaClassType;
  239. end;
  240. { TRttiInterfaceType }
  241. TRttiInterfaceType = class(TRttiStructuredType)
  242. private
  243. function GetGUID: TGUID;
  244. function GetInterfaceTypeInfo: TTypeInfoInterface;
  245. protected
  246. function GetAncestor: TRttiStructuredType; override;
  247. public
  248. constructor Create(ATypeInfo: PTypeInfo);
  249. property GUID: TGUID read GetGUID;
  250. property InterfaceTypeInfo: TTypeInfoInterface read GetInterfaceTypeInfo;
  251. end;
  252. { TRttiRecordType }
  253. TRttiRecordType = class(TRttiStructuredType)
  254. private
  255. function GetRecordTypeInfo: TTypeInfoRecord;
  256. protected
  257. function GetIsRecord: Boolean; override;
  258. public
  259. constructor Create(ATypeInfo: PTypeInfo);
  260. property RecordTypeInfo: TTypeInfoRecord read GetRecordTypeInfo;
  261. end;
  262. { TRttiOrdinalType }
  263. TRttiOrdinalType = class(TRttiType)
  264. private
  265. function GetMaxValue: Integer; virtual;
  266. function GetMinValue: Integer; virtual;
  267. function GetOrdType: TOrdType;
  268. function GetOrdinalTypeInfo: TTypeInfoInteger;
  269. public
  270. constructor Create(ATypeInfo: PTypeInfo);
  271. property OrdType: TOrdType read GetOrdType;
  272. property MinValue: Integer read GetMinValue;
  273. property MaxValue: Integer read GetMaxValue;
  274. property OrdinalTypeInfo: TTypeInfoInteger read GetOrdinalTypeInfo;
  275. end;
  276. { TRttiEnumerationType }
  277. TRttiEnumerationType = class(TRttiOrdinalType)
  278. private
  279. function GetEnumerationTypeInfo: TTypeInfoEnum;
  280. public
  281. constructor Create(ATypeInfo: PTypeInfo);
  282. property EnumerationTypeInfo: TTypeInfoEnum read GetEnumerationTypeInfo;
  283. function GetNames: TStringArray;
  284. generic class function GetName<T>(AValue: T): String; reintroduce;
  285. generic class function GetValue<T>(const AValue: String): T;
  286. end;
  287. { TRttiDynamicArrayType }
  288. TRttiDynamicArrayType = class(TRttiType)
  289. private
  290. function GetDynArrayTypeInfo: TTypeInfoDynArray;
  291. function GetElementType: TRttiType;
  292. public
  293. constructor Create(ATypeInfo: PTypeInfo);
  294. property DynArrayTypeInfo: TTypeInfoDynArray read GetDynArrayTypeInfo;
  295. property ElementType: TRttiType read GetElementType;
  296. end;
  297. EInvoke = EJS;
  298. TVirtualInterfaceInvokeEvent = function(const aMethodName: string;
  299. const Args: TJSValueDynArray): JSValue of object;
  300. { TVirtualInterface: A class that can implement any IInterface. Any method
  301. call is handled by the OnInvoke event. }
  302. TVirtualInterface = class(TInterfacedObject, IInterface)
  303. private
  304. FOnInvoke: TVirtualInterfaceInvokeEvent;
  305. public
  306. constructor Create(InterfaceTypeInfo: Pointer); overload; assembler;
  307. constructor Create(InterfaceTypeInfo: Pointer;
  308. const InvokeEvent: TVirtualInterfaceInvokeEvent); overload;
  309. function QueryInterface(const iid: TGuid; out obj): Integer; override;
  310. property OnInvoke: TVirtualInterfaceInvokeEvent read FOnInvoke write FOnInvoke;
  311. end;
  312. procedure CreateVirtualCorbaInterface(InterfaceTypeInfo: Pointer;
  313. const MethodImplementation: TVirtualInterfaceInvokeEvent; out IntfVar); assembler;
  314. function Invoke(ACodeAddress: Pointer; const AArgs: TJSValueDynArray;
  315. ACallConv: TCallConv; AResultType: PTypeInfo; AIsStatic: Boolean;
  316. AIsConstructor: Boolean): TValue;
  317. implementation
  318. var
  319. GRttiContext: TRTTIContext;
  320. procedure CreateVirtualCorbaInterface(InterfaceTypeInfo: Pointer;
  321. const MethodImplementation: TVirtualInterfaceInvokeEvent; out IntfVar); assembler;
  322. asm
  323. var IntfType = InterfaceTypeInfo.interface;
  324. var i = Object.create(IntfType);
  325. var o = { $name: "virtual", $fullname: "virtual" };
  326. i.$o = o;
  327. do {
  328. var names = IntfType.$names;
  329. if (!names) break;
  330. for (var j=0; j<names.length; j++){
  331. let fnname = names[j];
  332. i[fnname] = function(){ return MethodImplementation(fnname,arguments); };
  333. }
  334. IntfType = Object.getPrototypeOf(IntfType);
  335. } while(IntfType!=null);
  336. IntfVar.set(i);
  337. end;
  338. { TRttiDynamicArrayType }
  339. function TRttiDynamicArrayType.GetDynArrayTypeInfo: TTypeInfoDynArray;
  340. begin
  341. Result := TTypeInfoDynArray(FTypeInfo);
  342. end;
  343. function TRttiDynamicArrayType.GetElementType: TRttiType;
  344. begin
  345. Result := GRttiContext.GetType(DynArrayTypeInfo.ElType);
  346. end;
  347. constructor TRttiDynamicArrayType.Create(ATypeInfo: PTypeInfo);
  348. begin
  349. if not (TTypeInfo(ATypeInfo) is TTypeInfoDynArray) then
  350. raise EInvalidCast.Create('');
  351. inherited Create(ATypeInfo);
  352. end;
  353. { TRttiOrdinalType }
  354. function TRttiOrdinalType.GetMaxValue: Integer;
  355. begin
  356. Result := OrdinalTypeInfo.MaxValue;
  357. end;
  358. function TRttiOrdinalType.GetMinValue: Integer;
  359. begin
  360. Result := OrdinalTypeInfo.MinValue;
  361. end;
  362. function TRttiOrdinalType.GetOrdType: TOrdType;
  363. begin
  364. Result := OrdinalTypeInfo.OrdType;
  365. end;
  366. function TRttiOrdinalType.GetOrdinalTypeInfo: TTypeInfoInteger;
  367. begin
  368. Result := TTypeInfoInteger(FTypeInfo);
  369. end;
  370. constructor TRttiOrdinalType.Create(ATypeInfo: PTypeInfo);
  371. begin
  372. if not (TTypeInfo(ATypeInfo) is TTypeInfoInteger) then
  373. raise EInvalidCast.Create('');
  374. inherited Create(ATypeInfo);
  375. end;
  376. { TRttiEnumerationType }
  377. function TRttiEnumerationType.GetEnumerationTypeInfo: TTypeInfoEnum;
  378. begin
  379. Result := TTypeInfoEnum(FTypeInfo);
  380. end;
  381. function TRttiEnumerationType.GetNames: TStringArray;
  382. var
  383. A, NamesSize: Integer;
  384. begin
  385. NamesSize := GetEnumNameCount(EnumerationTypeInfo);
  386. SetLength(Result, NamesSize);
  387. for A := 0 to Pred(NamesSize) do
  388. Result[A] := EnumerationTypeInfo.EnumType.IntToName[A + MinValue];
  389. end;
  390. generic class function TRttiEnumerationType.GetName<T>(AValue: T): String;
  391. Var
  392. P : PTypeInfo;
  393. begin
  394. P:=TypeInfo(T);
  395. if not (TTypeInfo(P).kind=tkEnumeration) then
  396. raise EInvalidCast.CreateFmt(SErrTypeIsNotEnumerated,[TTypeInfo(P).Name]);
  397. Result := GetEnumName(TTypeInfoEnum(P), Integer(JSValue(AValue)));
  398. end;
  399. generic class function TRttiEnumerationType.GetValue<T>(const AValue: String): T;
  400. Var
  401. P : PTypeInfo;
  402. begin
  403. P:=TypeInfo(T);
  404. if not (TTypeInfo(P).kind=tkEnumeration) then
  405. raise EInvalidCast.CreateFmt(SErrTypeIsNotEnumerated,[TTypeInfo(P).Name]);
  406. Result := T(JSValue(GetEnumValue(TTypeInfoEnum(TypeInfo(T)), AValue)));
  407. end;
  408. constructor TRttiEnumerationType.Create(ATypeInfo: PTypeInfo);
  409. begin
  410. if not (TTypeInfo(ATypeInfo) is TTypeInfoEnum) then
  411. raise EInvalidCast.Create('');
  412. inherited Create(ATypeInfo);
  413. end;
  414. { TValue }
  415. function TValue.GetTypeKind: TTypeKind;
  416. begin
  417. if TypeInfo=nil then
  418. Result:=tkUnknown
  419. else
  420. Result:=FTypeInfo.Kind;
  421. end;
  422. generic class function TValue.From<T>(const Value: T): TValue;
  423. begin
  424. Result := Make(System.TypeInfo(T), Value);
  425. end;
  426. class function TValue.Make(TypeInfo: TTypeInfo; const Value: JSValue): TValue;
  427. begin
  428. Result.FData := Value;
  429. Result.FTypeInfo := TypeInfo;
  430. end;
  431. class function TValue.Make(const Value: TValue): TValue;
  432. begin
  433. Result := TValue.Make(Value.TypeInfo, Value.AsJSValue);
  434. end;
  435. class function TValue.FromJSValue(v: JSValue): TValue;
  436. var
  437. i: NativeInt;
  438. TypeOfValue: TTypeInfo;
  439. begin
  440. case jsTypeOf(v) of
  441. 'number':
  442. if JS.isInteger(v) then
  443. begin
  444. i:=NativeInt(v);
  445. if (i>=low(integer)) and (i<=high(integer)) then
  446. TypeOfValue:=system.TypeInfo(Integer)
  447. else
  448. TypeOfValue:=system.TypeInfo(NativeInt);
  449. end
  450. else
  451. TypeOfValue:=system.TypeInfo(Double);
  452. 'string': TypeOfValue:=system.TypeInfo(String);
  453. 'boolean': TypeOfValue:=system.TypeInfo(Boolean);
  454. 'object':
  455. begin
  456. if v=nil then
  457. TypeOfValue:=system.TypeInfo(Pointer)
  458. else if JS.isClass(v) and JS.isExt(v,TObject) then
  459. TypeOfValue:=system.TypeInfo(TClass(v))
  460. else if JS.isObject(v) and JS.isExt(v,TObject) then
  461. TypeOfValue:=system.TypeInfo(TObject(v))
  462. else
  463. TypeOfValue:=system.TypeInfo(Pointer);
  464. if (TypeOfValue=JS.Undefined) or (TypeOfValue=nil) then
  465. TypeOfValue:=system.TypeInfo(Pointer);
  466. end
  467. else
  468. TypeOfValue:=system.TypeInfo(JSValue);
  469. end;
  470. Result := Make(TypeOfValue, v);
  471. end;
  472. function TValue.IsObject: boolean;
  473. begin
  474. Result:=IsEmpty or (TypeInfo.Kind=tkClass);
  475. end;
  476. function TValue.AsObject: TObject;
  477. begin
  478. if IsObject or (IsClass and not js.isObject(FData)) then
  479. Result := TObject(FData)
  480. else
  481. raise EInvalidCast.Create(SErrInvalidTypecast);
  482. end;
  483. function TValue.IsObjectInstance: boolean;
  484. begin
  485. Result:=(TypeInfo<>nil) and (TypeInfo.Kind=tkClass);
  486. end;
  487. function TValue.IsArray: boolean;
  488. begin
  489. case Kind of
  490. tkDynArray: Exit(True);
  491. tkArray: Exit(Length(TTypeInfoStaticArray(FTypeInfo).Dims) = 1);
  492. else Result := False;
  493. end;
  494. end;
  495. function TValue.IsClass: boolean;
  496. var
  497. k: TTypeKind;
  498. begin
  499. k:=Kind;
  500. Result := (k = tkClassRef)
  501. or ((k in [tkClass,tkUnknown]) and not JS.IsObject(FData));
  502. end;
  503. function TValue.AsClass: TClass;
  504. begin
  505. if IsClass then
  506. Result := TClass(FData)
  507. else
  508. raise EInvalidCast.Create(SErrInvalidTypecast);
  509. end;
  510. function TValue.IsOrdinal: boolean;
  511. var
  512. k: TTypeKind;
  513. begin
  514. k:=Kind;
  515. Result := (k in [tkInteger, tkBool]) or
  516. ((k in [tkClass, tkClassRef, tkUnknown]) and not JS.isObject(FData));
  517. end;
  518. function TValue.AsOrdinal: NativeInt;
  519. begin
  520. if IsOrdinal then
  521. Result:=NativeInt(FData)
  522. else
  523. raise EInvalidCast.Create(SErrInvalidTypecast);
  524. end;
  525. function TValue.AsBoolean: boolean;
  526. begin
  527. if (Kind = tkBool) then
  528. Result:=boolean(FData)
  529. else
  530. raise EInvalidCast.Create(SErrInvalidTypecast);
  531. end;
  532. function TValue.AsInteger: Integer;
  533. begin
  534. if JS.isInteger(FData) then
  535. Result:=NativeInt(FData)
  536. else
  537. raise EInvalidCast.Create(SErrInvalidTypecast);
  538. end;
  539. function TValue.AsNativeInt: NativeInt;
  540. begin
  541. if JS.isInteger(FData) then
  542. Result:=NativeInt(FData)
  543. else
  544. raise EInvalidCast.Create(SErrInvalidTypecast);
  545. end;
  546. function TValue.AsInterface: IInterface;
  547. var
  548. k: TTypeKind;
  549. begin
  550. k:=Kind;
  551. if k = tkInterface then
  552. Result := IInterface(FData)// ToDo
  553. else if (k in [tkClass, tkClassRef, tkUnknown]) and not JS.isObject(FData) then
  554. Result := Nil
  555. else
  556. raise EInvalidCast.Create(SErrInvalidTypecast);
  557. end;
  558. function TValue.AsString: string;
  559. begin
  560. if js.isString(FData) then
  561. Result:=String(FData)
  562. else
  563. raise EInvalidCast.Create(SErrInvalidTypecast);
  564. end;
  565. function TValue.AsUnicodeString: UnicodeString;
  566. begin
  567. Result:=AsString;
  568. end;
  569. function TValue.AsExtended: Extended;
  570. begin
  571. if js.isNumber(FData) then
  572. Result:=Double(FData)
  573. else
  574. raise EInvalidCast.Create(SErrInvalidTypecast);
  575. end;
  576. function TValue.ToString: String;
  577. begin
  578. case Kind of
  579. tkString: Result := AsString;
  580. tkInteger: Result := IntToStr(AsNativeInt);
  581. tkBool: Result := BoolToStr(AsBoolean, True);
  582. else
  583. Result := '';
  584. end;
  585. end;
  586. function TValue.GetArrayLength: SizeInt;
  587. begin
  588. if IsArray then
  589. Exit(Length(TJSValueDynArray(FData)));
  590. raise EInvalidCast.Create(SErrInvalidTypecast);
  591. end;
  592. function TValue.GetArrayElement(aIndex: SizeInt): TValue;
  593. begin
  594. if IsArray then
  595. begin
  596. case Kind of
  597. tkArray: Result.FTypeInfo:=TTypeInfoStaticArray(FTypeInfo).ElType;
  598. tkDynArray: Result.FTypeInfo:=TTypeInfoDynArray(FTypeInfo).ElType;
  599. end;
  600. Result.FData:=TJSValueDynArray(FData)[aIndex];
  601. end
  602. else
  603. raise EInvalidCast.Create(SErrInvalidTypecast);
  604. end;
  605. procedure TValue.SetArrayLength(const Size: SizeInt);
  606. var
  607. NewArray: TJSValueDynArray;
  608. begin
  609. NewArray := TJSValueDynArray(FData);
  610. SetLength(NewArray, Size);
  611. FData := NewArray;
  612. end;
  613. procedure TValue.SetArrayElement(aIndex: SizeInt; const AValue: TValue);
  614. var
  615. ValueTypeInfo: TTypeInfo;
  616. begin
  617. if IsArray then
  618. TJSValueDynArray(FData)[aIndex] := AValue.AsJSValue
  619. else
  620. raise EInvalidCast.Create(SErrInvalidTypecast);
  621. end;
  622. function TValue.IsType(ATypeInfo: PTypeInfo): boolean;
  623. begin
  624. Result := ATypeInfo = TypeInfo;
  625. end;
  626. function TValue.GetIsEmpty: boolean;
  627. begin
  628. if (TypeInfo=nil) or (FData=Undefined) or (FData=nil) then
  629. exit(true);
  630. case TypeInfo.Kind of
  631. tkDynArray:
  632. Result:=TJSArray(FData).Length=0;
  633. else
  634. Result:=false;
  635. end;
  636. end;
  637. function TValue.AsJSValue: JSValue;
  638. begin
  639. Result := FData;
  640. end;
  641. class function TValue.Empty: TValue;
  642. begin
  643. Result.FTypeInfo := nil;
  644. end;
  645. { TRttiStructuredType }
  646. function TRttiStructuredType.GetMethods: TRttiMethodArray;
  647. var
  648. A, Start: Integer;
  649. BaseClass: TRttiStructuredType;
  650. Declared: TRttiMethodArray;
  651. begin
  652. BaseClass := Self;
  653. Result := nil;
  654. while Assigned(BaseClass) do
  655. begin
  656. Declared := BaseClass.GetDeclaredMethods;
  657. Start := Length(Result);
  658. SetLength(Result, Start + Length(Declared));
  659. for A := Low(Declared) to High(Declared) do
  660. Result[Start + A] := Declared[A];
  661. BaseClass := BaseClass.GetAncestor;
  662. end;
  663. end;
  664. function TRttiStructuredType.GetMethods(const aName: String): TRttiMethodArray;
  665. var
  666. Method: TRttiMethod;
  667. MethodCount: Integer;
  668. begin
  669. MethodCount := 0;
  670. for Method in GetMethods do
  671. if aName = Method.Name then
  672. Inc(MethodCount);
  673. SetLength(Result, MethodCount);
  674. for Method in GetMethods do
  675. if aName = Method.Name then
  676. begin
  677. Dec(MethodCount);
  678. Result[MethodCount] := Method;
  679. end;
  680. end;
  681. function TRttiStructuredType.GetProperties: TRttiPropertyArray;
  682. var
  683. A, Start: Integer;
  684. BaseClass: TRttiStructuredType;
  685. Declared: TRttiPropertyArray;
  686. begin
  687. BaseClass := Self;
  688. Result := nil;
  689. while Assigned(BaseClass) do
  690. begin
  691. Declared := BaseClass.GetDeclaredProperties;
  692. Start := Length(Result);
  693. SetLength(Result, Start + Length(Declared));
  694. for A := Low(Declared) to High(Declared) do
  695. Result[Start + A] := Declared[A];
  696. BaseClass := BaseClass.GetAncestor;
  697. end;
  698. end;
  699. function TRttiStructuredType.GetMethod(const aName: String): TRttiMethod;
  700. var
  701. Method: TRttiMethod;
  702. begin
  703. for Method in GetMethods do
  704. if aName = Method.Name then
  705. Exit(Method);
  706. end;
  707. function TRttiStructuredType.GetProperty(const AName: string): TRttiProperty;
  708. var
  709. Prop: TRttiProperty;
  710. begin
  711. for Prop in GetProperties do
  712. if Prop.Name = AName then
  713. Exit(Prop);
  714. end;
  715. function TRttiStructuredType.GetDeclaredProperties: TRttiPropertyArray;
  716. var
  717. A, PropCount: Integer;
  718. begin
  719. if not Assigned(FProperties) then
  720. begin
  721. PropCount := StructTypeInfo.PropCount;
  722. SetLength(FProperties, PropCount);
  723. for A := 0 to Pred(PropCount) do
  724. FProperties[A] := TRttiProperty.Create(Self, StructTypeInfo.GetProp(A));
  725. end;
  726. Result := FProperties;
  727. end;
  728. function TRttiStructuredType.GetAncestor: TRttiStructuredType;
  729. begin
  730. Result := nil;
  731. end;
  732. function TRttiStructuredType.GetStructTypeInfo: TTypeInfoStruct;
  733. begin
  734. Result:=TTypeInfoStruct(FTypeInfo);
  735. end;
  736. constructor TRttiStructuredType.Create(ATypeInfo: PTypeInfo);
  737. begin
  738. if not (TTypeInfo(ATypeInfo) is TTypeInfoStruct) then
  739. raise EInvalidCast.Create('');
  740. inherited Create(ATypeInfo);
  741. end;
  742. destructor TRttiStructuredType.Destroy;
  743. var
  744. Method: TRttiMethod;
  745. Prop: TRttiProperty;
  746. begin
  747. for Method in FMethods do
  748. Method.Free;
  749. for Prop in FProperties do
  750. Prop.Free;
  751. inherited Destroy;
  752. end;
  753. function TRttiStructuredType.GetDeclaredMethods: TRttiMethodArray;
  754. var
  755. A, MethodCount: Integer;
  756. BaseClass: TRttiStructuredType;
  757. begin
  758. if not Assigned(FMethods) then
  759. begin
  760. MethodCount := StructTypeInfo.MethodCount;
  761. SetLength(FMethods, MethodCount);
  762. for A := 0 to Pred(MethodCount) do
  763. FMethods[A] := TRttiMethod.Create(Self, StructTypeInfo.GetMethod(A));
  764. end;
  765. Result := FMethods;
  766. end;
  767. { TRttiInstanceType }
  768. function TRttiInstanceType.GetClassTypeInfo: TTypeInfoClass;
  769. begin
  770. Result:=TTypeInfoClass(FTypeInfo);
  771. end;
  772. function TRttiInstanceType.GetMetaClassType: TClass;
  773. begin
  774. Result:=ClassTypeInfo.ClassType;
  775. end;
  776. function TRttiInstanceType.GetAncestor: TRttiStructuredType;
  777. begin
  778. Result := GRttiContext.GetType(ClassTypeInfo.Ancestor) as TRttiStructuredType;
  779. end;
  780. constructor TRttiInstanceType.Create(ATypeInfo: PTypeInfo);
  781. begin
  782. if not (TTypeInfo(ATypeInfo) is TTypeInfoClass) then
  783. raise EInvalidCast.Create('');
  784. inherited Create(ATypeInfo);
  785. end;
  786. function TRttiInstanceType.GetIsInstance: boolean;
  787. begin
  788. Result:=True;
  789. end;
  790. { TRttiInterfaceType }
  791. constructor TRttiInterfaceType.Create(ATypeInfo: PTypeInfo);
  792. begin
  793. if not (TTypeInfo(ATypeInfo) is TTypeInfoInterface) then
  794. raise EInvalidCast.Create('');
  795. inherited Create(ATypeInfo);
  796. end;
  797. function TRttiInterfaceType.GetGUID: TGUID;
  798. var
  799. Guid: String;
  800. begin
  801. Guid := String(InterfaceTypeInfo.InterfaceType['$guid']);
  802. TryStringToGUID(Guid, Result);
  803. end;
  804. function TRttiInterfaceType.GetInterfaceTypeInfo: TTypeInfoInterface;
  805. begin
  806. Result := TTypeInfoInterface(FTypeInfo);
  807. end;
  808. function TRttiInterfaceType.GetAncestor: TRttiStructuredType;
  809. begin
  810. Result := GRttiContext.GetType(InterfaceTypeInfo.Ancestor) as TRttiStructuredType;
  811. end;
  812. { TRttiRecordType }
  813. function TRttiRecordType.GetRecordTypeInfo: TTypeInfoRecord;
  814. begin
  815. Result := TTypeInfoRecord(FTypeInfo);
  816. end;
  817. function TRttiRecordType.GetIsRecord: Boolean;
  818. begin
  819. Result := True;
  820. end;
  821. constructor TRttiRecordType.Create(ATypeInfo: PTypeInfo);
  822. begin
  823. if not (TTypeInfo(ATypeInfo) is TTypeInfoClass) then
  824. raise EInvalidCast.Create('');
  825. inherited Create(ATypeInfo);
  826. end;
  827. { TRTTIContext }
  828. class constructor TRTTIContext.Init;
  829. begin
  830. GRttiContext:=TRTTIContext.Create;
  831. end;
  832. class function TRTTIContext.Create: TRTTIContext;
  833. begin
  834. Result.FPool:=TJSObject.new;
  835. end;
  836. procedure TRTTIContext.Free;
  837. var
  838. key: string;
  839. o: TRttiType;
  840. begin
  841. for key in FPool do
  842. if FPool.hasOwnProperty(key) then begin
  843. o:=TRTTIType(FPool[key]);
  844. o.Free;
  845. end;
  846. FPool:=nil;
  847. end;
  848. function TRTTIContext.GetType(aTypeInfo: PTypeInfo): TRTTIType;
  849. var
  850. RttiTypeClass: array[TTypeKind] of TRttiTypeClass = (
  851. nil, // tkUnknown
  852. TRttiOrdinalType, // tkInteger
  853. TRttiOrdinalType, // tkChar
  854. TRttiType, // tkString
  855. TRttiEnumerationType, // tkEnumeration
  856. TRttiType, // tkSet
  857. TRttiOrdinalType, // tkDouble
  858. TRttiEnumerationType, // tkBool
  859. TRttiType, // tkProcVar
  860. nil, // tkMethod
  861. TRttiType, // tkArray
  862. TRttiDynamicArrayType, // tkDynArray
  863. TRttiRecordType, // tkRecord
  864. TRttiInstanceType, // tkClass
  865. TRttiType, // tkClassRef
  866. TRttiType, // tkPointer
  867. TRttiType, // tkJSValue
  868. TRttiType, // tkRefToProcVar
  869. TRttiInterfaceType, // tkInterface
  870. TRttiType, // tkHelper
  871. TRttiInstanceType // tkExtClass
  872. );
  873. t: TTypeinfo absolute aTypeInfo;
  874. Name: String;
  875. begin
  876. if aTypeInfo=nil then exit(nil);
  877. Name:=t.Name;
  878. if isModule(t.Module) then
  879. Name:=t.Module.Name+'.'+Name;
  880. if FPool.hasOwnProperty(Name) then
  881. Result:=TRttiType(FPool[Name])
  882. else
  883. begin
  884. Result := RttiTypeClass[T.Kind].Create(aTypeInfo);
  885. FPool[Name]:=Result;
  886. end;
  887. end;
  888. function TRTTIContext.GetType(aClass: TClass): TRTTIType;
  889. begin
  890. if aClass=nil then exit(nil);
  891. Result:=GetType(TypeInfo(aClass));
  892. end;
  893. { TRttiObject }
  894. function TRttiObject.GetAttributes: TCustomAttributeArray;
  895. begin
  896. Result:=nil;
  897. end;
  898. { TRttiNamedObject }
  899. function TRttiNamedObject.GetName: string;
  900. begin
  901. Result:='';
  902. end;
  903. { TRttiMember }
  904. function TRttiMember.GetName: string;
  905. begin
  906. Result:=FTypeInfo.Name;
  907. end;
  908. function TRttiMember.GetVisibility: TMemberVisibility;
  909. begin
  910. Result:=mvPublished;
  911. end;
  912. constructor TRttiMember.Create(AParent: TRttiType; ATypeInfo: TTypeMember);
  913. begin
  914. if not (ATypeInfo is TTypeMember) then
  915. raise EInvalidCast.Create('');
  916. inherited Create();
  917. FParent := AParent;
  918. FTypeInfo:=ATypeInfo;
  919. end;
  920. function TRttiMember.GetAttributes: TCustomAttributeArray;
  921. begin
  922. Result:=inherited GetAttributes;
  923. end;
  924. function TRttiMember.GetMemberTypeInfo: TTypeMember;
  925. begin
  926. Result := TTypeMember(FTypeInfo);
  927. end;
  928. { TRttiField }
  929. function TRttiField.GetFieldType: TRttiType;
  930. begin
  931. Result := GRttiContext.GetType(FTypeInfo);
  932. end;
  933. { TRttiMethod }
  934. function TRttiMethod.GetMethodTypeInfo: TTypeMemberMethod;
  935. begin
  936. Result := TTypeMemberMethod(FTypeInfo);
  937. end;
  938. function TRttiMethod.GetIsClassMethod: boolean;
  939. begin
  940. Result:=MethodTypeInfo.MethodKind in [mkClassFunction,mkClassProcedure];
  941. end;
  942. function TRttiMethod.GetIsConstructor: boolean;
  943. begin
  944. Result:=MethodTypeInfo.MethodKind=mkConstructor;
  945. end;
  946. function TRttiMethod.GetIsDestructor: boolean;
  947. begin
  948. Result:=MethodTypeInfo.MethodKind=mkDestructor;
  949. end;
  950. function TRttiMethod.GetIsExternal: boolean;
  951. begin
  952. Result:=(MethodTypeInfo.ProcSig.Flags and 4)>0; // pfExternal
  953. end;
  954. function TRttiMethod.GetIsStatic: boolean;
  955. begin
  956. Result:=(MethodTypeInfo.ProcSig.Flags and 1)>0; // pfStatic
  957. end;
  958. function TRttiMethod.GetIsVarArgs: boolean;
  959. begin
  960. Result:=(MethodTypeInfo.ProcSig.Flags and 2)>0; // pfVarargs
  961. end;
  962. function TRttiMethod.GetMethodKind: TMethodKind;
  963. begin
  964. Result:=MethodTypeInfo.MethodKind;;
  965. end;
  966. function TRttiMethod.GetReturnType: TRttiType;
  967. begin
  968. Result := GRttiContext.GetType(MethodTypeInfo.ProcSig.ResultType);
  969. end;
  970. { TRttiProperty }
  971. constructor TRttiProperty.Create(AParent: TRttiType; ATypeInfo: TTypeMember);
  972. begin
  973. if not (ATypeInfo is TTypeMemberProperty) then
  974. raise EInvalidCast.Create('');
  975. inherited;
  976. end;
  977. function TRttiProperty.GetPropertyTypeInfo: TTypeMemberProperty;
  978. begin
  979. Result := TTypeMemberProperty(FTypeInfo);
  980. end;
  981. function TRttiProperty.GetValue(Instance: TObject): TValue;
  982. begin
  983. Result := TValue.Make(PropertyType.Handle, GetJSValueProp(Instance, PropertyTypeInfo));
  984. end;
  985. procedure TRttiProperty.SetValue(Instance: TObject; const AValue: TValue);
  986. begin
  987. SetJSValueProp(Instance, PropertyTypeInfo, AValue.AsJSValue);
  988. end;
  989. procedure TRttiProperty.SetValue(Instance: TObject; const AValue: JSValue);
  990. begin
  991. SetJSValueProp(Instance, PropertyTypeInfo, AValue);
  992. end;
  993. function TRttiProperty.GetPropertyType: TRttiType;
  994. begin
  995. Result := GRttiContext.GetType(PropertyTypeInfo.TypeInfo);
  996. end;
  997. function TRttiProperty.GetIsWritable: boolean;
  998. begin
  999. Result := PropertyTypeInfo.Setter<>'';
  1000. end;
  1001. function TRttiProperty.GetIsReadable: boolean;
  1002. begin
  1003. Result := PropertyTypeInfo.Getter<>'';
  1004. end;
  1005. function TRttiProperty.GetVisibility: TMemberVisibility;
  1006. begin
  1007. // At this moment only pulished rtti-property-info is supported by pas2js
  1008. Result := mvPublished;
  1009. end;
  1010. { TRttiType }
  1011. function TRttiType.GetName: string;
  1012. begin
  1013. Result:=FTypeInfo.Name;
  1014. end;
  1015. function TRttiType.GetIsInstance: boolean;
  1016. begin
  1017. Result:=false;
  1018. end;
  1019. function TRttiType.GetIsOrdinal: boolean;
  1020. begin
  1021. Result:=false;
  1022. end;
  1023. function TRttiType.GetIsRecord: boolean;
  1024. begin
  1025. Result:=false;
  1026. end;
  1027. function TRttiType.GetIsSet: boolean;
  1028. begin
  1029. Result:=false;
  1030. end;
  1031. function TRttiType.GetTypeKind: TTypeKind;
  1032. begin
  1033. Result:=FTypeInfo.Kind;
  1034. end;
  1035. constructor TRttiType.Create(ATypeInfo: PTypeInfo);
  1036. begin
  1037. inherited Create();
  1038. FTypeInfo:=TTypeInfo(ATypeInfo);
  1039. end;
  1040. destructor TRttiType.Destroy;
  1041. var
  1042. o: TCustomAttribute;
  1043. begin
  1044. for o in FAttributes do
  1045. o.Free;
  1046. FAttributes:=nil;
  1047. inherited Destroy;
  1048. end;
  1049. function TRttiType.GetAttributes: TCustomAttributeArray;
  1050. begin
  1051. FAttributes:=GetRTTIAttributes(FTypeInfo.Attributes);
  1052. Result:=FAttributes;
  1053. end;
  1054. function TRttiType.GetDeclaredProperties: TRttiPropertyArray;
  1055. begin
  1056. Result:=nil;
  1057. end;
  1058. function TRttiType.GetProperty(const AName: string): TRttiProperty;
  1059. begin
  1060. Result:=nil;
  1061. if AName='' then ;
  1062. end;
  1063. function TRttiType.GetMethods: TRttiMethodArray;
  1064. begin
  1065. Result:=nil;
  1066. end;
  1067. function TRttiType.GetMethods(const aName: String): TRttiMethodArray;
  1068. begin
  1069. Result:=nil;
  1070. end;
  1071. function TRttiType.GetMethod(const aName: String): TRttiMethod;
  1072. begin
  1073. Result:=nil;
  1074. if aName='' then ;
  1075. end;
  1076. function TRttiType.GetDeclaredMethods: TRttiMethodArray;
  1077. begin
  1078. Result:=nil;
  1079. end;
  1080. function TRttiType.GetDeclaredFields: TRttiFieldArray;
  1081. begin
  1082. Result:=nil;
  1083. end;
  1084. function TRttiType.GetField(const AName: string): TRttiField;
  1085. begin
  1086. Result:=nil;
  1087. if AName='' then ;
  1088. end;
  1089. { TVirtualInterface }
  1090. constructor TVirtualInterface.Create(InterfaceTypeInfo: Pointer); assembler;
  1091. asm
  1092. var IntfType = InterfaceTypeInfo.interface;
  1093. if (IntfType.$kind !== 'com') rtl.raiseE('EInvalidCast');
  1094. var guid = IntfType.$guid;
  1095. var i = Object.create(IntfType); // needed by IntfVar is IntfType
  1096. i.$o = this;
  1097. // copy IInterface methods: _AddRef, _Release, QueryInterface
  1098. var iinterfaceguid = '{00000000-0000-0000-C000-000000000046}';
  1099. var map = this.$intfmaps[iinterfaceguid];
  1100. for (var key in map){
  1101. var v = map[key];
  1102. if (typeof(v)!=='function') continue;
  1103. i[key] = map[key];
  1104. }
  1105. // all other methods call OnInvoke
  1106. do {
  1107. var names = IntfType.$names;
  1108. if (!names) break;
  1109. for (var j=0; j<names.length; j++){
  1110. let fnname = names[j];
  1111. if (i[fnname]) continue;
  1112. i[fnname] = function(){ return this.$o.FOnInvoke(fnname,arguments); };
  1113. }
  1114. IntfType = Object.getPrototypeOf(IntfType);
  1115. } while(IntfType!=null);
  1116. // create a new list of interface map, supporting IInterface and IntfType
  1117. this.$intfmaps = {};
  1118. this.$intfmaps[iinterfaceguid] = map;
  1119. this.$intfmaps[guid] = {};
  1120. // store the implementation of IntfType (used by the as-operator)
  1121. this.$interfaces = {};
  1122. this.$interfaces[guid] = i;
  1123. end;
  1124. constructor TVirtualInterface.Create(InterfaceTypeInfo: Pointer;
  1125. const InvokeEvent: TVirtualInterfaceInvokeEvent);
  1126. begin
  1127. Create(InterfaceTypeInfo);
  1128. OnInvoke:=InvokeEvent;
  1129. end;
  1130. function TVirtualInterface.QueryInterface(const iid: TGuid; out obj): Integer;
  1131. begin
  1132. Result := inherited QueryInterface(iid, obj);
  1133. end;
  1134. function Invoke(ACodeAddress: Pointer; const AArgs: TJSValueDynArray;
  1135. ACallConv: TCallConv; AResultType: PTypeInfo; AIsStatic: Boolean;
  1136. AIsConstructor: Boolean): TValue;
  1137. begin
  1138. if ACallConv=ccReg then ;
  1139. if AIsStatic then ;
  1140. if AIsConstructor then
  1141. raise EInvoke.Create('not supported');
  1142. if isFunction(ACodeAddress) then
  1143. begin
  1144. Result.FData := TJSFunction(ACodeAddress).apply(nil, AArgs);
  1145. if AResultType<>nil then
  1146. Result.FTypeInfo:=AResultType
  1147. else
  1148. Result.FTypeInfo:=TypeInfo(JSValue);
  1149. end
  1150. else
  1151. raise EInvoke.Create(SErrInvokeInvalidCodeAddr);
  1152. end;
  1153. end.