rtti.pas 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847
  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. type
  19. { TValue }
  20. TValue = record
  21. private
  22. FTypeInfo: TTypeInfo;
  23. FData: JSValue;
  24. function GetIsEmpty: boolean;
  25. function GetTypeKind: TTypeKind;
  26. public
  27. class function FromJSValue(v: JSValue): TValue; static;
  28. property Kind: TTypeKind read GetTypeKind;
  29. property TypeInfo: TTypeInfo read FTypeInfo;
  30. property IsEmpty: boolean read GetIsEmpty; // check if nil or undefined
  31. function IsObject: boolean;
  32. function AsObject: TObject;
  33. function IsObjectInstance: boolean;
  34. function IsArray: boolean;
  35. function IsClass: boolean;
  36. function AsClass: TClass;
  37. function IsOrdinal: boolean;
  38. function AsOrdinal: NativeInt;
  39. function AsBoolean: boolean;
  40. //ToDo: function AsCurrency: Currency;
  41. function AsInteger: Integer;
  42. function AsNativeInt: NativeInt;
  43. function AsInterface: IInterface;
  44. function AsString: string;
  45. function AsUnicodeString: UnicodeString;
  46. function AsExtended: Extended;
  47. function ToString: String;
  48. function GetArrayLength: SizeInt;
  49. function GetArrayElement(aIndex: SizeInt): TValue;
  50. //ToDo: procedure SetArrayElement(aIndex: SizeInt; constref AValue: TValue);
  51. function IsType(ATypeInfo: PTypeInfo): boolean;
  52. end;
  53. TRttiType = class;
  54. { TRTTIContext }
  55. TRTTIContext = record
  56. private
  57. FPool: TJSObject; // maps 'modulename.typename' to TRTTIType
  58. class constructor Init;
  59. public
  60. class function Create: TRTTIContext; static;
  61. procedure Free;
  62. function GetType(aTypeInfo: PTypeInfo): TRTTIType; overload;
  63. function GetType(aClass: TClass): TRTTIType; overload;
  64. end;
  65. { TRttiObject }
  66. TRttiObject = class abstract
  67. public
  68. //property Handle: Pointer read GetHandle; not supported in pas2js
  69. function GetAttributes: TCustomAttributeArray; virtual;
  70. end;
  71. { TRttiNamedObject }
  72. TRttiNamedObject = class(TRttiObject)
  73. protected
  74. function GetName: string; virtual;
  75. public
  76. property Name: string read GetName;
  77. end;
  78. { TRttiMember }
  79. TMemberVisibility=(
  80. mvPrivate,
  81. mvProtected,
  82. mvPublic,
  83. mvPublished);
  84. TRttiMember = class(TRttiNamedObject)
  85. private
  86. FTypeInfo: TTypeMember;
  87. FParent: TRttiType;
  88. protected
  89. function GetName: string; override;
  90. function GetVisibility: TMemberVisibility; virtual;
  91. public
  92. constructor Create(AParent: TRttiType; ATypeInfo: TTypeMember);
  93. function GetAttributes: TCustomAttributeArray; override;
  94. property Visibility: TMemberVisibility read GetVisibility;
  95. property Parent: TRttiType read FParent;
  96. end;
  97. { TRttiField }
  98. TRttiField = class(TRttiMember)
  99. private
  100. function GetFieldType: TRttiType;
  101. public
  102. property FieldType: TRttiType read GetFieldType;
  103. //function GetValue(Instance: Pointer): TValue;
  104. //procedure SetValue(Instance: Pointer; const AValue: TValue);
  105. //function ToString: string; override;
  106. end;
  107. TRttiFieldArray = array of TRttiField;
  108. { TRttiMethod }
  109. TRttiMethod = class(TRttiMember)
  110. private
  111. function GetIsClassMethod: boolean;
  112. function GetIsConstructor: boolean;
  113. function GetIsDestructor: boolean;
  114. function GetIsExternal: boolean;
  115. function GetIsStatic: boolean;
  116. function GetIsVarArgs: boolean;
  117. function GetMethodKind: TMethodKind;
  118. function GetReturnType: TRttiType;
  119. public
  120. property ReturnType: TRttiType read GetReturnType;
  121. property MethodKind: TMethodKind read GetMethodKind;
  122. property IsConstructor: boolean read GetIsConstructor;
  123. property IsDestructor: boolean read GetIsDestructor;
  124. property IsClassMethod: boolean read GetIsClassMethod;
  125. property IsExternal: boolean read GetIsExternal;
  126. property IsStatic: boolean read GetIsStatic;// true = has Self argument
  127. property IsVarArgs: boolean read GetIsVarArgs;
  128. //function GetParameters:
  129. end;
  130. TRttiMethodArray = array of TRttiMethod;
  131. { TRttiProperty }
  132. TRttiProperty = class(TRttiMember)
  133. private
  134. function GetPropertyType: TRttiType;
  135. function GetIsWritable: boolean;
  136. function GetIsReadable: boolean;
  137. protected
  138. function GetVisibility: TMemberVisibility; override;
  139. public
  140. //function GetValue(Instance: Pointer): TValue;
  141. //procedure SetValue(Instance: Pointer; const AValue: TValue);
  142. property PropertyType: TRttiType read GetPropertyType;
  143. property IsReadable: boolean read GetIsReadable;
  144. property IsWritable: boolean read GetIsWritable;
  145. property Visibility: TMemberVisibility read GetVisibility;
  146. end;
  147. TRttiPropertyArray = array of TRttiProperty;
  148. { TRttiType }
  149. TRttiType = class(TRttiNamedObject)
  150. private
  151. FAttributes: TCustomAttributeArray;
  152. FTypeInfo: TTypeInfo;
  153. //FMethods: specialize TArray<TRttiMethod>;
  154. //function GetAsInstance: TRttiInstanceType;
  155. protected
  156. function GetName: string; override;
  157. //function GetHandle: Pointer; override;
  158. function GetIsInstance: boolean; virtual;
  159. //function GetIsManaged: boolean; virtual;
  160. function GetIsOrdinal: boolean; virtual;
  161. function GetIsRecord: boolean; virtual;
  162. function GetIsSet: boolean; virtual;
  163. function GetTypeKind: TTypeKind; virtual;
  164. //function GetTypeSize: integer; virtual;
  165. //function GetBaseType: TRttiType; virtual;
  166. public
  167. constructor Create(ATypeInfo : PTypeInfo);
  168. destructor Destroy; override;
  169. function GetAttributes: TCustomAttributeArray; override;
  170. function GetField(const AName: string): TRttiField; virtual;
  171. function GetMethods(const aName: String): TRttiMethodArray; virtual;
  172. function GetMethod(const aName: String): TRttiMethod; virtual;
  173. function GetProperty(const AName: string): TRttiProperty; virtual;
  174. //function GetIndexedProperty(const AName: string): TRttiIndexedProperty; virtual;
  175. function GetDeclaredProperties: TRttiPropertyArray; virtual;
  176. //function GetDeclaredIndexedProperties: TRttiIndexedPropertyArray; virtual;
  177. function GetDeclaredMethods: TRttiMethodArray; virtual;
  178. function GetDeclaredFields: TRttiFieldArray; virtual;
  179. property IsInstance: boolean read GetIsInstance;
  180. //property isManaged: boolean read GetIsManaged;
  181. property IsOrdinal: boolean read GetIsOrdinal;
  182. property IsRecord: boolean read GetIsRecord;
  183. property IsSet: boolean read GetIsSet;
  184. //property BaseType: TRttiType read GetBaseType;
  185. //property AsInstance: TRttiInstanceType read GetAsInstance;
  186. property TypeKind: TTypeKind read GetTypeKind;
  187. //property TypeSize: integer read GetTypeSize;
  188. end;
  189. { TRttiStructuredType }
  190. TRttiStructuredType = class abstract(TRttiType)
  191. end;
  192. { TRttiInstanceType }
  193. TRttiInstanceType = class(TRttiStructuredType)
  194. private
  195. function GetClassTypeInfo: TTypeInfoClass;
  196. function GetMetaClassType: TClass;
  197. public
  198. constructor Create(ATypeInfo: PTypeInfo);
  199. property ClassTypeInfo: TTypeInfoClass read GetClassTypeInfo;
  200. property MetaClassType: TClass read GetMetaClassType;
  201. //function GetDeclaredProperties: TRttiPropertyArray;
  202. end;
  203. EInvoke = EJS;
  204. TVirtualInterfaceInvokeEvent = function(const aMethodName: string;
  205. const Args: TJSValueDynArray): JSValue of object;
  206. { TVirtualInterface: A class that can implement any IInterface. Any method
  207. call is handled by the OnInvoke event. }
  208. TVirtualInterface = class(TInterfacedObject, IInterface)
  209. private
  210. FOnInvoke: TVirtualInterfaceInvokeEvent;
  211. public
  212. constructor Create(InterfaceTypeInfo: Pointer); overload; assembler;
  213. constructor Create(InterfaceTypeInfo: Pointer;
  214. const InvokeEvent: TVirtualInterfaceInvokeEvent); overload;
  215. property OnInvoke: TVirtualInterfaceInvokeEvent read FOnInvoke write FOnInvoke;
  216. end;
  217. procedure CreateVirtualCorbaInterface(InterfaceTypeInfo: Pointer;
  218. const MethodImplementation: TVirtualInterfaceInvokeEvent; out IntfVar); assembler;
  219. function Invoke(ACodeAddress: Pointer; const AArgs: TJSValueDynArray;
  220. ACallConv: TCallConv; AResultType: PTypeInfo; AIsStatic: Boolean;
  221. AIsConstructor: Boolean): TValue;
  222. implementation
  223. var
  224. GRttiContext: TRTTIContext;
  225. procedure CreateVirtualCorbaInterface(InterfaceTypeInfo: Pointer;
  226. const MethodImplementation: TVirtualInterfaceInvokeEvent; out IntfVar); assembler;
  227. asm
  228. var IntfType = InterfaceTypeInfo.interface;
  229. var i = Object.create(IntfType);
  230. var o = { $name: "virtual", $fullname: "virtual" };
  231. i.$o = o;
  232. do {
  233. var names = IntfType.$names;
  234. if (!names) break;
  235. for (var j=0; j<names.length; j++){
  236. let fnname = names[j];
  237. i[fnname] = function(){ return MethodImplementation(fnname,arguments); };
  238. }
  239. IntfType = Object.getPrototypeOf(IntfType);
  240. } while(IntfType!=null);
  241. IntfVar.set(i);
  242. end;
  243. { TValue }
  244. function TValue.GetTypeKind: TTypeKind;
  245. begin
  246. if TypeInfo=nil then
  247. Result:=tkUnknown
  248. else
  249. Result:=FTypeInfo.Kind;
  250. end;
  251. class function TValue.FromJSValue(v: JSValue): TValue;
  252. var
  253. i: NativeInt;
  254. begin
  255. Result.FData:=v;
  256. case jsTypeOf(v) of
  257. 'number':
  258. if JS.isInteger(v) then
  259. begin
  260. i:=NativeInt(v);
  261. if (i>=low(integer)) and (i<=high(integer)) then
  262. Result.FTypeInfo:=system.TypeInfo(Integer)
  263. else
  264. Result.FTypeInfo:=system.TypeInfo(NativeInt);
  265. end
  266. else
  267. Result.FTypeInfo:=system.TypeInfo(Double);
  268. 'string': Result.FTypeInfo:=system.TypeInfo(String);
  269. 'boolean': Result.FTypeInfo:=system.TypeInfo(Boolean);
  270. 'object':
  271. begin
  272. if v=nil then
  273. Result.FTypeInfo:=system.TypeInfo(Pointer)
  274. else if JS.isClass(v) and JS.isExt(v,TObject) then
  275. Result.FTypeInfo:=system.TypeInfo(TClass(v))
  276. else if JS.isObject(v) and JS.isExt(v,TObject) then
  277. Result.FTypeInfo:=system.TypeInfo(TObject(v))
  278. else
  279. Result.FTypeInfo:=system.TypeInfo(Pointer);
  280. if (Result.FTypeInfo=JS.Undefined) or (Result.FTypeInfo=nil) then
  281. Result.FTypeInfo:=system.TypeInfo(Pointer);
  282. end
  283. else
  284. Result.FTypeInfo:=system.TypeInfo(JSValue);
  285. end;
  286. end;
  287. function TValue.IsObject: boolean;
  288. begin
  289. Result:=IsEmpty or (TypeInfo.Kind=tkClass);
  290. end;
  291. function TValue.AsObject: TObject;
  292. begin
  293. if IsObject or (IsClass and not js.isObject(FData)) then
  294. Result := TObject(FData)
  295. else
  296. raise EInvalidCast.Create(SErrInvalidTypecast);
  297. end;
  298. function TValue.IsObjectInstance: boolean;
  299. begin
  300. Result:=(TypeInfo<>nil) and (TypeInfo.Kind=tkClass);
  301. end;
  302. function TValue.IsArray: boolean;
  303. begin
  304. Result := Kind in [tkArray, tkDynArray];
  305. end;
  306. function TValue.IsClass: boolean;
  307. var
  308. k: TTypeKind;
  309. begin
  310. k:=Kind;
  311. Result := (k = tkClassRef)
  312. or ((k in [tkClass,tkUnknown]) and not JS.IsObject(FData));
  313. end;
  314. function TValue.AsClass: TClass;
  315. begin
  316. if IsClass then
  317. Result := TClass(FData)
  318. else
  319. raise EInvalidCast.Create(SErrInvalidTypecast);
  320. end;
  321. function TValue.IsOrdinal: boolean;
  322. var
  323. k: TTypeKind;
  324. begin
  325. k:=Kind;
  326. Result := (k in [tkInteger, tkBool]) or
  327. ((k in [tkClass, tkClassRef, tkUnknown]) and not JS.isObject(FData));
  328. end;
  329. function TValue.AsOrdinal: NativeInt;
  330. begin
  331. if IsOrdinal then
  332. Result:=NativeInt(FData)
  333. else
  334. raise EInvalidCast.Create(SErrInvalidTypecast);
  335. end;
  336. function TValue.AsBoolean: boolean;
  337. begin
  338. if (Kind = tkBool) then
  339. Result:=boolean(FData)
  340. else
  341. raise EInvalidCast.Create(SErrInvalidTypecast);
  342. end;
  343. function TValue.AsInteger: Integer;
  344. begin
  345. if JS.isInteger(FData) then
  346. Result:=NativeInt(FData)
  347. else
  348. raise EInvalidCast.Create(SErrInvalidTypecast);
  349. end;
  350. function TValue.AsNativeInt: NativeInt;
  351. begin
  352. if JS.isInteger(FData) then
  353. Result:=NativeInt(FData)
  354. else
  355. raise EInvalidCast.Create(SErrInvalidTypecast);
  356. end;
  357. function TValue.AsInterface: IInterface;
  358. var
  359. k: TTypeKind;
  360. begin
  361. k:=Kind;
  362. if k = tkInterface then
  363. Result := IInterface(FData)// ToDo
  364. else if (k in [tkClass, tkClassRef, tkUnknown]) and not JS.isObject(FData) then
  365. Result := Nil
  366. else
  367. raise EInvalidCast.Create(SErrInvalidTypecast);
  368. end;
  369. function TValue.AsString: string;
  370. begin
  371. if js.isString(FData) then
  372. Result:=String(FData)
  373. else
  374. raise EInvalidCast.Create(SErrInvalidTypecast);
  375. end;
  376. function TValue.AsUnicodeString: UnicodeString;
  377. begin
  378. Result:=AsString;
  379. end;
  380. function TValue.AsExtended: Extended;
  381. begin
  382. if js.isNumber(FData) then
  383. Result:=Double(FData)
  384. else
  385. raise EInvalidCast.Create(SErrInvalidTypecast);
  386. end;
  387. function TValue.ToString: String;
  388. begin
  389. case Kind of
  390. tkString: Result := AsString;
  391. tkInteger: Result := IntToStr(AsNativeInt);
  392. tkBool: Result := BoolToStr(AsBoolean, True);
  393. else
  394. Result := '';
  395. end;
  396. end;
  397. function TValue.GetArrayLength: SizeInt;
  398. begin
  399. if not IsArray then
  400. raise EInvalidCast.Create(SErrInvalidTypecast);
  401. Result:=length(TJSValueDynArray(FData));
  402. end;
  403. function TValue.GetArrayElement(aIndex: SizeInt): TValue;
  404. var
  405. StaticTI: TTypeInfoStaticArray;
  406. DynIT: TTypeInfoDynArray;
  407. begin
  408. case Kind of
  409. tkDynArray:
  410. begin
  411. DynIT:=TTypeInfoDynArray(FTypeInfo);
  412. Result.FTypeInfo:=DynIT.ElType;
  413. if DynIT.DimCount<>1 then
  414. raise EInvalidCast.Create(SErrInvalidTypecast);
  415. end;
  416. tkArray:
  417. begin
  418. StaticTI:=TTypeInfoStaticArray(FTypeInfo);
  419. if length(StaticTI.Dims)<>1 then
  420. raise EInvalidCast.Create(SErrInvalidTypecast);
  421. Result.FTypeInfo:=StaticTI.ElType;
  422. end;
  423. else
  424. raise EInvalidCast.Create(SErrInvalidTypecast);
  425. end;
  426. Result.FData:=TJSValueDynArray(FData)[aIndex];
  427. end;
  428. function TValue.IsType(ATypeInfo: PTypeInfo): boolean;
  429. begin
  430. Result := ATypeInfo = TypeInfo;
  431. end;
  432. function TValue.GetIsEmpty: boolean;
  433. begin
  434. if (TypeInfo=nil) or (FData=Undefined) or (FData=nil) then
  435. exit(true);
  436. case TypeInfo.Kind of
  437. tkDynArray:
  438. Result:=TJSArray(FData).Length=0;
  439. else
  440. Result:=false;
  441. end;
  442. end;
  443. { TRttiInstanceType }
  444. function TRttiInstanceType.GetClassTypeInfo: TTypeInfoClass;
  445. begin
  446. Result:=TTypeInfoClass(FTypeInfo);
  447. end;
  448. function TRttiInstanceType.GetMetaClassType: TClass;
  449. begin
  450. Result:=TTypeInfoClass(FTypeInfo).ClassType;
  451. end;
  452. constructor TRttiInstanceType.Create(ATypeInfo: PTypeInfo);
  453. begin
  454. if not (TTypeInfo(ATypeInfo) is TTypeInfoClass) then
  455. raise EInvalidCast.Create('');
  456. inherited Create(ATypeInfo);
  457. end;
  458. { TRTTIContext }
  459. class constructor TRTTIContext.Init;
  460. begin
  461. GRttiContext:=TRTTIContext.Create;
  462. end;
  463. class function TRTTIContext.Create: TRTTIContext;
  464. begin
  465. Result.FPool:=TJSObject.new;
  466. end;
  467. procedure TRTTIContext.Free;
  468. var
  469. key: string;
  470. o: TRttiType;
  471. begin
  472. for key in FPool do
  473. if FPool.hasOwnProperty(key) then begin
  474. o:=TRTTIType(FPool[key]);
  475. o.Free;
  476. end;
  477. FPool:=nil;
  478. end;
  479. function TRTTIContext.GetType(aTypeInfo: PTypeInfo): TRTTIType;
  480. var
  481. t: TTypeinfo absolute aTypeInfo;
  482. Name: String;
  483. begin
  484. if aTypeInfo=nil then exit(nil);
  485. Name:=t.Name;
  486. if isModule(t.Module) then
  487. Name:=t.Module.Name+'.'+Name;
  488. if FPool.hasOwnProperty(Name) then
  489. Result:=TRttiType(FPool[Name])
  490. else
  491. begin
  492. Result:=TRttiType.Create(aTypeInfo);
  493. FPool[Name]:=Result;
  494. end;
  495. end;
  496. function TRTTIContext.GetType(aClass: TClass): TRTTIType;
  497. begin
  498. if aClass=nil then exit(nil);
  499. Result:=GetType(TypeInfo(aClass));
  500. end;
  501. { TRttiObject }
  502. function TRttiObject.GetAttributes: TCustomAttributeArray;
  503. begin
  504. Result:=nil;
  505. end;
  506. { TRttiNamedObject }
  507. function TRttiNamedObject.GetName: string;
  508. begin
  509. Result:='';
  510. end;
  511. { TRttiMember }
  512. function TRttiMember.GetName: string;
  513. begin
  514. Result:=FTypeInfo.Name;
  515. end;
  516. function TRttiMember.GetVisibility: TMemberVisibility;
  517. begin
  518. Result:=mvPublished;
  519. end;
  520. constructor TRttiMember.Create(AParent: TRttiType; ATypeInfo: TTypeMember);
  521. begin
  522. inherited Create();
  523. FParent := AParent;
  524. FTypeInfo:=ATypeInfo;
  525. end;
  526. function TRttiMember.GetAttributes: TCustomAttributeArray;
  527. begin
  528. Result:=inherited GetAttributes;
  529. end;
  530. { TRttiField }
  531. function TRttiField.GetFieldType: TRttiType;
  532. begin
  533. Result := GRttiContext.GetType(FTypeInfo);
  534. end;
  535. { TRttiMethod }
  536. function TRttiMethod.GetIsClassMethod: boolean;
  537. begin
  538. Result:=TTypeMemberMethod(FTypeInfo).MethodKind in [mkClassFunction,mkClassProcedure];
  539. end;
  540. function TRttiMethod.GetIsConstructor: boolean;
  541. begin
  542. Result:=TTypeMemberMethod(FTypeInfo).MethodKind=mkConstructor;
  543. end;
  544. function TRttiMethod.GetIsDestructor: boolean;
  545. begin
  546. Result:=TTypeMemberMethod(FTypeInfo).MethodKind=mkDestructor;
  547. end;
  548. function TRttiMethod.GetIsExternal: boolean;
  549. begin
  550. Result:=(TTypeMemberMethod(FTypeInfo).ProcSig.Flags and 4)>0; // pfExternal
  551. end;
  552. function TRttiMethod.GetIsStatic: boolean;
  553. begin
  554. Result:=(TTypeMemberMethod(FTypeInfo).ProcSig.Flags and 1)>0; // pfStatic
  555. end;
  556. function TRttiMethod.GetIsVarArgs: boolean;
  557. begin
  558. Result:=(TTypeMemberMethod(FTypeInfo).ProcSig.Flags and 2)>0; // pfVarargs
  559. end;
  560. function TRttiMethod.GetMethodKind: TMethodKind;
  561. begin
  562. Result:=TTypeMemberMethod(FTypeInfo).MethodKind;;
  563. end;
  564. function TRttiMethod.GetReturnType: TRttiType;
  565. begin
  566. Result := GRttiContext.GetType(TTypeMemberMethod(FTypeInfo).ProcSig.ResultType);
  567. end;
  568. { TRttiProperty }
  569. function TRttiProperty.GetPropertyType: TRttiType;
  570. begin
  571. Result := GRttiContext.GetType(FTypeInfo);
  572. end;
  573. function TRttiProperty.GetIsWritable: boolean;
  574. begin
  575. Result := TTypeMemberProperty(FTypeInfo).Setter<>'';
  576. end;
  577. function TRttiProperty.GetIsReadable: boolean;
  578. begin
  579. Result := TTypeMemberProperty(FTypeInfo).Getter<>'';
  580. end;
  581. function TRttiProperty.GetVisibility: TMemberVisibility;
  582. begin
  583. // At this moment only pulished rtti-property-info is supported by pas2js
  584. Result := mvPublished;
  585. end;
  586. { TRttiType }
  587. function TRttiType.GetName: string;
  588. begin
  589. Result:=FTypeInfo.Name;
  590. end;
  591. function TRttiType.GetIsInstance: boolean;
  592. begin
  593. Result:=false;
  594. end;
  595. function TRttiType.GetIsOrdinal: boolean;
  596. begin
  597. Result:=false;
  598. end;
  599. function TRttiType.GetIsRecord: boolean;
  600. begin
  601. Result:=false;
  602. end;
  603. function TRttiType.GetIsSet: boolean;
  604. begin
  605. Result:=false;
  606. end;
  607. function TRttiType.GetTypeKind: TTypeKind;
  608. begin
  609. Result:=FTypeInfo.Kind;
  610. end;
  611. constructor TRttiType.Create(ATypeInfo: PTypeInfo);
  612. begin
  613. inherited Create();
  614. FTypeInfo:=TTypeInfo(ATypeInfo);
  615. end;
  616. destructor TRttiType.Destroy;
  617. var
  618. o: TCustomAttribute;
  619. begin
  620. for o in FAttributes do
  621. o.Free;
  622. FAttributes:=nil;
  623. inherited Destroy;
  624. end;
  625. function TRttiType.GetAttributes: TCustomAttributeArray;
  626. begin
  627. FAttributes:=GetRTTIAttributes(FTypeInfo.Attributes);
  628. Result:=FAttributes;
  629. end;
  630. function TRttiType.GetDeclaredProperties: TRttiPropertyArray;
  631. begin
  632. Result:=nil;
  633. end;
  634. function TRttiType.GetProperty(const AName: string): TRttiProperty;
  635. begin
  636. Result:=nil;
  637. if AName='' then ;
  638. end;
  639. function TRttiType.GetMethods(const aName: String): TRttiMethodArray;
  640. begin
  641. Result:=nil;
  642. end;
  643. function TRttiType.GetMethod(const aName: String): TRttiMethod;
  644. begin
  645. Result:=nil;
  646. if aName='' then ;
  647. end;
  648. function TRttiType.GetDeclaredMethods: TRttiMethodArray;
  649. begin
  650. Result:=nil;
  651. end;
  652. function TRttiType.GetDeclaredFields: TRttiFieldArray;
  653. begin
  654. Result:=nil;
  655. end;
  656. function TRttiType.GetField(const AName: string): TRttiField;
  657. begin
  658. Result:=nil;
  659. if AName='' then ;
  660. end;
  661. { TVirtualInterface }
  662. constructor TVirtualInterface.Create(InterfaceTypeInfo: Pointer); assembler;
  663. asm
  664. var IntfType = InterfaceTypeInfo.interface;
  665. if (IntfType.$kind !== 'com') rtl.raiseE('EInvalidCast');
  666. var guid = IntfType.$guid;
  667. var i = Object.create(IntfType); // needed by IntfVar is IntfType
  668. i.$o = this;
  669. // copy IInterface methods: _AddRef, _Release, QueryInterface
  670. var iinterfaceguid = '{00000000-0000-0000-C000-000000000046}';
  671. var map = this.$intfmaps[iinterfaceguid];
  672. for (var key in map){
  673. var v = map[key];
  674. if (typeof(v)!=='function') continue;
  675. i[key] = map[key];
  676. }
  677. // all other methods call OnInvoke
  678. do {
  679. var names = IntfType.$names;
  680. if (!names) break;
  681. for (var j=0; j<names.length; j++){
  682. let fnname = names[j];
  683. if (i[fnname]) continue;
  684. i[fnname] = function(){ return this.$o.FOnInvoke(fnname,arguments); };
  685. }
  686. IntfType = Object.getPrototypeOf(IntfType);
  687. } while(IntfType!=null);
  688. // create a new list of interface map, supporting IInterface and IntfType
  689. this.$intfmaps = {};
  690. this.$intfmaps[iinterfaceguid] = map;
  691. this.$intfmaps[guid] = {};
  692. // store the implementation of IntfType (used by the as-operator)
  693. this.$interfaces = {};
  694. this.$interfaces[guid] = i;
  695. end;
  696. constructor TVirtualInterface.Create(InterfaceTypeInfo: Pointer;
  697. const InvokeEvent: TVirtualInterfaceInvokeEvent);
  698. begin
  699. Create(InterfaceTypeInfo);
  700. OnInvoke:=InvokeEvent;
  701. end;
  702. function Invoke(ACodeAddress: Pointer; const AArgs: TJSValueDynArray;
  703. ACallConv: TCallConv; AResultType: PTypeInfo; AIsStatic: Boolean;
  704. AIsConstructor: Boolean): TValue;
  705. begin
  706. if ACallConv=ccReg then ;
  707. if AIsStatic then ;
  708. if AIsConstructor then
  709. raise EInvoke.Create('not supported');
  710. if isFunction(ACodeAddress) then
  711. begin
  712. Result.FData := TJSFunction(ACodeAddress).apply(nil, AArgs);
  713. if AResultType<>nil then
  714. Result.FTypeInfo:=AResultType
  715. else
  716. Result.FTypeInfo:=TypeInfo(JSValue);
  717. end
  718. else
  719. raise EInvoke.Create(SErrInvokeInvalidCodeAddr);
  720. end;
  721. end.