The type comes from XCTest. I’m trying to enumerate Objective-C methods in 
order to use them with XCTest in the open-source Swift version of XCTest, which 
needs the tests to be supplied as this type:

/// This is a compound type used by `XCTMain` to represent tests to run. It 
combines an
/// `XCTestCase` subclass type with the list of test case methods to invoke on 
the class.
/// This type is intended to be produced by the `testCase` helper function.
/// - seealso: `testCase`
/// - seealso: `XCTMain`
public typealias XCTestCaseEntry = (testCaseClass: XCTestCase.Type, allTests: 
[(String, (XCTestCase) throws -> Void)])



Jeff Kelley

slauncha...@gmail.com | @SlaunchaMan <https://twitter.com/SlaunchaMan> | 
jeffkelley.org <http://jeffkelley.org/>
> On Nov 21, 2016, at 1:13 AM, Jacob Bandes-Storch <jtban...@gmail.com> wrote:
> 
> "throws" is the part that's not representable in Obj-C. Why are you using it? 
> If you're interacting with method_getImplementation, you need to think like 
> the Obj-C runtime.
> 
> https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtHowMessagingWorks.html#//apple_ref/doc/uid/TP40008048-CH104-SW1
>  
> <https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtHowMessagingWorks.html#//apple_ref/doc/uid/TP40008048-CH104-SW1>
> 
> This works:
> 
>     typealias DescriptionMethod = @convention(c) (NSObject, Selector) -> 
> NSString 
> 
>     let fn = 
> unsafeBitCast(method_getImplementation(class_getInstanceMethod(NSObject.self, 
> "description")), DescriptionMethod.self)
> 
>     fn(NSObject(), "description") as String
> 
> 
> Jacob
> 
> On Sun, Nov 20, 2016 at 9:41 PM, Jeff Kelley <slauncha...@gmail.com 
> <mailto:slauncha...@gmail.com>> wrote:
> Still trying on this (copied the code directly, Foo is actually XCTestCase):
> 
> typealias TestMethod = @convention(c) (XCTestCase) throws -> Void
> 
> This seagulls the compiler with “error: '(XCTestCase) throws -> Void' is not 
> representable in Objective-C, so it cannot be used with '@convention(c)’”. 
> I’m trying to use it here:
> 
> let testMethod: IMP = method_getImplementation(method)
> 
> let test: TestMethod = unsafeBitCast(testMethod,
>                                      to: TestMethod.self)
> 
> testMethods.append((methodName as String, test))
> 
> If I try to put the type directly in the call to unsafeBitCast(), the 
> compiler gives me an error:
> 
> Attribute can only be applied to types, not declarations
> 
> Thanks for your suggestions! I hadn’t seen @convention() before.
> 
> 
> Jeff Kelley
> 
> slauncha...@gmail.com <mailto:slauncha...@gmail.com> | @SlaunchaMan 
> <https://twitter.com/SlaunchaMan> | jeffkelley.org <http://jeffkelley.org/>
>> On Nov 21, 2016, at 12:08 AM, Jacob Bandes-Storch <jtban...@gmail.com 
>> <mailto:jtban...@gmail.com>> wrote:
>> 
>> For a function such as bar() above, the type you want to cast the IMP to 
>> would probably be "@convention(c) (Foo, Selector) -> ()".
>> 
>> On Sun, Nov 20, 2016 at 9:05 PM, Jeff Kelley <slauncha...@gmail.com 
>> <mailto:slauncha...@gmail.com>> wrote:
>> Thanks Jacob! I tried using unsafeBitCast, but it fails with the following: 
>> “fatal error: can't unsafeBitCast between types of different sizes”. I 
>> considered wrapping every call in a closure that calls objc_msgSend(), but 
>> alas, that’s not exposed to Swift. I have another approach in mind, so I’ll 
>> try that next.
>> 
>> 
>> Jeff Kelley
>> 
>> slauncha...@gmail.com <mailto:slauncha...@gmail.com> | @SlaunchaMan 
>> <https://twitter.com/SlaunchaMan> | jeffkelley.org <http://jeffkelley.org/>
>>> On Nov 19, 2016, at 1:58 AM, Jacob Bandes-Storch <jtban...@gmail.com 
>>> <mailto:jtban...@gmail.com>> wrote:
>>> 
>>> I imagine unsafeBitCast would be the way to go here. But are you assuming 
>>> that all of the instance methods have type "(Foo) throws -> Void" ? Or do 
>>> you somehow want to dynamically use the type information?
>>> 
>>> Jacob
>>> 
>>> On Fri, Nov 18, 2016 at 10:37 PM, Jeff Kelley via swift-users 
>>> <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
>>> Hello,
>>> 
>>>     I’m trying to enumerate the methods of a class in Swift using the 
>>> Objective-C runtime. Everything is working fine so far, except for the very 
>>> last step. Suppose I have a Swift class like this:
>>> 
>>> class Foo: SomeSuperclass {
>>>     
>>>     @objc func bar() {
>>>         print("Hello, World!")
>>>     }
>>>     
>>> }
>>> 
>>>     Using the Objective-C runtime methods, I can get the method with 
>>> class_copyMethodList and then get to the method’s implementation using 
>>> method_getImplementation. However, what I need to do next is to stick this 
>>> into a tuple that looks like this:
>>> 
>>> typealias FooEntry = (fooClass: SomeSuperclass.Type, methods: [(String, 
>>> (Foo) throws -> Void)])
>>> 
>>>     For now, the workaround is to make a static variable that returns all 
>>> of the entries:
>>> 
>>>     static var allEntries = {
>>>         return [
>>>             ("bar", bar),
>>>         ]
>>>     }
>>> 
>>>     Is there any way to go from the raw IMP that I get back from the 
>>> runtime to the Swift type so I can construct this list dynamically?
>>> 
>>> 
>>> Jeff Kelley
>>> 
>>> slauncha...@gmail.com <mailto:slauncha...@gmail.com> | @SlaunchaMan 
>>> <https://twitter.com/SlaunchaMan> | jeffkelley.org <http://jeffkelley.org/>
>>> 
>>> _______________________________________________
>>> swift-users mailing list
>>> swift-users@swift.org <mailto:swift-users@swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-users 
>>> <https://lists.swift.org/mailman/listinfo/swift-users>
>>> 
>>> 
>> 
>> 
> 
> 

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Reply via email to