diff --git a/idea/src/org/jetbrains/jet/plugin/formatter/JetBlock.java b/idea/src/org/jetbrains/jet/plugin/formatter/JetBlock.java index 61915ef54eb..3ecca8d8668 100644 --- a/idea/src/org/jetbrains/jet/plugin/formatter/JetBlock.java +++ b/idea/src/org/jetbrains/jet/plugin/formatter/JetBlock.java @@ -22,6 +22,7 @@ import com.intellij.lang.ASTNode; import com.intellij.psi.TokenType; import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CommonCodeStyleSettings; +import com.intellij.psi.formatter.FormatterUtil; import com.intellij.psi.formatter.common.AbstractBlock; import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.TokenSet; @@ -135,11 +136,15 @@ public class JetBlock extends AbstractBlock { @Override public Spacing getSpacing(@Nullable Block child1, @NotNull Block child2) { - Spacing spacing = mySpacingBuilder.getSpacing(this, child1, child2); - if (spacing != null) { - return spacing; + Spacing customSpacing = getCustomSpacing(child1, child2); + if (customSpacing != null) { + return customSpacing; } + return mySpacingBuilder.getSpacing(this, child1, child2); + } + @Nullable + private Spacing getCustomSpacing(@Nullable Block child1, @NotNull Block child2) { // TODO: extend SpacingBuilder API - afterInside(RBRACE, FUNCTION_LITERAL).spacing(...), beforeInside(RBRACE, FUNCTION_LITERAL).spacing(...) if (!(child1 instanceof ASTBlock && child2 instanceof ASTBlock)) { return null; @@ -181,6 +186,20 @@ public class JetBlock extends AbstractBlock { mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE); } + if (parentType == IF && (child2Type == THEN || child2Type == ELSE)) { + ASTNode blockOrExpression = ((ASTBlock) child2).getNode().getFirstChildNode(); + if (blockOrExpression != null && blockOrExpression.getElementType() == BLOCK) { + ASTNode leftBrace = blockOrExpression.getFirstChildNode(); + if (leftBrace != null && leftBrace.getElementType() == LBRACE) { + ASTNode previousLeaf = FormatterUtil.getPreviousNonWhitespaceLeaf(leftBrace); + boolean isAfterEolComment = previousLeaf != null && (previousLeaf.getElementType() == EOL_COMMENT); + boolean keepLineBreaks = jetSettings.LBRACE_ON_NEXT_LINE || isAfterEolComment; + int minimumLF = jetSettings.LBRACE_ON_NEXT_LINE ? 1 : 0; + return Spacing.createSpacing(1, 1, minimumLF, keepLineBreaks, /*don't keep blank lines*/ 0); + } + } + } + return null; } diff --git a/idea/src/org/jetbrains/jet/plugin/formatter/JetCodeStyleSettings.java b/idea/src/org/jetbrains/jet/plugin/formatter/JetCodeStyleSettings.java index a5ddd3afe90..53e691a2635 100644 --- a/idea/src/org/jetbrains/jet/plugin/formatter/JetCodeStyleSettings.java +++ b/idea/src/org/jetbrains/jet/plugin/formatter/JetCodeStyleSettings.java @@ -39,6 +39,8 @@ public class JetCodeStyleSettings extends CustomCodeStyleSettings { public boolean SPACE_AROUND_WHEN_ARROW = true; public boolean SPACE_BEFORE_LAMBDA_ARROW = true; + public boolean LBRACE_ON_NEXT_LINE = false; + public static JetCodeStyleSettings getInstance(Project project) { return CodeStyleSettingsManager.getSettings(project).getCustomSettings(JetCodeStyleSettings.class); } diff --git a/idea/testData/copyPaste/conversion/SeveralMethodsSample.expected.kt b/idea/testData/copyPaste/conversion/SeveralMethodsSample.expected.kt index 5027de905ab..d04b77bd96d 100644 --- a/idea/testData/copyPaste/conversion/SeveralMethodsSample.expected.kt +++ b/idea/testData/copyPaste/conversion/SeveralMethodsSample.expected.kt @@ -3,16 +3,13 @@ class A { private fun formatElement(var element: PsiElement): String { element = JetPsiUtil.ascendIfPropertyAccessor(element) - if (element is JetNamedFunction || element is JetProperty) - { + if (element is JetNamedFunction || element is JetProperty) { val bindingContext = AnalyzerFacadeWithCache.analyzeFileWithCache((element.getContainingFile() as JetFile)).getBindingContext() val declarationDescriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element) - if (declarationDescriptor is CallableMemberDescriptor) - { + if (declarationDescriptor is CallableMemberDescriptor) { val containingDescriptor = declarationDescriptor.getContainingDeclaration() - if (containingDescriptor is ClassDescriptor) - { + if (containingDescriptor is ClassDescriptor) { return JetBundle.message("x.in.y", DescriptorRenderer.COMPACT.render(declarationDescriptor), DescriptorRenderer.SOURCE_CODE_SHORT_NAMES_IN_TYPES.render(containingDescriptor)) } } @@ -29,8 +26,7 @@ class A { public fun getSelected(): ArrayList { val result = ArrayList() for (i in 0..myChecked.length - 1) { - if (myChecked[i]) - { + if (myChecked[i]) { result.add(myOverridingMethods.get(i)) } } diff --git a/idea/testData/formatter/IfElseRemoveLineBreak.after.kt b/idea/testData/formatter/IfElseRemoveLineBreak.after.kt new file mode 100644 index 00000000000..085784b747c --- /dev/null +++ b/idea/testData/formatter/IfElseRemoveLineBreak.after.kt @@ -0,0 +1,16 @@ +fun main(args: Array) { + if (true) { + false + } else if (false) { + true + } else { + } + + if (true) { + } + + if (true) { + } +} + +// SET_FALSE: LBRACE_ON_NEXT_LINE \ No newline at end of file diff --git a/idea/testData/formatter/IfElseRemoveLineBreak.kt b/idea/testData/formatter/IfElseRemoveLineBreak.kt new file mode 100644 index 00000000000..a242e33dc4e --- /dev/null +++ b/idea/testData/formatter/IfElseRemoveLineBreak.kt @@ -0,0 +1,28 @@ +fun main(args: Array) { + if (true) + { + false + } else if (false) + { + true + } else + { + } + + if (true) + + { + } + + if (true) + + + + + + + { + } +} + +// SET_FALSE: LBRACE_ON_NEXT_LINE \ No newline at end of file diff --git a/idea/testData/formatter/IfElseWithLineBreak.after.kt b/idea/testData/formatter/IfElseWithLineBreak.after.kt new file mode 100644 index 00000000000..ed515aa53ec --- /dev/null +++ b/idea/testData/formatter/IfElseWithLineBreak.after.kt @@ -0,0 +1,21 @@ +fun main(args: Array) { + if (true) + { + false + } else if (false) + { + true + } else + { + } + + if (true) + { + } + + if (true) + { + } +} + +// SET_TRUE: LBRACE_ON_NEXT_LINE \ No newline at end of file diff --git a/idea/testData/formatter/IfElseWithLineBreak.kt b/idea/testData/formatter/IfElseWithLineBreak.kt new file mode 100644 index 00000000000..c98f9df157d --- /dev/null +++ b/idea/testData/formatter/IfElseWithLineBreak.kt @@ -0,0 +1,22 @@ +fun main(args: Array) { + if (true) { + false + } else if (false) { + true + } else { + } + + if (true) + + + + { + } + + if (true) + + { + } +} + +// SET_TRUE: LBRACE_ON_NEXT_LINE \ No newline at end of file diff --git a/idea/testData/formatter/IfElseWithTrickyComments.after.inv.kt b/idea/testData/formatter/IfElseWithTrickyComments.after.inv.kt new file mode 100644 index 00000000000..b042c0ab740 --- /dev/null +++ b/idea/testData/formatter/IfElseWithTrickyComments.after.inv.kt @@ -0,0 +1,26 @@ +fun main(args: Array) { + if (true) // tricky comment + { + } + + if (true) //tricky comment + { + } + + if (true) + { + + } else + // 1 + + /*2*/ + + + + /*3*/ + { + } + +} + +// SET_FALSE: LBRACE_ON_NEXT_LINE \ No newline at end of file diff --git a/idea/testData/formatter/IfElseWithTrickyComments.after.kt b/idea/testData/formatter/IfElseWithTrickyComments.after.kt new file mode 100644 index 00000000000..ca11e9393e8 --- /dev/null +++ b/idea/testData/formatter/IfElseWithTrickyComments.after.kt @@ -0,0 +1,24 @@ +fun main(args: Array) { + if (true) // tricky comment + { + } + + if (true) //tricky comment + { + } + + if (true) { + + } else + // 1 + + /*2*/ + + + + /*3*/ { + } + +} + +// SET_FALSE: LBRACE_ON_NEXT_LINE \ No newline at end of file diff --git a/idea/testData/formatter/IfElseWithTrickyComments.kt b/idea/testData/formatter/IfElseWithTrickyComments.kt new file mode 100644 index 00000000000..a3a0d458b0a --- /dev/null +++ b/idea/testData/formatter/IfElseWithTrickyComments.kt @@ -0,0 +1,26 @@ +fun main(args: Array) { + if (true) // tricky comment + { + } + + if (true) //tricky comment + + { + } + + if (true) { + + } else + // 1 + + /*2*/ + + + + /*3*/ + { + } + +} + +// SET_FALSE: LBRACE_ON_NEXT_LINE \ No newline at end of file diff --git a/idea/testData/formatter/IfSpacing.after.kt b/idea/testData/formatter/IfSpacing.after.kt index 0545f1d5691..8027b85d9aa 100644 --- a/idea/testData/formatter/IfSpacing.after.kt +++ b/idea/testData/formatter/IfSpacing.after.kt @@ -19,15 +19,12 @@ fun f() { } else { } - if (true) - { + if (true) { } - else - { + else { } - if (true) - { + if (true) { } else diff --git a/idea/tests/org/jetbrains/jet/formatter/JetFormatterTestGenerated.java b/idea/tests/org/jetbrains/jet/formatter/JetFormatterTestGenerated.java index 028e0357297..c50c67af6c1 100644 --- a/idea/tests/org/jetbrains/jet/formatter/JetFormatterTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/formatter/JetFormatterTestGenerated.java @@ -112,6 +112,21 @@ public class JetFormatterTestGenerated extends AbstractJetFormatterTest { doTest("idea/testData/formatter/If.kt"); } + @TestMetadata("IfElseRemoveLineBreak.kt") + public void testIfElseRemoveLineBreak() throws Exception { + doTest("idea/testData/formatter/IfElseRemoveLineBreak.kt"); + } + + @TestMetadata("IfElseWithLineBreak.kt") + public void testIfElseWithLineBreak() throws Exception { + doTest("idea/testData/formatter/IfElseWithLineBreak.kt"); + } + + @TestMetadata("IfElseWithTrickyComments.kt") + public void testIfElseWithTrickyComments() throws Exception { + doTest("idea/testData/formatter/IfElseWithTrickyComments.kt"); + } + @TestMetadata("IfSpacing.kt") public void testIfSpacing() throws Exception { doTest("idea/testData/formatter/IfSpacing.kt"); diff --git a/j2k/tests/testData/ast/issues/kt-824-isDir.ide.kt b/j2k/tests/testData/ast/issues/kt-824-isDir.ide.kt index f34e446f1b1..a9f9714ed46 100644 --- a/j2k/tests/testData/ast/issues/kt-824-isDir.ide.kt +++ b/j2k/tests/testData/ast/issues/kt-824-isDir.ide.kt @@ -8,13 +8,11 @@ import java.io.File public class Test() { class object { public fun isDir(parent: File): Boolean { - if (parent == null || !parent.exists()) - { + if (parent == null || !parent.exists()) { return false } val result = true - if (parent.isDirectory()) - { + if (parent.isDirectory()) { return true } else diff --git a/j2k/tests/testData/ast/issues/kt-824-isDir.kt b/j2k/tests/testData/ast/issues/kt-824-isDir.kt index 4e088c7b1e4..9a162b3cd0c 100644 --- a/j2k/tests/testData/ast/issues/kt-824-isDir.kt +++ b/j2k/tests/testData/ast/issues/kt-824-isDir.kt @@ -8,13 +8,11 @@ import java.io.File public open class Test() { class object { public open fun isDir(parent: File?): Boolean { - if (parent == null || !parent?.exists()!!) - { + if (parent == null || !parent?.exists()!!) { return false } var result: Boolean = true - if (parent?.isDirectory()!!) - { + if (parent?.isDirectory()!!) { return true } else