diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeStyle/GroovyCodeStyleSettings.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeStyle/GroovyCodeStyleSettings.java index de942838e2dc..12bdef1decb2 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeStyle/GroovyCodeStyleSettings.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeStyle/GroovyCodeStyleSettings.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -49,6 +49,7 @@ public class GroovyCodeStyleSettings extends CustomCodeStyleSettings { public boolean ALIGN_NAMED_ARGS_IN_MAP = false; public boolean SPACE_BEFORE_CLOSURE_LBRACE = true; public boolean SPACE_WITHIN_GSTRING_INJECTION_BRACES = false; + public boolean SPACE_WITHIN_TUPLE_EXPRESSION = false; //imports public boolean USE_FQ_CLASS_NAMES = false; @@ -56,7 +57,7 @@ public class GroovyCodeStyleSettings extends CustomCodeStyleSettings { public boolean USE_SINGLE_CLASS_IMPORTS = true; public boolean INSERT_INNER_CLASS_IMPORTS = false; public int CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND = 5; - public int NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND=3; + public int NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND = 3; public final PackageEntryTable PACKAGES_TO_USE_IMPORT_ON_DEMAND = new PackageEntryTable(); public final PackageEntryTable IMPORT_LAYOUT_TABLE = new PackageEntryTable(); public boolean LAYOUT_STATIC_IMPORTS_SEPARATELY = true; @@ -70,7 +71,6 @@ public class GroovyCodeStyleSettings extends CustomCodeStyleSettings { IMPORT_LAYOUT_TABLE.addEntry(new PackageEntry(false, "java", true)); IMPORT_LAYOUT_TABLE.addEntry(PackageEntry.BLANK_LINE_ENTRY); IMPORT_LAYOUT_TABLE.addEntry(PackageEntry.ALL_OTHER_STATIC_IMPORTS_ENTRY); - } public GroovyCodeStyleSettings(CodeStyleSettings container) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeStyle/GroovyLanguageCodeStyleSettingsProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeStyle/GroovyLanguageCodeStyleSettingsProvider.java index 463aedd710d8..21e615f8a27c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeStyle/GroovyLanguageCodeStyleSettingsProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeStyle/GroovyLanguageCodeStyleSettingsProvider.java @@ -115,10 +115,12 @@ public class GroovyLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSe "SPACE_BEFORE_ANOTATION_PARAMETER_LIST", "SPACE_WITHIN_ANNOTATION_PARENTHESES" ); - consumer.showCustomOption(GroovyCodeStyleSettings.class, "SPACE_IN_NAMED_ARGUMENT", "In named argument after ':'", CodeStyleSettingsCustomizable.SPACES_OTHER); + consumer.showCustomOption(GroovyCodeStyleSettings.class, "SPACE_IN_NAMED_ARGUMENT", "In named argument after ':'", + CodeStyleSettingsCustomizable.SPACES_OTHER); consumer.showCustomOption(GroovyCodeStyleSettings.class, "SPACE_WITHIN_LIST_OR_MAP", "List and maps literals", CodeStyleSettingsCustomizable.SPACES_WITHIN); consumer.showCustomOption(GroovyCodeStyleSettings.class, "SPACE_BEFORE_CLOSURE_LBRACE", "Closure left brace in method calls", CodeStyleSettingsCustomizable.SPACES_BEFORE_LEFT_BRACE); consumer.showCustomOption(GroovyCodeStyleSettings.class, "SPACE_WITHIN_GSTRING_INJECTION_BRACES", "GString injection braces", CodeStyleSettingsCustomizable.SPACES_WITHIN); + consumer.showCustomOption(GroovyCodeStyleSettings.class, "SPACE_WITHIN_TUPLE_EXPRESSION", "Tuple assignment expression", CodeStyleSettingsCustomizable.SPACES_WITHIN); return; } consumer.showAllStandardOptions(); @@ -131,7 +133,7 @@ public class GroovyLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSe defaultSettings.SPACE_WITHIN_BRACES = true; defaultSettings.KEEP_SIMPLE_CLASSES_IN_ONE_LINE = true; defaultSettings.KEEP_SIMPLE_METHODS_IN_ONE_LINE = true; - defaultSettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE = true; + //defaultSettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE = true; return defaultSettings; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessor.java index f042ebb83634..ccc339094d32 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessor.java @@ -18,7 +18,6 @@ package org.jetbrains.plugins.groovy.formatter.processors; import com.intellij.formatting.Spacing; import com.intellij.lang.ASTNode; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; @@ -53,14 +52,17 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrForInClaus import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrStringInjection; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrIndexProperty; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousClassDefinition; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinitionBody; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAnnotationMethod; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrEnumConstant; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.GrTopStatement; import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.packaging.GrPackageDefinition; +import org.jetbrains.plugins.groovy.lang.psi.api.types.GrArrayTypeElement; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeParameterList; @@ -99,8 +101,6 @@ import static org.jetbrains.plugins.groovy.lang.lexer.TokenSets.COMMENT_SET; * @author ilyas */ public class GroovySpacingProcessor extends GroovyElementVisitor { - private static final Logger LOG = Logger.getInstance(GroovySpacingProcessor.class); - private PsiElement myParent; private final CommonCodeStyleSettings mySettings; @@ -115,59 +115,72 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { mySettings = settings; myGroovySettings = groovySettings; - _init(node); - - if (myChild1 == null || myChild2 == null) { - return; - } - - PsiElement psi1 = myChild1.getPsi(); - PsiElement psi2 = myChild2.getPsi(); - if (psi1 == null || psi2 == null) return; - if (psi1.getLanguage() != GROOVY_LANGUAGE || psi2.getLanguage() != GROOVY_LANGUAGE) { - return; - } - - ASTNode prev = getPrevElementType(myChild2); - if (prev != null && prev.getElementType() == mNLS) { - prev = getPrevElementType(prev); - } - if (mySettings.KEEP_FIRST_COLUMN_COMMENT && COMMENT_SET.contains(myType2)) { - if (myType1 != IMPORT_STATEMENT) { - myResult = Spacing.createKeepingFirstColumnSpacing(0, Integer.MAX_VALUE, true, 1); - } - return; - } - if (prev != null && prev.getElementType() == mSL_COMMENT) { - myResult = Spacing.createSpacing(0, Integer.MAX_VALUE, 1, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE); - return; - } - + if (init(node)) return; + if (manageComments()) return; if (myParent instanceof GroovyPsiElement) { ((GroovyPsiElement) myParent).accept(this); } } - private void _init(final ASTNode child) { - if (child != null) { - ASTNode treePrev = child.getTreePrev(); - while (treePrev != null && isWhiteSpace(treePrev)) { - treePrev = treePrev.getTreePrev(); - } - if (treePrev == null) { - _init(child.getTreeParent()); - } - else { - myChild2 = child; - myType2 = myChild2.getElementType(); + private boolean init(ASTNode node) { + _init(node); - myChild1 = treePrev; - myType1 = myChild1.getElementType(); - final CompositeElement parent = (CompositeElement)treePrev.getTreeParent(); - myParent = SourceTreeToPsiMap.treeElementToPsi(parent); - } + if (myChild1 == null || myChild2 == null) { + return true; } + + PsiElement psi1 = myChild1.getPsi(); + PsiElement psi2 = myChild2.getPsi(); + if (psi1 == null || psi2 == null) { + return true; + } + + if (psi1.getLanguage() != GROOVY_LANGUAGE || psi2.getLanguage() != GROOVY_LANGUAGE) { + return true; + } + return false; + } + + private void _init(@Nullable final ASTNode child) { + if (child == null) return; + + ASTNode treePrev = child.getTreePrev(); + while (treePrev != null && isWhiteSpace(treePrev)) { + treePrev = treePrev.getTreePrev(); + } + + if (treePrev == null) { + _init(child.getTreeParent()); + } + else { + myChild2 = child; + myType2 = myChild2.getElementType(); + + myChild1 = treePrev; + myType1 = myChild1.getElementType(); + final CompositeElement parent = (CompositeElement)treePrev.getTreeParent(); + myParent = SourceTreeToPsiMap.treeElementToPsi(parent); + } + } + + private boolean manageComments() { + if (mySettings.KEEP_FIRST_COLUMN_COMMENT && COMMENT_SET.contains(myType2)) { + if (myType1 != IMPORT_STATEMENT) { + myResult = Spacing.createKeepingFirstColumnSpacing(0, Integer.MAX_VALUE, true, 1); + } + return true; + } + + ASTNode prev = FormatterUtil.getPreviousNonWhitespaceLeaf(myChild2); + if (prev != null && prev.getElementType() == mNLS) { + prev = FormatterUtil.getPreviousNonWhitespaceLeaf(prev); + } + if (prev != null && prev.getElementType() == mSL_COMMENT) { + myResult = Spacing.createSpacing(0, Integer.MAX_VALUE, 1, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE); + return true; + } + return false; } @Override @@ -208,6 +221,8 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { } } + + @Override public void visitConditionalExpression(GrConditionalExpression expression) { if (myType2 == mQUESTION) { @@ -236,8 +251,75 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { @Override public void visitMethodCallExpression(GrMethodCallExpression methodCallExpression) { - if (myType2 == ARGUMENTS) createSpaceInCode(mySettings.SPACE_BEFORE_METHOD_CALL_PARENTHESES); - if (myType2 == CLOSABLE_BLOCK) createSpaceInCode(myGroovySettings.SPACE_BEFORE_CLOSURE_LBRACE); + if (myType2 == ARGUMENTS) { + manageSpaceBeforeCallLParenth(); + } + else if (myType2 == CLOSABLE_BLOCK) { + createSpaceInCode(myGroovySettings.SPACE_BEFORE_CLOSURE_LBRACE); + } + } + + private void manageSpaceBeforeCallLParenth() { + createSpaceInCode(mySettings.SPACE_BEFORE_METHOD_CALL_PARENTHESES); + } + + @Override + public void visitApplicationStatement(GrApplicationStatement applicationStatement) { + if (myType2 == ARGUMENTS) manageSpaceBeforeCallLParenth(); + } + + @Override + public void visitIndexProperty(GrIndexProperty expression) { + if (myType2 == ARGUMENTS) manageSpaceBeforeCallLParenth(); + } + + @Override + public void visitConstructorInvocation(GrConstructorInvocation invocation) { + if (myType2 == ARGUMENTS) manageSpaceBeforeCallLParenth(); + } + + public void visitNewExpression(GrNewExpression newExpression) { + if (myType1 == kNEW) { + createSpaceInCode(true); + } + else if (myType2 == ARGUMENTS) { + manageSpaceBeforeCallLParenth(); + } + else if (myType2 == ARRAY_DECLARATOR) { + createSpaceInCode(false); + } + } + + @Override + public void visitArrayDeclaration(GrArrayDeclaration arrayDeclaration) { + createSpaceInCode(false); + } + + @Override + public void visitArrayTypeElement(GrArrayTypeElement typeElement) { + createSpaceInCode(false); + } + + private void manageSpaceInTuple() { + if (myType1 == mLPAREN || myType2 == mRPAREN) { + createSpaceInCode(myGroovySettings.SPACE_WITHIN_TUPLE_EXPRESSION); + } + } + + @Override + public void visitEnumConstant(GrEnumConstant enumConstant) { + manageSpaceBeforeCallLParenth(); + } + + @Override + public void visitVariableDeclaration(GrVariableDeclaration variableDeclaration) { + manageSpaceInTuple(); + } + + + @Override + public void visitTupleExpression(GrTupleExpression tupleExpression) { + manageSpaceInTuple(); } @Override @@ -249,9 +331,6 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { else if (myType2 == PACKAGE_DEFINITION) { myResult = Spacing.createSpacing(0, 0, mySettings.BLANK_LINES_BEFORE_PACKAGE + 1, mySettings.KEEP_LINE_BREAKS, 100); } - else { - super.visitFile(file); - } } @Nullable @@ -285,18 +364,25 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { else if (myType1 == mLCURLY && myType2 == mRCURLY) { //empty closure myResult = Spacing.createSpacing(0, 0, 0, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE); } - else if (closure.getParameters().length == 0 && (myType1 == mLCURLY && myType2 != PARAMETERS_LIST && myType2 != mCLOSABLE_BLOCK_OP || myType2 == mRCURLY)) { //spaces between statements + else if (myType1 == mLCURLY && myType2 != PARAMETERS_LIST && myType2 != mCLOSABLE_BLOCK_OP || myType2 == mRCURLY) { //spaces between statements boolean spacesWithinBraces = closure.getParent() instanceof GrStringInjection ? myGroovySettings.SPACE_WITHIN_GSTRING_INJECTION_BRACES : mySettings.SPACE_WITHIN_BRACES; - int minSpaces = spacesWithinBraces ? 1 : 0; - myResult = Spacing.createDependentLFSpacing(minSpaces, 1, closure.getTextRange(), mySettings.KEEP_LINE_BREAKS, + int space = spacesWithinBraces ? 1 : 0; + myResult = Spacing.createDependentLFSpacing(space, space, closure.getTextRange(), mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE); } else if (myType1 == mCLOSABLE_BLOCK_OP) { myResult = GroovySpacingProcessorBasic.createDependentSpacingForClosure(mySettings, myGroovySettings, closure, true); } + else if (myType1 == mLCURLY && (myType2 == PARAMETERS_LIST || myType2 == mCLOSABLE_BLOCK_OP)) { + boolean spacesWithinBraces = closure.getParent() instanceof GrStringInjection + ? myGroovySettings.SPACE_WITHIN_GSTRING_INJECTION_BRACES + : mySettings.SPACE_WITHIN_BRACES; + createSpaceInCode(spacesWithinBraces); + } + } public void visitOpenBlock(GrOpenBlock block) { @@ -318,15 +404,6 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { } } - public void visitNewExpression(GrNewExpression newExpression) { - if (myType1 == kNEW) { - createSpaceInCode(true); - } - else if (myType2 == ARGUMENTS) { - createSpaceInCode(mySettings.SPACE_BEFORE_METHOD_CALL_PARENTHESES); - } - } - public void visitTypeDefinition(GrTypeDefinition typeDefinition) { if (myType2 == CLASS_BODY) { if (typeDefinition instanceof GrAnonymousClassDefinition) { @@ -339,6 +416,12 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { createSpaceBeforeLBrace(mySettings.SPACE_BEFORE_CLASS_LBRACE, mySettings.CLASS_BRACE_STYLE, range, false); } } + else if (myType2 == TYPE_PARAMETER_LIST) { + manageSpaceBeforeTypeParameters(); + } + else if (myType2 == ARGUMENTS) { + manageSpaceBeforeCallLParenth(); + } } public void visitTypeDefinitionBody(GrTypeDefinitionBody typeDefinitionBody) { @@ -369,6 +452,10 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { if (myType1 == mCOMMA) { createSpaceInCode(mySettings.SPACE_AFTER_COMMA_IN_TYPE_ARGUMENTS); } + else if (myType1 == mLT && myType2 == TYPE_PARAMETER || + myType1 == TYPE_PARAMETER && myType2 == mGT) { + createSpaceInCode(false); + } } @Override @@ -414,10 +501,16 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { else if (myType1 == MODIFIERS) { processModifierList(myChild1); } - else if (COMMENT_SET.contains(myType1) && - (myType2 == MODIFIERS || myType2 == REFERENCE_ELEMENT)) { + else if (COMMENT_SET.contains(myType1) && (myType2 == MODIFIERS || myType2 == REFERENCE_ELEMENT)) { myResult = Spacing.createSpacing(0, 0, 1, mySettings.KEEP_LINE_BREAKS, 0); } + else if (myType2 == TYPE_PARAMETER_LIST) { + manageSpaceBeforeTypeParameters(); + } + } + + private void manageSpaceBeforeTypeParameters() { + createSpaceInCode(false); } @Override @@ -565,12 +658,17 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { public void visitSwitchStatement(GrSwitchStatement switchStatement) { if (myType1 == kSWITCH && myType2 == mLPAREN) { createSpaceInCode(mySettings.SPACE_BEFORE_SWITCH_PARENTHESES); - } else if (myType1 == mLPAREN || myType2 == mRPAREN) { + } + else if (myType1 == mLPAREN || myType2 == mRPAREN) { createSpaceInCode(mySettings.SPACE_WITHIN_SWITCH_PARENTHESES); - } else if (myType2 == mLCURLY) { + } + else if (myType2 == mLCURLY) { createSpaceBeforeLBrace(mySettings.SPACE_BEFORE_SWITCH_LBRACE, mySettings.BRACE_STYLE, null, mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE); } + else if (myType1 == mLCURLY || myType2 == mRCURLY) { + createLF(); + } } public void visitSynchronizedStatement(GrSynchronizedStatement synchronizedStatement) { @@ -851,7 +949,7 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { } private Spacing createNonLFSpace(int spaces, @Nullable final TextRange dependantRange, final boolean keepLineBreaks) { - final ASTNode prev = getPrevElementType(myChild2); + final ASTNode prev = FormatterUtil.getPreviousNonWhitespaceLeaf(myChild2); if (prev != null && prev.getElementType() == mSL_COMMENT) { return Spacing.createSpacing(0, Integer.MAX_VALUE, 1, keepLineBreaks, mySettings.KEEP_BLANK_LINES_IN_CODE); } else if (dependantRange != null) { @@ -864,10 +962,5 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { static boolean isWhiteSpace(final ASTNode node) { return node != null && (TokenSets.WHITE_SPACES_SET.contains(node.getElementType()) || node.getTextLength() == 0); } - - @Nullable - static ASTNode getPrevElementType(final ASTNode child) { - return FormatterUtil.getPreviousNonWhitespaceLeaf(child); - } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessorBasic.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessorBasic.java index 43df2267b5e8..acc4fbcec596 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessorBasic.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessorBasic.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -24,6 +24,7 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiErrorElement; import com.intellij.psi.codeStyle.CommonCodeStyleSettings; import com.intellij.psi.tree.IElementType; +import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.codeStyle.GroovyCodeStyleSettings; import org.jetbrains.plugins.groovy.formatter.ClosureBodyBlock; import org.jetbrains.plugins.groovy.formatter.GroovyBlock; @@ -37,8 +38,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousClassDefinition; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeArgumentList; -import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeParameter; -import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeParameterList; import org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner; import static org.jetbrains.plugins.groovy.formatter.models.spacing.SpacingTokens.*; @@ -75,8 +74,6 @@ public abstract class GroovySpacingProcessorBasic { IElementType leftType = leftNode.getElementType(); IElementType rightType = rightNode.getElementType(); - //Braces Placement - // For multi-line strings if (!(mirrorsAst(child1) && mirrorsAst(child2))) { return NO_SPACING; } @@ -98,24 +95,6 @@ public abstract class GroovySpacingProcessorBasic { return COMMON_SPACING_WITH_NL; } - //For type parameters - if (mLT == leftType && right instanceof GrTypeParameter || - mGT == rightType && left instanceof GrTypeParameter || - mIDENT == leftType && right instanceof GrTypeParameterList) { - return NO_SPACING; - } - - if (ARGUMENTS.equals(rightType)) { - return NO_SPACING; - } - // For left square bracket in array declarations and selections by index - if ((mLBRACK.equals(rightType) && - rightNode.getTreeParent() != null && - INDEX_OR_ARRAY.contains(rightNode.getTreeParent().getElementType())) || - ARRAY_DECLARATOR.equals(rightType)) { - return NO_SPACING; - } - if (METHOD_DEFS.contains(leftType)) { if (rightType == mSEMI) { return NO_SPACING; @@ -130,15 +109,6 @@ public abstract class GroovySpacingProcessorBasic { return Spacing.createSpacing(0, 0, settings.BLANK_LINES_AROUND_METHOD + 1, settings.KEEP_LINE_BREAKS, 100); } - if (leftType == mLCURLY && rightType == PARAMETERS_LIST) { //closure - return LAZY_SPACING; - } - - // For parentheses in arguments and typecasts - if (LEFT_BRACES.contains(leftType) || RIGHT_BRACES.contains(rightType)) { - return NO_SPACING_WITH_NEWLINE; - } - if (right != null && right instanceof GrTypeArgumentList) { return NO_SPACING_WITH_NEWLINE; } @@ -256,15 +226,18 @@ public abstract class GroovySpacingProcessorBasic { return COMMON_SPACING; } - static Spacing createDependentSpacingForClosure(CommonCodeStyleSettings settings, - GroovyCodeStyleSettings groovySettings, GrClosableBlock closure, + @NotNull + static Spacing createDependentSpacingForClosure(@NotNull CommonCodeStyleSettings settings, + @NotNull GroovyCodeStyleSettings groovySettings, + @NotNull GrClosableBlock closure, final boolean forArrow) { boolean spaceWithinBraces = closure.getParent() instanceof GrStringInjection ? groovySettings.SPACE_WITHIN_GSTRING_INJECTION_BRACES : settings.SPACE_WITHIN_BRACES; GrStatement[] statements = closure.getStatements(); if (statements.length > 0) { - int start = statements[0].getTextRange().getStartOffset(); + final PsiElement startElem = forArrow ? statements[0] : closure; + int start = startElem.getTextRange().getStartOffset(); int end = statements[statements.length - 1].getTextRange().getEndOffset(); TextRange range = new TextRange(start, end); @@ -276,6 +249,8 @@ public abstract class GroovySpacingProcessorBasic { } private static boolean mirrorsAst(GroovyBlock block) { - return block.getNode().getTextRange().equals(block.getTextRange()) || block instanceof MethodCallWithoutQualifierBlock || block instanceof ClosureBodyBlock; + return block.getNode().getTextRange().equals(block.getTextRange()) || + block instanceof MethodCallWithoutQualifierBlock || + block instanceof ClosureBodyBlock; } } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/formatter/FormatterTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/formatter/FormatterTest.groovy index aa258ec47e41..422c165d0467 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/formatter/FormatterTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/formatter/FormatterTest.groovy @@ -368,6 +368,116 @@ def foo() ''') } + void testSpacesWithinClosure0() { + groovySettings.SPACE_WITHIN_BRACES = true + checkFormatting('''def cl = {print 2}''', '''def cl = { print 2 }''') + } + + void testSpacesWithinClosure1() { + groovySettings.SPACE_WITHIN_BRACES = true + checkFormatting('''\ +def cl = { +print 2} +''', '''\ +def cl = { + print 2 +} +''') + } + + void testSpacesWithinClosure2() { + groovySettings.SPACE_WITHIN_BRACES = true + checkFormatting('''\ +def cl = {-> +print 2} +''', '''\ +def cl = { -> + print 2 +} +''') + } + + void testSpacesWithinClosure3() { + groovySettings.SPACE_WITHIN_BRACES = true + checkFormatting('''\ +def cl = {def a-> +print 2} +''', '''\ +def cl = { def a -> + print 2 +} +''') + } + + void testSpacesWithinClosure4() { + groovySettings.SPACE_WITHIN_BRACES = true + checkFormatting('''\ +def cl = { +def a-> +print 2} +''', '''\ +def cl = { + def a -> + print 2 +} +''') + } + + void testSpacesWithinClosure5() { + groovySettings.SPACE_WITHIN_BRACES = false + checkFormatting('''def cl = { print 2 }''', '''def cl = {print 2}''') + } + + void testSpacesWithinClosure6() { + groovySettings.SPACE_WITHIN_BRACES = false + checkFormatting('''\ +def cl = { +print 2} +''', '''\ +def cl = { + print 2 +} +''') + } + + void testSpacesWithinClosure7() { + groovySettings.SPACE_WITHIN_BRACES = false + checkFormatting('''\ +def cl = { -> +print 2} +''', '''\ +def cl = {-> + print 2 +} +''') + } + + void testSpacesWithinClosure8() { + groovySettings.SPACE_WITHIN_BRACES = false + checkFormatting('''\ +def cl = { def a-> +print 2} +''', '''\ +def cl = {def a -> + print 2 +} +''') + } + + void testSpacesWithinClosure9() { + groovySettings.SPACE_WITHIN_BRACES = false + checkFormatting('''\ +def cl = { +def a-> +print 2} +''', '''\ +def cl = { + def a -> + print 2 +} +''') + } + private void doGeeseTest() { GroovyCodeStyleSettings customSettings = myTempSettings.getCustomSettings(GroovyCodeStyleSettings.class); boolean oldvalue = customSettings.USE_FLYING_GEESE_BRACES; diff --git a/plugins/groovy/testdata/groovy/actions/smartEnter/catchClause.test b/plugins/groovy/testdata/groovy/actions/smartEnter/catchClause.test index 3d3505d94e59..063a6aaa5375 100644 --- a/plugins/groovy/testdata/groovy/actions/smartEnter/catchClause.test +++ b/plugins/groovy/testdata/groovy/actions/smartEnter/catchClause.test @@ -1,7 +1,8 @@ try {} catch (NumberFormatException e) ----- -try {} +try { +} catch (NumberFormatException e) { } \ No newline at end of file diff --git a/plugins/groovy/testdata/groovy/codeStyle/try2.test b/plugins/groovy/testdata/groovy/codeStyle/try2.test index 850d5a441355..87b6763d27c0 100644 --- a/plugins/groovy/testdata/groovy/codeStyle/try2.test +++ b/plugins/groovy/testdata/groovy/codeStyle/try2.test @@ -4,5 +4,10 @@ try {foo()} catch (E e) {} finally {bar()} ----- -try { foo() } -catch (E e) {} finally { bar() } \ No newline at end of file +try { + foo() +} +catch (E e) { +} finally { + bar() +} \ No newline at end of file diff --git a/plugins/groovy/testdata/groovy/surround/statements/closure1.test b/plugins/groovy/testdata/groovy/surround/statements/closure1.test index 3e63ce0c8ec2..9ec82b5995e0 100644 --- a/plugins/groovy/testdata/groovy/surround/statements/closure1.test +++ b/plugins/groovy/testdata/groovy/surround/statements/closure1.test @@ -1,5 +1,5 @@ return a = b ----- -{-> +{ -> return a = b }.call() \ No newline at end of file diff --git a/plugins/groovy/testdata/groovy/surround/statements/closure2.test b/plugins/groovy/testdata/groovy/surround/statements/closure2.test index fe1f883ea153..e7d2ad5c8b28 100644 --- a/plugins/groovy/testdata/groovy/surround/statements/closure2.test +++ b/plugins/groovy/testdata/groovy/surround/statements/closure2.test @@ -9,7 +9,7 @@ def call() { a() ----- def a() { - {-> + { -> owner.call() }.call() } diff --git a/plugins/groovy/testdata/groovy/surround/statements/closure3.test b/plugins/groovy/testdata/groovy/surround/statements/closure3.test index 74a1bdf68ed3..85061aa3f741 100644 --- a/plugins/groovy/testdata/groovy/surround/statements/closure3.test +++ b/plugins/groovy/testdata/groovy/surround/statements/closure3.test @@ -3,7 +3,7 @@ } ----- { - {-> + { -> owner.call 0 }.call() } \ No newline at end of file