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
Formatting breaks @ts-ignore comments #5411
Comments
This is a really hard problem, not just a "move
Line SpreadingBelow is an example from my current project (which brought me to this issue). The This is the original code: // @ts-ignore
const result = evaluate(chain, opts.filename, args.map(arg => arg.node.value)) It becomes: // @ts-ignore
const result = evaluate(
chain,
opts.filename,
args.map(arg => arg.node.value)
) When it should become: const result = evaluate(
chain,
opts.filename,
// @ts-ignore
args.map(arg => arg.node.value)
) And since there's no way for Prettier to know which is the part to be ignored, it should either bail out of formatting that line completely or prepend a // @ts-ignore
const result = evaluate(
// @ts-ignore
chain,
// @ts-ignore
opts.filename,
// @ts-ignore
args.map(arg => arg.node.value)
// @ts-ignore
) This is pragmatic yet in no way... prettier than before. Therefore I'd vote for bailing out on a Line CondensingHowever, even bailing out is not always trivial. It becomes way harder when the line below the Take this example: // @ts-ignore
const foo = () =>
bar() which is prettified to: // @ts-ignore
const foo = () => bar(); It's not strictly breaking anything, but it might in rare edge cases suppress TypeScript errors that were not supposed to be suppressed. No actual bottom line here, those are just some cases to consider when attempting to fix this issue. |
I don't think this is true. Yes, the formatter would break the statement, but it should be manually fixed as there is no way for Prettier to understand that this is the desired behavior. The issue is actually about that, instead of trying to understand what the |
That sounds reasonable. I actually considered writing down that option too but apparently somehow forgot about that, sorry. It's probably the best approach as 100% correct behaviour seems unachievable with either solution applied, so the one wth the least disruption should be chosen. |
I'm gonna throw in my two cents on a function flattenOptions(
options: ReactSelectOption[]
): ReactSelectOptionObject[] {
return options.reduce(
(acc: ReactSelectOptionObject[], option: ReactSelectOption) =>
option.hasOwnProperty("options")
// @ts-ignore: totally legal thing to do
? flattenOptions(option.options)
// @ts-ignore: another totally legal thing to do
: acc.concat([option]),
[]
);
} gets formatted like so and means the function flattenOptions(
options: ReactSelectOption[]
): ReactSelectOptionObject[] {
return options.reduce(
(acc: ReactSelectOptionObject[], option: ReactSelectOption) =>
option.hasOwnProperty("options")
? // @ts-ignore: totally legal thing to do
flattenOptions(option.options)
: // @ts-ignore: another totally legal thing to do
acc.concat([option]),
[]
);
} I've also tried using |
Does the formatted version no longer ignore the issues? |
@j-f1 yeah, it stops the effectiveness of the |
As a workaround, this might work: Prettier 1.16.4 --parser babylon Input: function flattenOptions(
options: ReactSelectOption[]
): ReactSelectOptionObject[] {
return options.reduce(
(acc: ReactSelectOptionObject[], option: ReactSelectOption) =>
option.hasOwnProperty("options")
// dummy comment to make ts-ignore work
// @ts-ignore: totally legal thing to do
? flattenOptions(option.options)
// dummy comment to make ts-ignore work
// @ts-ignore: another totally legal thing to do
: acc.concat([option]),
[]
);
} Output: function flattenOptions(
options: ReactSelectOption[]
): ReactSelectOptionObject[] {
return options.reduce(
(acc: ReactSelectOptionObject[], option: ReactSelectOption) =>
option.hasOwnProperty("options")
? // dummy comment to make ts-ignore work
// @ts-ignore: totally legal thing to do
flattenOptions(option.options)
: // dummy comment to make ts-ignore work
// @ts-ignore: another totally legal thing to do
acc.concat([option]),
[]
);
} |
Sweet trick @lydell — it works! However a part of me wishes that this could be an internal rule that prettier can automatically work around. |
Wow that's unfortunate |
This seems to be fixed now? |
Yes, original issue was solved, feel free to open new issue if you have other problems with comments, thanks |
The specific example from the top post works now, but the general problem with |
@thorn0 I prefer new issues, #5411 (comment) should be solved manually not on prettier side, we can't duplicate comments, same problem with eslint comments and etc, we already discussed about it |
Comments inside ternary have other issue, so we can close this issue |
I'm not talking only about ternaries. I mean the general problem with the fact that |
@thorn0 still can't understand problem and how we can solve this, please clarify, as i said early comments like |
The problem is described in the comment I linked to. In order to not break anything, foo(
baz,
// @ts-ignore
bar
); should be treated as // prettier-ignore
foo(
baz,
// @ts-ignore
bar
); |
Sorry, I deleted my previous comment. It was completely wrong. Ignoring the whole statement seems to be a solution, albeit an ugly one. So this issue is fixable. |
This comment is completely bogus, ignore it. |
@thorn0 i disagree, we should not ignore nodes with comments, other developers can potential use other comments with any values and we can't change output based on comment text |
We already do so with JSDoc type assertions. And |
That solution would also cause other parts to be ignored, so: foo(
baz,
// @ts-ignore
bar,baz
); ... would not be formatted at all? |
@glen-84 Right. But what else can be done here? |
Also original issue was about other problem, if you want to discussion how we can solve post/feedback from the issue you need open an new issue, it is very hard to track problems inside thread in other issue |
We also try to ignore original input as much as possible when we format, so you change formatting based on comment text is horrible idea for me. Also it is very bad for DX, better get errors and move |
@evilebottnawi Do you really need an example of how I wouldn't say the original issue was different. The title and the discussion of this issue are about the generic problem. I really don't see why open a new one. Using |
@thorn0 okay, please rename issue and move main idea of problem on top, otherwise better close original issue and open new, it is really hard to search problems inside posts into thread |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
@evilebottnawi It was hypothetical. @thorn0 Apologies, I missed that spreading case, but I still believe that:
I don't see how this issue could be solved. |
|
Would it be possible to disable the spreading behaviour for the line following a In that way, at least the rest of the line is formatted correctly. |
No, Prettier doesn't operate on lines. |
The next AST node then. |
Wouldn't be sufficient either. // @ts-ignore
const foo = 1; const bar = 2; |
Who writes code like that? 😛 Also, the previously-suggested solution would have the same limitation. I don't know anything about the internals of Prettier, but perhaps you could use the location metadata in the AST to ignore all nodes on the line following the comment. |
@glen-84 It's not worth the trouble. |
Just pinging here, as I just ran into exactly this problem (from earlier in this thread) with ternaries and VSCode: #5411 (comment) The workaround with dummy comments does work, but it would be great if the underlying problem could be fixed. NB: Someone mentioned that there is a separate issue for ternaries, but I couldn't find it. Happy to move this there if someone can point me in the right direction. Thanks! |
Alternatively, prettier could apply ts-ignore to every line when it does an expansion -- as noted by @loilo . This would be semantically identical to the original code, which would be my default expectation when running a prettifier. I will admit it is not "prettier", but despite the name of the tool I believe its primary purpose is to achieve consistency in a codebase -- not actually to monotonically make it prettier every time it is run. In any case, |
IMO prettier should maintain a list of "directive comments", and ignore lines below these comments. |
fwiw, within google we've locally patched prettier to treat ts-ignore as prettier-ignore. This seems to work alright. |
@iteriani - Neat idea. To save some digging, mind sharing how you did that? |
There's some function called function isPrettierIgnoreComment(comment) {} We basically did something like
|
Great, will give it a shot, thanks! |
edited by @thorn0, citing this comment:
Prettier 1.19.1
Playground link
Input:
Output:
The original code example is below. Prettier doesn't break it anymore, but the general problem with
@ts-ignore
comments hasn't been solved.original code example
Prettier 1.15.1
Playground link
# Options (if any): --single-quote
Input:
Output:
Expected behavior:
Same as input. The comment is mean to ignore the function call, but by moving the comment inside the function, the meaning of the comment is lost.
The text was updated successfully, but these errors were encountered: