|
@@ -76,15 +76,27 @@ type
|
|
private
|
|
private
|
|
FData: TValueData;
|
|
FData: TValueData;
|
|
function GetTypeDataProp: PTypeData;
|
|
function GetTypeDataProp: PTypeData;
|
|
|
|
+ function GetTypeInfo: PTypeInfo;
|
|
|
|
+ function GetTypeKind: TTypeKind;
|
|
public
|
|
public
|
|
|
|
+ function IsArray: boolean;
|
|
function AsString: string;
|
|
function AsString: string;
|
|
function AsExtended: Extended;
|
|
function AsExtended: Extended;
|
|
- function AsObject: TObject;
|
|
|
|
|
|
+ function IsClass: boolean;
|
|
|
|
+ function AsClass: TClass;
|
|
function IsObject: boolean;
|
|
function IsObject: boolean;
|
|
|
|
+ function AsObject: TObject;
|
|
|
|
+ function IsOrdinal: boolean;
|
|
|
|
+ function AsOrdinal: Int64;
|
|
function AsBoolean: boolean;
|
|
function AsBoolean: boolean;
|
|
function AsCurrency: Currency;
|
|
function AsCurrency: Currency;
|
|
function AsInteger: Integer;
|
|
function AsInteger: Integer;
|
|
|
|
+ function ToString: string;
|
|
|
|
+ function IsType(ATypeInfo: PTypeInfo): boolean;
|
|
|
|
+ function TryAsOrdinal(out AResult: int64): boolean;
|
|
|
|
+ property Kind: TTypeKind read GetTypeKind;
|
|
property TypeData: PTypeData read GetTypeDataProp;
|
|
property TypeData: PTypeData read GetTypeDataProp;
|
|
|
|
+ property TypeInfo: PTypeInfo read GetTypeInfo;
|
|
end;
|
|
end;
|
|
|
|
|
|
{ TRttiContext }
|
|
{ TRttiContext }
|
|
@@ -130,7 +142,13 @@ type
|
|
FTypeData: PTypeData;
|
|
FTypeData: PTypeData;
|
|
function GetName: string; override;
|
|
function GetName: string; override;
|
|
function GetIsInstance: boolean; virtual;
|
|
function GetIsInstance: boolean; virtual;
|
|
|
|
+ function GetIsManaged: boolean; virtual;
|
|
|
|
+ function GetIsOrdinal: boolean; virtual;
|
|
|
|
+ function GetIsRecord: boolean; virtual;
|
|
|
|
+ function GetIsSet: boolean; virtual;
|
|
function GetTypeKind: TTypeKind; virtual;
|
|
function GetTypeKind: TTypeKind; virtual;
|
|
|
|
+ function GetTypeSize: integer; virtual;
|
|
|
|
+ function GetBaseType: TRttiType; virtual;
|
|
public
|
|
public
|
|
constructor create(ATypeInfo : PTypeInfo);
|
|
constructor create(ATypeInfo : PTypeInfo);
|
|
function GetAttributes: specialize TArray<TCustomAttribute>; override;
|
|
function GetAttributes: specialize TArray<TCustomAttribute>; override;
|
|
@@ -138,8 +156,14 @@ type
|
|
function GetProperty(const AName: string): TRttiProperty; virtual;
|
|
function GetProperty(const AName: string): TRttiProperty; virtual;
|
|
destructor destroy; override;
|
|
destructor destroy; override;
|
|
property IsInstance: boolean read GetIsInstance;
|
|
property IsInstance: boolean read GetIsInstance;
|
|
|
|
+ property isManaged: boolean read GetIsManaged;
|
|
|
|
+ property IsOrdinal: boolean read GetIsOrdinal;
|
|
|
|
+ property IsRecord: boolean read GetIsRecord;
|
|
|
|
+ property IsSet: boolean read GetIsSet;
|
|
|
|
+ property BaseType: TRttiType read GetBaseType;
|
|
property AsInstance: TRttiInstanceType read GetAsInstance;
|
|
property AsInstance: TRttiInstanceType read GetAsInstance;
|
|
property TypeKind: TTypeKind read GetTypeKind;
|
|
property TypeKind: TTypeKind read GetTypeKind;
|
|
|
|
+ property TypeSize: integer read GetTypeSize;
|
|
end;
|
|
end;
|
|
|
|
|
|
TRttiStructuredType = class(TRttiType)
|
|
TRttiStructuredType = class(TRttiType)
|
|
@@ -172,11 +196,15 @@ type
|
|
|
|
|
|
TRttiInstanceType = class(TRttiStructuredType)
|
|
TRttiInstanceType = class(TRttiStructuredType)
|
|
private
|
|
private
|
|
|
|
+ function GetDeclaringUnitName: string;
|
|
function GetMetaClassType: TClass;
|
|
function GetMetaClassType: TClass;
|
|
protected
|
|
protected
|
|
function GetIsInstance: boolean; override;
|
|
function GetIsInstance: boolean; override;
|
|
|
|
+ function GetTypeSize: integer; override;
|
|
|
|
+ function GetBaseType: TRttiType; override;
|
|
public
|
|
public
|
|
property MetaClassType: TClass read GetMetaClassType;
|
|
property MetaClassType: TClass read GetMetaClassType;
|
|
|
|
+ property DeclaringUnitName: string read GetDeclaringUnitName;
|
|
|
|
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -214,6 +242,8 @@ type
|
|
|
|
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+function IsManaged(TypeInfo: PTypeInfo): boolean;
|
|
|
|
+
|
|
implementation
|
|
implementation
|
|
|
|
|
|
type
|
|
type
|
|
@@ -267,6 +297,11 @@ var
|
|
PoolRefCount : integer;
|
|
PoolRefCount : integer;
|
|
GRttiPool : TRttiPool;
|
|
GRttiPool : TRttiPool;
|
|
|
|
|
|
|
|
+function IsManaged(TypeInfo: PTypeInfo): boolean;
|
|
|
|
+begin
|
|
|
|
+ result := TypeInfo^.Kind in [tkString, tkAString, tkLString, tkInterface, tkArray, tkDynArray];
|
|
|
|
+end;
|
|
|
|
+
|
|
{ TRttiPool }
|
|
{ TRttiPool }
|
|
|
|
|
|
function TRttiPool.GetTypes: specialize TArray<TRttiType>;
|
|
function TRttiPool.GetTypes: specialize TArray<TRttiType>;
|
|
@@ -423,28 +458,50 @@ begin
|
|
result := GetTypeData(FData.FTypeInfo);
|
|
result := GetTypeData(FData.FTypeInfo);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+function TValue.GetTypeInfo: PTypeInfo;
|
|
|
|
+begin
|
|
|
|
+ result := FData.FTypeInfo;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TValue.GetTypeKind: TTypeKind;
|
|
|
|
+begin
|
|
|
|
+ result := FData.FTypeInfo^.Kind;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TValue.IsArray: boolean;
|
|
|
|
+begin
|
|
|
|
+ result := kind in [tkArray, tkDynArray];
|
|
|
|
+end;
|
|
|
|
+
|
|
function TValue.AsString: string;
|
|
function TValue.AsString: string;
|
|
var
|
|
var
|
|
s: string;
|
|
s: string;
|
|
begin
|
|
begin
|
|
- case fdata.FTypeInfo^.Kind of
|
|
|
|
|
|
+ case Kind of
|
|
tkSString,
|
|
tkSString,
|
|
tkAString : begin
|
|
tkAString : begin
|
|
setlength(s,FData.FValueData.GetDataSize);
|
|
setlength(s,FData.FValueData.GetDataSize);
|
|
system.move(FData.FValueData.GetReferenceToRawData^,s[1],FData.FValueData.GetDataSize);
|
|
system.move(FData.FValueData.GetReferenceToRawData^,s[1],FData.FValueData.GetDataSize);
|
|
end;
|
|
end;
|
|
else
|
|
else
|
|
- raise exception.Create(SErrInvalidTypecast);
|
|
|
|
|
|
+ raise EInvalidCast.Create(SErrInvalidTypecast);
|
|
end;
|
|
end;
|
|
result := s;
|
|
result := s;
|
|
end;
|
|
end;
|
|
|
|
|
|
function TValue.AsExtended: Extended;
|
|
function TValue.AsExtended: Extended;
|
|
begin
|
|
begin
|
|
- case TypeData^.FloatType of
|
|
|
|
- ftDouble : result := FData.FAsDouble;
|
|
|
|
- ftExtended : result := FData.FAsExtenden;
|
|
|
|
- end;
|
|
|
|
|
|
+ if Kind = tkFloat then
|
|
|
|
+ begin
|
|
|
|
+ case TypeData^.FloatType of
|
|
|
|
+ ftDouble : result := FData.FAsDouble;
|
|
|
|
+ ftExtended : result := FData.FAsExtenden;
|
|
|
|
+ else
|
|
|
|
+ raise EInvalidCast.Create(SErrInvalidTypecast);
|
|
|
|
+ end;
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ raise EInvalidCast.Create(SErrInvalidTypecast);
|
|
end;
|
|
end;
|
|
|
|
|
|
function TValue.AsObject: TObject;
|
|
function TValue.AsObject: TObject;
|
|
@@ -452,29 +509,89 @@ begin
|
|
if IsObject then
|
|
if IsObject then
|
|
result := FData.FAsObject
|
|
result := FData.FAsObject
|
|
else
|
|
else
|
|
- raise exception.Create(SErrInvalidTypecast);
|
|
|
|
|
|
+ raise EInvalidCast.Create(SErrInvalidTypecast);
|
|
end;
|
|
end;
|
|
|
|
|
|
function TValue.IsObject: boolean;
|
|
function TValue.IsObject: boolean;
|
|
|
|
+begin
|
|
|
|
+ result := fdata.FTypeInfo^.Kind = tkObject;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TValue.IsClass: boolean;
|
|
begin
|
|
begin
|
|
result := fdata.FTypeInfo^.Kind = tkClass;
|
|
result := fdata.FTypeInfo^.Kind = tkClass;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+function TValue.AsClass: TClass;
|
|
|
|
+begin
|
|
|
|
+ if IsClass then
|
|
|
|
+ result := FData.FAsClass
|
|
|
|
+ else
|
|
|
|
+ raise EInvalidCast.Create(SErrInvalidTypecast);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TValue.IsOrdinal: boolean;
|
|
|
|
+begin
|
|
|
|
+ result := Kind in [tkInteger, tkInt64, tkBool];
|
|
|
|
+end;
|
|
|
|
+
|
|
function TValue.AsBoolean: boolean;
|
|
function TValue.AsBoolean: boolean;
|
|
begin
|
|
begin
|
|
- result := boolean(FData.FAsSInt64)
|
|
|
|
|
|
+ if (Kind = tkBool) then
|
|
|
|
+ result := boolean(FData.FAsSInt64)
|
|
|
|
+ else
|
|
|
|
+ raise EInvalidCast.Create(SErrInvalidTypecast);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TValue.AsOrdinal: int64;
|
|
|
|
+begin
|
|
|
|
+ if IsOrdinal then
|
|
|
|
+ result := FData.FAsSInt64
|
|
|
|
+ else
|
|
|
|
+ raise EInvalidCast.Create(SErrInvalidTypecast);
|
|
end;
|
|
end;
|
|
|
|
|
|
function TValue.AsCurrency: Currency;
|
|
function TValue.AsCurrency: Currency;
|
|
begin
|
|
begin
|
|
- result := FData.FAsCurr;
|
|
|
|
|
|
+ if (Kind = tkFloat) and (TypeData^.FloatType=ftCurr) then
|
|
|
|
+ result := FData.FAsCurr
|
|
|
|
+ else
|
|
|
|
+ raise EInvalidCast.Create(SErrInvalidTypecast);
|
|
end;
|
|
end;
|
|
|
|
|
|
function TValue.AsInteger: Integer;
|
|
function TValue.AsInteger: Integer;
|
|
begin
|
|
begin
|
|
- result := Integer(FData.FAsSInt64)
|
|
|
|
|
|
+ if Kind in [tkInteger, tkInt64] then
|
|
|
|
+ result := integer(FData.FAsSInt64)
|
|
|
|
+ else
|
|
|
|
+ raise EInvalidCast.Create(SErrInvalidTypecast);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TValue.ToString: String;
|
|
|
|
+begin
|
|
|
|
+ case Kind of
|
|
|
|
+ tkString,
|
|
|
|
+ tkAString : result := AsString;
|
|
|
|
+ tkInteger : result := IntToStr(AsInteger);
|
|
|
|
+ tkBool : result := BoolToStr(AsBoolean, True);
|
|
|
|
+ else
|
|
|
|
+ result := '';
|
|
|
|
+ end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+function TValue.IsType(ATypeInfo: PTypeInfo): boolean;
|
|
|
|
+begin
|
|
|
|
+ result := ATypeInfo = TypeInfo;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TValue.TryAsOrdinal(out AResult: int64): boolean;
|
|
|
|
+begin
|
|
|
|
+ result := IsOrdinal;
|
|
|
|
+ if result then
|
|
|
|
+ AResult := AsOrdinal;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+
|
|
{ TRttiStringType }
|
|
{ TRttiStringType }
|
|
|
|
|
|
function TRttiStringType.GetStringKind: TRttiStringKind;
|
|
function TRttiStringType.GetStringKind: TRttiStringKind;
|
|
@@ -495,11 +612,33 @@ begin
|
|
result := FTypeData^.ClassType;
|
|
result := FTypeData^.ClassType;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+function TRttiInstanceType.GetDeclaringUnitName: string;
|
|
|
|
+begin
|
|
|
|
+ result := FTypeData^.UnitInfo^.UnitName;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TRttiInstanceType.GetBaseType: TRttiType;
|
|
|
|
+var
|
|
|
|
+ AContext: TRttiContext;
|
|
|
|
+begin
|
|
|
|
+ AContext := TRttiContext.Create;
|
|
|
|
+ try
|
|
|
|
+ result := AContext.GetType(FTypeData^.ParentInfo);
|
|
|
|
+ finally
|
|
|
|
+ AContext.Free;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
function TRttiInstanceType.GetIsInstance: boolean;
|
|
function TRttiInstanceType.GetIsInstance: boolean;
|
|
begin
|
|
begin
|
|
Result:=True;
|
|
Result:=True;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+function TRttiInstanceType.GetTypeSize: integer;
|
|
|
|
+begin
|
|
|
|
+ Result:=sizeof(TObject);
|
|
|
|
+end;
|
|
|
|
+
|
|
{ TRttiMember }
|
|
{ TRttiMember }
|
|
|
|
|
|
function TRttiMember.GetVisibility: TMemberVisibility;
|
|
function TRttiMember.GetVisibility: TMemberVisibility;
|
|
@@ -578,17 +717,47 @@ begin
|
|
result := false;
|
|
result := false;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+function TRttiType.GetIsManaged: boolean;
|
|
|
|
+begin
|
|
|
|
+ result := Rtti.IsManaged(FTypeInfo);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TRttiType.GetIsOrdinal: boolean;
|
|
|
|
+begin
|
|
|
|
+ result := false;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TRttiType.GetIsRecord: boolean;
|
|
|
|
+begin
|
|
|
|
+ result := false;
|
|
|
|
+end;
|
|
|
|
+function TRttiType.GetIsSet: boolean;
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ result := false;
|
|
|
|
+end;
|
|
|
|
+
|
|
function TRttiType.GetAsInstance: TRttiInstanceType;
|
|
function TRttiType.GetAsInstance: TRttiInstanceType;
|
|
begin
|
|
begin
|
|
// This is a ridicoulous design, but Delphi-compatible...
|
|
// This is a ridicoulous design, but Delphi-compatible...
|
|
result := TRttiInstanceType(self);
|
|
result := TRttiInstanceType(self);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+function TRttiType.GetBaseType: TRttiType;
|
|
|
|
+begin
|
|
|
|
+ result := nil;
|
|
|
|
+end;
|
|
|
|
+
|
|
function TRttiType.GetTypeKind: TTypeKind;
|
|
function TRttiType.GetTypeKind: TTypeKind;
|
|
begin
|
|
begin
|
|
result := FTypeInfo^.Kind;
|
|
result := FTypeInfo^.Kind;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+function TRttiType.GetTypeSize: integer;
|
|
|
|
+begin
|
|
|
|
+ result := -1;
|
|
|
|
+end;
|
|
|
|
+
|
|
function TRttiType.GetName: string;
|
|
function TRttiType.GetName: string;
|
|
begin
|
|
begin
|
|
Result:=FTypeInfo^.Name;
|
|
Result:=FTypeInfo^.Name;
|