Skip to content
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

🐛 zx: Prevent collisions between methods, signals and properties #722

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

bachp
Copy link
Contributor

@bachp bachp commented Apr 17, 2024

Prevent collisons by adding an explicit suffix to properties and signals.

If a collision is detected a _ is added to the identifier until there is no more collision.

Closes:

zbus_xmlgen/src/lib.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@zeenix zeenix left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks so much for contributing this PR and also to follow our dev practices from the start. However, I think a good solution here would require more work than changing all generated names.

@bachp bachp requested a review from zeenix April 18, 2024 19:09
Copy link
Contributor

@zeenix zeenix left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM otherwise.

Comment on lines 197 to 198
let name = collision_hander
.avoid_collision(to_identifier(&to_snakecase(signal.name().as_str())));
Copy link
Contributor

@zeenix zeenix Apr 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the 2 steps should be combined into one. We don't really need a separate type for name collision, just one for creating identifiers, that ensures that the identifier isn't already used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First I also tought this, but the to_identifier is also used in other places, eg. function parameters, and they don't collide with signals and properties. but

I could move the to_identifier function inside the avoid_collision but I thought this was it is more explict

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was just wondering if there is a case where we also have collisions in arguments?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First I also tought this

Ah, you're ahead of me. :)

I could move the to_identifier function inside the avoid_collision but I thought this was it is more explict

Or you could have the new API use to_identifier itself so that caller doesn't need to care. I'd call the type UniqueNameGenerator and method identifier_for_name, which takes the name as arg, also taking care of to_snakecase. You can suggest a better name, just don't like collision in the name (sounds negative 😆).

I was just wondering if there is a case where we also have collisions in arguments?

Doubtful but even if there was, it won't be global (i-e args of different methods can have the same name).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried severl variants of combining operations. In the end I found it's best to keep the operations separate so I can combine these in the different cases:

  • Functions and signals i need to_snakecase, to_identifier and make_unique
  • For Properties I need to_snakecase, to_identifier, and I need make_unique as a separate operation depending on read or write case.
  • For arguments I only need to_identifier, optionally we could apply make_unique per function here but I don't see this needed.

So my solution now is to just rename the CollisionHandler to Idenfifier and have a make_unique method.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Functions and signals i need to_snakecase, to_identifier and make_unique

As I wrote, it would be best to just abstract it all. The caller should just ask for a unique identifier for the name and that's it.

  • For Properties I need to_snakecase, to_identifier, and I need make_unique as a separate operation depending on read or write case.

From what I can tell from your commit, it's basically doing the same thing. Of course, it would make sense to have a separate API for properties in UniqueNameGenerator, e.g property_getter and property_setter (or it could just be property with a boolean arg that tells the direction. Then identifier_for_name could just be method.

  • For arguments I only need to_identifier, optionally we could apply make_unique per function here but I don't see this needed.

👍

Copy link
Contributor Author

@bachp bachp Apr 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure what you are asking now.

As I see it the current implementation has several functions/methods (to_snakecase, to_identifier and make_unique) that can be combined ot form the final identifier.

The rules how these need to be combined for the different cases are applied locally where the element (method, property, signal and arguments) are processed.

The way I understand your proposal is to put the rules how to combine these into separate functions/methods and just call them, e.g. to_method,to_signal, to_property and to_argument? While I can do that I'm not convinced it is a good idea as it basically splits the rules into two locations.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way I understand your proposal is to put the rules how to combine these into separate functions/methods and just call them, e.g. to_method,to_signal, to_property and to_argument

At the very least, it should have been clear, which names I proposed. :)

While I can do that I'm not convinced it is a good idea as it basically splits the rules into two locations.

How so? They'll do pretty much the same thing as you're doing right now, just in one place/type. They will all use to_snakecase and to_identifier, for example.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me know, if you'd want me to make the proposed changes in a separate commit on top.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a test with these changes and the NetworkManager dbus xml, and it doesn't solve all the conflicts. I need to dig a bit deeper. I think I will add a test case using the NetworkManager interface description to make the issue more reproducible.

If a collision is detected and additional `_` is appended to the
identifier until there is no more collision.

Signed-off-by: Pascal Bach <[email protected]>
@bachp bachp requested a review from zeenix April 20, 2024 07:02
@zeenix
Copy link
Contributor

zeenix commented Jun 15, 2024

@bachp oh I'm so sorry. I never got a notification that you requested a review after updating the pr. I'll look into this very soon.

Thanks for your patience. 🙏

@bachp
Copy link
Contributor Author

bachp commented Jun 15, 2024

@zeenix As mentioned in #722 (comment) my change didn't completely solve the issue with the networkmanager dbus specification. Unfortunately I was busy with other things.

I want to add a test based on the real world example, not sure when I will get to it tough.

@zeenix
Copy link
Contributor

zeenix commented Jul 11, 2024

@bachp i hope you've not forgotten about your existing PR. 😉

@bachp
Copy link
Contributor Author

bachp commented Jul 11, 2024

@zeenix No I did not but I ran into other issues while trying to interact with network manager, mainly #312 which is more of a blocker for me.I will come back to this once I found a solution for the more blocking issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants