12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559 |
- {
- 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 TypInfo;
- {$mode objfpc}
- {$modeswitch externalclass}
- interface
- uses
- SysUtils, Types, RTLConsts, JS;
- type
- // TCallConv for compatibility with Delphi/FPC, ignored under pas2js
- TCallConv = (ccReg, ccCdecl, ccPascal, ccStdCall, ccSafeCall, ccCppdecl,
- ccFar16, ccOldFPCCall, ccInternProc, ccSysCall, ccSoftFloat, ccMWPascal);
- { TSectionRTTI }
- TSectionRTTI = class external name 'rtl.tSectionRTTI'(TJSObject)
- end;
- { TTypeInfoModule }
- TTypeInfoModule = class external name 'pasmodule'(TJSObject)
- public
- Name: String external name '$name';
- RTTI: TSectionRTTI external name '$rtti';
- end;
- TTypeInfoAttributes = type TJSValueDynArray;
- { TTypeInfo }
- TTypeInfo = class external name 'rtl.tTypeInfo'
- public
- Name: String external name 'name';
- Kind: TTypeKind external name 'kind';
- Attributes: TTypeInfoAttributes external name 'attr'; // can be undefined
- Module: TTypeInfoModule external name '$module'; // can be undefined
- end;
- TTypeInfoClassOf = class of TTypeInfo;
- PTypeInfo = Pointer; // for compatibility with Delphi/FPC, under pas2js it is a TTypeInfo
- TOrdType = (
- otSByte, // 0
- otUByte, // 1
- otSWord, // 2
- otUWord, // 3
- otSLong, // 4
- otULong, // 5
- otSIntDouble, // 6 NativeInt
- otUIntDouble // 7 NativeUInt
- );
- { TTypeInfoInteger - Kind = tkInteger }
- TTypeInfoInteger = class external name 'rtl.tTypeInfoInteger'(TTypeInfo)
- public
- MinValue: NativeInt external name 'minvalue';
- MaxValue: NativeInt external name 'maxvalue';
- OrdType : TOrdType external name 'ordtype';
- end;
- { TEnumType }
- TEnumType = class external name 'anonymous'
- private
- function GetIntToName(Index: NativeInt): String; external name '[]';
- function GetNameToInt(Name: String): NativeInt; external name '[]';
- public
- property IntToName[Index: NativeInt]: String read GetIntToName;
- property NameToInt[Name: String]: NativeInt read GetNameToInt;
- end;
- { TTypeInfoEnum - Kind = tkEnumeration }
- TTypeInfoEnum = class external name 'rtl.tTypeInfoEnum'(TTypeInfoInteger)
- public
- // not supported: BaseType: TTypeInfo
- EnumType: TEnumType external name 'enumtype';
- end;
- { TTypeInfoSet - Kind = tkSet }
- TTypeInfoSet = class external name 'rtl.tTypeInfoSet'(TTypeInfo)
- public
- // not supported: BaseType: TTypeInfo
- CompType: TTypeInfo external name 'comptype';
- end;
- { TTypeInfoStaticArray - Kind = tkArray }
- TTypeInfoStaticArray = class external name 'rtl.tTypeInfoStaticArray'(TTypeInfo)
- public
- Dims: TIntegerDynArray external name 'dims';
- ElType: TTypeInfo external name 'eltype';
- end;
- { TTypeInfoDynArray - Kind = tkDynArray }
- TTypeInfoDynArray = class external name 'rtl.tTypeInfoDynArray'(TTypeInfo)
- public
- ElType: TTypeInfo external name 'eltype';
- end;
- TParamFlag = (
- pfVar, // 2^0 = 1
- pfConst, // 2^1 = 2
- pfOut, // 2^2 = 4
- pfArray, // 2^3 = 8
- pfAddress, // 2^4 = 16
- pfReference // 2^5 = 32
- );
- TParamFlags = set of TParamFlag;
- { TProcedureParam }
- TProcedureParam = class external name 'anonymous'
- public
- Name: String external name 'name';
- TypeInfo: TTypeInfo external name 'typeinfo';
- Flags: NativeInt external name 'flags'; // TParamFlags as bit vector
- end;
- TProcedureParams = array of TProcedureParam;
- TProcedureFlag = (
- pfStatic, // 2^0 = 1
- pfVarargs, // 2^1 = 2
- pfExternal, // 2^2 = 4 name may be an expression
- pfSafeCall, // 2^3 = 8
- pfAsync // 2^4 = 16
- );
- TProcedureFlags = set of TProcedureFlag;
- { TProcedureSignature }
- TProcedureSignature = class external name 'anonymous'
- public
- Params: TProcedureParams external name 'params'; // can be null
- ResultType: TTypeInfo external name 'resulttype'; // can be null
- Flags: NativeInt external name 'flags'; // TProcedureFlags as bit vector
- end;
- { TTypeInfoProcVar - Kind = tkProcVar }
- TTypeInfoProcVar = class external name 'rtl.tTypeInfoProcVar'(TTypeInfo)
- public
- ProcSig: TProcedureSignature external name 'procsig';
- end;
- { TTypeInfoRefToProcVar - Kind = tkRefToProcVar }
- TTypeInfoRefToProcVar = class external name 'rtl.tTypeInfoRefToProcVar'(TTypeInfoProcVar)
- end;
- TMethodKind = (
- mkProcedure, // 0 default
- mkFunction, // 1
- mkConstructor, // 2
- mkDestructor, // 3
- mkClassProcedure,// 4
- mkClassFunction // 5
- //mkClassConstructor,mkClassDestructor,mkOperatorOverload
- );
- TMethodKinds = set of TMethodKind;
- { TTypeInfoMethodVar - Kind = tkMethod }
- TTypeInfoMethodVar = class external name 'rtl.tTypeInfoMethodVar'(TTypeInfoProcVar)
- public
- MethodKind: TMethodKind external name 'methodkind';
- end;
- TTypeMemberKind = (
- tmkUnknown, // 0
- tmkField, // 1
- tmkMethod, // 2
- tmkProperty // 3
- );
- TTypeMemberKinds = set of TTypeMemberKind;
- { TTypeMember }
- TTypeMember = class external name 'rtl.tTypeMember'
- public
- Name: String external name 'name';
- Kind: TTypeMemberKind external name 'kind';
- Attributes: TTypeInfoAttributes external name 'attr'; // can be undefined
- end;
- TTypeMemberDynArray = array of TTypeMember;
- { TTypeMemberField - Kind = tmkField }
- TTypeMemberField = class external name 'rtl.tTypeMemberField'(TTypeMember)
- public
- TypeInfo: TTypeInfo external name 'typeinfo';
- end;
- { TTypeMemberMethod - Kind = tmkMethod }
- TTypeMemberMethod = class external name 'rtl.tTypeMemberMethod'(TTypeMember)
- public
- MethodKind: TMethodKind external name 'methodkind';
- ProcSig: TProcedureSignature external name 'procsig';
- end;
- TTypeMemberMethodDynArray = array of TTypeMemberMethod;
- const
- pfGetFunction = 1; // getter is a function
- pfSetProcedure = 2; // setter is a procedure
- // stored is a 2-bit vector:
- pfStoredFalse = 4; // stored false, never
- pfStoredField = 8; // stored field, field name is in Stored
- pfStoredFunction = 12; // stored function, function name is in Stored
- pfHasIndex = 16; { if getter is function, append Index as last param
- if setter is function, append Index as second last param }
- type
- { TTypeMemberProperty - Kind = tmkProperty }
- TTypeMemberProperty = class external name 'rtl.tTypeMemberProperty'(TTypeMember)
- public
- TypeInfo: TTypeInfo external name 'typeinfo';
- Flags: NativeInt external name 'flags'; // bit vector, see pf constants above
- Params: TProcedureParams external name 'params'; // can be null or undefined
- Index: JSValue external name 'index'; // can be undefined
- Getter: String external name 'getter'; // name of field or function
- Setter: String external name 'setter'; // name of field or function
- Stored: String external name 'stored'; // name of field or function, can be undefined
- Default: JSValue external name 'Default'; // can be undefined
- end;
- TTypeMemberPropertyDynArray = array of TTypeMemberProperty;
- { TTypeMembers }
- TTypeMembers = class external name 'rtl.tTypeMembers'
- private
- function GetItems(Name: String): TTypeMember; external name '[]';
- procedure SetItems(Name: String; const AValue: TTypeMember); external name '[]';
- public
- property Members[Name: String]: TTypeMember read GetItems write SetItems; default;
- end;
- { TTypeInfoStruct }
- TTypeInfoStruct = class external name 'rtl.tTypeInfoStruct'(TTypeInfo)
- private
- FFieldCount: NativeInt external name 'fields.length';
- FMethodCount: NativeInt external name 'methods.length';
- FPropCount: NativeInt external name 'properties.length';
- public
- Members: TTypeMembers external name 'members';
- Names: TStringDynArray external name 'names'; // all member names with TTypeInfo
- Fields: TStringDynArray external name 'fields';
- Methods: TStringDynArray external name 'methods';
- Properties: TStringDynArray external name 'properties';
- property FieldCount: NativeInt read FFieldCount;
- function GetField(Index: NativeInt): TTypeMemberField; external name 'getField';
- function AddField(aName: String; aType: TTypeInfo; Options: TJSObject = nil
- ): TTypeMemberField; external name 'addField';
- property MethodCount: NativeInt read FMethodCount;
- function GetMethod(Index: NativeInt): TTypeMemberMethod; external name 'getMethod';
- function AddMethod(aName: String; MethodKind: TMethodKind = mkProcedure;
- Params: TJSArray = nil; ResultType: TTypeInfo = nil;
- Options: TJSObject = nil): TTypeMemberMethod; external name 'addMethod';
- property PropCount: NativeInt read FPropCount;
- function GetProp(Index: NativeInt): TTypeMemberProperty; external name 'getProperty';
- function AddProperty(aName: String; Flags: NativeInt; ResultType: TTypeInfo;
- Getter, Setter: String; Options: TJSObject = nil): TTypeMemberProperty; external name 'addProperty';
- end;
- { TTypeInfoRecord - Kind = tkRecord }
- TTypeInfoRecord = class external name 'rtl.tTypeInfoRecord'(TTypeInfoStruct)
- public
- RecordType: TJSObject external name '$record'; // only records with class vars, else jsundefined
- end;
- { TTypeInfoClass - Kind = tkClass }
- TTypeInfoClass = class external name 'rtl.tTypeInfoClass'(TTypeInfoStruct)
- public
- ClassType: TClass external name 'class';
- Ancestor: TTypeInfoClass external name 'ancestor';
- end;
- { TTypeInfoExtClass - Kind = tkExtClass }
- TTypeInfoExtClass = class external name 'rtl.tTypeInfoExtClass'(TTypeInfoClass)
- public
- JSClassName: String external name 'jsclass';
- end;
- { TTypeInfoClassRef - class-of, Kind = tkClassRef }
- TTypeInfoClassRef = class external name 'rtl.tTypeInfoClassRef'(TTypeInfo)
- public
- InstanceType: TTypeInfo external name 'instancetype';
- end;
- { TTypeInfoPointer - Kind = tkPointer }
- TTypeInfoPointer = class external name 'rtl.tTypeInfoPointer'(TTypeInfo)
- public
- RefType: TTypeInfo external name 'reftype'; // can be null
- end;
- { TTypeInfoInterface - Kind = tkInterface }
- TTypeInfoInterface = class external name 'rtl.tTypeInfoInterface'(TTypeInfoStruct)
- public
- InterfaceType: TJSObject external name 'interface';
- Ancestor: TTypeInfoInterface external name 'ancestor';
- end;
- { TTypeInfoHelper - Kind = tkHelper }
- TTypeInfoHelper = class external name 'rtl.tTypeInfoHelper'(TTypeInfoStruct)
- public
- HelperType: TJSObject external name 'helper';
- Ancestor: TTypeInfoHelper external name 'ancestor';
- HelperFor: TTypeInfo external name 'helperfor';
- end;
- EPropertyError = class(Exception);
- function GetTypeName(TypeInfo: TTypeInfo): string;
- function GetClassMembers(aTIStruct: TTypeInfoStruct): TTypeMemberDynArray;
- function GetClassMember(aTIStruct: TTypeInfoStruct; const aName: String): TTypeMember;
- function GetInstanceMethod(Instance: TObject; const aName: String): Pointer;
- function GetClassMethods(aTIStruct: TTypeInfoStruct): TTypeMemberMethodDynArray;
- function CreateMethod(Instance: TObject; FuncName: String): Pointer; external name 'rtl.createCallback';
- function GetInterfaceMembers(aTIInterface: TTypeInfoInterface): TTypeMemberDynArray;
- function GetInterfaceMember(aTIInterface: TTypeInfoInterface; const aName: String): TTypeMember;
- function GetInterfaceMethods(aTIInterface: TTypeInfoInterface): TTypeMemberMethodDynArray;
- function GetRTTIAttributes(const Attributes: TTypeInfoAttributes): TCustomAttributeArray;
- function GetPropInfos(aTIStruct: TTypeInfoStruct): TTypeMemberPropertyDynArray;
- function GetPropList(aTIStruct: TTypeInfoStruct; TypeKinds: TTypeKinds; Sorted: boolean = true): TTypeMemberPropertyDynArray;
- function GetPropList(aTIStruct: TTypeInfoStruct): TTypeMemberPropertyDynArray;
- function GetPropList(AClass: TClass): TTypeMemberPropertyDynArray;
- function GetPropList(Instance: TObject): TTypeMemberPropertyDynArray;
- function GetPropInfo(TI: TTypeInfoStruct; const PropName: String): TTypeMemberProperty;
- function GetPropInfo(TI: TTypeInfoStruct; const PropName: String; const Kinds: TTypeKinds): TTypeMemberProperty;
- function GetPropInfo(Instance: TObject; const PropName: String): TTypeMemberProperty;
- function GetPropInfo(Instance: TObject; const PropName: String; const Kinds: TTypeKinds): TTypeMemberProperty;
- function GetPropInfo(aClass: TClass; const PropName: String): TTypeMemberProperty;
- function GetPropInfo(aClass: TClass; const PropName: String; const Kinds: TTypeKinds): TTypeMemberProperty;
- function FindPropInfo(Instance: TObject; const PropName: String): TTypeMemberProperty;
- function FindPropInfo(Instance: TObject; const PropName: String; const Kinds: TTypeKinds): TTypeMemberProperty;
- function FindPropInfo(aClass: TClass; const PropName: String): TTypeMemberProperty;
- function FindPropInfo(aClass: TClass; const PropName: String; const Kinds: TTypeKinds): TTypeMemberProperty;
- // Property information routines.
- Function IsStoredProp(Instance: TObject; const PropInfo: TTypeMemberProperty): Boolean;
- Function IsStoredProp(Instance: TObject; const PropName: string): Boolean;
- function IsPublishedProp(Instance: TObject; const PropName: String): Boolean;
- function IsPublishedProp(aClass: TClass; const PropName: String): Boolean;
- function PropType(Instance: TObject; const PropName: string): TTypeKind;
- function PropType(aClass: TClass; const PropName: string): TTypeKind;
- function PropIsType(Instance: TObject; const PropName: string; const TypeKind: TTypeKind): Boolean;
- function PropIsType(aClass: TClass; const PropName: string; const TypeKind: TTypeKind): Boolean;
- function GetJSValueProp(Instance: TJSObject; TI: TTypeInfoStruct; const PropName: String): JSValue;
- function GetJSValueProp(Instance: TJSObject; const PropInfo: TTypeMemberProperty): JSValue;
- function GetJSValueProp(Instance: TObject; const PropName: String): JSValue;
- function GetJSValueProp(Instance: TObject; const PropInfo: TTypeMemberProperty): JSValue;
- procedure SetJSValueProp(Instance: TJSObject; TI: TTypeInfoStruct; const PropName: String; Value: JSValue);
- procedure SetJSValueProp(Instance: TJSObject; const PropInfo: TTypeMemberProperty; Value: JSValue);
- procedure SetJSValueProp(Instance: TObject; const PropName: String; Value: JSValue);
- procedure SetJSValueProp(Instance: TObject; const PropInfo: TTypeMemberProperty; Value: JSValue);
- function GetNativeIntProp(Instance: TObject; const PropName: String): NativeInt;
- function GetNativeIntProp(Instance: TObject; const PropInfo: TTypeMemberProperty): NativeInt;
- procedure SetNativeIntProp(Instance: TObject; const PropName: String; Value: NativeInt);
- procedure SetNativeIntProp(Instance: TObject; const PropInfo: TTypeMemberProperty; Value: NativeInt);
- function GetOrdProp(Instance: TObject; const PropName: String): longint;
- function GetOrdProp(Instance: TObject; const PropInfo: TTypeMemberProperty): longint;
- procedure SetOrdProp(Instance: TObject; const PropName: String; Value: longint);
- procedure SetOrdProp(Instance: TObject; const PropInfo: TTypeMemberProperty; Value: longint);
- function GetEnumProp(Instance: TObject; const PropName: String): String;
- function GetEnumProp(Instance: TObject; const PropInfo: TTypeMemberProperty): String;
- procedure SetEnumProp(Instance: TObject; const PropName: String; const Value: String);
- procedure SetEnumProp(Instance: TObject; const PropInfo: TTypeMemberProperty; const Value: String);
- // Auxiliary routines, which may be useful
- function GetEnumName(TypeInfo: TTypeInfoEnum; Value: Integer): String;
- function GetEnumValue(TypeInfo: TTypeInfoEnum; const Name: string): Longint;
- function GetEnumNameCount(TypeInfo: TTypeInfoEnum): Longint;
- function GetSetProp(Instance: TObject; const PropName: String): String; overload;
- function GetSetProp(Instance: TObject; const PropInfo: TTypeMemberProperty): String; overload;
- function GetSetPropArray(Instance: TObject; const PropName: String): TIntegerDynArray; overload;
- function GetSetPropArray(Instance: TObject; const PropInfo: TTypeMemberProperty): TIntegerDynArray; overload;
- procedure SetSetPropArray(Instance: TObject; const PropName: String; const Arr: TIntegerDynArray); overload;
- procedure SetSetPropArray(Instance: TObject; const PropInfo: TTypeMemberProperty; const Arr: TIntegerDynArray); overload;
- function GetBoolProp(Instance: TObject; const PropName: String): boolean;
- function GetBoolProp(Instance: TObject; const PropInfo: TTypeMemberProperty): boolean;
- procedure SetBoolProp(Instance: TObject; const PropName: String; Value: boolean);
- procedure SetBoolProp(Instance: TObject; const PropInfo: TTypeMemberProperty; Value: boolean);
- function GetStrProp(Instance: TObject; const PropName: String): String;
- function GetStrProp(Instance: TObject; const PropInfo: TTypeMemberProperty): String;
- procedure SetStrProp(Instance: TObject; const PropName: String; Value: String);
- procedure SetStrProp(Instance: TObject; const PropInfo: TTypeMemberProperty; Value: String);
- function GetStringProp(Instance: TObject; const PropName: String): String; deprecated; // use GetStrProp
- function GetStringProp(Instance: TObject; const PropInfo: TTypeMemberProperty): String; deprecated; // use GetStrProp
- procedure SetStringProp(Instance: TObject; const PropName: String; Value: String); deprecated; // use GetStrProp
- procedure SetStringProp(Instance: TObject; const PropInfo: TTypeMemberProperty; Value: String); deprecated; // use GetStrProp
- function GetFloatProp(Instance: TObject; const PropName: string): Double;
- function GetFloatProp(Instance: TObject; PropInfo : TTypeMemberProperty) : Double;
- procedure SetFloatProp(Instance: TObject; const PropName: string; Value: Double);
- procedure SetFloatProp(Instance: TObject; PropInfo : TTypeMemberProperty; Value : Double);
- function GetObjectProp(Instance: TObject; const PropName: String): TObject;
- function GetObjectProp(Instance: TObject; const PropName: String; MinClass: TClass): TObject;
- function GetObjectProp(Instance: TObject; const PropInfo: TTypeMemberProperty): TObject;
- function GetObjectProp(Instance: TObject; const PropInfo: TTypeMemberProperty; MinClass: TClass): TObject;
- procedure SetObjectProp(Instance: TObject; const PropName: String; Value: TObject) ;
- procedure SetObjectProp(Instance: TObject; const PropInfo: TTypeMemberProperty; Value: TObject);
- function GetMethodProp(Instance: TObject; PropInfo: TTypeMemberProperty): TMethod;
- function GetMethodProp(Instance: TObject; const PropName: string): TMethod;
- procedure SetMethodProp(Instance: TObject; PropInfo: TTypeMemberProperty; const Value : TMethod);
- procedure SetMethodProp(Instance: TObject; const PropName: string; const Value: TMethod);
- function GetInterfaceProp(Instance: TObject; const PropName: string): IInterface;
- function GetInterfaceProp(Instance: TObject; PropInfo: TTypeMemberProperty): IInterface;
- procedure SetInterfaceProp(Instance: TObject; const PropName: string; const Value: IInterface);
- procedure SetInterfaceProp(Instance: TObject; PropInfo: TTypeMemberProperty; const Value: IInterface);
- function GetRawInterfaceProp(Instance: TObject; const PropName: string): Pointer;
- function GetRawInterfaceProp(Instance: TObject; PropInfo: TTypeMemberProperty): Pointer;
- procedure SetRawInterfaceProp(Instance: TObject; const PropName: string; const Value: Pointer);
- procedure SetRawInterfaceProp(Instance: TObject; PropInfo: TTypeMemberProperty; const Value: Pointer);
- implementation
- function GetTypeName(TypeInfo: TTypeInfo): string;
- begin
- Result := TypeInfo.Name;
- end;
- function GetClassMembers(aTIStruct: TTypeInfoStruct): TTypeMemberDynArray;
- var
- C: TTypeInfoStruct;
- i: Integer;
- PropName: String;
- Names: TJSObject;
- begin
- Result:=nil;
- Names:=TJSObject.new;
- C:=aTIStruct;
- while C<>nil do
- begin
- for i:=0 to length(C.Names)-1 do
- begin
- PropName:=C.Names[i];
- if Names.hasOwnProperty(PropName) then continue;
- TJSArray(Result).push(C.Members[PropName]);
- Names[PropName]:=true;
- end;
- if not (C is TTypeInfoClass) then break;
- C:=TTypeInfoClass(C).Ancestor;
- end;
- end;
- function GetClassMember(aTIStruct: TTypeInfoStruct; const aName: String): TTypeMember;
- var
- C: TTypeInfoStruct;
- i: Integer;
- begin
- // quick search: case sensitive
- C:=aTIStruct;
- while C<>nil do
- begin
- if TJSObject(C.Members).hasOwnProperty(aName) then
- exit(C.Members[aName]);
- if not (C is TTypeInfoClass) then break;
- C:=TTypeInfoClass(C).Ancestor;
- end;
- // slow search: case insensitive
- C:=aTIStruct;
- while C<>nil do
- begin
- for i:=0 to length(C.Names)-1 do
- if CompareText(C.Names[i],aName)=0 then
- exit(C.Members[C.Names[i]]);
- if not (C is TTypeInfoClass) then break;
- C:=TTypeInfoClass(C).Ancestor;
- end;
- Result:=nil;
- end;
- function GetInstanceMethod(Instance: TObject; const aName: String): Pointer;
- var
- TI: TTypeMember;
- begin
- if Instance=nil then exit(nil);
- TI:=GetClassMember(TypeInfo(Instance),aName);
- if not (TI is TTypeMemberMethod) then exit(nil);
- Result:=CreateMethod(Instance,TI.Name); // Note: use TI.Name for the correct case!
- end;
- function GetClassMethods(aTIStruct: TTypeInfoStruct): TTypeMemberMethodDynArray;
- var
- C: TTypeInfoStruct;
- i, Cnt, j: Integer;
- begin
- Cnt:=0;
- C:=aTIStruct;
- while C<>nil do
- begin
- inc(Cnt,C.MethodCount);
- if not (C is TTypeInfoClass) then break;
- C:=TTypeInfoClass(C).Ancestor;
- end;
- SetLength(Result,Cnt);
- C:=aTIStruct;
- i:=0;
- while C<>nil do
- begin
- for j:=0 to C.MethodCount-1 do
- begin
- Result[i]:=TTypeMemberMethod(C.Members[C.Methods[j]]);
- inc(i);
- end;
- if not (C is TTypeInfoClass) then break;
- C:=TTypeInfoClass(C).Ancestor;
- end;
- end;
- function GetInterfaceMembers(aTIInterface: TTypeInfoInterface
- ): TTypeMemberDynArray;
- var
- Intf: TTypeInfoInterface;
- i, Cnt, j: Integer;
- begin
- Cnt:=0;
- Intf:=aTIInterface;
- while Intf<>nil do
- begin
- inc(Cnt,length(Intf.Names));
- Intf:=Intf.Ancestor;
- end;
- SetLength(Result,Cnt);
- Intf:=aTIInterface;
- i:=0;
- while Intf<>nil do
- begin
- for j:=0 to length(Intf.Names)-1 do
- begin
- Result[i]:=Intf.Members[Intf.Names[j]];
- inc(i);
- end;
- Intf:=Intf.Ancestor;
- end;
- end;
- function GetInterfaceMember(aTIInterface: TTypeInfoInterface;
- const aName: String): TTypeMember;
- var
- Intf: TTypeInfoInterface;
- i: Integer;
- begin
- // quick search: case sensitive
- Intf:=aTIInterface;
- while Intf<>nil do
- begin
- if TJSObject(Intf.Members).hasOwnProperty(aName) then
- exit(Intf.Members[aName]);
- Intf:=Intf.Ancestor;
- end;
- // slow search: case insensitive
- Intf:=aTIInterface;
- while Intf<>nil do
- begin
- for i:=0 to length(Intf.Names)-1 do
- if CompareText(Intf.Names[i],aName)=0 then
- exit(Intf.Members[Intf.Names[i]]);
- Intf:=Intf.Ancestor;
- end;
- Result:=nil;
- end;
- function GetInterfaceMethods(aTIInterface: TTypeInfoInterface
- ): TTypeMemberMethodDynArray;
- var
- Intf: TTypeInfoInterface;
- i, Cnt, j: Integer;
- begin
- Cnt:=0;
- Intf:=aTIInterface;
- while Intf<>nil do
- begin
- inc(Cnt,Intf.MethodCount);
- Intf:=Intf.Ancestor;
- end;
- SetLength(Result,Cnt);
- Intf:=aTIInterface;
- i:=0;
- while Intf<>nil do
- begin
- for j:=0 to Intf.MethodCount-1 do
- begin
- Result[i]:=TTypeMemberMethod(Intf.Members[Intf.Methods[j]]);
- inc(i);
- end;
- Intf:=Intf.Ancestor;
- end;
- end;
- type
- TCreatorAttribute = class external name 'attr'
- class function Create(const ProcName: string): TCustomAttribute; overload; external name '$create';
- class function Create(const ProcName: string; Params: jsvalue): TCustomAttribute; overload; external name '$create';
- end;
- TCreatorAttributeClass = class of TCreatorAttribute;
- function GetRTTIAttributes(const Attributes: TTypeInfoAttributes
- ): TCustomAttributeArray;
- var
- i, len: Integer;
- AttrClass: TCreatorAttributeClass;
- ProcName: String;
- Attr: TCustomAttribute;
- begin
- Result:=nil;
- if Attributes=Undefined then exit;
- i:=0;
- len:=length(Attributes);
- while i<len do
- begin
- AttrClass:=TCreatorAttributeClass(Attributes[i]);
- inc(i);
- ProcName:=String(Attributes[i]);
- inc(i);
- if (i<len) and isArray(Attributes[i]) then
- begin
- Attr:=AttrClass.Create(ProcName,Attributes[i]);
- inc(i);
- end
- else
- Attr:=AttrClass.Create(ProcName);
- Insert(Attr,Result,length(Result));
- end;
- end;
- function GetPropInfos(aTIStruct: TTypeInfoStruct): TTypeMemberPropertyDynArray;
- var
- C: TTypeInfoStruct;
- i: Integer;
- Names: TJSObject;
- PropName: String;
- begin
- Result:=nil;
- C:=aTIStruct;
- Names:=TJSObject.new;
- while C<>nil do
- begin
- for i:=0 to C.PropCount-1 do
- begin
- PropName:=C.Properties[i];
- if Names.hasOwnProperty(PropName) then continue;
- TJSArray(Result).push(TTypeMemberProperty(C.Members[PropName]));
- Names[PropName]:=true;
- end;
- if not (C is TTypeInfoClass) then
- break;
- C:=TTypeInfoClass(C).Ancestor;
- end;
- end;
- function GetPropList(aTIStruct: TTypeInfoStruct; TypeKinds: TTypeKinds;
- Sorted: boolean): TTypeMemberPropertyDynArray;
- function NameSort(a,b: JSValue): NativeInt;
- begin
- if TTypeMemberProperty(a).Name<TTypeMemberProperty(b).Name then
- Result:=-1
- else if TTypeMemberProperty(a).Name>TTypeMemberProperty(b).Name then
- Result:=1
- else
- Result:=0;
- end;
- var
- C: TTypeInfoStruct;
- i: Integer;
- Names: TJSObject;
- PropName: String;
- Prop: TTypeMemberProperty;
- begin
- Result:=nil;
- C:=aTIStruct;
- Names:=TJSObject.new;
- while C<>nil do
- begin
- for i:=0 to C.PropCount-1 do
- begin
- PropName:=C.Properties[i];
- if Names.hasOwnProperty(PropName) then continue;
- Prop:=TTypeMemberProperty(C.Members[PropName]);
- if not (Prop.TypeInfo.Kind in TypeKinds) then continue;
- TJSArray(Result).push(Prop);
- Names[PropName]:=true;
- end;
- if not (C is TTypeInfoClass) then
- break;
- C:=TTypeInfoClass(C).Ancestor;
- end;
- if Sorted then
- TJSArray(Result).sort(@NameSort);
- end;
- function GetPropList(aTIStruct: TTypeInfoStruct): TTypeMemberPropertyDynArray;
- begin
- Result:=GetPropInfos(aTIStruct);
- end;
- function GetPropList(AClass: TClass): TTypeMemberPropertyDynArray;
- begin
- Result:=GetPropInfos(TypeInfo(AClass));
- end;
- function GetPropList(Instance: TObject): TTypeMemberPropertyDynArray;
- begin
- Result:=GetPropList(Instance.ClassType);
- end;
- function GetPropInfo(TI: TTypeInfoStruct; const PropName: String
- ): TTypeMemberProperty;
- var
- m: TTypeMember;
- i: Integer;
- C: TTypeInfoStruct;
- begin
- // quick search case sensitive
- C:=TI;
- while C<>nil do
- begin
- m:=C.Members[PropName];
- if m is TTypeMemberProperty then
- exit(TTypeMemberProperty(m));
- if not (C is TTypeInfoClass) then
- break;
- C:=TTypeInfoClass(C).Ancestor;
- end;
- // slow search case insensitive
- Result:=nil;
- repeat
- for i:=0 to TI.PropCount-1 do
- if CompareText(PropName,TI.Properties[i])=0 then
- begin
- m:=TI.Members[TI.Properties[i]];
- if m is TTypeMemberProperty then
- Result:=TTypeMemberProperty(m);
- exit;
- end;
- if not (TI is TTypeInfoClass) then
- break;
- TI:=TTypeInfoClass(TI).Ancestor;
- until TI=nil;
- end;
- function GetPropInfo(TI: TTypeInfoStruct; const PropName: String;
- const Kinds: TTypeKinds): TTypeMemberProperty;
- begin
- Result:=GetPropInfo(TI,PropName);
- if (Kinds<>[]) and (Result<>nil) and not (Result.TypeInfo.Kind in Kinds) then
- Result:=nil;
- end;
- function GetPropInfo(Instance: TObject; const PropName: String
- ): TTypeMemberProperty;
- begin
- Result:=GetPropInfo(TypeInfo(Instance),PropName,[]);
- end;
- function GetPropInfo(Instance: TObject; const PropName: String;
- const Kinds: TTypeKinds): TTypeMemberProperty;
- begin
- Result:=GetPropInfo(TypeInfo(Instance),PropName,Kinds);
- end;
- function GetPropInfo(aClass: TClass; const PropName: String
- ): TTypeMemberProperty;
- begin
- Result:=GetPropInfo(TypeInfo(AClass),PropName,[]);
- end;
- function GetPropInfo(aClass: TClass; const PropName: String;
- const Kinds: TTypeKinds): TTypeMemberProperty;
- begin
- Result:=GetPropInfo(TypeInfo(AClass),PropName,Kinds);
- end;
- function FindPropInfo(Instance: TObject; const PropName: String
- ): TTypeMemberProperty;
- begin
- Result:=GetPropInfo(TypeInfo(Instance), PropName);
- if Result=nil then
- raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
- end;
- function FindPropInfo(Instance: TObject; const PropName: String;
- const Kinds: TTypeKinds): TTypeMemberProperty;
- begin
- Result:=GetPropInfo(TypeInfo(Instance), PropName, Kinds);
- if Result=nil then
- raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
- end;
- function FindPropInfo(aClass: TClass; const PropName: String
- ): TTypeMemberProperty;
- begin
- Result:=GetPropInfo(TypeInfo(aClass), PropName);
- if Result=nil then
- raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
- end;
- function FindPropInfo(aClass: TClass; const PropName: String;
- const Kinds: TTypeKinds): TTypeMemberProperty;
- begin
- Result:=GetPropInfo(TypeInfo(aClass), PropName, Kinds);
- if Result=nil then
- raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
- end;
- function IsStoredProp(Instance: TObject; const PropInfo: TTypeMemberProperty
- ): Boolean;
- type
- TIsStored = function: Boolean of object;
- begin
- case PropInfo.Flags and 12 of
- 0: Result:=true;
- 4: Result:=false;
- 8: Result:=Boolean(TJSObject(Instance)[PropInfo.Stored]);
- else Result:=TIsStored(TJSObject(Instance)[PropInfo.Stored])();
- end;
- end;
- function IsStoredProp(Instance: TObject; const PropName: string): Boolean;
- begin
- Result:=IsStoredProp(Instance,FindPropInfo(Instance,PropName));
- end;
- function IsPublishedProp(Instance: TObject; const PropName: String): Boolean;
- begin
- Result:=GetPropInfo(Instance,PropName)<>nil;
- end;
- function IsPublishedProp(aClass: TClass; const PropName: String): Boolean;
- begin
- Result:=GetPropInfo(aClass,PropName)<>nil;
- end;
- function PropType(Instance: TObject; const PropName: string): TTypeKind;
- begin
- Result:=FindPropInfo(Instance,PropName).TypeInfo.Kind;
- end;
- function PropType(aClass: TClass; const PropName: string): TTypeKind;
- begin
- Result:=FindPropInfo(aClass,PropName).TypeInfo.Kind;
- end;
- function PropIsType(Instance: TObject; const PropName: string;
- const TypeKind: TTypeKind): Boolean;
- begin
- Result:=PropType(Instance,PropName)=TypeKind;
- end;
- function PropIsType(aClass: TClass; const PropName: string;
- const TypeKind: TTypeKind): Boolean;
- begin
- Result:=PropType(aClass,PropName)=TypeKind;
- end;
- type
- TGetterKind = (
- gkNone,
- gkField,
- gkFunction,
- gkFunctionWithParams
- );
- function GetPropGetterKind(const PropInfo: TTypeMemberProperty): TGetterKind;
- begin
- if PropInfo.Getter='' then
- Result:=gkNone
- else if (pfGetFunction and PropInfo.Flags)>0 then
- begin
- if length(PropInfo.Params)>0 then
- // array property
- Result:=gkFunctionWithParams
- else
- Result:=gkFunction;
- end
- else
- Result:=gkField;
- end;
- type
- TSetterKind = (
- skNone,
- skField,
- skProcedure,
- skProcedureWithParams
- );
- function GetPropSetterKind(const PropInfo: TTypeMemberProperty): TSetterKind;
- begin
- if PropInfo.Setter='' then
- Result:=skNone
- else if (pfSetProcedure and PropInfo.Flags)>0 then
- begin
- if length(PropInfo.Params)>0 then
- // array property
- Result:=skProcedureWithParams
- else
- Result:=skProcedure;
- end
- else
- Result:=skField;
- end;
- function GetJSValueProp(Instance: TJSObject; TI: TTypeInfoStruct;
- const PropName: String): JSValue;
- var
- PropInfo: TTypeMemberProperty;
- begin
- PropInfo:=GetPropInfo(TI,PropName);
- if PropInfo=nil then
- raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
- Result:=GetJSValueProp(Instance,PropInfo);
- end;
- function GetJSValueProp(Instance: TJSObject;
- const PropInfo: TTypeMemberProperty): JSValue;
- type
- TGetter = function: JSValue of object;
- TGetterWithIndex = function(Index: JSValue): JSValue of object;
- var
- gk: TGetterKind;
- begin
- gk:=GetPropGetterKind(PropInfo);
- case gk of
- gkNone:
- raise EPropertyError.CreateFmt(SCantReadPropertyS, [PropInfo.Name]);
- gkField:
- Result:=Instance[PropInfo.Getter];
- gkFunction:
- if (pfHasIndex and PropInfo.Flags)>0 then
- Result:=TGetterWithIndex(Instance[PropInfo.Getter])(PropInfo.Index)
- else
- Result:=TGetter(Instance[PropInfo.Getter])();
- gkFunctionWithParams:
- raise EPropertyError.CreateFmt(SIndexedPropertyNeedsParams, [PropInfo.Name]);
- end;
- end;
- function GetJSValueProp(Instance: TObject; const PropName: String): JSValue;
- begin
- Result:=GetJSValueProp(Instance,FindPropInfo(Instance,PropName));
- end;
- function GetJSValueProp(Instance: TObject; const PropInfo: TTypeMemberProperty
- ): JSValue;
- begin
- Result:=GetJSValueProp(TJSObject(Instance),PropInfo);
- end;
- procedure SetJSValueProp(Instance: TJSObject; TI: TTypeInfoStruct;
- const PropName: String; Value: JSValue);
- var
- PropInfo: TTypeMemberProperty;
- begin
- PropInfo:=GetPropInfo(TI,PropName);
- if PropInfo=nil then
- raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
- SetJSValueProp(Instance,PropInfo,Value);
- end;
- procedure SetJSValueProp(Instance: TJSObject;
- const PropInfo: TTypeMemberProperty; Value: JSValue);
- type
- TSetter = procedure(Value: JSValue) of object;
- TSetterWithIndex = procedure(Index, Value: JSValue) of object;
- var
- sk: TSetterKind;
- begin
- sk:=GetPropSetterKind(PropInfo);
- case sk of
- skNone:
- raise EPropertyError.CreateFmt(SCantWritePropertyS, [PropInfo.Name]);
- skField:
- Instance[PropInfo.Setter]:=Value;
- skProcedure:
- if (pfHasIndex and PropInfo.Flags)>0 then
- TSetterWithIndex(Instance[PropInfo.Setter])(PropInfo.Index,Value)
- else
- TSetter(Instance[PropInfo.Setter])(Value);
- skProcedureWithParams:
- raise EPropertyError.CreateFmt(SIndexedPropertyNeedsParams, [PropInfo.Name]);
- end;
- end;
- procedure SetJSValueProp(Instance: TObject; const PropName: String;
- Value: JSValue);
- begin
- SetJSValueProp(Instance,FindPropInfo(Instance,PropName),Value);
- end;
- procedure SetJSValueProp(Instance: TObject;
- const PropInfo: TTypeMemberProperty; Value: JSValue);
- begin
- SetJSValueProp(TJSObject(Instance),PropInfo,Value);
- end;
- function GetNativeIntProp(Instance: TObject; const PropName: String): NativeInt;
- begin
- Result:=GetNativeIntProp(Instance,FindPropInfo(Instance,PropName));
- end;
- function GetNativeIntProp(Instance: TObject; const PropInfo: TTypeMemberProperty
- ): NativeInt;
- begin
- Result:=NativeInt(GetJSValueProp(Instance,PropInfo));
- end;
- procedure SetNativeIntProp(Instance: TObject; const PropName: String;
- Value: NativeInt);
- begin
- SetJSValueProp(Instance,FindPropInfo(Instance,PropName),Value);
- end;
- procedure SetNativeIntProp(Instance: TObject;
- const PropInfo: TTypeMemberProperty; Value: NativeInt);
- begin
- SetJSValueProp(Instance,PropInfo,Value);
- end;
- function GetOrdProp(Instance: TObject; const PropName: String): longint;
- begin
- Result:=GetOrdProp(Instance,FindPropInfo(Instance,PropName));
- end;
- function GetOrdProp(Instance: TObject; const PropInfo: TTypeMemberProperty
- ): longint;
- var
- o: TJSObject;
- Key: String;
- n: NativeInt;
- begin
- if PropInfo.TypeInfo.Kind=tkSet then
- begin
- // a set is a JS object, with the following property: o[ElementDecimal]=true
- o:=TJSObject(GetJSValueProp(Instance,PropInfo));
- Result:=0;
- for Key in o do
- begin
- n:=parseInt(Key,10);
- if n<32 then
- Result:=Result+(1 shl n);
- end;
- end else
- Result:=longint(GetJSValueProp(Instance,PropInfo));
- end;
- procedure SetOrdProp(Instance: TObject; const PropName: String; Value: longint);
- begin
- SetOrdProp(Instance,FindPropInfo(Instance,PropName),Value);
- end;
- procedure SetOrdProp(Instance: TObject; const PropInfo: TTypeMemberProperty;
- Value: longint);
- var
- o: TJSObject;
- i: Integer;
- begin
- if PropInfo.TypeInfo.Kind=tkSet then
- begin
- o:=TJSObject.new;
- for i:=0 to 31 do
- if (1 shl i) and Value>0 then
- o[str(i)]:=true;
- SetJSValueProp(Instance,PropInfo,o);
- end else
- SetJSValueProp(Instance,PropInfo,Value);
- end;
- function GetEnumProp(Instance: TObject; const PropName: String): String;
- begin
- Result:=GetEnumProp(Instance,FindPropInfo(Instance,PropName));
- end;
- function GetEnumProp(Instance: TObject; const PropInfo: TTypeMemberProperty): String;
- var
- n: NativeInt;
- TIEnum: TTypeInfoEnum;
- begin
- TIEnum:=PropInfo.TypeInfo as TTypeInfoEnum;
- n:=NativeInt(GetJSValueProp(Instance,PropInfo));
- if (n>=TIEnum.MinValue) and (n<=TIEnum.MaxValue) then
- Result:=TIEnum.EnumType.IntToName[n]
- else
- Result:=str(n);
- end;
- procedure SetEnumProp(Instance: TObject; const PropName: String;
- const Value: String);
- begin
- SetEnumProp(Instance,FindPropInfo(Instance,PropName),Value);
- end;
- procedure SetEnumProp(Instance: TObject; const PropInfo: TTypeMemberProperty;
- const Value: String);
- var
- TIEnum: TTypeInfoEnum;
- n: NativeInt;
- begin
- TIEnum:=PropInfo.TypeInfo as TTypeInfoEnum;
- n:=TIEnum.EnumType.NameToInt[Value];
- if not isUndefined(n) then
- SetJSValueProp(Instance,PropInfo,n);
- end;
- function GetEnumName(TypeInfo: TTypeInfoEnum; Value: Integer): String;
- begin
- Result:=TypeInfo.EnumType.IntToName[Value];
- end;
- function GetEnumValue(TypeInfo: TTypeInfoEnum; const Name: string): Longint;
- begin
- Result:=TypeInfo.EnumType.NameToInt[Name];
- end;
- function GetEnumNameCount(TypeInfo: TTypeInfoEnum): Longint;
- var
- o: TJSObject;
- l, r: LongInt;
- begin
- o:=TJSObject(TypeInfo.EnumType);
- // as of pas2js 1.0 the RTTI does not contain a min/max value
- // -> use exponential search
- // ToDo: adapt this once enums with gaps are supported
- Result:=1;
- while o.hasOwnProperty(String(JSValue(Result))) do
- Result:=Result*2;
- l:=Result div 2;
- r:=Result;
- while l<=r do
- begin
- Result:=(l+r) div 2;
- if o.hasOwnProperty(String(JSValue(Result))) then
- l:=Result+1
- else
- r:=Result-1;
- end;
- if o.hasOwnProperty(String(JSValue(Result))) then
- inc(Result);
- end;
- function GetSetProp(Instance: TObject; const PropName: String): String;
- begin
- Result:=GetSetProp(Instance,FindPropInfo(Instance,PropName));
- end;
- function GetSetProp(Instance: TObject; const PropInfo: TTypeMemberProperty
- ): String;
- var
- o: TJSObject;
- key, Value: String;
- n: NativeInt;
- TIEnum: TTypeInfoEnum;
- TISet: TTypeInfoSet;
- begin
- Result:='';
- // get enum type if available
- TISet:=PropInfo.TypeInfo as TTypeInfoSet;
- TIEnum:=nil;
- if TISet.CompType is TTypeInfoEnum then
- TIEnum:=TTypeInfoEnum(TISet.CompType);
- // read value
- o:=TJSObject(GetJSValueProp(Instance,PropInfo));
- // a set is a JS object, where included element is stored as: o[ElementDecimal]=true
- for Key in o do
- begin
- n:=parseInt(Key,10);
- if (TIEnum<>nil) and (n>=TIEnum.MinValue) and (n<=TIEnum.MaxValue) then
- Value:=TIEnum.EnumType.IntToName[n]
- else
- Value:=str(n);
- if Result<>'' then Result:=Result+',';
- Result:=Result+Value;
- end;
- Result:='['+Result+']';
- end;
- function GetSetPropArray(Instance: TObject; const PropName: String
- ): TIntegerDynArray;
- begin
- Result:=GetSetPropArray(Instance,FindPropInfo(Instance,PropName));
- end;
- function GetSetPropArray(Instance: TObject; const PropInfo: TTypeMemberProperty
- ): TIntegerDynArray;
- var
- o: TJSObject;
- Key: string;
- begin
- Result:=[];
- // read value
- o:=TJSObject(GetJSValueProp(Instance,PropInfo));
- // a set is a JS object, where included element is stored as: o[ElementDecimal]=true
- for Key in o do
- TJSArray(Result).push(parseInt(Key,10));
- end;
- procedure SetSetPropArray(Instance: TObject; const PropName: String;
- const Arr: TIntegerDynArray);
- begin
- SetSetPropArray(Instance,FindPropInfo(Instance,PropName),Arr);
- end;
- procedure SetSetPropArray(Instance: TObject;
- const PropInfo: TTypeMemberProperty; const Arr: TIntegerDynArray);
- var
- o: TJSObject;
- i: integer;
- begin
- o:=TJSObject.new;
- for i in Arr do
- o[str(i)]:=true;
- SetJSValueProp(Instance,PropInfo,o);
- end;
- function GetStrProp(Instance: TObject; const PropName: String): String;
- begin
- Result:=GetStrProp(Instance,FindPropInfo(Instance,PropName));
- end;
- function GetStrProp(Instance: TObject; const PropInfo: TTypeMemberProperty
- ): String;
- begin
- Result:=String(GetJSValueProp(Instance,PropInfo));
- end;
- procedure SetStrProp(Instance: TObject; const PropName: String; Value: String
- );
- begin
- SetStrProp(Instance,FindPropInfo(Instance,PropName),Value);
- end;
- procedure SetStrProp(Instance: TObject; const PropInfo: TTypeMemberProperty;
- Value: String);
- begin
- SetJSValueProp(Instance,PropInfo,Value);
- end;
- function GetStringProp(Instance: TObject; const PropName: String): String;
- begin
- Result:=GetStrProp(Instance,PropName);
- end;
- function GetStringProp(Instance: TObject; const PropInfo: TTypeMemberProperty
- ): String;
- begin
- Result:=GetStrProp(Instance,PropInfo);
- end;
- procedure SetStringProp(Instance: TObject; const PropName: String; Value: String
- );
- begin
- SetStrProp(Instance,PropName,Value);
- end;
- procedure SetStringProp(Instance: TObject; const PropInfo: TTypeMemberProperty;
- Value: String);
- begin
- SetStrProp(Instance,PropInfo,Value);
- end;
- function GetBoolProp(Instance: TObject; const PropName: String): boolean;
- begin
- Result:=GetBoolProp(Instance,FindPropInfo(Instance,PropName));
- end;
- function GetBoolProp(Instance: TObject; const PropInfo: TTypeMemberProperty
- ): boolean;
- begin
- Result:=Boolean(GetJSValueProp(Instance,PropInfo));
- end;
- procedure SetBoolProp(Instance: TObject; const PropName: String; Value: boolean
- );
- begin
- SetBoolProp(Instance,FindPropInfo(Instance,PropName),Value);
- end;
- procedure SetBoolProp(Instance: TObject; const PropInfo: TTypeMemberProperty;
- Value: boolean);
- begin
- SetJSValueProp(Instance,PropInfo,Value);
- end;
- function GetObjectProp(Instance: TObject; const PropName: String): TObject;
- begin
- Result:=GetObjectProp(Instance,FindPropInfo(Instance,PropName));
- end;
- function GetObjectProp(Instance: TObject; const PropName: String; MinClass : TClass): TObject;
- begin
- Result:=GetObjectProp(Instance,FindPropInfo(Instance,PropName));
- if (MinClass<>Nil) and (Result<>Nil) Then
- if not Result.InheritsFrom(MinClass) then
- Result:=Nil;
- end;
- function GetObjectProp(Instance: TObject; const PropInfo: TTypeMemberProperty): TObject;
- begin
- Result:=GetObjectProp(Instance,PropInfo,Nil);
- end;
- function GetObjectProp(Instance: TObject; const PropInfo: TTypeMemberProperty; MinClass : TClass): TObject;
- Var
- O : TObject;
- begin
- O:=TObject(GetJSValueProp(Instance,PropInfo));
- if (MinClass<>Nil) and not O.InheritsFrom(MinClass) then
- Result:=Nil
- else
- Result:=O;
- end;
- procedure SetObjectProp(Instance: TObject; const PropName: String; Value: TObject) ;
- begin
- SetObjectProp(Instance,FindPropInfo(Instance,PropName),Value);
- end;
- procedure SetObjectProp(Instance: TObject; const PropInfo: TTypeMemberProperty; Value: TObject);
- begin
- SetJSValueProp(Instance,PropInfo,Value);
- end;
- function GetMethodProp(Instance: TObject; PropInfo: TTypeMemberProperty
- ): TMethod;
- var
- v, fn: JSValue;
- begin
- Result.Code:=nil;
- Result.Data:=nil;
- v:=GetJSValueProp(Instance,PropInfo);
- if not isFunction(v) then exit;
- Result.Data:=Pointer(TJSObject(v)['scope']);
- fn:=TJSObject(v)['fn'];
- if isString(fn) then
- begin
- if Result.Data<>nil then
- // named callback
- Result.Code:=CodePointer(TJSObject(Result.Data)[String(fn)])
- else
- // this is not an rtl callback, return the value
- Result.Code:=CodePointer(v);
- end
- else
- // anonymous callback
- Result.Code:=CodePointer(fn);
- end;
- function GetMethodProp(Instance: TObject; const PropName: string): TMethod;
- begin
- Result:=GetMethodProp(Instance,FindPropInfo(Instance,PropName));
- end;
- function createCallbackPtr(scope: Pointer; fn: CodePointer): TJSFunction; external name 'rtl.createCallback';
- function createCallbackStr(scope: Pointer; fn: string): TJSFunction; external name 'rtl.createCallback';
- procedure SetMethodProp(Instance: TObject; PropInfo: TTypeMemberProperty;
- const Value: TMethod);
- var
- cb: TJSFunction;
- Code: Pointer;
- begin
- // Note: Value.Data=nil is allowed and can be used by designer code
- Code:=Value.Code;
- if Code=nil then
- cb:=nil
- else if isFunction(Code) then
- begin
- if (TJSObject(Code)['scope']=Value.Data)
- and (isFunction(TJSObject(Code)['fn']) or isString(TJSObject(Code)['fn']))
- then
- begin
- // Value.Code is already the needed callback
- cb:=TJSFunction(Code);
- end
- else if isString(TJSObject(Code)['fn']) then
- // named callback, different scope
- cb:=createCallbackStr(Value.Data,string(TJSObject(Code)['fn']))
- else
- // normal function
- cb:=createCallbackPtr(Value.Data,Code);
- end
- else
- // not a valid value -> for compatibility set it anyway
- cb:=createCallbackPtr(Value.Data,Code);
- SetJSValueProp(Instance,PropInfo,cb);
- end;
- procedure SetMethodProp(Instance: TObject; const PropName: string;
- const Value: TMethod);
- begin
- SetMethodProp(Instance,FindPropInfo(Instance,PropName),Value);
- end;
- function GetInterfaceProp(Instance: TObject; const PropName: string
- ): IInterface;
- begin
- Result:=GetInterfaceProp(Instance,FindPropInfo(Instance,PropName));
- end;
- function GetInterfaceProp(Instance: TObject; PropInfo: TTypeMemberProperty
- ): IInterface;
- type
- TGetter = function: IInterface of object;
- TGetterWithIndex = function(Index: JSValue): IInterface of object;
- var
- gk: TGetterKind;
- begin
- if Propinfo.TypeInfo.Kind<>tkInterface then
- raise Exception.Create('Cannot get RAW interface from IInterface interface');
- gk:=GetPropGetterKind(PropInfo);
- case gk of
- gkNone:
- raise EPropertyError.CreateFmt(SCantReadPropertyS, [PropInfo.Name]);
- gkField:
- Result:=IInterface(TJSObject(Instance)[PropInfo.Getter]);
- gkFunction:
- if (pfHasIndex and PropInfo.Flags)>0 then
- Result:=TGetterWithIndex(TJSObject(Instance)[PropInfo.Getter])(PropInfo.Index)
- else
- Result:=TGetter(TJSObject(Instance)[PropInfo.Getter])();
- gkFunctionWithParams:
- raise EPropertyError.CreateFmt(SIndexedPropertyNeedsParams, [PropInfo.Name]);
- end;
- end;
- procedure SetInterfaceProp(Instance: TObject; const PropName: string;
- const Value: IInterface);
- begin
- SetInterfaceProp(Instance,FindPropInfo(Instance,PropName),Value);
- end;
- procedure SetInterfaceProp(Instance: TObject; PropInfo: TTypeMemberProperty;
- const Value: IInterface);
- type
- TSetter = procedure(Value: IInterface) of object;
- TSetterWithIndex = procedure(Index: JSValue; Value: IInterface) of object;
- procedure setIntfP(Instance: TObject; const PropName: string; value: jsvalue); external name 'rtl.setIntfP';
- var
- sk: TSetterKind;
- Setter: String;
- begin
- if Propinfo.TypeInfo.Kind<>tkInterface then
- raise Exception.Create('Cannot set RAW interface from IInterface interface');
- sk:=GetPropSetterKind(PropInfo);
- Setter:=PropInfo.Setter;
- case sk of
- skNone:
- raise EPropertyError.CreateFmt(SCantWritePropertyS, [PropInfo.Name]);
- skField:
- setIntfP(Instance,Setter,Value);
- skProcedure:
- if (pfHasIndex and PropInfo.Flags)>0 then
- TSetterWithIndex(TJSObject(Instance)[Setter])(PropInfo.Index,Value)
- else
- TSetter(TJSObject(Instance)[Setter])(Value);
- skProcedureWithParams:
- raise EPropertyError.CreateFmt(SIndexedPropertyNeedsParams, [PropInfo.Name]);
- end;
- end;
- function GetRawInterfaceProp(Instance: TObject; const PropName: string
- ): Pointer;
- begin
- Result:=GetRawInterfaceProp(Instance,FindPropInfo(Instance,PropName));
- end;
- function GetRawInterfaceProp(Instance: TObject; PropInfo: TTypeMemberProperty
- ): Pointer;
- begin
- Result:=Pointer(GetJSValueProp(Instance,PropInfo));
- end;
- procedure SetRawInterfaceProp(Instance: TObject; const PropName: string;
- const Value: Pointer);
- begin
- SetRawInterfaceProp(Instance,FindPropInfo(Instance,PropName),Value);
- end;
- procedure SetRawInterfaceProp(Instance: TObject; PropInfo: TTypeMemberProperty;
- const Value: Pointer);
- begin
- SetJSValueProp(Instance,PropInfo,Value);
- end;
- function GetFloatProp(Instance: TObject; PropInfo: TTypeMemberProperty): Double;
- begin
- Result:=Double(GetJSValueProp(Instance,PropInfo));
- end;
- function GetFloatProp(Instance: TObject; const PropName: string): Double;
- begin
- Result:=GetFloatProp(Instance,FindPropInfo(Instance,PropName));
- end;
- procedure SetFloatProp(Instance: TObject; const PropName: string; Value: Double
- );
- begin
- SetFloatProp(Instance,FindPropInfo(Instance,PropName),Value);
- end;
- procedure SetFloatProp(Instance: TObject; PropInfo: TTypeMemberProperty;
- Value: Double);
- begin
- SetJSValueProp(Instance,PropInfo,Value);
- end;
- end.
|