From 0a8ab036ccc76b33a60994920f6611377f4d16c5 Mon Sep 17 00:00:00 2001 From: mgroth0 Date: Mon, 6 Jan 2025 13:01:35 -0500 Subject: [PATCH] make isDeclaration public and use it in all rules --- .../api/ktlint-rule-engine-core.api | 1 + .../ktlint/rule/engine/core/api/ASTNodeExtension.kt | 9 +++++++++ .../standard/rules/BlankLineBeforeDeclarationRule.kt | 4 ++-- .../SpacingBetweenDeclarationsWithAnnotationsRule.kt | 6 +++--- .../SpacingBetweenDeclarationsWithCommentsRule.kt | 10 +--------- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/ktlint-rule-engine-core/api/ktlint-rule-engine-core.api b/ktlint-rule-engine-core/api/ktlint-rule-engine-core.api index 999f5df343..ec8b9de636 100644 --- a/ktlint-rule-engine-core/api/ktlint-rule-engine-core.api +++ b/ktlint-rule-engine-core/api/ktlint-rule-engine-core.api @@ -14,6 +14,7 @@ public final class com/pinterest/ktlint/rule/engine/core/api/ASTNodeExtensionKt public static final fun indent (Lorg/jetbrains/kotlin/com/intellij/lang/ASTNode;Z)Ljava/lang/String; public static synthetic fun indent$default (Lorg/jetbrains/kotlin/com/intellij/lang/ASTNode;ZILjava/lang/Object;)Ljava/lang/String; public static final fun isCodeLeaf (Lorg/jetbrains/kotlin/com/intellij/lang/ASTNode;)Z + public static final fun isDeclaration (Lorg/jetbrains/kotlin/com/intellij/lang/ASTNode;)Z public static final fun isKtAnnotated (Lorg/jetbrains/kotlin/com/intellij/lang/ASTNode;)Z public static final fun isLeaf (Lorg/jetbrains/kotlin/com/intellij/lang/ASTNode;)Z public static final fun isPartOf (Lorg/jetbrains/kotlin/com/intellij/lang/ASTNode;Lkotlin/reflect/KClass;)Z diff --git a/ktlint-rule-engine-core/src/main/kotlin/com/pinterest/ktlint/rule/engine/core/api/ASTNodeExtension.kt b/ktlint-rule-engine-core/src/main/kotlin/com/pinterest/ktlint/rule/engine/core/api/ASTNodeExtension.kt index 2722e63676..6129dc5f8e 100644 --- a/ktlint-rule-engine-core/src/main/kotlin/com/pinterest/ktlint/rule/engine/core/api/ASTNodeExtension.kt +++ b/ktlint-rule-engine-core/src/main/kotlin/com/pinterest/ktlint/rule/engine/core/api/ASTNodeExtension.kt @@ -2,6 +2,7 @@ package com.pinterest.ktlint.rule.engine.core.api import com.pinterest.ktlint.rule.engine.core.api.ElementType.EOL_COMMENT import com.pinterest.ktlint.rule.engine.core.api.ElementType.REGULAR_STRING_PART +import com.pinterest.ktlint.rule.engine.core.api.ElementType.SCRIPT_INITIALIZER import com.pinterest.ktlint.rule.engine.core.api.ElementType.STRING_TEMPLATE import com.pinterest.ktlint.rule.engine.core.api.ElementType.VAL_KEYWORD import com.pinterest.ktlint.rule.engine.core.api.ElementType.VARARG_KEYWORD @@ -25,11 +26,13 @@ import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.lexer.KtKeywordToken import org.jetbrains.kotlin.lexer.KtToken import org.jetbrains.kotlin.psi.KtAnnotated +import org.jetbrains.kotlin.psi.KtDeclarationImpl import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.psiUtil.leaves import org.jetbrains.kotlin.psi.stubs.elements.KtFileElementType import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementType +import org.jetbrains.kotlin.psi.stubs.elements.KtTokenSets import org.jetbrains.kotlin.util.prefixIfNot import org.jetbrains.kotlin.utils.addToStdlib.applyIf import kotlin.contracts.ExperimentalContracts @@ -669,3 +672,9 @@ private fun createDummyKtFile(): KtFile { disposable.dispose() } } + +/** + * Returns true if the receiver is not null and it represents a declaration + * [KtScriptInitializer] is considered a type of declaration in terms of it being a subtype of [KtDeclarationImpl] even though SCRIPT_INITIALIZER is not included in DECLARATION_TYPES. We consider SCRIPT_INITIALIZER a declaration here to match previous behavior of ktlint in older versions. + */ +public fun ASTNode?.isDeclaration() = this != null && (elementType in KtTokenSets.DECLARATION_TYPES || elementType == SCRIPT_INITIALIZER) diff --git a/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/BlankLineBeforeDeclarationRule.kt b/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/BlankLineBeforeDeclarationRule.kt index 24c864649d..5bbfa70e1f 100644 --- a/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/BlankLineBeforeDeclarationRule.kt +++ b/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/BlankLineBeforeDeclarationRule.kt @@ -24,6 +24,7 @@ import com.pinterest.ktlint.rule.engine.core.api.SinceKtlint.Status.STABLE import com.pinterest.ktlint.rule.engine.core.api.children import com.pinterest.ktlint.rule.engine.core.api.ifAutocorrectAllowed import com.pinterest.ktlint.rule.engine.core.api.indent +import com.pinterest.ktlint.rule.engine.core.api.isDeclaration import com.pinterest.ktlint.rule.engine.core.api.isPartOfComment import com.pinterest.ktlint.rule.engine.core.api.isWhiteSpace import com.pinterest.ktlint.rule.engine.core.api.nextCodeSibling @@ -32,7 +33,6 @@ import com.pinterest.ktlint.rule.engine.core.api.prevLeaf import com.pinterest.ktlint.rule.engine.core.api.upsertWhitespaceBeforeMe import com.pinterest.ktlint.ruleset.standard.StandardRule import org.jetbrains.kotlin.com.intellij.lang.ASTNode -import org.jetbrains.kotlin.psi.stubs.elements.KtTokenSets /** * Insert a blank line before declarations. No blank line is inserted before between a class or method signature and the first declaration @@ -148,7 +148,7 @@ public class BlankLineBeforeDeclarationRule : } node - .takeIf { it.elementType in KtTokenSets.DECLARATION_TYPES } + .takeIf { it.isDeclaration() } ?.takeIf { val prevLeaf = it.prevLeaf() prevLeaf != null && (!prevLeaf.isWhiteSpace() || !prevLeaf.text.startsWith("\n\n")) diff --git a/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/SpacingBetweenDeclarationsWithAnnotationsRule.kt b/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/SpacingBetweenDeclarationsWithAnnotationsRule.kt index 183c247f7a..affe8357d9 100644 --- a/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/SpacingBetweenDeclarationsWithAnnotationsRule.kt +++ b/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/SpacingBetweenDeclarationsWithAnnotationsRule.kt @@ -10,6 +10,7 @@ import com.pinterest.ktlint.rule.engine.core.api.SinceKtlint.Status.STABLE import com.pinterest.ktlint.rule.engine.core.api.children import com.pinterest.ktlint.rule.engine.core.api.ifAutocorrectAllowed import com.pinterest.ktlint.rule.engine.core.api.indent +import com.pinterest.ktlint.rule.engine.core.api.isDeclaration import com.pinterest.ktlint.rule.engine.core.api.isPartOfComment import com.pinterest.ktlint.rule.engine.core.api.isWhiteSpace import com.pinterest.ktlint.rule.engine.core.api.nextLeaf @@ -19,7 +20,6 @@ import com.pinterest.ktlint.rule.engine.core.api.upsertWhitespaceBeforeMe import com.pinterest.ktlint.ruleset.standard.StandardRule import org.jetbrains.kotlin.com.intellij.lang.ASTNode import org.jetbrains.kotlin.psi.psiUtil.leaves -import org.jetbrains.kotlin.psi.stubs.elements.KtTokenSets /** * @see https://youtrack.jetbrains.com/issue/KT-35106 @@ -31,7 +31,7 @@ public class SpacingBetweenDeclarationsWithAnnotationsRule : StandardRule("spaci node: ASTNode, emit: (offset: Int, errorMessage: String, canBeAutoCorrected: Boolean) -> AutocorrectDecision, ) { - if (node.elementType in KtTokenSets.DECLARATION_TYPES && node.isAnnotated()) { + if (node.isDeclaration() && node.isAnnotated()) { visitDeclaration(node, emit) } } @@ -42,7 +42,7 @@ public class SpacingBetweenDeclarationsWithAnnotationsRule : StandardRule("spaci ) { node .prevCodeSibling() - ?.takeIf { it.elementType in KtTokenSets.DECLARATION_TYPES } + ?.takeIf { it.isDeclaration() } ?.takeIf { prevDeclaration -> hasNoBlankLineBetweenDeclarations(node, prevDeclaration) } ?.let { val prevLeaf = node.prevCodeLeaf()?.nextLeaf { it.isWhiteSpace() }!! diff --git a/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/SpacingBetweenDeclarationsWithCommentsRule.kt b/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/SpacingBetweenDeclarationsWithCommentsRule.kt index ecd86596d8..406d41ce5d 100644 --- a/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/SpacingBetweenDeclarationsWithCommentsRule.kt +++ b/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/rules/SpacingBetweenDeclarationsWithCommentsRule.kt @@ -1,13 +1,13 @@ package com.pinterest.ktlint.ruleset.standard.rules import com.pinterest.ktlint.rule.engine.core.api.AutocorrectDecision -import com.pinterest.ktlint.rule.engine.core.api.ElementType.SCRIPT_INITIALIZER import com.pinterest.ktlint.rule.engine.core.api.RuleId import com.pinterest.ktlint.rule.engine.core.api.SinceKtlint import com.pinterest.ktlint.rule.engine.core.api.SinceKtlint.Status.EXPERIMENTAL import com.pinterest.ktlint.rule.engine.core.api.SinceKtlint.Status.STABLE import com.pinterest.ktlint.rule.engine.core.api.TokenSets import com.pinterest.ktlint.rule.engine.core.api.ifAutocorrectAllowed +import com.pinterest.ktlint.rule.engine.core.api.isDeclaration import com.pinterest.ktlint.rule.engine.core.api.isWhiteSpace import com.pinterest.ktlint.rule.engine.core.api.isWhiteSpaceWithNewline import com.pinterest.ktlint.rule.engine.core.api.prevCodeSibling @@ -16,8 +16,6 @@ import com.pinterest.ktlint.rule.engine.core.api.prevSibling import com.pinterest.ktlint.ruleset.standard.StandardRule import org.jetbrains.kotlin.com.intellij.lang.ASTNode import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafElement -import org.jetbrains.kotlin.psi.KtDeclarationImpl -import org.jetbrains.kotlin.psi.stubs.elements.KtTokenSets /** * @see https://youtrack.jetbrains.com/issue/KT-35088 @@ -57,12 +55,6 @@ public class SpacingBetweenDeclarationsWithCommentsRule : StandardRule("spacing- } } } - - /** - * [KtScriptInitializer] is considered a type of declaration in terms of it being a subtype of [KtDeclarationImpl] even though SCRIPT_INITIALIZER is not included in DECLARATION_TYPES. We consider SCRIPT_INITIALIZER a declaration here to match previous behavior of ktlint in older versions. - */ - private fun ASTNode?.isDeclaration() = - this != null && (elementType in KtTokenSets.DECLARATION_TYPES || elementType == SCRIPT_INITIALIZER) } public val SPACING_BETWEEN_DECLARATIONS_WITH_COMMENTS_RULE_ID: RuleId = SpacingBetweenDeclarationsWithCommentsRule().ruleId