Skip to content

Commit 3cc04af

Browse files
RBusarowkodiakhq[bot]
authored andcommitted
fix suppressing findings within the AGP DSL
fixes #710
1 parent aead3c5 commit 3cc04af

File tree

29 files changed

+632
-316
lines changed

29 files changed

+632
-316
lines changed

modulecheck-core/src/test/kotlin/modulecheck/core/DisableAndroidResourcesTest.kt

+38
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,44 @@ class DisableAndroidResourcesTest : RunnerTest() {
149149
logger.parsedReport() shouldBe listOf()
150150
}
151151

152+
@Test
153+
fun `unused resource generation should pass if suppressed`() {
154+
155+
val lib1 = androidLibrary(":lib1", "com.modulecheck.lib1") {
156+
buildFile {
157+
"""
158+
plugins {
159+
id("com.android.library")
160+
kotlin("android")
161+
}
162+
163+
android {
164+
@Suppress("disable-android-resources")
165+
buildFeatures.androidResources = true
166+
}
167+
"""
168+
}
169+
}
170+
171+
run(
172+
autoCorrect = false
173+
).isSuccess shouldBe true
174+
175+
lib1.buildFile shouldHaveText """
176+
plugins {
177+
id("com.android.library")
178+
kotlin("android")
179+
}
180+
181+
android {
182+
@Suppress("disable-android-resources")
183+
buildFeatures.androidResources = true
184+
}
185+
"""
186+
187+
logger.parsedReport() shouldBe listOf()
188+
}
189+
152190
@Test
153191
fun `unused resource generation should be ignored in dynamic-feature module`() {
154192

modulecheck-core/src/test/kotlin/modulecheck/core/DisableViewBindingTest.kt

+38
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,44 @@ class DisableViewBindingTest : RunnerTest() {
531531
logger.parsedReport() shouldBe listOf()
532532
}
533533

534+
@Test
535+
fun `unused ViewBinding should pass if suppressed`() {
536+
537+
val lib1 = androidLibrary(":lib1", "com.modulecheck.lib1") {
538+
buildFile {
539+
"""
540+
plugins {
541+
id("com.android.library")
542+
kotlin("android")
543+
}
544+
545+
android {
546+
@Suppress("disable-view-binding")
547+
buildFeatures.viewBinding = true
548+
}
549+
"""
550+
}
551+
}
552+
553+
run(
554+
autoCorrect = false
555+
).isSuccess shouldBe true
556+
557+
lib1.buildFile shouldHaveText """
558+
plugins {
559+
id("com.android.library")
560+
kotlin("android")
561+
}
562+
563+
android {
564+
@Suppress("disable-view-binding")
565+
buildFeatures.viewBinding = true
566+
}
567+
"""
568+
569+
logger.parsedReport() shouldBe listOf()
570+
}
571+
534572
@Test
535573
fun `unused ViewBinding without auto-correct should fail`() {
536574

modulecheck-finding/api/src/main/kotlin/modulecheck/finding/Problem.kt

+6-1
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,14 @@ interface Problem :
2424
Finding,
2525
DependencyFinding {
2626

27+
/**
28+
* Whether this Problem should be ignored. True if the associated statement is annotated with
29+
* `@Suppress` and the corresponding finding ID.
30+
*/
2731
val isSuppressed: LazyDeferred<Boolean>
2832
get() = lazyDeferred {
29-
statementOrNull.await()?.suppressed
33+
statementOrNull.await()
34+
?.suppressed
3035
?.contains(findingName.id)
3136
?: false
3237
}

modulecheck-finding/impl-android/src/main/kotlin/modulecheck/finding/android/DisableViewBindingGenerationFinding.kt

+12-6
Original file line numberDiff line numberDiff line change
@@ -33,25 +33,26 @@ import org.jetbrains.kotlin.util.suffixIfNot
3333
import java.io.File
3434

3535
data class DisableViewBindingGenerationFinding(
36-
override val findingName: FindingName,
3736
override val dependentProject: McProject,
3837
override val dependentPath: ProjectPath.StringProjectPath,
3938
override val buildFile: File
4039
) : Finding, Fixable {
4140

41+
override val findingName = NAME
42+
4243
override val message: String
4344
get() = "Android viewBinding generation is enabled, but no generated code is being used."
4445

4546
override val dependencyIdentifier = ""
4647

47-
override val statementOrNull: LazyDeferred<BuildFileStatement?> = lazyDeferred { null }
48-
49-
override val statementTextOrNull: LazyDeferred<String?> = lazyDeferred {
50-
48+
override val statementOrNull: LazyDeferred<BuildFileStatement?> = lazyDeferred {
5149
dependentProject.buildFileParser.androidSettings()
5250
.assignments
5351
.firstOrNull { it.propertyFullName == "viewBinding" }
54-
?.declarationText
52+
}
53+
54+
override val statementTextOrNull: LazyDeferred<String?> = lazyDeferred {
55+
statementOrNull.await()?.declarationText
5556
}
5657

5758
override val positionOrNull: LazyDeferred<Position?> = lazyDeferred {
@@ -139,4 +140,9 @@ data class DisableViewBindingGenerationFinding(
139140

140141
return buildFile.readText().replace(fullText, newBlockText)
141142
}
143+
144+
companion object {
145+
/** @suppress */
146+
val NAME = FindingName("disable-view-binding")
147+
}
142148
}

modulecheck-finding/impl-android/src/main/kotlin/modulecheck/finding/android/UnusedResourcesGenerationFinding.kt

+12-6
Original file line numberDiff line numberDiff line change
@@ -33,25 +33,26 @@ import org.jetbrains.kotlin.util.suffixIfNot
3333
import java.io.File
3434

3535
data class UnusedResourcesGenerationFinding(
36-
override val findingName: FindingName,
3736
override val dependentProject: McProject,
3837
override val dependentPath: ProjectPath.StringProjectPath,
3938
override val buildFile: File
4039
) : Finding, Fixable {
4140

41+
override val findingName = NAME
42+
4243
override val message: String
4344
get() = "`androidResources` generation is enabled, but no resources are defined in this module."
4445

4546
override val dependencyIdentifier = ""
4647

47-
override val statementOrNull: LazyDeferred<BuildFileStatement?> = lazyDeferred { null }
48-
49-
override val statementTextOrNull = lazyDeferred {
50-
48+
override val statementOrNull: LazyDeferred<BuildFileStatement?> = lazyDeferred {
5149
dependentProject.buildFileParser.androidSettings()
5250
.assignments
5351
.firstOrNull { it.propertyFullName == "androidResources" }
54-
?.declarationText
52+
}
53+
54+
override val statementTextOrNull = lazyDeferred {
55+
statementOrNull.await()?.declarationText
5556
}
5657

5758
override val positionOrNull: LazyDeferred<Position?> = lazyDeferred {
@@ -140,4 +141,9 @@ data class UnusedResourcesGenerationFinding(
140141

141142
return buildFile.readText().replace(fullText, newBlockText)
142143
}
144+
145+
companion object {
146+
/** @suppress */
147+
val NAME = FindingName("disable-android-resources")
148+
}
143149
}

modulecheck-parsing/gradle/dsl/api/src/main/kotlin/modulecheck/parsing/gradle/dsl/AndroidGradleSettings.kt

+4-2
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,15 @@ data class AndroidGradleSettings(
2727
data class AndroidBlock(
2828
override val fullText: String,
2929
override val lambdaContent: String,
30-
override val settings: List<Assignment>
30+
override val settings: List<Assignment>,
31+
override val blockSuppressed: List<String>
3132
) : AgpBlock
3233

3334
data class BuildFeaturesBlock(
3435
override val fullText: String,
3536
override val lambdaContent: String,
36-
override val settings: List<Assignment>
37+
override val settings: List<Assignment>,
38+
override val blockSuppressed: List<String>
3739
) : AgpBlock
3840
}
3941
}

modulecheck-parsing/gradle/dsl/api/src/main/kotlin/modulecheck/parsing/gradle/dsl/Assignment.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,5 @@ data class Assignment(
2121
val value: String,
2222
override val declarationText: String,
2323
override val statementWithSurroundingText: String = declarationText,
24-
override val suppressed: List<String> = emptyList()
24+
override val suppressed: List<String>
2525
) : BuildFileStatement

modulecheck-parsing/gradle/dsl/api/src/main/kotlin/modulecheck/parsing/gradle/dsl/Block.kt

+3
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,7 @@ sealed interface Block<T> {
1919
val fullText: String
2020
val lambdaContent: String
2121
val settings: List<T>
22+
23+
/** [FindingNames][modulecheck.finding.FindingName] which are suppressed at the block level */
24+
val blockSuppressed: List<String>
2225
}

modulecheck-parsing/gradle/dsl/internal/src/main/kotlin/modulecheck/parsing/gradle/dsl/internal/AbstractDependenciesBlock.kt

+7-7
Original file line numberDiff line numberDiff line change
@@ -38,28 +38,28 @@ import modulecheck.utils.remove
3838

3939
abstract class AbstractDependenciesBlock(
4040
private val logger: McLogger,
41-
suppressedForEntireBlock: List<String>,
41+
blockSuppressed: List<String>,
4242
private val configurationNameTransform: ConfigurationNameTransform,
4343
private val projectDependency: ProjectDependency.Factory
4444
) : DependenciesBlock {
4545

4646
private val resetManager = ResetManager()
4747

48-
val suppressedForEntireBlock = suppressedForEntireBlock.updateOldSuppresses()
48+
final override val blockSuppressed = blockSuppressed.updateOldSuppresses()
4949

5050
override val allSuppressions: Map<ProjectDependency, Set<FindingName>> by resetManager.lazyResets {
5151
buildMap<ProjectDependency, MutableSet<FindingName>> {
5252

5353
allModuleDeclarations.forEach { (configuredModule, declarations) ->
5454

5555
val cached = getOrPut(configuredModule) {
56-
suppressedForEntireBlock.mapTo(mutableSetOf()) { FindingName(it) }
56+
blockSuppressed.mapTo(mutableSetOf()) { FindingName(it) }
5757
}
5858

5959
declarations.forEach { moduleDependencyDeclaration ->
6060

6161
cached += moduleDependencyDeclaration.suppressed.updateOldSuppresses()
62-
.plus(suppressedForEntireBlock)
62+
.plus(blockSuppressed)
6363
.asFindingNames()
6464
}
6565
}
@@ -95,7 +95,7 @@ abstract class AbstractDependenciesBlock(
9595
moduleName = coordinates.moduleName,
9696
version = coordinates.version,
9797
coordinates = coordinates,
98-
suppressed = suppressed.updateOldSuppresses() + suppressedForEntireBlock,
98+
suppressed = suppressed.updateOldSuppresses() + blockSuppressed,
9999
configurationNameTransform = configurationNameTransform
100100
)
101101
_allDeclarations.add(declaration)
@@ -116,7 +116,7 @@ abstract class AbstractDependenciesBlock(
116116
configName = configName,
117117
declarationText = parsedString,
118118
statementWithSurroundingText = originalString,
119-
suppressed = suppressed.updateOldSuppresses() + suppressedForEntireBlock,
119+
suppressed = suppressed.updateOldSuppresses() + blockSuppressed,
120120
configurationNameTransform = configurationNameTransform
121121
)
122122
_allDeclarations.add(declaration)
@@ -150,7 +150,7 @@ abstract class AbstractDependenciesBlock(
150150
configName = configName,
151151
declarationText = parsedString,
152152
statementWithSurroundingText = originalString,
153-
suppressed = suppressed.updateOldSuppresses() + suppressedForEntireBlock,
153+
suppressed = suppressed.updateOldSuppresses() + blockSuppressed,
154154
configurationNameTransform = configurationNameTransform
155155
)
156156

modulecheck-parsing/gradle/dsl/internal/src/main/kotlin/modulecheck/parsing/gradle/dsl/internal/AbstractPluginsBlock.kt

+5-5
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import java.io.File
2626

2727
abstract class AbstractPluginsBlock(
2828
private val logger: McLogger,
29-
suppressedForEntireBlock: List<String>
29+
blockSuppressed: List<String>
3030
) : PluginsBlock {
3131

3232
private val resetManager = ResetManager()
@@ -40,19 +40,19 @@ abstract class AbstractPluginsBlock(
4040

4141
protected val allBlockStatements = mutableListOf<String>()
4242

43-
private val suppressedForEntireBlock = suppressedForEntireBlock.updateOldSuppresses()
43+
override val blockSuppressed = blockSuppressed.updateOldSuppresses()
4444

4545
override val allSuppressions: Map<PluginDeclaration, Set<FindingName>> by resetManager.lazyResets {
4646
buildMap<PluginDeclaration, MutableSet<FindingName>> {
4747

4848
_allDeclarations.forEach { pluginDeclaration ->
4949

5050
val cached = getOrPut(pluginDeclaration) {
51-
suppressedForEntireBlock.mapTo(mutableSetOf()) { FindingName(it) }
51+
blockSuppressed.mapTo(mutableSetOf()) { FindingName(it) }
5252
}
5353

5454
cached += pluginDeclaration.suppressed.updateOldSuppresses()
55-
.plus(suppressedForEntireBlock)
55+
.plus(blockSuppressed)
5656
.asFindingNames()
5757
}
5858
}
@@ -67,7 +67,7 @@ abstract class AbstractPluginsBlock(
6767
val declaration = PluginDeclaration(
6868
statementWithSurroundingText = originalString,
6969
declarationText = parsedString,
70-
suppressed = suppressed.updateOldSuppresses() + suppressedForEntireBlock
70+
suppressed = suppressed.updateOldSuppresses() + blockSuppressed
7171
)
7272
_allDeclarations.add(declaration)
7373
resetManager.resetAll()

0 commit comments

Comments
 (0)