123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847 |
- {
- This file is part of the Pas2JS run time library.
- Copyright (c) 2018 by Mattias Gaertner
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- unit RTTI;
- {$mode objfpc}
- {$ModeSwitch advancedrecords}
- interface
- uses
- JS, RTLConsts, Types, SysUtils, TypInfo;
- resourcestring
- SErrInvokeInvalidCodeAddr = 'CodeAddress is not a function';
- type
- { TValue }
- TValue = record
- private
- FTypeInfo: TTypeInfo;
- FData: JSValue;
- function GetIsEmpty: boolean;
- function GetTypeKind: TTypeKind;
- public
- class function FromJSValue(v: JSValue): TValue; static;
- property Kind: TTypeKind read GetTypeKind;
- property TypeInfo: TTypeInfo read FTypeInfo;
- property IsEmpty: boolean read GetIsEmpty; // check if nil or undefined
- function IsObject: boolean;
- function AsObject: TObject;
- function IsObjectInstance: boolean;
- function IsArray: boolean;
- function IsClass: boolean;
- function AsClass: TClass;
- function IsOrdinal: boolean;
- function AsOrdinal: NativeInt;
- function AsBoolean: boolean;
- //ToDo: function AsCurrency: Currency;
- function AsInteger: Integer;
- function AsNativeInt: NativeInt;
- function AsInterface: IInterface;
- function AsString: string;
- function AsUnicodeString: UnicodeString;
- function AsExtended: Extended;
- function ToString: String;
- function GetArrayLength: SizeInt;
- function GetArrayElement(aIndex: SizeInt): TValue;
- //ToDo: procedure SetArrayElement(aIndex: SizeInt; constref AValue: TValue);
- function IsType(ATypeInfo: PTypeInfo): boolean;
- end;
- TRttiType = class;
- { TRTTIContext }
- TRTTIContext = record
- private
- FPool: TJSObject; // maps 'modulename.typename' to TRTTIType
- class constructor Init;
- public
- class function Create: TRTTIContext; static;
- procedure Free;
- function GetType(aTypeInfo: PTypeInfo): TRTTIType; overload;
- function GetType(aClass: TClass): TRTTIType; overload;
- end;
- { TRttiObject }
- TRttiObject = class abstract
- public
- //property Handle: Pointer read GetHandle; not supported in pas2js
- function GetAttributes: TCustomAttributeArray; virtual;
- end;
- { TRttiNamedObject }
- TRttiNamedObject = class(TRttiObject)
- protected
- function GetName: string; virtual;
- public
- property Name: string read GetName;
- end;
- { TRttiMember }
- TMemberVisibility=(
- mvPrivate,
- mvProtected,
- mvPublic,
- mvPublished);
- TRttiMember = class(TRttiNamedObject)
- private
- FTypeInfo: TTypeMember;
- FParent: TRttiType;
- protected
- function GetName: string; override;
- function GetVisibility: TMemberVisibility; virtual;
- public
- constructor Create(AParent: TRttiType; ATypeInfo: TTypeMember);
- function GetAttributes: TCustomAttributeArray; override;
- property Visibility: TMemberVisibility read GetVisibility;
- property Parent: TRttiType read FParent;
- end;
- { TRttiField }
- TRttiField = class(TRttiMember)
- private
- function GetFieldType: TRttiType;
- public
- property FieldType: TRttiType read GetFieldType;
- //function GetValue(Instance: Pointer): TValue;
- //procedure SetValue(Instance: Pointer; const AValue: TValue);
- //function ToString: string; override;
- end;
- TRttiFieldArray = array of TRttiField;
- { TRttiMethod }
- TRttiMethod = class(TRttiMember)
- private
- function GetIsClassMethod: boolean;
- function GetIsConstructor: boolean;
- function GetIsDestructor: boolean;
- function GetIsExternal: boolean;
- function GetIsStatic: boolean;
- function GetIsVarArgs: boolean;
- function GetMethodKind: TMethodKind;
- function GetReturnType: TRttiType;
- public
- property ReturnType: TRttiType read GetReturnType;
- property MethodKind: TMethodKind read GetMethodKind;
- property IsConstructor: boolean read GetIsConstructor;
- property IsDestructor: boolean read GetIsDestructor;
- property IsClassMethod: boolean read GetIsClassMethod;
- property IsExternal: boolean read GetIsExternal;
- property IsStatic: boolean read GetIsStatic;// true = has Self argument
- property IsVarArgs: boolean read GetIsVarArgs;
- //function GetParameters:
- end;
- TRttiMethodArray = array of TRttiMethod;
- { TRttiProperty }
- TRttiProperty = class(TRttiMember)
- private
- function GetPropertyType: TRttiType;
- function GetIsWritable: boolean;
- function GetIsReadable: boolean;
- protected
- function GetVisibility: TMemberVisibility; override;
- public
- //function GetValue(Instance: Pointer): TValue;
- //procedure SetValue(Instance: Pointer; const AValue: TValue);
- property PropertyType: TRttiType read GetPropertyType;
- property IsReadable: boolean read GetIsReadable;
- property IsWritable: boolean read GetIsWritable;
- property Visibility: TMemberVisibility read GetVisibility;
- end;
- TRttiPropertyArray = array of TRttiProperty;
- { TRttiType }
- TRttiType = class(TRttiNamedObject)
- private
- FAttributes: TCustomAttributeArray;
- FTypeInfo: TTypeInfo;
- //FMethods: specialize TArray<TRttiMethod>;
- //function GetAsInstance: TRttiInstanceType;
- protected
- function GetName: string; override;
- //function GetHandle: Pointer; override;
- function GetIsInstance: boolean; virtual;
- //function GetIsManaged: boolean; virtual;
- function GetIsOrdinal: boolean; virtual;
- function GetIsRecord: boolean; virtual;
- function GetIsSet: boolean; virtual;
- function GetTypeKind: TTypeKind; virtual;
- //function GetTypeSize: integer; virtual;
- //function GetBaseType: TRttiType; virtual;
- public
- constructor Create(ATypeInfo : PTypeInfo);
- destructor Destroy; override;
- function GetAttributes: TCustomAttributeArray; override;
- function GetField(const AName: string): TRttiField; virtual;
- function GetMethods(const aName: String): TRttiMethodArray; virtual;
- function GetMethod(const aName: String): TRttiMethod; virtual;
- function GetProperty(const AName: string): TRttiProperty; virtual;
- //function GetIndexedProperty(const AName: string): TRttiIndexedProperty; virtual;
- function GetDeclaredProperties: TRttiPropertyArray; virtual;
- //function GetDeclaredIndexedProperties: TRttiIndexedPropertyArray; virtual;
- function GetDeclaredMethods: TRttiMethodArray; virtual;
- function GetDeclaredFields: TRttiFieldArray; virtual;
- property IsInstance: boolean read GetIsInstance;
- //property isManaged: boolean read GetIsManaged;
- property IsOrdinal: boolean read GetIsOrdinal;
- property IsRecord: boolean read GetIsRecord;
- property IsSet: boolean read GetIsSet;
- //property BaseType: TRttiType read GetBaseType;
- //property AsInstance: TRttiInstanceType read GetAsInstance;
- property TypeKind: TTypeKind read GetTypeKind;
- //property TypeSize: integer read GetTypeSize;
- end;
- { TRttiStructuredType }
- TRttiStructuredType = class abstract(TRttiType)
- end;
- { TRttiInstanceType }
- TRttiInstanceType = class(TRttiStructuredType)
- private
- function GetClassTypeInfo: TTypeInfoClass;
- function GetMetaClassType: TClass;
- public
- constructor Create(ATypeInfo: PTypeInfo);
- property ClassTypeInfo: TTypeInfoClass read GetClassTypeInfo;
- property MetaClassType: TClass read GetMetaClassType;
- //function GetDeclaredProperties: TRttiPropertyArray;
- end;
- EInvoke = EJS;
- TVirtualInterfaceInvokeEvent = function(const aMethodName: string;
- const Args: TJSValueDynArray): JSValue of object;
- { TVirtualInterface: A class that can implement any IInterface. Any method
- call is handled by the OnInvoke event. }
- TVirtualInterface = class(TInterfacedObject, IInterface)
- private
- FOnInvoke: TVirtualInterfaceInvokeEvent;
- public
- constructor Create(InterfaceTypeInfo: Pointer); overload; assembler;
- constructor Create(InterfaceTypeInfo: Pointer;
- const InvokeEvent: TVirtualInterfaceInvokeEvent); overload;
- property OnInvoke: TVirtualInterfaceInvokeEvent read FOnInvoke write FOnInvoke;
- end;
- procedure CreateVirtualCorbaInterface(InterfaceTypeInfo: Pointer;
- const MethodImplementation: TVirtualInterfaceInvokeEvent; out IntfVar); assembler;
- function Invoke(ACodeAddress: Pointer; const AArgs: TJSValueDynArray;
- ACallConv: TCallConv; AResultType: PTypeInfo; AIsStatic: Boolean;
- AIsConstructor: Boolean): TValue;
- implementation
- var
- GRttiContext: TRTTIContext;
- procedure CreateVirtualCorbaInterface(InterfaceTypeInfo: Pointer;
- const MethodImplementation: TVirtualInterfaceInvokeEvent; out IntfVar); assembler;
- asm
- var IntfType = InterfaceTypeInfo.interface;
- var i = Object.create(IntfType);
- var o = { $name: "virtual", $fullname: "virtual" };
- i.$o = o;
- do {
- var names = IntfType.$names;
- if (!names) break;
- for (var j=0; j<names.length; j++){
- let fnname = names[j];
- i[fnname] = function(){ return MethodImplementation(fnname,arguments); };
- }
- IntfType = Object.getPrototypeOf(IntfType);
- } while(IntfType!=null);
- IntfVar.set(i);
- end;
- { TValue }
- function TValue.GetTypeKind: TTypeKind;
- begin
- if TypeInfo=nil then
- Result:=tkUnknown
- else
- Result:=FTypeInfo.Kind;
- end;
- class function TValue.FromJSValue(v: JSValue): TValue;
- var
- i: NativeInt;
- begin
- Result.FData:=v;
- case jsTypeOf(v) of
- 'number':
- if JS.isInteger(v) then
- begin
- i:=NativeInt(v);
- if (i>=low(integer)) and (i<=high(integer)) then
- Result.FTypeInfo:=system.TypeInfo(Integer)
- else
- Result.FTypeInfo:=system.TypeInfo(NativeInt);
- end
- else
- Result.FTypeInfo:=system.TypeInfo(Double);
- 'string': Result.FTypeInfo:=system.TypeInfo(String);
- 'boolean': Result.FTypeInfo:=system.TypeInfo(Boolean);
- 'object':
- begin
- if v=nil then
- Result.FTypeInfo:=system.TypeInfo(Pointer)
- else if JS.isClass(v) and JS.isExt(v,TObject) then
- Result.FTypeInfo:=system.TypeInfo(TClass(v))
- else if JS.isObject(v) and JS.isExt(v,TObject) then
- Result.FTypeInfo:=system.TypeInfo(TObject(v))
- else
- Result.FTypeInfo:=system.TypeInfo(Pointer);
- if (Result.FTypeInfo=JS.Undefined) or (Result.FTypeInfo=nil) then
- Result.FTypeInfo:=system.TypeInfo(Pointer);
- end
- else
- Result.FTypeInfo:=system.TypeInfo(JSValue);
- end;
- end;
- function TValue.IsObject: boolean;
- begin
- Result:=IsEmpty or (TypeInfo.Kind=tkClass);
- end;
- function TValue.AsObject: TObject;
- begin
- if IsObject or (IsClass and not js.isObject(FData)) then
- Result := TObject(FData)
- else
- raise EInvalidCast.Create(SErrInvalidTypecast);
- end;
- function TValue.IsObjectInstance: boolean;
- begin
- Result:=(TypeInfo<>nil) and (TypeInfo.Kind=tkClass);
- end;
- function TValue.IsArray: boolean;
- begin
- Result := Kind in [tkArray, tkDynArray];
- end;
- function TValue.IsClass: boolean;
- var
- k: TTypeKind;
- begin
- k:=Kind;
- Result := (k = tkClassRef)
- or ((k in [tkClass,tkUnknown]) and not JS.IsObject(FData));
- end;
- function TValue.AsClass: TClass;
- begin
- if IsClass then
- Result := TClass(FData)
- else
- raise EInvalidCast.Create(SErrInvalidTypecast);
- end;
- function TValue.IsOrdinal: boolean;
- var
- k: TTypeKind;
- begin
- k:=Kind;
- Result := (k in [tkInteger, tkBool]) or
- ((k in [tkClass, tkClassRef, tkUnknown]) and not JS.isObject(FData));
- end;
- function TValue.AsOrdinal: NativeInt;
- begin
- if IsOrdinal then
- Result:=NativeInt(FData)
- else
- raise EInvalidCast.Create(SErrInvalidTypecast);
- end;
- function TValue.AsBoolean: boolean;
- begin
- if (Kind = tkBool) then
- Result:=boolean(FData)
- else
- raise EInvalidCast.Create(SErrInvalidTypecast);
- end;
- function TValue.AsInteger: Integer;
- begin
- if JS.isInteger(FData) then
- Result:=NativeInt(FData)
- else
- raise EInvalidCast.Create(SErrInvalidTypecast);
- end;
- function TValue.AsNativeInt: NativeInt;
- begin
- if JS.isInteger(FData) then
- Result:=NativeInt(FData)
- else
- raise EInvalidCast.Create(SErrInvalidTypecast);
- end;
- function TValue.AsInterface: IInterface;
- var
- k: TTypeKind;
- begin
- k:=Kind;
- if k = tkInterface then
- Result := IInterface(FData)// ToDo
- else if (k in [tkClass, tkClassRef, tkUnknown]) and not JS.isObject(FData) then
- Result := Nil
- else
- raise EInvalidCast.Create(SErrInvalidTypecast);
- end;
- function TValue.AsString: string;
- begin
- if js.isString(FData) then
- Result:=String(FData)
- else
- raise EInvalidCast.Create(SErrInvalidTypecast);
- end;
- function TValue.AsUnicodeString: UnicodeString;
- begin
- Result:=AsString;
- end;
- function TValue.AsExtended: Extended;
- begin
- if js.isNumber(FData) then
- Result:=Double(FData)
- else
- raise EInvalidCast.Create(SErrInvalidTypecast);
- end;
- function TValue.ToString: String;
- begin
- case Kind of
- tkString: Result := AsString;
- tkInteger: Result := IntToStr(AsNativeInt);
- tkBool: Result := BoolToStr(AsBoolean, True);
- else
- Result := '';
- end;
- end;
- function TValue.GetArrayLength: SizeInt;
- begin
- if not IsArray then
- raise EInvalidCast.Create(SErrInvalidTypecast);
- Result:=length(TJSValueDynArray(FData));
- end;
- function TValue.GetArrayElement(aIndex: SizeInt): TValue;
- var
- StaticTI: TTypeInfoStaticArray;
- DynIT: TTypeInfoDynArray;
- begin
- case Kind of
- tkDynArray:
- begin
- DynIT:=TTypeInfoDynArray(FTypeInfo);
- Result.FTypeInfo:=DynIT.ElType;
- if DynIT.DimCount<>1 then
- raise EInvalidCast.Create(SErrInvalidTypecast);
- end;
- tkArray:
- begin
- StaticTI:=TTypeInfoStaticArray(FTypeInfo);
- if length(StaticTI.Dims)<>1 then
- raise EInvalidCast.Create(SErrInvalidTypecast);
- Result.FTypeInfo:=StaticTI.ElType;
- end;
- else
- raise EInvalidCast.Create(SErrInvalidTypecast);
- end;
- Result.FData:=TJSValueDynArray(FData)[aIndex];
- end;
- function TValue.IsType(ATypeInfo: PTypeInfo): boolean;
- begin
- Result := ATypeInfo = TypeInfo;
- end;
- function TValue.GetIsEmpty: boolean;
- begin
- if (TypeInfo=nil) or (FData=Undefined) or (FData=nil) then
- exit(true);
- case TypeInfo.Kind of
- tkDynArray:
- Result:=TJSArray(FData).Length=0;
- else
- Result:=false;
- end;
- end;
- { TRttiInstanceType }
- function TRttiInstanceType.GetClassTypeInfo: TTypeInfoClass;
- begin
- Result:=TTypeInfoClass(FTypeInfo);
- end;
- function TRttiInstanceType.GetMetaClassType: TClass;
- begin
- Result:=TTypeInfoClass(FTypeInfo).ClassType;
- end;
- constructor TRttiInstanceType.Create(ATypeInfo: PTypeInfo);
- begin
- if not (TTypeInfo(ATypeInfo) is TTypeInfoClass) then
- raise EInvalidCast.Create('');
- inherited Create(ATypeInfo);
- end;
- { TRTTIContext }
- class constructor TRTTIContext.Init;
- begin
- GRttiContext:=TRTTIContext.Create;
- end;
- class function TRTTIContext.Create: TRTTIContext;
- begin
- Result.FPool:=TJSObject.new;
- end;
- procedure TRTTIContext.Free;
- var
- key: string;
- o: TRttiType;
- begin
- for key in FPool do
- if FPool.hasOwnProperty(key) then begin
- o:=TRTTIType(FPool[key]);
- o.Free;
- end;
- FPool:=nil;
- end;
- function TRTTIContext.GetType(aTypeInfo: PTypeInfo): TRTTIType;
- var
- t: TTypeinfo absolute aTypeInfo;
- Name: String;
- begin
- if aTypeInfo=nil then exit(nil);
- Name:=t.Name;
- if isModule(t.Module) then
- Name:=t.Module.Name+'.'+Name;
- if FPool.hasOwnProperty(Name) then
- Result:=TRttiType(FPool[Name])
- else
- begin
- Result:=TRttiType.Create(aTypeInfo);
- FPool[Name]:=Result;
- end;
- end;
- function TRTTIContext.GetType(aClass: TClass): TRTTIType;
- begin
- if aClass=nil then exit(nil);
- Result:=GetType(TypeInfo(aClass));
- end;
- { TRttiObject }
- function TRttiObject.GetAttributes: TCustomAttributeArray;
- begin
- Result:=nil;
- end;
- { TRttiNamedObject }
- function TRttiNamedObject.GetName: string;
- begin
- Result:='';
- end;
- { TRttiMember }
- function TRttiMember.GetName: string;
- begin
- Result:=FTypeInfo.Name;
- end;
- function TRttiMember.GetVisibility: TMemberVisibility;
- begin
- Result:=mvPublished;
- end;
- constructor TRttiMember.Create(AParent: TRttiType; ATypeInfo: TTypeMember);
- begin
- inherited Create();
- FParent := AParent;
- FTypeInfo:=ATypeInfo;
- end;
- function TRttiMember.GetAttributes: TCustomAttributeArray;
- begin
- Result:=inherited GetAttributes;
- end;
- { TRttiField }
- function TRttiField.GetFieldType: TRttiType;
- begin
- Result := GRttiContext.GetType(FTypeInfo);
- end;
- { TRttiMethod }
- function TRttiMethod.GetIsClassMethod: boolean;
- begin
- Result:=TTypeMemberMethod(FTypeInfo).MethodKind in [mkClassFunction,mkClassProcedure];
- end;
- function TRttiMethod.GetIsConstructor: boolean;
- begin
- Result:=TTypeMemberMethod(FTypeInfo).MethodKind=mkConstructor;
- end;
- function TRttiMethod.GetIsDestructor: boolean;
- begin
- Result:=TTypeMemberMethod(FTypeInfo).MethodKind=mkDestructor;
- end;
- function TRttiMethod.GetIsExternal: boolean;
- begin
- Result:=(TTypeMemberMethod(FTypeInfo).ProcSig.Flags and 4)>0; // pfExternal
- end;
- function TRttiMethod.GetIsStatic: boolean;
- begin
- Result:=(TTypeMemberMethod(FTypeInfo).ProcSig.Flags and 1)>0; // pfStatic
- end;
- function TRttiMethod.GetIsVarArgs: boolean;
- begin
- Result:=(TTypeMemberMethod(FTypeInfo).ProcSig.Flags and 2)>0; // pfVarargs
- end;
- function TRttiMethod.GetMethodKind: TMethodKind;
- begin
- Result:=TTypeMemberMethod(FTypeInfo).MethodKind;;
- end;
- function TRttiMethod.GetReturnType: TRttiType;
- begin
- Result := GRttiContext.GetType(TTypeMemberMethod(FTypeInfo).ProcSig.ResultType);
- end;
- { TRttiProperty }
- function TRttiProperty.GetPropertyType: TRttiType;
- begin
- Result := GRttiContext.GetType(FTypeInfo);
- end;
- function TRttiProperty.GetIsWritable: boolean;
- begin
- Result := TTypeMemberProperty(FTypeInfo).Setter<>'';
- end;
- function TRttiProperty.GetIsReadable: boolean;
- begin
- Result := TTypeMemberProperty(FTypeInfo).Getter<>'';
- end;
- function TRttiProperty.GetVisibility: TMemberVisibility;
- begin
- // At this moment only pulished rtti-property-info is supported by pas2js
- Result := mvPublished;
- end;
- { TRttiType }
- function TRttiType.GetName: string;
- begin
- Result:=FTypeInfo.Name;
- end;
- function TRttiType.GetIsInstance: boolean;
- begin
- Result:=false;
- end;
- function TRttiType.GetIsOrdinal: boolean;
- begin
- Result:=false;
- end;
- function TRttiType.GetIsRecord: boolean;
- begin
- Result:=false;
- end;
- function TRttiType.GetIsSet: boolean;
- begin
- Result:=false;
- end;
- function TRttiType.GetTypeKind: TTypeKind;
- begin
- Result:=FTypeInfo.Kind;
- end;
- constructor TRttiType.Create(ATypeInfo: PTypeInfo);
- begin
- inherited Create();
- FTypeInfo:=TTypeInfo(ATypeInfo);
- end;
- destructor TRttiType.Destroy;
- var
- o: TCustomAttribute;
- begin
- for o in FAttributes do
- o.Free;
- FAttributes:=nil;
- inherited Destroy;
- end;
- function TRttiType.GetAttributes: TCustomAttributeArray;
- begin
- FAttributes:=GetRTTIAttributes(FTypeInfo.Attributes);
- Result:=FAttributes;
- end;
- function TRttiType.GetDeclaredProperties: TRttiPropertyArray;
- begin
- Result:=nil;
- end;
- function TRttiType.GetProperty(const AName: string): TRttiProperty;
- begin
- Result:=nil;
- if AName='' then ;
- end;
- function TRttiType.GetMethods(const aName: String): TRttiMethodArray;
- begin
- Result:=nil;
- end;
- function TRttiType.GetMethod(const aName: String): TRttiMethod;
- begin
- Result:=nil;
- if aName='' then ;
- end;
- function TRttiType.GetDeclaredMethods: TRttiMethodArray;
- begin
- Result:=nil;
- end;
- function TRttiType.GetDeclaredFields: TRttiFieldArray;
- begin
- Result:=nil;
- end;
- function TRttiType.GetField(const AName: string): TRttiField;
- begin
- Result:=nil;
- if AName='' then ;
- end;
- { TVirtualInterface }
- constructor TVirtualInterface.Create(InterfaceTypeInfo: Pointer); assembler;
- asm
- var IntfType = InterfaceTypeInfo.interface;
- if (IntfType.$kind !== 'com') rtl.raiseE('EInvalidCast');
- var guid = IntfType.$guid;
- var i = Object.create(IntfType); // needed by IntfVar is IntfType
- i.$o = this;
- // copy IInterface methods: _AddRef, _Release, QueryInterface
- var iinterfaceguid = '{00000000-0000-0000-C000-000000000046}';
- var map = this.$intfmaps[iinterfaceguid];
- for (var key in map){
- var v = map[key];
- if (typeof(v)!=='function') continue;
- i[key] = map[key];
- }
- // all other methods call OnInvoke
- do {
- var names = IntfType.$names;
- if (!names) break;
- for (var j=0; j<names.length; j++){
- let fnname = names[j];
- if (i[fnname]) continue;
- i[fnname] = function(){ return this.$o.FOnInvoke(fnname,arguments); };
- }
- IntfType = Object.getPrototypeOf(IntfType);
- } while(IntfType!=null);
- // create a new list of interface map, supporting IInterface and IntfType
- this.$intfmaps = {};
- this.$intfmaps[iinterfaceguid] = map;
- this.$intfmaps[guid] = {};
- // store the implementation of IntfType (used by the as-operator)
- this.$interfaces = {};
- this.$interfaces[guid] = i;
- end;
- constructor TVirtualInterface.Create(InterfaceTypeInfo: Pointer;
- const InvokeEvent: TVirtualInterfaceInvokeEvent);
- begin
- Create(InterfaceTypeInfo);
- OnInvoke:=InvokeEvent;
- end;
- function Invoke(ACodeAddress: Pointer; const AArgs: TJSValueDynArray;
- ACallConv: TCallConv; AResultType: PTypeInfo; AIsStatic: Boolean;
- AIsConstructor: Boolean): TValue;
- begin
- if ACallConv=ccReg then ;
- if AIsStatic then ;
- if AIsConstructor then
- raise EInvoke.Create('not supported');
- if isFunction(ACodeAddress) then
- begin
- Result.FData := TJSFunction(ACodeAddress).apply(nil, AArgs);
- if AResultType<>nil then
- Result.FTypeInfo:=AResultType
- else
- Result.FTypeInfo:=TypeInfo(JSValue);
- end
- else
- raise EInvoke.Create(SErrInvokeInvalidCodeAddr);
- end;
- end.
|