* Patch from Henrigque Werlang, implementing TRTTIInterface and adding RTTIStructuredType methods

This commit is contained in:
michael 2020-08-27 14:10:30 +00:00
parent 9ed5a58808
commit bff1abd2ed

View File

@ -200,6 +200,7 @@ type
destructor Destroy; override; destructor Destroy; override;
function GetAttributes: TCustomAttributeArray; override; function GetAttributes: TCustomAttributeArray; override;
function GetField(const AName: string): TRttiField; virtual; function GetField(const AName: string): TRttiField; virtual;
function GetMethods: TRttiMethodArray; virtual;
function GetMethods(const aName: String): TRttiMethodArray; virtual; function GetMethods(const aName: String): TRttiMethodArray; virtual;
function GetMethod(const aName: String): TRttiMethod; virtual; function GetMethod(const aName: String): TRttiMethod; virtual;
function GetProperty(const AName: string): TRttiProperty; virtual; function GetProperty(const AName: string): TRttiProperty; virtual;
@ -225,6 +226,17 @@ type
{ TRttiStructuredType } { TRttiStructuredType }
TRttiStructuredType = class abstract(TRttiType) TRttiStructuredType = class abstract(TRttiType)
protected
function GetDeclaredProperties: TRttiPropertyArray; override;
function GetMethod(const aName: String): TRttiMethod; override;
function GetMethods: TRttiMethodArray; override;
function GetMethods(const aName: String): TRttiMethodArray; override;
function GetProperty(const AName: string): TRttiProperty; override;
function GetStructTypeInfo: TTypeInfoStruct;
public
constructor Create(ATypeInfo: PTypeInfo);
property StructTypeInfo: TTypeInfoStruct read GetStructTypeInfo;
end; end;
{ TRttiInstanceType } { TRttiInstanceType }
@ -237,8 +249,17 @@ type
constructor Create(ATypeInfo: PTypeInfo); constructor Create(ATypeInfo: PTypeInfo);
property ClassTypeInfo: TTypeInfoClass read GetClassTypeInfo; property ClassTypeInfo: TTypeInfoClass read GetClassTypeInfo;
property MetaClassType: TClass read GetMetaClassType; property MetaClassType: TClass read GetMetaClassType;
function GetProperty(const AName: string): TRttiProperty; override; end;
function GetDeclaredProperties: TRttiPropertyArray; override;
TRttiInterfaceType = class(TRttiStructuredType)
private
function GetGUID: TGUID;
function GetInterfaceTypeInfo: TTypeInfoInterface;
public
constructor Create(ATypeInfo: PTypeInfo);
property GUID: TGUID read GetGUID;
property InterfaceTypeInfo: TTypeInfoInterface read GetInterfaceTypeInfo;
end; end;
EInvoke = EJS; EInvoke = EJS;
@ -255,6 +276,7 @@ type
constructor Create(InterfaceTypeInfo: Pointer); overload; assembler; constructor Create(InterfaceTypeInfo: Pointer); overload; assembler;
constructor Create(InterfaceTypeInfo: Pointer; constructor Create(InterfaceTypeInfo: Pointer;
const InvokeEvent: TVirtualInterfaceInvokeEvent); overload; const InvokeEvent: TVirtualInterfaceInvokeEvent); overload;
function QueryInterface(const iid: TGuid; out obj): Integer; override;
property OnInvoke: TVirtualInterfaceInvokeEvent read FOnInvoke write FOnInvoke; property OnInvoke: TVirtualInterfaceInvokeEvent read FOnInvoke write FOnInvoke;
end; end;
@ -517,6 +539,91 @@ begin
Result := FData; Result := FData;
end; end;
{ TRttiStructuredType }
function TRttiStructuredType.GetMethods: TRttiMethodArray;
var
A: Integer;
begin
SetLength(Result, StructTypeInfo.MethodCount);
for A := 0 to Pred(StructTypeInfo.MethodCount) do
Result[A] := TRttiMethod.Create(Self, StructTypeInfo.GetMethod(A));
end;
function TRttiStructuredType.GetMethods(const aName: String): TRttiMethodArray;
var
A: Integer;
Method: TTypeMemberMethod;
begin
SetLength(Result, StructTypeInfo.MethodCount);
for A := 0 to Pred(StructTypeInfo.MethodCount) do
begin
Method := StructTypeInfo.GetMethod(A);
if aName = Method.Name then
Result[A] := TRttiMethod.Create(Self, Method);
end;
end;
function TRttiStructuredType.GetMethod(const aName: String): TRttiMethod;
var
A: Integer;
Method: TTypeMemberMethod;
begin
Result := nil;
for A := 0 to Pred(StructTypeInfo.MethodCount) do
begin
Method := StructTypeInfo.GetMethod(A);
if aName = Method.Name then
Exit(TRttiMethod.Create(Self, Method));
end;
end;
function TRttiStructuredType.GetProperty(const AName: string): TRttiProperty;
var
A: Integer;
begin
Result := nil;
for A := 0 to Pred(StructTypeInfo.PropCount) do
if StructTypeInfo.GetProp(A).Name = AName then
Exit(TRttiProperty.Create(Self, StructTypeInfo.GetProp(A)));
end;
function TRttiStructuredType.GetDeclaredProperties: TRttiPropertyArray;
var
A: Integer;
begin
SetLength(Result, StructTypeInfo.PropCount);
for A := 0 to Pred(StructTypeInfo.PropCount) do
Result[A] := TRttiProperty.Create(Self, StructTypeInfo.GetProp(A));
end;
function TRttiStructuredType.GetStructTypeInfo: TTypeInfoStruct;
begin
Result:=TTypeInfoStruct(FTypeInfo);
end;
constructor TRttiStructuredType.Create(ATypeInfo: PTypeInfo);
begin
if not (TTypeInfo(ATypeInfo) is TTypeInfoStruct) then
raise EInvalidCast.Create('');
inherited Create(ATypeInfo);
end;
{ TRttiInstanceType } { TRttiInstanceType }
function TRttiInstanceType.GetClassTypeInfo: TTypeInfoClass; function TRttiInstanceType.GetClassTypeInfo: TTypeInfoClass;
@ -526,7 +633,7 @@ end;
function TRttiInstanceType.GetMetaClassType: TClass; function TRttiInstanceType.GetMetaClassType: TClass;
begin begin
Result:=TTypeInfoClass(FTypeInfo).ClassType; Result:=ClassTypeInfo.ClassType;
end; end;
constructor TRttiInstanceType.Create(ATypeInfo: PTypeInfo); constructor TRttiInstanceType.Create(ATypeInfo: PTypeInfo);
@ -536,34 +643,28 @@ begin
inherited Create(ATypeInfo); inherited Create(ATypeInfo);
end; end;
function TRttiInstanceType.GetProperty(const AName: string): TRttiProperty; { TRttiInterfaceType }
var
A: Integer;
Info: TTypeInfoClass;
constructor TRttiInterfaceType.Create(ATypeInfo: PTypeInfo);
begin begin
Info := TTypeInfoClass(FTypeInfo); if not (TTypeInfo(ATypeInfo) is TTypeInfoInterface) then
Result := nil; raise EInvalidCast.Create('');
inherited Create(ATypeInfo);
for A := 0 to Pred(Info.PropCount) do
if Info.GetProp(A).Name = AName then
Exit(TRttiProperty.Create(Self, Info.GetProp(A)));
end; end;
function TRttiInstanceType.GetDeclaredProperties: TRttiPropertyArray; function TRttiInterfaceType.GetGUID: TGUID;
var var
A: Integer; Guid: String;
Info: TTypeInfoClass;
begin begin
Info := TTypeInfoClass(FTypeInfo); Guid := String(InterfaceTypeInfo.InterfaceType['$guid']);
SetLength(Result, Info.PropCount); TryStringToGUID(Guid, Result);
end;
for A := 0 to Pred(Info.PropCount) do function TRttiInterfaceType.GetInterfaceTypeInfo: TTypeInfoInterface;
Result[A] := TRttiProperty.Create(Self, Info.GetProp(A)); begin
Result := TTypeInfoInterface(FTypeInfo);
end; end;
{ TRTTIContext } { TRTTIContext }
@ -606,6 +707,7 @@ begin
begin begin
case T.Kind of case T.Kind of
tkClass: Result:=TRttiInstanceType.Create(aTypeInfo); tkClass: Result:=TRttiInstanceType.Create(aTypeInfo);
tkInterface: Result:=TRttiInterfaceType.Create(aTypeInfo);
else Result:=TRttiType.Create(aTypeInfo); else Result:=TRttiType.Create(aTypeInfo);
end; end;
@ -804,6 +906,11 @@ begin
if AName='' then ; if AName='' then ;
end; end;
function TRttiType.GetMethods: TRttiMethodArray;
begin
Result:=nil;
end;
function TRttiType.GetMethods(const aName: String): TRttiMethodArray; function TRttiType.GetMethods(const aName: String): TRttiMethodArray;
begin begin
Result:=nil; Result:=nil;
@ -875,6 +982,11 @@ begin
OnInvoke:=InvokeEvent; OnInvoke:=InvokeEvent;
end; end;
function TVirtualInterface.QueryInterface(const iid: TGuid; out obj): Integer;
begin
Result := inherited QueryInterface(iid, obj);
end;
function Invoke(ACodeAddress: Pointer; const AArgs: TJSValueDynArray; function Invoke(ACodeAddress: Pointer; const AArgs: TJSValueDynArray;
ACallConv: TCallConv; AResultType: PTypeInfo; AIsStatic: Boolean; ACallConv: TCallConv; AResultType: PTypeInfo; AIsStatic: Boolean;
AIsConstructor: Boolean): TValue; AIsConstructor: Boolean): TValue;