From 4051d75eaffaf9d6e0cbabf94e312005a44fbbc2 Mon Sep 17 00:00:00 2001 From: Yaroslav Lepenkin Date: Fri, 28 Aug 2015 12:29:59 +0300 Subject: [PATCH] Extracted annotation parameter list blocks builder, fixed couple issues when pressing enter near right parenthesis --- .../psi/formatter/java/AbstractJavaBlock.java | 9 +- .../AnnotationInitializerBlocksBuilder.java | 75 +++++++++++++ .../formatter/java/JavaEnterActionTest.java | 104 ++++++++++++++++++ 3 files changed, 184 insertions(+), 4 deletions(-) create mode 100644 java/java-impl/src/com/intellij/psi/formatter/java/AnnotationInitializerBlocksBuilder.java create mode 100644 java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaEnterActionTest.java diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java b/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java index 25bd89226a38..336c549861a8 100644 --- a/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java +++ b/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java @@ -530,10 +530,11 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo mySettings.ALIGN_MULTILINE_RESOURCES); } else if (childType == JavaTokenType.LPARENTH && nodeType == JavaElementType.ANNOTATION_PARAMETER_LIST) { - Wrap wrap = Wrap.createWrap(getWrapType(myJavaSettings.ANNOTATION_PARAMETER_WRAP), false); - child = processParenthesisBlock(result, child, - WrappingStrategy.createDoNotWrapCommaStrategy(wrap), - myJavaSettings.ALIGN_MULTILINE_ANNOTATION_PARAMETERS); + AnnotationInitializerBlocksBuilder builder = new AnnotationInitializerBlocksBuilder(myNode, myBlockFactory); + List newlyCreated = builder.buildBlocks(); + + child = myNode.getLastChildNode(); + result.addAll(newlyCreated); } else if (childType == JavaTokenType.LPARENTH && nodeType == JavaElementType.PARENTH_EXPRESSION) { child = processParenthesisBlock(result, child, diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/AnnotationInitializerBlocksBuilder.java b/java/java-impl/src/com/intellij/psi/formatter/java/AnnotationInitializerBlocksBuilder.java new file mode 100644 index 000000000000..19218dea7f35 --- /dev/null +++ b/java/java-impl/src/com/intellij/psi/formatter/java/AnnotationInitializerBlocksBuilder.java @@ -0,0 +1,75 @@ +/* + * Copyright 2000-2015 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.formatting.Alignment; +import com.intellij.formatting.Block; +import com.intellij.formatting.Indent; +import com.intellij.formatting.Wrap; +import com.intellij.lang.ASTNode; +import com.intellij.openapi.util.Condition; +import com.intellij.psi.JavaTokenType; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiNameValuePair; +import com.intellij.psi.PsiWhiteSpace; +import com.intellij.psi.codeStyle.JavaCodeStyleSettings; +import com.intellij.psi.util.PsiTreeUtil; + +import java.util.List; + +import static com.intellij.psi.formatter.java.JavaFormatterUtil.getWrapType; + +public class AnnotationInitializerBlocksBuilder { + + private final BlockFactory myFactory; + private final ASTNode myNode; + private final JavaCodeStyleSettings myJavaSettings; + + public AnnotationInitializerBlocksBuilder(ASTNode node, BlockFactory factory) { + myNode = node; + myFactory = factory; + myJavaSettings = myFactory.getJavaSettings(); + } + + public List buildBlocks() { + final Wrap wrap = Wrap.createWrap(getWrapType(myJavaSettings.ANNOTATION_PARAMETER_WRAP), false); + final Alignment alignment = myJavaSettings.ALIGN_MULTILINE_ANNOTATION_PARAMETERS ? Alignment.createAlignment() : null; + + ChildrenBlocksBuilder.Config config = new ChildrenBlocksBuilder.Config() + .setDefaultIndent(Indent.getContinuationWithoutFirstIndent()) + .setIndent(JavaTokenType.RPARENTH, Indent.getNoneIndent()) + .setIndent(JavaTokenType.LPARENTH, Indent.getNoneIndent()) + + .setDefaultWrap(wrap) + .setNoWrap(JavaTokenType.COMMA) + .setNoWrap(JavaTokenType.RPARENTH) + .setNoWrap(JavaTokenType.LPARENTH) + + .setDefaultAlignment(alignment) + .setNoAlignment(JavaTokenType.COMMA) + .setNoAlignment(JavaTokenType.LPARENTH) + .setNoAlignmentIf(JavaTokenType.RPARENTH, new Condition() { + @Override + public boolean value(ASTNode node) { + PsiElement prev = PsiTreeUtil.skipSiblingsBackward(node.getPsi(), PsiWhiteSpace.class); + if (prev == null) return false; + return prev instanceof PsiNameValuePair && !PsiTreeUtil.hasErrorElements(prev); + } + }); + + return config.createBuilder().buildNodeChildBlocks(myNode, myFactory); + } +} diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaEnterActionTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaEnterActionTest.java new file mode 100644 index 000000000000..fd6ba563d2c0 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaEnterActionTest.java @@ -0,0 +1,104 @@ +/* + * Copyright 2000-2015 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.codeInsight.AbstractEnterActionTestCase; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.JavaCodeStyleSettings; + +import java.io.IOException; + +public class JavaEnterActionTest extends AbstractEnterActionTestCase { + + public void testEnterInsideAnnotationParameters() throws IOException { + CodeStyleSettings settings = getCodeStyleSettings(); + JavaCodeStyleSettings javaSettings = settings.getCustomSettings(JavaCodeStyleSettings.class); + javaSettings.ALIGN_MULTILINE_ANNOTATION_PARAMETERS = true; + setCodeStyleSettings(settings); + + doTextTest("java", + "public class T {\n" + + "\n" + + " @Configurable(order = 25, \n" + + " validator = BigDecimalPercentValidator.class, )\n" + + " public void run() {\n" + + " }\n" + + " \n" + + " \n" + + "}", + "public class T {\n" + + "\n" + + " @Configurable(order = 25, \n" + + " validator = BigDecimalPercentValidator.class, \n" + + " )\n" + + " public void run() {\n" + + " }\n" + + " \n" + + " \n" + + "}"); + + doTextTest("java", + "public class T {\n" + + "\n" + + " @Configurable(order = 25, \n" + + " validator = BigDecimalPercentValidator.class, \n" + + " )\n" + + " public void run() {\n" + + " }\n" + + " \n" + + " \n" + + "}", + "public class T {\n" + + "\n" + + " @Configurable(order = 25, \n" + + " validator = BigDecimalPercentValidator.class, \n" + + " \n" + + " )\n" + + " public void run() {\n" + + " }\n" + + " \n" + + " \n" + + "}"); + } + + public void testEnterInsideAnnotationParameters_AfterNameValuePairBeforeLparenth() throws IOException { + CodeStyleSettings settings = getCodeStyleSettings(); + JavaCodeStyleSettings javaSettings = settings.getCustomSettings(JavaCodeStyleSettings.class); + javaSettings.ALIGN_MULTILINE_ANNOTATION_PARAMETERS = true; + setCodeStyleSettings(settings); + + doTextTest("java", + "public class T {\n" + + "\n" + + " @Configurable(order = 25, \n" + + " validator = BigDecimalPercentValidator.class)\n" + + " public void run() {\n" + + " }\n" + + " \n" + + " \n" + + "}", + "public class T {\n" + + "\n" + + " @Configurable(order = 25, \n" + + " validator = BigDecimalPercentValidator.class\n" + + " )\n" + + " public void run() {\n" + + " }\n" + + " \n" + + " \n" + + "}"); + } +} \ No newline at end of file