diff --git a/annotations/com/intellij/formatting/annotations.xml b/annotations/com/intellij/formatting/annotations.xml
new file mode 100644
index 00000000000..1b6175d1c7d
--- /dev/null
+++ b/annotations/com/intellij/formatting/annotations.xml
@@ -0,0 +1,111 @@
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
\ No newline at end of file
diff --git a/idea/src/org/jetbrains/jet/plugin/formatter/JetBlock.java b/idea/src/org/jetbrains/jet/plugin/formatter/JetBlock.java
index 3ecca8d8668..31591519897 100644
--- a/idea/src/org/jetbrains/jet/plugin/formatter/JetBlock.java
+++ b/idea/src/org/jetbrains/jet/plugin/formatter/JetBlock.java
@@ -47,7 +47,7 @@ public class JetBlock extends AbstractBlock {
private final ASTAlignmentStrategy myAlignmentStrategy;
private final Indent myIndent;
private final CodeStyleSettings mySettings;
- private final SpacingBuilder mySpacingBuilder;
+ private final KotlinSpacingBuilder mySpacingBuilder;
private List mySubBlocks;
@@ -63,7 +63,8 @@ public class JetBlock extends AbstractBlock {
Indent indent,
Wrap wrap,
CodeStyleSettings settings,
- SpacingBuilder spacingBuilder) {
+ KotlinSpacingBuilder spacingBuilder
+ ) {
super(node, wrap, alignmentStrategy.getAlignment(node));
myAlignmentStrategy = alignmentStrategy;
@@ -136,73 +137,9 @@ public class JetBlock extends AbstractBlock {
@Override
public Spacing getSpacing(@Nullable Block child1, @NotNull Block child2) {
- 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;
- }
-
- IElementType parentType = this.getNode().getElementType();
- IElementType child1Type = ((ASTBlock) child1).getNode().getElementType();
- IElementType child2Type = ((ASTBlock) child2).getNode().getElementType();
-
- JetCodeStyleSettings jetSettings = mySettings.getCustomSettings(JetCodeStyleSettings.class);
- int spacesInSimpleMethod = jetSettings.INSERT_WHITESPACES_IN_SIMPLE_ONE_LINE_METHOD ? 1 : 0;
-
- if (parentType == FUNCTION_LITERAL && child1Type == LBRACE && child2Type == BLOCK) {
- return Spacing.createDependentLFSpacing(
- spacesInSimpleMethod, spacesInSimpleMethod, this.getTextRange(),
- mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE);
- }
-
- if (parentType == FUNCTION_LITERAL && child1Type == ARROW && child2Type == BLOCK) {
- return Spacing.createDependentLFSpacing(1, 1, this.getTextRange(), mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE);
- }
-
- if (parentType == FUNCTION_LITERAL && child2Type == RBRACE) {
- return Spacing.createDependentLFSpacing(
- spacesInSimpleMethod, spacesInSimpleMethod, this.getTextRange(),
- mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE);
- }
-
- if (parentType == FUNCTION_LITERAL && child1Type == LBRACE) {
- if (child2Type == VALUE_PARAMETER_LIST) {
- ASTNode firstParamListNode = ((ASTBlock) child2).getNode().getFirstChildNode();
- if (firstParamListNode != null && firstParamListNode.getElementType() == LPAR) {
- // Don't put space for situation {(a: Int) -> a }
- return Spacing.createSpacing(0, 0, 0, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE);
- }
- }
-
- return Spacing.createSpacing(spacesInSimpleMethod, spacesInSimpleMethod, 0,
- 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;
- }
-
@NotNull
@Override
public ChildAttributes getChildAttributes(int newChildIndex) {
diff --git a/idea/src/org/jetbrains/jet/plugin/formatter/JetFormattingModelBuilder.java b/idea/src/org/jetbrains/jet/plugin/formatter/JetFormattingModelBuilder.java
index 5a8fd779048..923143b0039 100644
--- a/idea/src/org/jetbrains/jet/plugin/formatter/JetFormattingModelBuilder.java
+++ b/idea/src/org/jetbrains/jet/plugin/formatter/JetFormattingModelBuilder.java
@@ -16,20 +16,18 @@
package org.jetbrains.jet.plugin.formatter;
-import com.intellij.formatting.*;
+import com.intellij.formatting.FormattingModel;
+import com.intellij.formatting.FormattingModelBuilder;
+import com.intellij.formatting.FormattingModelProvider;
+import com.intellij.formatting.Indent;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CodeStyleSettings;
-import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
-import com.intellij.psi.tree.TokenSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.plugin.JetLanguage;
-import static org.jetbrains.jet.JetNodeTypes.*;
-import static org.jetbrains.jet.lexer.JetTokens.*;
-
public class JetFormattingModelBuilder implements FormattingModelBuilder {
@NotNull
@Override
@@ -37,102 +35,12 @@ public class JetFormattingModelBuilder implements FormattingModelBuilder {
PsiFile containingFile = element.getContainingFile().getViewProvider().getPsi(JetLanguage.INSTANCE);
JetBlock block = new JetBlock(
containingFile.getNode(), ASTAlignmentStrategy.getNullStrategy(), Indent.getNoneIndent(), null, settings,
- createSpacingBuilder(settings));
+ FormatterPackage.createSpacingBuilder(settings));
return FormattingModelProvider.createFormattingModelForPsiFile(
element.getContainingFile(), block, settings);
}
- private static SpacingBuilder createSpacingBuilder(CodeStyleSettings settings) {
- JetCodeStyleSettings jetSettings = settings.getCustomSettings(JetCodeStyleSettings.class);
- CommonCodeStyleSettings jetCommonSettings = settings.getCommonSettings(JetLanguage.INSTANCE);
-
- return new SpacingBuilder(settings, JetLanguage.INSTANCE)
- // ============ Line breaks ==============
- .after(PACKAGE_DIRECTIVE).blankLines(1)
-
- .between(IMPORT_DIRECTIVE, IMPORT_DIRECTIVE).lineBreakInCode()
- .after(IMPORT_LIST).blankLines(1)
-
- .before(DOC_COMMENT).lineBreakInCode()
- .before(FUN).lineBreakInCode()
- .before(PROPERTY).lineBreakInCode()
- .between(FUN, FUN).blankLines(1)
- .between(FUN, PROPERTY).blankLines(1)
-
- .afterInside(LBRACE, BLOCK).lineBreakInCode()
- .beforeInside(RBRACE, CLASS_BODY).lineBreakInCode()
- .beforeInside(RBRACE, BLOCK).lineBreakInCode()
-
- // =============== Spacing ================
- .before(COMMA).spaceIf(jetCommonSettings.SPACE_BEFORE_COMMA)
- .after(COMMA).spaceIf(jetCommonSettings.SPACE_AFTER_COMMA)
-
- .around(TokenSet.create(EQ, MULTEQ, DIVEQ, PLUSEQ, MINUSEQ, PERCEQ)).spaceIf(jetCommonSettings.SPACE_AROUND_ASSIGNMENT_OPERATORS)
- .around(TokenSet.create(ANDAND, OROR)).spaceIf(jetCommonSettings.SPACE_AROUND_LOGICAL_OPERATORS)
- .around(TokenSet.create(EQEQ, EXCLEQ, EQEQEQ, EXCLEQEQEQ)).spaceIf(jetCommonSettings.SPACE_AROUND_EQUALITY_OPERATORS)
- .aroundInside(TokenSet.create(LT, GT, LTEQ, GTEQ), BINARY_EXPRESSION).spaceIf(jetCommonSettings.SPACE_AROUND_RELATIONAL_OPERATORS)
- .aroundInside(TokenSet.create(PLUS, MINUS), BINARY_EXPRESSION).spaceIf(jetCommonSettings.SPACE_AROUND_ADDITIVE_OPERATORS)
- .aroundInside(TokenSet.create(MUL, DIV, PERC), BINARY_EXPRESSION).spaceIf(
- jetCommonSettings.SPACE_AROUND_MULTIPLICATIVE_OPERATORS)
- .around(TokenSet.create(PLUSPLUS, MINUSMINUS, EXCLEXCL, MINUS, PLUS, EXCL)).spaceIf(
- jetCommonSettings.SPACE_AROUND_UNARY_OPERATOR)
- .around(RANGE).spaceIf(jetSettings.SPACE_AROUND_RANGE)
-
- .beforeInside(BLOCK, FUN).spaceIf(jetCommonSettings.SPACE_BEFORE_METHOD_LBRACE)
-
- .afterInside(LPAR, VALUE_PARAMETER_LIST).spaces(0)
- .beforeInside(RPAR, VALUE_PARAMETER_LIST).spaces(0)
- .afterInside(LT, TYPE_PARAMETER_LIST).spaces(0)
- .beforeInside(GT, TYPE_PARAMETER_LIST).spaces(0)
- .afterInside(LPAR, VALUE_ARGUMENT_LIST).spaces(0)
- .beforeInside(RPAR, VALUE_ARGUMENT_LIST).spaces(0)
- .afterInside(LT, TYPE_ARGUMENT_LIST).spaces(0)
- .beforeInside(GT, TYPE_ARGUMENT_LIST).spaces(0)
-
- .betweenInside(FOR_KEYWORD, LPAR, FOR).spacing(1, 1, 0, false, 0)
- .betweenInside(IF_KEYWORD, LPAR, IF).spacing(1, 1, 0, false, 0)
- .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)
- .afterInside(DO_KEYWORD, DO_WHILE).spaces(1)
-
- // TODO: Ask for better API
- // Type of the declaration colon
- .beforeInside(COLON, PROPERTY).spaceIf(jetSettings.SPACE_BEFORE_TYPE_COLON)
- .afterInside(COLON, PROPERTY).spaceIf(jetSettings.SPACE_AFTER_TYPE_COLON)
- .beforeInside(COLON, FUN).spaceIf(jetSettings.SPACE_BEFORE_TYPE_COLON)
- .afterInside(COLON, FUN).spaceIf(jetSettings.SPACE_AFTER_TYPE_COLON)
- .beforeInside(COLON, VALUE_PARAMETER).spaceIf(jetSettings.SPACE_BEFORE_TYPE_COLON)
- .afterInside(COLON, VALUE_PARAMETER).spaceIf(jetSettings.SPACE_AFTER_TYPE_COLON)
-
- // Extends or constraint colon
- .beforeInside(COLON, TYPE_CONSTRAINT).spaceIf(jetSettings.SPACE_BEFORE_EXTEND_COLON)
- .afterInside(COLON, TYPE_CONSTRAINT).spaceIf(jetSettings.SPACE_AFTER_EXTEND_COLON)
- .beforeInside(COLON, CLASS).spaceIf(jetSettings.SPACE_BEFORE_EXTEND_COLON)
- .afterInside(COLON, CLASS).spaceIf(jetSettings.SPACE_AFTER_EXTEND_COLON)
- .beforeInside(COLON, TYPE_PARAMETER).spaceIf(jetSettings.SPACE_BEFORE_EXTEND_COLON)
- .afterInside(COLON, TYPE_PARAMETER).spaceIf(jetSettings.SPACE_AFTER_EXTEND_COLON)
-
- .between(VALUE_ARGUMENT_LIST, FUNCTION_LITERAL_EXPRESSION).spaces(1)
- .beforeInside(ARROW, FUNCTION_LITERAL).spaceIf(jetSettings.SPACE_BEFORE_LAMBDA_ARROW)
-
- //when
- .aroundInside(ARROW, WHEN_ENTRY).spaceIf(jetSettings.SPACE_AROUND_WHEN_ARROW)
- .beforeInside(LBRACE, WHEN).spacing(1, 1, 0, true, 0) //omit blank lines before '{' in 'when' statement
-
- .aroundInside(ARROW, FUNCTION_TYPE).spaceIf(jetSettings.SPACE_AROUND_FUNCTION_TYPE_ARROW)
-
- .betweenInside(REFERENCE_EXPRESSION, FUNCTION_LITERAL_EXPRESSION, CALL_EXPRESSION).spaces(1)
-
- .aroundInside(ELSE_KEYWORD, IF).spaces(1)
- .betweenInside(RPAR, THEN, IF).spaces(1)
-
- .between(RPAR, BODY).spaces(1)
- ;
- }
-
@Override
public TextRange getRangeAffectingIndent(PsiFile psiFile, int i, ASTNode astNode) {
return null;
diff --git a/idea/src/org/jetbrains/jet/plugin/formatter/KotlinSpacingBuilder.kt b/idea/src/org/jetbrains/jet/plugin/formatter/KotlinSpacingBuilder.kt
new file mode 100644
index 00000000000..3789482b76c
--- /dev/null
+++ b/idea/src/org/jetbrains/jet/plugin/formatter/KotlinSpacingBuilder.kt
@@ -0,0 +1,263 @@
+/*
+ * Copyright 2010-2014 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.plugin.formatter
+
+import com.intellij.formatting.*
+
+import org.jetbrains.jet.plugin.JetLanguage
+import com.intellij.psi.codeStyle.CodeStyleSettings
+import java.util.ArrayList
+import org.jetbrains.jet.JetNodeTypes.*
+import org.jetbrains.jet.lexer.JetTokens.*
+import com.intellij.psi.tree.TokenSet
+import com.intellij.psi.tree.IElementType
+import com.intellij.psi.formatter.FormatterUtil
+
+class KotlinSpacingBuilder(val codeStyleSettings: CodeStyleSettings) {
+
+ private val builders = ArrayList()
+
+ private trait Builder {
+ fun getSpacing(parent: ASTBlock, left: ASTBlock, right: ASTBlock): Spacing?
+ }
+
+ inner class BasicSpacingBuilder() : SpacingBuilder(codeStyleSettings, JetLanguage.INSTANCE), Builder {
+ override fun getSpacing(parent: ASTBlock, left: ASTBlock, right: ASTBlock): Spacing? {
+ return super.getSpacing(parent, left, right)
+ }
+ }
+
+ inner class CustomSpacingBuilder() : Builder {
+ private val rules = ArrayList<(ASTBlock, ASTBlock, ASTBlock) -> Spacing?>()
+ private var conditions = ArrayList<(ASTBlock, ASTBlock, ASTBlock) -> Boolean>()
+
+ override fun getSpacing(parent: ASTBlock, left: ASTBlock, right: ASTBlock): Spacing? {
+ for (rule in rules) {
+ val spacing = rule(parent, left, right)
+ if (spacing != null) {
+ return spacing
+ }
+ }
+ return null
+ }
+
+ fun inPosition(parent: IElementType? = null, left: IElementType? = null, right: IElementType? = null): CustomSpacingBuilder {
+ conditions.add {
+ p, l, r ->
+ (parent == null || p.getNode()!!.getElementType() == parent) &&
+ (left == null || l.getNode()!!.getElementType() == left) &&
+ (right == null || r.getNode()!!.getElementType() == right)
+ }
+ return this
+ }
+
+ fun lineBreakIfLineBreakInParent(numSpacesOtherwise: Int) {
+ newRule {
+ p, l, r ->
+ Spacing.createDependentLFSpacing(numSpacesOtherwise, numSpacesOtherwise, p.getTextRange(),
+ codeStyleSettings.KEEP_LINE_BREAKS, codeStyleSettings.KEEP_BLANK_LINES_IN_CODE)
+ }
+ }
+
+ fun customRule(block: (ASTBlock, ASTBlock, ASTBlock) -> Spacing?) {
+ newRule(block)
+ }
+
+ private fun newRule(rule: (ASTBlock, ASTBlock, ASTBlock) -> Spacing?) {
+ val savedConditions = ArrayList(conditions)
+ rules.add { p, l, r -> if (savedConditions.all { it(p, l, r) }) rule(p, l, r) else null }
+ conditions.clear()
+ }
+ }
+
+ fun getSpacing(parent: Block, child1: Block?, child2: Block): Spacing? {
+ if (parent !is ASTBlock || child1 !is ASTBlock || child2 !is ASTBlock) {
+ return null
+ }
+
+ for (builder in builders) {
+ val spacing = builder.getSpacing(parent, child1, child2)
+ if (spacing != null) {
+ return spacing
+ }
+ }
+ return null
+ }
+
+ fun simple(init: BasicSpacingBuilder.() -> Unit) {
+ val builder = BasicSpacingBuilder()
+ builder.init()
+ builders.add(builder)
+ }
+
+ fun custom(init: CustomSpacingBuilder.() -> Unit) {
+ val builder = CustomSpacingBuilder()
+ builder.init()
+ builders.add(builder)
+ }
+}
+
+fun rules(codeStyleSettings: CodeStyleSettings, init: KotlinSpacingBuilder.() -> Unit): KotlinSpacingBuilder {
+ val builder = KotlinSpacingBuilder(codeStyleSettings)
+ builder.init()
+ return builder
+}
+
+fun createSpacingBuilder(settings: CodeStyleSettings): KotlinSpacingBuilder {
+ val jetSettings = settings.getCustomSettings(javaClass())!!
+ val jetCommonSettings = settings.getCommonSettings(JetLanguage.INSTANCE)!!
+ return rules(settings) {
+ custom {
+ val lbraceRuleForControlStructure: (ASTBlock, ASTBlock, ASTBlock) -> Spacing? = {
+ parent, left, right ->
+ val blockOrExpression = right.getNode()!!.getFirstChildNode()
+ if (blockOrExpression != null && blockOrExpression.getElementType() == BLOCK) {
+ val leftBrace = blockOrExpression.getFirstChildNode()
+ when {
+ leftBrace != null && leftBrace.getElementType() == LBRACE -> {
+ val previousLeaf = FormatterUtil.getPreviousNonWhitespaceLeaf(leftBrace)
+ val isAfterEolComment = previousLeaf != null && (previousLeaf.getElementType() == EOL_COMMENT)
+ val keepLineBreaks = jetSettings.LBRACE_ON_NEXT_LINE || isAfterEolComment
+ val minimumLF = if (jetSettings.LBRACE_ON_NEXT_LINE) 1 else 0
+ Spacing.createSpacing(1, 1, minimumLF, keepLineBreaks, 0)
+ }
+ else -> null
+ }
+ }
+ else null
+ }
+ inPosition(parent = IF, right = THEN).customRule(lbraceRuleForControlStructure)
+ inPosition(parent = IF, right = ELSE).customRule(lbraceRuleForControlStructure)
+ }
+ simple {
+ // ============ Line breaks ==============
+ after(PACKAGE_DIRECTIVE).blankLines(1)
+ between(IMPORT_DIRECTIVE, IMPORT_DIRECTIVE).lineBreakInCode()
+ after(IMPORT_LIST).blankLines(1)
+
+ before(DOC_COMMENT).lineBreakInCode()
+ before(FUN).lineBreakInCode()
+ before(PROPERTY).lineBreakInCode()
+ between(FUN, FUN).blankLines(1)
+ between(FUN, PROPERTY).blankLines(1)
+
+ afterInside(LBRACE, BLOCK).lineBreakInCode()
+ beforeInside(RBRACE, CLASS_BODY).lineBreakInCode()
+ beforeInside(RBRACE, BLOCK).lineBreakInCode()
+
+ // =============== Spacing ================
+ before(COMMA).spaceIf(jetCommonSettings.SPACE_BEFORE_COMMA)
+ after(COMMA).spaceIf(jetCommonSettings.SPACE_AFTER_COMMA)
+
+ around(TokenSet.create(EQ, MULTEQ, DIVEQ, PLUSEQ, MINUSEQ, PERCEQ)).spaceIf(jetCommonSettings.SPACE_AROUND_ASSIGNMENT_OPERATORS)
+ around(TokenSet.create(ANDAND, OROR)).spaceIf(jetCommonSettings.SPACE_AROUND_LOGICAL_OPERATORS)
+ around(TokenSet.create(EQEQ, EXCLEQ, EQEQEQ, EXCLEQEQEQ)).spaceIf(jetCommonSettings.SPACE_AROUND_EQUALITY_OPERATORS)
+ aroundInside(TokenSet.create(LT, GT, LTEQ, GTEQ), BINARY_EXPRESSION).spaceIf(jetCommonSettings.SPACE_AROUND_RELATIONAL_OPERATORS)
+ aroundInside(TokenSet.create(PLUS, MINUS), BINARY_EXPRESSION).spaceIf(jetCommonSettings.SPACE_AROUND_ADDITIVE_OPERATORS)
+ aroundInside(TokenSet.create(MUL, DIV, PERC), BINARY_EXPRESSION).spaceIf(jetCommonSettings.SPACE_AROUND_MULTIPLICATIVE_OPERATORS)
+ around(TokenSet.create(PLUSPLUS, MINUSMINUS, EXCLEXCL, MINUS, PLUS, EXCL)).spaceIf(jetCommonSettings.SPACE_AROUND_UNARY_OPERATOR)
+ around(RANGE).spaceIf(jetSettings.SPACE_AROUND_RANGE)
+
+ beforeInside(BLOCK, FUN).spaceIf(jetCommonSettings.SPACE_BEFORE_METHOD_LBRACE)
+
+ afterInside(LPAR, VALUE_PARAMETER_LIST).spaces(0)
+ beforeInside(RPAR, VALUE_PARAMETER_LIST).spaces(0)
+ afterInside(LT, TYPE_PARAMETER_LIST).spaces(0)
+ beforeInside(GT, TYPE_PARAMETER_LIST).spaces(0)
+ afterInside(LPAR, VALUE_ARGUMENT_LIST).spaces(0)
+ beforeInside(RPAR, VALUE_ARGUMENT_LIST).spaces(0)
+ afterInside(LT, TYPE_ARGUMENT_LIST).spaces(0)
+ beforeInside(GT, TYPE_ARGUMENT_LIST).spaces(0)
+
+ betweenInside(FOR_KEYWORD, LPAR, FOR).spacing(1, 1, 0, false, 0)
+ betweenInside(IF_KEYWORD, LPAR, IF).spacing(1, 1, 0, false, 0)
+ 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)
+ afterInside(DO_KEYWORD, DO_WHILE).spaces(1)
+
+ // TODO: Ask for better API
+ // Type of the declaration colon
+ beforeInside(COLON, PROPERTY).spaceIf(jetSettings.SPACE_BEFORE_TYPE_COLON)
+ afterInside(COLON, PROPERTY).spaceIf(jetSettings.SPACE_AFTER_TYPE_COLON)
+ beforeInside(COLON, FUN).spaceIf(jetSettings.SPACE_BEFORE_TYPE_COLON)
+ afterInside(COLON, FUN).spaceIf(jetSettings.SPACE_AFTER_TYPE_COLON)
+ beforeInside(COLON, VALUE_PARAMETER).spaceIf(jetSettings.SPACE_BEFORE_TYPE_COLON)
+ afterInside(COLON, VALUE_PARAMETER).spaceIf(jetSettings.SPACE_AFTER_TYPE_COLON)
+
+ // Extends or constraint colon
+ beforeInside(COLON, TYPE_CONSTRAINT).spaceIf(jetSettings.SPACE_BEFORE_EXTEND_COLON)
+ afterInside(COLON, TYPE_CONSTRAINT).spaceIf(jetSettings.SPACE_AFTER_EXTEND_COLON)
+ beforeInside(COLON, CLASS).spaceIf(jetSettings.SPACE_BEFORE_EXTEND_COLON)
+ afterInside(COLON, CLASS).spaceIf(jetSettings.SPACE_AFTER_EXTEND_COLON)
+ beforeInside(COLON, TYPE_PARAMETER).spaceIf(jetSettings.SPACE_BEFORE_EXTEND_COLON)
+ afterInside(COLON, TYPE_PARAMETER).spaceIf(jetSettings.SPACE_AFTER_EXTEND_COLON)
+
+ between(VALUE_ARGUMENT_LIST, FUNCTION_LITERAL_EXPRESSION).spaces(1)
+ beforeInside(ARROW, FUNCTION_LITERAL).spaceIf(jetSettings.SPACE_BEFORE_LAMBDA_ARROW)
+
+ //when
+ aroundInside(ARROW, WHEN_ENTRY).spaceIf(jetSettings.SPACE_AROUND_WHEN_ARROW)
+ beforeInside(LBRACE, WHEN).spacing(1, 1, 0, true, 0) //omit blank lines before '{' in 'when' statement
+
+ aroundInside(ARROW, FUNCTION_TYPE).spaceIf(jetSettings.SPACE_AROUND_FUNCTION_TYPE_ARROW)
+
+ betweenInside(REFERENCE_EXPRESSION, FUNCTION_LITERAL_EXPRESSION, CALL_EXPRESSION).spaces(1)
+
+ aroundInside(ELSE_KEYWORD, IF).spaces(1)
+ betweenInside(RPAR, THEN, IF).spaces(1)
+
+ between(RPAR, BODY).spaces(1)
+ }
+ custom {
+ val spacesInSimpleFunction = if (jetSettings.INSERT_WHITESPACES_IN_SIMPLE_ONE_LINE_METHOD) 1 else 0
+ inPosition(parent = FUNCTION_LITERAL,
+ left = LBRACE,
+ right = BLOCK)
+ .lineBreakIfLineBreakInParent(numSpacesOtherwise = spacesInSimpleFunction)
+
+ inPosition(parent = FUNCTION_LITERAL,
+ left = ARROW,
+ right = BLOCK)
+ .lineBreakIfLineBreakInParent(numSpacesOtherwise = 1)
+
+ inPosition(parent = FUNCTION_LITERAL,
+ right = RBRACE)
+ .lineBreakIfLineBreakInParent(numSpacesOtherwise = spacesInSimpleFunction)
+
+ inPosition(parent = FUNCTION_LITERAL,
+ left = LBRACE)
+ .customRule {
+ parent, left, right ->
+ val rightNode = right.getNode()!!
+ val rightType = rightNode.getElementType()
+ var numSpaces = spacesInSimpleFunction
+ if (rightType == VALUE_PARAMETER_LIST) {
+ val firstParamListNode = rightNode.getFirstChildNode()
+ if (firstParamListNode != null && firstParamListNode.getElementType() == LPAR) {
+ // Don't put space for situation {(a: Int) -> a }
+ numSpaces = 0
+ }
+ }
+
+ Spacing.createSpacing(numSpaces, numSpaces, 0, settings.KEEP_LINE_BREAKS, settings.KEEP_BLANK_LINES_IN_CODE)
+ }
+ }
+ }
+}
+