Skip to content

Commit

Permalink
Refactor Analyzer so that RuleSetProvider.instance is only called once (
Browse files Browse the repository at this point in the history
  • Loading branch information
chao2zhang committed Mar 24, 2021
1 parent abe36cd commit 4a89a25
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 23 deletions.
Expand Up @@ -17,7 +17,6 @@ import io.gitlab.arturbosch.detekt.api.internal.whichOS
import io.gitlab.arturbosch.detekt.core.config.DefaultConfig
import io.gitlab.arturbosch.detekt.core.config.DisabledAutoCorrectConfig
import io.gitlab.arturbosch.detekt.core.config.AllRulesConfig
import io.gitlab.arturbosch.detekt.core.rules.IdMapping
import io.gitlab.arturbosch.detekt.core.rules.associateRuleIdsToRuleSetIds
import io.gitlab.arturbosch.detekt.core.rules.isActive
import io.gitlab.arturbosch.detekt.core.rules.shouldAnalyzeFile
Expand All @@ -35,8 +34,6 @@ internal class Analyzer(
) {

private val config: Config = settings.spec.workaroundConfiguration(settings.config)
private val idMapping: IdMapping =
associateRuleIdsToRuleSetIds(providers.associate { it.ruleSetId to it.instance(config).rules })

fun run(
ktFiles: Collection<KtFile>,
Expand Down Expand Up @@ -103,11 +100,17 @@ internal class Analyzer(
else -> error("No other rule type expected.")
}

val (correctableRules, otherRules) = providers.asSequence()
val activeRuleSetsToRuleSetConfigs = providers.asSequence()
.map { it to config.subConfig(it.ruleSetId) }
.filter { (_, ruleSetConfig) -> ruleSetConfig.isActive() }
.mapLeft { provider, ruleSetConfig -> provider.instance(ruleSetConfig) }
.map { (provider, ruleSetConfig) -> provider.instance(ruleSetConfig) to ruleSetConfig }
.filter { (_, ruleSetConfig) -> ruleSetConfig.shouldAnalyzeFile(file) }

val ruleIdsToRuleSetIds = associateRuleIdsToRuleSetIds(
activeRuleSetsToRuleSetConfigs.map { (ruleSet, _) -> ruleSet }
)

val (correctableRules, otherRules) = activeRuleSetsToRuleSetConfigs
.flatMap { (ruleSet, _) -> ruleSet.rules.asSequence() }
.partition { isCorrectable(it) }

Expand All @@ -117,7 +120,9 @@ internal class Analyzer(
for (rule in rules) {
rule.visitFile(file, bindingContext, compilerResources)
for (finding in rule.findings) {
val mappedRuleSet = checkNotNull(idMapping[finding.id]) { "Mapping for '${finding.id}' expected." }
val mappedRuleSet = checkNotNull(ruleIdsToRuleSetIds[finding.id]) {
"Mapping for '${finding.id}' expected."
}
result.computeIfAbsent(mappedRuleSet) { mutableListOf() }
.add(finding)
}
Expand All @@ -131,10 +136,6 @@ internal class Analyzer(
}
}

private fun <T, U, R> Sequence<Pair<T, U>>.mapLeft(transform: (T, U) -> R): Sequence<Pair<R, U>> {
return this.map { (first, second) -> transform(first, second) to second }
}

private fun MutableMap<String, List<Finding>>.mergeSmells(other: Map<String, List<Finding>>) {
for ((key, findings) in other.entries) {
merge(key, findings) { f1, f2 -> f1.plus(f2) }
Expand Down
Expand Up @@ -33,25 +33,22 @@ fun RuleSet.visitFile(
it.findings
}

typealias IdMapping = Map<RuleId, RuleSetId>

fun associateRuleIdsToRuleSetIds(rules: Map<RuleSetId, List<BaseRule>>): IdMapping {
fun associateRuleIdsToRuleSetIds(ruleSets: Sequence<RuleSet>): Map<RuleId, RuleSetId> {
fun extractIds(rule: BaseRule) =
if (rule is MultiRule) {
rule.rules.asSequence().map(Rule::ruleId)
} else {
sequenceOf(rule.ruleId)
}
return rules
.asSequence()
.flatMap { (ruleSetId, baseRules) ->
baseRules
.asSequence()
.flatMap(::extractIds)
.distinct()
.map { ruleId -> ruleId to ruleSetId }
}
.toMap()
return ruleSets.flatMap { ruleSet ->
ruleSet.rules
.asSequence()
.flatMap { rule ->
extractIds(rule).map { ruleId ->
ruleId to ruleSet.id
}
}
}.toMap()
}

fun ProcessingSettings.createRuleProviders(): List<RuleSetProvider> = when (val runPolicy = spec.rulesSpec.runPolicy) {
Expand Down

0 comments on commit 4a89a25

Please sign in to comment.