Recent

Author Topic: RTTI - Functions/Procedures  (Read 649 times)

gii

  • New Member
  • *
  • Posts: 34
RTTI - Functions/Procedures
« on: June 14, 2019, 02:34:20 am »
Is it possible to identify whether a method is a procedure or a function, and if it is a function, get the data type of the return?

lucamar

  • Hero Member
  • *****
  • Posts: 2958
Re: RTTI - Functions/Procedures
« Reply #1 on: June 14, 2019, 02:49:49 am »
The function GetTypeData() in unit TypInfo should give you that information. It's described (more or less) in the RTL help file.

Note: I'm not much versed in this so I may be wrong  :-[
« Last Edit: June 14, 2019, 02:51:26 am by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.8/FPC 3.0.4 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

PascalDragon

  • Hero Member
  • *****
  • Posts: 1922
  • Compiler Developer
Re: RTTI - Functions/Procedures
« Reply #2 on: June 14, 2019, 09:11:47 am »
Currently it's only possible to do this for procedure and method variable types (already in 3.0.x) and interfaces (in the upcoming 3.2.0). The remainder, namely the methods of classes, objects and records as well as standalone procedures/functions are not yet supported.

Thaddy

  • Hero Member
  • *****
  • Posts: 10272
Re: RTTI - Functions/Procedures
« Reply #3 on: June 14, 2019, 12:03:12 pm »
@PascalDragon
For standalone  procedures and functions  it looks possible like so:
Code: Pascal  [Select][+][-]
  1. {$mode objfpc}
  2. uses typinfo;
  3.  
  4. procedure TestIt(const value:Boolean);
  5. begin
  6.   writeln(value);
  7. end;
  8.  
  9. function testme(const test:Boolean):Boolean;
  10. begin
  11.  Result :=test;
  12. end;
  13.  
  14. var
  15.   Info:PTypeInfo = nil;
  16.   Data:PTypeData = nil;
  17. begin
  18.   Info := TypeInfo(@Testme);
  19.   Data := GetTypeData(Info);
  20.   writeln('function test: ',Info^.Kind);
  21.   // test if it is a procedure or function.
  22.   // If resulttyperef is nil, it's a procedure
  23.   // otherwise retrieve the result type
  24.   if (Info^.kind = tkProcVar) and (Data^.ProcSig.ResultTypeRef <> nil) then
  25.     writeln('This is a Function with result type ',Data^.ProcSig.ResultType^.Kind)
  26.   else writeln(' This is a procedure');
  27.   Info := TypeInfo(@Testit);
  28.   Data := GetTypeData(Info);
  29.   writeln('procedure test: ',Info^.Kind);
  30.   if (Info^.kind = tkProcVar) and (Data^.ProcSig.ResultTypeRef <> nil) then
  31.     writeln('This is a Function with result type',Data^.ProcSig.ResultType^.Kind)
  32.   else writeln('This is a procedure');
  33. end.

Methods can be done like this:
Code: Pascal  [Select][+][-]
  1.  // methods
  2. {$mode objfpc}
  3.  uses typinfo, classes;
  4. var
  5.   O:Tobject;
  6.    List:Tstringlist;
  7.    Info:PTypeInfo;
  8.    Data:PTypeData;
  9. begin
  10.   O := Tobject.Create;
  11.   try
  12.   Info :=TypeInfo(@O.ToString);
  13.   Data :=GetTypeData(Info);
  14.   writeln(Info^.Kind);
  15.   if (Info^.kind = tkMethod) and (Data^.MethodKind = mkFunction) then
  16.   begin
  17.     List := TStringlist.Create;
  18.     try
  19.       List.Text := Data^.ParamList;
  20.       writeln('This is a method Function with result type ', list[2])
  21.     finally
  22.      list.free;
  23.     end
  24.   end;
  25.   finally
  26.   O.free;
  27.   end;
  28. end.
« Last Edit: June 14, 2019, 01:00:35 pm by Thaddy »
I am more like donkey than shrek

gii

  • New Member
  • *
  • Posts: 34
Re: RTTI - Functions/Procedures
« Reply #4 on: June 14, 2019, 03:35:41 pm »
The function GetTypeData() in unit TypInfo should give you that information. It's described (more or less) in the RTL help file.

Note: I'm not much versed in this so I may be wrong  :-[
@PascalDragon

..

Methods can be done like this:
Code: Pascal  [Select][+][-]
  1.  // methods
  2. {$mode objfpc}
  3.  uses typinfo, classes;
  4. var
  5.   O:Tobject;
  6.    List:Tstringlist;
  7.    Info:PTypeInfo;
  8.    Data:PTypeData;
  9. begin
  10.   O := Tobject.Create;
  11.   try
  12.   Info :=TypeInfo(@O.ToString);
  13.   Data :=GetTypeData(Info);
  14.   writeln(Info^.Kind);
  15.   if (Info^.kind = tkMethod) and (Data^.MethodKind = mkFunction) then
  16.   begin
  17.     List := TStringlist.Create;
  18.     try
  19.       List.Text := Data^.ParamList;
  20.       writeln('This is a method Function with result type ', list[2])
  21.     finally
  22.      list.free;
  23.     end
  24.   end;
  25.   finally
  26.   O.free;
  27.   end;
  28. end.

I tested with some methods and it worked.

Thank you.

The only problem I found was in:

Code: Pascal  [Select][+][-]
  1. List.Text := Data^.ParamList

For example, it is returned:

Code: Pascal  [Select][+][-]
  1. Data^.ParamList = #7'LongIntp'#163'X'#0#0#0#0#0#15#6'TForm1' ....

And the return is not broken into rows in the StringList, but this I can solve.

Another question, is it possible to get the parameter list (name and data type)?

 

TinyPortal © 2005-2018