From 506118d2d5e98c7bbc594e46abc479eba64cd70a Mon Sep 17 00:00:00 2001 From: Sha Sha Chu Date: Fri, 5 Jul 2019 16:53:26 -0700 Subject: [PATCH 1/2] Allow unreferenced provideDelegate if there is a by keyword in the file Fixes https://github.com/pinterest/ktlint/issues/506 --- .../ruleset/standard/NoUnusedImportsRule.kt | 26 ++++++++++- .../standard/NoUnusedImportsRuleTest.kt | 46 +++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/NoUnusedImportsRule.kt b/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/NoUnusedImportsRule.kt index 255d5cf0b2..266bbbfe1e 100644 --- a/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/NoUnusedImportsRule.kt +++ b/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/NoUnusedImportsRule.kt @@ -1,6 +1,7 @@ package com.pinterest.ktlint.ruleset.standard import com.pinterest.ktlint.core.Rule +import com.pinterest.ktlint.core.ast.ElementType.BY_KEYWORD import com.pinterest.ktlint.core.ast.ElementType.DOT_QUALIFIED_EXPRESSION import com.pinterest.ktlint.core.ast.ElementType.IMPORT_DIRECTIVE import com.pinterest.ktlint.core.ast.ElementType.OPERATION_REFERENCE @@ -44,9 +45,28 @@ class NoUnusedImportsRule : Rule("no-unused-imports") { // by (https://github.com/shyiko/ktlint/issues/54) "getValue", "setValue" ) + + private val conditionalWhitelist = mapOf Boolean>( + Pair( + // Ignore provideDelegate if there is a `by` anywhere in the file + "org.gradle.kotlin.dsl.provideDelegate", + { rootNode -> + var hasByKeyword = false + rootNode.visit { child -> + if (child.elementType == BY_KEYWORD) { + hasByKeyword = true + return@visit + } + } + hasByKeyword + } + ) + ) + private val ref = mutableSetOf() private val imports = mutableSetOf() private var packageName = "" + private var rootNode: ASTNode? = null override fun visit( node: ASTNode, @@ -54,8 +74,10 @@ class NoUnusedImportsRule : Rule("no-unused-imports") { emit: (offset: Int, errorMessage: String, canBeAutoCorrected: Boolean) -> Unit ) { if (node.isRoot()) { + rootNode = node ref.clear() // rule can potentially be executed more than once (when formatting) ref.add("*") + imports.clear() var parentExpression: String? = null node.visit { vnode -> val psi = vnode.psi @@ -92,7 +114,9 @@ class NoUnusedImportsRule : Rule("no-unused-imports") { importDirective.delete() } } else if (name != null && (!ref.contains(name) || !isAValidImport(importPath)) && - !operatorSet.contains(name) && !name.isComponentN() + !operatorSet.contains(name) && + !name.isComponentN() && + conditionalWhitelist[importPath]?.invoke(rootNode!!) != true ) { emit(node.startOffset, "Unused import", true) if (autoCorrect) { diff --git a/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/NoUnusedImportsRuleTest.kt b/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/NoUnusedImportsRuleTest.kt index d9bf25ba76..e045d05611 100644 --- a/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/NoUnusedImportsRuleTest.kt +++ b/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/NoUnusedImportsRuleTest.kt @@ -395,4 +395,50 @@ class NoUnusedImportsRuleTest { """.trimIndent() ) } + + @Test + fun `provideDelegate is allowed if there is a by keyword`() { + assertThat( + NoUnusedImportsRule().lint( + """ + import org.gradle.api.Plugin + import org.gradle.api.Project + import org.gradle.api.tasks.WriteProperties + import org.gradle.kotlin.dsl.getValue + import org.gradle.kotlin.dsl.provideDelegate + import org.gradle.kotlin.dsl.registering + + class DumpVersionProperties : Plugin { + override fun apply(target: Project) { + with(target) { + val dumpVersionProperties by tasks.registering(WriteProperties::class) { + setProperties(mapOf("version" to "1.2.3")) + outputFile = rootDir.resolve("version.properties") + } + + } + } + } + """.trimIndent() + ) + ).isEmpty() + } + + @Test + fun `provideDelegate is not allowed without by keyword`() { + assertThat( + NoUnusedImportsRule().lint( + """ + import org.gradle.kotlin.dsl.registering + + fun main() { + } + """.trimIndent() + ) + ).isEqualTo( + listOf( + LintError(1, 1, "no-unused-imports", "Unused import") + ) + ) + } } From 070b9f7fb1b2cf84c2cb68eb79d1ad66276f3e1d Mon Sep 17 00:00:00 2001 From: Sha Sha Chu Date: Fri, 5 Jul 2019 16:57:12 -0700 Subject: [PATCH 2/2] fix test --- .../ktlint/ruleset/standard/NoUnusedImportsRuleTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/NoUnusedImportsRuleTest.kt b/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/NoUnusedImportsRuleTest.kt index e045d05611..d39b914db9 100644 --- a/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/NoUnusedImportsRuleTest.kt +++ b/ktlint-ruleset-standard/src/test/kotlin/com/pinterest/ktlint/ruleset/standard/NoUnusedImportsRuleTest.kt @@ -429,7 +429,7 @@ class NoUnusedImportsRuleTest { assertThat( NoUnusedImportsRule().lint( """ - import org.gradle.kotlin.dsl.registering + import org.gradle.kotlin.dsl.provideDelegate fun main() { }