diff --git a/.github/workflows/detekt-with-type-resolution.yaml b/.github/workflows/detekt-with-type-resolution.yaml new file mode 100644 index 000000000..5481b644c --- /dev/null +++ b/.github/workflows/detekt-with-type-resolution.yaml @@ -0,0 +1,37 @@ +name: detekt with type resolution + +on: + push: + branches: + - master + pull_request: + branches: + - '*' + +jobs: + gradle: + runs-on: ubuntu-latest + if: ${{ !contains(github.event.head_commit.message, 'ci skip') }} + env: + GRADLE_OPTS: -Dorg.gradle.daemon=false + steps: + - name: Checkout Repo + uses: actions/checkout@v2 + + - name: Cache Gradle Folders + uses: actions/cache@v2 + with: + path: | + ~/.gradle/caches/ + ~/.gradle/wrapper/ + key: cache-gradle-${{ hashFiles('detekt-bom/build.gradle.kts') }} + restore-keys: | + cache-gradle- + + - name: Setup Java + uses: actions/setup-java@v1 + with: + java-version: 11 + + - name: Run analysis + run: ./gradlew detektMain detektTest --build-cache --parallel diff --git a/.github/workflows/pre-merge.yaml b/.github/workflows/pre-merge.yaml index eafbf002a..1a8cb6df8 100644 --- a/.github/workflows/pre-merge.yaml +++ b/.github/workflows/pre-merge.yaml @@ -53,7 +53,7 @@ jobs: - name: Build detekt - run: ./gradlew build :detekt-cli:shadowJarExecutable --parallel + run: ./gradlew build :detekt-cli:shadowJarExecutable --parallel -x detekt - name: Run detekt-cli --help run: java -jar ./detekt-cli/build/run/detekt --help - name: Run detekt-cli with argsfile diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/internal/ValidatableConfiguration.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/internal/ValidatableConfiguration.kt index 26022fe73..32b867754 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/internal/ValidatableConfiguration.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/internal/ValidatableConfiguration.kt @@ -54,16 +54,16 @@ fun validateConfig( val propertyPath = "${if (parentPath == null) "" else "$parentPath>"}$prop" - val matchedDeprecation = DEPRECATED_PROPERTIES + val deprecationWarning = DEPRECATED_PROPERTIES .find { (regex, _) -> regex.matches(propertyPath) } - val isDeprecated = matchedDeprecation != null + ?.second val isExcluded = excludePatterns.any { it.matches(propertyPath) } - if (isDeprecated) { - notifications.add(propertyIsDeprecated(propertyPath, matchedDeprecation!!.second)) + if (deprecationWarning != null) { + notifications.add(propertyIsDeprecated(propertyPath, deprecationWarning)) } - if (isDeprecated || isExcluded) { + if (deprecationWarning != null || isExcluded) { continue } diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/Analyzer.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/Analyzer.kt index 22f4ead02..9d1ae8f7e 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/Analyzer.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/Analyzer.kt @@ -37,6 +37,7 @@ internal class Analyzer( bindingContext: BindingContext = BindingContext.EMPTY ): Map> { val languageVersionSettings = settings.environment.configuration.languageVersionSettings + @Suppress("DEPRECATION") val dataFlowValueFactory = DataFlowValueFactoryImpl(languageVersionSettings) val compilerResources = CompilerResources(languageVersionSettings, dataFlowValueFactory) @@ -113,9 +114,9 @@ internal class Analyzer( for (rule in rules) { rule.visitFile(file, bindingContext, compilerResources) for (finding in rule.findings) { - val mappedRuleSet = idMapping[finding.id] ?: error("Mapping for '${finding.id}' expected.") - result.putIfAbsent(mappedRuleSet, mutableListOf()) - result[mappedRuleSet]!!.add(finding) + val mappedRuleSet = checkNotNull(idMapping[finding.id]) { "Mapping for '${finding.id}' expected." } + result.computeIfAbsent(mappedRuleSet) { mutableListOf() } + .add(finding) } } } diff --git a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/rules/MultiRuleSpec.kt b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/rules/MultiRuleSpec.kt index bc4c22c17..4c0ebb94e 100644 --- a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/rules/MultiRuleSpec.kt +++ b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/rules/MultiRuleSpec.kt @@ -83,6 +83,7 @@ private class TestMultiRule(config: Config) : MultiRule() { } } +@Suppress("detekt.UnnecessaryAbstractClass") // uses inherited members private abstract class AbstractRule(config: Config) : Rule(config) { override val issue: Issue = Issue(javaClass.simpleName, Severity.Minor, "", Debt.TWENTY_MINS) override fun visitKtFile(file: KtFile) = report(CodeSmell(issue, Entity.from(file), message = "")) diff --git a/detekt-metrics/src/main/kotlin/io/github/detekt/metrics/ComplexityReportGenerator.kt b/detekt-metrics/src/main/kotlin/io/github/detekt/metrics/ComplexityReportGenerator.kt index 577ae252d..b3f6793a5 100644 --- a/detekt-metrics/src/main/kotlin/io/github/detekt/metrics/ComplexityReportGenerator.kt +++ b/detekt-metrics/src/main/kotlin/io/github/detekt/metrics/ComplexityReportGenerator.kt @@ -43,8 +43,8 @@ class ComplexityReportGenerator(private val complexityMetric: ComplexityMetric) else -> { numberOfSmells = complexityMetric.findings.sumBy { it.value.size } smellPerThousandLines = numberOfSmells * 1000 / complexityMetric.lloc - mccPerThousandLines = complexityMetric.mcc!! * 1000 / complexityMetric.lloc - commentSourceRatio = complexityMetric.cloc!! * 100 / complexityMetric.sloc + mccPerThousandLines = requireNotNull(complexityMetric.mcc) * 1000 / complexityMetric.lloc + commentSourceRatio = requireNotNull(complexityMetric.cloc) * 100 / complexityMetric.sloc false } } diff --git a/detekt-rules-complexity/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/TooManyFunctions.kt b/detekt-rules-complexity/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/TooManyFunctions.kt index 2876a82b5..9a1ff7603 100644 --- a/detekt-rules-complexity/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/TooManyFunctions.kt +++ b/detekt-rules-complexity/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/TooManyFunctions.kt @@ -79,7 +79,7 @@ class TooManyFunctions(config: Config = Config.empty) : Rule(config) { klass.isInterface() -> { if (amount >= thresholdInInterfaces) { report(ThresholdedCodeSmell(issue, - Entity.from(klass.nameIdentifier!!), + Entity.atName(klass), Metric("SIZE", amount, thresholdInInterfaces), "Interface '${klass.name}' with '$amount' functions detected. " + "Defined threshold inside interfaces is set to " + @@ -89,7 +89,7 @@ class TooManyFunctions(config: Config = Config.empty) : Rule(config) { klass.isEnum() -> { if (amount >= thresholdInEnums) { report(ThresholdedCodeSmell(issue, - Entity.from(klass.nameIdentifier!!), + Entity.atName(klass), Metric("SIZE", amount, thresholdInEnums), "Enum class '${klass.name}' with '$amount' functions detected. " + "Defined threshold inside enum classes is set to " + @@ -99,7 +99,7 @@ class TooManyFunctions(config: Config = Config.empty) : Rule(config) { else -> { if (amount >= thresholdInClasses) { report(ThresholdedCodeSmell(issue, - Entity.from(klass.nameIdentifier!!), + Entity.atName(klass), Metric("SIZE", amount, thresholdInClasses), "Class '${klass.name}' with '$amount' functions detected. " + "Defined threshold inside classes is set to '$thresholdInClasses'")) diff --git a/detekt-rules-empty/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyRule.kt b/detekt-rules-empty/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyRule.kt index bd7ddcd90..8a2bd39fa 100644 --- a/detekt-rules-empty/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyRule.kt +++ b/detekt-rules-empty/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyRule.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.psi.KtExpression /** * Rule to detect empty blocks of code. */ +@Suppress("detekt.UnnecessaryAbstractClass") // we really do not want instances of this class abstract class EmptyRule( config: Config, description: String = "Empty block of code detected. As they serve no purpose they should be removed.", diff --git a/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/FindingsAssertions.kt b/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/FindingsAssertions.kt index f5e7d2acd..2a2425e4f 100644 --- a/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/FindingsAssertions.kt +++ b/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/FindingsAssertions.kt @@ -25,8 +25,6 @@ class FindingsAssert(actual: List) : FindingAssert(value).`as`(description) fun hasSourceLocations(vararg expected: SourceLocation) = apply { - isNotNull - val actualSources = actual.asSequence() .map { it.location.source } .sortedWith(compareBy({ it.line }, { it.column })) @@ -46,8 +44,6 @@ class FindingsAssert(actual: List) : } fun hasTextLocations(vararg expected: Pair) = apply { - isNotNull - val actualSources = actual.asSequence() .map { it.location.text } .sortedWith(compareBy({ it.start }, { it.end })) @@ -64,8 +60,6 @@ class FindingsAssert(actual: List) : } fun hasTextLocations(vararg expected: String): FindingsAssert { - isNotNull - val finding = actual.firstOrNull() if (finding == null) { if (expected.isEmpty()) { @@ -74,13 +68,12 @@ class FindingsAssert(actual: List) : failWithMessage("Expected ${expected.size} findings but was 0") } } - val code = finding!!.entity.ktElement?.containingKtFile?.text - if (code == null) { - failWithMessage("Expected ${expected.size} findings but was 0") + val code = requireNotNull(finding?.entity?.ktElement?.containingKtFile?.text) { + "Finding expected to provide a KtElement." } val textLocations = expected.map { snippet -> - val index = code!!.indexOf(snippet) + val index = code.indexOf(snippet) if (index < 0) { failWithMessage("The snippet \"$snippet\" doesn't exist in the code") } else {