diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaPsiFormattingTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaPsiFormattingTest.java new file mode 100644 index 000000000000..66fbdf8891d4 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaPsiFormattingTest.java @@ -0,0 +1,59 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.psi.formatter.java; + +import com.intellij.openapi.application.WriteAction; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.util.Ref; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiIfStatement; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.impl.DebugUtil; +import com.intellij.psi.util.PsiTreeUtil; + +public class JavaPsiFormattingTest extends AbstractJavaFormatterTest { + + public void testReferenceExpressionSpaceInsertion() { + String text = "if(x&y);"; + PsiFile file = createFile("A.java", "class C{{\n" + text + "\n}}"); + PsiElement element = file.findElementAt(file.getText().indexOf(text)); + PsiIfStatement statement = PsiTreeUtil.getParentOfType(element, PsiIfStatement.class); + assertNotNull(statement); + + Ref result = Ref.create(); + CommandProcessor.getInstance().executeCommand(getProject(), () -> WriteAction.run( + () -> result.set(CodeStyleManager.getInstance(getProject()).reformat(statement)) + ), "", null); + + PsiExpression expr = ((PsiIfStatement)result.get()).getCondition(); + assertEquals("PsiBinaryExpression:x & y\n" + + " PsiReferenceExpression:x\n" + + " PsiReferenceParameterList\n" + + " \n" + + " PsiIdentifier:x('x')\n" + + " PsiWhiteSpace(' ')\n" + + " PsiJavaToken:AND('&')\n" + + " PsiWhiteSpace(' ')\n" + + " PsiReferenceExpression:y\n" + + " PsiReferenceParameterList\n" + + " \n" + + " PsiIdentifier:y('y')\n", + DebugUtil.psiToString(expr, false)); + } + +} diff --git a/platform/lang-impl/src/com/intellij/psi/formatter/FormatterUtil.java b/platform/lang-impl/src/com/intellij/psi/formatter/FormatterUtil.java index 4b6e96fcc1c7..fd43a86453b6 100644 --- a/platform/lang-impl/src/com/intellij/psi/formatter/FormatterUtil.java +++ b/platform/lang-impl/src/com/intellij/psi/formatter/FormatterUtil.java @@ -378,7 +378,7 @@ public class FormatterUtil { if (treePrev.getElementType() == TokenType.WHITE_SPACE) { return treePrev; } - else if (treePrev.getTextLength() == 0 && !treePrev.getElementType().isLeftBound()) { + else if (treePrev.getTextLength() == 0 && isSpaceBeforeEmptyElement(treePrev)) { return getWsCandidate(treePrev); } else { @@ -395,6 +395,14 @@ public class FormatterUtil { } } + private static boolean isSpaceBeforeEmptyElement(ASTNode node) { + if (node.getElementType().isLeftBound()) { + final ASTNode parent = node.getTreeParent(); + return parent != null && parent.getFirstChildNode() == node; + } + return true; + } + private static StringBuilder createNewLeafChars(final ASTNode leafElement, final TextRange textRange, final String whiteSpace) { final TextRange elementRange = leafElement.getTextRange(); final String elementText = leafElement.getText();