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

Parse inherit names with quotes #107

Closed
wants to merge 4 commits into from
Closed

Conversation

Lucus16
Copy link
Contributor

@Lucus16 Lucus16 commented Oct 21, 2022

  • CHANGELOG
  • simplify names elsewhere
  • check if comments are moved correctly

@Lucus16 Lucus16 force-pushed the parse-quoted-inherit branch 2 times, most recently from adbb326 to 4652cca Compare October 21, 2022 10:33
@Enzime
Copy link
Member

Enzime commented May 29, 2023

I just rebased this and it still works, is there any plans on merging this PR?

Also I was just wondering, would fixing #97 be a part of this PR or is it a separate piece of work?

@piegamesde
Copy link
Member

As far as I can tell, fancyIdentifier should not be necessary. Instead, all inherits should use selector Nothing. I am pretty sure the parsing of inherit and binder paths is identical. This can also be reflected in the Binder type, where the [Leaf] can be replaced by [SimpleSelector]

@Lucus16
Copy link
Contributor Author

Lucus16 commented Oct 10, 2023

I added some tests that indicate why fancyIdentifier exists and intentionally has different behavior from selector Nothing. The fact that ${"foo"} and "in" are supported in inherit statements at all is due to an upstream Nix parser quirk. It only works for static interpolations, not for ones that are actually a computation.

@piegamesde
Copy link
Member

I took the freedom to rebase onto master. Code looks good to me, so I'm inclined to merge

@piegamesde
Copy link
Member

What does "simplify names elsewhere" and "check if comments are moved correctly" mean exactly? And is this a merge blocker?

@Lucus16
Copy link
Contributor Author

Lucus16 commented Oct 14, 2023

This PR simplifies fancy identifiers that are fancy for no reason: In inherit expressions, ${"foo"} and "foo" can and should just be written as foo and this PR fixes that. I guess I wanted to check if there are other places where I should make the same simplifications. It's not a blocker.

As for moving comments correctly, when simplifying those names, the tokens that used to be in the fancy identifiers are dropped but they may have had comments attached which must not be dropped. So we need to verify, preferably with a test, that all the possible places comments might have been attached to one of the tokens that are dropped, those comments are still in the output. This is a blocker.

Note that each token might have two different kinds of comments attached: leading and trailing. Also, the implementation will probably need to be different after #117. In that case I might put fancyIdentifier in the Lexer since I'd be able to use takeTrivia and pushTrivia which guarantee that no comments are lost or duplicated.

I also just noticed something else. This PR parses and formats identifiers which are also keywords correctly, with quotes. But it does not yet parse or format other quoted strings as identifiers, which Nix does allow.

@piegamesde
Copy link
Member

Oh okay, I hadn't noticed that it also changes the style of the identifiers. I'd honestly advise against doing such simplifications (and the current RFC 101 draft explicitly declares them out of scope, FWIW), as it has several issues:

  • Handling of comments, as you already said
  • Consistency with other code lines, e.g. an attribute set where everything is in quotes but only some of them require them (arguably this only applies to binders and not inherit simplifications, but I think we should handle both equally for consistency)
    • For example I use quotes around free-form keys, like boot.initrd.luks.devices."myPartition".device
    • This is a mildly common pattern within Nixpkgs itself too—see rg '\."[[:alnum:]-_]+"'
  • Consistency with superfluous parentheses, but removing these might reduce readability in addition to the other concerns.

I just noticed that Nixfmt does not (properly) handle multiline string identifiers in general (as far as I can tell), I'll go and investigate that

@Lucus16
Copy link
Contributor Author

Lucus16 commented Oct 14, 2023

This PR currently only changes the style of identifiers in inherit expressions, not elsewhere.

Regarding superfluous parentheses, I had meant to remove all parentheses during parsing and regenerate them when needed for either correct parsing or for readability. In that case nixfmt would decide for everyone what is readable and what is not, which is pretty doable in the case of operator precedence, since you only need to consider the number of operators squared cases of whether the precedence is obvious. I never got around to implementing it. Of course I understand you won't make the same choice, I'm fine with that.

The same goes for quoted identifiers. I tried to build nixfmt to be maximally opinionated so an AST could only have one canonical format, but I understand that does not match the needs of an official nixpkgs formatter, so feel free to make different choices.

I do believe that ${"foo"} is always bad and should always be rerendered as e.g. "foo", at least in inherit expressions where you're not allowed to put anything other than string literals in the interpolation. The fact that the former is even accepted by Nix is a parser bug in my opinion. It means that nixfmt must accept it as valid input but shouldn't give it as output.

@Lucus16
Copy link
Contributor Author

Lucus16 commented Oct 14, 2023

To be clear, feel free to change what this PR does. I already consider the Nix formatter team to be the maintainers of nixfmt, including the current version.

@piegamesde
Copy link
Member

Thank you for your input on this. I'll put it onto the agenda for the next team meeting to discuss before making any changes to the implementation.

@piegamesde
Copy link
Member

This was discussed in the last meeting. While some AST changes may be okay, this one is simply not worth the effort properly implementing ("bad code does not deserve good formatting").

I re-implemented the change and copied over the tests in #141. Feel free to take a look.

@piegamesde piegamesde closed this Nov 10, 2023
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

4 participants