From 7dc7db04b3ed1b30b25fa908ea0c874165725bfa Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Fri, 17 Jan 2014 18:59:35 +0400 Subject: [PATCH] Formatter: support "while on new line" option --- .../JetLanguageCodeStyleSettingsProvider.java | 3 +- .../plugin/formatter/KotlinSpacingBuilder.kt | 32 +++++++++++-------- .../formatter/DoWhileSpacing.after.kt | 6 ++-- .../formatter/WhileOnNewLine.after.inv.kt | 16 ++++++++++ .../formatter/WhileOnNewLine.after.kt | 18 +++++++++++ idea/testData/formatter/WhileOnNewLine.kt | 17 ++++++++++ .../formatter/JetFormatterTestGenerated.java | 10 ++++++ j2k/tests/testData/ast/issues/kt-824.ide.kt | 3 +- j2k/tests/testData/ast/issues/kt-824.kt | 3 +- 9 files changed, 86 insertions(+), 22 deletions(-) create mode 100644 idea/testData/formatter/WhileOnNewLine.after.inv.kt create mode 100644 idea/testData/formatter/WhileOnNewLine.after.kt create mode 100644 idea/testData/formatter/WhileOnNewLine.kt diff --git a/idea/src/org/jetbrains/jet/plugin/formatter/JetLanguageCodeStyleSettingsProvider.java b/idea/src/org/jetbrains/jet/plugin/formatter/JetLanguageCodeStyleSettingsProvider.java index 9cf68e32449..3b657deb7dd 100644 --- a/idea/src/org/jetbrains/jet/plugin/formatter/JetLanguageCodeStyleSettingsProvider.java +++ b/idea/src/org/jetbrains/jet/plugin/formatter/JetLanguageCodeStyleSettingsProvider.java @@ -142,7 +142,8 @@ public class JetLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSetti "ALIGN_MULTILINE_PARAMETERS", "ALIGN_MULTILINE_PARAMETERS_IN_CALLS", "ALIGN_MULTILINE_METHOD_BRACKETS", - "ELSE_ON_NEW_LINE" + "ELSE_ON_NEW_LINE", + "WHILE_ON_NEW_LINE" ); consumer.renameStandardOption(CodeStyleSettingsCustomizable.WRAPPING_SWITCH_STATEMENT, "'when' statements"); consumer.showCustomOption(JetCodeStyleSettings.class, "ALIGN_IN_COLUMNS_CASE_BRANCH", "Align in columns 'case' branches", diff --git a/idea/src/org/jetbrains/jet/plugin/formatter/KotlinSpacingBuilder.kt b/idea/src/org/jetbrains/jet/plugin/formatter/KotlinSpacingBuilder.kt index 6cfdc0620e0..42419c510b3 100644 --- a/idea/src/org/jetbrains/jet/plugin/formatter/KotlinSpacingBuilder.kt +++ b/idea/src/org/jetbrains/jet/plugin/formatter/KotlinSpacingBuilder.kt @@ -27,6 +27,7 @@ import com.intellij.psi.tree.TokenSet import com.intellij.psi.tree.IElementType import com.intellij.psi.formatter.FormatterUtil import com.intellij.lang.ASTNode +import org.jetbrains.jet.plugin.formatter.KotlinSpacingBuilder.CustomSpacingBuilder class KotlinSpacingBuilder(val codeStyleSettings: CodeStyleSettings) { @@ -161,8 +162,6 @@ fun createSpacingBuilder(settings: CodeStyleSettings): KotlinSpacingBuilder { betweenInside(WHILE_KEYWORD, LPAR, WHILE).spacing(1, 1, 0, false, 0) betweenInside(WHILE_KEYWORD, LPAR, DO_WHILE).spacing(1, 1, 0, false, 0) - aroundInside(WHILE_KEYWORD, DO_WHILE).spaces(1) - // TODO: Ask for better API // Type of the declaration colon beforeInside(COLON, PROPERTY).spaceIf(jetSettings.SPACE_BEFORE_TYPE_COLON) @@ -188,20 +187,27 @@ fun createSpacingBuilder(settings: CodeStyleSettings): KotlinSpacingBuilder { betweenInside(REFERENCE_EXPRESSION, FUNCTION_LITERAL_EXPRESSION, CALL_EXPRESSION).spaces(1) } custom { - if (jetCommonSettings.ELSE_ON_NEW_LINE) { - inPosition(parent = IF, right = ELSE_KEYWORD) - .lineBreakIfLineBreakInParent(numSpacesOtherwise = 1) - } - else { - inPosition(parent = IF, left = THEN, right = ELSE_KEYWORD).customRule { - parent, left, right -> - // do not remove linebreak if "then" expression is not a block - val expressionOrBlock = left.getNode()!!.getFirstChildNode() - val keepLineBreaks = expressionOrBlock == null || expressionOrBlock.getElementType() != BLOCK - Spacing.createSpacing(1, 1, 0, keepLineBreaks, 0) + + fun CustomSpacingBuilder.ruleForKeywordOnNewLine(shouldBeOnNewLine: Boolean, keyword: IElementType, parent: IElementType) { + if (shouldBeOnNewLine) { + inPosition(parent = parent, right = keyword) + .lineBreakIfLineBreakInParent(numSpacesOtherwise = 1) + } + else { + inPosition(parent = parent, right = keyword).customRule { + parent, left, right -> + // do not remove linebreak if expression to the left is not a block + val previousNonWhitespaceLeaf = FormatterUtil.getPreviousNonWhitespaceLeaf(right.getNode()) + val keepLineBreaks = previousNonWhitespaceLeaf == null || previousNonWhitespaceLeaf.getElementType() != RBRACE + Spacing.createSpacing(1, 1, 0, keepLineBreaks, 0) + } } } + ruleForKeywordOnNewLine(jetCommonSettings.ELSE_ON_NEW_LINE, keyword = ELSE_KEYWORD, parent = IF) + ruleForKeywordOnNewLine(jetCommonSettings.WHILE_ON_NEW_LINE, keyword = WHILE_KEYWORD, parent = DO_WHILE) + + fun spacingForLeftBrace(block: ASTNode?, blockType: IElementType = BLOCK): Spacing? { if (block != null && block.getElementType() == blockType) { val leftBrace = block.findChildByType(LBRACE) diff --git a/idea/testData/formatter/DoWhileSpacing.after.kt b/idea/testData/formatter/DoWhileSpacing.after.kt index bb2d1fd2e26..3f6483460ec 100644 --- a/idea/testData/formatter/DoWhileSpacing.after.kt +++ b/idea/testData/formatter/DoWhileSpacing.after.kt @@ -6,12 +6,10 @@ fun test() { } while (true) do { - } - while (true) + } while (true) do { - } - while (true) + } while (true) do { } while (true) diff --git a/idea/testData/formatter/WhileOnNewLine.after.inv.kt b/idea/testData/formatter/WhileOnNewLine.after.inv.kt new file mode 100644 index 00000000000..4c9863a3243 --- /dev/null +++ b/idea/testData/formatter/WhileOnNewLine.after.inv.kt @@ -0,0 +1,16 @@ +fun f() { + do { + + } while (true) + + do { + + } while (true) + + do a += 1 while (true) + + do a += 1 + while (true) +} + +// SET_TRUE: WHILE_ON_NEW_LINE \ No newline at end of file diff --git a/idea/testData/formatter/WhileOnNewLine.after.kt b/idea/testData/formatter/WhileOnNewLine.after.kt new file mode 100644 index 00000000000..d8413603c1b --- /dev/null +++ b/idea/testData/formatter/WhileOnNewLine.after.kt @@ -0,0 +1,18 @@ +fun f() { + do { + + } + while (true) + + do { + + } + while (true) + + do a += 1 while (true) + + do a += 1 + while (true) +} + +// SET_TRUE: WHILE_ON_NEW_LINE \ No newline at end of file diff --git a/idea/testData/formatter/WhileOnNewLine.kt b/idea/testData/formatter/WhileOnNewLine.kt new file mode 100644 index 00000000000..90fc6f22dfe --- /dev/null +++ b/idea/testData/formatter/WhileOnNewLine.kt @@ -0,0 +1,17 @@ +fun f() { + do { + + } while (true) + + do { + + } + while (true) + + do a += 1 while (true) + + do a += 1 + while (true) +} + +// SET_TRUE: WHILE_ON_NEW_LINE \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/formatter/JetFormatterTestGenerated.java b/idea/tests/org/jetbrains/jet/formatter/JetFormatterTestGenerated.java index 77fa36cc376..5ff4320d12e 100644 --- a/idea/tests/org/jetbrains/jet/formatter/JetFormatterTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/formatter/JetFormatterTestGenerated.java @@ -269,6 +269,11 @@ public class JetFormatterTestGenerated extends AbstractJetFormatterTest { doTest("idea/testData/formatter/WhileLineBreak.after.kt"); } + @TestMetadata("WhileOnNewLine.after.kt") + public void testWhileOnNewLine() throws Exception { + doTest("idea/testData/formatter/WhileOnNewLine.after.kt"); + } + @TestMetadata("WhileSpacing.after.kt") public void testWhileSpacing() throws Exception { doTest("idea/testData/formatter/WhileSpacing.after.kt"); @@ -477,6 +482,11 @@ public class JetFormatterTestGenerated extends AbstractJetFormatterTest { doTestInverted("idea/testData/formatter/WhileLineBreak.after.inv.kt"); } + @TestMetadata("WhileOnNewLine.after.inv.kt") + public void testWhileOnNewLine() throws Exception { + doTestInverted("idea/testData/formatter/WhileOnNewLine.after.inv.kt"); + } + public static Test innerSuite() { TestSuite suite = new TestSuite("FormatterInverted"); suite.addTestSuite(FormatterInverted.class); diff --git a/j2k/tests/testData/ast/issues/kt-824.ide.kt b/j2k/tests/testData/ast/issues/kt-824.ide.kt index 470a8a75464..0c65acfe367 100644 --- a/j2k/tests/testData/ast/issues/kt-824.ide.kt +++ b/j2k/tests/testData/ast/issues/kt-824.ide.kt @@ -25,7 +25,6 @@ class Test() { do { System.out.println("Ok") - } - while (One.myContainer.myBoolean) + } while (One.myContainer.myBoolean) } } \ No newline at end of file diff --git a/j2k/tests/testData/ast/issues/kt-824.kt b/j2k/tests/testData/ast/issues/kt-824.kt index 59c87ef49a1..a2330e6e817 100644 --- a/j2k/tests/testData/ast/issues/kt-824.kt +++ b/j2k/tests/testData/ast/issues/kt-824.kt @@ -25,7 +25,6 @@ open class Test() { do { System.out?.println("Ok") - } - while (One.myContainer?.myBoolean!!) + } while (One.myContainer?.myBoolean!!) } } \ No newline at end of file