formatter: cleanup code

This commit is contained in:
Dmitry Gridin
2019-10-31 19:23:53 +07:00
parent 0098588a6b
commit 7f1935b82e
7 changed files with 106 additions and 118 deletions
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 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.
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.core.formatter;
@@ -149,9 +138,11 @@ public class KotlinCodeStyleSettings extends CustomCodeStyleSettings {
if (KotlinStyleGuideCodeStyle.CODE_STYLE_ID.equals(customDefaults)) {
KotlinStyleGuideCodeStyle.Companion.applyToKotlinCustomSettings(this, true);
} else if (KotlinObsoleteCodeStyle.CODE_STYLE_ID.equals(customDefaults)) {
}
else if (KotlinObsoleteCodeStyle.CODE_STYLE_ID.equals(customDefaults)) {
KotlinObsoleteCodeStyle.Companion.applyToKotlinCustomSettings(this, true);
} else if (customDefaults == null && FormatterUtilKt.isDefaultOfficialCodeStyle()) {
}
else if (customDefaults == null && FormatterUtilKt.isDefaultOfficialCodeStyle()) {
// Temporary load settings against previous defaults
settingsAgainstPreviousDefaults = new KotlinCodeStyleSettings(null, true);
KotlinObsoleteCodeStyle.Companion.applyToKotlinCustomSettings(settingsAgainstPreviousDefaults, true);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2000-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -142,7 +142,8 @@ abstract class KotlinCommonBlock(
enforceIndentToChildren
)
val wrap = if ((settings.kotlinCommonSettings.WRAP_FIRST_METHOD_IN_CALL_CHAIN || isNonFirstChainedCall) &&
canWrapCallChain(node))
canWrapCallChain(node)
)
Wrap.createWrap(settings.kotlinCommonSettings.METHOD_CALL_CHAIN_WRAP, true)
else
null
@@ -521,7 +522,8 @@ abstract class KotlinCommonBlock(
elementType === VALUE_PARAMETER_LIST -> {
if (parentElementType === FUN ||
parentElementType === PRIMARY_CONSTRUCTOR ||
parentElementType === SECONDARY_CONSTRUCTOR) {
parentElementType === SECONDARY_CONSTRUCTOR
) {
val wrap = Wrap.createWrap(commonSettings.METHOD_PARAMETERS_WRAP, false)
return { childElement ->
if (childElement.elementType === VALUE_PARAMETER && !childElement.startsWithAnnotation())
@@ -541,8 +543,7 @@ abstract class KotlinCommonBlock(
return getWrappingStrategyForItemList(commonSettings.ENUM_CONSTANTS_WRAP, ENUM_ENTRY)
elementType === MODIFIER_LIST -> {
val parent = node.treeParent.psi
when (parent) {
when (val parent = node.treeParent.psi) {
is KtParameter ->
return getWrappingStrategyForItemList(
commonSettings.PARAMETER_ANNOTATION_WRAP,
@@ -947,7 +948,8 @@ private fun getWrappingStrategyForItemList(wrapType: Int, itemTypes: TokenSet, w
val thisType = childElement.elementType
val prevType = getPrevWithoutWhitespace(childElement)?.elementType
if (thisType in itemTypes || prevType in itemTypes &&
thisType != EOL_COMMENT && prevType != EOL_COMMENT)
thisType != EOL_COMMENT && prevType != EOL_COMMENT
)
itemWrap
else
null
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2000-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -69,9 +69,11 @@ public class KotlinCommonCodeStyleSettings extends CommonCodeStyleSettings {
String customDefaults = tempDeserialize.CODE_STYLE_DEFAULTS;
if (KotlinStyleGuideCodeStyle.CODE_STYLE_ID.equals(customDefaults)) {
KotlinStyleGuideCodeStyle.Companion.applyToCommonSettings(this, true);
} else if (KotlinObsoleteCodeStyle.CODE_STYLE_ID.equals(customDefaults)) {
}
else if (KotlinObsoleteCodeStyle.CODE_STYLE_ID.equals(customDefaults)) {
KotlinObsoleteCodeStyle.Companion.applyToCommonSettings(this, true);
} else if (customDefaults == null && FormatterUtilKt.isDefaultOfficialCodeStyle()) {
}
else if (customDefaults == null && FormatterUtilKt.isDefaultOfficialCodeStyle()) {
// Temporary load settings against previous defaults
settingsAgainstPreviousDefaults = createForTempDeserialize();
KotlinObsoleteCodeStyle.Companion.applyToCommonSettings(settingsAgainstPreviousDefaults, true);
@@ -88,7 +90,8 @@ public class KotlinCommonCodeStyleSettings extends CommonCodeStyleSettings {
if (defaultSettings != null) {
if (KotlinStyleGuideCodeStyle.CODE_STYLE_ID.equals(CODE_STYLE_DEFAULTS)) {
KotlinStyleGuideCodeStyle.Companion.applyToCommonSettings(defaultSettings, false);
} else if (KotlinObsoleteCodeStyle.CODE_STYLE_ID.equals(CODE_STYLE_DEFAULTS)) {
}
else if (KotlinObsoleteCodeStyle.CODE_STYLE_ID.equals(CODE_STYLE_DEFAULTS)) {
KotlinObsoleteCodeStyle.Companion.applyToCommonSettings(defaultSettings, false);
}
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 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.
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.formatter
@@ -32,9 +21,11 @@ import java.util.*
import kotlin.math.max
fun CommonCodeStyleSettings.createSpaceBeforeRBrace(numSpacesOtherwise: Int, textRange: TextRange): Spacing? {
return Spacing.createDependentLFSpacing(numSpacesOtherwise, numSpacesOtherwise, textRange,
KEEP_LINE_BREAKS,
KEEP_BLANK_LINES_BEFORE_RBRACE)
return Spacing.createDependentLFSpacing(
numSpacesOtherwise, numSpacesOtherwise, textRange,
KEEP_LINE_BREAKS,
KEEP_BLANK_LINES_BEFORE_RBRACE
)
}
class KotlinSpacingBuilder(val commonCodeStyleSettings: CommonCodeStyleSettings, val spacingBuilderUtil: KotlinSpacingBuilderUtil) {
@@ -51,24 +42,26 @@ class KotlinSpacingBuilder(val commonCodeStyleSettings: CommonCodeStyleSettings,
}
private data class Condition(
val parent: IElementType? = null,
val left: IElementType? = null,
val right: IElementType? = null,
val parentSet: TokenSet? = null,
val leftSet: TokenSet? = null,
val rightSet: TokenSet? = null
val parent: IElementType? = null,
val left: IElementType? = null,
val right: IElementType? = null,
val parentSet: TokenSet? = null,
val leftSet: TokenSet? = null,
val rightSet: TokenSet? = null
) : (ASTBlock, ASTBlock, ASTBlock) -> Boolean {
override fun invoke(p: ASTBlock, l: ASTBlock, r: ASTBlock): Boolean =
(parent == null || p.requireNode().elementType == parent) &&
(left == null || l.requireNode().elementType == left) &&
(right == null || r.requireNode().elementType == right) &&
(parentSet == null || parentSet.contains(p.requireNode().elementType)) &&
(leftSet == null || leftSet.contains(l.requireNode().elementType)) &&
(rightSet == null || rightSet.contains(r.requireNode().elementType))
(left == null || l.requireNode().elementType == left) &&
(right == null || r.requireNode().elementType == right) &&
(parentSet == null || parentSet.contains(p.requireNode().elementType)) &&
(leftSet == null || leftSet.contains(l.requireNode().elementType)) &&
(rightSet == null || rightSet.contains(r.requireNode().elementType))
}
private data class Rule(val conditions: List<Condition>,
val action: (ASTBlock, ASTBlock, ASTBlock) -> Spacing?) : (ASTBlock, ASTBlock, ASTBlock) -> Spacing? {
private data class Rule(
val conditions: List<Condition>,
val action: (ASTBlock, ASTBlock, ASTBlock) -> Spacing?
) : (ASTBlock, ASTBlock, ASTBlock) -> Spacing? {
override fun invoke(p: ASTBlock, l: ASTBlock, r: ASTBlock): Spacing? =
if (conditions.all { it(p, l, r) }) action(p, l, r) else null
}
@@ -87,17 +80,21 @@ class KotlinSpacingBuilder(val commonCodeStyleSettings: CommonCodeStyleSettings,
return null
}
fun inPosition(parent: IElementType? = null, left: IElementType? = null, right: IElementType? = null,
parentSet: TokenSet? = null, leftSet: TokenSet? = null, rightSet: TokenSet? = null): CustomSpacingBuilder {
fun inPosition(
parent: IElementType? = null, left: IElementType? = null, right: IElementType? = null,
parentSet: TokenSet? = null, leftSet: TokenSet? = null, rightSet: TokenSet? = null
): CustomSpacingBuilder {
conditions.add(Condition(parent, left, right, parentSet, leftSet, rightSet))
return this
}
fun lineBreakIfLineBreakInParent(numSpacesOtherwise: Int, allowBlankLines: Boolean = true) {
newRule { p, _, _ ->
Spacing.createDependentLFSpacing(numSpacesOtherwise, numSpacesOtherwise, p.textRange,
commonCodeStyleSettings.KEEP_LINE_BREAKS,
if (allowBlankLines) commonCodeStyleSettings.KEEP_BLANK_LINES_IN_CODE else 0)
Spacing.createDependentLFSpacing(
numSpacesOtherwise, numSpacesOtherwise, p.textRange,
commonCodeStyleSettings.KEEP_LINE_BREAKS,
if (allowBlankLines) commonCodeStyleSettings.KEEP_BLANK_LINES_IN_CODE else 0
)
}
}
@@ -106,13 +103,15 @@ class KotlinSpacingBuilder(val commonCodeStyleSettings: CommonCodeStyleSettings,
val lastChild = left.node?.psi?.lastChild
val leftEndsWithComment = lastChild is PsiComment && lastChild.tokenType == KtTokens.EOL_COMMENT
val dependentSpacingRule = DependentSpacingRule(Trigger.HAS_LINE_FEEDS).registerData(Anchor.MIN_LINE_FEEDS, emptyLines + 1)
spacingBuilderUtil.createLineFeedDependentSpacing(numSpacesOtherwise,
numSpacesOtherwise,
if (leftEndsWithComment) max(1, numberOfLineFeedsOtherwise) else numberOfLineFeedsOtherwise,
commonCodeStyleSettings.KEEP_LINE_BREAKS,
commonCodeStyleSettings.KEEP_BLANK_LINES_IN_DECLARATIONS,
left.textRange,
dependentSpacingRule)
spacingBuilderUtil.createLineFeedDependentSpacing(
numSpacesOtherwise,
numSpacesOtherwise,
if (leftEndsWithComment) max(1, numberOfLineFeedsOtherwise) else numberOfLineFeedsOtherwise,
commonCodeStyleSettings.KEEP_LINE_BREAKS,
commonCodeStyleSettings.KEEP_BLANK_LINES_IN_DECLARATIONS,
left.textRange,
dependentSpacingRule
)
}
}
@@ -142,7 +141,8 @@ class KotlinSpacingBuilder(val commonCodeStyleSettings: CommonCodeStyleSettings,
if (spacing != null) {
// TODO: it's a severe hack but I don't know how to implement it in other way
if (child1.requireNode().elementType == KtTokens.EOL_COMMENT && spacing.toString().contains("minLineFeeds=0")) {
val isBeforeBlock = child2.requireNode().elementType == KtNodeTypes.BLOCK || child2.requireNode().firstChildNode?.elementType == KtNodeTypes.BLOCK
val isBeforeBlock =
child2.requireNode().elementType == KtNodeTypes.BLOCK || child2.requireNode().firstChildNode?.elementType == KtNodeTypes.BLOCK
val keepBlankLines = if (isBeforeBlock) 0 else commonCodeStyleSettings.KEEP_BLANK_LINES_IN_CODE
return createSpacing(0, minLineFeeds = 1, keepLineBreaks = true, keepBlankLines = keepBlankLines)
}
@@ -164,30 +164,38 @@ class KotlinSpacingBuilder(val commonCodeStyleSettings: CommonCodeStyleSettings,
builders.add(builder)
}
fun createSpacing(minSpaces: Int,
maxSpaces: Int = minSpaces,
minLineFeeds: Int = 0,
keepLineBreaks: Boolean = commonCodeStyleSettings.KEEP_LINE_BREAKS,
keepBlankLines: Int = commonCodeStyleSettings.KEEP_BLANK_LINES_IN_CODE): Spacing {
fun createSpacing(
minSpaces: Int,
maxSpaces: Int = minSpaces,
minLineFeeds: Int = 0,
keepLineBreaks: Boolean = commonCodeStyleSettings.KEEP_LINE_BREAKS,
keepBlankLines: Int = commonCodeStyleSettings.KEEP_BLANK_LINES_IN_CODE
): Spacing {
return Spacing.createSpacing(minSpaces, maxSpaces, minLineFeeds, keepLineBreaks, keepBlankLines)
}
}
interface KotlinSpacingBuilderUtil {
fun createLineFeedDependentSpacing(minSpaces: Int,
maxSpaces: Int,
minimumLineFeeds: Int,
keepLineBreaks: Boolean,
keepBlankLines: Int,
dependency: TextRange,
rule: DependentSpacingRule): Spacing
fun createLineFeedDependentSpacing(
minSpaces: Int,
maxSpaces: Int,
minimumLineFeeds: Int,
keepLineBreaks: Boolean,
keepBlankLines: Int,
dependency: TextRange,
rule: DependentSpacingRule
): Spacing
fun getPreviousNonWhitespaceLeaf(node: ASTNode?): ASTNode?
fun isWhitespaceOrEmpty(node: ASTNode?): Boolean
}
fun rules(commonCodeStyleSettings: CommonCodeStyleSettings, builderUtil: KotlinSpacingBuilderUtil, init: KotlinSpacingBuilder.() -> Unit): KotlinSpacingBuilder {
fun rules(
commonCodeStyleSettings: CommonCodeStyleSettings,
builderUtil: KotlinSpacingBuilderUtil,
init: KotlinSpacingBuilder.() -> Unit
): KotlinSpacingBuilder {
val builder = KotlinSpacingBuilder(commonCodeStyleSettings, builderUtil)
builder.init()
return builder
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 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.
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.formatter
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 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.
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.formatter
@@ -21,18 +10,19 @@ import com.intellij.lang.ASTNode
import com.intellij.openapi.util.TextRange
class SyntheticKotlinBlock(
private val node: ASTNode,
private val subBlocks: List<ASTBlock>,
private val alignment: Alignment?,
private val indent: Indent?,
private val wrap: Wrap?,
private val spacingBuilder: KotlinSpacingBuilder,
private val createParentSyntheticSpacingBlock: (ASTNode) -> ASTBlock
private val node: ASTNode,
private val subBlocks: List<ASTBlock>,
private val alignment: Alignment?,
private val indent: Indent?,
private val wrap: Wrap?,
private val spacingBuilder: KotlinSpacingBuilder,
private val createParentSyntheticSpacingBlock: (ASTNode) -> ASTBlock
) : ASTBlock {
private val textRange = TextRange(
subBlocks.first().textRange.startOffset,
subBlocks.last().textRange.endOffset)
subBlocks.first().textRange.startOffset,
subBlocks.last().textRange.endOffset
)
override fun getTextRange(): TextRange = textRange
override fun getSubBlocks() = subBlocks
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -19,13 +19,18 @@ import java.util.Set;
public class ReflectionUtil {
@Retention(RetentionPolicy.RUNTIME)
public @interface SkipInEquals {}
public @interface SkipInEquals {
}
public static boolean comparePublicNonFinalFieldsWithSkip(@NotNull Object first, @NotNull Object second) {
return comparePublicNonFinalFields(first, second, field -> field.getAnnotation(SkipInEquals.class) == null);
}
private static boolean comparePublicNonFinalFields(@NotNull Object first, @NotNull Object second, @Nullable Predicate<Field> acceptPredicate) {
private static boolean comparePublicNonFinalFields(
@NotNull Object first,
@NotNull Object second,
@Nullable Predicate<Field> acceptPredicate
) {
Set<Field> firstFields = ContainerUtil.newHashSet(first.getClass().getFields());
for (Field field : second.getClass().getFields()) {