-
Notifications
You must be signed in to change notification settings - Fork 241
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
refactor: disentangle bindgen extractor logic (continued) #1025
refactor: disentangle bindgen extractor logic (continued) #1025
Conversation
As there was only the mod.rs file remaining in the `visitor` submodule, I removed `visitor/mod.rs` and replaced it with `visitor.rs`.
@agostbiro I have not reviewed the code yet, but I checked that buildkite CI fails due to Cargo.lock files in examples being not up-to-date ( |
Thanks @frol , I committed the updated Cargo.lock files in 6637e59 and the CI passes 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.
Thank you for such clear and self-contained commits; reviewing your PR was a pleasure!
Your approach to polymorphism makes a lot more sense, thank you for looking into it and writing up your thoughts. It's a shame we lose per-kind data structures that only contain the fields each kind actually needs (writing that part is what made me question what can be private/payable etc, which I see as a benefit for code transparency) and I don't know if removing some code duplication was worth losing it, but regardless I don't hold a strong opinion here and happy to go with what is already in the PR.
A reviewer in #890 #890 (comment) that private view functions shouldn't be allowed. This wasn't implemented in #890 and when I made the change several tests failed, because methods that take &self as argument are considered private.
I think you meant that methods that take &self
argument are considered view, right? So, as @austinabell mentioned in the original PR, view methods can never be private. That being said, the current near_bindgen
API is flawed in that it does not provide clear control of which methods are view
or call
. There are a couple of ways we could resolve this that we have discussed in the past but never :
- Make
private
,payable
and other such modifiers automatically mean that this method iscall
- Create
#[call]
and#[view]
modifiers and slowly phase out the oldself
-based deduction system - Just leave everything as is, it has been working so far
In any case, probably out of scope for this PR, just though I would share this here since its related to the work you are doing. I propose we do not prohibit private view functions for now and move this conversation to a separate issue.
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.
@agostbiro This PR looks great to me. Only one nit comment is left, but overall once CI is green, I will be happy to merge it (the comment can be addressed in a separate PR)
The Buildkite CI failed on the last commit with this error:
The same Buildkite job succeeded on the previous commit and the only difference between the two is just a comment, so I'm thinking this is likely a transient problem. Is there any way we can trigger the job to run again in Buildkite? |
@agostbiro I have re-run the job, should be good now |
Hi,
As discussed with @frol I took over #890 and continued it here.
Thanks for all the great work prior @itegulov ! I really appreciate your refactoring after making a small change in related code yesterday.
TODOs
There were the following unresolved questions in #890 :
build
can be made more idiomatic.handles_result
andvisit_result
relate.Polymorphism
When looking at the trait object based polymorphism approach I noticed that there is some repetition in the trait implementations. I initially tried to resolve this by providing default implementations, but then realized that the combinations of shared code are not amenable to this. Specifically, given the three kinds of methods (call, view, init), there were no trait method with more than two differing implementations, but how the the the three methods are split into two groups varies.
For this reason, I switched from a trait based approach to an enum based approach, where there is just one visitor object (as opposed to three visitor objects for each method kind implementing a trait). The methods of this single visitor object match on an enum to alter their behavior based on an internal tag that determines the method kind that the visitor object represents.
For example I changed
to
I found that this approach significantly reduced the code size and I found it easier to check the rules for a specific attribute as it's all in one function. It also makes it possible for the
build
method to takeself
by value which was brought up in the review for #890.The downside is that all the parsed data is now in a single internal data structure even though not all methods need all fields from it which is not so clean. In contrast, with the trait based approach each method kind visitor had its own parsed data structure holding only the data the variant supports. I don't think the single parsed data structure should cause problems in practice, because a visitor method errors if it's called on a variant that doesn't support it.
I'm curious to hear what you think about this approach! Happy to adjust it. The change is done in f6ab89d.
handles_result
andvisit_result
A review in #890 asked whether
visit_result
needs to be called whenhandles_result
is visited.Visiting
handles_result
was not part of the visitor yet, so I added a method calledvisit_handles_result
for it in 3e843b0. I later renamed fromvisit_handles_result
tovisit_handle_result_attr
in 76be952 for consistency.I noticed a potential for confusion based on the method name so I renamed
visit_result
tovisit_return_type
in 83534ed which is more accurate.When calling
visit_return_type
there was a potential for error, because it needs to be called afterhandles_result
is set for correct behavior. I resolved this by merging the build step and thevisit_return_type
step since there is only ever one return type and calling it inbuild
ensures that it's called last.Private view functions
A reviewer in #890 commented that private view functions shouldn't be allowed. This wasn't implemented in #890 and when I made the change several tests failed, because methods that take
&self
as argument are consideredprivateview. Example failing test case:On a related note, at first I was surprised that methods that take
self
by value are view, but I guess that it makes sense since they cannot mutate the object. As I haven't found a test case for this I added one to make sure thatmethod(self)
isn't payable in 56394ec.Next steps