SwiftScripting icon indicating copy to clipboard operation
SwiftScripting copied to clipboard

Bug: Functions lack return values on Mojave / Xcode 10

Open bdkjones opened this issue 5 years ago • 16 comments

Here is part of Finder.h generated in Objective-C, following Apple's usual instructions:

screen shot 2018-10-03 at 16 41 25

And here is what gets generated for the Swift API:

screen shot 2018-10-03 at 16 47 41

The Issue

Notice that in the ObjC version, -items returns an SBElementArray of FinderItem objects. In the Swift version, items() returns void. This is not correct and completely breaks the API.

Manually changing the Swift file to:

@objc optional func items() -> SBElementArray

Causes items() to return the expected value, which can then be used. I do not see how a void return can be appropriate here and believe this is a bug with the scripts translating the sdef into Swift.

bdkjones avatar Oct 04 '18 00:10 bdkjones

Hello, and thank you for checking out SwiftScripting.

The Xcode command line tools need to be installed for the sbhc.py script to work properly.

You can issue the command xcode-select --install in a Terminal window to initiate installation of the command line tools.

tingraldi avatar Oct 04 '18 02:10 tingraldi

Thanks for the quick reply! I have installed the command line tools, but that makes no difference. I've spent some time diving into the issue by adding some logging to sbhc.py and here's what I'm seeing:

screen shot 2018-10-03 at 19 18 09

emit_fuction walks the children property of the cursor we pass in, and then looks for one that does not have the "parameter" type. I log all the children and you can see that items has none. The only children that appear are parameters. So it would seem that return_type will never be anything but nil.

Attempting to log the kind property of result_type shows everything to have an INVALID return type.

Question:

Have you tested the script using Xcode 10 and Mojave? That's what I'm running on. I have not tried Xcode 9 and High Sierra.

bdkjones avatar Oct 04 '18 02:10 bdkjones

I'm also curious about anyone's experience with Xcode 10 & Mojave. I have an app using Scripting Bridge that worked fine on High Sierra but on Mojave the Scripting Bridge code compiles but doesn't do anything. I think it has something to do with the new security restrictions in 10.14. Haven't tackled fixing it yet but anyone else run into this and find a solution?

I've run through all the obvious stuff like adding the app to the various categories in the Security pane of System Preferences, etc. Strangely, the OS is not popping up the permission request dialog like most other apps will when they try to script another app.

orchetect avatar Oct 04 '18 02:10 orchetect

@orchetect That's a different issue. Have you enabled the new Hardened Runtime for your app and granted the AppleEvents entitlement? You'll also need to add some specific keys to your info.plist file or the app will crash the first time you ask for permission to send an AppleEvent. (See the WWDC session video about it.)

bdkjones avatar Oct 04 '18 02:10 bdkjones

@bdkjones Thanks for the tip. I did watch some of the new Apple videos on this topic but that wasn't mentioned.

orchetect avatar Oct 04 '18 02:10 orchetect

@orchetect They spent a good while on it in the session about modern security and securing your app.

bdkjones avatar Oct 04 '18 02:10 bdkjones

@bdkjones Bingo. Works now after adding entitlements and plist entries.

Re: your original post - that's a good idea. I haven't tested the script on Mojave yet but I remember even on Sierra I ran into problems that required a fair amount of hand-editing of the resulting output. And if I recall the script wasn't even working (some or all of the time). But I figured out what needed to go where.

orchetect avatar Oct 04 '18 03:10 orchetect

Well, I'm making progress. I went back to High Sierra and Xcode 9.4.1. When I ran pip install clang I got version 6.0.0. This threw an error about a missing symbol. So, I ran pip install clang==3.5 and then ran it again. This is the output:

screen shot 2018-10-03 at 8 35 06 pm

Notice that the return values ARE now listed as children of each cursor. I'm going to try Mojave with Clang 3.5 and see if I can get the same result.

bdkjones avatar Oct 04 '18 03:10 bdkjones

Back on Mojave, with Xcode 10 and clang 3.5, I get this output:

screen shot 2018-10-03 at 20 42 12

It would appear that something has changed in Clang?

bdkjones avatar Oct 04 '18 03:10 bdkjones

This is the extent of my abilities in Python, so I'm unable to take this farther. I can simply confirm that Xcode 10 on Mojave breaks the script, even when using the older clang python bindings. I'd love to see a fix!

bdkjones avatar Oct 04 '18 03:10 bdkjones

I'm motivated to fix the issue, but without a deep understanding of Clang's inner workings, I've had to enlist help. Hopefully somebody can figure out what's changed:

https://stackoverflow.com/questions/52640399/libclang-python-binding-get-objc-method-return-value

bdkjones avatar Oct 04 '18 06:10 bdkjones

@tingraldi any ideas of what I should try? Happy to play around some more.

bdkjones avatar Oct 04 '18 17:10 bdkjones

@bdkjones I haven't yet made the leap to Mojave. I don't have any tips off the top of my head to get past this issue. I hope to get on Mojave before too long. If the Scripting Bridge is still viable there, we should be able to move forward.

tingraldi avatar Oct 05 '18 02:10 tingraldi

@tingraldi Ha! Has it ever really been viable? Tolerable, maybe. Infuriating, definitely.

I sent an email to the Clang mailing list asking for their help. One guy who worked on the Python bindings replied and said he might take a look. I'm thinking something either (A) changed or (B) broke in Clang 10.0.0.0, which is the version shipped with Xcode 10. I've gone all the way up to the translation unit and logged every single cursor and every property/child I can get for each one: nothing turns up an ObjC return type.

I'm giving it some time to see what the mailing list comes up with, but all I can think to do is ask the cursor for its location in the source file and then go manually pull any alphanumeric characters that appear in a - ( ) wrapper, up to the first NON-alphanumeric character, which eliminates the * and things like NSArray<NSString *> * etc.

bdkjones avatar Oct 05 '18 03:10 bdkjones

@bdkjones @tingraldi @orchetect

This should be solved by now either "with time" either with this PR

I wasn't able to reproduce the issue.

adam-rocska avatar Feb 20 '21 18:02 adam-rocska

Excellent! Once @tingraldi merges that PR I’ll give it a shot and report back.

bdkjones avatar Feb 20 '21 19:02 bdkjones