Add wrap option for expression body functions
#KT-21470 Fixed
This commit is contained in:
+1
@@ -46,6 +46,7 @@ public class KotlinCodeStyleSettings extends CustomCodeStyleSettings {
|
|||||||
public boolean CONTINUATION_INDENT_FOR_CHAINED_CALLS = true;
|
public boolean CONTINUATION_INDENT_FOR_CHAINED_CALLS = true;
|
||||||
public boolean CONTINUATION_INDENT_IN_SUPERTYPE_LISTS = true;
|
public boolean CONTINUATION_INDENT_IN_SUPERTYPE_LISTS = true;
|
||||||
public int BLANK_LINES_AROUND_BLOCK_WHEN_BRANCHES = 0;
|
public int BLANK_LINES_AROUND_BLOCK_WHEN_BRANCHES = 0;
|
||||||
|
public int WRAP_EXPRESSION_BODY_FUNCTIONS = 0;
|
||||||
|
|
||||||
public KotlinCodeStyleSettings(CodeStyleSettings container) {
|
public KotlinCodeStyleSettings(CodeStyleSettings container) {
|
||||||
super("JetCodeStyleSettings", container);
|
super("JetCodeStyleSettings", container);
|
||||||
|
|||||||
@@ -337,6 +337,7 @@ abstract class KotlinCommonBlock(
|
|||||||
private fun getWrappingStrategy(): WrappingStrategy {
|
private fun getWrappingStrategy(): WrappingStrategy {
|
||||||
val commonSettings = settings.kotlinCommonSettings
|
val commonSettings = settings.kotlinCommonSettings
|
||||||
val elementType = node.elementType
|
val elementType = node.elementType
|
||||||
|
val parentElementType = node.treeParent?.elementType
|
||||||
val nodePsi = node.psi
|
val nodePsi = node.psi
|
||||||
|
|
||||||
when {
|
when {
|
||||||
@@ -344,7 +345,6 @@ abstract class KotlinCommonBlock(
|
|||||||
return getWrappingStrategyForItemList(commonSettings.CALL_PARAMETERS_WRAP, KtNodeTypes.VALUE_ARGUMENT)
|
return getWrappingStrategyForItemList(commonSettings.CALL_PARAMETERS_WRAP, KtNodeTypes.VALUE_ARGUMENT)
|
||||||
|
|
||||||
elementType === KtNodeTypes.VALUE_PARAMETER_LIST -> {
|
elementType === KtNodeTypes.VALUE_PARAMETER_LIST -> {
|
||||||
val parentElementType = node.treeParent.elementType
|
|
||||||
if (parentElementType === KtNodeTypes.FUN ||
|
if (parentElementType === KtNodeTypes.FUN ||
|
||||||
parentElementType === KtNodeTypes.PRIMARY_CONSTRUCTOR ||
|
parentElementType === KtNodeTypes.PRIMARY_CONSTRUCTOR ||
|
||||||
parentElementType === KtNodeTypes.SECONDARY_CONSTRUCTOR) {
|
parentElementType === KtNodeTypes.SECONDARY_CONSTRUCTOR) {
|
||||||
@@ -402,7 +402,17 @@ abstract class KotlinCommonBlock(
|
|||||||
return wrapAfterAnnotation(commonSettings.CLASS_ANNOTATION_WRAP)
|
return wrapAfterAnnotation(commonSettings.CLASS_ANNOTATION_WRAP)
|
||||||
|
|
||||||
nodePsi is KtNamedFunction ->
|
nodePsi is KtNamedFunction ->
|
||||||
return wrapAfterAnnotation(commonSettings.METHOD_ANNOTATION_WRAP)
|
return object : WrappingStrategy {
|
||||||
|
override fun getWrap(childElement: ASTNode): Wrap? {
|
||||||
|
getWrapAfterAnnotation(childElement, commonSettings.METHOD_ANNOTATION_WRAP)?.let {
|
||||||
|
return it
|
||||||
|
}
|
||||||
|
if (getPrevWithoutWhitespaceAndComments(childElement)?.elementType == KtTokens.EQ) {
|
||||||
|
return Wrap.createWrap(settings.kotlinCustomSettings.WRAP_EXPRESSION_BODY_FUNCTIONS, true)
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nodePsi is KtProperty ->
|
nodePsi is KtProperty ->
|
||||||
return wrapAfterAnnotation(if (nodePsi.isLocal)
|
return wrapAfterAnnotation(if (nodePsi.isLocal)
|
||||||
@@ -422,21 +432,25 @@ private fun ASTNode.isFirstParameter(): Boolean = treePrev?.elementType == KtTok
|
|||||||
private fun wrapAfterAnnotation(wrapType: Int): WrappingStrategy {
|
private fun wrapAfterAnnotation(wrapType: Int): WrappingStrategy {
|
||||||
return object : WrappingStrategy {
|
return object : WrappingStrategy {
|
||||||
override fun getWrap(childElement: ASTNode): Wrap? {
|
override fun getWrap(childElement: ASTNode): Wrap? {
|
||||||
if (childElement.elementType in KtTokens.COMMENTS) return null
|
return getWrapAfterAnnotation(childElement, wrapType)
|
||||||
var prevLeaf = childElement.treePrev
|
|
||||||
while (prevLeaf?.elementType == TokenType.WHITE_SPACE) {
|
|
||||||
prevLeaf = prevLeaf.treePrev
|
|
||||||
}
|
|
||||||
if (prevLeaf?.elementType == KtNodeTypes.MODIFIER_LIST) {
|
|
||||||
if (prevLeaf?.lastChildNode?.elementType in ANNOTATIONS) {
|
|
||||||
return Wrap.createWrap(wrapType, true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getWrapAfterAnnotation(childElement: ASTNode, wrapType: Int): Wrap? {
|
||||||
|
if (childElement.elementType in COMMENTS) return null
|
||||||
|
var prevLeaf = childElement.treePrev
|
||||||
|
while (prevLeaf?.elementType == TokenType.WHITE_SPACE) {
|
||||||
|
prevLeaf = prevLeaf.treePrev
|
||||||
|
}
|
||||||
|
if (prevLeaf?.elementType == KtNodeTypes.MODIFIER_LIST) {
|
||||||
|
if (prevLeaf?.lastChildNode?.elementType in ANNOTATIONS) {
|
||||||
|
return Wrap.createWrap(wrapType, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
private val INDENT_RULES = arrayOf<NodeIndentStrategy>(
|
private val INDENT_RULES = arrayOf<NodeIndentStrategy>(
|
||||||
strategy("No indent for braces in blocks")
|
strategy("No indent for braces in blocks")
|
||||||
.within(KtNodeTypes.BLOCK, KtNodeTypes.CLASS_BODY, KtNodeTypes.FUNCTION_LITERAL)
|
.within(KtNodeTypes.BLOCK, KtNodeTypes.CLASS_BODY, KtNodeTypes.FUNCTION_LITERAL)
|
||||||
|
|||||||
@@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2017 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.kotlin.idea.formatter
|
|
||||||
|
|
||||||
import com.intellij.application.options.IndentOptionsEditor
|
|
||||||
import com.intellij.application.options.SmartIndentOptionsEditor
|
|
||||||
import com.intellij.psi.codeStyle.CodeStyleSettings
|
|
||||||
import com.intellij.psi.codeStyle.CommonCodeStyleSettings
|
|
||||||
import org.jetbrains.kotlin.idea.core.formatter.KotlinCodeStyleSettings
|
|
||||||
import javax.swing.JCheckBox
|
|
||||||
|
|
||||||
class KotlinIndentOptionsEditor : SmartIndentOptionsEditor() {
|
|
||||||
private val useContinuationIndentForExpressionBodies = JCheckBox("Use continuation indent for expression bodies")
|
|
||||||
|
|
||||||
override fun addComponents() {
|
|
||||||
super.addComponents()
|
|
||||||
add(useContinuationIndentForExpressionBodies)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun isModified(settings: CodeStyleSettings, options: CommonCodeStyleSettings.IndentOptions): Boolean {
|
|
||||||
var isModified = super.isModified(settings, options)
|
|
||||||
val kotlinSettings = settings.kotlinCustomSettings
|
|
||||||
isModified = isModified || IndentOptionsEditor.isFieldModified(useContinuationIndentForExpressionBodies,
|
|
||||||
kotlinSettings.CONTINUATION_INDENT_FOR_EXPRESSION_BODIES)
|
|
||||||
return isModified
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun apply(settings: CodeStyleSettings, options: CommonCodeStyleSettings.IndentOptions) {
|
|
||||||
super.apply(settings, options)
|
|
||||||
val kotlinSettings = settings.getCustomSettings(KotlinCodeStyleSettings::class.java)
|
|
||||||
kotlinSettings.CONTINUATION_INDENT_FOR_EXPRESSION_BODIES = useContinuationIndentForExpressionBodies.isSelected
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun reset(settings: CodeStyleSettings, options: CommonCodeStyleSettings.IndentOptions) {
|
|
||||||
super.reset(settings, options)
|
|
||||||
val kotlinSettings = settings.getCustomSettings(KotlinCodeStyleSettings::class.java)
|
|
||||||
useContinuationIndentForExpressionBodies.isSelected = kotlinSettings.CONTINUATION_INDENT_FOR_EXPRESSION_BODIES
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setEnabled(enabled: Boolean) {
|
|
||||||
super.setEnabled(enabled)
|
|
||||||
useContinuationIndentForExpressionBodies.isEnabled = enabled
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+17
-3
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.idea.formatter
|
package org.jetbrains.kotlin.idea.formatter
|
||||||
|
|
||||||
import com.intellij.application.options.IndentOptionsEditor
|
import com.intellij.application.options.IndentOptionsEditor
|
||||||
|
import com.intellij.application.options.SmartIndentOptionsEditor
|
||||||
import com.intellij.psi.codeStyle.CodeStyleSettingsCustomizable
|
import com.intellij.psi.codeStyle.CodeStyleSettingsCustomizable
|
||||||
import com.intellij.psi.codeStyle.CommonCodeStyleSettings
|
import com.intellij.psi.codeStyle.CommonCodeStyleSettings
|
||||||
import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider
|
import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider
|
||||||
@@ -66,6 +67,8 @@ class KotlinLanguageCodeStyleSettingsProvider : LanguageCodeStyleSettingsProvide
|
|||||||
enum class Enumeration {
|
enum class Enumeration {
|
||||||
A, B
|
A, B
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun veryLongExpressionBodyMethod() = "abc"
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
|
|
||||||
LanguageCodeStyleSettingsProvider.SettingsType.BLANK_LINES_SETTINGS ->
|
LanguageCodeStyleSettingsProvider.SettingsType.BLANK_LINES_SETTINGS ->
|
||||||
@@ -167,8 +170,8 @@ class KotlinLanguageCodeStyleSettingsProvider : LanguageCodeStyleSettingsProvide
|
|||||||
override fun getLanguageName(): String = KotlinLanguage.NAME
|
override fun getLanguageName(): String = KotlinLanguage.NAME
|
||||||
|
|
||||||
override fun customizeSettings(consumer: CodeStyleSettingsCustomizable, settingsType: LanguageCodeStyleSettingsProvider.SettingsType) {
|
override fun customizeSettings(consumer: CodeStyleSettingsCustomizable, settingsType: LanguageCodeStyleSettingsProvider.SettingsType) {
|
||||||
fun showCustomOption(field: KProperty<*>, title: String, groupName: String? = null) {
|
fun showCustomOption(field: KProperty<*>, title: String, groupName: String? = null, vararg options: Any) {
|
||||||
consumer.showCustomOption(KotlinCodeStyleSettings::class.java, field.name, title, groupName)
|
consumer.showCustomOption(KotlinCodeStyleSettings::class.java, field.name, title, groupName, *options)
|
||||||
}
|
}
|
||||||
|
|
||||||
when (settingsType) {
|
when (settingsType) {
|
||||||
@@ -285,6 +288,17 @@ class KotlinLanguageCodeStyleSettingsProvider : LanguageCodeStyleSettingsProvide
|
|||||||
KotlinCodeStyleSettings::CONTINUATION_INDENT_IN_SUPERTYPE_LISTS,
|
KotlinCodeStyleSettings::CONTINUATION_INDENT_IN_SUPERTYPE_LISTS,
|
||||||
"Use continuation indent",
|
"Use continuation indent",
|
||||||
CodeStyleSettingsCustomizable.WRAPPING_EXTENDS_LIST)
|
CodeStyleSettingsCustomizable.WRAPPING_EXTENDS_LIST)
|
||||||
|
|
||||||
|
showCustomOption(
|
||||||
|
KotlinCodeStyleSettings::WRAP_EXPRESSION_BODY_FUNCTIONS,
|
||||||
|
"Expression body functions",
|
||||||
|
options = *arrayOf(CodeStyleSettingsCustomizable.WRAP_OPTIONS_FOR_SINGLETON, CodeStyleSettingsCustomizable.WRAP_VALUES_FOR_SINGLETON)
|
||||||
|
)
|
||||||
|
showCustomOption(
|
||||||
|
KotlinCodeStyleSettings::CONTINUATION_INDENT_FOR_EXPRESSION_BODIES,
|
||||||
|
"Use continuation indent",
|
||||||
|
"Expression body functions"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
LanguageCodeStyleSettingsProvider.SettingsType.BLANK_LINES_SETTINGS -> {
|
LanguageCodeStyleSettingsProvider.SettingsType.BLANK_LINES_SETTINGS -> {
|
||||||
consumer.showStandardOptions(
|
consumer.showStandardOptions(
|
||||||
@@ -301,7 +315,7 @@ class KotlinLanguageCodeStyleSettingsProvider : LanguageCodeStyleSettingsProvide
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getIndentOptionsEditor(): IndentOptionsEditor = KotlinIndentOptionsEditor()
|
override fun getIndentOptionsEditor(): IndentOptionsEditor = SmartIndentOptionsEditor()
|
||||||
|
|
||||||
override fun getDefaultCommonSettings(): CommonCodeStyleSettings =
|
override fun getDefaultCommonSettings(): CommonCodeStyleSettings =
|
||||||
CommonCodeStyleSettings(language).apply {
|
CommonCodeStyleSettings(language).apply {
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
fun foo() =
|
||||||
|
"abc"
|
||||||
|
|
||||||
|
// SET_INT: WRAP_EXPRESSION_BODY_FUNCTIONS = 2
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fun foo() = "abc"
|
||||||
|
|
||||||
|
// SET_INT: WRAP_EXPRESSION_BODY_FUNCTIONS = 2
|
||||||
@@ -344,6 +344,12 @@ public class FormatterTestGenerated extends AbstractFormatterTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ExpressionBodyWrap.after.kt")
|
||||||
|
public void testExpressionBodyWrap() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/formatter/ExpressionBodyWrap.after.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("ExtendsListWrap.after.kt")
|
@TestMetadata("ExtendsListWrap.after.kt")
|
||||||
public void testExtendsListWrap() throws Exception {
|
public void testExtendsListWrap() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/formatter/ExtendsListWrap.after.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/formatter/ExtendsListWrap.after.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user