Dump Object Methods

Mac OSX specific forum
User avatar
mk-soft
Always Here
Always Here
Posts: 5386
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Dump Object Methods

Post by mk-soft »

It is sometimes difficult to get the correct method name from a class (Object) for CocoaMessage.

Update v1.06

Update v1.08.1
- Get SuperClass with level (SuperLevel = 0 .. x)
- Format of output

Update v1.08.2
- Fixed object is nil

Update v1.09.1
- String return value now optional

Code: Select all

;-TOP Dump Object Methods

; by mk-soft, 29.12.2019 - 06.10.2023, v1.09.1

Declare.s DumpObjectMethods(*Object, SuperLevel = 0, HidePrivate = #True, ShowEncoding = #False, FirstArgument = 2)

Structure ArrayOfMethods
  i.i[0]
EndStructure

ImportC ""
  class_copyMethodList(*Class, *p_methodCount)
  ; -> An array of pointers of type Method describing
  ;    the instance methods implemented by the class
  ;    Any instance methods implemented by superclasses are Not included
  ;    You must free the array with free()
  class_getName(*Class) ; -> UnsafePointer<Int8> -> *string
  sel_getName(*Selector); -> const char *
  method_getName(*Method) ; -> Selector
  method_getTypeEncoding(*Method) ; -> const char *
  method_getReturnType(*Method, *dst, dst_len) ; -> void
  method_getNumberOfArguments(*Method)         ; -> unsigned int
  method_getArgumentType(*Method, index, *dst, dst_len) ; -> void
  
  NSGetSizeAndAlignment(*StringPtr, *p_size, *p_align) 
  ; -> const char *
  ;    Obtains the actual size and the aligned size of an encoded type.
EndImport

; ----

Procedure.s GetArgumentType(*String)
  Protected r1.s, arg.s, size.i, ofs.i
  
  arg = PeekS(*String, -1, #PB_UTF8)
  r1 + arg + " - "
  If Left(arg, 1) = "^"
    r1 + "A pointer to type of "
    arg = Mid(arg, 2)
  EndIf
  Select arg
    Case "c" : r1 + "A char "
    Case "i" : r1 + "An int "
    Case "s" : r1 + "A short "
    Case "l" : r1 + "A long "
    Case "q" : r1 + "A long long"
    Case "C" : r1 + "An unsigned char "
    Case "I" : r1 + "An unsigned int "
    Case "S" : r1 + "An unsigned short "
    Case "L" : r1 + "An unsigned long "
    Case "Q" : r1 + "An unsigned long long "
    Case "f" : r1 + "A float "
    Case "d" : r1 + "A double "
    Case "B" : r1 + "A C++ bool Or a C99 _Bool "
    Case "v" : r1 + "A void"
    Case "*" : r1 + "A character string (char *) "
    Case "@" : r1 + "An object (whether statically typed Or typed id) "
    Case "#" : r1 + "A class object (Class) "
    Case ":" : r1 + "A method selector (SEL) "
    Default:
      NSGetSizeAndAlignment(*String, @size, @ofs)
      r1 + "[" + Str(size) + " bytes]"
  EndSelect
  If Right(arg, 1) = "?"
    r1 + "An unknown type (e.g. function pointer)"
  EndIf
  ProcedureReturn r1
EndProcedure

; ----

Procedure.s DumpObjectMethods(*Object, SuperLevel = 0, HidePrivate = #True, ShowEncoding = #False, FirstArgument = 2)
  Protected result.s, r1.s, i, c, n, methodCount, Method.s
  Protected *Class, *SuperClass, *Method, *Methods.ArrayOfMethods
  Protected *String
  
  *Class = object_getclass_(*Object)
  If *Class
    *String = AllocateMemory(1024)
    r1 = PeekS(class_getName(*Class), -1, #PB_UTF8)
    If SuperLevel
      For i = 1 To SuperLevel
        *SuperClass = class_getsuperclass_(*Class)
        If *SuperClass
          *Class = *SuperClass
          r1 + " -> " + PeekS(class_getName(*Class), -1, #PB_UTF8)
        Else
          Break
        EndIf
      Next
    EndIf
    *Methods = class_copyMethodList(*Class, @methodCount)
    r1 + #LF$ + #LF$ + "Count of Methods: " + methodCount + #LF$
    result = r1 + #LF$
    Debug r1
    r1 = ""
    For i = 0 To methodCount - 1
      *Method = *Methods\i[i];
      Method = PeekS(sel_getName(method_getName(*Method)), -1, #PB_UTF8)
      If HidePrivate And Left(Method, 1) = "_"
        Continue
      EndIf
      r1 + "Method " + Method + #LF$
      If ShowEncoding
        r1 + " * Encoding " + PeekS(method_getTypeEncoding(*Method), -1, #PB_UTF8) + #LF$
      EndIf
      method_getReturnType(*Method, *String, 1024)
      r1 + " -- ReturnType = " + GetArgumentType(*String) + #LF$
      c = method_getNumberOfArguments(*Method)
      For n = FirstArgument To c - 1
        method_getArgumentType(*Method, n, *String, 1024)
        r1 + " -- Argument " + Str(n - FirstArgument + 1) + " = " + GetArgumentType(*String) + #LF$
      Next
      result + r1 + #LF$
      Debug r1
      r1 = ""
    Next
    r1 + "End Class" + #LF$
    result + r1 + #LF$
    Debug r1
    If *Methods
      free_(*Methods)
    EndIf
    FreeMemory(*String)
  Else
    r1 = "Object is nil" + #LF$
    result = r1
    Debug r1
  EndIf
  ProcedureReturn result
EndProcedure

; ****

;- Example

CompilerIf #PB_Compiler_IsMainFile
  
  
  ;  Define NSAffineTransform = CocoaMessage(0, 0, "NSAffineTransform transform")
  ;  DumpObjectMethods(NSAffineTransform)
  ;
  ;  Define NSWorkspace = CocoaMessage(0, 0, "NSWorkspace sharedWorkspace")
  ;  DumpObjectMethods(NSWorkspace, 1)
  ;   
  ;  Define NSApplication = CocoaMessage(0, 0, "NSApplication sharedApplication")
  ;  DumpObjectMethods(NSApplication)
  ;  DumpObjectMethods(NSApplication, 1)
  
  If OpenWindow(0, #PB_Ignore, #PB_Ignore, 800, 600, "Dump Object Methods", #PB_Window_SystemMenu)
    EditorGadget(0, 0, 0, 800, 600, #PB_Editor_ReadOnly)
    
    ;r1.s = DumpObjectMethods(GadgetID(0), 0)
    r1.s = DumpObjectMethods(GadgetID(0), 1)
    SetGadgetText(0, r1)
    
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          Break
          
      EndSelect
      
    ForEver
    
  EndIf
  
CompilerEndIf
Last edited by mk-soft on Fri Oct 06, 2023 5:16 pm, edited 18 times in total.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Dump Object Methods

Post by wilbert »

Type encodings are explained here
https://developer.apple.com/library/arc ... dings.html

You could consider using api functions to get the return type and arguments for a method one by one.
That might be easier to view compared to a string describing the return type and all arguments at once.
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
mk-soft
Always Here
Always Here
Posts: 5386
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Dump Object Methods

Post by mk-soft »

Update v1.03

Thanks Wilbert :wink:
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Dump Object Methods

Post by wilbert »

Much better. :)

It would also be nice if you could add an option to hide the methods starting with an underscore _ since they most likely are all private methods which are undocumented.

Argument 0 and 1 are hidden arguments which are the same for every objective c call.

If you have for example [NSMutableArray arrayWithCapacity:0]
Argument 0 is the object the message is send to (in this case the class NSMutableArray)
Argument 1 is the selector that was used (in this case arrayWithCapacity:)
Argument 2 is the first real argument (in this case the capacity value)
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
mk-soft
Always Here
Always Here
Posts: 5386
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Dump Object Methods

Post by mk-soft »

Update v1.04

Ok Wilbert...
Now with more parameters. :wink:
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Dump Object Methods

Post by wilbert »

Great :)

One more thing that might be worth showing is how many bytes are required for structures.
For normal types like float or int it isn't that important but for structures is can be convenient to verify the structures you are passing are of the correct size.
For example if you are dumping an object like

Code: Select all

  Define NSAffineTransform = CocoaMessage(0, 0, "NSAffineTransform transform")
  Debug DumpObjectMethods(NSAffineTransform)
If the functionality seems useful to you, add the following function to the imports

Code: Select all

NSGetSizeAndAlignment(*typePtr, *sizep, *alignp)
Once imported, you can use it in your code for example by changing your GetArgumentType procedure like this

Code: Select all

Procedure.s GetArgumentType(*String)
  Protected r1.s, arg.s, size.i
  arg = PeekS(*String, -1, #PB_UTF8)
  r1 + arg + " - "
  
  If Left(arg, 1) = "^"
    r1 + "A pointer to type of "
    arg = Mid(arg, 2)
  EndIf
  
  Select arg
    Case "c" : r1 + "A char"
    Case "i" : r1 + "An int"
    Case "s" : r1 + "A short"
    Case "l" : r1 + "A long"
    Case "q" : r1 + "A long long"
    Case "C" : r1 + "An unsigned char"
    Case "I" : r1 + "An unsigned int"
    Case "S" : r1 + "An unsigned short"
    Case "L" : r1 + "An unsigned long"
    Case "Q" : r1 + "An unsigned long long"
    Case "f" : r1 + "A float"
    Case "d" : r1 + "A double"
    Case "B" : r1 + "A C++ bool Or a C99 _Bool"
    Case "v" : r1 + "A void"
    Case "*" : r1 + "A character string (char *)"
    Case "@" : r1 + "An object (whether statically typed Or typed id)"
    Case "#" : r1 + "A class object (Class)"
    Case ":" : r1 + "A method selector (SEL)"
    Default:
      NSGetSizeAndAlignment(*String, @size, #Null)
      r1 + " [" + Str(size) + " bytes] "
  EndSelect
  
  If Right(arg, 1) = "?"
    r1 + "An unknown type (e.g. function pointer)"
  EndIf
  
  ProcedureReturn r1
  
EndProcedure
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
mk-soft
Always Here
Always Here
Posts: 5386
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Dump Object Methods

Post by mk-soft »

Update v1.06

So the output is already very helpful. So I know how to name the methods correctly and where to look in the developer help. :wink:
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Dump Object Methods

Post by wilbert »

mk-soft wrote:So the output is already very helpful. So I know how to name the methods correctly and where to look in the developer help. :wink:
It sure is :)
And it's also an easy way to see what methods PureBasic adds in its custom classes.
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
mk-soft
Always Here
Always Here
Posts: 5386
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Dump Object Methods

Post by mk-soft »

Update v1.08.1
- Get SuperClass with level (Super = 0 .. x)
- Format of output

:wink:
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
fsw
Addict
Addict
Posts: 1572
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Re: Dump Object Methods

Post by fsw »

The Dump Object Methods code doesn't as is on my MacBook with M1.
It doesn't matter if I choose the intel or Apple Silicon version of PB.
(with C backend...)

The error message is:
PureBasic - Assembler error
error: implicit declaration of function
'SYS_FastAllocateString4' is invalid in C99
[-Werror,-Wimplicit-function-declaration]
SYS_FastAllocateString4(&pb_select1,v_arg);
^
1 error generated.
macOS Monterey 12.3.1

Am I doing something wrong?
(wouldn't be the first time...)

I am to provide the public with beneficial shocks.
Alfred Hitshock
User avatar
mk-soft
Always Here
Always Here
Posts: 5386
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Dump Object Methods

Post by mk-soft »

Works on Intel with C-Backend.

Please move to Bugreport C-Backend for macOS M1 with my code.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
mk-soft
Always Here
Always Here
Posts: 5386
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Dump Object Methods

Post by mk-soft »

Update v1.08.2
- Fixed object is nil
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
mk-soft
Always Here
Always Here
Posts: 5386
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Dump Object Methods

Post by mk-soft »

Update v1.09.0
- String return value now optional
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Post Reply