New formatter option: Align in columns 'case' branches

This commit is contained in:
Andrey Ponomarev
2013-02-20 18:08:31 +01:00
committed by Nikolay Krasko
parent 6a7e72bfc5
commit c91cd9b962
8 changed files with 52 additions and 15 deletions
@@ -17,6 +17,7 @@
package org.jetbrains.jet.plugin.formatter; package org.jetbrains.jet.plugin.formatter;
import com.intellij.formatting.*; import com.intellij.formatting.*;
import com.intellij.formatting.alignment.AlignmentStrategy;
import com.intellij.lang.ASTNode; import com.intellij.lang.ASTNode;
import com.intellij.psi.TokenType; import com.intellij.psi.TokenType;
import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CodeStyleSettings;
@@ -37,6 +38,7 @@ import static org.jetbrains.jet.lexer.JetTokens.*;
* @see Block for good JavaDoc documentation * @see Block for good JavaDoc documentation
*/ */
public class JetBlock extends AbstractBlock { public class JetBlock extends AbstractBlock {
private final ASTAlignmentStrategy myAlignmentStrategy;
private final Indent myIndent; private final Indent myIndent;
private final CodeStyleSettings mySettings; private final CodeStyleSettings mySettings;
private final SpacingBuilder mySpacingBuilder; private final SpacingBuilder mySpacingBuilder;
@@ -51,13 +53,14 @@ public class JetBlock extends AbstractBlock {
// private static final List<IndentWhitespaceRule> // private static final List<IndentWhitespaceRule>
public JetBlock(@NotNull ASTNode node, public JetBlock(@NotNull ASTNode node,
Alignment alignment, ASTAlignmentStrategy alignmentStrategy,
Indent indent, Indent indent,
Wrap wrap, Wrap wrap,
CodeStyleSettings settings, CodeStyleSettings settings,
SpacingBuilder spacingBuilder) { SpacingBuilder spacingBuilder) {
super(node, wrap, alignment); super(node, wrap, alignmentStrategy.getAlignment(node));
myAlignmentStrategy = alignmentStrategy;
myIndent = indent; myIndent = indent;
mySettings = settings; mySettings = settings;
mySpacingBuilder = spacingBuilder; mySpacingBuilder = spacingBuilder;
@@ -90,25 +93,24 @@ public class JetBlock extends AbstractBlock {
continue; continue;
} }
Alignment childAlignment = childrenAlignmentStrategy.getAlignment(child); blocks.add(buildSubBlock(child, childrenAlignmentStrategy));
blocks.add(buildSubBlock(child, childAlignment));
} }
return Collections.unmodifiableList(blocks); return Collections.unmodifiableList(blocks);
} }
@NotNull @NotNull
private Block buildSubBlock(@NotNull ASTNode child, Alignment childAlignment) { private Block buildSubBlock(@NotNull ASTNode child, ASTAlignmentStrategy alignmentStrategy) {
Wrap wrap = null; Wrap wrap = null;
// Affects to spaces around operators... // Affects to spaces around operators...
if (child.getElementType() == OPERATION_REFERENCE) { if (child.getElementType() == OPERATION_REFERENCE) {
ASTNode operationNode = child.getFirstChildNode(); ASTNode operationNode = child.getFirstChildNode();
if (operationNode != null) { if (operationNode != null) {
return new JetBlock(operationNode, childAlignment, Indent.getNoneIndent(), wrap, mySettings, mySpacingBuilder); return new JetBlock(operationNode, alignmentStrategy, Indent.getNoneIndent(), wrap, mySettings, mySpacingBuilder);
} }
} }
return new JetBlock(child, childAlignment, createChildIndent(child), wrap, mySettings, mySpacingBuilder); return new JetBlock(child, alignmentStrategy, createChildIndent(child), wrap, mySettings, mySpacingBuilder);
} }
private static Indent indentIfNotBrace(@NotNull ASTNode child) { private static Indent indentIfNotBrace(@NotNull ASTNode child) {
@@ -221,9 +223,10 @@ public class JetBlock extends AbstractBlock {
private ASTAlignmentStrategy getChildrenAlignmentStrategy() { private ASTAlignmentStrategy getChildrenAlignmentStrategy() {
CommonCodeStyleSettings jetCommonSettings = mySettings.getCommonSettings(JetLanguage.INSTANCE); CommonCodeStyleSettings jetCommonSettings = mySettings.getCommonSettings(JetLanguage.INSTANCE);
JetCodeStyleSettings jetSettings = mySettings.getCustomSettings(JetCodeStyleSettings.class);
// Prepare default null strategy // Prepare default null strategy
ASTAlignmentStrategy strategy = ASTAlignmentStrategy.getNullStrategy(); ASTAlignmentStrategy strategy = myAlignmentStrategy;
// Redefine list of strategies for some special elements // Redefine list of strategies for some special elements
IElementType parentType = myNode.getElementType(); IElementType parentType = myNode.getElementType();
@@ -237,6 +240,9 @@ public class JetBlock extends AbstractBlock {
jetCommonSettings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS, VALUE_ARGUMENT, COMMA, jetCommonSettings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS, VALUE_ARGUMENT, COMMA,
jetCommonSettings.ALIGN_MULTILINE_METHOD_BRACKETS, LPAR, RPAR); jetCommonSettings.ALIGN_MULTILINE_METHOD_BRACKETS, LPAR, RPAR);
} }
else if (parentType == WHEN) {
strategy = getAlignmentForCaseBranch(jetSettings.ALIGN_IN_COLUMNS_CASE_BRANCH);
}
return strategy; return strategy;
} }
@@ -271,6 +277,16 @@ public class JetBlock extends AbstractBlock {
}; };
} }
private static ASTAlignmentStrategy getAlignmentForCaseBranch(boolean shouldAlignInColumns) {
if (shouldAlignInColumns) {
return ASTAlignmentStrategy
.fromTypes(AlignmentStrategy.createAlignmentPerTypeStrategy(Arrays.asList((IElementType) ARROW), WHEN_ENTRY, true));
}
else {
return ASTAlignmentStrategy.getNullStrategy();
}
}
static ASTIndentStrategy[] INDENT_RULES = new ASTIndentStrategy[] { static ASTIndentStrategy[] INDENT_RULES = new ASTIndentStrategy[] {
ASTIndentStrategy.forNode("No indent for braces in blocks") ASTIndentStrategy.forNode("No indent for braces in blocks")
.in(BLOCK, CLASS_BODY, FUNCTION_LITERAL) .in(BLOCK, CLASS_BODY, FUNCTION_LITERAL)
@@ -32,6 +32,7 @@ public class JetCodeStyleSettings extends CustomCodeStyleSettings {
public boolean SPACE_AFTER_EXTEND_COLON = true; public boolean SPACE_AFTER_EXTEND_COLON = true;
public boolean INSERT_WHITESPACES_IN_SIMPLE_ONE_LINE_METHOD = true; public boolean INSERT_WHITESPACES_IN_SIMPLE_ONE_LINE_METHOD = true;
public boolean ALIGN_IN_COLUMNS_CASE_BRANCH = false;
public static JetCodeStyleSettings getInstance(Project project) { public static JetCodeStyleSettings getInstance(Project project) {
return CodeStyleSettingsManager.getSettings(project).getCustomSettings(JetCodeStyleSettings.class); return CodeStyleSettingsManager.getSettings(project).getCustomSettings(JetCodeStyleSettings.class);
@@ -35,7 +35,7 @@ public class JetFormattingModelBuilder implements FormattingModelBuilder {
@Override @Override
public FormattingModel createModel(PsiElement element, CodeStyleSettings settings) { public FormattingModel createModel(PsiElement element, CodeStyleSettings settings) {
final JetBlock block = new JetBlock( final JetBlock block = new JetBlock(
element.getNode(), null, Indent.getNoneIndent(), null, settings, element.getNode(), ASTAlignmentStrategy.getNullStrategy(), Indent.getNoneIndent(), null, settings,
createSpacingBuilder(settings)); createSpacingBuilder(settings));
return FormattingModelProvider.createFormattingModelForPsiFile( return FormattingModelProvider.createFormattingModelForPsiFile(
@@ -104,6 +104,7 @@ public class JetFormattingModelBuilder implements FormattingModelBuilder {
.afterInside(COLON, TYPE_PARAMETER).spaceIf(jetSettings.SPACE_AFTER_EXTEND_COLON) .afterInside(COLON, TYPE_PARAMETER).spaceIf(jetSettings.SPACE_AFTER_EXTEND_COLON)
.between(VALUE_ARGUMENT_LIST, FUNCTION_LITERAL_EXPRESSION).spaces(1) .between(VALUE_ARGUMENT_LIST, FUNCTION_LITERAL_EXPRESSION).spaces(1)
.aroundInside(ARROW, WHEN_ENTRY).spaces(1)
; ;
} }
@@ -41,6 +41,10 @@ public class JetLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSetti
" private fun foo1(i1: Int,\n" + " private fun foo1(i1: Int,\n" +
" i2: Int,\n" + " i2: Int,\n" +
" i3: Int) : Int {\n" + " i3: Int) : Int {\n" +
" when (i1) {\n" +
" is Number -> 0\n" +
" else -> 1\n" +
" }\n" +
" return 0\n" + " return 0\n" +
" }\n" + " }\n" +
" private fun foo2():Int {\n" + " private fun foo2():Int {\n" +
@@ -116,6 +120,9 @@ public class JetLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSetti
"ALIGN_MULTILINE_PARAMETERS_IN_CALLS", "ALIGN_MULTILINE_PARAMETERS_IN_CALLS",
"ALIGN_MULTILINE_METHOD_BRACKETS" "ALIGN_MULTILINE_METHOD_BRACKETS"
); );
consumer.renameStandardOption(CodeStyleSettingsCustomizable.WRAPPING_SWITCH_STATEMENT, "'when' statements");
consumer.showCustomOption(JetCodeStyleSettings.class, "ALIGN_IN_COLUMNS_CASE_BRANCH", "Align in columns 'case' branches",
CodeStyleSettingsCustomizable.WRAPPING_SWITCH_STATEMENT);
break; break;
default: default:
consumer.showStandardOptions(); consumer.showStandardOptions();
+5 -3
View File
@@ -1,6 +1,8 @@
fun some(x : Any) { fun some(x : Any) {
when (x) { when (x) {
is Int -> 0 is Number -> 0
else -> 1 else->1
} }
} }
// SET_FALSE: ALIGN_IN_COLUMNS_CASE_BRANCH
+4 -2
View File
@@ -1,6 +1,8 @@
fun some(x: Any) { fun some(x: Any) {
when (x) { when (x) {
is Int -> 0 is Number -> 0
else -> 1 else -> 1
} }
} }
// SET_FALSE: ALIGN_IN_COLUMNS_CASE_BRANCH
@@ -0,0 +1,8 @@
fun some(x: Any) {
when (x) {
is Number -> 0
else -> 1
}
}
// SET_FALSE: ALIGN_IN_COLUMNS_CASE_BRANCH
@@ -121,7 +121,7 @@ public class JetFormatterTest extends AbstractJetFormatterTest {
} }
public void testWhen() throws Exception { public void testWhen() throws Exception {
doTest(); doTestWithInvert();
} }
public void testWhenEntryExpr() throws Exception { public void testWhenEntryExpr() throws Exception {