Skip to content

Protocol methods missing from classes #1487

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
stuartmorgan-g opened this issue Aug 30, 2024 · 5 comments · Fixed by #1567 or #1583
Closed

Protocol methods missing from classes #1487

stuartmorgan-g opened this issue Aug 30, 2024 · 5 comments · Fixed by #1567 or #1583

Comments

@stuartmorgan-g
Copy link

(There's a bit of related discussion in #1462, but this is a distinct issue.)

I'm unable to call methods on an object that come from a protocol, even when they are required methods. The concrete case I hit is:

@interface AVAsset : NSObject <NSCopying, AVAsynchronousKeyValueLoading>
...
@end

@protocol AVAsynchronousKeyValueLoading
@required

- (AVKeyValueStatus)statusOfValueForKey:(NSString *)key error:(NSError * _Nullable * _Nullable)outError ...;

- (void)loadValuesAsynchronouslyForKeys:(NSArray<NSString *> *)keys completionHandler:(nullable void (^)(void))handler ...;
@end

In Obj-C code I can then of course call:

[asset statusOfValueForKey:@"tracks" error:nil] != AVKeyValueStatusLoaded

But that method simply doesn't exist on AVAsset in the ffigen output, even though it's an explicit part of the public interface.

@liamappelbe
Copy link
Contributor

liamappelbe commented Sep 16, 2024

Looks like we're bitten by limitations of libclang again. Traversing the children of the interface declaration cursor, I find a CXCursor_ObjCProtocolRef for each of the protocols it implements. But there's no way of getting from the CXCursor_ObjCProtocolRef to the CXCursor_ObjCProtocolDecl. The only information on the CXCursor_ObjCProtocolRef is the name of the protocol (it doesn't even have a usr ID). So the best I can do is look up the protocol by name and throw an error if there's more than one protocol declared with that name. This should cover most of the use cases at least.

Nevermind, turns out clang_getCursorDefinition works in this case. 😅

@stuartmorgan-g
Copy link
Author

Do I need to do something special in my config to pick up the protocol? I synced to the hash with that fix, and still don't have the methods described in the original issue description.

@liamappelbe liamappelbe reopened this Sep 17, 2024
@liamappelbe
Copy link
Contributor

@stuartmorgan No, you shouldn't need to do anything. Can you send me your config? I'll see if I can repro. There might be a second bug here.

@stuartmorgan-g
Copy link
Author

My actual repro case is here, but I think this should be the relevant parts (I haven't set up a clean test with this though):

name: Foo
description: Test
language: objc
output:
  bindings: 'ffi_bindings.dart'
  objc-bindings: 'ffi_bindings.dart.m'
headers:
  entry-points:
    - '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/AVFoundation.framework/Headers/AVFoundation.h'
exclude-all-by-default: true
objc-interfaces:
  include:
    - 'AVAudioSession'
    - 'AVMutableVideoCompositionInstruction'
    - 'AVMutableVideoCompositionLayerInstruction'
    - 'AVPlayer'
    - 'AVPlayerLayer'
enums:
  include:
    - 'AVAudioSessionCategoryOptions'

@liamappelbe
Copy link
Contributor

Ah ok. The issue is that the protocol is not being included by the config. I think probably the correct behavior here is that protocols that an interface conforms to should always be included in the interface's methods, regardless of the filters (or rather they should go through the same method filtering as ordinary methods). But we should only generate bindings for the protocol itself if the protocol is included in the filter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
2 participants