dart-lang / native

Dart packages related to FFI and native assets bundling.
BSD 3-Clause "New" or "Revised" License
115 stars 40 forks source link

[ffigen] Improve handling of ObjC method families and retention annotations #1446

Closed liamappelbe closed 1 week ago

liamappelbe commented 3 weeks ago

To deduce whether an ObjC method returns a retained reference or not, we use a combination of method family detection and annotations. But our support for this is incomplete, and misses a few edge cases. The full docs are here.

Specifically, the method family detection rules are slightly more complicated than what we've implemented, we're not handling the annotations that can alter the method family, and we're only handling the NS_RETURNS_RETAINED annotation (the other annotations can opt-out a method that is supposed to return retained due to its method family).

We're also not handling the argument consumption annotations, or the consumes self annotation.

Finally, all these rules (except method families) should also apply to blocks.

Follow up to #1441

dcharkes commented 3 weeks ago

https://clang.llvm.org/docs/AutomaticReferenceCounting.html

That was an interesting read! I was rather surprised that method names automatically apply families. Lot's of magic in the name or conciseness.

liamappelbe commented 2 weeks ago

The objc_method_family annotation is not exposed in libclang, so I'll ignore it for now. It seems pretty obscure anyway.

liamappelbe commented 1 week ago

Finally, all these rules (except method families) should also apply to blocks.

Unfortunately libclang doesn't seem to have a way of accessing __attribute__((ns_returns_retained)) and __attribute__((ns_consumed)) annotations on blocks.

For methods and top level functions, these annotations are on the CXCursor of the declaration, but for blocks I only have a CXType with no declaration cursor. If I annotate a block with NS_RETURNS_RETAINED, the CXType's kind changes from FunctionProto to Unexposed. If I annotate it with __attribute__((ns_returns_retained)) the kind changes to Attributed, which is a bit more promising, but I can't find a way of getting the attribute. If I annotate one of the args with __attribute__((ns_consumed)), nothing happens at all.

I'll fix what bugs I can, and leave parsing these attributes as follow up work: #1490