123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545 |
- {
- 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
- // if you change the following enumeration type in any way
- // you also have to change the rtl.js in an appropriate way !
- TTypeKind = (
- tkUnknown, // 0
- tkInteger, // 1
- tkChar, // 2 in Delphi/FPC tkWChar, tkUChar
- tkString, // 3 in Delphi/FPC tkSString, tkWString or tkUString
- tkEnumeration, // 4
- tkSet, // 5
- tkDouble, // 6
- tkBool, // 7
- tkProcVar, // 8 function or procedure
- tkMethod, // 9 proc var of object
- tkArray, // 10 static array
- tkDynArray, // 11
- tkRecord, // 12
- tkClass, // 13
- tkClassRef, // 14
- tkPointer, // 15
- tkJSValue, // 16
- tkRefToProcVar, // 17 variable of procedure type
- tkInterface, // 18
- //tkObject,
- //tkSString,tkLString,tkAString,tkWString,
- //tkVariant,
- //tkWChar,
- //tkInt64,
- //tkQWord,
- //tkInterfaceRaw,
- //tkUString,tkUChar,
- tkHelper // 19
- //tkFile,
- );
- TTypeKinds = set of TTypeKind;
- // TCallConv for compatibility with Delphi/FPC, ignored under pas2js
- TCallConv = (ccReg, ccCdecl, ccPascal, ccStdCall, ccSafeCall, ccCppdecl,
- ccFar16, ccOldFPCCall, ccInternProc, ccSysCall, ccSoftFloat, ccMWPascal);
- const
- tkFloat = tkDouble; // for compatibility with Delphi/FPC
- tkProcedure = tkProcVar; // for compatibility with Delphi
- tkAny = [Low(TTypeKind)..High(TTypeKind)];
- tkMethods = [tkMethod];
- tkProperties = tkAny-tkMethods-[tkUnknown];
- type
- { TTypeInfoModule }
- TTypeInfoModule = class external name 'pasmodule'
- public
- Name: String external name '$name';
- 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;
- ElType: TTypeInfo external name 'eltype';
- end;
- { TTypeInfoDynArray - Kind = tkDynArray }
- TTypeInfoDynArray = class external name 'rtl.tTypeInfoDynArray'(TTypeInfo)
- public
- DimCount: NativeInt external name 'dimcount';
- ElType: TTypeInfo external name 'eltype';
- end;
- TParamFlag = (
- pfVar, // 2^0 = 1
- pfConst, // 2^1 = 2
- pfOut, // 2^2 = 4
- pfArray // 2^3 = 8
- //pfAddress,pfReference,
- );
- 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
- );
- 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';
- end;
- { TTypeInfoClass - Kind = tkClass }
- TTypeInfoClass = class external name 'rtl.tTypeInfoClass'(TTypeInfoStruct)
- public
- ClassType: TClass external name 'class';
- Ancestor: TTypeInfoClass external name 'ancestor';
- 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 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 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: JSValue;
- begin
- Result.Code:=nil;
- Result.Data:=nil;
- v:=GetJSValueProp(Instance,PropInfo);
- if not isFunction(v) then exit;
- Result.Data:=Pointer(TJSObject(v)['scope']);
- Result.Code:=CodePointer(TJSObject(v)['fn']);
- end;
- function GetMethodProp(Instance: TObject; const PropName: string): TMethod;
- begin
- Result:=GetMethodProp(Instance,FindPropInfo(Instance,PropName));
- end;
- function createCallback(scope: Pointer; fn: CodePointer): TJSFunction; external name 'rtl.createCallback';
- procedure SetMethodProp(Instance: TObject; PropInfo: TTypeMemberProperty;
- const Value: TMethod);
- var
- cb: TJSFunction;
- begin
- cb:=createCallback(Value.Data,Value.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.
|