You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I can't speak for the google-java-format team, but I'm struggling to understand what you mean by "breakpoints" in this context. Could you clarify for me? 🤔
I wonder, does this problem reproduce if you format with Eclipse's built-in formatter and the google-java-format CLI tool?
I ask because if so, then it would suggest to me that it's an unavoidable part of how Eclipse works, but if not then it would suggest to me that it's a bug in the google-java-format Eclipse plugin.
I wonder, does this problem reproduce if you format with Eclipse's built-in formatter and the google-java-format CLI tool?
I ask because if so, then it would suggest to me that it's an unavoidable part of how Eclipse works, but if not then it would suggest to me that it's a bug in the google-java-format Eclipse plugin.
This issue does not occur when using the built-in formatter (or at least I haven't encountered an edge-case where it does). It does, however, occur consistently when using the GJF plugin. This behavior seems to be caused by a combination of how Eclipse tracks breakpoints and how GJF formats code.
Eclipse breakpoints seem to be bound to the surrounding method as far as I can tell. As a result, the breakpoint is removed when the method is removed (even if just temporarily). This also applies when the method is just replaced.
This behavior can be observed by replacing editor content, either by using the replace functionality in Eclipse or by selecting and replacing text using copy&past. If only a part of the method is replaced (not including the method declaration), the breakpoint remains. If the whole method is replaced, the breakpoint is removed.
As far as I can tell, GJF only offers the option to format by replacement and not by exact diff (at least this approach is used by the methods used by the GJF Eclipse plugin). What I mean by this is that the formatting method returns the formatted version of the given range which can then be used to replace the original in the document (instead of returning the exact changes necessary to go from the input to the wanted output). Additionally, everything in the given range is included in the replacement and not just the blocks/sub-ranges that were actually changed. As a result, when formatting a file (or even just a method) using GJF in Eclipse, the entire formatted range will be replaced with the formatted version, even if the formatter just did some minor changes like removing some whitespace or fixing an indentation.
This behavior in combination with the above mentioned Eclipse breakpoint handling leads to breakpoints being removed from the editor when formatting. The issue can be nicely recreated when first formatting only a method body and then the entire method (including declaration and closing brace). The first run will not remove breakpoints while the second run will remove any breakpoint in the method (assuming both runs had anything to format and were not NOPs).
The Eclipse formatter avoids this issue by operating in exact diffs (e.g. if it wants to fix an indentation, it removes or adds spaces/tabs instead of replacing the whole line).
As to how to fix this issue, I am not really sure.
The Eclipse formatter interface/method only has access to the string containing the text of the document to format and the specific ranges to format in that string, not the document the text is sourced from. So saving and re-adding the breakpoints after formatting is not an option. (Also, this would still leave the issue of correctly adjusting the breakpoint position after the formatting.)
And just trying to calculate the diffs from the input and output string calculated by GJF is not really feasible either in my opinion. Too much content can change and move around, especially when formatting whole files, making it hard to correctly calculate the minimal diff.
@cushon Do you have any suggestions or insight on how to best calculate such minimal diffs/avoid the described issue?
Activity
jbduncan commentedon Nov 3, 2018
Hi @eddi-weiss, welcome to google-java-format!
I can't speak for the google-java-format team, but I'm struggling to understand what you mean by "breakpoints" in this context. Could you clarify for me? 🤔
white-speedy commentedon Nov 3, 2018
Just create a debugger line breakpoint inside java editor. Then format the source code.
-> The breakpoint is removed.
PS: see the movie
2018-11-04_00h44_15.zip
jbduncan commentedon Nov 4, 2018
Ah, I see, thank you!
I wonder, does this problem reproduce if you format with Eclipse's built-in formatter and the google-java-format CLI tool?
I ask because if so, then it would suggest to me that it's an unavoidable part of how Eclipse works, but if not then it would suggest to me that it's a bug in the google-java-format Eclipse plugin.
tobous commentedon Dec 23, 2020
This issue does not occur when using the built-in formatter (or at least I haven't encountered an edge-case where it does). It does, however, occur consistently when using the GJF plugin. This behavior seems to be caused by a combination of how Eclipse tracks breakpoints and how GJF formats code.
Eclipse breakpoints seem to be bound to the surrounding method as far as I can tell. As a result, the breakpoint is removed when the method is removed (even if just temporarily). This also applies when the method is just replaced.
This behavior can be observed by replacing editor content, either by using the replace functionality in Eclipse or by selecting and replacing text using copy&past. If only a part of the method is replaced (not including the method declaration), the breakpoint remains. If the whole method is replaced, the breakpoint is removed.
As far as I can tell, GJF only offers the option to format by replacement and not by exact diff (at least this approach is used by the methods used by the GJF Eclipse plugin). What I mean by this is that the formatting method returns the formatted version of the given range which can then be used to replace the original in the document (instead of returning the exact changes necessary to go from the input to the wanted output). Additionally, everything in the given range is included in the replacement and not just the blocks/sub-ranges that were actually changed. As a result, when formatting a file (or even just a method) using GJF in Eclipse, the entire formatted range will be replaced with the formatted version, even if the formatter just did some minor changes like removing some whitespace or fixing an indentation.
This behavior in combination with the above mentioned Eclipse breakpoint handling leads to breakpoints being removed from the editor when formatting. The issue can be nicely recreated when first formatting only a method body and then the entire method (including declaration and closing brace). The first run will not remove breakpoints while the second run will remove any breakpoint in the method (assuming both runs had anything to format and were not NOPs).
The Eclipse formatter avoids this issue by operating in exact diffs (e.g. if it wants to fix an indentation, it removes or adds spaces/tabs instead of replacing the whole line).
As to how to fix this issue, I am not really sure.
The Eclipse formatter interface/method only has access to the string containing the text of the document to format and the specific ranges to format in that string, not the document the text is sourced from. So saving and re-adding the breakpoints after formatting is not an option. (Also, this would still leave the issue of correctly adjusting the breakpoint position after the formatting.)
And just trying to calculate the diffs from the input and output string calculated by GJF is not really feasible either in my opinion. Too much content can change and move around, especially when formatting whole files, making it hard to correctly calculate the minimal diff.
@cushon Do you have any suggestions or insight on how to best calculate such minimal diffs/avoid the described issue?