Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / RTTI GetMethods / 19 сообщений из 19, страница 1 из 1
25.03.2019, 21:09
    #39791183
Foxpc
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RTTI GetMethods
Почему для той же формы, он может вернуть 7 конструкторов, 6 деструкторов ? Как отсортировать только те, что имеет TForm ? А не всех наследников как я понимаю

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
program Project2;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils, vcl.forms, rtti;

var
  Method: TRttiMethod;
  ClassInfo: TRttiType;
  r: TRttiContext;

begin
  try
    ClassInfo := r.FindType('Vcl.Forms.TForm');
    for Method in ClassInfo.GetMethods do
      if Method.IsConstructor or Method.IsDestructor then
        Writeln(Method.ToString);

  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;

end.

...
Рейтинг: 0 / 0
25.03.2019, 21:49
    #39791195
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RTTI GetMethods
GetDeclaredMethods
...
Рейтинг: 0 / 0
25.03.2019, 22:01
    #39791197
Foxpc
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RTTI GetMethods
X-Cite,

То есть можно по base отсортировать overload и потом недостающие методы выковырять по цыпочке ? Что бы не плодить дубликаты со всех предков
...
Рейтинг: 0 / 0
25.03.2019, 22:32
    #39791206
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RTTI GetMethods
GetDeclaredMethods - вернет только то что у TForm
т.к. у TForm нет конструкторов или деструкторов, то ничего и не вернется у вас.
Если укажете TCustomForm то вернет 2 конструктора
http://docwiki.embarcadero.com/Libraries/Rio/en/System.Rtti.TRttiType.GetDeclaredMethods
...
Рейтинг: 0 / 0
25.03.2019, 22:34
    #39791207
Foxpc
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RTTI GetMethods
После очередного вык..косяка, я написал это

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
program Project2;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils, vcl.forms, Generics.Collections, rtti;

function GetMethodsOnly(v: TRttiType): TArray<TRttiMethod>;
type
  TMethodExistList = TDictionary<string, Integer>;
var
  ExistList: TMethodExistList;
  ListCurrent, tmp: Integer;
  base: TRttiType;
  Method: TRttiMethod;
  NewFor: Boolean;
  name: string;
begin
  ExistList := TMethodExistList.Create;
  ListCurrent := 0;
  SetLength(Result, 500);
  base := v.BaseType;
  while base <> nil do
  begin
    NewFor := ListCurrent <= 0;
    for Method in base.GetDeclaredMethods do
    begin
      name := Method.name;
      if NewFor or not ExistList.TryGetValue(name, tmp) then
      begin
        Result[ListCurrent] := Method;
        inc(ListCurrent);
        ExistList.Add(name, 1);
      end
    end;
    base := base.BaseType;
  end;
  SetLength(Result, ListCurrent);
  ExistList.Free;
end;

var
  Method: TRttiMethod;
  ClassInfo, base: TRttiType;
  r: TRttiContext;

begin
  try
    ClassInfo := r.FindType('Vcl.Forms.TForm');

    for Method in GetMethodsOnly(ClassInfo) do
      if Method.IsConstructor or Method.IsDestructor then
        Writeln(Method.ToString);

  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;

end.
...
Рейтинг: 0 / 0
25.03.2019, 22:55
    #39791214
Foxpc
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RTTI GetMethods
С постепенным увеличением, оно в любом случае нужно

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
function GetMethodsOnly(v: TRttiType): TArray<TRttiMethod>;
type
  TMethodExistList = TDictionary<string, Integer>;
var
  ExistList: TMethodExistList;
  ListCurrent, ListMax, tmp: Integer;
  base: TRttiType;
  Method: TRttiMethod;
  NewFor: Boolean;
  name: string;
begin
  ExistList := TMethodExistList.Create;
  ListCurrent := 0;
  ListMax := 100;
  SetLength(Result, ListMax);
  base := v.BaseType;
  while base <> nil do
  begin
    NewFor := ListCurrent <= 0;
    for Method in base.GetDeclaredMethods do
    begin
      name := Method.name;
      if NewFor or not ExistList.TryGetValue(name, tmp) then
      begin
        Result[ListCurrent] := Method;
        inc(ListCurrent);
        ExistList.Add(name, 1);

        if ListCurrent >= ListMax then
        begin
          inc(ListMax, 100);
          SetLength(Result, ListMax);
        end;
      end
    end;
    base := base.BaseType;
  end;
  SetLength(Result, ListCurrent);
  ExistList.Free;
end;

...
Рейтинг: 0 / 0
25.03.2019, 23:11
    #39791222
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RTTI GetMethods
Совершенно непонятно для чего это и совершенно не совпадает с первым сообщением
...
Рейтинг: 0 / 0
25.03.2019, 23:19
    #39791225
Foxpc
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RTTI GetMethods
X-Cite,

надо собрать чистокровку, без повторяющийся методов от предвков. С сохранением overload, во всех классах(предках)

Функция с косясками, я сейчас её в тесты запихнул и увидел что дубликаты, все дела.. Надо переписать
...
Рейтинг: 0 / 0
26.03.2019, 01:07
    #39791233
Foxpc
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RTTI GetMethods
Без пятой бутылки пивка было не разобраться.. Пришлось бегать в ночной

Теперь работает как я и хотел
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
program Project2;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils,
  vcl.forms,
  Generics.Collections,
  rtti, UnitClass;

function GetMethodsOnly(v: TRttiType): TArray<TRttiMethod>;
type
  TArrArgsType = TArray<TRttiParameter>;
  TTTArrArgsType = TArray<TArrArgsType>;
  TArgsExistList = TDictionary<string, TTTArrArgsType>;
var
  Item: TPair<string, TTTArrArgsType>;
  base: TRttiType;
  Method: TRttiMethod;
  List: TArgsExistList;
  name: string;
  tmp: TTTArrArgsType;
  l, ListCurrent, ListMax: Integer;
  isExist, NewFor: Boolean;
  function IsParameterExist(p: TArrArgsType; List: TTTArrArgsType): Boolean;
  var
    t: TArrArgsType;
    param: TRttiParameter;
    i, count: Integer;
  begin
    for t in List do
    begin
      count := length(t);
      if count <> length(p) then
        exit(false);

      for i := 0 to count - 1 do
      begin
        if t[i].ParamType <> p[i].ParamType then
          exit(false);
      end;
    end;
    exit(true);
  end;

begin
  ListCurrent := 0;
  ListMax := 100;
  SetLength(Result, ListMax);

  List := TArgsExistList.Create();
  base := v.BaseType;
  while base <> nil do
  begin
    NewFor := ListCurrent <= 0;
    for Method in base.GetDeclaredMethods do
    begin
      name := Method.name;
      isExist := List.TryGetValue(name, tmp);

      if not NewFor and isExist then
      begin
        if IsParameterExist(Method.GetParameters, tmp) then
          Continue;
      end;

      l := length(tmp);
      SetLength(tmp, l + 1);

      tmp[l] := Method.GetParameters;

      List.AddOrSetValue(name, tmp);

      Result[ListCurrent] := Method;
      inc(ListCurrent);

      if ListCurrent >= ListMax then
      begin
        inc(ListMax, 100);
        SetLength(Result, ListMax);
      end;
    end;
    base := base.BaseType;
  end;

  List.Free;

  SetLength(Result, ListCurrent);
end;

var
  Method: TRttiMethod;
  ClassInfo, base: TRttiType;
  r: TRttiContext;

begin
  try
    ClassInfo := r.GetType(TypeInfo(TForm));

    for Method in GetMethodsOnly(ClassInfo) do
      if Method.IsConstructor or Method.IsDestructor then
        Writeln(Method.ToString);

  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;

end.




Код: sql
1.
2.
3.
4.
5.
constructor Create(AOwner: TComponent)
constructor CreateNew(AOwner: TComponent; Dummy: Integer)
destructor Destroy
constructor CreateParented(ParentWindow: HWND)
constructor Create



Весь результат
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
constructor Create(AOwner: TComponent)
constructor CreateNew(AOwner: TComponent; Dummy: Integer)
destructor Destroy
procedure ScaleForPPI(NewPPI: Integer)
procedure Close
function CloseQuery: Boolean
procedure DefaultHandler(var Message)
procedure DefocusControl(Control: TWinControl; Removing: Boolean)
procedure Dock(NewDockSite: TWinControl; ARect: TRect)
procedure FocusControl(Control: TWinControl)
procedure GetChildren(Proc: TGetChildProc = procedure(Child: TComponent) of object; Root: TComponent)
function GetFormImage: TBitmap
procedure Hide
function IsShortCut(var Message: TWMKey): Boolean
procedure MakeFullyVisible(AMonitor: TMonitor)
procedure MouseWheelHandler(var Message: TMessage)
procedure Print
procedure RecreateAsPopup(AWindowHandle: HWND)
procedure Release
procedure SendCancelMode(Sender: TControl)
procedure SetFocus
function SetFocusedControl(Control: TWinControl): Boolean
procedure Show
function ShowModal: Integer
function WantChildKey(Child: TControl; var Message: TMessage): Boolean
procedure set_PopupParent(Value: TCustomForm)
procedure AfterConstruction
procedure BeforeDestruction
procedure DisableAutoRange
procedure EnableAutoRange
procedure ScrollInView(AControl: TControl)
constructor CreateParented(ParentWindow: HWND)
class function CreateParentedControl(ParentWindow: HWND): TWinControl
procedure Broadcast(var Message)
function CanFocus: Boolean
function ContainsControl(Control: TControl): Boolean
function ControlAtPos(const Pos: TPoint; AllowDisabled: Boolean; AllowWinControls: Boolean; AllLevels: Boolean): TControl
procedure DisableAlign
procedure DockDrop(Source: TDragDockObject; X: Integer; Y: Integer)
procedure EnableAlign
function FindChildControl(const ControlName: string): TControl
procedure FlipChildren(AllLevels: Boolean)
function Focused: Boolean
procedure GetTabControlList(List: TList)
procedure GetTabOrderList(List: TList)
function HandleAllocated: Boolean
procedure HandleNeeded
procedure InsertControl(AControl: TControl)
procedure Invalidate
procedure PaintTo(DC: HDC; X: Integer; Y: Integer)
procedure PaintTo(Canvas: TCanvas; X: Integer; Y: Integer)
function PreProcessMessage(var Msg: tagMSG): Boolean
procedure RemoveControl(AControl: TControl)
procedure Realign
procedure Repaint
procedure ScaleBy(M: Integer; D: Integer)
procedure ScrollBy(DeltaX: Integer; DeltaY: Integer)
procedure SetBounds(ALeft: Integer; ATop: Integer; AWidth: Integer; AHeight: Integer)
procedure SetDesignVisible(Value: Boolean)
procedure Update
procedure UpdateControlState
function GetDockClients(Index: Integer): TControl
function GetControl(Index: Integer): TControl
procedure BeginDrag(Immediate: Boolean; Threshold: Integer)
procedure BringToFront
function ClientToScreen(const Point: TPoint): TPoint
function ClientToParent(const Point: TPoint; AParent: TWinControl): TPoint
function Dragging: Boolean
procedure DragDrop(Source: TObject; X: Integer; Y: Integer)
function DrawTextBiDiModeFlags(Flags: Integer): Integer
function DrawTextBiDiModeFlagsReadingOnly: Integer
procedure EndDrag(Drop: Boolean)
function GetControlsAlignment: TAlignment
function GetParentComponent: TComponent
function HasParent: Boolean
procedure InitiateAction
function IsRightToLeft: Boolean
function ManualDock(NewDockSite: TWinControl; DropControl: TControl; ControlSide: TAlign): Boolean
function ManualFloat(ScreenPos: TRect): Boolean
function Perform(Msg: Cardinal; WParam: NativeUInt; LParam: NativeInt): NativeInt
procedure Refresh
function ReplaceDockedControl(Control: TControl; NewDockSite: TWinControl; DropControl: TControl; ControlSide: TAlign): Boolean
function ScreenToClient(const Point: TPoint): TPoint
function ParentToClient(const Point: TPoint; AParent: TWinControl): TPoint
procedure SendToBack
procedure SetParentComponent(Value: TComponent)
function UseRightToLeftAlignment: Boolean
function UseRightToLeftReading: Boolean
function UseRightToLeftScrollBar: Boolean
function GetTextBuf(Buffer: PWideChar; BufSize: Integer): Integer
function GetTextLen: Integer
function Perform(Msg: Cardinal; WParam: NativeUInt; LParam: PWideChar): NativeInt
function Perform(Msg: Cardinal; WParam: NativeUInt; var LParam: TRect): NativeInt
procedure SetTextBuf(Buffer: PWideChar)
function BeginInvoke(const AProc: TProc; const AContext: TObject): IAsyncResult
function BeginInvoke(const AProc: TAsyncProcedureEvent = procedure(const ASyncResult: IAsyncResult) of object; const AContext: TObject): IAsyncResult
function BeginInvoke(const AProc: TAsyncConstArrayProc; const Params: TVarRec; const AContext: TObject): IAsyncResult
function BeginInvoke(const AProc: TAsyncConstArrayProcedureEvent = procedure(const ASyncResult: IAsyncResult; const Params: TVarRec) of object; const Params: TVarRec; const AContext: TObject): IAsyncResult
function BeginInvoke(const AFunc: TAsyncConstArrayFunctionEvent = procedure(const ASyncResult: IAsyncResult; out Result: TObject; const Params: TVarRec) of object; const Params: TVarRec; const AContext: TObject): IAsyncResult
function BeginInvoke(const AFunc: TAsyncFunctionEvent = procedure(const ASyncResult: IAsyncResult; out Result: TObject) of object; const AContext: TObject): IAsyncResult
procedure EndInvoke(const ASyncResult: IAsyncResult)
function EndFunctionInvoke(const AsyncResult: IAsyncResult): TObject
procedure DestroyComponents
procedure Destroying
function ExecuteAction(Action: TBasicAction): Boolean
function FindComponent(const AName: string): TComponent
procedure FreeNotification(AComponent: TComponent)
procedure RemoveFreeNotification(AComponent: TComponent)
procedure FreeOnRelease
function GetEnumerator: TComponentEnumerator
function GetNamePath: string
procedure InsertComponent(const AComponent: TComponent)
procedure RemoveComponent(const AComponent: TComponent)
procedure SetSubComponent(IsSubComponent: Boolean)
function SafeCallException(ExceptObject: TObject; ExceptAddr: Pointer): HRESULT
function UpdateAction(Action: TBasicAction): Boolean
function IsImplementorOf(const I: IInterface): Boolean
function ReferenceInterface(const I: IInterface; Operation: TOperation): Boolean
function GetComponent(AIndex: Integer): TComponent
procedure Assign(Source: TPersistent)
constructor Create
procedure Free
procedure DisposeOf
class function InitInstance(Instance: Pointer): TObject
procedure CleanupInstance
function ClassType: TClass
class function ClassName: string
class function ClassNameIs(const Name: string): Boolean
class function ClassParent: TClass
class function ClassInfo: Pointer
class function InstanceSize: Integer
class function InheritsFrom(AClass: TClass): Boolean
class function MethodAddress(const Name: ShortString): Pointer
class function MethodAddress(const Name: string): Pointer
class function MethodName(Address: Pointer): string
class function QualifiedClassName: string
function FieldAddress(const Name: ShortString): Pointer
function FieldAddress(const Name: string): Pointer
function GetInterface(const IID: TGUID; out Obj): Boolean
class function GetInterfaceEntry(const IID: TGUID): PInterfaceEntry
class function GetInterfaceTable: PInterfaceTable
class function UnitName: string
class function UnitScope: string
function Equals(Obj: TObject): Boolean
function GetHashCode: Integer
function ToString: string
procedure Dispatch(var Message)
class function NewInstance: TObject
procedure FreeInstance

...
Рейтинг: 0 / 0
26.03.2019, 01:53
    #39791236
Foxpc
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RTTI GetMethods
Багфикс замены base := v.BaseType; на изначальный аргумент функции

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
program Project2;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils,
  vcl.forms,
  Generics.Collections,
  rtti, UnitClass;

function GetMethodsOnly(base: TRttiType): TArray<TRttiMethod>;
type
  TArrArgsType = TArray<TRttiParameter>;
  TTTArrArgsType = TArray<TArrArgsType>;
  TArgsExistList = TDictionary<string, TTTArrArgsType>;
var
  Item: TPair<string, TTTArrArgsType>;
  Method: TRttiMethod;
  List: TArgsExistList;
  name: string;
  tmp: TTTArrArgsType;
  l, ListCurrent, ListMax: Integer;
  NewFor: Boolean;
  function IsParameterExist(p: TArrArgsType): Boolean;
  var
    t: TArrArgsType;
    param: TRttiParameter;
    i, count: Integer;
  begin
    for t in tmp do
    begin
      count := length(t);
      if count <> length(p) then
        exit(false);

      for i := 0 to count - 1 do
      begin
        if t[i].ParamType <> p[i].ParamType then
          exit(false);
      end;
    end;
    exit(true);
  end;

begin
  ListCurrent := 0;
  ListMax := 100;
  SetLength(Result, ListMax);

  List := TArgsExistList.Create();
  while base <> nil do
  begin
    NewFor := ListCurrent <= 0;
    for Method in base.GetDeclaredMethods do
    begin
      name := Method.name;

      if not NewFor and List.TryGetValue(name, tmp) then
      begin
        if IsParameterExist(Method.GetParameters) then
          Continue;
      end;

      l := length(tmp);
      SetLength(tmp, l + 1);

      tmp[l] := Method.GetParameters;

      List.AddOrSetValue(name, tmp);

      Result[ListCurrent] := Method;
      inc(ListCurrent);

      if ListCurrent >= ListMax then
      begin
        inc(ListMax, 100);
        SetLength(Result, ListMax);
      end;
    end;
    base := base.BaseType;
  end;

  List.Free;

  SetLength(Result, ListCurrent);
end;

var
  Method: TRttiMethod;
  ClassInfo, base: TRttiType;
  r: TRttiContext;

begin
  try
    ClassInfo := r.GetType(TypeInfo(TForm));

    for Method in GetMethodsOnly(ClassInfo) do
      if Method.IsConstructor or Method.IsDestructor then
        Writeln(Method.ToString);

  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;

end.

...
Рейтинг: 0 / 0
26.03.2019, 10:17
    #39791324
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RTTI GetMethods
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
 TA = class
  public
    constructor Create; virtual;
  end;

  TB = class(TA)
  public
    constructor Create; overload; override;
    constructor Create(const aParam: Int32); reintroduce; overload;
  end;

ClassInfo := r.GetType(TypeInfo(TB));



Выведет
constructor Create
constructor Create(const aParam: Integer)
constructor Create
constructor Create
destructor Destroy
...
Рейтинг: 0 / 0
26.03.2019, 11:21
    #39791373
Foxpc
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RTTI GetMethods
X-Cite,




Код: sql
1.
2.
3.
constructor Create
constructor Create(const aParam: Integer)
destructor Destroy



Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
program Project2;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils,
  vcl.forms,
  Generics.Collections,
  rtti;

type
  TA = class
  public
    constructor Create; virtual;
  end;

  TB = class(TA)
  public
    constructor Create; overload; override;
    constructor Create(const aParam: Int32); reintroduce; overload;
  end;

function GetMethodsOnly(base: TRttiType): TArray<TRttiMethod>;
type
  TArrArgsType = TArray<TRttiParameter>;
  TTTArrArgsType = TArray<TArrArgsType>;
  TArgsExistList = TDictionary<string, TTTArrArgsType>;
var
  Item: TPair<string, TTTArrArgsType>;
  Method: TRttiMethod;
  List: TArgsExistList;
  name: string;
  tmp: TTTArrArgsType;
  l, ListCurrent, ListMax: Integer;
  NewFor: Boolean;
  function IsParameterExist(p: TArrArgsType): Boolean;
  var
    t: TArrArgsType;
    i, count: Integer;
  begin
    for t in tmp do
    begin
      count := length(t);

      if count = length(p) then
      begin
        if count = 0 then
          exit(true);

        for i := 0 to count - 1 do
        begin
          if t[i].ParamType <> p[i].ParamType then
            exit(false);
        end;
      end;
    end;
    exit(true);
  end;

begin
  ListCurrent := 0;
  ListMax := 100;
  SetLength(Result, ListMax);

  List := TArgsExistList.Create();
  while base <> nil do
  begin
    NewFor := ListCurrent <= 0;
    for Method in base.GetDeclaredMethods do
    begin
      name := Method.name;

      if not NewFor and List.TryGetValue(name, tmp) then
      begin
        if IsParameterExist(Method.GetParameters) then
          Continue;
      end;

      l := length(tmp);
      SetLength(tmp, l + 1);

      tmp[l] := Method.GetParameters;

      List.AddOrSetValue(name, tmp);

      Result[ListCurrent] := Method;
      inc(ListCurrent);

      if ListCurrent >= ListMax then
      begin
        inc(ListMax, 100);
        SetLength(Result, ListMax);
      end;
    end;
    base := base.BaseType;
  end;

  List.Free;

  SetLength(Result, ListCurrent);
end;

constructor TA.Create;
begin
end;

constructor TB.Create;
begin
end;

constructor TB.Create(const aParam: Int32);
begin

end;

var
  Method: TRttiMethod;
  ClassInfo: TRttiType;
  r: TRttiContext;

begin
  try
    ClassInfo := r.GetType(TypeInfo(TB));

    for Method in GetMethodsOnly(ClassInfo) do
      if Method.IsConstructor or Method.IsDestructor then
        Writeln(Method.ToString);

  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;

end.

...
Рейтинг: 0 / 0
26.03.2019, 23:58
    #39791938
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RTTI GetMethods
А нельзя напихать описание в TStringList и выкидывая дубликаты ?
Зачем такая простынь ?
...
Рейтинг: 0 / 0
27.03.2019, 01:06
    #39791947
Foxpc
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RTTI GetMethods
DimaBr,

1) Нужна динамика
2) Один раз нужно вызвать, для сбора информации
...
Рейтинг: 0 / 0
27.03.2019, 01:11
    #39791948
Foxpc
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RTTI GetMethods
Функция работает так

1) Набираем информацию о методах текущего класса
2) Идём гулять по унаследованным классам
3) Добавляем из них новые методы
4) Если метод существует в базе по имени ранее, смотрим есть ли в нём различие в аргументах. Если есть, то добавляем в базу

В общем то и всё.

Я не представляю для себя возможных, проверку аргументов для методов используя TStringList
...
Рейтинг: 0 / 0
27.03.2019, 02:55
    #39791958
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RTTI GetMethods
Зачем их проверять ? Нельзя просто собрать уникальные ?
...
Рейтинг: 0 / 0
27.03.2019, 11:02
    #39792092
Foxpc
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RTTI GetMethods
DimaBr,

почитай про overload
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
14.02.2021, 16:47
    #40045230
inbox
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RTTI GetMethods
Если удалить говнокод из сортировки

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
type
  TListMethods = TArray<TRttiMethod>;

  TArgsExistList = TDictionary<string, TListMethods>;
  TArgsExistListPairItem = TPair<string, TListMethods>;

function GetMethodsOnly2(Base: TRttiType; var MethodsCount: Integer)
  : TArgsExistList;
var
  Method: TRttiMethod;
  Name: string;

  Items: TListMethods;
  L: Integer;
  function IsParameterExist: Boolean;
  var
    Mt: TRttiMethod;
    T, P: TArray<TRttiParameter>;
    Count: Integer;
  begin
    P := Method.GetParameters;
    for Mt in Items do
    begin
      T := Mt.GetParameters;

      Count := Length(T);
      if Count <> Length(P) then
        Continue;

      while Count > 0 do
      begin
        dec(Count);
        if T[Count].ParamType <> P[Count].ParamType then
          Exit(False);
      end;

      Exit(Count <= 0);
    end;
    Exit(False);
  end;

begin
  MethodsCount := 0;

  Result := TArgsExistList.Create();
  while Base <> nil do
  begin
    for Method in Base.GetDeclaredMethods do
    begin
      name := Method.Name.ToLower;

      if Result.TryGetValue(name, Items) then
        if IsParameterExist then
          Continue;

      L := Length(Items);
      SetLength(Items, L + 1);

      Items[L] := Method;
      Inc(MethodsCount);

      Result.AddOrSetValue(name, Items);
    end;
    Base := Base.BaseType;
  end;
end;



https://pastebin.com/h0cZGEtm
...
Рейтинг: 0 / 0
15.02.2021, 22:25
    #40045622
inbox
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RTTI GetMethods
FIX

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, rtti,
  Generics.Collections, Vcl.ExtCtrls,
  System.IOUtils, typinfo;

type
  TForm2 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TA = class
  public
    constructor Create; virtual;
    function Test(const A: string): Integer; overload;
    function Test(const B: PWideChar): Integer; overload;
    function Test(const B: PAnsiChar): Integer; overload;
  end;

  TB = class(TA)
  public
    constructor Create; overload; override;
    constructor Create(const aParam: Int32); reintroduce; overload;

    function Test(const A: string): Integer; overload;
    function Test(const B: PWideChar): Integer; overload;
    function Test(const B: PAnsiChar): Integer; overload;
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

function TA.Test(const A: string): Integer;
begin

end;

function TA.Test(const B: PWideChar): Integer;
begin

end;

function TA.Test(const B: PAnsiChar): Integer;
begin

end;

constructor TA.Create;
begin

end;

constructor TB.Create;
begin

end;

function TB.Test(const A: string): Integer;
begin

end;

function TB.Test(const B: PWideChar): Integer;
begin

end;

function TB.Test(const B: PAnsiChar): Integer;
begin

end;

constructor TB.Create(const aParam: Int32);
begin

end;

type
  TListMethods = TArray<TRttiMethod>;

  TArgsExistList = TDictionary<string, TListMethods>;
  TArgsExistListPairItem = TPair<string, TListMethods>;

function GetMethodsOnly2(base: TRttiType; var MethodsCount: Integer)
  : TArgsExistList;
var
  Method: TRttiMethod;
  name: string;

  Items: TListMethods;
  i: Integer;
  function IsParameterExist: Boolean;
  var
    A, B: TArray<TRttiParameter>;
    count, i: Integer;
  begin
    A := Method.GetParameters;

    for i := Low(Items) to High(Items) do
    begin
      B := Items[i].GetParameters;

      count := length(A);
      if count <> length(B) then
        Continue;

      while count > 0 do
      begin
        if A[count - 1].ParamType <> B[count - 1].ParamType then
          Break;

        dec(count);
      end;

      if count <= 0 then
        exit(true);
    end;

    Result := false;
  end;

begin
  MethodsCount := 0;

  Result := TArgsExistList.Create();
  while base <> nil do
  begin
    for Method in base.GetDeclaredMethods do
    begin
      name := Method.name.ToLower;

      if Result.TryGetValue(name, Items) then
        if IsParameterExist then
          Continue;

      i := length(Items);
      SetLength(Items, i + 1);
      Items[i] := Method;

      inc(MethodsCount);

      Result.AddOrSetValue(name, Items);
    end;
    base := base.BaseType;
  end;
end;

procedure TForm2.Button1Click(Sender: TObject);
var
  r: TRttiType;
  m: TRttiMethod;
  List: TArgsExistList;

  Item: TArgsExistListPairItem;
  MethodsCount: Integer;
begin
  Memo1.Lines.Clear;

  r := TRttiContext.Create.GetType(TypeInfo(TB));

  List := GetMethodsOnly2(r, MethodsCount);

  Memo1.Lines.Add('-------------');
  for Item in List do
  begin
    for m in Item.Value do
    begin
      Memo1.Lines.Add(m.ToString);
    end;
    Memo1.Lines.Add('-------------');
  end;
  Memo1.Lines.Add(MethodsCount.ToString);
  List.Free;
end;

end.





Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
-------------
function ClassType: TClass
-------------
class function GetInterfaceTable: PInterfaceTable
-------------
class function InheritsFrom(AClass: TClass): Boolean
-------------
class function GetInterfaceEntry(const IID: TGUID): PInterfaceEntry
-------------
class function InstanceSize: Integer
-------------
function Test(const A: string): Integer
function Test(const B: PWideChar): Integer
function Test(const B: PAnsiChar): Integer
-------------
function SafeCallException(ExceptObject: TObject; ExceptAddr: Pointer): HRESULT
-------------
procedure AfterConstruction
-------------
class function InitInstance(Instance: Pointer): TObject
-------------
class function ClassParent: TClass
-------------
function GetHashCode: Integer
-------------
procedure Free
-------------
class function MethodAddress(const Name: ShortString): Pointer
class function MethodAddress(const Name: string): Pointer
-------------
class function QualifiedClassName: string
-------------
function GetInterface(const IID: TGUID; out Obj): Boolean
-------------
class function UnitName: string
-------------
procedure Dispatch(var Message)
-------------
constructor Create
constructor Create(const aParam: Integer)
-------------
procedure BeforeDestruction
-------------
class function ClassInfo: Pointer
-------------
class function MethodName(Address: Pointer): string
-------------
procedure CleanupInstance
-------------
procedure DefaultHandler(var Message)
-------------
function FieldAddress(const Name: ShortString): Pointer
function FieldAddress(const Name: string): Pointer
-------------
destructor Destroy
-------------
class function ClassName: string
-------------
class function NewInstance: TObject
-------------
function ToString: string
-------------
function Equals(Obj: TObject): Boolean
-------------
procedure FreeInstance
-------------
procedure DisposeOf
-------------
class function ClassNameIs(const Name: string): Boolean
-------------
class function UnitScope: string
-------------
38
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / RTTI GetMethods / 19 сообщений из 19, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]