-
Notifications
You must be signed in to change notification settings - Fork 168
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
Support Bindgen opt-in list #6639
Conversation
@elle-j Just to be sure, with this we are giving a way for sdk to define which part of the whole spec they need? So instead of creating bindings for everything it will create bindings only for methods/properties in the opt-in file? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice work
} | ||
|
||
addField(field: Field) { | ||
assert(!(field.name in this._fields), `Duplicate field name on record/struct '${this.name}': '${field.name}'.`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm pretty sure it is impossible[1] to express duplicate fields in the spec file syntax right now, but I suppose it is fine to leave it incase that changes.
[1] You could have duplicates in the spec.yaml file, but the yaml spec requires that keys in a mapping are unique, so such a file isn't valid yaml. And even if the yaml parser doesn't detect that, since it parses into a Plain Old JS Object, any later field will completely replace the prior duplicate, so by the time you get to this code, you won't have any trace of the in-file duplication.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point!
@papafe, yes that's correct. I've added this to the description now, thanks! |
My initial assumption, was that the part of the spec not opted into, would be completely left out of the parsed spec, this would make it simpler for the generator as it doesn't have to check for the I'm curious if you actively choose "opt-in" instead of "allow", "include" or "expose"? |
@@ -16,12 +16,13 @@ | |||
// | |||
//////////////////////////////////////////////////////////////////////////// | |||
|
|||
import { Spec } from "./spec"; | |||
import { OptInSpec, Spec } from "./spec"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Starting a thread here to facilitate discussing this previous comment from @kraenhansen:
(A) My initial assumption, was that the part of the spec not opted into, would be completely left out of the parsed spec, this would make it simpler for the generator as it doesn't have to check for the isOptedInTo.
I'm curious if you thought about that approach and if yes, why you didn't choose to go that route?(B) I'm curious if you actively choose "opt-in" instead of "allow", "include" or "expose"?
I personally think isAllowed, isIncluded or isExposed might make equal amount of sense and be more direct.
Regarding (A), we may want to handle the isOptedInTo
differently. For instance, currently in our TS template (see RealmJS PR) we add deprecation annotations to the generated types with a message saying what to add to the opt-in list to be able to use it. This way we can still see the available methods and props when working with the binding
, rather than switching to the spec to see if it's available. What's your take on this?
Regarding (B), there were some discussions regarding the word "allow" and how it may be ambiguous in the sense that everything in the general spec is essentially allowed (and I guess "exposed" as well) to be used. "included" is also on the table and the current name "opt-in" is definitely easy to change 👍 I thought it made the intent a bit clearer than the other alternatives, but I'm very open to changing it to something that everyone finds suitable 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's your take on this?
I agree that seems valuable 👍
a bit clearer than the other alternatives
My main gripe is that "opt-in" is two words and "opted in to" is three 🙈 But ... I'm not strongly opposed 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the input, I'll leave the conversation unresolved for now to see if others want to weigh in on this 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a slight preference for "includeList"/"isIncluded", but not enough to overrule the patch author. Just stating my preference in case it comes to a vote.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for preparing the path of other SDKs to adopt the binding generator!
@nhachicha, do you mean if there's an option to only list things to exclude rather than include? If so, then no, at least not at this time. Everything is excluded by default and needs to be explicitly opted in to via the opt-in list. The main reason for this is to be able to add things to the general spec in Core without silently adding it to all consumers of the spec as well. So for the commented out parts of your diff example, you'd just not include them in the opt-in list 👍 (You could start by copying the Realm JS opt-in list. It includes most things of the general spec but not everything. There's also an earlier commit that includes everything from the general spec before removing unused parts if that's more helpful for you.) Does this answer your question? |
@nhachicha You can always do your own skipping in the template file if you need to. This is just attempting to bake in a particularly common form into the bindgen lib, but since each generator is Just Code, you are free to do whatever logic you need there. That said we considered adding something that would help with this case, but decided not to add it at this time. Right now we only support a single opt-in yaml file, but we could fairly easily add support for multiple yaml files. That would allow 1 file for "realm-js common" stuff used by all engines, as well as an engine-specific file. We weren't sure if any other SDKs would need this, and the space savings for JS would be minimal, so we decided to do the simplest thing for now. We can revisit that decision once the main functionality lands. |
This makes sense. WASM target will use the Opt-in approach for now 👍 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please revert c985657. Other than that, LGTM
@@ -16,12 +16,13 @@ | |||
// | |||
//////////////////////////////////////////////////////////////////////////// | |||
|
|||
import { Spec } from "./spec"; | |||
import { OptInSpec, Spec } from "./spec"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a slight preference for "includeList"/"isIncluded", but not enough to overrule the patch author. Just stating my preference in case it comes to a vote.
I know you've sunk a great deal of time in this already, but I just realised that a lot of the code could perhaps be simplified if we just included an optional |
@kraenhansen, as we discussed on Slack, I'll go ahead and note your suggestion as a potential change for an upcoming iteration and merge this as is 👍 |
We'll instead have the binding generator generate the opt-in spec schema file from spec.yaml in order to list all classes and records with their corresponding methods and fields. The validation would then also provide autocomplete in the opt-in spec file.
3bca1cc
to
3b888b4
Compare
* Add initial support for a Bindgen opt-in list. * Update CMakeLists with opt-in option. * Move calling of 'bindModel()' to Bindgen. * Remove 'Readonly' return types from getters. * Add comment to 'opt in' command option. * Move logic of applying the opt-in list and require consumers to invoke it. * Update doc comments. * Validate parsed yaml file. * Update name in 'OptInSpec' type. * Revert 'Validate parsed yaml file'. We'll instead have the binding generator generate the opt-in spec schema file from spec.yaml in order to list all classes and records with their corresponding methods and fields. The validation would then also provide autocomplete in the opt-in spec file. * Update pointer to 'external/catch'. * Update error message for missing method/field.
What, How & Why?
Adds initial support for an opt-in list for the Bindgen spec. This allows SDKs to use only some of the classes and records/structs of the general spec and generate bindings only for the items in the opt-in list.
Added Behavior:
realm-bindgen
command now accepts an optional--opt-in
option specifying the path of the opt-in list.# Command line realm-bindgen --opt-in path/to/opt/in/spec.yml
records
along with theirfields
(names).classes
along with theirmethods
(unique names).SDK Requirements:
generate()
function will receive aBoundSpec
containing all of the entries of the general spec.BoundSpec
, the SDK is responsible for calling the instance methodBoundSpec.applyOptInList()
if an opt-in list was provided.BoundSpec
that also appear in the opt-in list will have the propertyisOptedInTo = true
, otherwise it will be set tofalse
.Updated Type:
generate()
function accepts an object as an argument which now also contains theBoundSpec
.SDK Usage Examples:
Example using CMake:
bindgen()
function for each of your templates inCMakeLists.txt
, pass the path of the opt-in list.Example of the
generate()
function:BoundSpec
have anisOptedInTo
boolean property that the consumer can handle accordingly.Potential Additions in Upcoming Iterations:
isOptedInTo
on the bound class/record itself so that it can be assignedfalse
if omitted.☑️ ToDos