diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyLanguageCodeStyleSettingsProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyLanguageCodeStyleSettingsProvider.java index f855c554159d..828e9939cae2 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyLanguageCodeStyleSettingsProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyLanguageCodeStyleSettingsProvider.java @@ -47,7 +47,72 @@ public class GroovyLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSe return; } if (settingsType == SettingsType.SPACING_SETTINGS) { - consumer.showAllStandardOptions(); + consumer.showStandardOptions("INSERT_FIRST_SPACE_IN_LINE", + "SPACE_AROUND_ASSIGNMENT_OPERATORS", + "SPACE_AROUND_LOGICAL_OPERATORS", + "SPACE_AROUND_EQUALITY_OPERATORS", + "SPACE_AROUND_RELATIONAL_OPERATORS", + "SPACE_AROUND_BITWISE_OPERATORS", + "SPACE_AROUND_ADDITIVE_OPERATORS", + "SPACE_AROUND_MULTIPLICATIVE_OPERATORS", + "SPACE_AROUND_SHIFT_OPERATORS", + "SPACE_AROUND_UNARY_OPERATOR", + "SPACE_AFTER_COMMA", + "SPACE_AFTER_COMMA_IN_TYPE_ARGUMENTS", + "SPACE_BEFORE_COMMA", + "SPACE_AFTER_SEMICOLON", + "SPACE_BEFORE_SEMICOLON", + "SPACE_WITHIN_PARENTHESES", + "SPACE_WITHIN_EMPTY_METHOD_CALL_PARENTHESES", + "SPACE_WITHIN_METHOD_CALL_PARENTHESES", + "SPACE_WITHIN_METHOD_PARENTHESES", + "SPACE_WITHIN_IF_PARENTHESES", + "SPACE_WITHIN_WHILE_PARENTHESES", + "SPACE_WITHIN_FOR_PARENTHESES", +// "SPACE_WITHIN_TRY_PARENTHESES", + "SPACE_WITHIN_CATCH_PARENTHESES", + "SPACE_WITHIN_SWITCH_PARENTHESES", + "SPACE_WITHIN_SYNCHRONIZED_PARENTHESES", + "SPACE_WITHIN_CAST_PARENTHESES", + "SPACE_WITHIN_BRACKETS", + "SPACE_WITHIN_BRACES", +// "SPACE_WITHIN_ARRAY_INITIALIZER_BRACES", + "SPACE_AFTER_TYPE_CAST", + "SPACE_BEFORE_METHOD_CALL_PARENTHESES", + "SPACE_BEFORE_METHOD_PARENTHESES", + "SPACE_BEFORE_IF_PARENTHESES", + "SPACE_BEFORE_WHILE_PARENTHESES", + "SPACE_BEFORE_FOR_PARENTHESES", +// "SPACE_BEFORE_TRY_PARENTHESES", + "SPACE_BEFORE_CATCH_PARENTHESES", + "SPACE_BEFORE_SWITCH_PARENTHESES", + "SPACE_BEFORE_SYNCHRONIZED_PARENTHESES", + "SPACE_BEFORE_CLASS_LBRACE", + "SPACE_BEFORE_METHOD_LBRACE", + "SPACE_BEFORE_IF_LBRACE", + "SPACE_BEFORE_ELSE_LBRACE", + "SPACE_BEFORE_WHILE_LBRACE", + "SPACE_BEFORE_FOR_LBRACE", +// "SPACE_BEFORE_DO_LBRACE", + "SPACE_BEFORE_SWITCH_LBRACE", + "SPACE_BEFORE_TRY_LBRACE", + "SPACE_BEFORE_CATCH_LBRACE", + "SPACE_BEFORE_FINALLY_LBRACE", + "SPACE_BEFORE_SYNCHRONIZED_LBRACE", +// "SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE", +// "SPACE_BEFORE_ANNOTATION_ARRAY_INITIALIZER_LBRACE", + "SPACE_BEFORE_ELSE_KEYWORD", +// "SPACE_BEFORE_WHILE_KEYWORD", + "SPACE_BEFORE_CATCH_KEYWORD", + "SPACE_BEFORE_FINALLY_KEYWORD", + "SPACE_BEFORE_QUEST", + "SPACE_AFTER_QUEST", + "SPACE_BEFORE_COLON", + "SPACE_AFTER_COLON", + "SPACE_BEFORE_TYPE_PARAMETER_LIST", + "SPACE_BEFORE_ANOTATION_PARAMETER_LIST", + "SPACE_WITHIN_ANNOTATION_PARENTHESES" + ); consumer.showCustomOption(GroovyCodeStyleSettings.class, "SPACE_IN_NAMED_ARGUMENT", "In named argument after ':'", CodeStyleSettingsCustomizable.SPACES_OTHER); return; } @@ -145,7 +210,9 @@ public class GroovyLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSe private final static String SPACING_SAMPLE = "class Foo {\n" + - " public static foo(int x, int y) {\n" + + " @Annotation(param=\"foo\")\n"+ + " @Ann([1, 2])\n" + + " public static void foo(int x, int y) {\n" + " for (int i = 0; i < x; i++) {\n" + " y += (y ^ 0x123) << 2\n" + " }\n" + @@ -168,6 +235,7 @@ public class GroovyLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSe " } finally {\n" + " int[] arr = (int[]) g(y)\n" + " x = y >= 0 ? arr[y] : -1\n" + + " y = [1, 2, 3] ?: 4\n" + " }\n" + " }\n" + " }\n" + diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/models/spacing/SpacingTokens.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/models/spacing/SpacingTokens.java index 6a9cd13a571a..b630a9c03145 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/models/spacing/SpacingTokens.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/models/spacing/SpacingTokens.java @@ -27,8 +27,6 @@ public interface SpacingTokens extends GroovyElementTypes { TokenSet LEFT_BRACES = TokenSet.create(mLPAREN, mLBRACK, mLCURLY); TokenSet RIGHT_BRACES = TokenSet.create(mRPAREN, mRBRACK, mRCURLY); - TokenSet PUNCTUATION_SIGNS = TokenSet.create(mDOT, mMEMBER_POINTER, mSPREAD_DOT, mOPTIONAL_DOT, mCOMMA, mSEMI); - TokenSet INDEX_OR_ARRAY = TokenSet.create(PATH_INDEX_PROPERTY, ARRAY_TYPE, ARRAY_DECLARATOR); TokenSet PREFIXES = TokenSet.create(mDEC, mINC, mAT, mBNOT, mLNOT); @@ -36,4 +34,12 @@ public interface SpacingTokens extends GroovyElementTypes { TokenSet PREFIXES_OPTIONAL = TokenSet.create(mPLUS, mMINUS); TokenSet RANGES = TokenSet.create(mRANGE_EXCLUSIVE, mRANGE_INCLUSIVE); + + TokenSet LOGICAL_OPERATORS = TokenSet.create(mLAND, mLOR); + TokenSet EQUALITY_OPERATORS = TokenSet.create(mEQUAL, mNOT_EQUAL); + TokenSet RELATIONAL_OPERATORS = TokenSet.create(mGT, mGE, mLT, mLE); + TokenSet BITWISE_OPERATORS = TokenSet.create(mBAND, mBOR, mBXOR); + TokenSet ADDITIVE_OPERATORS = TokenSet.create(mPLUS, mMINUS); + TokenSet MULTIPLICATIVE_OPERATORS = TokenSet.create(mSTAR, mDIV, mMOD); + TokenSet SHIFT_OPERATORS = TokenSet.create(COMPOSITE_LSHIFT_SIGN, COMPOSITE_RSHIFT_SIGN, COMPOSITE_TRIPLE_SHIFT_SIGN); } 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 a5cf90ab21e9..18c08d51d08a 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,6 +18,7 @@ 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.PsiElement; import com.intellij.psi.PsiIdentifier; @@ -27,22 +28,26 @@ import com.intellij.psi.formatter.FormatterUtil; import com.intellij.psi.impl.source.SourceTreeToPsiMap; import com.intellij.psi.impl.source.tree.CompositeElement; import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.formatter.GeeseUtil; import org.jetbrains.plugins.groovy.formatter.GroovyCodeStyleSettings; import org.jetbrains.plugins.groovy.lang.editor.actions.GroovyEditorActionUtil; import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.*; +import org.jetbrains.plugins.groovy.lang.lexer.TokenSets; import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; +import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation; +import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationArgumentList; +import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationArrayInitializer; import org.jetbrains.plugins.groovy.lang.psi.api.statements.*; 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.GrOpenBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrForInClause; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrNewExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrTypeCastExpression; +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.GrMethodCallExpression; @@ -51,10 +56,13 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefini import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAnnotationMethod; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeArgumentList; +import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeParameterList; import static org.jetbrains.plugins.groovy.GroovyFileType.GROOVY_LANGUAGE; -import static org.jetbrains.plugins.groovy.formatter.models.spacing.SpacingTokens.LEFT_BRACES; -import static org.jetbrains.plugins.groovy.formatter.models.spacing.SpacingTokens.RIGHT_BRACES; +import static org.jetbrains.plugins.groovy.formatter.models.spacing.SpacingTokens.*; +import static org.jetbrains.plugins.groovy.formatter.models.spacing.SpacingTokens.mCOMMA; +import static org.jetbrains.plugins.groovy.formatter.models.spacing.SpacingTokens.mELVIS; +import static org.jetbrains.plugins.groovy.formatter.models.spacing.SpacingTokens.mQUESTION; import static org.jetbrains.plugins.groovy.lang.groovydoc.lexer.GroovyDocTokenTypes.mGDOC_ASTERISKS; import static org.jetbrains.plugins.groovy.lang.groovydoc.lexer.GroovyDocTokenTypes.mGDOC_INLINE_TAG_END; import static org.jetbrains.plugins.groovy.lang.groovydoc.lexer.GroovyDocTokenTypes.mGDOC_INLINE_TAG_START; @@ -79,12 +87,13 @@ import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.mRCURLY; import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.mRPAREN; import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.mSL_COMMENT; import static org.jetbrains.plugins.groovy.lang.lexer.TokenSets.COMMENT_SET; -import static org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes.*; /** * @author ilyas */ public class GroovySpacingProcessor extends GroovyElementVisitor { + private static final Logger LOG = Logger.getInstance(GroovySpacingProcessor.class); + private PsiElement myParent; private final CommonCodeStyleSettings mySettings; @@ -167,7 +176,14 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { @Override public void visitAnnotation(GrAnnotation annotation) { if (myType2 == ANNOTATION_ARGUMENTS) { - myResult = Spacing.createSpacing(0, 0, 0, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE); + createSpaceInCode(mySettings.SPACE_BEFORE_ANOTATION_PARAMETER_LIST); + } + } + + @Override + public void visitAnnotationArgumentList(GrAnnotationArgumentList annotationArgumentList) { + if (myType1 == mLPAREN || myType2 == mRPAREN) { + createSpaceInCode(mySettings.SPACE_WITHIN_ANNOTATION_PARENTHESES); } } @@ -175,7 +191,40 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { if (myType1 == mLBRACK || myType2 == mRBRACK) { createSpaceInCode(mySettings.SPACE_WITHIN_BRACKETS); } - // todo add other cases + else if (myType1 == mLPAREN || myType2 == mRPAREN) { + if (list.getAllArguments().length > 0) { + createSpaceInCode(mySettings.SPACE_WITHIN_METHOD_CALL_PARENTHESES); + } + else { + createSpaceInCode(mySettings.SPACE_WITHIN_EMPTY_METHOD_CALL_PARENTHESES); + } + } + } + + @Override + public void visitConditionalExpression(GrConditionalExpression expression) { + if (myType2 == mQUESTION) { + createSpaceInCode(mySettings.SPACE_BEFORE_QUEST); + } + else if (myType1 == mQUESTION) { + createSpaceInCode(mySettings.SPACE_AFTER_QUEST); + } + else if (myType2 == mCOLON) { + createSpaceInCode(mySettings.SPACE_BEFORE_COLON); + } + else if (myType1 == mCOLON) { + createSpaceInCode(mySettings.SPACE_AFTER_COLON); + } + } + + @Override + public void visitElvisExpression(GrElvisExpression expression) { + if (myType1 == mELVIS) { + createSpaceInCode(mySettings.SPACE_AFTER_COLON); + } + else if (myType2 == mELVIS) { + createSpaceInCode(mySettings.SPACE_BEFORE_QUEST); + } } @Override @@ -198,16 +247,18 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { myResult = Spacing.createSpacing(0, 0, 0, true, 100, 0); } } - else if ((myType1 == mLCURLY && - myType2 != PARAMETERS_LIST && - myType2 != mCLOSABLE_BLOCK_OP) - || myType2 == mRCURLY) { - myResult = Spacing.createDependentLFSpacing(0, 1, closure.getTextRange(), mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE); - } else if (myType1 == mCLOSABLE_BLOCK_OP) { + else if (myType1 == mLCURLY && myType2 != PARAMETERS_LIST && myType2 != mCLOSABLE_BLOCK_OP || myType2 == mRCURLY) { + myResult = Spacing + .createDependentLFSpacing(mySettings.SPACE_WITHIN_BRACES ? 1 : 0, 1, closure.getTextRange(), mySettings.KEEP_LINE_BREAKS, + mySettings.KEEP_BLANK_LINES_IN_CODE); + } + else if (myType1 == mCLOSABLE_BLOCK_OP) { GrStatement[] statements = closure.getStatements(); if (statements.length > 0) { - TextRange range = new TextRange(statements[0].getTextRange().getStartOffset(), statements[statements.length - 1].getTextRange().getEndOffset()); - myResult = Spacing.createDependentLFSpacing(1, Integer.MAX_VALUE, range, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE); + TextRange range = + new TextRange(statements[0].getTextRange().getStartOffset(), statements[statements.length - 1].getTextRange().getEndOffset()); + myResult = + Spacing.createDependentLFSpacing(1, Integer.MAX_VALUE, range, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE); } } } @@ -215,10 +266,12 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { public void visitOpenBlock(GrOpenBlock block) { if (myType1 == mLCURLY && myType2 == mRCURLY && block.getParent() instanceof GrBlockStatement) { myResult = Spacing.createSpacing(1, 1, 1, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE); - } else - if (myType1 == mLCURLY && !GroovyEditorActionUtil.isMultilineStringElement(myChild2) || - myType2 == mRCURLY && !GroovyEditorActionUtil.isMultilineStringElement(myChild1)) { - myResult = Spacing.createDependentLFSpacing(0, 1, block.getTextRange(), mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE); + } + else if (myType1 == mLCURLY && !GroovyEditorActionUtil.isMultilineStringElement(myChild2) || + myType2 == mRCURLY && !GroovyEditorActionUtil.isMultilineStringElement(myChild1)) { + myResult = Spacing + .createDependentLFSpacing(mySettings.SPACE_WITHIN_BRACES ? 1 : 0, 1, block.getTextRange(), mySettings.KEEP_LINE_BREAKS, + mySettings.KEEP_BLANK_LINES_IN_CODE); } } @@ -234,8 +287,7 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { if (myType2 == CLASS_BODY) { PsiIdentifier nameIdentifier = typeDefinition.getNameIdentifier(); int dependenceStart = nameIdentifier == null ? myParent.getTextRange().getStartOffset() : nameIdentifier.getTextRange().getStartOffset(); - myResult = getSpaceBeforeLBrace(mySettings.SPACE_BEFORE_CLASS_LBRACE, mySettings.CLASS_BRACE_STYLE, - new TextRange(dependenceStart, myChild1.getTextRange().getEndOffset()), false); + createSpaceBeforeLBrace(mySettings.SPACE_BEFORE_CLASS_LBRACE, mySettings.CLASS_BRACE_STYLE, new TextRange(dependenceStart, myChild1.getTextRange().getEndOffset()), false); } } @@ -252,11 +304,18 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { @Override public void visitTypeArgumentList(GrTypeArgumentList typeArgumentList) { - if (mLT.equals(myType1) || mGT.equals(myType2)) { + if (myType1 == mLT || myType2 == mGT) { createSpaceProperty(false, true, 1); } } + @Override + public void visitTypeParameterList(GrTypeParameterList list) { + if (myType1 == mCOMMA) { + createSpaceInCode(mySettings.SPACE_AFTER_COMMA_IN_TYPE_ARGUMENTS); + } + } + @Override public void visitForInClause(GrForInClause forInClause) { if (myType1 == PARAMETER && myType2 == mCOLON) { @@ -279,15 +338,18 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { if (myType2 == mLPAREN) { createSpaceInCode(mySettings.SPACE_BEFORE_METHOD_PARENTHESES); } - else if (myType2 == mRPAREN && myType2 == THROW_CLAUSE) { + else if (myType1 == mLPAREN || myType2 == mRPAREN) { + createSpaceInCode(mySettings.SPACE_WITHIN_METHOD_PARENTHESES); + } + else if (myType1 == mRPAREN && myType2 == THROW_CLAUSE) { createSpaceInCode(true); } else if (isOpenBlock(myType2)) { PsiElement methodName = method.getNameIdentifier(); int dependencyStart = methodName == null ? myParent.getTextRange().getStartOffset() : methodName.getTextRange().getStartOffset(); - myResult = getSpaceBeforeLBrace(mySettings.SPACE_BEFORE_METHOD_LBRACE, mySettings.METHOD_BRACE_STYLE, - new TextRange(dependencyStart, myChild1.getTextRange().getEndOffset()), - mySettings.KEEP_SIMPLE_METHODS_IN_ONE_LINE); + createSpaceBeforeLBrace(mySettings.SPACE_BEFORE_METHOD_LBRACE, mySettings.METHOD_BRACE_STYLE, + new TextRange(dependencyStart, myChild1.getTextRange().getEndOffset()), + mySettings.KEEP_SIMPLE_METHODS_IN_ONE_LINE); } else if (myType1 == MODIFIERS) { processModifierList(myChild1); @@ -338,38 +400,102 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { public void visitWhileStatement(GrWhileStatement statement) { if (myType2 == mLPAREN) { createSpaceInCode(mySettings.SPACE_BEFORE_WHILE_PARENTHESES); - } else if (myType1 == mLPAREN || myType2 == mRPAREN) { + } + else if (myType1 == mLPAREN || myType2 == mRPAREN) { createSpaceInCode(mySettings.SPACE_WITHIN_WHILE_PARENTHESES); - } else if (myChild2.getPsi() instanceof GrBlockStatement) { - myResult = getSpaceBeforeLBrace(mySettings.SPACE_BEFORE_WHILE_LBRACE, mySettings.BRACE_STYLE, - new TextRange(myParent.getTextRange().getStartOffset(), myChild1.getTextRange().getEndOffset()), mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE); - } else { + } + else if (myChild2.getPsi() instanceof GrBlockStatement) { + createSpaceBeforeLBrace(mySettings.SPACE_BEFORE_WHILE_LBRACE, mySettings.BRACE_STYLE, + new TextRange(myParent.getTextRange().getStartOffset(), myChild1.getTextRange().getEndOffset()), + mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE); + } + else { createSpacingBeforeElementInsideControlStatement(); } } public void visitCatchClause(GrCatchClause catchClause) { if (isOpenBlock(myType2)) { - myResult = getSpaceBeforeLBrace(mySettings.SPACE_BEFORE_TRY_LBRACE, mySettings.BRACE_STYLE, null, - mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE); + createSpaceBeforeLBrace(mySettings.SPACE_BEFORE_CATCH_LBRACE, mySettings.BRACE_STYLE, null, + mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE); + } + else if (myType2 == mLPAREN) { + createSpaceInCode(mySettings.SPACE_BEFORE_CATCH_PARENTHESES); + } + else if (myType1 == mLPAREN || myType2 == mRPAREN) { + createSpaceInCode(mySettings.SPACE_WITHIN_CATCH_PARENTHESES); } } public void visitFinallyClause(GrFinallyClause catchClause) { if (isOpenBlock(myType2)) { - myResult = getSpaceBeforeLBrace(mySettings.SPACE_BEFORE_TRY_LBRACE, mySettings.BRACE_STYLE, null, - mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE); + createSpaceBeforeLBrace(mySettings.SPACE_BEFORE_FINALLY_LBRACE, mySettings.BRACE_STYLE, null, + mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE); } } public void visitTryStatement(GrTryCatchStatement tryCatchStatement) { if (myType2 == FINALLY_CLAUSE) { - processOnNewLineCondition(mySettings.FINALLY_ON_NEW_LINE); - } else if (isOpenBlock(myType2)) { - myResult = getSpaceBeforeLBrace(mySettings.SPACE_BEFORE_TRY_LBRACE, mySettings.BRACE_STYLE, null, - mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE); - } else if (myType2 == CATCH_CLAUSE) { - processOnNewLineCondition(mySettings.CATCH_ON_NEW_LINE); + processOnNewLineCondition(mySettings.FINALLY_ON_NEW_LINE, mySettings.SPACE_BEFORE_FINALLY_KEYWORD); + } + else if (isOpenBlock(myType2)) { + createSpaceBeforeLBrace(mySettings.SPACE_BEFORE_TRY_LBRACE, mySettings.BRACE_STYLE, null, mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE); + } + else if (myType2 == CATCH_CLAUSE) { + processOnNewLineCondition(mySettings.CATCH_ON_NEW_LINE, mySettings.SPACE_BEFORE_CATCH_KEYWORD); + } + } + + @Override + public void visitAssignmentExpression(GrAssignmentExpression expression) { + if (TokenSets.ASSIGN_OP_SET.contains(myType1) || TokenSets.ASSIGN_OP_SET.contains(myType2)) { + createSpaceInCode(mySettings.SPACE_AROUND_ASSIGNMENT_OPERATORS); + } + } + + @Override + public void visitBinaryExpression(GrBinaryExpression expression) { + if (isLeftOrRight(LOGICAL_OPERATORS)) { + createSpaceInCode(mySettings.SPACE_AROUND_LOGICAL_OPERATORS); + } + else if (isLeftOrRight(EQUALITY_OPERATORS)) { + createSpaceInCode(mySettings.SPACE_AROUND_EQUALITY_OPERATORS); + } + else if (isLeftOrRight(RELATIONAL_OPERATORS)) { + createSpaceInCode(mySettings.SPACE_AROUND_RELATIONAL_OPERATORS); + } + else if (isLeftOrRight(BITWISE_OPERATORS)) { + createSpaceInCode(mySettings.SPACE_AROUND_BITWISE_OPERATORS); + } + else if (isLeftOrRight(ADDITIVE_OPERATORS)) { + createSpaceInCode(mySettings.SPACE_AROUND_ADDITIVE_OPERATORS); + } + else if (isLeftOrRight(MULTIPLICATIVE_OPERATORS)) { + createSpaceInCode(mySettings.SPACE_AROUND_MULTIPLICATIVE_OPERATORS); + } + else if (isLeftOrRight(SHIFT_OPERATORS)) { + createSpaceInCode(mySettings.SPACE_AROUND_SHIFT_OPERATORS); + } + } + + private boolean isLeftOrRight(TokenSet operators) { + return operators.contains(myType1) || operators.contains(myType2); + } + + @Override + public void visitUnaryExpression(GrUnaryExpression expression) { + //prefix only + LOG.assertTrue(!(expression instanceof GrPostfixExpression)); + + if (expression.getOperationToken() == myChild1) { + createSpaceInCode(mySettings.SPACE_AROUND_UNARY_OPERATOR); + } + } + + @Override + public void visitPostfixExpression(GrPostfixExpression expression) { + if (expression.getOperationToken() == myChild2) { + createSpaceInCode(mySettings.SPACE_AROUND_UNARY_OPERATOR); } } @@ -379,8 +505,8 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { } else if (myType1 == mLPAREN || myType2 == mRPAREN) { createSpaceInCode(mySettings.SPACE_WITHIN_SWITCH_PARENTHESES); } else if (myType2 == mLCURLY) { - myResult = getSpaceBeforeLBrace(mySettings.SPACE_BEFORE_SWITCH_LBRACE, mySettings.BRACE_STYLE, null, - mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE); + createSpaceBeforeLBrace(mySettings.SPACE_BEFORE_SWITCH_LBRACE, mySettings.BRACE_STYLE, null, + mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE); } } @@ -390,9 +516,8 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { } else if (myType1 == mLPAREN || myType2 == mRPAREN) { createSpaceInCode(mySettings.SPACE_WITHIN_SYNCHRONIZED_PARENTHESES); } else if (isOpenBlock(myType2)) { - myResult = getSpaceBeforeLBrace(mySettings.SPACE_BEFORE_SYNCHRONIZED_LBRACE, - mySettings.BRACE_STYLE, null, - mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE); + createSpaceBeforeLBrace(mySettings.SPACE_BEFORE_SYNCHRONIZED_LBRACE, mySettings.BRACE_STYLE, null, + mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE); } } @@ -427,43 +552,77 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { } } + @Override + public void visitListOrMap(GrListOrMap listOrMap) { + if (myType1 == mLBRACK || myType2 == mRBRACK) { + createSpaceInCode(mySettings.SPACE_WITHIN_BRACKETS); + } + } + + @Override + public void visitParenthesizedExpression(GrParenthesizedExpression expression) { + if (myType1 == mLPAREN || myType2 == mRPAREN) { + createSpaceInCode(mySettings.SPACE_WITHIN_PARENTHESES); + } + } + + @Override + public void visitAnnotationArrayInitializer(GrAnnotationArrayInitializer arrayInitializer) { + if (myType1 == mLBRACK || myType2 == mRBRACK) { + createSpaceInCode(mySettings.SPACE_WITHIN_BRACKETS); + } + } + + + public void visitIfStatement(GrIfStatement ifStatement) { if (myType2 == kELSE) { if (!isOpenBlock(myType1) && myType1 != BLOCK_STATEMENT) { myResult = Spacing.createSpacing(1, 1, 0, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE); - } else { + } + else { if (mySettings.ELSE_ON_NEW_LINE) { myResult = Spacing.createSpacing(0, 0, 1, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE); - } else { - createSpaceProperty(true, false, 0); + } + else { + createSpaceProperty(mySettings.SPACE_BEFORE_ELSE_KEYWORD, false, 0); } } - } else if (myType1 == kELSE) { + } + else if (myType1 == kELSE) { if (myType2 == IF_STATEMENT) { if (mySettings.SPECIAL_ELSE_IF_TREATMENT) { createSpaceProperty(true, false, 0); - } else { + } + else { myResult = Spacing.createSpacing(1, 1, 1, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE); } - } else { + } + else { if (myType2 == BLOCK_STATEMENT || isOpenBlock(myType2)) { - myResult = getSpaceBeforeLBrace(mySettings.SPACE_BEFORE_ELSE_LBRACE, mySettings.BRACE_STYLE, - null, - mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE); - } else { + createSpaceBeforeLBrace(mySettings.SPACE_BEFORE_ELSE_LBRACE, mySettings.BRACE_STYLE, null, + mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE); + } + else { createSpacingBeforeElementInsideControlStatement(); } } - } else if (myType2 == BLOCK_STATEMENT || isOpenBlock(myType2)) { - boolean space = myChild2.getPsi() == ((GrIfStatement) myParent).getElseBranch() ? mySettings.SPACE_BEFORE_ELSE_LBRACE : mySettings.SPACE_BEFORE_IF_LBRACE; - myResult = getSpaceBeforeLBrace(space, mySettings.BRACE_STYLE, new TextRange(myParent.getTextRange().getStartOffset(), - myChild1.getTextRange().getEndOffset()), - mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE); - } else if (myType2 == mLPAREN) { + } + else if (myType2 == BLOCK_STATEMENT || isOpenBlock(myType2)) { + boolean space = myChild2.getPsi() == ((GrIfStatement)myParent).getElseBranch() + ? mySettings.SPACE_BEFORE_ELSE_LBRACE + : mySettings.SPACE_BEFORE_IF_LBRACE; + createSpaceBeforeLBrace(space, mySettings.BRACE_STYLE, + new TextRange(myParent.getTextRange().getStartOffset(), myChild1.getTextRange().getEndOffset()), + mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE); + } + else if (myType2 == mLPAREN) { createSpaceInCode(mySettings.SPACE_BEFORE_IF_PARENTHESES); - } else if (myType1 == mLPAREN || myType2 == mRPAREN) { + } + else if (myType1 == mLPAREN || myType2 == mRPAREN) { createSpaceInCode(mySettings.SPACE_WITHIN_IF_PARENTHESES); - } else if (((GrIfStatement) myParent).getThenBranch() == myChild2.getPsi()) { + } + else if (((GrIfStatement)myParent).getThenBranch() == myChild2.getPsi()) { createSpacingBeforeElementInsideControlStatement(); } } @@ -490,8 +649,9 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { } else if (myType2 == BLOCK_STATEMENT || isOpenBlock(myType2)) { if (myType2 == BLOCK_STATEMENT) { - myResult = getSpaceBeforeLBrace(mySettings.SPACE_BEFORE_FOR_LBRACE, mySettings.BRACE_STYLE, - new TextRange(myParent.getTextRange().getStartOffset(), myChild1.getTextRange().getEndOffset()), mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE); + createSpaceBeforeLBrace(mySettings.SPACE_BEFORE_FOR_LBRACE, mySettings.BRACE_STYLE, + new TextRange(myParent.getTextRange().getStartOffset(), myChild1.getTextRange().getEndOffset()), + mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE); } else if (mySettings.KEEP_CONTROL_STATEMENT_IN_ONE_LINE) { myResult = Spacing.createDependentLFSpacing(1, 1, myParent.getTextRange(), false, mySettings.KEEP_BLANK_LINES_IN_CODE); } else { @@ -525,15 +685,18 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { } - private void processOnNewLineCondition(final boolean onNewLine) { + private void processOnNewLineCondition(boolean onNewLine, boolean spaceIfNotNewLine) { if (onNewLine) { - if (!mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE) { - myResult = Spacing.createSpacing(0, 0, 1, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE); - } else { - myResult = Spacing.createDependentLFSpacing(0, 1, myParent.getTextRange(), mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE); + if (mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE) { + myResult = + Spacing.createDependentLFSpacing(0, 1, myParent.getTextRange(), mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE); } - } else { - createSpaceProperty(true, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE); + else { + myResult = Spacing.createSpacing(0, 0, 1, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE); + } + } + else { + createSpaceProperty(spaceIfNotNewLine, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE); } } @@ -573,18 +736,24 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { myResult = Spacing.createSpacing(space ? 1 : 0, space ? 1 : 0, 0, keepLineBreaks, keepBlankLines); } - private Spacing getSpaceBeforeLBrace(final boolean spaceBeforeLbrace, int braceStyle, @Nullable TextRange dependantRange, boolean keepOneLine) { + private void createSpaceBeforeLBrace(final boolean spaceBeforeLbrace, + int braceStyle, + @Nullable TextRange dependantRange, + boolean keepOneLine) { if (dependantRange != null && braceStyle == CommonCodeStyleSettings.NEXT_LINE_IF_WRAPPED) { int space = spaceBeforeLbrace ? 1 : 0; - return createNonLFSpace(space, dependantRange, false); - } else if (braceStyle == CommonCodeStyleSettings.END_OF_LINE || braceStyle == CommonCodeStyleSettings.NEXT_LINE_IF_WRAPPED) { + myResult = createNonLFSpace(space, dependantRange, false); + } + else if (braceStyle == CommonCodeStyleSettings.END_OF_LINE || braceStyle == CommonCodeStyleSettings.NEXT_LINE_IF_WRAPPED) { int space = spaceBeforeLbrace ? 1 : 0; - return createNonLFSpace(space, null, false); - } else if (keepOneLine) { + myResult = createNonLFSpace(space, null, false); + } + else if (keepOneLine) { int space = spaceBeforeLbrace ? 1 : 0; - return Spacing.createDependentLFSpacing(space, space, myParent.getTextRange(), mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE); - } else { - return Spacing.createSpacing(0, 0, 1, false, mySettings.KEEP_BLANK_LINES_IN_CODE); + myResult = Spacing.createDependentLFSpacing(space, space, myParent.getTextRange(), mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE); + } + else { + myResult = Spacing.createSpacing(0, 0, 1, false, mySettings.KEEP_BLANK_LINES_IN_CODE); } } 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 cf34326ad3a4..27dcb45224b0 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 @@ -124,8 +124,20 @@ public abstract class GroovySpacingProcessorBasic { } /********** punctuation marks ************/ + if (mCOMMA == leftType) { + return settings.SPACE_AFTER_COMMA ? COMMON_SPACING : NO_SPACING_WITH_NEWLINE; + } + if (mCOMMA == rightType) { + return settings.SPACE_BEFORE_COMMA ? COMMON_SPACING : NO_SPACING_WITH_NEWLINE; + } + if (mSEMI == leftType) { + return settings.SPACE_AFTER_SEMICOLON ? COMMON_SPACING : NO_SPACING_WITH_NEWLINE; + } + if (mSEMI == rightType) { + return settings.SPACE_BEFORE_SEMICOLON ? COMMON_SPACING : NO_SPACING_WITH_NEWLINE; + } // For dots, commas etc. - if ((PUNCTUATION_SIGNS.contains(rightType)) || + if ((DOTS.contains(rightType)) || (mCOLON.equals(rightType) && !(right.getParent() instanceof GrConditionalExpression))) { return NO_SPACING_WITH_NEWLINE; }