-
Notifications
You must be signed in to change notification settings - Fork 44
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
[jnigen][ffigen] Standardize filtering policy #1678
Comments
I've been giving this some thought over the past couple of weeks; I don't think either is the ideal model, but my ideal would be much closer to jnigen's ffigen's transitive behavior creates truly enormous files, which caused me no end of problems:
jnigen's approach made files that felt reasonable to read/navigate as a human, and didn't cause any tooling problems. There are a couple of issues (some of which I've filed issues for):
What I think I'd like to see for both is something that has ffigen-style upward transitive inclusion, but jnigen-style pruning for everything else, but (and maybe this is what you mean by "a stub in future") instead of replacing non-included classes with |
Something we could consider if this ends up being a usability problem is an optional mode to do current-ffigen-style exhaustive generation (although we still have the unnecessary-broken-generation problem to contend with there). I could imagine a workflow where you start with exhaustive generation once, write your Dart code, and then look at everything you used to generate a config for what you ended up needing and that being what you check in (and iterate on if/when you change the code). Incremental small additions would likely be easier than the initial process of finding all the things you need to start. If we wanted to get really fancy, in theory it seems like we could build a tool that would analyze the code a client has written to see what it uses, and then automatically generate a tight-bound config file from it. That would be very cool, but not necessarily worth the eng effort depending on how complex it would be in practice. (I will say that in practice, I had to do a lot of incremental generation with |
SGTM! @HosseinYousefi is this what you're planning to do in jnigen? We should try and make the behavior as similar as possible.
// <Foo's API documentation, if any>
class Foo extends objc.NSObject {
// NOTE: This class is a stub. To generate its methods, add Foo to your config's includes.
}
Yeah, I'll definitely make this behavior a config option (for backwards compatibility, and because the current behavior works well for C bindings). But one thing I want to do is make some helper functions for constructing configs for ffigen's Dart API. We're at a stage now with the config yaml where the defaults are tuned for C bindings, and for ObjC we have a whole bunch of recommended options. So it'd be good to have helper functions that generate configs for specific use cases. In that case I'd enable the new behavior by default in the ObjC helper. |
That makes sense. I will address this.
I'm with you, that's why I had opened #642.
That's a fantastic idea and actually we need to do something similar to this to prune the native code, in case of jnigen, in form of generating proguard-rules: #681.
Yep, sgtm! |
If they have ever actually explicitly made something of type I'm not sure the use case of "I want to store a
My question/concern there is whether people find that comment easily enough. In particular I'm thinking about someone trying to figure out why some methods are in the autocomplete list on an instance of One of my biggest usability concerns of the *gen tools as compared to Pigeon is that with Pigeon, I explicitly write a simple interface definition, and the output is entirely predictable, so I'm not surprised when I go to interact with the generated code, whereas with *gen there's a ton of complex output that can't be trivially predicted from the config I write, so I keep hitting surprises, and then trying to figure out if it's because:
Because of that, my default position is to err on the side of making stubs really obvious. Maybe I'm overly concerned about this and it would be fine with that comment though; we'd probably need to do some user studies to actually find out. |
+1. /// WARNING: This class is a stub, to actually generate it run
/// `dart run jnigen:add_class 'baz.bar.Foo' --config <the path to your jnigen.yaml>`.
///
/// ... the rest of the doc comment ...
// Maybe a `@stub` annotation that shows a lint as well?
class Foo extends JObject { /* ... */ } And also add a |
The ObjC side of this is done. @HosseinYousefi can we close this issue? Are you using this to track the feature, or do you have separate bugs for your side? |
I'm using this to track it. (Since you had tagged both, I didn't create another issue) |
In ffigen, when an API element is included by the config, all its transitive deps are also included. Eg, if the user asks for a class to be generated (and doesn't filter the methods), we generate bindings for all the methods and all the classes consumed or returned by those methods.
In jnigen, transitive deps are not included by default. Instead, if a method refers to a class that hasn't been explicitly requested by the user, it will be replaced by a
JObject
(or maybe a stub in future).We should settle on one approach. I'm about to refactor ffigen's filtering, so now is a good time to think about it.
@stuartmorgan Any opinions about which has been easier?
The text was updated successfully, but these errors were encountered: