Bug 563487 - [formatter] Wrong indentation with "Format edited lines" save action in lambda body after wrap
Summary: [formatter] Wrong indentation with "Format edited lines" save action in lambd...
Status: RESOLVED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 4.16   Edit
Hardware: PC Windows 10
: P3 normal (vote)
Target Milestone: 4.16 RC2   Edit
Assignee: Mateusz Matela CLA
QA Contact:
URL:
Whiteboard: To be verified for 4.16 RC2
Keywords: regression
: 564253 (view as bug list)
Depends on:
Blocks:
 
Reported: 2020-05-22 11:21 EDT by Garret Wilson CLA
Modified: 2020-08-09 11:55 EDT (History)
3 users (show)

See Also:
manoj.palat: review+


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Garret Wilson CLA 2020-05-22 11:21:44 EDT
This bug is very similar to Bug 560889, except in the opposite direction: it unnecessarily indents code when I save, rather than wrapping lines.

I'm using the Eclipse Enterprise package 2020-06 (4.16.0) M2 (20200507-0346) on AdoptOpenJDK 11, with an almost identical formatting configuration to Bug 560889.

If I hit `Ctrl+Shift+F` it reformats the code nicely. Then I hit `Ctrl+S` to save, and it _indents_ two lines.

Here is an excerpt of code. (I don't have time to break it down into a minimal reproducible example. Hopefully since it's yet another manifestation of very similar bugs which keep cropping up, you'll be able to find the source with this example. And I can't help the crummy presentation; that's what we get for using Bugzilla rather than something modern.)

```
	protected List<Element> regenerateNavigationList(@Nonnull MummyContext context, @Nonnull final Artifact contextArtifact, @Nonnull final Artifact artifact,
			@Nonnull final Element navigationListElement) throws IOException, DOMException {

//stuff cut here to make the example smaller

		//add new navigation links from templates
		navigation(context, contextArtifact)
				//generate navigation elements 
				.forEach(navigationItem -> {
					//if the navigation artifact is this artifact, use the template for an active link
							final Element liTemplate = navigationItem.equals(contextArtifact) ? activeLiTemplate : inactiveLiTemplate;
					final Element liElement = (Element)liTemplate.cloneNode(true);
					//update the icon: <li><i> (transform to <span></span>)
					findFirst(liElement.getElementsByTagNameNS(XHTML_NAMESPACE_URI_STRING, ELEMENT_I)).map(Element.class::cast).ifPresent(iElement -> {
						//if the navigation element has an icon, replace the `<i></i>` with an icon `<span></span>` 
								navigationItem.findIconId().ifPresentOrElse(iconId -> {
							final String iconClass;
							final String iconContent;
							final String[] iconIdParts = iconId.split("/", -1); //TODO use constant
							if(iconIdParts.length == 2 && !iconIdParts[0].isBlank() && !iconIdParts[1].isBlank()) {
								final String iconGroup = iconIdParts[0];
								final String iconName = iconIdParts[1];
								if(FONT_AWESOME_ICON_GROUPS.contains(iconGroup)) {
									iconClass = iconGroup + ' ' + iconName; //e.g. `<span class="fas fa-home"></span>` (Font Awesome)
									iconContent = null;
								} else {
									iconClass = iconGroup; //e.g. `<span class="material-icons">home</span>` (Material Icons)
									iconContent = iconName;
								}
							} else { //if the icon name isn't in the format we expect, just use it as the content
								iconClass = null;
								iconContent = iconId;
							}
							final Element iconElement = iElement.getOwnerDocument().createElementNS(XHTML_NAMESPACE_URI_STRING, ELEMENT_SPAN);
							if(iconClass != null) {
								iconElement.setAttributeNS(null, ATTRIBUTE_CLASS, iconClass);
							}
							if(iconContent != null) {
								appendText(iconElement, iconContent);
							}
							iElement.getParentNode().replaceChild(iconElement, iElement);
						}, () -> iElement.getParentNode().removeChild(iElement)); //if the navigation element has no icon, remove the `<i></i>`
					});
					//update the link: <li><a>
					findFirst(liElement.getElementsByTagNameNS(XHTML_NAMESPACE_URI_STRING, ELEMENT_A)).map(Element.class::cast).ifPresent(aElement -> {
								navigationItem.findHref().ifPresentOrElse(href -> aElement.setAttributeNS(null, ELEMENT_A_ATTRIBUTE_HREF, href),
										() -> aElement.removeAttributeNS(null, ELEMENT_A_ATTRIBUTE_HREF));
						//remove text nodes (leaving the icon or any other element)
						final Iterator<Node> childNodeIterator = XmlDom.childNodesIterator(aElement);
						while(childNodeIterator.hasNext()) {
							final Node childNode = childNodeIterator.next();
							if(childNode.getNodeType() == Node.TEXT_NODE) {
								childNodeIterator.remove();
							}
						}
								final String navigationLabel = navigationItem.getLabel();
						final String linkLabel = aElement.getChildNodes().getLength() > 0 ? " " + navigationLabel : navigationLabel; //add spacing if there are other elements (e.g. an icon)
						//append the link label
						appendText(aElement, linkLabel);
					});
					navigationListElement.appendChild(liElement);
				});

		return List.of(navigationListElement);
	}
```

The key thing to look at are these two lines:

```
							final Element liTemplate = navigationItem.equals(contextArtifact) ? activeLiTemplate : inactiveLiTemplate;

								final String navigationLabel = navigationItem.getLabel();
```

(There's a logic bug in the first of those lines, but ignore that; I'm in the middle of updating the code.)

These lines are indented too much: 7 and 8 tabs, respectively.

When I hit `Ctrl+Shift+F`, it brings the lines back to 5 and 6 tab indents, which is correct. But then when I hit `Ctrl+S` to save the code, it re-indents them to an incorrect number of indents.

So it's Bug 560889 all over again, just with extra indents rather than extra line breaks. Just like Bug 560889, if I remember to hit `Ctrl+Z` after saving and save again, I get "undo" the bad formatting things. But I don't always remember. And I don't even always see the things it screwed up, because they may be outside the current viewport.

I note that we have not had an Eclipse that would reliably format code since Eclipse 2019-12, so it it would be _really_ nice to get this fixed by Eclipse 2020-06. Thank you.
Comment 1 Garret Wilson CLA 2020-05-22 11:33:46 EDT
To clarify the description: when I said "… it _indents_ two lines", I was anticipating my example. It would have been clearer if I would have said, "… it adds extra indention to some lines; my example has two such lines that demonstrates this".
Comment 2 Garret Wilson CLA 2020-05-22 12:33:13 EDT
You can reproduce this problem in the following Git commit:

https://bitbucket.org/globalmentor/guise/commits/37847df1081ac08ddfb666d16d9c91fa0cedbb6f

The file is `io.guise.mummy.mummify.page.AbstractPageMummifier` and the lines are 1002 and 1047.
Comment 3 Garret Wilson CLA 2020-05-23 13:43:58 EDT
This is a huge regression, actually. It's just as bad as Bug 560889. Maybe the "fix" for Bug 560889 caused this; I don't know.

What I do know is that yet again these bugs are so screwing up my formatting that I will have to revert back to Eclipse 2019-12.

One of the problems with these formatting bugs is that I don't even notice it's happening until later, because it make muck up indents that are outside the view area, so it's hard to guard against even knowing it's happening.

If these formatting bugs keep popping up again and again (Bug 559638, Bug 559638, etc.), maybe it's worth taking a step back, reverting to the 2019-12 formatting code, and redoing whatever was done to "improve things" but in a more controlled and verifiable manner. Because the way it's going, if this is not fixed by 2020-06 GA, then these things will have broken half a year's worth of Eclipse releases.

If someone else has a better suggestion for keeping this from happening again and again, that's great.
Comment 4 Garret Wilson CLA 2020-05-23 14:07:07 EDT
I reverted and verified that this bug does not occur in 2019-12.
Comment 5 Mateusz Matela CLA 2020-05-30 15:06:07 EDT
I would miss this one if not for your comment in bug 560889 as I'm querying for bugs by the 'formatter' keyword and you've managed to avoid it. I'll also include 'formatting' in my query.

I understand it's annoying, but let's spare the 'critical' label for really serious ones like data loss and crashes.

It's not that we keep introducing bugs "again and again", it was one particularly unfortunate change with two side effects that manifested pretty often and now you found a more rare case (it's about lambda/anonymous class body inside a wrapped statement).
Comment 6 Eclipse Genie CLA 2020-05-30 15:09:47 EDT
New Gerrit change created: https://git.eclipse.org/r/163891
Comment 7 Mateusz Matela CLA 2020-05-30 15:12:25 EDT
Manoj, will you approve for RC2?
Comment 8 Manoj N Palat CLA 2020-06-01 06:49:15 EDT
(In reply to Mateusz Matela from comment #7)
> Manoj, will you approve for RC2?

+1
Comment 10 Garret Wilson CLA 2020-06-12 15:12:04 EDT
(In reply to Mateusz Matela from comment #7)
> Manoj, will you approve for RC2?

Could you clarify the status of RC2? I was eagerly awaiting RC2 to get a fix for this bug so I can move on from 2019-12. According to the wiki page at https://wiki.eclipse.org/Category:SimRel-2020-06 , RC2 should have dropped this morning.

But https://www.eclipse.org/downloads/packages/release/2020-06/rc2 does not bring up an RC2 page. In fact https://www.eclipse.org/downloads/packages/release/2020-06 doesn't even list an RC2 at all; it only shows a final release R page, but that is blank.

So did Eclipse skip RC2? Does that mean this bug won't get fixed in Eclipse 2020-06 after all?

Please clarify; I'm hoping I won't have to wait yet another three months.

Thank you very much in advance. I'm crossing my fingers.
Comment 11 Mateusz Matela CLA 2020-06-13 17:34:34 EDT
*** Bug 564253 has been marked as a duplicate of this bug. ***
Comment 12 Mateusz Matela CLA 2020-06-13 17:38:27 EDT
(In reply to Garret Wilson from comment #10)

The Gerrit was pushed to master before RC2, so it will be fixed in RC2 and 2020-06.
I can't help on RC2 distributions.
Comment 13 Garret Wilson CLA 2020-06-13 17:41:02 EDT
If it is fixed for 4.16 RC2, then why was it just moved to 4.17 RC2? Was that a mistake?
Comment 14 Garret Wilson CLA 2020-06-13 17:41:25 EDT
To clarify, the "whiteboard" now says "To be verified for 4.17 RC2".
Comment 15 Mateusz Matela CLA 2020-06-13 17:42:43 EDT
Oh right, I'm getting lost in these version numbers :P
4.16 it is.
Comment 16 Garret Wilson CLA 2020-06-13 17:44:58 EDT
Whew! That was scaring me.

I'm still worried that https://www.eclipse.org/downloads/packages/release/2020-06/rc2 doesn't exist.

What's the point of having an RC2 if the packages are not released like https://www.eclipse.org/downloads/packages/release/2020-06/rc1 was? How will we be able to confirm that this was fixed in the packaged version before GA?

I know that the packages aren't your area of responsibility. Any idea whom I could ask?
Comment 17 Garret Wilson CLA 2020-08-09 11:55:00 EDT
I just wanted to circle back and give a special thanks to Mateusz and everyone involved for fixing this. Eclipse 2020-06 was released and as far as I can tell this version has no major formatting bugs. Whew! It's really a breath of fresh air to be able to move to a working, recent version again.

Thanks!