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