-
Notifications
You must be signed in to change notification settings - Fork 190
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
Printer quoting bug #1720
Printer quoting bug #1720
Conversation
|
Added proposed fix, which preserves the original quote style whenever possible, based on the source |
72f0246
to
1c34f75
Compare
Hm, definitely agree we should fix the bug. However I also think the printer should be self-consistent. Robert did a bunch of stuff here for codemods, which I wasn't super familiar with. Reading the current implementation though, it seems like the printer generally takes on a "normalizing" role by default (e.g. all comment styles get normalized to the full form) – but there is a hook that codemods can override to accomplish things like this. I'm leaning towards we should preserve that overall characteristics here (i.e. by fixing this via If we don't think that normalizing mode is generally useful, that's fine too, but we should make a deliberate decision to start moving in the other direction and ask for/accept patches to fix the comment formatting, etc. I think a problem we have/used to have is things get added/changed to solve one specific problem in a way that's inconsistent with the existing design, and overtime it becomes hard to tell what the code is supposed to do and manage people's expectations. Personally, that's the kind of think I care about, but I also don't actively work on this very much so if other maintainers don't share that perspective, feel free to merge. (Looking at things more closely, it seems like concat possibly have the same bug, which will affect attributes with curlies I think.) |
I’m supportive of a best-effort verbatim codemod mode if someone wants it (personally, I also don’t mind the codemod outputting whatever as long as it’s correct, then have prettier fix it), but IMO the current code isn’t intending to do that; if that’s the new goal it would need to be done carefully/holistically with better test coverage around these edge cases. |
hm, I guess not, it seems like attribute nodes have special parsing rules that are unlike string literals: https://astexplorer.net/#/gist/3763b1482a332946dc94c727c33d8ea8/e4def25bc6c4bacf8aff3d7c1f10c28a4a952362 In that case, this is less of a stylistic choice and more of a correctness issue. It's probably more correct to check
Does that work? |
let quote = '"'; | ||
let originalChar = value.loc.asString()[0]; | ||
if (originalChar === "'") { | ||
quote = "'"; | ||
} |
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.
let quote = '"'; | |
let originalChar = value.loc.asString()[0]; | |
if (originalChar === "'") { | |
quote = "'"; | |
} | |
let quote = '"'; | |
if (node.value.includes('"')) { | |
// or whatever we need to do to report errors properly in this context | |
assert('unable to print malformed attribute node, an attribute cannot contain both `"` and `'`', !node.value.includes("'")); | |
quote = "'"; | |
} |
Yeah, this general strategy seems fine, I didn't love the idea of relying on
I think the HTML answer here is entity encoding, and there are already other tests that are exercising that. In the default mode, my example already transforms like this: -<div class='He said "yes"' ></div>
+<div class="He said "yes""></div> which is correct, but presumably is an example of what annoyed somebody enough that they introduced
Unfortunately that horse left the barn many years ago. We're looking at a bug while using an existing mode named "codemod". So it absolutely does intend to do that, it just does it badly. The implementation is very confused and poorly layered (which is why it's also riddled with override points). Of course I agree it would be great to holistically refactor the printer to be self-consistent. Somebody's gotta do it though. Until then, we have an existing "codemod mode" with a correctness bug. |
60406be
to
a6292f4
Compare
New implementation is pushed and passing tests.
|
a6292f4
to
656817c
Compare
Yea, seems good to me. For the codemod mode, reading the comments here, my impression is that the intention is for the caller (whoever wires up the codemod mode upstream) to use this: glimmer-vm/packages/@glimmer/syntax/lib/generation/printer.ts Lines 33 to 47 in 1c34f75
I don’t think that’s necessarily the end consumer, but maybe some code in here/some shared thing Robert made years ago? In any case trying to avoid HTML escaping where possible seems like a reasonable goal even with the normalizing philosophy, especially when it’s reliable. So I’m good with this regardless. |
I'm aware of the override thing, it's really only useful for one very specific use case, which is when you want to return the cached old serialization of known nodes that haven't changed. I think the only user is https://github.com/ember-template-lint/ember-template-recast/blob/3da4525e530436ea3faec6ff9b402a0fadd2e900/src/index.ts#L15-L19 I'm not doing anything like that, I don't actually care about trying to get format preservation, I'm only using "codemod mode" to get the better entity handling (which I agree should probably just be part of the default behavior anyway). |
I hit this printer bug while testing
@embroider/template-tag-codemod
against http://github.com/rust-lang/crates.io.The printer replaces
'
with"
, even when there were already"
characters inside the string literal, and they don't get escaped, resulting in a syntax error.The real line that triggered this was: https://github.com/rust-lang/crates.io/blob/54ad496796eaf3499fc2b6fb96d167b3e94d7d70/app/components/crate-row.hbs#L12