mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 13:39:39 +01:00 
			
		
		
		
	+ add ability to create method implementations for method and procedure variables (Delphi does not support this, but I see no reason to prohibit this...)
git-svn-id: trunk@40699 -
This commit is contained in:
		
							parent
							
								
									f97688a07b
								
							
						
					
					
						commit
						d3acbc1784
					
				@ -345,11 +345,18 @@ type
 | 
				
			|||||||
    function GetParameters(aWithHidden: Boolean): specialize TArray<TRttiParameter>; virtual; abstract;
 | 
					    function GetParameters(aWithHidden: Boolean): specialize TArray<TRttiParameter>; virtual; abstract;
 | 
				
			||||||
    function GetCallingConvention: TCallConv; virtual; abstract;
 | 
					    function GetCallingConvention: TCallConv; virtual; abstract;
 | 
				
			||||||
    function GetReturnType: TRttiType; virtual; abstract;
 | 
					    function GetReturnType: TRttiType; virtual; abstract;
 | 
				
			||||||
 | 
					    function GetFlags: TFunctionCallFlags; virtual; abstract;
 | 
				
			||||||
 | 
					  public type
 | 
				
			||||||
 | 
					    TCallbackMethod = procedure(aInvokable: TRttiInvokableType; const aArgs: TValueArray; out aResult: TValue) of object;
 | 
				
			||||||
 | 
					    TCallbackProc = procedure(aInvokable: TRttiInvokableType; const aArgs: TValueArray; out aResult: TValue);
 | 
				
			||||||
  public
 | 
					  public
 | 
				
			||||||
    function GetParameters: specialize TArray<TRttiParameter>; inline;
 | 
					    function GetParameters: specialize TArray<TRttiParameter>; inline;
 | 
				
			||||||
    property CallingConvention: TCallConv read GetCallingConvention;
 | 
					    property CallingConvention: TCallConv read GetCallingConvention;
 | 
				
			||||||
    property ReturnType: TRttiType read GetReturnType;
 | 
					    property ReturnType: TRttiType read GetReturnType;
 | 
				
			||||||
    function Invoke(const aProcOrMeth: TValue; const aArgs: array of TValue): TValue; virtual; abstract;
 | 
					    function Invoke(const aProcOrMeth: TValue; const aArgs: array of TValue): TValue; virtual; abstract;
 | 
				
			||||||
 | 
					    { Note: once "reference to" is supported these will be replaced by a single method }
 | 
				
			||||||
 | 
					    function CreateImplementation(aCallback: TCallbackMethod): TMethodImplementation;
 | 
				
			||||||
 | 
					    function CreateImplementation(aCallback: TCallbackProc): TMethodImplementation;
 | 
				
			||||||
  end;
 | 
					  end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  TRttiMethodType = class(TRttiInvokableType)
 | 
					  TRttiMethodType = class(TRttiInvokableType)
 | 
				
			||||||
@ -361,6 +368,7 @@ type
 | 
				
			|||||||
    function GetParameters(aWithHidden: Boolean): specialize TArray<TRttiParameter>; override;
 | 
					    function GetParameters(aWithHidden: Boolean): specialize TArray<TRttiParameter>; override;
 | 
				
			||||||
    function GetCallingConvention: TCallConv; override;
 | 
					    function GetCallingConvention: TCallConv; override;
 | 
				
			||||||
    function GetReturnType: TRttiType; override;
 | 
					    function GetReturnType: TRttiType; override;
 | 
				
			||||||
 | 
					    function GetFlags: TFunctionCallFlags; override;
 | 
				
			||||||
  public
 | 
					  public
 | 
				
			||||||
    function Invoke(const aCallable: TValue; const aArgs: array of TValue): TValue; override;
 | 
					    function Invoke(const aCallable: TValue; const aArgs: array of TValue): TValue; override;
 | 
				
			||||||
  end;
 | 
					  end;
 | 
				
			||||||
@ -372,6 +380,7 @@ type
 | 
				
			|||||||
    function GetParameters(aWithHidden: Boolean): specialize TArray<TRttiParameter>; override;
 | 
					    function GetParameters(aWithHidden: Boolean): specialize TArray<TRttiParameter>; override;
 | 
				
			||||||
    function GetCallingConvention: TCallConv; override;
 | 
					    function GetCallingConvention: TCallConv; override;
 | 
				
			||||||
    function GetReturnType: TRttiType; override;
 | 
					    function GetReturnType: TRttiType; override;
 | 
				
			||||||
 | 
					    function GetFlags: TFunctionCallFlags; override;
 | 
				
			||||||
  public
 | 
					  public
 | 
				
			||||||
    function Invoke(const aCallable: TValue; const aArgs: array of TValue): TValue; override;
 | 
					    function Invoke(const aCallable: TValue; const aArgs: array of TValue): TValue; override;
 | 
				
			||||||
  end;
 | 
					  end;
 | 
				
			||||||
@ -2663,6 +2672,70 @@ begin
 | 
				
			|||||||
  Result := GetParameters(False);
 | 
					  Result := GetParameters(False);
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function TRttiInvokableType.CreateImplementation(aCallback: TCallbackMethod): TMethodImplementation;
 | 
				
			||||||
 | 
					var
 | 
				
			||||||
 | 
					  params: specialize TArray<TRttiParameter>;
 | 
				
			||||||
 | 
					  args: specialize TArray<TFunctionCallParameterInfo>;
 | 
				
			||||||
 | 
					  res: PTypeInfo;
 | 
				
			||||||
 | 
					  restype: TRttiType;
 | 
				
			||||||
 | 
					  resinparam: Boolean;
 | 
				
			||||||
 | 
					  i: SizeInt;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  if not Assigned(aCallback) then
 | 
				
			||||||
 | 
					    raise EArgumentNilException.Create(SErrMethodImplNoCallback);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  resinparam := False;
 | 
				
			||||||
 | 
					  params := GetParameters(True);
 | 
				
			||||||
 | 
					  SetLength(args, Length(params));
 | 
				
			||||||
 | 
					  for i := 0 to High(params) do begin
 | 
				
			||||||
 | 
					    args[i].ParamType := params[i].ParamType.FTypeInfo;
 | 
				
			||||||
 | 
					    args[i].ParamFlags := params[i].Flags;
 | 
				
			||||||
 | 
					    args[i].ParaLocs := Nil;
 | 
				
			||||||
 | 
					    if pfResult in params[i].Flags then
 | 
				
			||||||
 | 
					      resinparam := True;
 | 
				
			||||||
 | 
					  end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  restype := GetReturnType;
 | 
				
			||||||
 | 
					  if Assigned(restype) and not resinparam then
 | 
				
			||||||
 | 
					    res := restype.FTypeInfo
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    res := Nil;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Result := TMethodImplementation.Create(GetCallingConvention, args, res, GetFlags, Self, TMethodImplementationCallbackMethod(aCallback));
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function TRttiInvokableType.CreateImplementation(aCallback: TCallbackProc): TMethodImplementation;
 | 
				
			||||||
 | 
					var
 | 
				
			||||||
 | 
					  params: specialize TArray<TRttiParameter>;
 | 
				
			||||||
 | 
					  args: specialize TArray<TFunctionCallParameterInfo>;
 | 
				
			||||||
 | 
					  res: PTypeInfo;
 | 
				
			||||||
 | 
					  restype: TRttiType;
 | 
				
			||||||
 | 
					  resinparam: Boolean;
 | 
				
			||||||
 | 
					  i: SizeInt;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  if not Assigned(aCallback) then
 | 
				
			||||||
 | 
					    raise EArgumentNilException.Create(SErrMethodImplNoCallback);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  resinparam := False;
 | 
				
			||||||
 | 
					  params := GetParameters(True);
 | 
				
			||||||
 | 
					  SetLength(args, Length(params));
 | 
				
			||||||
 | 
					  for i := 0 to High(params) do begin
 | 
				
			||||||
 | 
					    args[i].ParamType := params[i].ParamType.FTypeInfo;
 | 
				
			||||||
 | 
					    args[i].ParamFlags := params[i].Flags;
 | 
				
			||||||
 | 
					    args[i].ParaLocs := Nil;
 | 
				
			||||||
 | 
					    if pfResult in params[i].Flags then
 | 
				
			||||||
 | 
					      resinparam := True;
 | 
				
			||||||
 | 
					  end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  restype := GetReturnType;
 | 
				
			||||||
 | 
					  if Assigned(restype) and not resinparam then
 | 
				
			||||||
 | 
					    res := restype.FTypeInfo
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    res := Nil;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Result := TMethodImplementation.Create(GetCallingConvention, args, res, GetFlags, Self, TMethodImplementationCallbackProc(aCallback));
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{ TRttiMethodType }
 | 
					{ TRttiMethodType }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function TRttiMethodType.GetParameters(aWithHidden: Boolean): specialize TArray<TRttiParameter>;
 | 
					function TRttiMethodType.GetParameters(aWithHidden: Boolean): specialize TArray<TRttiParameter>;
 | 
				
			||||||
@ -2777,6 +2850,11 @@ begin
 | 
				
			|||||||
    Result := Nil;
 | 
					    Result := Nil;
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function TRttiMethodType.GetFlags: TFunctionCallFlags;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  Result := [];
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function TRttiMethodType.Invoke(const aCallable: TValue; const aArgs: array of TValue): TValue;
 | 
					function TRttiMethodType.Invoke(const aCallable: TValue; const aArgs: array of TValue): TValue;
 | 
				
			||||||
var
 | 
					var
 | 
				
			||||||
  method: PMethod;
 | 
					  method: PMethod;
 | 
				
			||||||
@ -2865,6 +2943,11 @@ begin
 | 
				
			|||||||
  end;
 | 
					  end;
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function TRttiProcedureType.GetFlags: TFunctionCallFlags;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  Result := [fcfStatic];
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function TRttiProcedureType.Invoke(const aCallable: TValue; const aArgs: array of TValue): TValue;
 | 
					function TRttiProcedureType.Invoke(const aCallable: TValue; const aArgs: array of TValue): TValue;
 | 
				
			||||||
begin
 | 
					begin
 | 
				
			||||||
  if aCallable.Kind <> tkProcVar then
 | 
					  if aCallable.Kind <> tkProcVar then
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user