Skip to content

Figure out and document (a) pattern(s) for handling #if #1589

Open
@stuartmorgan

Description

This is a high-level issue for general tracking, since it's a topic I'm sure we'll need at least some solution to, even if it's docs. Maybe we will identify specific use cases that we can split out into sub-issues to address in specific ways, but we will need some way of answering a user with the question "What do I do about this #if/#ifdef when I'm trying to use FFI?"

There are lots of potential use cases; here are a couple of concrete ones to provide a starting point:

  1. I have a plugin that is 95+% shared iOS/macOS code, and I'm trying to convert it from Obj-C to FFI. The code that's not shared is behind a platform #if check. What's the right way to handle that in Dart? For now, I changed it to a Platform runtime check, but that's objectively worse: in the native version, if I accidentally try to use an iOS API in the macOS codepath, the code won't compile. In the Dart version, my IDE will happily auto-complete APIs that I can't actually use, without even a warning, and the code will crash at runtime, and only (I think?) once I hit that code. Can we do better?

  2. WKWebView has the following definition:

    #if TARGET_OS_IPHONE
    WK_EXTERN API_AVAILABLE(macos(10.10), ios(8.0))
    @interface WKWebView : UIView
    #else
    WK_EXTERN API_AVAILABLE(macos(10.10), ios(8.0))
    @interface WKWebView : NSView
    #endif 

    What should ffigen even create here? Is there any good option? The general case of this can get arbitrarily complicated; e.g., if the answer to the first question is that it inherits from some franken-class that is a mashup of NSView and UIView so that I can get any method I need, what happens if there's a collision between methods (e.g., each has a method with the same name but a different return type—a plausible scenario since methods called view that return the platform view type are common, for example). Or do we recommend putting everything behind a more FFI-friendly native facade in a case like this?

(#1469 touched on this slightly, but was specifically about the generation of code that did not compile, rather than the overall use case.)

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions