Skip to content

support suppressing findings #235

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion modulecheck-api/src/main/kotlin/modulecheck/api/Finding.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package modulecheck.api

import modulecheck.api.Finding.Position
import modulecheck.parsing.ModuleDependencyDeclaration
import java.io.File

interface Finding {
Expand All @@ -24,9 +25,16 @@ interface Finding {
val dependentPath: String
val buildFile: File

val statementOrNull: ModuleDependencyDeclaration? get() = null
val statementTextOrNull: String? get() = null
val positionOrNull: Position?

fun logElement(): LogElement

fun shouldSkip(): Boolean = statementOrNull?.suppressed
?.contains(problemName)
?: false

fun logString(): String {
return "${buildFile.path}: ${positionString()} $problemName"
}
Expand All @@ -36,8 +44,23 @@ interface Finding {
data class Position(
val row: Int,
val column: Int
) {
) : Comparable<Position> {
fun logString(): String = "($row, $column): "
override fun compareTo(other: Position): Int {
return row.compareTo(other.row)
}
}

data class LogElement(
val dependentPath: String,
val problemName: String,
val sourceOrNull: String?,
val dependencyPath: String,
val positionOrNull: Position?,
val buildFile: File,
var fixed: Boolean = false
) {
val filePathStr = "${buildFile.path}: ${positionOrNull?.logString().orEmpty()}"
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package modulecheck.core

import modulecheck.api.Finding
import modulecheck.api.Finding.LogElement
import modulecheck.api.Finding.Position
import modulecheck.api.Fixable
import modulecheck.core.internal.positionOf
Expand All @@ -29,7 +30,7 @@ data class CouldUseAnvilFinding(
) : Finding, Fixable {

override val dependencyIdentifier = "com.google.dagger:dagger-compiler"
override val problemName = "could use Anvil factory generator"
override val problemName = "useAnvilFactories"

override val positionOrNull: Position? by lazy {

Expand All @@ -42,5 +43,16 @@ data class CouldUseAnvilFinding(
?.positionOf(statement, "kapt".asConfigurationName())
}

override fun logElement(): LogElement {
return LogElement(
dependentPath = dependentPath,
problemName = problemName,
sourceOrNull = null,
dependencyPath = dependencyIdentifier,
positionOrNull = positionOrNull,
buildFile = buildFile
)
}

override val statementTextOrNull: String? get() = null
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@
package modulecheck.core

import modulecheck.api.Finding
import modulecheck.api.Finding.LogElement
import modulecheck.api.Fixable
import modulecheck.api.positionOfStatement
import modulecheck.core.internal.statementOrNullIn
import modulecheck.parsing.ConfigurationName
import modulecheck.parsing.ModuleDependencyDeclaration
import modulecheck.parsing.Project2

abstract class DependencyFinding(
Expand All @@ -37,10 +39,26 @@ abstract class DependencyFinding(
.positionOfStatement(statement)
}

override val statementTextOrNull: String? by lazy {
override val statementOrNull: ModuleDependencyDeclaration? by lazy {
dependencyProject
.statementOrNullIn(buildFile, configurationName)
}
override val statementTextOrNull: String? by lazy {
statementOrNull?.statementWithSurroundingText
}

override fun logElement(): LogElement {
return LogElement(
dependentPath = dependentPath,
problemName = problemName,
sourceOrNull = fromStringOrEmpty(),
dependencyPath = dependencyProject.path,
positionOrNull = positionOrNull,
buildFile = buildFile
)
}

abstract fun fromStringOrEmpty(): String

override fun equals(other: Any?): Boolean {
if (this === other) return true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

package modulecheck.core

import modulecheck.api.Finding.LogElement
import modulecheck.api.Finding.Position
import modulecheck.core.internal.positionIn
import modulecheck.parsing.ConfigurationName
Expand All @@ -38,11 +39,22 @@ data class InheritedDependencyFinding(
source?.project?.positionIn(buildFile, configurationName)
}

private fun fromStringOrEmpty(): String {
override fun logElement(): LogElement {
return LogElement(
dependentPath = dependentPath,
problemName = problemName,
sourceOrNull = fromStringOrEmpty(),
dependencyPath = dependencyProject.path,
positionOrNull = positionOrNull,
buildFile = buildFile
)
}

override fun fromStringOrEmpty(): String {
return if (dependencyProject.path == source?.project?.path) {
""
} else {
" from: ${source?.project?.path}"
"${source?.project?.path}"
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@

package modulecheck.core

import modulecheck.api.Finding.LogElement
import modulecheck.core.internal.statementOrNullIn
import modulecheck.parsing.ConfigurationName
import modulecheck.parsing.ConfiguredProjectDependency
import modulecheck.parsing.ModuleDependencyDeclaration
import modulecheck.parsing.Project2
import java.io.File

Expand All @@ -31,20 +33,35 @@ data class MustBeApiFinding(

override val dependencyIdentifier = dependencyProject.path + fromStringOrEmpty()

override val statementTextOrNull: String? by lazy {
super.statementTextOrNull
override val statementOrNull: ModuleDependencyDeclaration? by lazy {
super.statementOrNull
?: source?.project
?.statementOrNullIn(buildFile, configurationName)
}
override val statementTextOrNull: String? by lazy {
super.statementTextOrNull
?: statementOrNull?.statementWithSurroundingText
}

private fun fromStringOrEmpty(): String {
override fun fromStringOrEmpty(): String {
return if (dependencyProject.path == source?.project?.path) {
""
} else {
" from: ${source?.project?.path}"
"${source?.project?.path}"
}
}

override fun logElement(): LogElement {
return LogElement(
dependentPath = dependentPath,
problemName = problemName,
sourceOrNull = fromStringOrEmpty(),
dependencyPath = dependencyProject.path,
positionOrNull = positionOrNull,
buildFile = buildFile
)
}

override fun fix(): Boolean = synchronized(buildFile) {

val statement = statementTextOrNull ?: return false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ data class OverShotDependencyFinding(
override val dependencyProject: Project2,
override val dependencyIdentifier: String,
override val configurationName: ConfigurationName
) : DependencyFinding("demoted") {
) : DependencyFinding("overshot") {

override fun fix(): Boolean {

Expand Down Expand Up @@ -74,17 +74,14 @@ data class OverShotDependencyFinding(
return false
}

private fun matchingDeclaration(block: DependenciesBlock) =
(
block.allDeclarations
.filterIsInstance<ModuleDependencyDeclaration>()
.maxByOrNull { declaration -> declaration.configName == configurationName }
?: block.allDeclarations
.filterNot { it is ModuleDependencyDeclaration }
.maxByOrNull { declaration -> declaration.configName == configurationName }
?: block.allDeclarations
.lastOrNull()
)
private fun matchingDeclaration(block: DependenciesBlock) = block.allDeclarations
.filterIsInstance<ModuleDependencyDeclaration>()
.maxByOrNull { declaration -> declaration.configName == configurationName }
?: block.allDeclarations
.filterNot { it is ModuleDependencyDeclaration }
.maxByOrNull { declaration -> declaration.configName == configurationName }
?: block.allDeclarations
.lastOrNull()

private fun newModuleDeclaration(match: DependencyDeclaration) = when (match) {
is ExternalDependencyDeclaration -> dependencyProject.path
Expand Down Expand Up @@ -114,6 +111,8 @@ data class OverShotDependencyFinding(
}
}

override fun fromStringOrEmpty(): String = ""

override fun toString(): String {
return "OverShotDependency(\n" +
"\tdependentPath='$dependentPath', \n" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ data class RedundantDependencyFinding(

override val dependencyIdentifier = dependencyPath + fromStringOrEmpty()

private fun fromStringOrEmpty(): String {
override fun fromStringOrEmpty(): String {

return if (from.all { dependencyProject.path == it.path }) {
""
} else {
" from: ${from.joinToString { it.path }}"
from.joinToString { it.path }
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ data class UnusedDependency(
"\tconfigurationName=$configurationName\n" +
")"
}

override fun fromStringOrEmpty(): String = ""
}

data class UnusedDependencies(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,21 @@ import modulecheck.api.positionOfStatement
import modulecheck.core.parse
import modulecheck.parsing.ConfigurationName
import modulecheck.parsing.DependencyBlockParser
import modulecheck.parsing.ModuleDependencyDeclaration
import modulecheck.parsing.Project2
import java.io.File

fun Project2.statementOrNullIn(
dependentBuildFile: File,
configuration: ConfigurationName
): String? {
): ModuleDependencyDeclaration? {
return DependencyBlockParser
.parse(dependentBuildFile)
.firstNotNullOfOrNull { block ->
block.getOrEmpty(path, configuration)
.takeIf { it.isNotEmpty() }
}
?.firstOrNull()
?.statementWithSurroundingText
}

fun Project2.positionIn(
Expand All @@ -45,5 +45,5 @@ fun Project2.positionIn(
val statement = statementOrNullIn(dependentBuildFile, configuration) ?: return null

return dependentBuildFile.readText()
.positionOfStatement(statement)
.positionOfStatement(statement.statementWithSurroundingText)
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package modulecheck.core.kapt

import modulecheck.api.Finding
import modulecheck.api.Finding.LogElement
import modulecheck.api.Finding.Position
import modulecheck.api.Fixable
import modulecheck.core.rule.KAPT_PLUGIN_FUN
Expand All @@ -31,7 +32,18 @@ data class UnusedKaptPluginFinding(

override val dependencyIdentifier = KAPT_PLUGIN_ID

override val problemName = "unused kapt plugin"
override val problemName = "unusedKaptPlugin"

override fun logElement(): LogElement {
return LogElement(
dependentPath = dependentPath,
problemName = problemName,
sourceOrNull = null,
dependencyPath = dependencyIdentifier,
positionOrNull = positionOrNull,
buildFile = buildFile
)
}

override val positionOrNull: Position? by lazy {
val text = buildFile
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

package modulecheck.core.kapt

import modulecheck.api.Finding.LogElement
import modulecheck.api.Finding.Position
import modulecheck.core.internal.positionOf
import modulecheck.parsing.ConfigurationName
Expand All @@ -29,7 +30,18 @@ data class UnusedKaptProcessorFinding(

override val dependencyIdentifier = dependencyPath

override val problemName = "unused ${configurationName.value} dependency"
override val problemName = "unusedKaptProcessor"

override fun logElement(): LogElement {
return LogElement(
dependentPath = dependentPath,
problemName = problemName,
sourceOrNull = null,
dependencyPath = dependencyPath,
positionOrNull = positionOrNull,
buildFile = buildFile
)
}

override val positionOrNull: Position? by lazy {
// Kapt paths are different from other project dependencies.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package modulecheck.core.rule.android

import modulecheck.api.Finding
import modulecheck.api.Finding.LogElement
import modulecheck.api.Finding.Position
import modulecheck.api.Fixable
import modulecheck.api.positionOfStatement
Expand All @@ -28,7 +29,7 @@ data class DisableViewBindingGenerationFinding(
override val buildFile: File
) : Finding, Fixable {

override val problemName = "unused ViewBinding generation"
override val problemName = "disableViewBinding"

override val dependencyIdentifier = ""

Expand All @@ -47,6 +48,17 @@ data class DisableViewBindingGenerationFinding(
fileText.positionOfStatement(statement)
}

override fun logElement(): LogElement {
return LogElement(
dependentPath = dependentPath,
problemName = problemName,
sourceOrNull = null,
dependencyPath = "",
positionOrNull = positionOrNull,
buildFile = buildFile
)
}

override fun fix(): Boolean = synchronized(buildFile) {
val ktFile = kotlinBuildFileOrNull() ?: return false

Expand Down
Loading