IDEA-168549 Groovy shifted braces placement not shifted

This commit is contained in:
alexey.afanasiev
2017-04-21 18:03:13 +03:00
parent b56c04d540
commit 3e771f1908
11 changed files with 573 additions and 170 deletions
@@ -141,18 +141,7 @@ public class GroovyBlock implements Block, ASTBlock {
@Override
@Nullable
public Spacing getSpacing(Block child1, @NotNull Block child2) {
if (child1 instanceof GroovyBlock && child2 instanceof GroovyBlock) {
if (((GroovyBlock)child1).getNode() == ((GroovyBlock)child2).getNode()) {
return Spacing.getReadOnlySpacing();
}
Spacing spacing = new GroovySpacingProcessor(((GroovyBlock)child1), (GroovyBlock)child2, myContext).getSpacing();
if (spacing != null) {
return spacing;
}
return GroovySpacingProcessorBasic.getSpacing(((GroovyBlock)child1), ((GroovyBlock)child2), myContext);
}
return null;
return GroovySpacingProcessor.getSpacing(child1, child2, myContext);
}
@Override
@@ -164,37 +153,14 @@ public class GroovyBlock implements Block, ASTBlock {
return new ChildAttributes(Indent.getNoneIndent(), null);
}
if (psiParent instanceof GrSwitchStatement) {
List<Block> subBlocks = getSubBlocks();
if (newChildIndex > 0) {
Block block = subBlocks.get(newChildIndex - 1);
if (block instanceof GroovyBlock) {
PsiElement anchorPsi = ((GroovyBlock)block).getNode().getPsi();
if (anchorPsi instanceof GrCaseSection) {
for (GrStatement statement : ((GrCaseSection)anchorPsi).getStatements()) {
if (statement instanceof GrBreakStatement ||
statement instanceof GrContinueStatement ||
statement instanceof GrReturnStatement ||
statement instanceof GrThrowStatement) {
final Indent indent = GroovyIndentProcessor.getSwitchCaseIndent(myContext.getSettings());
return new ChildAttributes(indent, null);
}
}
int indentSize = myContext.getSettings().getIndentOptions().INDENT_SIZE;
final int spaces = myContext.getSettings().INDENT_CASE_FROM_SWITCH
? 2 * indentSize
: indentSize;
return new ChildAttributes(Indent.getSpaceIndent(spaces), null);
}
}
}
new ChildAttributes(Indent.getNoneIndent(), null);
}
if (psiParent instanceof GrCaseLabel) {
return new ChildAttributes(GroovyIndentProcessor.getSwitchCaseIndent(getContext().getSettings()), null);
}
if (psiParent instanceof GrCaseSection) {
return getSwitchIndent((GrCaseSection)psiParent, newChildIndex);
return GroovyIndentProcessor.getChildSwitchIndent((GrCaseSection)psiParent, newChildIndex);
}
if (TokenSets.BLOCK_SET.contains(astNode.getElementType()) || GroovyElementTypes.SWITCH_STATEMENT.equals(astNode.getElementType())) {
@@ -229,23 +195,6 @@ public class GroovyBlock implements Block, ASTBlock {
return new ChildAttributes(Indent.getNoneIndent(), null);
}
private ChildAttributes getSwitchIndent(GrCaseSection psiParent, int newIndex) {
final GrStatement[] statements = psiParent.getStatements();
newIndex--;
for (int i = 0; i < statements.length && i < newIndex; i++) {
GrStatement statement = statements[i];
if (statement instanceof GrBreakStatement ||
statement instanceof GrContinueStatement ||
statement instanceof GrReturnStatement ||
statement instanceof GrThrowStatement) {
return new ChildAttributes(Indent.getNoneIndent(), null);
}
}
final Indent indent = GroovyIndentProcessor.getSwitchCaseIndent(getContext().getSettings());
return new ChildAttributes(indent, null);
}
@Override
public boolean isIncomplete() {
return isIncomplete(myNode);
@@ -25,7 +25,9 @@ import com.intellij.patterns.PlatformPatterns;
import com.intellij.psi.PsiComment;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.psi.impl.source.tree.LeafPsiElement;
import com.intellij.psi.impl.source.tree.TreeElement;
import com.intellij.psi.templateLanguages.OuterLanguageElement;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
@@ -47,15 +49,13 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrThrowsClause;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrLabeledStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.*;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentLabel;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrCaseSection;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrTraditionalForClause;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral;
@@ -69,8 +69,11 @@ import org.jetbrains.plugins.groovy.lang.psi.util.GrStringUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.mLCURLY;
/**
* Utility class to generate myBlock hierarchy
*
@@ -110,7 +113,7 @@ public class GroovyBlockGenerator {
if (!children.isEmpty()) {
ASTNode first = children.get(0);
if (first.getElementType() == GroovyTokenTypes.mLCURLY) children.remove(0);
if (first.getElementType() == mLCURLY) children.remove(0);
}
if (!children.isEmpty()) {
@@ -132,7 +135,8 @@ public class GroovyBlockGenerator {
}
//For multiline strings
if ((elementType == GroovyTokenTypes.mSTRING_LITERAL || elementType == GroovyTokenTypes.mGSTRING_LITERAL) && myBlock.getTextRange().equals(myNode.getTextRange())) {
if ((elementType == GroovyTokenTypes.mSTRING_LITERAL || elementType == GroovyTokenTypes.mGSTRING_LITERAL) &&
myBlock.getTextRange().equals(myNode.getTextRange())) {
String text = myNode.getText();
if (text.length() > 6) {
if (text.substring(0, 3).equals("'''") && text.substring(text.length() - 3).equals("'''") ||
@@ -143,9 +147,10 @@ public class GroovyBlockGenerator {
}
//for gstrings
if (elementType == GroovyElementTypes.GSTRING || elementType == GroovyElementTypes.REGEX || elementType ==
GroovyTokenTypes.mREGEX_LITERAL || elementType ==
GroovyTokenTypes.mDOLLAR_SLASH_REGEX_LITERAL) {
if (elementType == GroovyElementTypes.GSTRING ||
elementType == GroovyElementTypes.REGEX ||
elementType == GroovyTokenTypes.mREGEX_LITERAL ||
elementType == GroovyTokenTypes.mDOLLAR_SLASH_REGEX_LITERAL) {
final FormattingContext context =
myNode.getPsi() instanceof GrString && ((GrString)myNode.getPsi()).isPlainString() ? myContext.createContext(true) : myContext;
@@ -159,10 +164,11 @@ public class GroovyBlockGenerator {
return subBlocks;
}
final CommonCodeStyleSettings settings = myContext.getSettings();
// chained properties, calls, indexing, etc
if (NESTED.contains(elementType) && blockPsi.getParent() != null && !NESTED.contains(blockPsi.getParent().getNode().getElementType())) {
final List<Block> subBlocks = new ArrayList<>();
AlignmentProvider.Aligner dotsAligner = myContext.getSettings().ALIGN_MULTILINE_CHAINED_METHODS ? myAlignmentProvider.createAligner(false) : null;
AlignmentProvider.Aligner dotsAligner = settings.ALIGN_MULTILINE_CHAINED_METHODS ? myAlignmentProvider.createAligner(false) : null;
final Wrap wrap = myWrappingProcessor.getChainedMethodCallWrap();
addNestedChildren(myNode.getPsi(), subBlocks, dotsAligner, true, wrap);
@@ -200,6 +206,28 @@ public class GroovyBlockGenerator {
return subBlocks;
}
if (blockPsi instanceof GrSwitchStatement) {
final ArrayList<Block> subBlocks = new ArrayList<>();
final ArrayList<Block> bodyBlocks = new ArrayList<>();
List<ASTNode> astNodes = visibleChildren(myNode);
boolean switchBody = false;
for (ASTNode childNode : astNodes) {
if (childNode.getElementType() == mLCURLY) {
switchBody = true;
}
if (switchBody) {
bodyBlocks.add(new GroovyBlock(childNode, getIndent(childNode), getChildWrap(childNode), myContext));
}
else {
subBlocks.add(new GroovyBlock(childNode, getIndent(childNode), getChildWrap(childNode), myContext));
}
}
subBlocks.add(createSwitchBodyBlock(bodyBlocks));
return subBlocks;
}
boolean classLevel = blockPsi instanceof GrTypeDefinitionBody;
if (blockPsi instanceof GrClosableBlock &&
((GrClosableBlock)blockPsi).getArrow() != null &&
@@ -215,20 +243,6 @@ public class GroovyBlockGenerator {
blocks.add(new GroovyBlock(node, getIndent(node), Wrap.createWrap(WrapType.NONE, false), myContext));
}
/* {
Indent indent = GroovyIndentProcessor.getChildIndent(myBlock, parameterListNode);
GroovyBlock block = new GroovyBlock(parameterListNode, indent, myWrap, mySettings, myGroovySettings, myAlignmentProvider);
blocks.add(block);
}
{
PsiElement arrow = closableBlock.getArrow();
ASTNode node = arrow.getNode();
Indent indent = GroovyIndentProcessor.getChildIndent(myBlock, node);
GroovyBlock block = new GroovyBlock(node, indent, myWrap, mySettings, myGroovySettings, myAlignmentProvider);
blocks.add(block);
}*/
{
Indent indent = Indent.getNormalIndent();
ASTNode parameterListNode = closableBlock.getParameterList().getNode();
@@ -265,11 +279,10 @@ public class GroovyBlockGenerator {
}
}
return subBlocks;
}
else if (blockPsi instanceof GrTraditionalForClause) {
if (myContext.getSettings().ALIGN_MULTILINE_FOR) {
if (settings.ALIGN_MULTILINE_FOR) {
final GrTraditionalForClause clause = (GrTraditionalForClause)blockPsi;
final AlignmentProvider.Aligner parenthesesAligner = myAlignmentProvider.createAligner(false);
parenthesesAligner.append(clause.getInitialization());
@@ -279,31 +292,31 @@ public class GroovyBlockGenerator {
}
else if (blockPsi instanceof GrBinaryExpression) {
if (myContext.getSettings().ALIGN_MULTILINE_BINARY_OPERATION) {
if (settings.ALIGN_MULTILINE_BINARY_OPERATION) {
final GrBinaryExpression binary = (GrBinaryExpression)blockPsi;
final GrExpression left = binary.getLeftOperand();
final GrExpression right = binary.getRightOperand();
if (left != null && right != null) {
if (right != null) {
myAlignmentProvider.addPair(left, right, false);
}
}
}
else if (blockPsi instanceof GrAssignmentExpression) {
if (myContext.getSettings().ALIGN_MULTILINE_ASSIGNMENT) {
if (settings.ALIGN_MULTILINE_ASSIGNMENT) {
final GrAssignmentExpression assignment = (GrAssignmentExpression)blockPsi;
final GrExpression lValue = assignment.getLValue();
final GrExpression rValue = assignment.getRValue();
if (lValue != null && rValue != null) {
if (rValue != null) {
myAlignmentProvider.addPair(lValue, rValue, false);
}
}
}
else if (blockPsi instanceof GrConditionalExpression) {
if (myContext.getSettings().ALIGN_MULTILINE_TERNARY_OPERATION) {
if (settings.ALIGN_MULTILINE_TERNARY_OPERATION) {
final GrConditionalExpression conditional = (GrConditionalExpression)blockPsi;
final AlignmentProvider.Aligner exprAligner = myAlignmentProvider.createAligner(false);
@@ -331,6 +344,43 @@ public class GroovyBlockGenerator {
return subBlocks;
}
private Block createSwitchBodyBlock(List<Block> bodyBlocks) {
CommonCodeStyleSettings settings = myContext.getSettings();
return new SyntheticGroovyBlock(
bodyBlocks,
Wrap.createWrap(WrapType.NONE, false),
GroovyIndentProcessor.getBlockIndent(settings.BRACE_STYLE),
GroovyIndentProcessor.getIndentInBlock(settings.BRACE_STYLE),
myContext) {
@NotNull
@Override
public ChildAttributes getChildAttributes(int newChildIndex) {
List<Block> subBlocks = getSubBlocks();
if (newChildIndex > 0) {
Block block = subBlocks.get(newChildIndex - 1);
if (block instanceof GroovyBlock) {
PsiElement anchorPsi = ((GroovyBlock)block).getNode().getPsi();
if (anchorPsi instanceof GrCaseSection) {
boolean finished = GroovyIndentProcessor.isFinishedCase((GrCaseSection)anchorPsi, Integer.MAX_VALUE);
Indent indent = GroovyIndentProcessor.getSwitchCaseIndent(settings);
int indentSize = 0;
CommonCodeStyleSettings.IndentOptions options = settings.getIndentOptions();
if (options != null) {
indentSize = options.INDENT_SIZE;
}
if (!finished) {
indent = Indent.getSpaceIndent((indent.getType() == Indent.Type.NORMAL ? indentSize : 0) + indentSize);
}
return new ChildAttributes(indent, null);
}
}
}
return super.getChildAttributes(newChildIndex);
}
};
}
private Wrap getChildWrap(ASTNode childNode) {
return myWrappingProcessor.getChildWrap(childNode);
}
@@ -353,7 +403,14 @@ public class GroovyBlockGenerator {
while (i < flattenChildren.size() &&
flattenChildren.get(i).getElementType() != GroovyElementTypes.LABELED_STATEMENT &&
flattenChildren.get(i).getElementType() != GroovyTokenTypes.mRCURLY);
subBlocks.add(new GrLabelBlock(childNode, flattenChildren.subList(start + 1, i), classLevel, getIndent(childNode), getChildWrap(childNode), myContext));
subBlocks.add(
new GrLabelBlock(
childNode,
flattenChildren.subList(start + 1, i),
classLevel, getIndent(childNode),
getChildWrap(childNode),
myContext)
);
i--;
}
else {
@@ -461,7 +518,8 @@ public class GroovyBlockGenerator {
}
if (spock) {
alignSpockTable(group);
} else {
}
else {
alignVariableDeclarations(group, classLevel);
}
}
@@ -471,7 +529,7 @@ public class GroovyBlockGenerator {
AlignmentProvider.Aligner varName = myAlignmentProvider.createAligner(true);
AlignmentProvider.Aligner eq = myAlignmentProvider.createAligner(true);
for (GrStatement statement : group) {
GrVariableDeclaration varDeclaration = (GrVariableDeclaration) statement;
GrVariableDeclaration varDeclaration = (GrVariableDeclaration)statement;
GrVariable[] variables = varDeclaration.getVariables();
for (GrVariable variable : variables) {
varName.append(variable.getNameIdentifierGroovy());
@@ -511,7 +569,8 @@ public class GroovyBlockGenerator {
private boolean fieldGroupEnded(PsiElement psi) {
if (!myContext.getSettings().ALIGN_GROUP_FIELD_DECLARATIONS) return true;
PsiElement prevSibling = psi.getPrevSibling();
return prevSibling != null && StringUtil.countChars(prevSibling.getText(), '\n') >= myContext.getSettings().KEEP_BLANK_LINES_IN_DECLARATIONS;
return prevSibling != null &&
StringUtil.countChars(prevSibling.getText(), '\n') >= myContext.getSettings().KEEP_BLANK_LINES_IN_DECLARATIONS;
}
private static List<LeafPsiElement> getSpockTable(GrStatement statement) {
@@ -525,12 +584,14 @@ public class GroovyBlockGenerator {
}
}
});
result.sort((l1, l2) -> l1.getStartOffset() - l2.getStartOffset());
result.sort(Comparator.comparingInt(TreeElement::getStartOffset));
return result;
}
private static boolean isTablePart(PsiElement psi) {
return psi instanceof GrBinaryExpression && (GroovyTokenTypes.mBOR == ((GrBinaryExpression)psi).getOperationTokenType() || GroovyTokenTypes.mLOR == ((GrBinaryExpression)psi).getOperationTokenType());
return psi instanceof GrBinaryExpression &&
(GroovyTokenTypes.mBOR == ((GrBinaryExpression)psi).getOperationTokenType() ||
GroovyTokenTypes.mLOR == ((GrBinaryExpression)psi).getOperationTokenType());
}
public static List<ASTNode> visibleChildren(ASTNode node) {
@@ -575,18 +636,19 @@ public class GroovyBlockGenerator {
private static boolean isListLikeClause(PsiElement blockPsi) {
return blockPsi instanceof GrParameterList ||
blockPsi instanceof GrArgumentList ||
blockPsi instanceof GrAssignmentExpression ||
blockPsi instanceof GrExtendsClause ||
blockPsi instanceof GrThrowsClause ||
blockPsi instanceof GrListOrMap;
blockPsi instanceof GrArgumentList ||
blockPsi instanceof GrAssignmentExpression ||
blockPsi instanceof GrExtendsClause ||
blockPsi instanceof GrThrowsClause ||
blockPsi instanceof GrListOrMap;
}
private static boolean isKeyword(ASTNode node) {
if (node == null) return false;
return TokenSets.KEYWORDS.contains(node.getElementType()) ||
TokenSets.BRACES.contains(node.getElementType()) && !PlatformPatterns.psiElement().withText(")").withParent(GrArgumentList.class).afterLeaf(",").accepts(node.getPsi());
TokenSets.BRACES.contains(node.getElementType()) &&
!PlatformPatterns.psiElement().withText(")").withParent(GrArgumentList.class).afterLeaf(",").accepts(node.getPsi());
}
@@ -633,7 +695,6 @@ public class GroovyBlockGenerator {
addChildNodes(child, childNodes, range, root);
}
}
}
/**
@@ -0,0 +1,94 @@
/*
* Copyright 2000-2017 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.
*/
/*
* Copyright 2000-2017 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 org.jetbrains.plugins.groovy.formatter.blocks
import com.intellij.formatting.*
import com.intellij.openapi.util.TextRange
import org.jetbrains.plugins.groovy.formatter.FormattingContext
import org.jetbrains.plugins.groovy.formatter.processors.GroovySpacingProcessor
open class SyntheticGroovyBlock(
private val subBlocks: List<Block>,
private val wrap: Wrap,
private val indent: Indent,
val childIndent: Indent,
val context: FormattingContext) : Block {
init {
if (subBlocks.isEmpty()) throw IllegalArgumentException("SyntheticGroovyBlock should contain at least one child block")
}
override fun getTextRange(): TextRange {
if (subBlocks.isEmpty()) return TextRange.EMPTY_RANGE
return TextRange(subBlocks.first().textRange.startOffset, subBlocks.last().textRange.endOffset)
}
override fun getSubBlocks(): List<Block> {
return subBlocks
}
override fun getWrap(): Wrap {
return wrap
}
override fun getIndent(): Indent {
return indent
}
override fun getAlignment(): Alignment? {
return null
}
override fun getSpacing(child1: Block?, child2: Block): Spacing {
return GroovySpacingProcessor.getSpacing(child1, child2, context)
}
override fun getChildAttributes(newChildIndex: Int): ChildAttributes {
return ChildAttributes(childIndent, null)
}
override fun isIncomplete(): Boolean {
return subBlocks.last().isIncomplete
}
override fun isLeaf(): Boolean {
return false
}
fun getFirstChild(): Block {
return subBlocks.first()
}
fun getLastChild(): Block {
return subBlocks.last()
}
}
@@ -16,6 +16,7 @@
package org.jetbrains.plugins.groovy.formatter.processors;
import com.intellij.formatting.ChildAttributes;
import com.intellij.formatting.Indent;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
@@ -44,7 +45,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgument
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrAssertStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.*;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrCaseSection;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrForClause;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrForInClause;
@@ -62,6 +63,10 @@ import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeParameterList;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrWildcardTypeArgument;
import static com.intellij.formatting.Indent.*;
import static com.intellij.psi.codeStyle.CommonCodeStyleSettings.NEXT_LINE_SHIFTED;
import static com.intellij.psi.codeStyle.CommonCodeStyleSettings.NEXT_LINE_SHIFTED2;
/**
* @author ilyas
*/
@@ -88,22 +93,21 @@ public class GroovyIndentProcessor extends GroovyElementVisitor {
myChildType = child.getElementType();
if (parentBlock instanceof ClosureBodyBlock) {
if (myChildType == GroovyElementTypes.PARAMETERS_LIST) {
return Indent.getNoneIndent();
return getNoneIndent();
}
else if (myChildType != GroovyTokenTypes.mLCURLY && myChildType != GroovyTokenTypes.mRCURLY) {
return Indent.getNormalIndent();
return getNormalIndent();
}
}
if (parentBlock instanceof GrLabelBlock) {
ASTNode first = parentBlock.getNode().getFirstChildNode();
return child == first
? Indent.getNoneIndent()
: Indent.getLabelIndent();
? getNoneIndent()
: getLabelIndent();
}
if (GSTRING_TOKENS_INNER.contains(myChildType)) {
return Indent.getAbsoluteNoneIndent();
return getAbsoluteNoneIndent();
}
final PsiElement parent = parentBlock.getNode().getPsi();
@@ -114,34 +118,34 @@ public class GroovyIndentProcessor extends GroovyElementVisitor {
if (myResult != null) return myResult;
}
return Indent.getNoneIndent();
return getNoneIndent();
}
@Override
public void visitAssertStatement(@NotNull GrAssertStatement assertStatement) {
if (myChildType != GroovyTokenTypes.kASSERT) {
myResult = Indent.getContinuationIndent();
myResult = getContinuationIndent();
}
}
@Override
public void visitAnnotationArrayInitializer(@NotNull GrAnnotationArrayInitializer arrayInitializer) {
if (myChildType != GroovyTokenTypes.mLBRACK && myChildType != GroovyTokenTypes.mRBRACK) {
myResult = Indent.getContinuationWithoutFirstIndent();
myResult = getContinuationWithoutFirstIndent();
}
}
@Override
public void visitListOrMap(@NotNull GrListOrMap listOrMap) {
if (myChildType != GroovyTokenTypes.mLBRACK && myChildType != GroovyTokenTypes.mRBRACK) {
myResult = Indent.getContinuationWithoutFirstIndent();
myResult = getContinuationWithoutFirstIndent();
}
}
@Override
public void visitCaseSection(@NotNull GrCaseSection caseSection) {
if (myChildType != GroovyElementTypes.CASE_LABEL) {
myResult = Indent.getNormalIndent();
myResult = getNormalIndent();
}
}
@@ -157,15 +161,15 @@ public class GroovyIndentProcessor extends GroovyElementVisitor {
if (myChildType == GroovyTokenTypes.mIDENT) {
CommonCodeStyleSettings.IndentOptions indentOptions = myBlock.getContext().getSettings().getIndentOptions();
if (indentOptions != null && indentOptions.LABEL_INDENT_ABSOLUTE) {
myResult = Indent.getAbsoluteLabelIndent();
myResult = getAbsoluteLabelIndent();
}
else if (!myBlock.getContext().getGroovySettings().INDENT_LABEL_BLOCKS) {
myResult = Indent.getLabelIndent();
myResult = getLabelIndent();
}
}
else {
if (myBlock.getContext().getGroovySettings().INDENT_LABEL_BLOCKS) {
myResult = Indent.getLabelIndent();
myResult = getLabelIndent();
}
}
}
@@ -173,17 +177,17 @@ public class GroovyIndentProcessor extends GroovyElementVisitor {
@Override
public void visitAnnotation(@NotNull GrAnnotation annotation) {
if (myChildType == GroovyElementTypes.ANNOTATION_ARGUMENTS) {
myResult = Indent.getContinuationIndent();
myResult = getContinuationIndent();
}
else {
myResult = Indent.getNoneIndent();
myResult = getNoneIndent();
}
}
@Override
public void visitArgumentList(@NotNull GrArgumentList list) {
if (myChildType != GroovyTokenTypes.mLPAREN && myChildType != GroovyTokenTypes.mRPAREN) {
myResult = Indent.getContinuationWithoutFirstIndent();
myResult = getContinuationWithoutFirstIndent();
}
}
@@ -191,18 +195,18 @@ public class GroovyIndentProcessor extends GroovyElementVisitor {
public void visitIfStatement(@NotNull GrIfStatement ifStatement) {
if (TokenSets.BLOCK_SET.contains(myChildType)) {
if (myChild == ifStatement.getCondition()) {
myResult = Indent.getContinuationWithoutFirstIndent();
myResult = getContinuationWithoutFirstIndent();
}
}
else if (myChild == ifStatement.getThenBranch()) {
myResult = Indent.getNormalIndent();
myResult = getNormalIndent();
}
else if (myChild == ifStatement.getElseBranch()) {
if (getGroovySettings().SPECIAL_ELSE_IF_TREATMENT && myChildType == GroovyElementTypes.IF_STATEMENT) {
myResult = Indent.getNoneIndent();
myResult = getNoneIndent();
}
else {
myResult = Indent.getNormalIndent();
myResult = getNormalIndent();
}
}
}
@@ -210,114 +214,119 @@ public class GroovyIndentProcessor extends GroovyElementVisitor {
@Override
public void visitAnnotationArgumentList(@NotNull GrAnnotationArgumentList annotationArgumentList) {
if (myChildType == GroovyTokenTypes.mLPAREN || myChildType == GroovyTokenTypes.mRPAREN) {
myResult = Indent.getNoneIndent();
myResult = getNoneIndent();
}
else {
myResult = Indent.getContinuationIndent();
myResult = getContinuationIndent();
}
}
@Override
public void visitNamedArgument(@NotNull GrNamedArgument argument) {
if (myChild == argument.getExpression()) {
myResult = Indent.getContinuationIndent();
myResult = getContinuationIndent();
}
}
@Override
public void visitVariable(@NotNull GrVariable variable) {
myResult = Indent.getContinuationWithoutFirstIndent();
myResult = getContinuationWithoutFirstIndent();
}
@Override
public void visitEnumConstant(@NotNull GrEnumConstant enumConstant) {
Indent.getNoneIndent();
getNoneIndent();
}
@Override
public void visitDocComment(@NotNull GrDocComment comment) {
if (myChildType != GroovyDocTokenTypes.mGDOC_COMMENT_START) {
myResult = Indent.getSpaceIndent(GDOC_COMMENT_INDENT);
myResult = getSpaceIndent(GDOC_COMMENT_INDENT);
}
}
@Override
public void visitVariableDeclaration(@NotNull GrVariableDeclaration variableDeclaration) {
if (myChild instanceof GrVariable) {
myResult = Indent.getContinuationWithoutFirstIndent();
myResult = getContinuationWithoutFirstIndent();
}
}
@Override
public void visitDocTag(@NotNull GrDocTag docTag) {
if (myChildType != GroovyDocTokenTypes.mGDOC_TAG_NAME) {
myResult = Indent.getSpaceIndent(GDOC_COMMENT_INDENT);
myResult = getSpaceIndent(GDOC_COMMENT_INDENT);
}
}
@Override
public void visitConditionalExpression(@NotNull GrConditionalExpression expression) {
myResult = Indent.getContinuationWithoutFirstIndent();
myResult = getContinuationWithoutFirstIndent();
}
@Override
public void visitAssignmentExpression(@NotNull GrAssignmentExpression expression) {
myResult = Indent.getContinuationWithoutFirstIndent();
myResult = getContinuationWithoutFirstIndent();
}
@Override
public void visitThrowsClause(@NotNull GrThrowsClause throwsClause) {
myResult = Indent.getContinuationWithoutFirstIndent();
myResult = getContinuationWithoutFirstIndent();
}
@Override
public void visitImplementsClause(@NotNull GrImplementsClause implementsClause) {
myResult = Indent.getContinuationWithoutFirstIndent();
myResult = getContinuationWithoutFirstIndent();
}
@Override
public void visitDocMethodParameterList(@NotNull GrDocMethodParams params) {
myResult = Indent.getContinuationWithoutFirstIndent();
myResult = getContinuationWithoutFirstIndent();
}
@Override
public void visitExtendsClause(@NotNull GrExtendsClause extendsClause) {
myResult = Indent.getContinuationWithoutFirstIndent();
myResult = getContinuationWithoutFirstIndent();
}
@Override
public void visitFile(@NotNull GroovyFileBase file) {
myResult = Indent.getNoneIndent();
myResult = getNoneIndent();
}
@Override
public void visitMethod(@NotNull GrMethod method) {
if (myChildType == GroovyElementTypes.PARAMETERS_LIST) {
myResult = Indent.getContinuationIndent();
myResult = getContinuationIndent();
}
else if (myChildType == GroovyElementTypes.THROW_CLAUSE) {
myResult = getGroovySettings().ALIGN_THROWS_KEYWORD ? Indent.getNoneIndent() : Indent.getContinuationIndent();
myResult = getGroovySettings().ALIGN_THROWS_KEYWORD ? getNoneIndent() : getContinuationIndent();
} else if (myChildType == GroovyElementTypes.OPEN_BLOCK) {
myResult = getBlockIndent(getGroovySettings().METHOD_BRACE_STYLE);
}
}
@Override
public void visitTypeDefinition(@NotNull GrTypeDefinition typeDefinition) {
if (myChildType == GroovyElementTypes.EXTENDS_CLAUSE || myChildType == GroovyElementTypes.IMPLEMENTS_CLAUSE) {
myResult = Indent.getContinuationIndent();
myResult = getContinuationIndent();
}
else if (myChildType == GroovyElementTypes.ENUM_BODY || myChildType == GroovyElementTypes.CLASS_BODY) {
myResult = getBlockIndent(getGroovySettings().CLASS_BRACE_STYLE);
}
}
@Override
public void visitTypeDefinitionBody(@NotNull GrTypeDefinitionBody typeDefinitionBody) {
if (myChildType != GroovyTokenTypes.mLCURLY && myChildType != GroovyTokenTypes.mRCURLY) {
myResult = Indent.getNormalIndent();
myResult = getIndentInBlock(getGroovySettings().CLASS_BRACE_STYLE);
}
}
@Override
public void visitClosure(@NotNull GrClosableBlock closure) {
if (myChildType != GroovyTokenTypes.mLCURLY && myChildType != GroovyTokenTypes.mRCURLY) {
myResult = Indent.getNormalIndent();
myResult = getNormalIndent();
}
}
@@ -326,35 +335,43 @@ public class GroovyIndentProcessor extends GroovyElementVisitor {
final IElementType type = block.getNode().getElementType();
if (type != GroovyElementTypes.OPEN_BLOCK && type != GroovyElementTypes.CONSTRUCTOR_BODY) return;
int braceStyle;
PsiElement parent = block.getParent();
if (parent instanceof GrMethod) {
braceStyle = getGroovySettings().METHOD_BRACE_STYLE;
} else {
braceStyle = getGroovySettings().BRACE_STYLE;
}
if (myChildType != GroovyTokenTypes.mLCURLY && myChildType != GroovyTokenTypes.mRCURLY) {
myResult = Indent.getNormalIndent();
myResult = getIndentInBlock(braceStyle);
}
}
@Override
public void visitWhileStatement(@NotNull GrWhileStatement whileStatement) {
if (myChild == (whileStatement).getBody() && !TokenSets.BLOCK_SET.contains(myChildType)) {
myResult = Indent.getNormalIndent();
if (myChild == whileStatement.getBody() && !TokenSets.BLOCK_SET.contains(myChildType)) {
myResult = getNormalIndent();
}
else if (myChild == whileStatement.getCondition()) {
myResult = Indent.getContinuationWithoutFirstIndent();
myResult = getContinuationWithoutFirstIndent();
}
}
@Override
public void visitSynchronizedStatement(@NotNull GrSynchronizedStatement synchronizedStatement) {
if (myChild == synchronizedStatement.getMonitor()) {
myResult = Indent.getContinuationWithoutFirstIndent();
myResult = getContinuationWithoutFirstIndent();
}
}
@Override
public void visitForStatement(@NotNull GrForStatement forStatement) {
if (myChild == forStatement.getBody() && !TokenSets.BLOCK_SET.contains(myChildType)) {
myResult = Indent.getNormalIndent();
myResult = getNormalIndent();
}
else if (myChild == forStatement.getClause()) {
myResult = Indent.getContinuationWithoutFirstIndent();
myResult = getContinuationWithoutFirstIndent();
}
}
@@ -365,56 +382,56 @@ public class GroovyIndentProcessor extends GroovyElementVisitor {
@Override
public void visitParenthesizedExpression(@NotNull GrParenthesizedExpression expression) {
if (myChildType == GroovyTokenTypes.mLPAREN || myChildType == GroovyTokenTypes.mRPAREN) {
myResult = Indent.getNoneIndent();
myResult = getNoneIndent();
}
else {
myResult = Indent.getContinuationIndent();
myResult = getContinuationIndent();
}
}
public static Indent getSwitchCaseIndent(final CommonCodeStyleSettings settings) {
public static Indent getSwitchCaseIndent(@NotNull CommonCodeStyleSettings settings) {
if (settings.INDENT_CASE_FROM_SWITCH) {
return Indent.getNormalIndent();
return getIndentInBlock(settings.BRACE_STYLE);
}
else {
return Indent.getNoneIndent();
return getNoneIndent();
}
}
@Override
public void visitParameterList(@NotNull GrParameterList parameterList) {
myResult = Indent.getContinuationWithoutFirstIndent();
myResult = getContinuationWithoutFirstIndent();
}
@Override
public void visitArrayDeclaration(@NotNull GrArrayDeclaration arrayDeclaration) {
myResult = Indent.getContinuationWithoutFirstIndent();
myResult = getContinuationWithoutFirstIndent();
}
@Override
public void visitExpression(@NotNull GrExpression expression) {
myResult = Indent.getContinuationWithoutFirstIndent();
myResult = getContinuationWithoutFirstIndent();
}
@Override
public void visitTypeArgumentList(@NotNull GrTypeArgumentList typeArgumentList) {
myResult = Indent.getContinuationWithoutFirstIndent();
myResult = getContinuationWithoutFirstIndent();
}
@Override
public void visitCodeReferenceElement(@NotNull GrCodeReferenceElement refElement) {
myResult = Indent.getContinuationWithoutFirstIndent();
myResult = getContinuationWithoutFirstIndent();
}
@Override
public void visitWildcardTypeArgument(@NotNull GrWildcardTypeArgument wildcardTypeArgument) {
myResult = Indent.getContinuationWithoutFirstIndent();
myResult = getContinuationWithoutFirstIndent();
}
@Override
public void visitAnnotationMethod(@NotNull GrAnnotationMethod annotationMethod) {
if (myChild instanceof GrAnnotationMemberValue) {
myResult = Indent.getContinuationIndent();
myResult = getContinuationIndent();
}
else {
super.visitAnnotationMethod(annotationMethod);
@@ -423,35 +440,81 @@ public class GroovyIndentProcessor extends GroovyElementVisitor {
@Override
public void visitAnnotationNameValuePair(@NotNull GrAnnotationNameValuePair nameValuePair) {
myResult = Indent.getContinuationWithoutFirstIndent();
myResult = getContinuationWithoutFirstIndent();
}
@Override
public void visitForInClause(@NotNull GrForInClause forInClause) {
myResult = Indent.getContinuationWithoutFirstIndent();
myResult = getContinuationWithoutFirstIndent();
}
@Override
public void visitForClause(@NotNull GrForClause forClause) {
myResult = Indent.getContinuationWithoutFirstIndent();
myResult = getContinuationWithoutFirstIndent();
}
@Override
public void visitCatchClause(@NotNull GrCatchClause catchClause) {
if (myChild == catchClause.getBody()) {
myResult = Indent.getNoneIndent();
myResult = getBlockIndent(getGroovySettings().BRACE_STYLE);
}
else {
myResult = Indent.getContinuationWithoutFirstIndent();
myResult = getContinuationWithoutFirstIndent();
}
}
@Override
public void visitTryStatement(@NotNull GrTryCatchStatement tryCatchStatement) {
if (myChildType == GroovyElementTypes.OPEN_BLOCK) {
myResult = getBlockIndent(getGroovySettings().BRACE_STYLE);
}
}
@Override
public void visitBlockStatement(@NotNull GrBlockStatement blockStatement) {
myResult = getBlockIndent(getGroovySettings().BRACE_STYLE);
}
@Override
public void visitFinallyClause(@NotNull GrFinallyClause catchClause) {
if (myChildType == GroovyElementTypes.OPEN_BLOCK) {
myResult = getBlockIndent(getGroovySettings().BRACE_STYLE);
}
}
@Override
public void visitTypeParameterList(@NotNull GrTypeParameterList list) {
myResult = Indent.getContinuationWithoutFirstIndent();
myResult = getContinuationWithoutFirstIndent();
}
@NotNull
public static Indent getIndentInBlock(int braceStyle) {
return braceStyle == NEXT_LINE_SHIFTED ? getNoneIndent() : getNormalIndent();
}
@NotNull
public static Indent getBlockIndent(int braceStyle) {
return braceStyle == NEXT_LINE_SHIFTED || braceStyle == NEXT_LINE_SHIFTED2 ? getNormalIndent() : getNoneIndent();
}
public static ChildAttributes getChildSwitchIndent(GrCaseSection psiParent, int newIndex) {
Indent indent = isFinishedCase(psiParent, newIndex) ? getNoneIndent() : getNormalIndent();
return new ChildAttributes(indent, null);
}
public static boolean isFinishedCase(GrCaseSection psiParent, int newIndex) {
final PsiElement[] children = psiParent.getChildren();
newIndex--;
for (int i = 0; i < children.length && i < newIndex; i++) {
PsiElement child = children[i];
if (child instanceof GrBreakStatement ||
child instanceof GrContinueStatement ||
child instanceof GrReturnStatement ||
child instanceof GrThrowStatement) {
return true;
}
}
return false;
}
}
@@ -16,6 +16,7 @@
package org.jetbrains.plugins.groovy.formatter.processors;
import com.intellij.formatting.Block;
import com.intellij.formatting.Spacing;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.TextRange;
@@ -34,6 +35,7 @@ import org.jetbrains.plugins.groovy.formatter.FormattingContext;
import org.jetbrains.plugins.groovy.formatter.GeeseUtil;
import org.jetbrains.plugins.groovy.formatter.blocks.GroovyBlock;
import org.jetbrains.plugins.groovy.formatter.blocks.ParameterListBlock;
import org.jetbrains.plugins.groovy.formatter.blocks.SyntheticGroovyBlock;
import org.jetbrains.plugins.groovy.formatter.models.spacing.SpacingTokens;
import org.jetbrains.plugins.groovy.lang.groovydoc.lexer.GroovyDocTokenTypes;
import org.jetbrains.plugins.groovy.lang.groovydoc.parser.GroovyDocElementTypes;
@@ -552,14 +554,11 @@ public class GroovySpacingProcessor extends GroovyElementVisitor {
if (TokenSets.TYPE_DEFINITIONS.contains(myType1) || isSemiAfter(TokenSets.TYPE_DEFINITIONS) || TokenSets.TYPE_DEFINITIONS.contains((myType2)) ) {
if (myType1 == GroovyDocElementTypes.GROOVY_DOC_COMMENT) {
createLF(true);
return;
}
else {
final int minBlankLines = mySettings.BLANK_LINES_AROUND_CLASS;
myResult = Spacing.createSpacing(0, 0, minBlankLines + 1, mySettings.KEEP_LINE_BREAKS, keepBlankLines());
return;
}
}
}
@@ -1081,5 +1080,23 @@ public class GroovySpacingProcessor extends GroovyElementVisitor {
static boolean isWhiteSpace(final ASTNode node) {
return node != null && (PsiImplUtil.isWhiteSpaceOrNls(node) || node.getTextLength() == 0);
}
public static Spacing getSpacing(@Nullable Block child1, @NotNull Block child2, FormattingContext context) {
if (child1 instanceof SyntheticGroovyBlock) return getSpacing(((SyntheticGroovyBlock)child1).getLastChild(), child2, context);
if (child2 instanceof SyntheticGroovyBlock) return getSpacing(child1, ((SyntheticGroovyBlock)child2).getFirstChild(), context);
if (child1 instanceof GroovyBlock && child2 instanceof GroovyBlock) {
if (((GroovyBlock)child1).getNode() == ((GroovyBlock)child2).getNode()) {
return Spacing.getReadOnlySpacing();
}
Spacing spacing = new GroovySpacingProcessor(((GroovyBlock)child1), (GroovyBlock)child2, context).getSpacing();
if (spacing != null) {
return spacing;
}
return GroovySpacingProcessorBasic.getSpacing(((GroovyBlock)child1), ((GroovyBlock)child2), context);
}
return null;
}
}
@@ -133,4 +133,12 @@ class GroovyCodeStyleFormatterTest extends GroovyFormatterTestCase {
void testSpace_in_named_arg_false() throws Throwable { doTest() }
void testAnonymousVsLBraceOnNewLine() { doTest() }
void testBracesNextLine() { doTest() }
void testBracesNextLineShifted() { doTest() }
void testBracesNextLineShifted2() { doTest() }
void testBracesEndLine() { doTest() }
}
@@ -0,0 +1,52 @@
<option>BRACE_STYLE=END_OF_LINE</option>
<option>METHOD_BRACE_STYLE=END_OF_LINE</option>
<option>CLASS_BRACE_STYLE=END_OF_LINE</option>
class Foo
{
def bar()
{
int a = 0
switch (a)
{
case 1:
case 2:
default:
break
}
for (int b = 0; b < 0; b++)
{
}
try {
int b = 0
} catch(RuntimeException e) {
print e
} finally {
int c = 0
}
}
}
-----
class Foo {
def bar() {
int a = 0
switch (a) {
case 1:
case 2:
default:
break
}
for (int b = 0; b < 0; b++) {
}
try {
int b = 0
} catch (RuntimeException e) {
print e
} finally {
int c = 0
}
}
}
@@ -0,0 +1,53 @@
<option>BRACE_STYLE=NEXT_LINE</option>
<option>METHOD_BRACE_STYLE=NEXT_LINE</option>
<option>CLASS_BRACE_STYLE=NEXT_LINE</option>
class Foo {
def bar() {
int a = 0
switch (a) {
case 1:
case 2:
default:
break
}
for (int b = 0; b < 0; b++) {
}
try {
int b = 0
} catch (RuntimeException e) {
print e
} finally {
int c = 0
}
}
}
-----
class Foo
{
def bar()
{
int a = 0
switch (a)
{
case 1:
case 2:
default:
break
}
for (int b = 0; b < 0; b++)
{
}
try
{
int b = 0
} catch (RuntimeException e)
{
print e
} finally
{
int c = 0
}
}
}
@@ -0,0 +1,53 @@
<option>BRACE_STYLE=NEXT_LINE_SHIFTED</option>
<option>METHOD_BRACE_STYLE=NEXT_LINE_SHIFTED</option>
<option>CLASS_BRACE_STYLE=NEXT_LINE_SHIFTED</option>
class Foo {
def bar() {
int a = 0
switch (a) {
case 1:
case 2:
default:
break
}
for (int b = 0; b < 0; b++) {
}
try {
int b = 0
} catch (RuntimeException e) {
print e
} finally {
int c = 0
}
}
}
-----
class Foo
{
def bar()
{
int a = 0
switch (a)
{
case 1:
case 2:
default:
break
}
for (int b = 0; b < 0; b++)
{
}
try
{
int b = 0
} catch (RuntimeException e)
{
print e
} finally
{
int c = 0
}
}
}
@@ -0,0 +1,53 @@
<option>BRACE_STYLE=NEXT_LINE_SHIFTED2</option>
<option>METHOD_BRACE_STYLE=NEXT_LINE_SHIFTED2</option>
<option>CLASS_BRACE_STYLE=NEXT_LINE_SHIFTED2</option>
class Foo {
def bar() {
int a = 0
switch (a) {
case 1:
case 2:
default:
break
}
for (int b = 0; b < 0; b++) {
}
try {
int b = 0
} catch (RuntimeException e) {
print e
} finally {
int c = 0
}
}
}
-----
class Foo
{
def bar()
{
int a = 0
switch (a)
{
case 1:
case 2:
default:
break
}
for (int b = 0; b < 0; b++)
{
}
try
{
int b = 0
} catch (RuntimeException e)
{
print e
} finally
{
int c = 0
}
}
}
+1 -1
View File
@@ -2,4 +2,4 @@
class A {}
-----
class A
{}
{}