Last active
October 26, 2023 01:25
-
-
Save SKaplanOfficial/6d7ce9b07488ca71aaa463f3f3f8b5c7 to your computer and use it in GitHub Desktop.
JXA/ASObjC script to briefly summarize methods and properties of an Objective-C class using objc runtime methods (e.g. class_copyMethodList, method_getTypeEncoding, etc.). The script reports method names, the number of arguments they accept, the argument types, property names, property types, and property attributes such as read-only and nonatomic.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(() => { | |
ObjC.import('objc'); | |
ObjC.import('AppKit') | |
// Get methods of ObjC class, store # of methods and properties in reference objects | |
const targetClass = $.NSImage; | |
const num_methods = Ref(); | |
const num_properties = Ref(); | |
const methods = $.class_copyMethodList(targetClass, num_methods); | |
const properties = $.class_copyPropertyList(targetClass, num_properties) | |
// Log name and argument info of each method | |
console.log(num_methods[0], "Methods:"); | |
for (let i=0; i<num_methods[0]; i++) { | |
const method = methods[i]; | |
console.log("\t", $.method_getName(method)); | |
console.log("\t\tType Encoding:", $.method_getTypeEncoding(method)); | |
console.log("\t\tArg Count:", $.method_getNumberOfArguments(method)); | |
} | |
// ObjC property type encodings | |
const typeEncodings = { | |
"Tc": "char", | |
"Ti": "int", | |
"Ts": "short", | |
"Tl": "long", | |
"Tq": "long long", | |
"TC": "unsigned char", | |
"TI": "unsigned int", | |
"TS": "unsigned short", | |
"TL": "unsigned long", | |
"TQ": "unsigned long long", | |
"Tf": "float", | |
"Td": "double", | |
"TB": "bool", | |
"Tv": "void", | |
"T*": "char string", | |
"T@": "object", | |
"T#": "Class", | |
"T:": "Selector", | |
"T[": "array", | |
"T{": "structure", | |
"T(": "union", | |
"Tb": "bit field", | |
"T^": "pointer", | |
"T?": "unknown" | |
}; | |
// Log name and attribute info of each property | |
console.log("\n"); | |
console.log(num_properties[0], "Properties:"); | |
for (let i=0; i<num_properties[0]; i++) { | |
const method = properties[i]; | |
console.log("\t", $.property_getName(method)); | |
const attributeString = $.property_getAttributes(method) | |
let attributeSummary = ""; | |
// Format the type nicely | |
const typeEncoding = attributeString.split(/(,| )/g)[0] | |
attributeSummary += typeEncodings[typeEncoding.slice(0,2)] | |
if (typeEncoding.length > 2) { | |
const data = typeEncoding.slice(2).replaceAll(/("|\)|]|{|}|<|>|=.*)/g, "") | |
attributeSummary += ` (${data})` | |
} | |
// Add attribute descriptions | |
if (attributeString.includes(",R")) attributeSummary += ", readonly" | |
if (attributeString.includes(",C")) attributeSummary += ", copy" | |
if (attributeString.includes(",&")) attributeSummary += ", retain" | |
if (attributeString.includes(",N")) attributeSummary += ", nonatomic" | |
if (attributeString.includes(",G")) attributeSummary += ", getter" | |
if (attributeString.includes(",S")) attributeSummary += ", setter" | |
if (attributeString.includes(",D")) attributeSummary += ", dynamic" | |
if (attributeString.includes(",W")) attributeSummary += ", weak" | |
if (attributeString.includes(",P")) attributeSummary += ", eligible for garbage collection" | |
console.log("\t\t", attributeSummary); | |
} | |
})() | |
/* Output for NSImage: */ | |
/* 256 Methods: */ | |
/* tintedImageWithColor:operation: */ | |
/* Type Encoding: @32@0:8@16Q24 */ | |
/* Arg Count: 4 */ | |
/* resizeTo: */ | |
/* Type Encoding: @24@0:8d16 */ | |
/* Arg Count: 3 */ | |
/* ... | |
/* ... | |
*/ | |
/* 42 Properties: */ | |
/* ik_fullResolutionFileURL */ | |
/* object (NSURL), retain, nonatomic */ | |
/* ikProfilePictureAttributedImageName */ | |
/* object (NSString), copy, nonatomic */ | |
/* CGImage */ | |
/* pointer (CGImage), readonly, nonatomic */ | |
/* vk_imageView */ | |
/* object (NSImageView), readonly, nonatomic */ | |
/* willProvideAdaptedImageForPresentation */ | |
/* bool, readonly */ | |
/* ... | |
/* ... | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment