diff --git a/.editorconfig b/.editorconfig index b05474df7..fbd50826f 100644 --- a/.editorconfig +++ b/.editorconfig @@ -4,8 +4,8 @@ root = true [*] insert_final_newline = true -[*.{kt,groovy}] -indent_style = tab +[*.{kt, groovy}] +indent_style = space [*.yml] indent_style = space diff --git a/build.gradle.kts b/build.gradle.kts index 9d7e3878d..17d710088 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,273 +1,309 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import com.jfrog.bintray.gradle.BintrayExtension -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile +import io.gitlab.arturbosch.detekt.Detekt +import java.util.Date import org.gradle.api.tasks.testing.logging.TestExceptionFormat import org.gradle.api.tasks.testing.logging.TestLogEvent import org.gradle.util.GFileUtils import org.jetbrains.dokka.gradle.DokkaTask -import io.gitlab.arturbosch.detekt.Detekt - -import java.util.Date +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { - kotlin("jvm") version "1.3.21" - id("com.jfrog.bintray") version "1.8.4" - id("com.github.ben-manes.versions") version "0.20.0" - id("com.github.johnrengelman.shadow") version "4.0.3" apply false - id("org.sonarqube") version "2.6.2" - id("io.gitlab.arturbosch.detekt") - id("org.jetbrains.dokka") version "0.9.17" - jacoco + kotlin("jvm") version "1.3.21" + id("com.jfrog.bintray") version "1.8.4" + id("com.github.ben-manes.versions") version "0.20.0" + id("com.github.johnrengelman.shadow") version "4.0.3" apply false + id("org.sonarqube") version "2.6.2" + id("io.gitlab.arturbosch.detekt") + id("org.jetbrains.dokka") version "0.9.17" + jacoco } tasks.withType { - gradleVersion = "5.2" - distributionType = Wrapper.DistributionType.ALL - doLast { - /* + gradleVersion = "5.2" + distributionType = Wrapper.DistributionType.ALL + doLast { + /* * Copy the properties file into the detekt-gradle-plugin project. * This allows IDEs like IntelliJ to import the detekt-gradle-plugin as a standalone project. */ - val gradlePluginWrapperDir = File(gradle.includedBuild("detekt-gradle-plugin").projectDir, "/gradle/wrapper") - GFileUtils.mkdirs(gradlePluginWrapperDir) - copy { - from(propertiesFile) - into(gradlePluginWrapperDir) - } - } + val gradlePluginWrapperDir = File(gradle.includedBuild("detekt-gradle-plugin").projectDir, "/gradle/wrapper") + GFileUtils.mkdirs(gradlePluginWrapperDir) + copy { + from(propertiesFile) + into(gradlePluginWrapperDir) + } + } } tasks.withType { - dependsOn(gradle.includedBuild("detekt-gradle-plugin").task(":test")) + dependsOn(gradle.includedBuild("detekt-gradle-plugin").task(":test")) } tasks.withType { - dependsOn("detekt-cli:assemble") - dependsOn("detekt-formatting:assemble") - dependsOn(gradle.includedBuild("detekt-gradle-plugin").task(":detekt")) + dependsOn("detekt-cli:assemble") + dependsOn("detekt-formatting:assemble") + dependsOn(gradle.includedBuild("detekt-gradle-plugin").task(":detekt")) } val detektVersion: String by project val usedDetektVersion: String by project allprojects { - group = "io.gitlab.arturbosch.detekt" - version = detektVersion + group = "io.gitlab.arturbosch.detekt" + version = detektVersion - repositories { - mavenLocal() - jcenter() - maven(url = "http://dl.bintray.com/jetbrains/spek") - maven(url = "https://dl.bintray.com/arturbosch/generic") - } + repositories { + mavenLocal() + jcenter() + maven(url = "http://dl.bintray.com/jetbrains/spek") + maven(url = "https://dl.bintray.com/arturbosch/generic") + } } subprojects { - val project = this + val project = this - apply { - plugin("java-library") - plugin("kotlin") - plugin("com.jfrog.bintray") - plugin("maven-publish") - plugin("io.gitlab.arturbosch.detekt") - plugin("org.jetbrains.dokka") - plugin("jacoco") - } + apply { + plugin("java-library") + plugin("kotlin") + plugin("com.jfrog.bintray") + plugin("maven-publish") + plugin("io.gitlab.arturbosch.detekt") + plugin("org.jetbrains.dokka") + plugin("jacoco") + } - val jacocoVersion: String by project - jacoco.toolVersion = jacocoVersion + val jacocoVersion: String by project + jacoco.toolVersion = jacocoVersion - tasks.named("jacocoTestReport").configure { - reports.xml.isEnabled = true - reports.html.isEnabled = true - dependsOn(tasks.named("test")) - } + tasks.named("jacocoTestReport").configure { + reports.xml.isEnabled = true + reports.html.isEnabled = true + dependsOn(tasks.named("test")) + } - val userHome = System.getProperty("user.home") + val userHome = System.getProperty("user.home") - detekt { - debug = true - toolVersion = usedDetektVersion - config = files( - project.rootDir.resolve("detekt-cli/src/main/resources/default-detekt-config.yml"), - project.rootDir.resolve("reports/failfast.yml") - ) - filters = ".*/resources/.*,.*/build/.*" - baseline = project.rootDir.resolve("reports/baseline.xml") + detekt { + debug = true + toolVersion = usedDetektVersion + config = files( + project.rootDir.resolve("detekt-cli/src/main/resources/default-detekt-config.yml"), + project.rootDir.resolve("reports/failfast.yml") + ) + filters = ".*/resources/.*,.*/build/.*" + baseline = project.rootDir.resolve("reports/baseline.xml") - reports { - xml.enabled = true - html.enabled = true - } + reports { + xml.enabled = true + html.enabled = true + } - idea { - path = "$userHome/.idea" - codeStyleScheme = "$userHome/.idea/idea-code-style.xml" - inspectionsProfile = "$userHome/.idea/inspect.xml" - report = "project.projectDir/reports" - mask = "*.kt" - } - } + idea { + path = "$userHome/.idea" + codeStyleScheme = "$userHome/.idea/idea-code-style.xml" + inspectionsProfile = "$userHome/.idea/inspect.xml" + report = "project.projectDir/reports" + mask = "*.kt" + } + } - val shadowedProjects = listOf("detekt-cli", "detekt-watcher", "detekt-generator") + val shadowedProjects = listOf("detekt-cli", "detekt-watcher", "detekt-generator") - if (project.name in shadowedProjects) { - apply { - plugin("application") - plugin("com.github.johnrengelman.shadow") - tasks.withType { - archiveClassifier.set("all") - } - } - } + if (project.name in shadowedProjects) { + apply { + plugin("application") + plugin("com.github.johnrengelman.shadow") + tasks.withType { + archiveClassifier.set("all") + } + } + } - tasks.withType { - useJUnitPlatform() - testLogging { - // set options for log level LIFECYCLE - events = setOf( - TestLogEvent.FAILED, - TestLogEvent.PASSED, - TestLogEvent.SKIPPED, - TestLogEvent.STANDARD_OUT - ) - exceptionFormat = TestExceptionFormat.FULL - showExceptions = true - showCauses = true - showStackTraces = true - } - } + tasks.withType { + useJUnitPlatform() + testLogging { + // set options for log level LIFECYCLE + events = setOf( + TestLogEvent.FAILED, + TestLogEvent.PASSED, + TestLogEvent.SKIPPED, + TestLogEvent.STANDARD_OUT + ) + exceptionFormat = TestExceptionFormat.FULL + showExceptions = true + showCauses = true + showStackTraces = true + } + } - tasks.withType { - kotlinOptions.jvmTarget = "1.8" - // https://youtrack.jetbrains.com/issue/KT-24946 - kotlinOptions.freeCompilerArgs = listOf( - "-Xskip-runtime-version-check", - "-Xdisable-default-scripting-plugin", - "-Xuse-experimental=kotlin.Experimental" - ) - kotlinOptions.allWarningsAsErrors = shouldTreatCompilerWarningsAsErrors() - } + tasks.withType { + kotlinOptions.jvmTarget = "1.8" + // https://youtrack.jetbrains.com/issue/KT-24946 + kotlinOptions.freeCompilerArgs = listOf( + "-Xskip-runtime-version-check", + "-Xdisable-default-scripting-plugin", + "-Xuse-experimental=kotlin.Experimental" + ) + kotlinOptions.allWarningsAsErrors = shouldTreatCompilerWarningsAsErrors() + } - bintray { - user = System.getenv("BINTRAY_USER") ?: "" - key = System.getenv("BINTRAY_API_KEY") ?: "" - val mavenCentralUser = System.getenv("MAVEN_CENTRAL_USER") ?: "" - val mavenCentralPassword = System.getenv("MAVEN_CENTRAL_PW") ?: "" + bintray { + user = System.getenv("BINTRAY_USER") ?: "" + key = System.getenv("BINTRAY_API_KEY") ?: "" + val mavenCentralUser = System.getenv("MAVEN_CENTRAL_USER") ?: "" + val mavenCentralPassword = System.getenv("MAVEN_CENTRAL_PW") ?: "" - setPublications("DetektPublication") + setPublications("DetektPublication") - override = (project.version as? String)?.endsWith("-SNAPSHOT") == true + override = (project.version as? String)?.endsWith("-SNAPSHOT") == true - pkg(delegateClosureOf { - repo = "code-analysis" - name = "detekt" - userOrg = "arturbosch" - setLicenses("Apache-2.0") - vcsUrl = "https://github.com/arturbosch/detekt" + pkg(delegateClosureOf { + repo = "code-analysis" + name = "detekt" + userOrg = "arturbosch" + setLicenses("Apache-2.0") + vcsUrl = "https://github.com/arturbosch/detekt" - version(delegateClosureOf { - name = project.version as? String - released = Date().toString() + version(delegateClosureOf { + name = project.version as? String + released = Date().toString() - gpg(delegateClosureOf { - sign = true - }) + gpg(delegateClosureOf { + sign = true + }) - mavenCentralSync(delegateClosureOf { - sync = true - user = mavenCentralUser - password = mavenCentralPassword - close = "1" - }) - }) - }) - } + mavenCentralSync(delegateClosureOf { + sync = true + user = mavenCentralUser + password = mavenCentralPassword + close = "1" + }) + }) + }) + } - tasks.withType { - // suppresses undocumented classes but not dokka warnings - // https://github.com/Kotlin/dokka/issues/229 && https://github.com/Kotlin/dokka/issues/319 - reportUndocumented = false - outputFormat = "javadoc" - outputDirectory = "$buildDir/javadoc" - // Java 8 is only version supported both by Oracle/OpenJDK and Dokka itself - // https://github.com/Kotlin/dokka/issues/294 - enabled = JavaVersion.current().isJava8 - } + tasks.withType { + // suppresses undocumented classes but not dokka warnings + // https://github.com/Kotlin/dokka/issues/229 && https://github.com/Kotlin/dokka/issues/319 + reportUndocumented = false + outputFormat = "javadoc" + outputDirectory = "$buildDir/javadoc" + // Java 8 is only version supported both by Oracle/OpenJDK and Dokka itself + // https://github.com/Kotlin/dokka/issues/294 + enabled = JavaVersion.current().isJava8 + } - val sourcesJar by tasks.creating(Jar::class) { - dependsOn("classes") - archiveClassifier.set("sources") - from(sourceSets["main"].allSource) - } + val sourcesJar by tasks.creating(Jar::class) { + dependsOn("classes") + archiveClassifier.set("sources") + from(sourceSets["main"].allSource) + } - val javadocJar by tasks.creating(Jar::class) { - dependsOn("dokka") - archiveClassifier.set("javadoc") - from(buildDir.resolve("javadoc")) - } + val javadocJar by tasks.creating(Jar::class) { + dependsOn("dokka") + archiveClassifier.set("javadoc") + from(buildDir.resolve("javadoc")) + } - artifacts { - archives(sourcesJar) - archives(javadocJar) - } + artifacts { + archives(sourcesJar) + archives(javadocJar) + } - configure { - publications.create("DetektPublication") { - from(components["java"]) - artifact(sourcesJar) - artifact(javadocJar) - if (project.name in shadowedProjects) { - artifact(tasks.getByName("shadowJar")) - } - groupId = this@subprojects.group as? String - artifactId = this@subprojects.name - version = this@subprojects.version as? String - pom.withXml { - asNode().apply { - appendNode("description", "Static code analysis for Kotlin") - appendNode("name", "detekt") - appendNode("url", "https://arturbosch.github.io/detekt") + configure { + publications.create("DetektPublication") { + from(components["java"]) + artifact(sourcesJar) + artifact(javadocJar) + if (project.name in shadowedProjects) { + artifact(tasks.getByName("shadowJar")) + } + groupId = this@subprojects.group as? String + artifactId = this@subprojects.name + version = this@subprojects.version as? String + pom.withXml { + asNode().apply { + appendNode("description", "Static code analysis for Kotlin") + appendNode("name", "detekt") + appendNode("url", "https://arturbosch.github.io/detekt") - val license = appendNode("licenses").appendNode("license") - license.appendNode("name", "The Apache Software License, Version 2.0") - license.appendNode("url", "http://www.apache.org/licenses/LICENSE-2.0.txt") - license.appendNode("distribution", "repo") + val license = appendNode("licenses").appendNode("license") + license.appendNode("name", "The Apache Software License, Version 2.0") + license.appendNode("url", "http://www.apache.org/licenses/LICENSE-2.0.txt") + license.appendNode("distribution", "repo") - val developer = appendNode("developers").appendNode("developer") - developer.appendNode("id", "Artur Bosch") - developer.appendNode("name", "Artur Bosch") - developer.appendNode("email", "arturbosch@gmx.de") + val developer = appendNode("developers").appendNode("developer") + developer.appendNode("id", "Artur Bosch") + developer.appendNode("name", "Artur Bosch") + developer.appendNode("email", "arturbosch@gmx.de") - appendNode("scm").appendNode("url", "https://github.com/arturbosch/detekt") - } - } - } - } + appendNode("scm").appendNode("url", "https://github.com/arturbosch/detekt") + } + } + } + } - val assertjVersion: String by project - val spekVersion: String by project - val kotlinTest by configurations.creating + val assertjVersion: String by project + val spekVersion: String by project + val kotlinTest by configurations.creating - dependencies { - implementation(kotlin("stdlib")) + dependencies { + implementation(kotlin("stdlib")) - detekt(project(":detekt-cli")) - detektPlugins(project(":detekt-formatting")) + detekt(project(":detekt-cli")) + detektPlugins(project(":detekt-formatting")) - kotlinTest("org.assertj:assertj-core:$assertjVersion") - kotlinTest("org.jetbrains.spek:spek-api:$spekVersion") - kotlinTest("org.jetbrains.spek:spek-subject-extension:$spekVersion") - } + kotlinTest("org.assertj:assertj-core:$assertjVersion") + kotlinTest("org.jetbrains.spek:spek-api:$spekVersion") + kotlinTest("org.jetbrains.spek:spek-subject-extension:$spekVersion") + } - sourceSets["main"].java.srcDirs("src/main/kotlin") + sourceSets["main"].java.srcDirs("src/main/kotlin") } /** * Usage: ./gradlew build -PwarningsAsErrors=true. */ fun shouldTreatCompilerWarningsAsErrors(): Boolean { - return project.findProperty("warningsAsErrors") == "true" + return project.findProperty("warningsAsErrors") == "true" +} + +dependencies { + detektPlugins(project(":detekt-formatting")) +} + +val detektFormat by tasks.registering(Detekt::class) { + description = "Reformats whole code base." + input = files(projectDir) + filters.set(".*/resources/.*") + config = files( + projectDir.resolve("detekt-cli/src/main/resources/default-detekt-config.yml"), + projectDir.resolve("reports/format.yml") + ) + debug = true + parallel = true + disableDefaultRuleSets = true + reports { + xml { enabled = false } + html { enabled = false } + } +} + +val detektAll by tasks.registering(Detekt::class) { + debug = true + parallel = true + input = files(projectDir) + config = files( + project.rootDir.resolve("detekt-cli/src/main/resources/default-detekt-config.yml"), + project.rootDir.resolve("reports/failfast.yml") + ) + filters.set(".*/resources/.*,.*/build/.*") + baseline.set(project.rootDir.resolve("reports/baseline.xml")) + reports { + xml.enabled = false + html.enabled = false + } } diff --git a/detekt-api/build.gradle.kts b/detekt-api/build.gradle.kts index 63ebae0c9..36b79ed03 100644 --- a/detekt-api/build.gradle.kts +++ b/detekt-api/build.gradle.kts @@ -5,12 +5,12 @@ val junitPlatformVersion: String by project val spekVersion: String by project dependencies { - implementation("org.yaml:snakeyaml:$yamlVersion") - api(kotlin("compiler-embeddable")) - implementation(kotlin("reflect")) + implementation("org.yaml:snakeyaml:$yamlVersion") + api(kotlin("compiler-embeddable")) + implementation(kotlin("reflect")) - testImplementation(project(":detekt-test")) + testImplementation(project(":detekt-test")) - testRuntimeOnly("org.junit.platform:junit-platform-launcher:$junitPlatformVersion") - testRuntimeOnly("org.jetbrains.spek:spek-junit-platform-engine:$spekVersion") + testRuntimeOnly("org.junit.platform:junit-platform-launcher:$junitPlatformVersion") + testRuntimeOnly("org.jetbrains.spek:spek-junit-platform-engine:$spekVersion") } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/AnnotationExcluder.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/AnnotationExcluder.kt index 3c79ac92f..ae8267036 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/AnnotationExcluder.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/AnnotationExcluder.kt @@ -13,25 +13,26 @@ import org.jetbrains.kotlin.psi.KtFile * @author schalkms */ class AnnotationExcluder( - root: KtFile, - private val excludes: SplitPattern) { + root: KtFile, + private val excludes: SplitPattern +) { - private var resolvedAnnotations = root.importList - ?.imports - ?.asSequence() - ?.filterNot { it.isAllUnder } - ?.mapNotNull { it.importedFqName?.asString() } - ?.map { Pair(it.substringAfterLast('.'), it) } - ?.toMap() + private var resolvedAnnotations = root.importList + ?.imports + ?.asSequence() + ?.filterNot { it.isAllUnder } + ?.mapNotNull { it.importedFqName?.asString() } + ?.map { Pair(it.substringAfterLast('.'), it) } + ?.toMap() - /** - * Is true if any given annotation name is declared in the SplitPattern - * which basically describes entries to exclude. - */ - fun shouldExclude(annotations: List) = - annotations.firstOrNull(::isExcluded) != null + /** + * Is true if any given annotation name is declared in the SplitPattern + * which basically describes entries to exclude. + */ + fun shouldExclude(annotations: List) = + annotations.firstOrNull(::isExcluded) != null - private fun isExcluded(annotation: KtAnnotationEntry): Boolean = - resolvedAnnotations?.get(annotation.typeReference?.text) - ?.let { excludes.contains(it) } ?: false + private fun isExcluded(annotation: KtAnnotationEntry): Boolean = + resolvedAnnotations?.get(annotation.typeReference?.text) + ?.let { excludes.contains(it) } ?: false } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/BaseRule.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/BaseRule.kt index d0115c5c2..c881cab0f 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/BaseRule.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/BaseRule.kt @@ -20,49 +20,49 @@ typealias RuleId = String * detekt core engine to only care about a single type. */ abstract class BaseRule( - protected val context: Context = DefaultContext() + protected val context: Context = DefaultContext() ) : DetektVisitor(), Context by context { - open val ruleId: RuleId = javaClass.simpleName + open val ruleId: RuleId = javaClass.simpleName - /** - * Before starting visiting kotlin elements, a check is performed if this rule should be triggered. - * Pre- and post-visit-hooks are executed before/after the visiting process. - */ - fun visitFile(root: KtFile) { - if (visitCondition(root)) { - clearFindings() - preVisit(root) - visit(root) - postVisit(root) - } - } + /** + * Before starting visiting kotlin elements, a check is performed if this rule should be triggered. + * Pre- and post-visit-hooks are executed before/after the visiting process. + */ + fun visitFile(root: KtFile) { + if (visitCondition(root)) { + clearFindings() + preVisit(root) + visit(root) + postVisit(root) + } + } - open fun visit(root: KtFile) { - root.accept(this) - } + open fun visit(root: KtFile) { + root.accept(this) + } - /** - * Basic mechanism to decide if a rule should run or not. - * - * By default any rule which is declared 'active' in the [Config] - * or not suppressed by a [Suppress] annotation on file level should run. - */ - abstract fun visitCondition(root: KtFile): Boolean + /** + * Basic mechanism to decide if a rule should run or not. + * + * By default any rule which is declared 'active' in the [Config] + * or not suppressed by a [Suppress] annotation on file level should run. + */ + abstract fun visitCondition(root: KtFile): Boolean - /** - * Could be overridden by subclasses to specify a behaviour which should be done before - * visiting kotlin elements. - */ - protected open fun preVisit(root: KtFile) { - // nothing to do by default - } + /** + * Could be overridden by subclasses to specify a behaviour which should be done before + * visiting kotlin elements. + */ + protected open fun preVisit(root: KtFile) { + // nothing to do by default + } - /** - * Could be overridden by subclasses to specify a behaviour which should be done after - * visiting kotlin elements. - */ - protected open fun postVisit(root: KtFile) { - // nothing to do by default - } + /** + * Could be overridden by subclasses to specify a behaviour which should be done after + * visiting kotlin elements. + */ + protected open fun postVisit(root: KtFile) { + // nothing to do by default + } } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/CodeSmell.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/CodeSmell.kt index 74c53f45f..841060f12 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/CodeSmell.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/CodeSmell.kt @@ -13,31 +13,32 @@ package io.gitlab.arturbosch.detekt.api * @author Artur Bosch * @author Marvin Ramin */ -open class CodeSmell(final override val issue: Issue, - override val entity: Entity, - override val message: String, - override val metrics: List = listOf(), - override val references: List = listOf()) : Finding { +open class CodeSmell( + final override val issue: Issue, + override val entity: Entity, + override val message: String, + override val metrics: List = listOf(), + override val references: List = listOf()) : Finding { - override val id: String = issue.id + override val id: String = issue.id - override fun compact(): String = "$id - ${entity.compact()}" + override fun compact(): String = "$id - ${entity.compact()}" - override fun compactWithSignature() = compact() + " - Signature=" + entity.signature + override fun compactWithSignature() = compact() + " - Signature=" + entity.signature - override fun toString(): String { - return "CodeSmell(issue=$issue, " + - "entity=$entity, " + - "message=$message, " + - "metrics=$metrics, " + - "references=$references, " + - "id='$id')" - } + override fun toString(): String { + return "CodeSmell(issue=$issue, " + + "entity=$entity, " + + "message=$message, " + + "metrics=$metrics, " + + "references=$references, " + + "id='$id')" + } - override fun messageOrDescription() = when { - message.isEmpty() -> issue.description - else -> message - } + override fun messageOrDescription() = when { + message.isEmpty() -> issue.description + else -> message + } } /** @@ -45,24 +46,24 @@ open class CodeSmell(final override val issue: Issue, * for the existence of this rule violation. */ open class ThresholdedCodeSmell( - issue: Issue, - entity: Entity, - val metric: Metric, - message: String, - references: List = emptyList() + issue: Issue, + entity: Entity, + val metric: Metric, + message: String, + references: List = emptyList() ) : CodeSmell( - issue, entity, message, metrics = listOf(metric), references = references + issue, entity, message, metrics = listOf(metric), references = references ) { - val value: Int - get() = metric.value - val threshold: Int - get() = metric.threshold + val value: Int + get() = metric.value + val threshold: Int + get() = metric.threshold - override fun compact(): String = "$id - $metric - ${entity.compact()}" + override fun compact(): String = "$id - $metric - ${entity.compact()}" - override fun messageOrDescription() = when { - message.isEmpty() -> issue.description - else -> message - } + override fun messageOrDescription() = when { + message.isEmpty() -> issue.description + else -> message + } } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/CompositeConfig.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/CompositeConfig.kt index 84a5f9a16..3e5264feb 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/CompositeConfig.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/CompositeConfig.kt @@ -7,17 +7,17 @@ package io.gitlab.arturbosch.detekt.api */ class CompositeConfig(private val lookFirst: Config, private val lookSecond: Config) : Config { - override fun subConfig(key: String): Config { - return CompositeConfig(lookFirst.subConfig(key), lookSecond.subConfig(key)) - } + override fun subConfig(key: String): Config { + return CompositeConfig(lookFirst.subConfig(key), lookSecond.subConfig(key)) + } - override fun valueOrDefault(key: String, default: T): T { - return lookFirst.valueOrNull(key) ?: lookSecond.valueOrDefault(key, default) - } + override fun valueOrDefault(key: String, default: T): T { + return lookFirst.valueOrNull(key) ?: lookSecond.valueOrDefault(key, default) + } - override fun valueOrNull(key: String): T? { - return lookFirst.valueOrNull(key) ?: lookSecond.valueOrNull(key) - } + override fun valueOrNull(key: String): T? { + return lookFirst.valueOrNull(key) ?: lookSecond.valueOrNull(key) + } - override fun toString() = "CompositeConfig(lookFirst=$lookFirst, lookSecond=$lookSecond)" + override fun toString() = "CompositeConfig(lookFirst=$lookFirst, lookSecond=$lookSecond)" } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Config.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Config.kt index fc5e0cd42..f762b9993 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Config.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Config.kt @@ -8,52 +8,54 @@ package io.gitlab.arturbosch.detekt.api */ interface Config { - /** - * Tries to retrieve part of the configuration based on given key. - */ - fun subConfig(key: String): Config + /** + * Tries to retrieve part of the configuration based on given key. + */ + fun subConfig(key: String): Config - /** - * Retrieves a sub configuration or value based on given key. If configuration property cannot be found - * the specified default value is returned. - */ - fun valueOrDefault(key: String, default: T): T + /** + * Retrieves a sub configuration or value based on given key. If configuration property cannot be found + * the specified default value is returned. + */ + fun valueOrDefault(key: String, default: T): T - /** - * Retrieves a sub configuration or value based on given key. - * If the configuration property cannot be found, null is returned. - */ - fun valueOrNull(key: String): T? + /** + * Retrieves a sub configuration or value based on given key. + * If the configuration property cannot be found, null is returned. + */ + fun valueOrNull(key: String): T? - /** - * Is thrown when loading a configuration results in errors. - */ - class InvalidConfigurationError(msg: String = "Provided configuration file is invalid:" + - " Structure must be from type Map!") : RuntimeException(msg) + /** + * Is thrown when loading a configuration results in errors. + */ + class InvalidConfigurationError( + msg: String = "Provided configuration file is invalid:" + + " Structure must be from type Map!" + ) : RuntimeException(msg) - companion object { + companion object { - /** - * An empty configuration with no properties. - * This config should only be used in test cases. - * Always returns the default value except when 'active' is queried, it returns true . - */ - val empty: Config = EmptyConfig - } + /** + * An empty configuration with no properties. + * This config should only be used in test cases. + * Always returns the default value except when 'active' is queried, it returns true . + */ + val empty: Config = EmptyConfig + } } /** * NOP-implementation of a config object. */ internal object EmptyConfig : Config { - override fun valueOrNull(key: String): T? = null + override fun valueOrNull(key: String): T? = null - override fun subConfig(key: String) = this - @Suppress("UNCHECKED_CAST") - override fun valueOrDefault(key: String, default: T): T = when (key) { - "active" -> true as T - else -> default - } + override fun subConfig(key: String) = this + @Suppress("UNCHECKED_CAST") + override fun valueOrDefault(key: String, default: T): T = when (key) { + "active" -> true as T + else -> default + } } /** @@ -61,28 +63,28 @@ internal object EmptyConfig : Config { */ abstract class BaseConfig : Config { - protected open fun valueOrDefaultInternal(result: Any?, default: Any): Any { - return try { - if (result != null) { - when (result) { - is String -> tryParseBasedOnDefault(result, default) - else -> result - } - } else { - default - } - } catch (e: ClassCastException) { - throw IllegalArgumentException("Type of value $result does not match the type of default value $default!") - } catch (e: NumberFormatException) { - throw IllegalArgumentException("Type of value $result does not match the type of default value $default!", e) - } - } + protected open fun valueOrDefaultInternal(result: Any?, default: Any): Any { + return try { + if (result != null) { + when (result) { + is String -> tryParseBasedOnDefault(result, default) + else -> result + } + } else { + default + } + } catch (e: ClassCastException) { + throw IllegalArgumentException("Type of value $result does not match the type of default value $default!") + } catch (e: NumberFormatException) { + throw IllegalArgumentException("Type of value $result does not match the type of default value $default!", e) + } + } - protected open fun tryParseBasedOnDefault(result: String, defaultResult: Any): Any = when (defaultResult) { - is Int -> result.toInt() - is Boolean -> result.toBoolean() - is Double -> result.toDouble() - is String -> result - else -> throw ClassCastException() - } + protected open fun tryParseBasedOnDefault(result: String, defaultResult: Any): Any = when (defaultResult) { + is Int -> result.toInt() + is Boolean -> result.toBoolean() + is Double -> result.toDouble() + is String -> result + else -> throw ClassCastException() + } } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/ConfigAware.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/ConfigAware.kt index e7b1bbc5a..fb4d80451 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/ConfigAware.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/ConfigAware.kt @@ -19,53 +19,53 @@ package io.gitlab.arturbosch.detekt.api */ interface ConfigAware : Config { - /** - * Id which is used to retrieve the sub config for the rule implementing this interface. - */ - val ruleId: RuleId + /** + * Id which is used to retrieve the sub config for the rule implementing this interface. + */ + val ruleId: RuleId - /** - * Wrapped configuration of the ruleSet this rule is in. - * Use #valueOrDefault function to retrieve properties specified for the rule - * implementing this interface instead. - * Only use this property directly if you need a specific rule set property. - */ - val ruleSetConfig: Config + /** + * Wrapped configuration of the ruleSet this rule is in. + * Use #valueOrDefault function to retrieve properties specified for the rule + * implementing this interface instead. + * Only use this property directly if you need a specific rule set property. + */ + val ruleSetConfig: Config - private val ruleConfig: Config - get() = ruleSetConfig.subConfig(ruleId) + private val ruleConfig: Config + get() = ruleSetConfig.subConfig(ruleId) - /** - * If your rule supports to automatically correct the misbehaviour of underlying smell, - * specify your code inside this method call, to allow the user of your rule to trigger auto correction - * only when needed. - */ - fun withAutoCorrect(block: () -> Unit) { - if (autoCorrect) { - block() - } - } + /** + * If your rule supports to automatically correct the misbehaviour of underlying smell, + * specify your code inside this method call, to allow the user of your rule to trigger auto correction + * only when needed. + */ + fun withAutoCorrect(block: () -> Unit) { + if (autoCorrect) { + block() + } + } - /** - * Does this rule have auto correct specified in configuration? - * For auto correction to work the rule set itself enable it. - */ - val autoCorrect: Boolean - get() = valueOrDefault("autoCorrect", false) && - ruleSetConfig.valueOrDefault("autoCorrect", true) + /** + * Does this rule have auto correct specified in configuration? + * For auto correction to work the rule set itself enable it. + */ + val autoCorrect: Boolean + get() = valueOrDefault("autoCorrect", false) && + ruleSetConfig.valueOrDefault("autoCorrect", true) - /** - * Is this rule specified as active in configuration? - * If an rule is not specified in the underlying configuration, we assume it should not be run. - */ - val active: Boolean get() = valueOrDefault("active", false) + /** + * Is this rule specified as active in configuration? + * If an rule is not specified in the underlying configuration, we assume it should not be run. + */ + val active: Boolean get() = valueOrDefault("active", false) - override fun subConfig(key: String): Config = - ruleConfig.subConfig(key) + override fun subConfig(key: String): Config = + ruleConfig.subConfig(key) - override fun valueOrDefault(key: String, default: T) = - ruleConfig.valueOrDefault(key, default) + override fun valueOrDefault(key: String, default: T) = + ruleConfig.valueOrDefault(key, default) - override fun valueOrNull(key: String): T? = - ruleConfig.valueOrNull(key) + override fun valueOrNull(key: String): T? = + ruleConfig.valueOrNull(key) } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/ConsoleReport.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/ConsoleReport.kt index 117570004..97cc4b26b 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/ConsoleReport.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/ConsoleReport.kt @@ -13,11 +13,11 @@ import java.io.PrintStream */ abstract class ConsoleReport : Extension { - fun print(printer: PrintStream, detektion: Detektion) { - render(detektion)?.let { - printer.println(it) - } - } + fun print(printer: PrintStream, detektion: Detektion) { + render(detektion)?.let { + printer.println(it) + } + } - abstract fun render(detektion: Detektion): String? + abstract fun render(detektion: Detektion): String? } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Context.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Context.kt index 58b72b837..7a53fd239 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Context.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Context.kt @@ -13,10 +13,10 @@ import org.jetbrains.kotlin.psi.KtFile * @author Marvin Ramin */ interface Context { - val findings: List - fun report(finding: Finding, aliases: Set = emptySet()) - fun report(findings: List, aliases: Set = emptySet()) - fun clearFindings() + val findings: List + fun report(finding: Finding, aliases: Set = emptySet()) + fun report(findings: List, aliases: Set = emptySet()) + fun clearFindings() } /** @@ -24,38 +24,38 @@ interface Context { */ open class DefaultContext : Context { - /** - * Returns a copy of violations for this rule. - */ - override val findings: List - get() = _findings.toList() + /** + * Returns a copy of violations for this rule. + */ + override val findings: List + get() = _findings.toList() - private var _findings: MutableList = mutableListOf() + private var _findings: MutableList = mutableListOf() - /** - * Reports a single code smell finding. - * - * Before adding a finding, it is checked if it is not suppressed - * by @Suppress or @SuppressWarnings annotations. - */ - override fun report(finding: Finding, aliases: Set) { - val ktElement = finding.entity.ktElement - if (ktElement == null || !ktElement.isSuppressedBy(finding.id, aliases)) { - _findings.add(finding) - } - } + /** + * Reports a single code smell finding. + * + * Before adding a finding, it is checked if it is not suppressed + * by @Suppress or @SuppressWarnings annotations. + */ + override fun report(finding: Finding, aliases: Set) { + val ktElement = finding.entity.ktElement + if (ktElement == null || !ktElement.isSuppressedBy(finding.id, aliases)) { + _findings.add(finding) + } + } - /** - * Reports a list of code smell findings. - * - * Before adding a finding, it is checked if it is not suppressed - * by @Suppress or @SuppressWarnings annotations. - */ - override fun report(findings: List, aliases: Set) { - findings.forEach { report(it, aliases) } - } + /** + * Reports a list of code smell findings. + * + * Before adding a finding, it is checked if it is not suppressed + * by @Suppress or @SuppressWarnings annotations. + */ + override fun report(findings: List, aliases: Set) { + findings.forEach { report(it, aliases) } + } - final override fun clearFindings() { - _findings = mutableListOf() - } + final override fun clearFindings() { + _findings = mutableListOf() + } } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Detektion.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Detektion.kt index 698ad3a6e..ff056ab9b 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Detektion.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Detektion.kt @@ -9,12 +9,12 @@ import org.jetbrains.kotlin.com.intellij.openapi.util.Key * @author Artur Bosch */ interface Detektion { - val findings: Map> - val notifications: Collection - val metrics: Collection + val findings: Map> + val notifications: Collection + val metrics: Collection - fun getData(key: Key): V? - fun addData(key: Key, value: V) - fun add(notification: Notification) - fun add(projectMetric: ProjectMetric) + fun getData(key: Key): V? + fun addData(key: Key, value: V) + fun add(notification: Notification) + fun add(projectMetric: ProjectMetric) } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Entity.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Entity.kt index 14cea4e24..8d832596d 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Entity.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Entity.kt @@ -11,23 +11,25 @@ import org.jetbrains.kotlin.psi.KtElement * * @author Artur Bosch */ -data class Entity(val name: String, - val className: String, - val signature: String, - val location: Location, - val ktElement: KtElement? = null) : Compactable { +data class Entity( + val name: String, + val className: String, + val signature: String, + val location: Location, + val ktElement: KtElement? = null +) : Compactable { - override fun compact(): String = "[$name] at ${location.compact()}" + override fun compact(): String = "[$name] at ${location.compact()}" - companion object { - /** - * Factory function which retrieves all needed information from the [PsiElement] itself. - */ - fun from(element: PsiElement, offset: Int = 0): Entity { - val name = element.searchName() - val signature = element.buildFullSignature() - val clazz = element.searchClass() - return Entity(name, clazz, signature, Location.from(element, offset), element as? KtElement) - } - } + companion object { + /** + * Factory function which retrieves all needed information from the [PsiElement] itself. + */ + fun from(element: PsiElement, offset: Int = 0): Entity { + val name = element.searchName() + val signature = element.buildFullSignature() + val clazz = element.searchClass() + return Entity(name, clazz, signature, Location.from(element, offset), element as? KtElement) + } + } } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Extension.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Extension.kt index a44372ff4..5be34071e 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Extension.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Extension.kt @@ -10,21 +10,21 @@ package io.gitlab.arturbosch.detekt.api * @author Artur Bosch */ interface Extension { - /** - * Name of the extension. - */ - val id: String get() = javaClass.simpleName - /** - * Is used to run extensions in a specific order. - * The higher the priority the sooner the extension will run in detekt's lifecycle. - */ - val priority: Int get() = -1 + /** + * Name of the extension. + */ + val id: String get() = javaClass.simpleName + /** + * Is used to run extensions in a specific order. + * The higher the priority the sooner the extension will run in detekt's lifecycle. + */ + val priority: Int get() = -1 - /** - * Allows to read any or even user defined properties from the detekt yaml config - * to setup this extension. - */ - fun init(config: Config) { - // for setup code - } + /** + * Allows to read any or even user defined properties from the detekt yaml config + * to setup this extension. + */ + fun init(config: Config) { + // for setup code + } } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/FileProcessListener.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/FileProcessListener.kt index 039af5406..281dde330 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/FileProcessListener.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/FileProcessListener.kt @@ -11,27 +11,27 @@ import org.jetbrains.kotlin.psi.KtFile @Suppress("EmptyFunctionBlock") interface FileProcessListener : Extension { - /** - * Use this to gather some additional information for the real onProcess function. - * This calculation should be lightweight as this method is called from the main thread. - */ - fun onStart(files: List) {} + /** + * Use this to gather some additional information for the real onProcess function. + * This calculation should be lightweight as this method is called from the main thread. + */ + fun onStart(files: List) {} - /** - * Called when processing of a file begins. - * This method is called from a thread pool thread. Heavy computations allowed. - */ - fun onProcess(file: KtFile) {} + /** + * Called when processing of a file begins. + * This method is called from a thread pool thread. Heavy computations allowed. + */ + fun onProcess(file: KtFile) {} - /** - * Called when processing of a file completes. - * This method is called from a thread pool thread. Heavy computations allowed. - */ - fun onProcessComplete(file: KtFile, findings: Map>) {} + /** + * Called when processing of a file completes. + * This method is called from a thread pool thread. Heavy computations allowed. + */ + fun onProcessComplete(file: KtFile, findings: Map>) {} - /** - * Mainly use this method to save computed metrics from KtFile's to the {@link Detektion} container. - * Do not do heavy computations here as this method is called from the main thread. - */ - fun onFinish(files: List, result: Detektion) {} + /** + * Mainly use this method to save computed metrics from KtFile's to the {@link Detektion} container. + * Do not do heavy computations here as this method is called from the main thread. + */ + fun onFinish(files: List, result: Detektion) {} } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Findings.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Findings.kt index 21a59ede3..2e7595f10 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Findings.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Findings.kt @@ -10,49 +10,49 @@ package io.gitlab.arturbosch.detekt.api * @author Artur Bosch */ interface Finding : Compactable, HasEntity, HasMetrics { - val id: String - val issue: Issue - val references: List - val message: String + val id: String + val issue: Issue + val references: List + val message: String - fun messageOrDescription(): String + fun messageOrDescription(): String } /** * Describes a source code position. */ interface HasEntity { - val entity: Entity - val location: Location - get() = entity.location - val locationAsString: String - get() = location.locationString - val startPosition: SourceLocation - get() = location.source - val charPosition: TextLocation - get() = location.text - val file: String - get() = location.file - val signature: String - get() = entity.signature - val name: String - get() = entity.name - val inClass: String - get() = entity.className + val entity: Entity + val location: Location + get() = entity.location + val locationAsString: String + get() = location.locationString + val startPosition: SourceLocation + get() = location.source + val charPosition: TextLocation + get() = location.text + val file: String + get() = location.file + val signature: String + get() = entity.signature + val name: String + get() = entity.name + val inClass: String + get() = entity.className } /** * Adds metric container behaviour. */ interface HasMetrics { - val metrics: List - fun metricByType(type: String): Metric? = metrics.find { it.type == type } + val metrics: List + fun metricByType(type: String): Metric? = metrics.find { it.type == type } } /** * Provides a compact string representation. */ interface Compactable { - fun compact(): String - fun compactWithSignature(): String = compact() + fun compact(): String + fun compactWithSignature(): String = compact() } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Issue.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Issue.kt index 3b7cb8d28..88777120b 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Issue.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Issue.kt @@ -9,18 +9,20 @@ import io.gitlab.arturbosch.detekt.api.internal.validateIdentifier * @author Marvin Ramin * @author schalkms */ -data class Issue(val id: String, - val severity: Severity, - val description: String, - val debt: Debt) { +data class Issue( + val id: String, + val severity: Severity, + val description: String, + val debt: Debt +) { - init { - validateIdentifier(id) - } + init { + validateIdentifier(id) + } - override fun toString(): String { - return "Issue(id='$id', severity=$severity, debt=$debt)" - } + override fun toString(): String { + return "Issue(id='$id', severity=$severity, debt=$debt)" + } } /** @@ -28,7 +30,7 @@ data class Issue(val id: String, * a grade which is most harmful to their projects. */ enum class Severity { - CodeSmell, Style, Warning, Defect, Minor, Maintainability, Security, Performance + CodeSmell, Style, Warning, Defect, Minor, Maintainability, Security, Performance } /** @@ -37,23 +39,23 @@ enum class Severity { @Suppress("MagicNumber") data class Debt(val days: Int = 0, val hours: Int = 0, val mins: Int = 0) { - init { - require(days >= 0 && hours >= 0 && mins >= 0) - require(!(days == 0 && hours == 0 && mins == 0)) - } + init { + require(days >= 0 && hours >= 0 && mins >= 0) + require(!(days == 0 && hours == 0 && mins == 0)) + } - companion object { - val TWENTY_MINS = Debt(0, 0, 20) - val TEN_MINS = Debt(0, 0, 10) - val FIVE_MINS = Debt(0, 0, 5) - } + companion object { + val TWENTY_MINS = Debt(0, 0, 20) + val TEN_MINS = Debt(0, 0, 10) + val FIVE_MINS = Debt(0, 0, 5) + } - override fun toString(): String { - return with(StringBuilder()) { - if (days > 0) append("${days}d ") - if (hours > 0) append("${hours}h ") - if (mins > 0) append("${mins}min") - toString() - }.trim() - } + override fun toString(): String { + return with(StringBuilder()) { + if (days > 0) append("${days}d ") + if (hours > 0) append("${hours}h ") + if (mins > 0) append("${mins}min") + toString() + }.trim() + } } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/LazyRegex.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/LazyRegex.kt index 56513203f..bdcfa2b7a 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/LazyRegex.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/LazyRegex.kt @@ -13,17 +13,17 @@ import kotlin.reflect.KProperty * @author Pavlos-Petros Tournaris */ class LazyRegex( - private val key: String, - private val default: String + private val key: String, + private val default: String ) : ReadOnlyProperty { - private var lazyRegexValue: Regex? = null + private var lazyRegexValue: Regex? = null - override fun getValue(thisRef: Rule, property: KProperty<*>): Regex { - return lazyRegexValue ?: createRegex(thisRef).also { lazyRegexValue = it } - } + override fun getValue(thisRef: Rule, property: KProperty<*>): Regex { + return lazyRegexValue ?: createRegex(thisRef).also { lazyRegexValue = it } + } - private fun createRegex(rule: Rule): Regex { - return Regex(rule.valueOrDefault(key = key, default = default)) - } + private fun createRegex(rule: Rule): Regex { + return Regex(rule.valueOrDefault(key = key, default = default)) + } } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Location.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Location.kt index 28743c392..506f0653e 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Location.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Location.kt @@ -16,54 +16,56 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffset * * @author Artur Bosch */ -data class Location(val source: SourceLocation, - val text: TextLocation, - val locationString: String, - val file: String) : Compactable { +data class Location( + val source: SourceLocation, + val text: TextLocation, + val locationString: String, + val file: String +) : Compactable { - override fun compact(): String = "$file:$source" + override fun compact(): String = "$file:$source" - companion object { - fun from(element: PsiElement, offset: Int = 0): Location { - val start = startLineAndColumn(element, offset) - val sourceLocation = SourceLocation(start.line, start.column) - val textLocation = TextLocation(element.startOffset + offset, element.endOffset + offset) - val fileName = element.originalFilePath() - val locationText = element.getTextAtLocationSafe() - return Location(sourceLocation, textLocation, locationText, fileName) - } + companion object { + fun from(element: PsiElement, offset: Int = 0): Location { + val start = startLineAndColumn(element, offset) + val sourceLocation = SourceLocation(start.line, start.column) + val textLocation = TextLocation(element.startOffset + offset, element.endOffset + offset) + val fileName = element.originalFilePath() + val locationText = element.getTextAtLocationSafe() + return Location(sourceLocation, textLocation, locationText, fileName) + } - @Suppress("TooGenericExceptionCaught") - fun startLineAndColumn(element: PsiElement, offset: Int = 0): PsiDiagnosticUtils.LineAndColumn { - return try { - val range = element.textRange - DiagnosticUtils.getLineAndColumnInPsiFile(element.containingFile, - TextRange(range.startOffset + offset, range.endOffset + offset)) - } catch (e: IndexOutOfBoundsException) { - // #18 - somehow the TextRange is out of bound on '}' leaf nodes, returning fail safe -1 - PsiDiagnosticUtils.LineAndColumn(-1, -1, null) - } - } + @Suppress("TooGenericExceptionCaught") + fun startLineAndColumn(element: PsiElement, offset: Int = 0): PsiDiagnosticUtils.LineAndColumn { + return try { + val range = element.textRange + DiagnosticUtils.getLineAndColumnInPsiFile(element.containingFile, + TextRange(range.startOffset + offset, range.endOffset + offset)) + } catch (e: IndexOutOfBoundsException) { + // #18 - somehow the TextRange is out of bound on '}' leaf nodes, returning fail safe -1 + PsiDiagnosticUtils.LineAndColumn(-1, -1, null) + } + } - private fun PsiElement.originalFilePath() = - (containingFile.viewProvider.virtualFile as? LightVirtualFile)?.originalFile?.name - ?: containingFile.name + private fun PsiElement.originalFilePath() = + (containingFile.viewProvider.virtualFile as? LightVirtualFile)?.originalFile?.name + ?: containingFile.name - private fun PsiElement.getTextAtLocationSafe() = - getTextSafe({ searchName() }, { getTextWithLocation() }) - } + private fun PsiElement.getTextAtLocationSafe() = + getTextSafe({ searchName() }, { getTextWithLocation() }) + } } /** * Stores line and column information of a location. */ data class SourceLocation(val line: Int, val column: Int) { - override fun toString() = "$line:$column" + override fun toString() = "$line:$column" } /** * Stores character start and end positions of an text file. */ data class TextLocation(val start: Int, val end: Int) { - override fun toString() = "$start:$end" + override fun toString() = "$start:$end" } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Metric.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Metric.kt index bdff5dc20..dd147bf4f 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Metric.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Metric.kt @@ -6,27 +6,31 @@ package io.gitlab.arturbosch.detekt.api * * @author Artur Bosch */ -data class Metric(val type: String, - val value: Int, - val threshold: Int, - val isDouble: Boolean = false, - val conversionFactor: Int = DEFAULT_FLOAT_CONVERSION_FACTOR) { +data class Metric( + val type: String, + val value: Int, + val threshold: Int, + val isDouble: Boolean = false, + val conversionFactor: Int = DEFAULT_FLOAT_CONVERSION_FACTOR +) { - constructor(type: String, - value: Double, - threshold: Double, - conversionFactor: Int = DEFAULT_FLOAT_CONVERSION_FACTOR) : - this(type, value = (value * conversionFactor).toInt(), - threshold = (threshold * conversionFactor).toInt(), - isDouble = true, conversionFactor = conversionFactor) + constructor( + type: String, + value: Double, + threshold: Double, + conversionFactor: Int = DEFAULT_FLOAT_CONVERSION_FACTOR + ) : + this(type, value = (value * conversionFactor).toInt(), + threshold = (threshold * conversionFactor).toInt(), + isDouble = true, conversionFactor = conversionFactor) - fun doubleValue(): Double = value.convertAsDouble() - fun doubleThreshold(): Double = threshold.convertAsDouble() + fun doubleValue(): Double = value.convertAsDouble() + fun doubleThreshold(): Double = threshold.convertAsDouble() - private fun Int.convertAsDouble(): Double = if (isDouble) this.toDouble() / conversionFactor - else throw IllegalStateException("This metric was not marked as double!") + private fun Int.convertAsDouble(): Double = if (isDouble) this.toDouble() / conversionFactor + else throw IllegalStateException("This metric was not marked as double!") - override fun toString(): String = if (isDouble) "${doubleValue()}/${doubleThreshold()}" else "$value/$threshold" + override fun toString(): String = if (isDouble) "${doubleValue()}/${doubleThreshold()}" else "$value/$threshold" } /** diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/MultiRule.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/MultiRule.kt index d0f2a6c08..ff5c30e4d 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/MultiRule.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/MultiRule.kt @@ -4,27 +4,27 @@ import org.jetbrains.kotlin.psi.KtFile abstract class MultiRule : BaseRule() { - abstract val rules: List - var activeRules: Set by SingleAssign() - var ruleFilters: Set = emptySet() + abstract val rules: List + var activeRules: Set by SingleAssign() + var ruleFilters: Set = emptySet() - override fun visitCondition(root: KtFile): Boolean = true + override fun visitCondition(root: KtFile): Boolean = true - override fun preVisit(root: KtFile) { - activeRules = rules.filterTo(HashSet()) { - it.ruleId !in ruleFilters && it.visitCondition(root) - } - } + override fun preVisit(root: KtFile) { + activeRules = rules.filterTo(HashSet()) { + it.ruleId !in ruleFilters && it.visitCondition(root) + } + } - override fun postVisit(root: KtFile) { - for (activeRule in activeRules) { - report(activeRule.findings, activeRule.aliases) - } - } + override fun postVisit(root: KtFile) { + for (activeRule in activeRules) { + report(activeRule.findings, activeRule.aliases) + } + } - fun T.runIfActive(block: T.() -> Unit) { - if (this in activeRules) { - block() - } - } + fun T.runIfActive(block: T.() -> Unit) { + if (this in activeRules) { + block() + } + } } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Notification.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Notification.kt index 40182349e..99d2493a9 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Notification.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Notification.kt @@ -8,5 +8,5 @@ package io.gitlab.arturbosch.detekt.api * @author Artur Bosch */ interface Notification { - val message: String + val message: String } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/OutputReport.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/OutputReport.kt index b8d34399e..e5326adb9 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/OutputReport.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/OutputReport.kt @@ -12,33 +12,33 @@ import java.nio.file.Path */ abstract class OutputReport : Extension { - /** - * Supported ending of this report type. - */ - abstract val ending: String + /** + * Supported ending of this report type. + */ + abstract val ending: String - /** - * Name of the report. Is used to exclude this report in the yaml config. - */ - open val name: String? - get() = this::class.simpleName + /** + * Name of the report. Is used to exclude this report in the yaml config. + */ + open val name: String? + get() = this::class.simpleName - /** - * Renders result and writes it to the given [filePath]. - */ - fun write(filePath: Path, detektion: Detektion) { - val reportData = render(detektion) - if (reportData != null) { - assert(filePath.fileName.toString().endsWith(ending)) { - "The $name needs to have a file ending of type .$ending, but was ${filePath.fileName}." - } - filePath.parent?.let { Files.createDirectories(it) } - Files.write(filePath, reportData.toByteArray()) - } - } + /** + * Renders result and writes it to the given [filePath]. + */ + fun write(filePath: Path, detektion: Detektion) { + val reportData = render(detektion) + if (reportData != null) { + assert(filePath.fileName.toString().endsWith(ending)) { + "The $name needs to have a file ending of type .$ending, but was ${filePath.fileName}." + } + filePath.parent?.let { Files.createDirectories(it) } + Files.write(filePath, reportData.toByteArray()) + } + } - /** - * Defines the translation process of detekt's result into a string. - */ - abstract fun render(detektion: Detektion): String? + /** + * Defines the translation process of detekt's result into a string. + */ + abstract fun render(detektion: Detektion): String? } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/ProjectExtension.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/ProjectExtension.kt index 79039e72c..3253d1fd3 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/ProjectExtension.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/ProjectExtension.kt @@ -33,42 +33,42 @@ val psiProject: Project = createKotlinCoreEnvironment() val psiFactory: KtPsiFactory = KtPsiFactory(psiProject, false) private fun createKotlinCoreEnvironment(): Project { - System.setProperty("idea.io.use.fallback", "true") - val configuration = CompilerConfiguration() - configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, - PrintingMessageCollector(System.err, MessageRenderer.PLAIN_FULL_PATHS, false)) - return KotlinCoreEnvironment.createForProduction(Disposer.newDisposable(), - configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES).project.apply { - makeMutable(this as? MockProject ?: throw IllegalStateException( - "Unexpected Type for psi project. MockProject expected. Please report this!")) - } + System.setProperty("idea.io.use.fallback", "true") + val configuration = CompilerConfiguration() + configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, + PrintingMessageCollector(System.err, MessageRenderer.PLAIN_FULL_PATHS, false)) + return KotlinCoreEnvironment.createForProduction(Disposer.newDisposable(), + configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES).project.apply { + makeMutable(this as? MockProject ?: throw IllegalStateException( + "Unexpected Type for psi project. MockProject expected. Please report this!")) + } } private fun makeMutable(project: MockProject) { - // Based on KtLint by Shyiko - val pomModel: PomModel = object : UserDataHolderBase(), PomModel { + // Based on KtLint by Shyiko + val pomModel: PomModel = object : UserDataHolderBase(), PomModel { - override fun runTransaction(transaction: PomTransaction) { - (transaction as? PomTransactionBase)?.run() - } + override fun runTransaction(transaction: PomTransaction) { + (transaction as? PomTransactionBase)?.run() + } - @Suppress("UNCHECKED_CAST") - override fun getModelAspect(aspect: Class): T? { - if (aspect == TreeAspect::class.java) { - // using approach described in https://git.io/vKQTo due to the magical bytecode of TreeAspect - // (check constructor signature and compare it to the source) - // (org.jetbrains.kotlin:kotlin-compiler-embeddable:1.0.3) - val constructor = ReflectionFactory.getReflectionFactory().newConstructorForSerialization( - aspect, Any::class.java.getDeclaredConstructor()) - return constructor.newInstance() as T - } - return null - } - } - val extensionPoint = "org.jetbrains.kotlin.com.intellij.treeCopyHandler" - val extensionClassName = TreeCopyHandler::class.java.name!! - arrayOf(Extensions.getArea(project), Extensions.getArea(null)) - .filter { !it.hasExtensionPoint(extensionPoint) } - .forEach { it.registerExtensionPoint(extensionPoint, extensionClassName, ExtensionPoint.Kind.INTERFACE) } - project.registerService(PomModel::class.java, pomModel) + @Suppress("UNCHECKED_CAST") + override fun getModelAspect(aspect: Class): T? { + if (aspect == TreeAspect::class.java) { + // using approach described in https://git.io/vKQTo due to the magical bytecode of TreeAspect + // (check constructor signature and compare it to the source) + // (org.jetbrains.kotlin:kotlin-compiler-embeddable:1.0.3) + val constructor = ReflectionFactory.getReflectionFactory().newConstructorForSerialization( + aspect, Any::class.java.getDeclaredConstructor()) + return constructor.newInstance() as T + } + return null + } + } + val extensionPoint = "org.jetbrains.kotlin.com.intellij.treeCopyHandler" + val extensionClassName = TreeCopyHandler::class.java.name!! + arrayOf(Extensions.getArea(project), Extensions.getArea(null)) + .filter { !it.hasExtensionPoint(extensionPoint) } + .forEach { it.registerExtensionPoint(extensionPoint, extensionClassName, ExtensionPoint.Kind.INTERFACE) } + project.registerService(PomModel::class.java, pomModel) } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/ProjectMetric.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/ProjectMetric.kt index 0409e3e81..f81bc9613 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/ProjectMetric.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/ProjectMetric.kt @@ -5,12 +5,14 @@ package io.gitlab.arturbosch.detekt.api * * @author Artur Bosch */ -open class ProjectMetric(val type: String, - val value: Int, - val priority: Int = -1, - val isDouble: Boolean = false, - val conversionFactor: Int = DEFAULT_FLOAT_CONVERSION_FACTOR) { +open class ProjectMetric( + val type: String, + val value: Int, + val priority: Int = -1, + val isDouble: Boolean = false, + val conversionFactor: Int = DEFAULT_FLOAT_CONVERSION_FACTOR +) { - override fun toString(): String = "$type: ${if (isDouble) - (value.toDouble() / conversionFactor).toString() else value.toString()}" + override fun toString(): String = "$type: ${if (isDouble) + (value.toDouble() / conversionFactor).toString() else value.toString()}" } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Rule.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Rule.kt index 92e3f2b62..92781c405 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Rule.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Rule.kt @@ -14,49 +14,50 @@ import org.jetbrains.kotlin.psi.KtFile * @author Artur Bosch * @author Marvin Ramin */ -abstract class Rule(override val ruleSetConfig: Config = Config.empty, - ruleContext: Context = DefaultContext()) : - BaseRule(ruleContext), ConfigAware { +abstract class Rule( + override val ruleSetConfig: Config = Config.empty, + ruleContext: Context = DefaultContext()) : + BaseRule(ruleContext), ConfigAware { - /** - * A rule is motivated to point out a specific issue in the code base. - */ - abstract val issue: Issue + /** + * A rule is motivated to point out a specific issue in the code base. + */ + abstract val issue: Issue - /** - * An id this rule is identified with. - * Conventionally the rule id is derived from the issue id as these two classes have a coexistence. - */ - final override val ruleId: RuleId get() = issue.id + /** + * An id this rule is identified with. + * Conventionally the rule id is derived from the issue id as these two classes have a coexistence. + */ + final override val ruleId: RuleId get() = issue.id - /** - * List of rule ids which can optionally be used in suppress annotations to refer to this rule. - */ - val aliases: Set get() = valueOrDefault("aliases", defaultRuleIdAliases) + /** + * List of rule ids which can optionally be used in suppress annotations to refer to this rule. + */ + val aliases: Set get() = valueOrDefault("aliases", defaultRuleIdAliases) - /** - * The default names which can be used instead of this #ruleId to refer to this rule in suppression's. - * - * When overriding this property make sure to meet following structure for detekt-generator to pick - * it up and generate documentation for aliases: - * - * override val defaultRuleIdAliases = setOf("Name1", "Name2") - */ - open val defaultRuleIdAliases: Set = emptySet() + /** + * The default names which can be used instead of this #ruleId to refer to this rule in suppression's. + * + * When overriding this property make sure to meet following structure for detekt-generator to pick + * it up and generate documentation for aliases: + * + * override val defaultRuleIdAliases = setOf("Name1", "Name2") + */ + open val defaultRuleIdAliases: Set = emptySet() - override fun visitCondition(root: KtFile): Boolean = active && !root.isSuppressedBy(ruleId, aliases) + override fun visitCondition(root: KtFile): Boolean = active && !root.isSuppressedBy(ruleId, aliases) - /** - * Simplified version of [Context.report] with aliases retrieval from the config. - */ - fun report(finding: Finding) { - report(finding, aliases) - } + /** + * Simplified version of [Context.report] with aliases retrieval from the config. + */ + fun report(finding: Finding) { + report(finding, aliases) + } - /** - * Simplified version of [Context.report] with aliases retrieval from the config. - */ - fun report(findings: List) { - report(findings, aliases) - } + /** + * Simplified version of [Context.report] with aliases retrieval from the config. + */ + fun report(findings: List) { + report(findings, aliases) + } } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/RuleSet.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/RuleSet.kt index f57d4d6d5..73b238d3f 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/RuleSet.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/RuleSet.kt @@ -12,26 +12,26 @@ typealias RuleSetId = String */ class RuleSet(val id: RuleSetId, val rules: List) { - init { - validateIdentifier(id) - } + init { + validateIdentifier(id) + } - /** - * Visits given file with all rules of this rule set, returning a list - * of all code smell findings. - */ - fun accept(file: KtFile): List = rules.flatMap { it.visitFile(file); it.findings } + /** + * Visits given file with all rules of this rule set, returning a list + * of all code smell findings. + */ + fun accept(file: KtFile): List = rules.flatMap { it.visitFile(file); it.findings } - /** - * Visits given file with all non-filtered rules of this rule set. - * If a rule is a [MultiRule] the filters are passed to it via a setter - * and later used to filter sub rules of the [MultiRule]. - * - * A list of findings is returned for given [KtFile] - */ - fun accept(file: KtFile, ruleFilters: Set): List = - rules.asSequence() - .filterNot { it.ruleId in ruleFilters } - .onEach { if (it is MultiRule) it.ruleFilters = ruleFilters }.toList() - .flatMap { it.visitFile(file); it.findings } + /** + * Visits given file with all non-filtered rules of this rule set. + * If a rule is a [MultiRule] the filters are passed to it via a setter + * and later used to filter sub rules of the [MultiRule]. + * + * A list of findings is returned for given [KtFile] + */ + fun accept(file: KtFile, ruleFilters: Set): List = + rules.asSequence() + .filterNot { it.ruleId in ruleFilters } + .onEach { if (it is MultiRule) it.ruleFilters = ruleFilters }.toList() + .flatMap { it.visitFile(file); it.findings } } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/RuleSetProvider.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/RuleSetProvider.kt index 58bb7f699..d76db21e8 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/RuleSetProvider.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/RuleSetProvider.kt @@ -10,28 +10,28 @@ package io.gitlab.arturbosch.detekt.api */ interface RuleSetProvider { - /** - * Every rule set must be pre-configured with an ID to validate if this rule set - * must be created for current analysis. - */ - val ruleSetId: String + /** + * Every rule set must be pre-configured with an ID to validate if this rule set + * must be created for current analysis. + */ + val ruleSetId: String - /** - * Can return a rule set if this specific rule set is not considered as ignore. - * - * Api notice: As the rule set id is not known before creating the rule set instance, - * we must first create the rule set and then check if it is active. - */ - fun buildRuleset(config: Config): RuleSet? { - val subConfig = config.subConfig(ruleSetId) - val active = subConfig.valueOrDefault("active", true) - return if (active) instance(subConfig) else null - } + /** + * Can return a rule set if this specific rule set is not considered as ignore. + * + * Api notice: As the rule set id is not known before creating the rule set instance, + * we must first create the rule set and then check if it is active. + */ + fun buildRuleset(config: Config): RuleSet? { + val subConfig = config.subConfig(ruleSetId) + val active = subConfig.valueOrDefault("active", true) + return if (active) instance(subConfig) else null + } - /** - * This function must be implemented to provide custom rule sets. - * Make sure to pass the configuration to each rule to allow rules - * to be self configurable. - */ - fun instance(config: Config): RuleSet + /** + * This function must be implemented to provide custom rule sets. + * Make sure to pass the configuration to each rule to allow rules + * to be self configurable. + */ + fun instance(config: Config): RuleSet } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/SingleAssign.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/SingleAssign.kt index b7ac2b978..de59160ad 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/SingleAssign.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/SingleAssign.kt @@ -10,15 +10,15 @@ import kotlin.reflect.KProperty */ class SingleAssign { - private lateinit var _value: T + private lateinit var _value: T - operator fun getValue(thisRef: Any?, property: KProperty<*>): T { - check(this::_value.isInitialized) { "Property ${property.name} has not been assigned yet!" } - return _value - } + operator fun getValue(thisRef: Any?, property: KProperty<*>): T { + check(this::_value.isInitialized) { "Property ${property.name} has not been assigned yet!" } + return _value + } - operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { - check(!this::_value.isInitialized) { "Property ${property.name} has already been assigned!" } - _value = value - } + operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { + check(!this::_value.isInitialized) { "Property ${property.name} has already been assigned!" } + _value = value + } } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/SplitPattern.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/SplitPattern.kt index f60b07625..5a528ebde 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/SplitPattern.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/SplitPattern.kt @@ -7,20 +7,22 @@ private val regex = Regex(",") * Basic use cases are to specify different function or class names in the detekt * yaml config and test for their appearance in specific rules. */ -class SplitPattern(text: String, - delimiters: Regex = regex) { +class SplitPattern( + text: String, + delimiters: Regex = regex +) { - private val excludes = text - .split(delimiters) - .map { it.trim() } - .filter { it.isNotBlank() } - .map { it.removePrefix("*") } - .map { it.removeSuffix("*") } + private val excludes = text + .split(delimiters) + .map { it.trim() } + .filter { it.isNotBlank() } + .map { it.removePrefix("*") } + .map { it.removeSuffix("*") } - fun contains(value: String?): Boolean = excludes.any { value?.contains(it, ignoreCase = true) == true } - fun equals(value: String?): Boolean = excludes.any { value?.equals(it, ignoreCase = true) == true } - fun none(value: String): Boolean = !contains(value) - fun matches(value: String): List = excludes.filter { value.contains(it, ignoreCase = true) } - fun startWith(name: String?): Boolean = excludes.any { name?.startsWith(it) ?: false } - fun mapAll(transform: (String) -> T): List = excludes.map(transform) + fun contains(value: String?): Boolean = excludes.any { value?.contains(it, ignoreCase = true) == true } + fun equals(value: String?): Boolean = excludes.any { value?.equals(it, ignoreCase = true) == true } + fun none(value: String): Boolean = !contains(value) + fun matches(value: String): List = excludes.filter { value.contains(it, ignoreCase = true) } + fun startWith(name: String?): Boolean = excludes.any { name?.startsWith(it) ?: false } + fun mapAll(transform: (String) -> T): List = excludes.map(transform) } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Suppressible.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Suppressible.kt index 847e0c323..bdbcfe69a 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Suppressible.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Suppressible.kt @@ -15,21 +15,21 @@ import org.jetbrains.kotlin.psi.KtFile * If this element cannot have annotations, the first annotative parent is searched. */ fun KtElement.isSuppressedBy(id: String, aliases: Set): Boolean = - this is KtAnnotated && this.isSuppressedBy(id, aliases) || findAnnotatedSuppressedParent(id, aliases) + this is KtAnnotated && this.isSuppressedBy(id, aliases) || findAnnotatedSuppressedParent(id, aliases) private fun KtElement.findAnnotatedSuppressedParent(id: String, aliases: Set): Boolean { - val parent = PsiTreeUtil.getParentOfType(this, KtAnnotated::class.java, true) + val parent = PsiTreeUtil.getParentOfType(this, KtAnnotated::class.java, true) - var suppressed = false - if (parent != null && parent !is KtFile) { - suppressed = if (parent.isSuppressedBy(id, aliases)) { - true - } else { - parent.findAnnotatedSuppressedParent(id, aliases) - } - } + var suppressed = false + if (parent != null && parent !is KtFile) { + suppressed = if (parent.isSuppressedBy(id, aliases)) { + true + } else { + parent.findAnnotatedSuppressedParent(id, aliases) + } + } - return suppressed + return suppressed } private val detektSuppressionPrefixRegex = Regex("(?i)detekt([.:])") @@ -40,13 +40,13 @@ private val suppressionAnnotations = setOf("Suppress", "SuppressWarnings") * Checks if this kt element is suppressed by @Suppress or @SuppressWarnings annotations. */ fun KtAnnotated.isSuppressedBy(id: RuleId, aliases: Set): Boolean { - val valid = mutableSetOf(id, "ALL", "all", "All") - valid.addAll(aliases) - return annotationEntries - .find { it.typeReference?.text in suppressionAnnotations } - ?.valueArguments - ?.map { it.getArgumentExpression()?.text } - ?.map { it?.replace(detektSuppressionPrefixRegex, "") } - ?.map { it?.replace(QUOTES, "") } - ?.find { it in valid } != null + val valid = mutableSetOf(id, "ALL", "all", "All") + valid.addAll(aliases) + return annotationEntries + .find { it.typeReference?.text in suppressionAnnotations } + ?.valueArguments + ?.map { it.getArgumentExpression()?.text } + ?.map { it?.replace(detektSuppressionPrefixRegex, "") } + ?.map { it?.replace(QUOTES, "") } + ?.find { it in valid } != null } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/ThresholdRule.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/ThresholdRule.kt index 502211644..4a9f55f89 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/ThresholdRule.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/ThresholdRule.kt @@ -5,8 +5,8 @@ package io.gitlab.arturbosch.detekt.api * but can be also obtained from within a configuration object. */ abstract class ThresholdRule(config: Config, private val defaultThreshold: Int) : Rule(config) { - /** - * The used threshold for this rule is loaded from the configuration or used from the constructor value. - */ - protected val threshold: Int get() = valueOrDefault("threshold", defaultThreshold) + /** + * The used threshold for this rule is loaded from the configuration or used from the constructor value. + */ + protected val threshold: Int get() = valueOrDefault("threshold", defaultThreshold) } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/YamlConfig.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/YamlConfig.kt index cd8903331..568d20b55 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/YamlConfig.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/YamlConfig.kt @@ -1,10 +1,10 @@ package io.gitlab.arturbosch.detekt.api -import org.yaml.snakeyaml.Yaml import java.io.BufferedReader import java.net.URL import java.nio.file.Files import java.nio.file.Path +import org.yaml.snakeyaml.Yaml /** * Config implementation using the yaml format. SubConfigurations can return sub maps according to the @@ -15,59 +15,59 @@ import java.nio.file.Path @Suppress("UNCHECKED_CAST") class YamlConfig internal constructor(val properties: Map) : BaseConfig() { - override fun subConfig(key: String): Config { - val subProperties = properties.getOrElse(key) { mapOf() } - return YamlConfig(subProperties as Map) - } + override fun subConfig(key: String): Config { + val subProperties = properties.getOrElse(key) { mapOf() } + return YamlConfig(subProperties as Map) + } - override fun valueOrDefault(key: String, default: T): T { - val result = properties[key] - return valueOrDefaultInternal(result, default) as T - } + override fun valueOrDefault(key: String, default: T): T { + val result = properties[key] + return valueOrDefaultInternal(result, default) as T + } - override fun valueOrNull(key: String): T? { - return properties[key] as? T? - } + override fun valueOrNull(key: String): T? { + return properties[key] as? T? + } - override fun toString(): String { - return "YamlConfig(properties=$properties)" - } + override fun toString(): String { + return "YamlConfig(properties=$properties)" + } - companion object { + companion object { - private const val YAML = ".yml" + private const val YAML = ".yml" - /** - * Factory method to load a yaml configuration. Given path must exist and end with "yml". - */ - fun load(path: Path): Config { - require(Files.exists(path)) { "File does not exist!" } - require(path.toString().endsWith(YAML)) { "File does not end with $YAML!" } - return load(Files.newBufferedReader(path)) - } + /** + * Factory method to load a yaml configuration. Given path must exist and end with "yml". + */ + fun load(path: Path): Config { + require(Files.exists(path)) { "File does not exist!" } + require(path.toString().endsWith(YAML)) { "File does not end with $YAML!" } + return load(Files.newBufferedReader(path)) + } - /** - * Factory method to load a yaml configuration from a URL. - */ - fun loadResource(url: URL): Config { - val reader = url.openStream().bufferedReader() - return load(reader) - } + /** + * Factory method to load a yaml configuration from a URL. + */ + fun loadResource(url: URL): Config { + val reader = url.openStream().bufferedReader() + return load(reader) + } - private fun load(reader: BufferedReader): Config = reader.use { - val yamlInput = it.readText() - if (yamlInput.isEmpty()) { - Config.empty - } else { - val map: Any = Yaml().load(yamlInput) - if (map is Map<*, *>) { - YamlConfig(map as Map) - } else { - throw Config.InvalidConfigurationError() - } - } - } + private fun load(reader: BufferedReader): Config = reader.use { + val yamlInput = it.readText() + if (yamlInput.isEmpty()) { + Config.empty + } else { + val map: Any = Yaml().load(yamlInput) + if (map is Map<*, *>) { + YamlConfig(map as Map) + } else { + throw Config.InvalidConfigurationError() + } + } + } - private fun BufferedReader.readText() = lineSequence().joinToString("\n") - } + private fun BufferedReader.readText() = lineSequence().joinToString("\n") + } } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/internal/McCabeVisitor.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/internal/McCabeVisitor.kt index da3b58d30..354278441 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/internal/McCabeVisitor.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/internal/McCabeVisitor.kt @@ -22,71 +22,71 @@ import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType */ class McCabeVisitor(private val ignoreSimpleWhenEntries: Boolean) : DetektVisitor() { - var mcc: Int = 0 - private set(value) { - field = value - } + var mcc: Int = 0 + private set(value) { + field = value + } - override fun visitNamedFunction(function: KtNamedFunction) { - if (!isInsideObjectLiteral(function)) { - mcc++ - super.visitNamedFunction(function) - } - } + override fun visitNamedFunction(function: KtNamedFunction) { + if (!isInsideObjectLiteral(function)) { + mcc++ + super.visitNamedFunction(function) + } + } - fun isInsideObjectLiteral(function: KtNamedFunction) = - function.getStrictParentOfType() != null + fun isInsideObjectLiteral(function: KtNamedFunction) = + function.getStrictParentOfType() != null - override fun visitIfExpression(expression: KtIfExpression) { - mcc++ - if (expression.`else` != null) { - mcc++ - } - super.visitIfExpression(expression) - } + override fun visitIfExpression(expression: KtIfExpression) { + mcc++ + if (expression.`else` != null) { + mcc++ + } + super.visitIfExpression(expression) + } - override fun visitLoopExpression(loopExpression: KtLoopExpression) { - mcc++ - super.visitLoopExpression(loopExpression) - } + override fun visitLoopExpression(loopExpression: KtLoopExpression) { + mcc++ + super.visitLoopExpression(loopExpression) + } - override fun visitWhenExpression(expression: KtWhenExpression) { - val entries = expression.extractEntries(ignoreSimpleWhenEntries) - mcc += if (ignoreSimpleWhenEntries && entries.count() == 0) 1 else entries.count() - super.visitWhenExpression(expression) - } + override fun visitWhenExpression(expression: KtWhenExpression) { + val entries = expression.extractEntries(ignoreSimpleWhenEntries) + mcc += if (ignoreSimpleWhenEntries && entries.count() == 0) 1 else entries.count() + super.visitWhenExpression(expression) + } - private fun KtWhenExpression.extractEntries(ignoreSimpleWhenEntries: Boolean): Sequence { - val entries = entries.asSequence() - return if (ignoreSimpleWhenEntries) entries.filter { it.expression is KtBlockExpression } else entries - } + private fun KtWhenExpression.extractEntries(ignoreSimpleWhenEntries: Boolean): Sequence { + val entries = entries.asSequence() + return if (ignoreSimpleWhenEntries) entries.filter { it.expression is KtBlockExpression } else entries + } - override fun visitTryExpression(expression: KtTryExpression) { - mcc++ - mcc += expression.catchClauses.size - expression.finallyBlock?.let { - mcc++ - Unit - } - super.visitTryExpression(expression) - } + override fun visitTryExpression(expression: KtTryExpression) { + mcc++ + mcc += expression.catchClauses.size + expression.finallyBlock?.let { + mcc++ + Unit + } + super.visitTryExpression(expression) + } - override fun visitCallExpression(expression: KtCallExpression) { - if (expression.isUsedForNesting()) { - val lambdaArguments = expression.lambdaArguments - if (lambdaArguments.size > 0) { - val lambdaArgument = lambdaArguments[0] - lambdaArgument.getLambdaExpression()?.bodyExpression?.let { - mcc++ - Unit - } - } - } - super.visitCallExpression(expression) - } + override fun visitCallExpression(expression: KtCallExpression) { + if (expression.isUsedForNesting()) { + val lambdaArguments = expression.lambdaArguments + if (lambdaArguments.size > 0) { + val lambdaArgument = lambdaArguments[0] + lambdaArgument.getLambdaExpression()?.bodyExpression?.let { + mcc++ + Unit + } + } + } + super.visitCallExpression(expression) + } } fun KtCallExpression.isUsedForNesting(): Boolean = when (getCallNameExpression()?.text) { - "run", "let", "apply", "with", "use", "forEach" -> true - else -> false + "run", "let", "apply", "with", "use", "forEach" -> true + else -> false } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/internal/Signatures.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/internal/Signatures.kt index 10d1b50e8..385fc9dfa 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/internal/Signatures.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/internal/Signatures.kt @@ -13,40 +13,40 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffset private val signatureRegex = Regex("\\s(\\s|\t)+") internal fun PsiElement.searchName(): String { - return this.namedUnwrappedElement?.name ?: "" + return this.namedUnwrappedElement?.name ?: "" } internal fun PsiElement.searchClass(): String { - val classElement = this.getNonStrictParentOfType(KtClassOrObject::class.java) - var className = classElement?.name - if (className != null && className == "Companion") { - classElement?.parent?.getNonStrictParentOfType(KtClassOrObject::class.java)?.name?.let { - className = "$it.$className" - } - } - return className ?: this.containingFile.name + val classElement = this.getNonStrictParentOfType(KtClassOrObject::class.java) + var className = classElement?.name + if (className != null && className == "Companion") { + classElement?.parent?.getNonStrictParentOfType(KtClassOrObject::class.java)?.name?.let { + className = "$it.$className" + } + } + return className ?: this.containingFile.name } internal fun PsiElement.buildFullSignature(): String { - val signature = this.searchSignature() - val fullClassSignature = this.parents.filter { it is KtClassOrObject } - .map { it.extractClassName() } - .fold("") { sig, sig2 -> "$sig2${dotOrNot(sig, sig2)}$sig" } - val filename = this.containingFile.name - return (if (!fullClassSignature.startsWith(filename)) filename + "\$" else "") + - if (fullClassSignature.isNotEmpty()) "$fullClassSignature\$$signature" else signature + val signature = this.searchSignature() + val fullClassSignature = this.parents.filter { it is KtClassOrObject } + .map { it.extractClassName() } + .fold("") { sig, sig2 -> "$sig2${dotOrNot(sig, sig2)}$sig" } + val filename = this.containingFile.name + return (if (!fullClassSignature.startsWith(filename)) filename + "\$" else "") + + if (fullClassSignature.isNotEmpty()) "$fullClassSignature\$$signature" else signature } private fun PsiElement.extractClassName() = - this.getNonStrictParentOfType(KtClassOrObject::class.java)?.nameAsSafeName?.asString() ?: "" + this.getNonStrictParentOfType(KtClassOrObject::class.java)?.nameAsSafeName?.asString() ?: "" private fun PsiElement.searchSignature(): String { - return when (this) { - is KtNamedFunction -> buildFunctionSignature(this) - is KtClassOrObject -> buildClassSignature(this) - is KtFile -> fileSignature() - else -> this.text - }.replace('\n', ' ').replace(signatureRegex, " ") + return when (this) { + is KtNamedFunction -> buildFunctionSignature(this) + is KtClassOrObject -> buildClassSignature(this) + is KtFile -> fileSignature() + else -> this.text + }.replace('\n', ' ').replace(signatureRegex, " ") } private fun KtFile.fileSignature() = "${this.packageFqName.asString()}.${this.name}" @@ -54,39 +54,39 @@ private fun KtFile.fileSignature() = "${this.packageFqName.asString()}.${this.na private fun dotOrNot(sig: String, sig2: String) = if (sig.isNotEmpty() && sig2.isNotEmpty()) "." else "" private fun buildClassSignature(classOrObject: KtClassOrObject): String { - var baseName = classOrObject.nameAsSafeName.asString() - val typeParameters = classOrObject.typeParameters - if (typeParameters.size > 0) { - baseName += "<" - baseName += typeParameters.joinToString(", ") { it.text } - baseName += ">" - } - val extendedEntries = classOrObject.superTypeListEntries - if (extendedEntries.isNotEmpty()) baseName += " : " - extendedEntries.forEach { baseName += it.typeAsUserType?.referencedName ?: "" } - return baseName + var baseName = classOrObject.nameAsSafeName.asString() + val typeParameters = classOrObject.typeParameters + if (typeParameters.size > 0) { + baseName += "<" + baseName += typeParameters.joinToString(", ") { it.text } + baseName += ">" + } + val extendedEntries = classOrObject.superTypeListEntries + if (extendedEntries.isNotEmpty()) baseName += " : " + extendedEntries.forEach { baseName += it.typeAsUserType?.referencedName ?: "" } + return baseName } private fun buildFunctionSignature(element: KtNamedFunction): String { - var methodStart = 0 - element.docComment?.let { - methodStart = it.endOffset - it.startOffset - } - var methodEnd = element.endOffset - element.startOffset - val typeReference = element.typeReference - if (typeReference != null) { - methodEnd = typeReference.endOffset - element.startOffset - } else { - element.valueParameterList?.let { - methodEnd = it.endOffset - element.startOffset - } - } - require(methodStart < methodEnd) { - "Error building function signature with range $methodStart - $methodEnd for element: ${element.text}" - } - return getTextSafe( - { element.nameAsSafeName.identifier }, - { element.text.substring(methodStart, methodEnd) }) + var methodStart = 0 + element.docComment?.let { + methodStart = it.endOffset - it.startOffset + } + var methodEnd = element.endOffset - element.startOffset + val typeReference = element.typeReference + if (typeReference != null) { + methodEnd = typeReference.endOffset - element.startOffset + } else { + element.valueParameterList?.let { + methodEnd = it.endOffset - element.startOffset + } + } + require(methodStart < methodEnd) { + "Error building function signature with range $methodStart - $methodEnd for element: ${element.text}" + } + return getTextSafe( + { element.nameAsSafeName.identifier }, + { element.text.substring(methodStart, methodEnd) }) } /* @@ -95,12 +95,12 @@ private fun buildFunctionSignature(element: KtNamedFunction): String { */ @Suppress("TooGenericExceptionCaught") internal fun getTextSafe(defaultValue: () -> String, block: () -> String) = try { - block() + block() } catch (e: RuntimeException) { - val message = e.message - if (message != null && message.contains("Underestimated text length")) { - defaultValue() + "!" - } else { - defaultValue() - } + val message = e.message + if (message != null && message.contains("Underestimated text length")) { + defaultValue() + "!" + } else { + defaultValue() + } } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/internal/Validation.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/internal/Validation.kt index 51661ed86..78dcec252 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/internal/Validation.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/internal/Validation.kt @@ -6,5 +6,5 @@ private val identifierRegex = Regex("[aA-zZ]+([-][aA-zZ]+)*") * Checks if given string matches the criteria of an id - [aA-zZ]+([-][aA-zZ]+)* . */ internal fun validateIdentifier(id: String) { - require(id.matches(identifierRegex)) { "id must match [aA-zZ]+([-][aA-zZ]+)*" } + require(id.matches(identifierRegex)) { "id must match [aA-zZ]+([-][aA-zZ]+)*" } } diff --git a/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/AnnotationExcluderSpec.kt b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/AnnotationExcluderSpec.kt index 26ab360b7..66eb44c58 100644 --- a/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/AnnotationExcluderSpec.kt +++ b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/AnnotationExcluderSpec.kt @@ -7,34 +7,34 @@ import org.jetbrains.spek.api.dsl.describe import org.jetbrains.spek.api.dsl.it class AnnotationExcluderSpec : Spek({ - describe("a kt file with some imports") { - val jvmFieldAnnotation = psiFactory.createAnnotationEntry("@JvmField") - val sinceKotlinAnnotation = psiFactory.createAnnotationEntry("@SinceKotlin") + describe("a kt file with some imports") { + val jvmFieldAnnotation = psiFactory.createAnnotationEntry("@JvmField") + val sinceKotlinAnnotation = psiFactory.createAnnotationEntry("@SinceKotlin") - val file = compileContentForTest(""" + val file = compileContentForTest(""" package foo import kotlin.jvm.JvmField """.trimIndent()) - it("should exclude when the annotation was found") { - val excluder = AnnotationExcluder(file, SplitPattern("JvmField")) - assertThat(excluder.shouldExclude(listOf(jvmFieldAnnotation))).isTrue() - } + it("should exclude when the annotation was found") { + val excluder = AnnotationExcluder(file, SplitPattern("JvmField")) + assertThat(excluder.shouldExclude(listOf(jvmFieldAnnotation))).isTrue() + } - it("should not exclude when the annotation was not found") { - val excluder = AnnotationExcluder(file, SplitPattern("Jvm Field")) - assertThat(excluder.shouldExclude(listOf(jvmFieldAnnotation))).isFalse() - } + it("should not exclude when the annotation was not found") { + val excluder = AnnotationExcluder(file, SplitPattern("Jvm Field")) + assertThat(excluder.shouldExclude(listOf(jvmFieldAnnotation))).isFalse() + } - it("should not exclude when no annotations should be excluded") { - val excluder = AnnotationExcluder(file, SplitPattern("")) - assertThat(excluder.shouldExclude(listOf(jvmFieldAnnotation))).isFalse() - } + it("should not exclude when no annotations should be excluded") { + val excluder = AnnotationExcluder(file, SplitPattern("")) + assertThat(excluder.shouldExclude(listOf(jvmFieldAnnotation))).isFalse() + } - it("should not exclude an annotation that is not imported") { - val excluder = AnnotationExcluder(file, SplitPattern("SinceKotlin")) - assertThat(excluder.shouldExclude(listOf(sinceKotlinAnnotation))).isFalse() - } - } + it("should not exclude an annotation that is not imported") { + val excluder = AnnotationExcluder(file, SplitPattern("SinceKotlin")) + assertThat(excluder.shouldExclude(listOf(sinceKotlinAnnotation))).isFalse() + } + } }) diff --git a/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/Compiler.kt b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/Compiler.kt index 32c00ba2a..3545f7032 100644 --- a/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/Compiler.kt +++ b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/Compiler.kt @@ -1,29 +1,29 @@ package io.gitlab.arturbosch.detekt.api +import java.io.File +import java.net.URI import org.jetbrains.kotlin.com.intellij.openapi.util.text.StringUtilRt import org.jetbrains.kotlin.com.intellij.psi.PsiFileFactory import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.psi.KtFile -import java.io.File -import java.net.URI /** * @author Artur Bosch */ internal object Compiler { - private val psiFileFactory: PsiFileFactory = PsiFileFactory.getInstance(psiProject) + private val psiFileFactory: PsiFileFactory = PsiFileFactory.getInstance(psiProject) - fun compileFromContent(content: String): KtFile { - val psiFile = psiFileFactory.createFileFromText( - KotlinLanguage.INSTANCE, - StringUtilRt.convertLineSeparators(content)) - return psiFile as? KtFile ?: throw IllegalStateException("kotlin file expected") - } + fun compileFromContent(content: String): KtFile { + val psiFile = psiFileFactory.createFileFromText( + KotlinLanguage.INSTANCE, + StringUtilRt.convertLineSeparators(content)) + return psiFile as? KtFile ?: throw IllegalStateException("kotlin file expected") + } } fun compilerFor(resource: String) = Compiler.compileFromContent( - File(Compiler.javaClass.getResource("/$resource").path).readText()) + File(Compiler.javaClass.getResource("/$resource").path).readText()) fun yamlConfig(resource: String) = YamlConfig.loadResource(Compiler.javaClass.getResource("/$resource")) diff --git a/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/CompositeConfigTest.kt b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/CompositeConfigTest.kt index d55ae32c0..dba21bb71 100644 --- a/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/CompositeConfigTest.kt +++ b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/CompositeConfigTest.kt @@ -10,30 +10,30 @@ import org.jetbrains.spek.api.dsl.it */ class CompositeConfigTest : Spek({ - describe("both configs should be considered") { - val second = yamlConfig("composite-test.yml") - val first = yamlConfig("detekt.yml") - val compositeConfig = CompositeConfig(second, first) + describe("both configs should be considered") { + val second = yamlConfig("composite-test.yml") + val first = yamlConfig("detekt.yml") + val compositeConfig = CompositeConfig(second, first) - it("should have style sub config with active false which is overridden in `second` config regardless of default value") { - val styleConfig = compositeConfig.subConfig("style").subConfig("WildcardImport") - assertThat(styleConfig.valueOrDefault("active", true)).isEqualTo(false) - assertThat(styleConfig.valueOrDefault("active", false)).isEqualTo(false) - } + it("should have style sub config with active false which is overridden in `second` config regardless of default value") { + val styleConfig = compositeConfig.subConfig("style").subConfig("WildcardImport") + assertThat(styleConfig.valueOrDefault("active", true)).isEqualTo(false) + assertThat(styleConfig.valueOrDefault("active", false)).isEqualTo(false) + } - it("should have code smell sub config with LongMethod threshold 20 from `first` config") { - val codeSmellConfig = compositeConfig.subConfig("code-smell").subConfig("LongMethod") - assertThat(codeSmellConfig.valueOrDefault("threshold", -1)).isEqualTo(20) - } + it("should have code smell sub config with LongMethod threshold 20 from `first` config") { + val codeSmellConfig = compositeConfig.subConfig("code-smell").subConfig("LongMethod") + assertThat(codeSmellConfig.valueOrDefault("threshold", -1)).isEqualTo(20) + } - it("should use the default as both part configurations do not have the value") { - assertThat(compositeConfig.valueOrDefault("TEST", 42)).isEqualTo(42) - } + it("should use the default as both part configurations do not have the value") { + assertThat(compositeConfig.valueOrDefault("TEST", 42)).isEqualTo(42) + } - it("should return a string based on default value") { - val config = compositeConfig.subConfig("style").subConfig("MagicNumber") - val value = config.valueOrDefault("ignoreNumbers", "-1,0,1,2") - assertThat(value).isEqualTo("-1,0,1,2,100,1000") - } - } + it("should return a string based on default value") { + val config = compositeConfig.subConfig("style").subConfig("MagicNumber") + val value = config.valueOrDefault("ignoreNumbers", "-1,0,1,2") + assertThat(value).isEqualTo("-1,0,1,2,100,1000") + } + } }) diff --git a/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/ConfigSpec.kt b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/ConfigSpec.kt index 55ec8d393..16ac6892d 100644 --- a/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/ConfigSpec.kt +++ b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/ConfigSpec.kt @@ -1,62 +1,62 @@ package io.gitlab.arturbosch.detekt.api +import java.nio.file.Paths import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThatExceptionOfType import org.assertj.core.api.Assertions.fail import org.jetbrains.spek.api.Spek import org.jetbrains.spek.api.dsl.describe import org.jetbrains.spek.api.dsl.it -import java.nio.file.Paths /** * @author Artur Bosch */ class ConfigSpec : Spek({ - describe("load yaml config") { - val configPath = Paths.get(resource("/detekt.yml")) - val config = YamlConfig.load(configPath) + describe("load yaml config") { + val configPath = Paths.get(resource("/detekt.yml")) + val config = YamlConfig.load(configPath) - it("should create a sub config") { - try { - val subConfig = config.subConfig("style") - assertThat(subConfig.valueOrDefault("WildcardImport", mapOf())).isNotEmpty - assertThat(subConfig.valueOrDefault("WildcardImport", mapOf())["active"].toString()).isEqualTo("true") - assertThat(subConfig.valueOrDefault("WildcardImport", mapOf())["active"] as Boolean).isTrue() - assertThat(subConfig.valueOrDefault("NotFound", mapOf())).isEmpty() - assertThat(subConfig.valueOrDefault("NotFound", "")).isEmpty() - } catch (ignored: Config.InvalidConfigurationError) { - fail("Creating a sub config should work for test resources config!") - } - } + it("should create a sub config") { + try { + val subConfig = config.subConfig("style") + assertThat(subConfig.valueOrDefault("WildcardImport", mapOf())).isNotEmpty + assertThat(subConfig.valueOrDefault("WildcardImport", mapOf())["active"].toString()).isEqualTo("true") + assertThat(subConfig.valueOrDefault("WildcardImport", mapOf())["active"] as Boolean).isTrue() + assertThat(subConfig.valueOrDefault("NotFound", mapOf())).isEmpty() + assertThat(subConfig.valueOrDefault("NotFound", "")).isEmpty() + } catch (ignored: Config.InvalidConfigurationError) { + fail("Creating a sub config should work for test resources config!") + } + } - it("should create a sub sub config") { - try { - val subConfig = config.subConfig("style") - val subSubConfig = subConfig.subConfig("WildcardImport") - assertThat(subSubConfig.valueOrDefault("active", false)).isTrue() - assertThat(subSubConfig.valueOrDefault("NotFound", true)).isTrue() - } catch (ignored: Config.InvalidConfigurationError) { - fail("Creating a sub config should work for test resources config!") - } - } + it("should create a sub sub config") { + try { + val subConfig = config.subConfig("style") + val subSubConfig = subConfig.subConfig("WildcardImport") + assertThat(subSubConfig.valueOrDefault("active", false)).isTrue() + assertThat(subSubConfig.valueOrDefault("NotFound", true)).isTrue() + } catch (ignored: Config.InvalidConfigurationError) { + fail("Creating a sub config should work for test resources config!") + } + } - it("tests wrong sub config conversion") { - assertThatExceptionOfType(ClassCastException::class.java).isThrownBy { - @Suppress("UNUSED_VARIABLE") - val ignored = config.valueOrDefault("style", "") - } - } - } + it("tests wrong sub config conversion") { + assertThatExceptionOfType(ClassCastException::class.java).isThrownBy { + @Suppress("UNUSED_VARIABLE") + val ignored = config.valueOrDefault("style", "") + } + } + } - describe("loading empty configurations") { + describe("loading empty configurations") { - it("empty yaml file is equivalent to empty config") { - YamlConfig.loadResource(javaClass.getResource("/empty.yml")) - } + it("empty yaml file is equivalent to empty config") { + YamlConfig.loadResource(javaClass.getResource("/empty.yml")) + } - it("single item in yaml file is valid") { - YamlConfig.loadResource(javaClass.getResource("/oneitem.yml")) - } - } + it("single item in yaml file is valid") { + YamlConfig.loadResource(javaClass.getResource("/oneitem.yml")) + } + } }) diff --git a/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/DebtSpec.kt b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/DebtSpec.kt index 0b267e530..db268007c 100644 --- a/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/DebtSpec.kt +++ b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/DebtSpec.kt @@ -11,26 +11,26 @@ import org.jetbrains.spek.api.dsl.it */ class DebtSpec : Spek({ - describe("creating issues with custom debt values") { - it("should fail on negative values") { - assertThatIllegalArgumentException().isThrownBy { Debt(-1, -1, -1) } - } + describe("creating issues with custom debt values") { + it("should fail on negative values") { + assertThatIllegalArgumentException().isThrownBy { Debt(-1, -1, -1) } + } - it("should fail if all values are less than zero ") { - assertThatIllegalArgumentException().isThrownBy { Debt(0, 0, 0) } - } + it("should fail if all values are less than zero ") { + assertThatIllegalArgumentException().isThrownBy { Debt(0, 0, 0) } + } - it("should print 20min, 10min and 5min") { - assertThat(Debt.TWENTY_MINS.toString()).isEqualTo("20min") - assertThat(Debt.TEN_MINS.toString()).isEqualTo("10min") - assertThat(Debt.FIVE_MINS.toString()).isEqualTo("5min") - } + it("should print 20min, 10min and 5min") { + assertThat(Debt.TWENTY_MINS.toString()).isEqualTo("20min") + assertThat(Debt.TEN_MINS.toString()).isEqualTo("10min") + assertThat(Debt.FIVE_MINS.toString()).isEqualTo("5min") + } - it("day, hours and min combinations should work") { - assertThat(Debt(1, 20, 20).toString()).isEqualTo("1d 20h 20min") - assertThat(Debt(1, 20, 0).toString()).isEqualTo("1d 20h") - assertThat(Debt(0, 20, 0).toString()).isEqualTo("20h") - assertThat(Debt(1, 0, 20).toString()).isEqualTo("1d 20min") - } - } + it("day, hours and min combinations should work") { + assertThat(Debt(1, 20, 20).toString()).isEqualTo("1d 20h 20min") + assertThat(Debt(1, 20, 0).toString()).isEqualTo("1d 20h") + assertThat(Debt(0, 20, 0).toString()).isEqualTo("20h") + assertThat(Debt(1, 0, 20).toString()).isEqualTo("1d 20min") + } + } }) diff --git a/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/MetricSpec.kt b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/MetricSpec.kt index 9c1b0fde1..83f689d0a 100644 --- a/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/MetricSpec.kt +++ b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/MetricSpec.kt @@ -10,15 +10,15 @@ import org.jetbrains.spek.api.dsl.it */ class MetricSpec : Spek({ - it("should convert double values to int") { - val metric = Metric("LOC", 0.33, 0.10, 100) - assertThat(metric.doubleValue()).isEqualTo(0.33) - assertThat(metric.doubleThreshold()).isEqualTo(0.10) - } + it("should convert double values to int") { + val metric = Metric("LOC", 0.33, 0.10, 100) + assertThat(metric.doubleValue()).isEqualTo(0.33) + assertThat(metric.doubleThreshold()).isEqualTo(0.10) + } - it("should throw error if double value is asked for int metric") { - assertThatIllegalStateException().isThrownBy { - Metric("LOC", 100, 50).doubleValue() - } - } + it("should throw error if double value is asked for int metric") { + assertThatIllegalStateException().isThrownBy { + Metric("LOC", 100, 50).doubleValue() + } + } }) diff --git a/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/MultiRuleTest.kt b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/MultiRuleTest.kt index 193a4aff0..6ddce8291 100644 --- a/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/MultiRuleTest.kt +++ b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/MultiRuleTest.kt @@ -11,45 +11,45 @@ import org.jetbrains.spek.api.dsl.it */ internal class MultiRuleTest : Spek({ - describe("a multi rule can have filters") { + describe("a multi rule can have filters") { - fun ruleSet() = RuleSet("TestMultiRule", listOf(TestMultiRule())) - val file = compilerFor("FilteredClass.kt") + fun ruleSet() = RuleSet("TestMultiRule", listOf(TestMultiRule())) + val file = compilerFor("FilteredClass.kt") - it("should not run any rules if both are filtered out") { - val filters = setOf("TestRuleOne", "TestRuleTwo") - val findings = ruleSet().accept(file, filters) + it("should not run any rules if both are filtered out") { + val filters = setOf("TestRuleOne", "TestRuleTwo") + val findings = ruleSet().accept(file, filters) - assertThat(findings).isEmpty() - } + assertThat(findings).isEmpty() + } - it("should only run one rule as the other is filtered") { - val filters = setOf("TestRuleOne") - val findings = ruleSet().accept(file, filters) + it("should only run one rule as the other is filtered") { + val filters = setOf("TestRuleOne") + val findings = ruleSet().accept(file, filters) - assertThat(findings).hasSize(1) - } - } + assertThat(findings).hasSize(1) + } + } }) class TestMultiRule : MultiRule() { - private val one = TestRuleOne() - private val two = TestRuleTwo() - override val rules: List = listOf(one, two) + private val one = TestRuleOne() + private val two = TestRuleTwo() + override val rules: List = listOf(one, two) - override fun visitKtFile(file: KtFile) { - one.runIfActive { visitKtFile(file) } - two.runIfActive { visitKtFile(file) } - } + override fun visitKtFile(file: KtFile) { + one.runIfActive { visitKtFile(file) } + two.runIfActive { visitKtFile(file) } + } } abstract class AbstractRule : Rule() { - override val issue: Issue = Issue(javaClass.simpleName, Severity.Minor, "", Debt.TWENTY_MINS) + override val issue: Issue = Issue(javaClass.simpleName, Severity.Minor, "", Debt.TWENTY_MINS) - override fun visitKtFile(file: KtFile) { - report(CodeSmell(issue, Entity.from(file), message = "")) - } + override fun visitKtFile(file: KtFile) { + report(CodeSmell(issue, Entity.from(file), message = "")) + } } class TestRuleOne : AbstractRule() diff --git a/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/SingleAssignTest.kt b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/SingleAssignTest.kt index 0cacebcdb..d269bd2d3 100644 --- a/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/SingleAssignTest.kt +++ b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/SingleAssignTest.kt @@ -7,30 +7,30 @@ import org.jetbrains.spek.api.dsl.describe import org.jetbrains.spek.api.dsl.it internal class SingleAssignTest : Spek({ - describe("value is unset") { - var unassigned: Int by SingleAssign() - it("should fail when value is retrieved") { - assertThatIllegalStateException().isThrownBy { - @Suppress("UNUSED_EXPRESSION") - unassigned - } + describe("value is unset") { + var unassigned: Int by SingleAssign() + it("should fail when value is retrieved") { + assertThatIllegalStateException().isThrownBy { + @Suppress("UNUSED_EXPRESSION") + unassigned + } + } + + it("should succeed when value is assigned") { + unassigned = 15 + } } - it("should succeed when value is assigned") { - unassigned = 15 - } - } + describe("value is set") { + var assigned: Int by SingleAssign() + assigned = 15 - describe("value is set") { - var assigned: Int by SingleAssign() - assigned = 15 + it("should succeed when value is retrieved") { + assertThat(assigned).isEqualTo(15) + } - it("should succeed when value is retrieved") { - assertThat(assigned).isEqualTo(15) + it("should fail when value is assigned") { + assertThatIllegalStateException().isThrownBy { assigned = -1 } + } } - - it("should fail when value is assigned") { - assertThatIllegalStateException().isThrownBy { assigned = -1 } - } - } }) diff --git a/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/SplitPatternSpec.kt b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/SplitPatternSpec.kt index 0f09d14c3..3dc79273d 100644 --- a/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/SplitPatternSpec.kt +++ b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/SplitPatternSpec.kt @@ -7,88 +7,88 @@ import org.jetbrains.spek.api.dsl.it class SplitPatternSpec : Spek({ - given("an excludes rule with a single exclude") { - val excludes = SplitPattern("test") + given("an excludes rule with a single exclude") { + val excludes = SplitPattern("test") - it("contains the `test` parameter") { - val parameter = "test" - assertThat(excludes.contains(parameter)).isTrue() - assertThat(excludes.none(parameter)).isFalse() - } + it("contains the `test` parameter") { + val parameter = "test" + assertThat(excludes.contains(parameter)).isTrue() + assertThat(excludes.none(parameter)).isFalse() + } - it("contains an extension of the `test` parameter") { - val parameter = "test.com" - assertThat(excludes.contains(parameter)).isTrue() - assertThat(excludes.none(parameter)).isFalse() - } + it("contains an extension of the `test` parameter") { + val parameter = "test.com" + assertThat(excludes.contains(parameter)).isTrue() + assertThat(excludes.none(parameter)).isFalse() + } - it("does not contain a different parameter") { - val parameter = "detekt" - assertThat(excludes.contains(parameter)).isFalse() - assertThat(excludes.none(parameter)).isTrue() - } + it("does not contain a different parameter") { + val parameter = "detekt" + assertThat(excludes.contains(parameter)).isFalse() + assertThat(excludes.none(parameter)).isTrue() + } - it("returns all matches") { - val parameter = "test.com" - val matches = excludes.matches(parameter) - assertThat(matches).hasSize(1) - assertThat(matches).contains("test") - } - } + it("returns all matches") { + val parameter = "test.com" + val matches = excludes.matches(parameter) + assertThat(matches).hasSize(1) + assertThat(matches).contains("test") + } + } - given("an excludes rule with multiple excludes") { - val excludes = SplitPattern("here.there.io, test.com") + given("an excludes rule with multiple excludes") { + val excludes = SplitPattern("here.there.io, test.com") - it("contains the `test` parameter") { - val parameter = "test.com" - assertThat(excludes.contains(parameter)).isTrue() - assertThat(excludes.none(parameter)).isFalse() - } + it("contains the `test` parameter") { + val parameter = "test.com" + assertThat(excludes.contains(parameter)).isTrue() + assertThat(excludes.none(parameter)).isFalse() + } - it("contains the `here.there.io` parameter") { - val parameter = "here.there.io" - assertThat(excludes.contains(parameter)).isTrue() - assertThat(excludes.none(parameter)).isFalse() - } + it("contains the `here.there.io` parameter") { + val parameter = "here.there.io" + assertThat(excludes.contains(parameter)).isTrue() + assertThat(excludes.none(parameter)).isFalse() + } - it("does not contain a parameter spanning over the excludes") { - val parameter = "io.test.com" - assertThat(excludes.contains(parameter)).isTrue() - assertThat(excludes.none(parameter)).isFalse() - } + it("does not contain a parameter spanning over the excludes") { + val parameter = "io.test.com" + assertThat(excludes.contains(parameter)).isTrue() + assertThat(excludes.none(parameter)).isFalse() + } - it("does not contain a different") { - val parameter = "detekt" - assertThat(excludes.contains(parameter)).isFalse() - assertThat(excludes.none(parameter)).isTrue() - } - } + it("does not contain a different") { + val parameter = "detekt" + assertThat(excludes.contains(parameter)).isFalse() + assertThat(excludes.none(parameter)).isTrue() + } + } - given("an excludes rule with lots of whitespace and an empty parameter") { - val excludes = SplitPattern(" test, , here.there ") + given("an excludes rule with lots of whitespace and an empty parameter") { + val excludes = SplitPattern(" test, , here.there ") - it("contains the `test` parameter") { - val parameter = "test" - assertThat(excludes.contains(parameter)).isTrue() - assertThat(excludes.none(parameter)).isFalse() - } + it("contains the `test` parameter") { + val parameter = "test" + assertThat(excludes.contains(parameter)).isTrue() + assertThat(excludes.none(parameter)).isFalse() + } - it("contains the `here.there` parameter") { - val parameter = "here.there" - assertThat(excludes.contains(parameter)).isTrue() - assertThat(excludes.none(parameter)).isFalse() - } + it("contains the `here.there` parameter") { + val parameter = "here.there" + assertThat(excludes.contains(parameter)).isTrue() + assertThat(excludes.none(parameter)).isFalse() + } - it("does not contain a different parameter") { - val parameter = "detekt" - assertThat(excludes.contains(parameter)).isFalse() - assertThat(excludes.none(parameter)).isTrue() - } + it("does not contain a different parameter") { + val parameter = "detekt" + assertThat(excludes.contains(parameter)).isFalse() + assertThat(excludes.none(parameter)).isTrue() + } - it("does not match empty strings") { - val parameter = " " - assertThat(excludes.contains(parameter)).isFalse() - assertThat(excludes.none(parameter)).isTrue() - } - } + it("does not match empty strings") { + val parameter = " " + assertThat(excludes.contains(parameter)).isFalse() + assertThat(excludes.none(parameter)).isTrue() + } + } }) diff --git a/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/SuppressibleSpec.kt b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/SuppressibleSpec.kt index 8eec59a73..44b7955cd 100644 --- a/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/SuppressibleSpec.kt +++ b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/SuppressibleSpec.kt @@ -13,92 +13,92 @@ import org.jetbrains.spek.api.dsl.it */ internal class SuppressibleSpec : Spek({ - given("a Test rule") { + given("a Test rule") { - it("should not be suppressed by a @Deprecated annotation") { - assertThat(checkSuppression("Deprecated", "This should no longer be used")).isFalse() - } + it("should not be suppressed by a @Deprecated annotation") { + assertThat(checkSuppression("Deprecated", "This should no longer be used")).isFalse() + } - it("should not be suppressed by a @Suppress annotation for another rule") { - assertThat(checkSuppression("Suppress", "NotATest")).isFalse() - } + it("should not be suppressed by a @Suppress annotation for another rule") { + assertThat(checkSuppression("Suppress", "NotATest")).isFalse() + } - it("should not be suppressed by a @SuppressWarnings annotation for another rule") { - assertThat(checkSuppression("SuppressWarnings", "NotATest")).isFalse() - } + it("should not be suppressed by a @SuppressWarnings annotation for another rule") { + assertThat(checkSuppression("SuppressWarnings", "NotATest")).isFalse() + } - it("should be suppressed by a @Suppress annotation for the rule") { - assertThat(checkSuppression("Suppress", "Test")).isTrue() - } + it("should be suppressed by a @Suppress annotation for the rule") { + assertThat(checkSuppression("Suppress", "Test")).isTrue() + } - it("should be suppressed by a @SuppressWarnings annotation for the rule") { - assertThat(checkSuppression("SuppressWarnings", "Test")).isTrue() - } + it("should be suppressed by a @SuppressWarnings annotation for the rule") { + assertThat(checkSuppression("SuppressWarnings", "Test")).isTrue() + } - it("should be suppressed by a @SuppressWarnings annotation for 'all' rules") { - assertThat(checkSuppression("Suppress", "all")).isTrue() - } + it("should be suppressed by a @SuppressWarnings annotation for 'all' rules") { + assertThat(checkSuppression("Suppress", "all")).isTrue() + } - it("should be suppressed by a @SuppressWarnings annotation for 'ALL' rules") { - assertThat(checkSuppression("SuppressWarnings", "ALL")).isTrue() - } + it("should be suppressed by a @SuppressWarnings annotation for 'ALL' rules") { + assertThat(checkSuppression("SuppressWarnings", "ALL")).isTrue() + } - it("should not be suppressed by a @Suppress annotation with a Checkstyle prefix") { - assertThat(checkSuppression("Suppress", "Checkstyle:Test")).isFalse() - } + it("should not be suppressed by a @Suppress annotation with a Checkstyle prefix") { + assertThat(checkSuppression("Suppress", "Checkstyle:Test")).isFalse() + } - it("should not be suppressed by a @SuppressWarnings annotation with a Checkstyle prefix") { - assertThat(checkSuppression("SuppressWarnings", "Checkstyle:Test")).isFalse() - } + it("should not be suppressed by a @SuppressWarnings annotation with a Checkstyle prefix") { + assertThat(checkSuppression("SuppressWarnings", "Checkstyle:Test")).isFalse() + } - it("should be suppressed by a @Suppress annotation with a 'Detekt' prefix") { - assertThat(checkSuppression("Suppress", "Detekt:Test")).isTrue() - } + it("should be suppressed by a @Suppress annotation with a 'Detekt' prefix") { + assertThat(checkSuppression("Suppress", "Detekt:Test")).isTrue() + } - it("should be suppressed by a @SuppressWarnings annotation with a 'Detekt' prefix") { - assertThat(checkSuppression("SuppressWarnings", "Detekt:Test")).isTrue() - } + it("should be suppressed by a @SuppressWarnings annotation with a 'Detekt' prefix") { + assertThat(checkSuppression("SuppressWarnings", "Detekt:Test")).isTrue() + } - it("should be suppressed by a @Suppress annotation with a 'detekt' prefix") { - assertThat(checkSuppression("Suppress", "detekt:Test")).isTrue() - } + it("should be suppressed by a @Suppress annotation with a 'detekt' prefix") { + assertThat(checkSuppression("Suppress", "detekt:Test")).isTrue() + } - it("should be suppressed by a @SuppressWarnings annotation with a 'detekt' prefix") { - assertThat(checkSuppression("SuppressWarnings", "detekt:Test")).isTrue() - } + it("should be suppressed by a @SuppressWarnings annotation with a 'detekt' prefix") { + assertThat(checkSuppression("SuppressWarnings", "detekt:Test")).isTrue() + } - it("should be suppressed by a @Suppress annotation with a 'detekt' prefix with a dot") { - assertThat(checkSuppression("Suppress", "detekt.Test")).isTrue() - } + it("should be suppressed by a @Suppress annotation with a 'detekt' prefix with a dot") { + assertThat(checkSuppression("Suppress", "detekt.Test")).isTrue() + } - it("should be suppressed by a @SuppressWarnings annotation with a 'detekt' prefix with a dot") { - assertThat(checkSuppression("SuppressWarnings", "detekt.Test")).isTrue() - } + it("should be suppressed by a @SuppressWarnings annotation with a 'detekt' prefix with a dot") { + assertThat(checkSuppression("SuppressWarnings", "detekt.Test")).isTrue() + } - it("should not be suppressed by a @Suppress annotation with a 'detekt' prefix with a wrong separator") { - assertThat(checkSuppression("Suppress", "detekt/Test")).isFalse() - } + it("should not be suppressed by a @Suppress annotation with a 'detekt' prefix with a wrong separator") { + assertThat(checkSuppression("Suppress", "detekt/Test")).isFalse() + } - it("should not be suppressed by a @SuppressWarnings annotation with a 'detekt' prefix with a wrong separator") { - assertThat(checkSuppression("SuppressWarnings", "detekt/Test")).isFalse() - } + it("should not be suppressed by a @SuppressWarnings annotation with a 'detekt' prefix with a wrong separator") { + assertThat(checkSuppression("SuppressWarnings", "detekt/Test")).isFalse() + } - it("should be suppressed by a @Suppress annotation with an alias") { - assertThat(checkSuppression("Suppress", "alias")).isTrue() - } + it("should be suppressed by a @Suppress annotation with an alias") { + assertThat(checkSuppression("Suppress", "alias")).isTrue() + } - it("should be suppressed by a @SuppressWarnings annotation with an alias") { - assertThat(checkSuppression("SuppressWarnings", "alias")).isTrue() - } - } + it("should be suppressed by a @SuppressWarnings annotation with an alias") { + assertThat(checkSuppression("SuppressWarnings", "alias")).isTrue() + } + } }) private fun checkSuppression(annotation: String, argument: String): Boolean { - val annotated = """ + val annotated = """ @$annotation("$argument") class Test {} """ - val file = compileContentForTest(annotated) - val annotatedClass = file.children.first { it is KtClass } as KtAnnotated - return annotatedClass.isSuppressedBy("Test", setOf("alias")) + val file = compileContentForTest(annotated) + val annotatedClass = file.children.first { it is KtClass } as KtAnnotated + return annotatedClass.isSuppressedBy("Test", setOf("alias")) } diff --git a/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/SuppressionSpec.kt b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/SuppressionSpec.kt index 341530b8c..739affffc 100644 --- a/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/SuppressionSpec.kt +++ b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/SuppressionSpec.kt @@ -15,31 +15,31 @@ import org.jetbrains.spek.api.dsl.it */ internal class SuppressionSpec : Spek({ - describe("different suppression scenarios") { + describe("different suppression scenarios") { - it("rule should be suppressed") { - val ktFile = compilerFor("SuppressedObject.kt") - val rule = TestRule() - rule.visitFile(ktFile) - assertThat(rule.expected).isNotNull() - } + it("rule should be suppressed") { + val ktFile = compilerFor("SuppressedObject.kt") + val rule = TestRule() + rule.visitFile(ktFile) + assertThat(rule.expected).isNotNull() + } - it("findings are suppressed") { - val ktFile = compilerFor("SuppressedElements.kt") - val ruleSet = RuleSet("Test", listOf(TestLM(), TestLPL())) - val findings = ruleSet.accept(ktFile) - assertThat(findings.size).isZero() - } + it("findings are suppressed") { + val ktFile = compilerFor("SuppressedElements.kt") + val ruleSet = RuleSet("Test", listOf(TestLM(), TestLPL())) + val findings = ruleSet.accept(ktFile) + assertThat(findings.size).isZero() + } - it("rule should be suppressed by ALL") { - val ktFile = compilerFor("SuppressedByAllObject.kt") - val rule = TestRule() - rule.visitFile(ktFile) - assertThat(rule.expected).isNotNull() - } + it("rule should be suppressed by ALL") { + val ktFile = compilerFor("SuppressedByAllObject.kt") + val rule = TestRule() + rule.visitFile(ktFile) + assertThat(rule.expected).isNotNull() + } - it("rule should be suppressed by detekt prefix in uppercase with dot separator") { - val ktFile = compileContentForTest(""" + it("rule should be suppressed by detekt prefix in uppercase with dot separator") { + val ktFile = compileContentForTest(""" @file:Suppress("Detekt.ALL") object SuppressedWithDetektPrefix { @@ -48,13 +48,13 @@ internal class SuppressionSpec : Spek({ } } """) - val rule = TestRule() - rule.visitFile(ktFile) - assertThat(rule.expected).isNotNull() - } + val rule = TestRule() + rule.visitFile(ktFile) + assertThat(rule.expected).isNotNull() + } - it("rule should be suppressed by detekt prefix in lowercase with colon separator") { - val ktFile = compileContentForTest(""" + it("rule should be suppressed by detekt prefix in lowercase with colon separator") { + val ktFile = compileContentForTest(""" @file:Suppress("detekt:ALL") object SuppressedWithDetektPrefix { @@ -63,13 +63,13 @@ internal class SuppressionSpec : Spek({ } } """) - val rule = TestRule() - rule.visitFile(ktFile) - assertThat(rule.expected).isNotNull() - } + val rule = TestRule() + rule.visitFile(ktFile) + assertThat(rule.expected).isNotNull() + } - it("rule should be suppressed by detekt prefix in all caps with colon separator") { - val ktFile = compileContentForTest(""" + it("rule should be suppressed by detekt prefix in all caps with colon separator") { + val ktFile = compileContentForTest(""" @file:Suppress("DETEKT:ALL") object SuppressedWithDetektPrefix { @@ -78,16 +78,16 @@ internal class SuppressionSpec : Spek({ } } """) - val rule = TestRule() - rule.visitFile(ktFile) - assertThat(rule.expected).isNotNull() - } - } + val rule = TestRule() + rule.visitFile(ktFile) + assertThat(rule.expected).isNotNull() + } + } - describe("suppression based on aliases from config property") { + describe("suppression based on aliases from config property") { - it("allows to declare") { - val ktFile = compileContentForTest(""" + it("allows to declare") { + val ktFile = compileContentForTest(""" @file:Suppress("detekt:MyTest") object SuppressedWithDetektPrefixAndCustomConfigBasedPrefix { @@ -96,35 +96,35 @@ internal class SuppressionSpec : Spek({ } } """) - val rule = TestRule(TestConfig(mutableMapOf("aliases" to "[MyTest]"))) - rule.visitFile(ktFile) - assertThat(rule.expected).isNotNull() - } - } + val rule = TestRule(TestConfig(mutableMapOf("aliases" to "[MyTest]"))) + rule.visitFile(ktFile) + assertThat(rule.expected).isNotNull() + } + } }) class TestRule(config: Config = Config.empty) : Rule(config) { - override val issue = Issue("Test", Severity.CodeSmell, "", Debt.TWENTY_MINS) - var expected: String? = "Test" - override fun visitClassOrObject(classOrObject: KtClassOrObject) { - expected = null - } + override val issue = Issue("Test", Severity.CodeSmell, "", Debt.TWENTY_MINS) + var expected: String? = "Test" + override fun visitClassOrObject(classOrObject: KtClassOrObject) { + expected = null + } } class TestLM : Rule() { - override val issue = Issue("LongMethod", Severity.CodeSmell, "", Debt.TWENTY_MINS) - override fun visitNamedFunction(function: KtNamedFunction) { - val start = Location.startLineAndColumn(function.funKeyword!!).line - val end = Location.startLineAndColumn(function.lastBlockStatementOrThis()).line - val offset = end - start - if (offset > 10) report(CodeSmell(issue, Entity.from(function), message = "")) - } + override val issue = Issue("LongMethod", Severity.CodeSmell, "", Debt.TWENTY_MINS) + override fun visitNamedFunction(function: KtNamedFunction) { + val start = Location.startLineAndColumn(function.funKeyword!!).line + val end = Location.startLineAndColumn(function.lastBlockStatementOrThis()).line + val offset = end - start + if (offset > 10) report(CodeSmell(issue, Entity.from(function), message = "")) + } } class TestLPL : Rule() { - override val issue = Issue("LongParameterList", Severity.CodeSmell, "", Debt.TWENTY_MINS) - override fun visitNamedFunction(function: KtNamedFunction) { - val size = function.valueParameters.size - if (size > 5) report(CodeSmell(issue, Entity.from(function), message = "")) - } + override val issue = Issue("LongParameterList", Severity.CodeSmell, "", Debt.TWENTY_MINS) + override fun visitNamedFunction(function: KtNamedFunction) { + val size = function.valueParameters.size + if (size > 5) report(CodeSmell(issue, Entity.from(function), message = "")) + } } diff --git a/detekt-api/src/test/resources/SuppressedByAllObject.kt b/detekt-api/src/test/resources/SuppressedByAllObject.kt index 8d1ee8b75..e8410f848 100644 --- a/detekt-api/src/test/resources/SuppressedByAllObject.kt +++ b/detekt-api/src/test/resources/SuppressedByAllObject.kt @@ -5,7 +5,7 @@ */ object SuppressedByAllObject { - fun stuff() { - println("FAILED TEST") - } + fun stuff() { + println("FAILED TEST") + } } diff --git a/detekt-api/src/test/resources/SuppressedElements.kt b/detekt-api/src/test/resources/SuppressedElements.kt index 946666a31..928e5c375 100644 --- a/detekt-api/src/test/resources/SuppressedElements.kt +++ b/detekt-api/src/test/resources/SuppressedElements.kt @@ -4,31 +4,31 @@ @SuppressWarnings("LongParameterList") fun lpl(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) = (a + b + c + d + e + f).apply { - assert(false) { "FAILED TEST" } + assert(false) { "FAILED TEST" } } @SuppressWarnings("LongMethod") fun lm() { - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - assert(false) { "FAILED TEST" } + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + assert(false) { "FAILED TEST" } } diff --git a/detekt-api/src/test/resources/SuppressedObject.kt b/detekt-api/src/test/resources/SuppressedObject.kt index 06e1d9825..5840b97e2 100644 --- a/detekt-api/src/test/resources/SuppressedObject.kt +++ b/detekt-api/src/test/resources/SuppressedObject.kt @@ -5,7 +5,7 @@ */ object SuppressedObject { - fun stuff() { - println("FAILED TEST") - } + fun stuff() { + println("FAILED TEST") + } } diff --git a/detekt-cli/build.gradle.kts b/detekt-cli/build.gradle.kts index 267a49e43..5133ff8d9 100644 --- a/detekt-cli/build.gradle.kts +++ b/detekt-cli/build.gradle.kts @@ -1,5 +1,5 @@ application { - mainClassName = "io.gitlab.arturbosch.detekt.cli.Main" + mainClassName = "io.gitlab.arturbosch.detekt.cli.Main" } val junitPlatformVersion: String by project @@ -12,23 +12,23 @@ val reflectionsVersion: String by project configurations.testImplementation.get().extendsFrom(configurations["kotlinTest"]) dependencies { - implementation(project(":detekt-core")) - runtimeOnly(project(":detekt-rules")) - implementation("com.beust:jcommander:$jcommanderVersion") - implementation(kotlin("compiler-embeddable")) + implementation(project(":detekt-core")) + runtimeOnly(project(":detekt-rules")) + implementation("com.beust:jcommander:$jcommanderVersion") + implementation(kotlin("compiler-embeddable")) - testImplementation(project(":detekt-test")) - testImplementation(project(":detekt-rules")) - testImplementation("org.reflections:reflections:$reflectionsVersion") - testRuntimeOnly("org.junit.platform:junit-platform-launcher:$junitPlatformVersion") - testRuntimeOnly("org.jetbrains.spek:spek-junit-platform-engine:$spekVersion") + testImplementation(project(":detekt-test")) + testImplementation(project(":detekt-rules")) + testImplementation("org.reflections:reflections:$reflectionsVersion") + testRuntimeOnly("org.junit.platform:junit-platform-launcher:$junitPlatformVersion") + testRuntimeOnly("org.jetbrains.spek:spek-junit-platform-engine:$spekVersion") } tasks["test"].dependsOn(":detekt-generator:generateDocumentation") // bundle detekt's version for debug logging on rule exceptions tasks.withType { - manifest { - attributes(mapOf("DetektVersion" to detektVersion)) - } + manifest { + attributes(mapOf("DetektVersion" to detektVersion)) + } } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/CliArgs.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/CliArgs.kt index d21d0b62b..0797e99c8 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/CliArgs.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/CliArgs.kt @@ -8,107 +8,107 @@ import java.nio.file.Path * @author Marvin Ramin */ interface Args { - var help: Boolean + var help: Boolean } class CliArgs : Args { - @Parameter(names = ["--input", "-i"], - description = "Input paths to analyze. Multiple paths are separated by comma. If not specified the " + - "current working directory is used.") - private var input: String? = null + @Parameter(names = ["--input", "-i"], + description = "Input paths to analyze. Multiple paths are separated by comma. If not specified the " + + "current working directory is used.") + private var input: String? = null - @Parameter(names = ["--filters", "-f"], - description = "Path filters defined through regex with separator ';' or ',' (\".*test.*\"). " + - "These filters apply on relative paths from the project root.") - var filters: String? = null // Using a converter for List resulted in a ClassCastException + @Parameter(names = ["--filters", "-f"], + description = "Path filters defined through regex with separator ';' or ',' (\".*test.*\"). " + + "These filters apply on relative paths from the project root.") + var filters: String? = null // Using a converter for List resulted in a ClassCastException - @Parameter(names = ["--config", "-c"], - description = "Path to the config file (path/to/config.yml). " + - "Multiple configuration files can be specified with ',' or ';' as separator.") - var config: String? = null + @Parameter(names = ["--config", "-c"], + description = "Path to the config file (path/to/config.yml). " + + "Multiple configuration files can be specified with ',' or ';' as separator.") + var config: String? = null - @Parameter(names = ["--config-resource", "-cr"], - description = "Path to the config resource on detekt's classpath (path/to/config.yml).") - var configResource: String? = null + @Parameter(names = ["--config-resource", "-cr"], + description = "Path to the config resource on detekt's classpath (path/to/config.yml).") + var configResource: String? = null - @Parameter(names = ["--generate-config", "-gc"], - description = "Export default config to default-detekt-config.yml.") - var generateConfig: Boolean = false + @Parameter(names = ["--generate-config", "-gc"], + description = "Export default config to default-detekt-config.yml.") + var generateConfig: Boolean = false - @Parameter(names = ["--plugins", "-p"], - description = "Extra paths to plugin jars separated by ',' or ';'.") - var plugins: String? = null + @Parameter(names = ["--plugins", "-p"], + description = "Extra paths to plugin jars separated by ',' or ';'.") + var plugins: String? = null - @Parameter(names = ["--parallel"], - description = "Enables parallel compilation of source files." + - " Should only be used if the analyzing project has more than ~200 kotlin files.") - var parallel: Boolean = false + @Parameter(names = ["--parallel"], + description = "Enables parallel compilation of source files." + + " Should only be used if the analyzing project has more than ~200 kotlin files.") + var parallel: Boolean = false - @Parameter(names = ["--baseline", "-b"], - description = "If a baseline xml file is passed in," + - " only new code smells not in the baseline are printed in the console.", - converter = PathConverter::class) - var baseline: Path? = null + @Parameter(names = ["--baseline", "-b"], + description = "If a baseline xml file is passed in," + + " only new code smells not in the baseline are printed in the console.", + converter = PathConverter::class) + var baseline: Path? = null - @Parameter(names = ["--create-baseline", "-cb"], - description = "Treats current analysis findings as a smell baseline for future detekt runs.") - var createBaseline: Boolean = false + @Parameter(names = ["--create-baseline", "-cb"], + description = "Treats current analysis findings as a smell baseline for future detekt runs.") + var createBaseline: Boolean = false - @Parameter(names = ["--report", "-r"], - description = "Generates a report for given 'report-id' and stores it on given 'path'. " + - "Entry should consist of: [report-id:path]. " + - "Available 'report-id' values: 'txt', 'xml', 'html'. " + - "These can also be used in combination with each other " + - "e.g. '-r txt:reports/detekt.txt -r xml:reports/detekt.xml'") - private var reports: List? = null + @Parameter(names = ["--report", "-r"], + description = "Generates a report for given 'report-id' and stores it on given 'path'. " + + "Entry should consist of: [report-id:path]. " + + "Available 'report-id' values: 'txt', 'xml', 'html'. " + + "These can also be used in combination with each other " + + "e.g. '-r txt:reports/detekt.txt -r xml:reports/detekt.xml'") + private var reports: List? = null - @Parameter(names = ["--disable-default-rulesets", "-dd"], - description = "Disables default rule sets.") - var disableDefaultRuleSets: Boolean = false + @Parameter(names = ["--disable-default-rulesets", "-dd"], + description = "Disables default rule sets.") + var disableDefaultRuleSets: Boolean = false - @Parameter(names = ["--build-upon-default-config"], - description = "Preconfigures detekt with a bunch of rules and some opinionated defaults for you. " + - "Allows additional provided configurations to override the defaults.") - var buildUponDefaultConfig: Boolean = false + @Parameter(names = ["--build-upon-default-config"], + description = "Preconfigures detekt with a bunch of rules and some opinionated defaults for you. " + + "Allows additional provided configurations to override the defaults.") + var buildUponDefaultConfig: Boolean = false - @Parameter(names = ["--fail-fast"], - description = "Shortcut for 'build-upon-default-config' together with all available rules active and " + - "exit code 0 only when no code smells are found. " + - "Additional configuration files can override properties but not the 'active' one.") - var failFast: Boolean = false + @Parameter(names = ["--fail-fast"], + description = "Shortcut for 'build-upon-default-config' together with all available rules active and " + + "exit code 0 only when no code smells are found. " + + "Additional configuration files can override properties but not the 'active' one.") + var failFast: Boolean = false - @Parameter(names = ["--debug"], - description = "Prints extra information about configurations and extensions.") - var debug: Boolean = false + @Parameter(names = ["--debug"], + description = "Prints extra information about configurations and extensions.") + var debug: Boolean = false - @Parameter(names = ["--help", "-h"], - help = true, description = "Shows the usage.") - override var help: Boolean = false + @Parameter(names = ["--help", "-h"], + help = true, description = "Shows the usage.") + override var help: Boolean = false - @Parameter(names = ["--run-rule"], - description = "Specify a rule by [RuleSet:Rule] pattern and run it on input.", - hidden = true) - var runRule: String? = null + @Parameter(names = ["--run-rule"], + description = "Specify a rule by [RuleSet:Rule] pattern and run it on input.", + hidden = true) + var runRule: String? = null - @Parameter(names = ["--print-ast"], - description = "Prints the AST for given [input] file. Must be no directory.", - hidden = true) - var printAst: Boolean = false + @Parameter(names = ["--print-ast"], + description = "Prints the AST for given [input] file. Must be no directory.", + hidden = true) + var printAst: Boolean = false - val inputPaths: List by lazy { - MultipleExistingPathConverter().convert(input ?: System.getProperty("user.dir")) - } + val inputPaths: List by lazy { + MultipleExistingPathConverter().convert(input ?: System.getProperty("user.dir")) + } - val reportPaths: List by lazy { - reports?.map { ReportPath.from(it) } ?: emptyList() - } + val reportPaths: List by lazy { + reports?.map { ReportPath.from(it) } ?: emptyList() + } - companion object { - /** - * When embedding the cli inside a tool, this closure style configuration - * of the arguments should be used. - */ - operator fun invoke(init: CliArgs.() -> Unit): CliArgs = CliArgs().apply(init) - } + companion object { + /** + * When embedding the cli inside a tool, this closure style configuration + * of the arguments should be used. + */ + operator fun invoke(init: CliArgs.() -> Unit): CliArgs = CliArgs().apply(init) + } } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/Configurations.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/Configurations.kt index 34a989156..712e00bc1 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/Configurations.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/Configurations.kt @@ -11,71 +11,71 @@ import java.nio.file.Path */ fun CliArgs.createPathFilters(): List = filters.letIfNonEmpty { - split(SEPARATOR_COMMA, SEPARATOR_SEMICOLON) - .asSequence() - .map { it.trim() } - .filter { it.isNotEmpty() } - .map { filter -> PathFilter(filter) } - .toList() + split(SEPARATOR_COMMA, SEPARATOR_SEMICOLON) + .asSequence() + .map { it.trim() } + .filter { it.isNotEmpty() } + .map { filter -> PathFilter(filter) } + .toList() } fun CliArgs.createPlugins(): List = plugins.letIfNonEmpty { - MultipleExistingPathConverter().convert(this) + MultipleExistingPathConverter().convert(this) } private fun String?.letIfNonEmpty(init: String.() -> List): List = - if (this == null || this.isEmpty()) listOf() else this.init() + if (this == null || this.isEmpty()) listOf() else this.init() fun CliArgs.loadConfiguration(): Config { - var declaredConfig: Config? = when { - !config.isNullOrBlank() -> parsePathConfig(config!!) - !configResource.isNullOrBlank() -> parseResourceConfig(configResource!!) - else -> null - } - var defaultConfig: Config? = null + var declaredConfig: Config? = when { + !config.isNullOrBlank() -> parsePathConfig(config!!) + !configResource.isNullOrBlank() -> parseResourceConfig(configResource!!) + else -> null + } + var defaultConfig: Config? = null - if (buildUponDefaultConfig) { - defaultConfig = loadDefaultConfig() - declaredConfig = CompositeConfig(declaredConfig ?: defaultConfig, defaultConfig) - } + if (buildUponDefaultConfig) { + defaultConfig = loadDefaultConfig() + declaredConfig = CompositeConfig(declaredConfig ?: defaultConfig, defaultConfig) + } - val failFastUsed = declaredConfig?.deprecatedFailFastUsage() ?: false - if (failFast || failFastUsed) { - val initializedDefaultConfig = defaultConfig ?: loadDefaultConfig() - declaredConfig = FailFastConfig(declaredConfig ?: initializedDefaultConfig, initializedDefaultConfig) - } + val failFastUsed = declaredConfig?.deprecatedFailFastUsage() ?: false + if (failFast || failFastUsed) { + val initializedDefaultConfig = defaultConfig ?: loadDefaultConfig() + declaredConfig = FailFastConfig(declaredConfig ?: initializedDefaultConfig, initializedDefaultConfig) + } - if (debug) println("\n$declaredConfig\n") - return declaredConfig ?: loadDefaultConfig() + if (debug) println("\n$declaredConfig\n") + return declaredConfig ?: loadDefaultConfig() } private fun Config.deprecatedFailFastUsage(): Boolean { - val value = valueOrDefault("failFast", false) - LOG.printer.println("Using deprecated property 'failFast' in the yaml config. " + - "Please migrate to the new '--fail-fast' cli-flag or 'failFast' detekt extension property.") - return value + val value = valueOrDefault("failFast", false) + LOG.printer.println("Using deprecated property 'failFast' in the yaml config. " + + "Please migrate to the new '--fail-fast' cli-flag or 'failFast' detekt extension property.") + return value } private fun parseResourceConfig(configPath: String): Config { - val urls = MultipleClasspathResourceConverter().convert(configPath) - return if (urls.size == 1) { - YamlConfig.loadResource(urls[0]) - } else { - urls.asSequence() - .map { YamlConfig.loadResource(it) } - .reduce { composite, config -> CompositeConfig(config, composite) } - } + val urls = MultipleClasspathResourceConverter().convert(configPath) + return if (urls.size == 1) { + YamlConfig.loadResource(urls[0]) + } else { + urls.asSequence() + .map { YamlConfig.loadResource(it) } + .reduce { composite, config -> CompositeConfig(config, composite) } + } } private fun parsePathConfig(configPath: String): Config { - val paths = MultipleExistingPathConverter().convert(configPath) - return if (paths.size == 1) { - YamlConfig.load(paths[0]) - } else { - paths.asSequence() - .map { YamlConfig.load(it) } - .reduce { composite, config -> CompositeConfig(config, composite) } - } + val paths = MultipleExistingPathConverter().convert(configPath) + return if (paths.size == 1) { + YamlConfig.load(paths[0]) + } else { + paths.asSequence() + .map { YamlConfig.load(it) } + .reduce { composite, config -> CompositeConfig(config, composite) } + } } private fun loadDefaultConfig() = YamlConfig.loadResource(ClasspathResourceConverter().convert(DEFAULT_CONFIG)) diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/DetektProgressListener.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/DetektProgressListener.kt index dc28acaf1..3cb4167f6 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/DetektProgressListener.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/DetektProgressListener.kt @@ -9,12 +9,12 @@ import org.jetbrains.kotlin.psi.KtFile */ class DetektProgressListener : FileProcessListener { - override fun onProcess(file: KtFile) { - kotlin.io.print(".") - } + override fun onProcess(file: KtFile) { + kotlin.io.print(".") + } - override fun onFinish(files: List, result: Detektion) { - val middlePart = if (files.size == 1) "file was" else "files were" - kotlin.io.println("\n\n${files.size} kotlin $middlePart analyzed.") - } + override fun onFinish(files: List, result: Detektion) { + val middlePart = if (files.size == 1) "file was" else "files were" + kotlin.io.println("\n\n${files.size} kotlin $middlePart analyzed.") + } } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/FailFastConfig.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/FailFastConfig.kt index 18d887d47..86796f6c6 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/FailFastConfig.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/FailFastConfig.kt @@ -7,21 +7,21 @@ import io.gitlab.arturbosch.detekt.api.Config */ @Suppress("UNCHECKED_CAST") data class FailFastConfig(private val originalConfig: Config, private val defaultConfig: Config) : Config { - override fun subConfig(key: String) = FailFastConfig(originalConfig.subConfig(key), defaultConfig.subConfig(key)) + override fun subConfig(key: String) = FailFastConfig(originalConfig.subConfig(key), defaultConfig.subConfig(key)) - override fun valueOrDefault(key: String, default: T): T { - return when (key) { - "active" -> originalConfig.valueOrDefault(key, true) as T - "maxIssues" -> originalConfig.valueOrDefault(key, 0) as T - else -> originalConfig.valueOrDefault(key, defaultConfig.valueOrDefault(key, default)) - } - } + override fun valueOrDefault(key: String, default: T): T { + return when (key) { + "active" -> originalConfig.valueOrDefault(key, true) as T + "maxIssues" -> originalConfig.valueOrDefault(key, 0) as T + else -> originalConfig.valueOrDefault(key, defaultConfig.valueOrDefault(key, default)) + } + } - override fun valueOrNull(key: String): T? { - return when (key) { - "active" -> true as? T - "maxIssues" -> 0 as? T - else -> originalConfig.valueOrNull(key) ?: defaultConfig.valueOrNull(key) - } - } + override fun valueOrNull(key: String): T? { + return when (key) { + "active" -> true as? T + "maxIssues" -> 0 as? T + else -> originalConfig.valueOrNull(key) ?: defaultConfig.valueOrNull(key) + } + } } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/FilteredDetectionResult.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/FilteredDetectionResult.kt index 91d86a4f6..22322b92c 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/FilteredDetectionResult.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/FilteredDetectionResult.kt @@ -10,13 +10,13 @@ import io.gitlab.arturbosch.detekt.cli.baseline.BaselineFacade */ class FilteredDetectionResult(detektion: Detektion, baselineFacade: BaselineFacade) : Detektion by detektion { - private val filteredFindings: Map> + private val filteredFindings: Map> - init { - filteredFindings = detektion.findings - .map { (key, value) -> key to baselineFacade.filter(value) } - .toMap() - } + init { + filteredFindings = detektion.findings + .map { (key, value) -> key to baselineFacade.filter(value) } + .toMap() + } - override val findings = filteredFindings + override val findings = filteredFindings } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/JCommander.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/JCommander.kt index bb6293fc9..fe6020869 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/JCommander.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/JCommander.kt @@ -4,39 +4,39 @@ import com.beust.jcommander.JCommander import com.beust.jcommander.ParameterException inline fun parseArguments(args: Array): Pair { - val cli = T::class.java.declaredConstructors.firstOrNull()?.newInstance() as? T - ?: throw IllegalStateException("Could not create Args object for class ${T::class.java}") + val cli = T::class.java.declaredConstructors.firstOrNull()?.newInstance() as? T + ?: throw IllegalStateException("Could not create Args object for class ${T::class.java}") - val jCommander = JCommander() + val jCommander = JCommander() - jCommander.addObject(cli) - jCommander.programName = "detekt" + jCommander.addObject(cli) + jCommander.programName = "detekt" - try { - @Suppress("SpreadOperator") - jCommander.parse(*args) - } catch (ex: ParameterException) { - val message = ex.message - jCommander.failWithErrorMessages(message) - } + try { + @Suppress("SpreadOperator") + jCommander.parse(*args) + } catch (ex: ParameterException) { + val message = ex.message + jCommander.failWithErrorMessages(message) + } - if (cli.help) { - jCommander.usage() - System.exit(0) - } + if (cli.help) { + jCommander.usage() + System.exit(0) + } - return cli to jCommander + return cli to jCommander } fun JCommander.failWithErrorMessages(vararg messages: String?) { - failWithErrorMessages(messages.asIterable()) + failWithErrorMessages(messages.asIterable()) } fun JCommander.failWithErrorMessages(messages: Iterable) { - messages.forEach { - println(it) - } - println() - this.usage() - System.exit(-1) + messages.forEach { + println(it) + } + println() + this.usage() + System.exit(-1) } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/Junk.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/Junk.kt index a4bea7067..ebec9b76e 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/Junk.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/Junk.kt @@ -4,18 +4,18 @@ import io.gitlab.arturbosch.detekt.api.Finding import java.util.HashMap val Finding.baselineId: String - get() = this.id + ":" + this.signature + get() = this.id + ":" + this.signature const val SEPARATOR_COMMA = "," const val SEPARATOR_SEMICOLON = ";" inline fun Collection.toHashMap( - keyFunction: (T) -> K, - valueFunction: (T) -> V + keyFunction: (T) -> K, + valueFunction: (T) -> V ): HashMap { - val result = HashMap() - for (element in this) { - result[keyFunction(element)] = valueFunction(element) - } - return result + val result = HashMap() + for (element in this) { + result[keyFunction(element)] = valueFunction(element) + } + return result } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/LOG.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/LOG.kt index 8762f3479..ed93db4dd 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/LOG.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/LOG.kt @@ -7,18 +7,18 @@ import java.io.PrintStream */ object LOG { - var printer: PrintStream = System.out - var active: Boolean = false + var printer: PrintStream = System.out + var active: Boolean = false - fun debug(message: String) { - if (active) { - printer.println(message) - } - } + fun debug(message: String) { + if (active) { + printer.println(message) + } + } - fun debug(message: () -> String) { - if (active) { - printer.println(message.invoke()) - } - } + fun debug(message: () -> String) { + if (active) { + printer.println(message.invoke()) + } + } } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/Main.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/Main.kt index 22fff4fcd..e1b70fcde 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/Main.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/Main.kt @@ -13,32 +13,32 @@ import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty * @author Marvin Ramin */ fun main(args: Array) { - val arguments = parseArguments(args) - LOG.active = arguments.debug - val executable = when { - arguments.generateConfig -> ConfigExporter() - arguments.runRule != null -> SingleRuleRunner(arguments) - arguments.printAst -> AstPrinter(arguments) - else -> Runner(arguments) - } - executable.execute() + val arguments = parseArguments(args) + LOG.active = arguments.debug + val executable = when { + arguments.generateConfig -> ConfigExporter() + arguments.runRule != null -> SingleRuleRunner(arguments) + arguments.printAst -> AstPrinter(arguments) + else -> Runner(arguments) + } + executable.execute() } private fun parseArguments(args: Array): CliArgs { - val (arguments, jcommander) = parseArguments(args) - val messages = validateCli(arguments) - messages.ifNotEmpty { - jcommander.failWithErrorMessages(messages) - } - return arguments + val (arguments, jcommander) = parseArguments(args) + val messages = validateCli(arguments) + messages.ifNotEmpty { + jcommander.failWithErrorMessages(messages) + } + return arguments } private fun validateCli(arguments: CliArgs): List { - val violations = ArrayList() - with(arguments) { - if (createBaseline && baseline == null) { - violations += "Creating a baseline.xml requires the --baseline parameter to specify a path." - } - } - return violations + val violations = ArrayList() + with(arguments) { + if (createBaseline && baseline == null) { + violations += "Creating a baseline.xml requires the --baseline parameter to specify a path." + } + } + return violations } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/OutputFacade.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/OutputFacade.kt index 1ac16c7d2..d4327fd9a 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/OutputFacade.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/OutputFacade.kt @@ -11,50 +11,52 @@ import io.gitlab.arturbosch.detekt.core.ProcessingSettings * @author Artur Bosch * @author Marvin Ramin */ -class OutputFacade(arguments: CliArgs, - private val detektion: Detektion, - private val settings: ProcessingSettings) { +class OutputFacade( + arguments: CliArgs, + private val detektion: Detektion, + private val settings: ProcessingSettings +) { - private val printStream = settings.outPrinter - private val config = settings.config - private val baselineFacade = arguments.baseline?.let { BaselineFacade(it) } - private val createBaseline = arguments.createBaseline - private val reportPaths = arguments.reportPaths.toHashMap({ it.kind }, { it.path }) + private val printStream = settings.outPrinter + private val config = settings.config + private val baselineFacade = arguments.baseline?.let { BaselineFacade(it) } + private val createBaseline = arguments.createBaseline + private val reportPaths = arguments.reportPaths.toHashMap({ it.kind }, { it.path }) - fun run() { - if (createBaseline) { - val smells = detektion.findings.flatMap { it.value } - baselineFacade?.create(smells) - } + fun run() { + if (createBaseline) { + val smells = detektion.findings.flatMap { it.value } + baselineFacade?.create(smells) + } - val result = if (baselineFacade != null) { - FilteredDetectionResult(detektion, baselineFacade) - } else detektion + val result = if (baselineFacade != null) { + FilteredDetectionResult(detektion, baselineFacade) + } else detektion - val reports = ReportLocator(settings) - .load() - .filterNot { createBaseline && it is BuildFailureReport } - .sortedBy { it.priority } - .asReversed() + val reports = ReportLocator(settings) + .load() + .filterNot { createBaseline && it is BuildFailureReport } + .sortedBy { it.priority } + .asReversed() - reports.forEach { report -> - report.init(config) - when (report) { - is ConsoleReport -> handleConsoleReport(report, result) - is OutputReport -> handleOutputReport(report, result) - } - } - } + reports.forEach { report -> + report.init(config) + when (report) { + is ConsoleReport -> handleConsoleReport(report, result) + is OutputReport -> handleOutputReport(report, result) + } + } + } - private fun handleOutputReport(report: OutputReport, result: Detektion) { - val filePath = reportPaths[report.id] - if (filePath != null) { - report.write(filePath, result) - printStream.println("Successfully generated ${report.name} at $filePath") - } - } + private fun handleOutputReport(report: OutputReport, result: Detektion) { + val filePath = reportPaths[report.id] + if (filePath != null) { + report.write(filePath, result) + printStream.println("Successfully generated ${report.name} at $filePath") + } + } - private fun handleConsoleReport(report: ConsoleReport, result: Detektion) { - report.print(printStream, result) - } + private fun handleConsoleReport(report: ConsoleReport, result: Detektion) { + report.print(printStream, result) + } } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/PathConverters.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/PathConverters.kt index 767ae95f7..d781b1bb6 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/PathConverters.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/PathConverters.kt @@ -13,46 +13,46 @@ import java.nio.file.Paths * @author Marvin Ramin */ class ExistingPathConverter : IStringConverter { - override fun convert(value: String): Path { - val config = File(value).toPath() - if (Files.notExists(config)) - throw ParameterException("Provided path '$value' does not exist!") - return config - } + override fun convert(value: String): Path { + val config = File(value).toPath() + if (Files.notExists(config)) + throw ParameterException("Provided path '$value' does not exist!") + return config + } } class PathConverter : IStringConverter { - override fun convert(value: String): Path { - return Paths.get(value) - } + override fun convert(value: String): Path { + return Paths.get(value) + } } interface DetektInputPathConverter : IStringConverter> { - val converter: IStringConverter - override fun convert(value: String): List = - value.splitToSequence(SEPARATOR_COMMA, SEPARATOR_SEMICOLON) - .map { it.trim() } - .map { converter.convert(it) } - .toList().apply { - if (isEmpty()) throw IllegalStateException("Given input '$value' was impossible to parse!") - } + val converter: IStringConverter + override fun convert(value: String): List = + value.splitToSequence(SEPARATOR_COMMA, SEPARATOR_SEMICOLON) + .map { it.trim() } + .map { converter.convert(it) } + .toList().apply { + if (isEmpty()) throw IllegalStateException("Given input '$value' was impossible to parse!") + } } class MultipleClasspathResourceConverter : DetektInputPathConverter { - override val converter = ClasspathResourceConverter() + override val converter = ClasspathResourceConverter() } class MultipleExistingPathConverter : DetektInputPathConverter { - override val converter = ExistingPathConverter() + override val converter = ExistingPathConverter() } /** * @author Sean Flanigan sflaniga@redhat.com */ class ClasspathResourceConverter : IStringConverter { - override fun convert(resource: String): URL { - val relativeResource = if (resource.startsWith("/")) resource else "/$resource" - return javaClass.getResource(relativeResource) - ?: throw ParameterException("Classpath resource '$resource' does not exist!") - } + override fun convert(resource: String): URL { + val relativeResource = if (resource.startsWith("/")) resource else "/$resource" + return javaClass.getResource(relativeResource) + ?: throw ParameterException("Classpath resource '$resource' does not exist!") + } } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/ReportLocator.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/ReportLocator.kt index 9bce98da1..581267917 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/ReportLocator.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/ReportLocator.kt @@ -12,45 +12,45 @@ import java.util.ServiceLoader */ class ReportLocator(private val settings: ProcessingSettings) { - private val consoleSubConfig = settings.config.subConfig("console-reports") - private val consoleActive = consoleSubConfig.valueOrDefault(ACTIVE, true) - private val consoleExcludes = consoleSubConfig.valueOrDefault(EXCLUDE, emptyList()).toSet() + private val consoleSubConfig = settings.config.subConfig("console-reports") + private val consoleActive = consoleSubConfig.valueOrDefault(ACTIVE, true) + private val consoleExcludes = consoleSubConfig.valueOrDefault(EXCLUDE, emptyList()).toSet() - private val outputSubConfig = settings.config.subConfig("output-reports") - private val outputActive = outputSubConfig.valueOrDefault(ACTIVE, true) - private val outputExcludes = outputSubConfig.valueOrDefault(EXCLUDE, emptyList()).toSet() + private val outputSubConfig = settings.config.subConfig("output-reports") + private val outputActive = outputSubConfig.valueOrDefault(ACTIVE, true) + private val outputExcludes = outputSubConfig.valueOrDefault(EXCLUDE, emptyList()).toSet() - fun load(): List { - LOG.debug("console-report=$consoleActive") - LOG.debug("output-report=$outputActive") - val detektLoader = URLClassLoader(settings.pluginUrls, javaClass.classLoader) - val consoleReports = loadConsoleReports(detektLoader) - LOG.debug { "ConsoleReports: $consoleReports" } - val outputReports = loadOutputReports(detektLoader) - LOG.debug { "OutputReports: $outputReports" } - return consoleReports.plus(outputReports) - } + fun load(): List { + LOG.debug("console-report=$consoleActive") + LOG.debug("output-report=$outputActive") + val detektLoader = URLClassLoader(settings.pluginUrls, javaClass.classLoader) + val consoleReports = loadConsoleReports(detektLoader) + LOG.debug { "ConsoleReports: $consoleReports" } + val outputReports = loadOutputReports(detektLoader) + LOG.debug { "OutputReports: $outputReports" } + return consoleReports.plus(outputReports) + } - private fun loadOutputReports(detektLoader: URLClassLoader) = - if (outputActive) { - ServiceLoader.load(OutputReport::class.java, detektLoader) - .filter { it.id !in outputExcludes } - .toList() - } else { - emptyList() - } + private fun loadOutputReports(detektLoader: URLClassLoader) = + if (outputActive) { + ServiceLoader.load(OutputReport::class.java, detektLoader) + .filter { it.id !in outputExcludes } + .toList() + } else { + emptyList() + } - private fun loadConsoleReports(detektLoader: URLClassLoader) = - if (consoleActive) { - ServiceLoader.load(ConsoleReport::class.java, detektLoader) - .filter { it.id !in consoleExcludes } - .toList() - } else { - emptyList() - } + private fun loadConsoleReports(detektLoader: URLClassLoader) = + if (consoleActive) { + ServiceLoader.load(ConsoleReport::class.java, detektLoader) + .filter { it.id !in consoleExcludes } + .toList() + } else { + emptyList() + } - companion object { - private const val ACTIVE = "active" - private const val EXCLUDE = "exclude" - } + companion object { + private const val ACTIVE = "active" + private const val EXCLUDE = "exclude" + } } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/ReportPath.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/ReportPath.kt index bdece6da2..7465f35c5 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/ReportPath.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/ReportPath.kt @@ -12,40 +12,40 @@ import java.nio.file.Paths */ data class ReportPath(val kind: String, val path: Path) { - companion object { - private const val NUM_OF_PARTS_UNIX = 2 - private const val NUM_OF_PARTS_WINDOWS = 3 - private const val REPORT_PATH_SEPARATOR = ":" - private const val ILLEGAL_PARTS_SIZE_ERROR = - "Must consist of two parts for Unix OSs or three for Windows (report-id:path)." + companion object { + private const val NUM_OF_PARTS_UNIX = 2 + private const val NUM_OF_PARTS_WINDOWS = 3 + private const val REPORT_PATH_SEPARATOR = ":" + private const val ILLEGAL_PARTS_SIZE_ERROR = + "Must consist of two parts for Unix OSs or three for Windows (report-id:path)." - fun from(input: String): ReportPath { - val parts = input.split(REPORT_PATH_SEPARATOR) - val partsSize = parts.size + fun from(input: String): ReportPath { + val parts = input.split(REPORT_PATH_SEPARATOR) + val partsSize = parts.size - require(partsSize == NUM_OF_PARTS_UNIX || partsSize == NUM_OF_PARTS_WINDOWS) { ILLEGAL_PARTS_SIZE_ERROR } + require(partsSize == NUM_OF_PARTS_UNIX || partsSize == NUM_OF_PARTS_WINDOWS) { ILLEGAL_PARTS_SIZE_ERROR } - val kind = parts[0] - val path = when (partsSize) { - NUM_OF_PARTS_UNIX -> parts[1] - NUM_OF_PARTS_WINDOWS -> parts.slice(1 until partsSize).joinToString(REPORT_PATH_SEPARATOR) - else -> throw IllegalStateException(ILLEGAL_PARTS_SIZE_ERROR) - } + val kind = parts[0] + val path = when (partsSize) { + NUM_OF_PARTS_UNIX -> parts[1] + NUM_OF_PARTS_WINDOWS -> parts.slice(1 until partsSize).joinToString(REPORT_PATH_SEPARATOR) + else -> throw IllegalStateException(ILLEGAL_PARTS_SIZE_ERROR) + } - assertNotEmpty(kind, path) - return ReportPath(defaultMapping(kind), Paths.get(path)) - } + assertNotEmpty(kind, path) + return ReportPath(defaultMapping(kind), Paths.get(path)) + } - private fun assertNotEmpty(kind: String, path: String) { - require(kind.isNotEmpty()) { "The kind of report must not be empty" } - require(path.isNotEmpty()) { "The path of the report must not be empty" } - } + private fun assertNotEmpty(kind: String, path: String) { + require(kind.isNotEmpty()) { "The kind of report must not be empty" } + require(path.isNotEmpty()) { "The path of the report must not be empty" } + } - private fun defaultMapping(reportId: String) = when (reportId) { - "txt" -> TxtOutputReport::class.java.simpleName - "xml" -> XmlOutputReport::class.java.simpleName - "html" -> HtmlOutputReport::class.java.simpleName - else -> reportId - } - } + private fun defaultMapping(reportId: String) = when (reportId) { + "txt" -> TxtOutputReport::class.java.simpleName + "xml" -> XmlOutputReport::class.java.simpleName + "html" -> HtmlOutputReport::class.java.simpleName + else -> reportId + } + } } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/Baseline.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/Baseline.kt index fc2353d9a..7cec19a74 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/Baseline.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/Baseline.kt @@ -5,9 +5,9 @@ package io.gitlab.arturbosch.detekt.cli.baseline */ data class Baseline(val blacklist: Blacklist, val whitelist: Whitelist) { - override fun toString(): String { - return "Baseline(blacklist=$blacklist, whitelist=$whitelist)" - } + override fun toString(): String { + return "Baseline(blacklist=$blacklist, whitelist=$whitelist)" + } } const val SMELL_BASELINE = "SmellBaseline" diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/BaselineFacade.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/BaselineFacade.kt index 1365fd29f..16d178c0d 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/BaselineFacade.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/BaselineFacade.kt @@ -13,32 +13,32 @@ import java.time.Instant */ class BaselineFacade(val baselineFile: Path) { - private val listings: Pair? = - if (baselineExists()) { - val format = BaselineFormat().read(baselineFile) - format.whitelist to format.blacklist - } else null + private val listings: Pair? = + if (baselineExists()) { + val format = BaselineFormat().read(baselineFile) + format.whitelist to format.blacklist + } else null - fun filter(smells: List) = - if (listings != null) { - val whiteFiltered = smells.filterNot { finding -> listings.first.ids.contains(finding.baselineId) } - val blackFiltered = whiteFiltered.filterNot { finding -> listings.second.ids.contains(finding.baselineId) } - blackFiltered - } else smells + fun filter(smells: List) = + if (listings != null) { + val whiteFiltered = smells.filterNot { finding -> listings.first.ids.contains(finding.baselineId) } + val blackFiltered = whiteFiltered.filterNot { finding -> listings.second.ids.contains(finding.baselineId) } + blackFiltered + } else smells - fun create(smells: List) { - val timestamp = Instant.now().toEpochMilli().toString() - val blacklist = if (baselineExists()) { - BaselineFormat().read(baselineFile).blacklist - } else { - Blacklist(emptySet(), timestamp) - } - val ids = smells.map { it.baselineId }.toSortedSet() - val smellBaseline = Baseline(blacklist, Whitelist(ids, timestamp)) - baselineFile.parent?.let { Files.createDirectories(it) } - BaselineFormat().write(smellBaseline, baselineFile) - println("Successfully wrote smell baseline to $baselineFile") - } + fun create(smells: List) { + val timestamp = Instant.now().toEpochMilli().toString() + val blacklist = if (baselineExists()) { + BaselineFormat().read(baselineFile).blacklist + } else { + Blacklist(emptySet(), timestamp) + } + val ids = smells.map { it.baselineId }.toSortedSet() + val smellBaseline = Baseline(blacklist, Whitelist(ids, timestamp)) + baselineFile.parent?.let { Files.createDirectories(it) } + BaselineFormat().write(smellBaseline, baselineFile) + println("Successfully wrote smell baseline to $baselineFile") + } - private fun baselineExists() = baselineFile.exists() && baselineFile.isFile() + private fun baselineExists() = baselineFile.exists() && baselineFile.isFile() } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/BaselineFormat.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/BaselineFormat.kt index 054dee047..8c811ab89 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/BaselineFormat.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/BaselineFormat.kt @@ -1,59 +1,59 @@ package io.gitlab.arturbosch.detekt.cli.baseline -import org.xml.sax.SAXParseException import java.nio.file.Files import java.nio.file.Path import javax.xml.parsers.SAXParserFactory import javax.xml.stream.XMLStreamException import javax.xml.stream.XMLStreamWriter +import org.xml.sax.SAXParseException /** * @author Artur Bosch */ class BaselineFormat { - fun read(path: Path): Baseline { - try { - Files.newInputStream(path).use { - val reader = SAXParserFactory.newInstance().newSAXParser() - val handler = BaselineHandler() - reader.parse(it, handler) - return handler.createBaseline() - } - } catch (error: SAXParseException) { - val (line, column) = error.lineNumber to error.columnNumber - throw InvalidBaselineState("Error on position $line:$column while reading the baseline xml file!", error) - } - } + fun read(path: Path): Baseline { + try { + Files.newInputStream(path).use { + val reader = SAXParserFactory.newInstance().newSAXParser() + val handler = BaselineHandler() + reader.parse(it, handler) + return handler.createBaseline() + } + } catch (error: SAXParseException) { + val (line, column) = error.lineNumber to error.columnNumber + throw InvalidBaselineState("Error on position $line:$column while reading the baseline xml file!", error) + } + } - fun write(baseline: Baseline, path: Path) { - try { - Files.newBufferedWriter(path).use { - it.streamXml().prettyPrinter().save(baseline) - } - } catch (error: XMLStreamException) { - val (line, column) = error.positions - throw InvalidBaselineState("Error on position $line:$column while writing the baseline xml file!", error) - } - } + fun write(baseline: Baseline, path: Path) { + try { + Files.newBufferedWriter(path).use { + it.streamXml().prettyPrinter().save(baseline) + } + } catch (error: XMLStreamException) { + val (line, column) = error.positions + throw InvalidBaselineState("Error on position $line:$column while writing the baseline xml file!", error) + } + } - private val XMLStreamException.positions - get() = location.lineNumber to location.columnNumber + private val XMLStreamException.positions + get() = location.lineNumber to location.columnNumber - private fun XMLStreamWriter.save(baseline: Baseline) { - document { - tag(SMELL_BASELINE) { - tag(BLACKLIST) { - val (ids, timestamp) = baseline.blacklist - attribute(TIMESTAMP, timestamp) - ids.forEach { tag(ID, it) } - } - tag(WHITELIST) { - val (ids, timestamp) = baseline.whitelist - attribute(TIMESTAMP, timestamp) - ids.forEach { tag(ID, it) } - } - } - } - } + private fun XMLStreamWriter.save(baseline: Baseline) { + document { + tag(SMELL_BASELINE) { + tag(BLACKLIST) { + val (ids, timestamp) = baseline.blacklist + attribute(TIMESTAMP, timestamp) + ids.forEach { tag(ID, it) } + } + tag(WHITELIST) { + val (ids, timestamp) = baseline.whitelist + attribute(TIMESTAMP, timestamp) + ids.forEach { tag(ID, it) } + } + } + } + } } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/BaselineHandler.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/BaselineHandler.kt index 51af76280..454fe293f 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/BaselineHandler.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/BaselineHandler.kt @@ -1,54 +1,54 @@ package io.gitlab.arturbosch.detekt.cli.baseline +import java.time.Instant import org.xml.sax.Attributes import org.xml.sax.helpers.DefaultHandler -import java.time.Instant /** * @author Artur Bosch */ class BaselineHandler : DefaultHandler() { - private var current: String? = null - private var content: String = "" - private var whitestamp: String? = null - private var blackstamp: String? = null - private val whiteIds = mutableSetOf() - private val blackIds = mutableSetOf() + private var current: String? = null + private var content: String = "" + private var whitestamp: String? = null + private var blackstamp: String? = null + private val whiteIds = mutableSetOf() + private val blackIds = mutableSetOf() - internal fun createBaseline() = Baseline( - Blacklist(blackIds, blackstamp ?: now()), Whitelist(whiteIds, whitestamp ?: now())) + internal fun createBaseline() = Baseline( + Blacklist(blackIds, blackstamp ?: now()), Whitelist(whiteIds, whitestamp ?: now())) - private fun now() = Instant.now().toEpochMilli().toString() + private fun now() = Instant.now().toEpochMilli().toString() - override fun startElement(uri: String, localName: String, qName: String, attributes: Attributes) { - when (qName) { - BLACKLIST -> { - current = BLACKLIST - blackstamp = attributes.getValue(TIMESTAMP) - } - WHITELIST -> { - current = WHITELIST - whitestamp = attributes.getValue(TIMESTAMP) - } - ID -> content = "" - } - } + override fun startElement(uri: String, localName: String, qName: String, attributes: Attributes) { + when (qName) { + BLACKLIST -> { + current = BLACKLIST + blackstamp = attributes.getValue(TIMESTAMP) + } + WHITELIST -> { + current = WHITELIST + whitestamp = attributes.getValue(TIMESTAMP) + } + ID -> content = "" + } + } - override fun endElement(uri: String, localName: String, qName: String) { - when (qName) { - ID -> if (content.isNotBlank()) { - when (current) { - BLACKLIST -> blackIds.add(content) - WHITELIST -> whiteIds.add(content) - } - content = "" - } - BLACKLIST, WHITELIST -> current == null - } - } + override fun endElement(uri: String, localName: String, qName: String) { + when (qName) { + ID -> if (content.isNotBlank()) { + when (current) { + BLACKLIST -> blackIds.add(content) + WHITELIST -> whiteIds.add(content) + } + content = "" + } + BLACKLIST, WHITELIST -> current == null + } + } - override fun characters(ch: CharArray, start: Int, length: Int) { - if (current != null) content += String(ch, start, length) - } + override fun characters(ch: CharArray, start: Int, length: Int) { + if (current != null) content += String(ch, start, length) + } } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/Blacklist.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/Blacklist.kt index 1459b2030..b4868523e 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/Blacklist.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/Blacklist.kt @@ -3,13 +3,17 @@ package io.gitlab.arturbosch.detekt.cli.baseline /** * @author Artur Bosch */ -data class Blacklist(override val ids: Set, - override val timestamp: String) : Listing { +data class Blacklist( + override val ids: Set, + override val timestamp: String +) : Listing { - override fun withNewTimestamp(timestamp: String, - list: Blacklist) = Blacklist(list.ids, timestamp) + override fun withNewTimestamp( + timestamp: String, + list: Blacklist + ) = Blacklist(list.ids, timestamp) - override fun toString(): String { - return "Blacklist(ids=$ids, timestamp='$timestamp')" - } + override fun toString(): String { + return "Blacklist(ids=$ids, timestamp='$timestamp')" + } } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/IndentingXMLStreamWriter.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/IndentingXMLStreamWriter.kt index 93a6ccc14..2e33cc324 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/IndentingXMLStreamWriter.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/IndentingXMLStreamWriter.kt @@ -8,119 +8,119 @@ import javax.xml.stream.XMLStreamWriter */ @Suppress("TooManyFunctions") class IndentingXMLStreamWriter( - writer: XMLStreamWriter, - private val indent: String = " " + writer: XMLStreamWriter, + private val indent: String = " " ) : DelegatingXMLStreamWriter(writer) { - private var currentState = NOTHING - private val stateStack = Stack() + private var currentState = NOTHING + private val stateStack = Stack() - private var indentationDepth = 0 + private var indentationDepth = 0 - private fun onStartTag() { - stateStack.push(TAG) - currentState = NOTHING - writeNL() - writeIndent() - indentationDepth++ - } + private fun onStartTag() { + stateStack.push(TAG) + currentState = NOTHING + writeNL() + writeIndent() + indentationDepth++ + } - private fun onEndTag() { - indentationDepth-- - if (currentState === TAG) { - super.writeCharacters("\n") - writeIndent() - } - currentState = stateStack.pop() - } + private fun onEndTag() { + indentationDepth-- + if (currentState === TAG) { + super.writeCharacters("\n") + writeIndent() + } + currentState = stateStack.pop() + } - private fun onEmptyTag() { - currentState = TAG - writeNL() - writeIndent() - } + private fun onEmptyTag() { + currentState = TAG + writeNL() + writeIndent() + } - private fun writeNL() { - if (indentationDepth > 0) { - super.writeCharacters("\n") - } - } + private fun writeNL() { + if (indentationDepth > 0) { + super.writeCharacters("\n") + } + } - @Suppress("RedundantLambdaArrow") - private fun writeIndent() { - if (indentationDepth > 0) { - (0 until indentationDepth).forEach { _ -> super.writeCharacters(indent) } - } - } + @Suppress("RedundantLambdaArrow") + private fun writeIndent() { + if (indentationDepth > 0) { + (0 until indentationDepth).forEach { _ -> super.writeCharacters(indent) } + } + } - override fun writeStartDocument() { - super.writeStartDocument() - super.writeCharacters("\n") - } + override fun writeStartDocument() { + super.writeStartDocument() + super.writeCharacters("\n") + } - override fun writeStartDocument(version: String) { - super.writeStartDocument(version) - super.writeCharacters("\n") - } + override fun writeStartDocument(version: String) { + super.writeStartDocument(version) + super.writeCharacters("\n") + } - override fun writeStartDocument(encoding: String, version: String) { - super.writeStartDocument(encoding, version) - super.writeCharacters("\n") - } + override fun writeStartDocument(encoding: String, version: String) { + super.writeStartDocument(encoding, version) + super.writeCharacters("\n") + } - override fun writeStartElement(localName: String) { - onStartTag() - super.writeStartElement(localName) - } + override fun writeStartElement(localName: String) { + onStartTag() + super.writeStartElement(localName) + } - override fun writeStartElement(namespaceURI: String, localName: String) { - onStartTag() - super.writeStartElement(namespaceURI, localName) - } + override fun writeStartElement(namespaceURI: String, localName: String) { + onStartTag() + super.writeStartElement(namespaceURI, localName) + } - override fun writeStartElement(prefix: String, localName: String, namespaceURI: String) { - onStartTag() - super.writeStartElement(prefix, localName, namespaceURI) - } + override fun writeStartElement(prefix: String, localName: String, namespaceURI: String) { + onStartTag() + super.writeStartElement(prefix, localName, namespaceURI) + } - override fun writeEmptyElement(namespaceURI: String, localName: String) { - onEmptyTag() - super.writeEmptyElement(namespaceURI, localName) - } + override fun writeEmptyElement(namespaceURI: String, localName: String) { + onEmptyTag() + super.writeEmptyElement(namespaceURI, localName) + } - override fun writeEmptyElement(prefix: String, localName: String, namespaceURI: String) { - onEmptyTag() - super.writeEmptyElement(prefix, localName, namespaceURI) - } + override fun writeEmptyElement(prefix: String, localName: String, namespaceURI: String) { + onEmptyTag() + super.writeEmptyElement(prefix, localName, namespaceURI) + } - override fun writeEmptyElement(localName: String) { - onEmptyTag() - super.writeEmptyElement(localName) - } + override fun writeEmptyElement(localName: String) { + onEmptyTag() + super.writeEmptyElement(localName) + } - override fun writeEndElement() { - onEndTag() - super.writeEndElement() - } + override fun writeEndElement() { + onEndTag() + super.writeEndElement() + } - override fun writeCharacters(text: String) { - currentState = DATA - super.writeCharacters(text) - } + override fun writeCharacters(text: String) { + currentState = DATA + super.writeCharacters(text) + } - override fun writeCharacters(text: CharArray, start: Int, len: Int) { - currentState = DATA - super.writeCharacters(text, start, len) - } + override fun writeCharacters(text: CharArray, start: Int, len: Int) { + currentState = DATA + super.writeCharacters(text, start, len) + } - override fun writeCData(data: String) { - currentState = DATA - super.writeCData(data) - } + override fun writeCData(data: String) { + currentState = DATA + super.writeCData(data) + } - companion object { - private val NOTHING = Any() - private val TAG = Any() - private val DATA = Any() - } + companion object { + private val NOTHING = Any() + private val TAG = Any() + private val DATA = Any() + } } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/Listing.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/Listing.kt index e3850e31d..acc2b33b5 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/Listing.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/Listing.kt @@ -5,8 +5,8 @@ package io.gitlab.arturbosch.detekt.cli.baseline */ interface Listing { - val timestamp: String - val ids: Set + val timestamp: String + val ids: Set - fun withNewTimestamp(timestamp: String, list: T): T + fun withNewTimestamp(timestamp: String, list: T): T } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/Whitelist.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/Whitelist.kt index 556867df6..e72daea5c 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/Whitelist.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/Whitelist.kt @@ -3,13 +3,17 @@ package io.gitlab.arturbosch.detekt.cli.baseline /** * @author Artur Bosch */ -data class Whitelist(override val ids: Set, - override val timestamp: String) : Listing { +data class Whitelist( + override val ids: Set, + override val timestamp: String +) : Listing { - override fun withNewTimestamp(timestamp: String, - list: Whitelist) = Whitelist(list.ids, timestamp) + override fun withNewTimestamp( + timestamp: String, + list: Whitelist + ) = Whitelist(list.ids, timestamp) - override fun toString(): String { - return "Blacklist(ids=$ids, timestamp='$timestamp')" - } + override fun toString(): String { + return "Blacklist(ids=$ids, timestamp='$timestamp')" + } } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/XmlExtensions.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/XmlExtensions.kt index e6da8bfa9..7cc659c54 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/XmlExtensions.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/XmlExtensions.kt @@ -9,52 +9,55 @@ fun Writer.streamXml(): XMLStreamWriter = XMLOutputFactory.newFactory().createXM fun XMLStreamWriter.prettyPrinter(): XMLStreamWriter = IndentingXMLStreamWriter(this) inline fun XMLStreamWriter.document( - version: String? = null, - encoding: String? = null, - init: XMLStreamWriter.() -> Unit + version: String? = null, + encoding: String? = null, + init: XMLStreamWriter.() -> Unit ) = apply { - when { - encoding != null && version != null -> writeStartDocument(encoding, version) - version != null -> writeStartDocument(version) - else -> writeStartDocument() - } - init() - writeEndDocument() + when { + encoding != null && version != null -> writeStartDocument(encoding, version) + version != null -> writeStartDocument(version) + else -> writeStartDocument() + } + init() + writeEndDocument() } inline fun XMLStreamWriter.tag( - name: String, - init: XMLStreamWriter.() -> Unit) = apply { - writeStartElement(name) - init() - writeEndElement() + name: String, + init: XMLStreamWriter.() -> Unit +) = apply { + writeStartElement(name) + init() + writeEndElement() } fun XMLStreamWriter.emptyTag( - name: String, - init: (XMLStreamWriter.() -> Unit)? = null) = apply { - writeEmptyElement(name) - init?.invoke(this) + name: String, + init: (XMLStreamWriter.() -> Unit)? = null +) = apply { + writeEmptyElement(name) + init?.invoke(this) } inline fun XMLStreamWriter.tag( - name: String, - content: String, - init: XMLStreamWriter.() -> Unit) = apply { - tag(name) { - init() - writeCharacters(content) - } + name: String, + content: String, + init: XMLStreamWriter.() -> Unit +) = apply { + tag(name) { + init() + writeCharacters(content) + } } fun XMLStreamWriter.tag(name: String, content: String) { - tag(name) { - writeCharacters(content) - } + tag(name) { + writeCharacters(content) + } } fun XMLStreamWriter.comment(content: String) { - writeComment(content) + writeComment(content) } fun XMLStreamWriter.attribute(name: String, value: String) = writeAttribute(name, value) diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/console/BuildFailureReport.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/console/BuildFailureReport.kt index a6a636ddf..3218c066b 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/console/BuildFailureReport.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/console/BuildFailureReport.kt @@ -13,68 +13,68 @@ import java.util.HashMap */ class BuildFailureReport : ConsoleReport() { - override val priority: Int = Int.MIN_VALUE + override val priority: Int = Int.MIN_VALUE - private var weightsConfig: Config by SingleAssign() - private var buildConfig: Config by SingleAssign() - private var warningThreshold: Int by SingleAssign() - private var failThreshold: Int by SingleAssign() - private var maxIssues: Int by SingleAssign() + private var weightsConfig: Config by SingleAssign() + private var buildConfig: Config by SingleAssign() + private var warningThreshold: Int by SingleAssign() + private var failThreshold: Int by SingleAssign() + private var maxIssues: Int by SingleAssign() - companion object { - private const val BUILD = "build" - private const val WEIGHTS = "weights" - private const val WARNING_THRESHOLD = "warningThreshold" - private const val FAIL_THRESHOLD = "failThreshold" - private const val MAX_ISSUES = "maxIssues" - } + companion object { + private const val BUILD = "build" + private const val WEIGHTS = "weights" + private const val WARNING_THRESHOLD = "warningThreshold" + private const val FAIL_THRESHOLD = "failThreshold" + private const val MAX_ISSUES = "maxIssues" + } - override fun init(config: Config) { - buildConfig = config.subConfig(BUILD) - weightsConfig = buildConfig.subConfig(WEIGHTS) - warningThreshold = buildConfig.valueOrDefault(WARNING_THRESHOLD, -1) - failThreshold = buildConfig.valueOrDefault(FAIL_THRESHOLD, -1) - maxIssues = buildConfig.valueOrDefault(MAX_ISSUES, -1) - } + override fun init(config: Config) { + buildConfig = config.subConfig(BUILD) + weightsConfig = buildConfig.subConfig(WEIGHTS) + warningThreshold = buildConfig.valueOrDefault(WARNING_THRESHOLD, -1) + failThreshold = buildConfig.valueOrDefault(FAIL_THRESHOLD, -1) + maxIssues = buildConfig.valueOrDefault(MAX_ISSUES, -1) + } - override fun render(detektion: Detektion): String? { - val smells = detektion.findings.flatMap { it.value } - val ruleToRuleSetId = extractRuleToRuleSetIdMap(detektion) - val amount = smells.map { it.weighted(ruleToRuleSetId) }.sum() + override fun render(detektion: Detektion): String? { + val smells = detektion.findings.flatMap { it.value } + val ruleToRuleSetId = extractRuleToRuleSetIdMap(detektion) + val amount = smells.map { it.weighted(ruleToRuleSetId) }.sum() - checkDeprecation() - return when { - maxIssues.reached(amount) -> throw BuildFailure("Build failed with $amount weighted issues " + - "(threshold defined was $maxIssues).") - failThreshold.reached(amount) -> throw BuildFailure("Build failure threshold of " + - "$failThreshold reached with $amount weighted smells!") - warningThreshold.reached(amount) -> "Warning: $amount weighted code smells found. " + - "Warning threshold is $warningThreshold and fail threshold is $failThreshold!" - else -> null - } - } + checkDeprecation() + return when { + maxIssues.reached(amount) -> throw BuildFailure("Build failed with $amount weighted issues " + + "(threshold defined was $maxIssues).") + failThreshold.reached(amount) -> throw BuildFailure("Build failure threshold of " + + "$failThreshold reached with $amount weighted smells!") + warningThreshold.reached(amount) -> "Warning: $amount weighted code smells found. " + + "Warning threshold is $warningThreshold and fail threshold is $failThreshold!" + else -> null + } + } - private fun checkDeprecation() { - if (buildConfig.valueOrDefault(WARNING_THRESHOLD, Int.MIN_VALUE) != Int.MIN_VALUE || - buildConfig.valueOrDefault(FAIL_THRESHOLD, Int.MIN_VALUE) != Int.MIN_VALUE) { - println("[Deprecation] - 'warningThreshold' and 'failThreshold' properties are deprecated." + - " Please use the new 'maxIssues' config property.") - } - } + private fun checkDeprecation() { + if (buildConfig.valueOrDefault(WARNING_THRESHOLD, Int.MIN_VALUE) != Int.MIN_VALUE || + buildConfig.valueOrDefault(FAIL_THRESHOLD, Int.MIN_VALUE) != Int.MIN_VALUE) { + println("[Deprecation] - 'warningThreshold' and 'failThreshold' properties are deprecated." + + " Please use the new 'maxIssues' config property.") + } + } - private fun extractRuleToRuleSetIdMap(detektion: Detektion): HashMap { - return detektion.findings.mapValues { it.value.map(Finding::id).toSet() } - .map { map -> map.value.map { it to map.key }.toMap() } - .fold(HashMap()) { result, map -> result.putAll(map); result } - } + private fun extractRuleToRuleSetIdMap(detektion: Detektion): HashMap { + return detektion.findings.mapValues { it.value.map(Finding::id).toSet() } + .map { map -> map.value.map { it to map.key }.toMap() } + .fold(HashMap()) { result, map -> result.putAll(map); result } + } - private fun Finding.weighted(ids: Map): Int { - val key = ids[id] // entry of ID > entry of RuleSet ID > default weight 1 - return weightsConfig.valueOrDefault(id, - if (key != null) weightsConfig.valueOrDefault(key, 1) else 1) - } + private fun Finding.weighted(ids: Map): Int { + val key = ids[id] // entry of ID > entry of RuleSet ID > default weight 1 + return weightsConfig.valueOrDefault(id, + if (key != null) weightsConfig.valueOrDefault(key, 1) else 1) + } - fun Int.reached(amount: Int): Boolean = !(this == 0 && amount == 0) && this != -1 && this <= amount + fun Int.reached(amount: Int): Boolean = !(this == 0 && amount == 0) && this != -1 && this <= amount } class BuildFailure(override val message: String?) : RuntimeException(message, null, true, false) diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/console/ComplexityMetric.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/console/ComplexityMetric.kt index 392dc12e8..c81750ce5 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/console/ComplexityMetric.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/console/ComplexityMetric.kt @@ -1,18 +1,18 @@ package io.gitlab.arturbosch.detekt.cli.console import io.gitlab.arturbosch.detekt.api.Detektion -import io.gitlab.arturbosch.detekt.core.processors.complexityKey -import io.gitlab.arturbosch.detekt.core.processors.logicalLinesKey -import io.gitlab.arturbosch.detekt.core.processors.linesKey import io.gitlab.arturbosch.detekt.core.processors.commentLinesKey +import io.gitlab.arturbosch.detekt.core.processors.complexityKey +import io.gitlab.arturbosch.detekt.core.processors.linesKey +import io.gitlab.arturbosch.detekt.core.processors.logicalLinesKey import io.gitlab.arturbosch.detekt.core.processors.sourceLinesKey class ComplexityMetric(detektion: Detektion) { - val mcc = detektion.getData(complexityKey) - val loc = detektion.getData(linesKey) - val sloc = detektion.getData(sourceLinesKey) - val lloc = detektion.getData(logicalLinesKey) - val cloc = detektion.getData(commentLinesKey) - val findings = detektion.findings.entries + val mcc = detektion.getData(complexityKey) + val loc = detektion.getData(linesKey) + val sloc = detektion.getData(sourceLinesKey) + val lloc = detektion.getData(logicalLinesKey) + val cloc = detektion.getData(commentLinesKey) + val findings = detektion.findings.entries } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/console/ComplexityReport.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/console/ComplexityReport.kt index 631d3e7a7..2ac102559 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/console/ComplexityReport.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/console/ComplexityReport.kt @@ -8,10 +8,10 @@ import io.gitlab.arturbosch.detekt.api.Detektion */ class ComplexityReport : ConsoleReport() { - override val priority: Int = 20 + override val priority: Int = 20 - override fun render(detektion: Detektion): String? { - val complexityReportGenerator = ComplexityReportGenerator.create(detektion) - return complexityReportGenerator.generate() - } + override fun render(detektion: Detektion): String? { + val complexityReportGenerator = ComplexityReportGenerator.create(detektion) + return complexityReportGenerator.generate() + } } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/console/ComplexityReportGenerator.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/console/ComplexityReportGenerator.kt index f52298b11..ae64f53d2 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/console/ComplexityReportGenerator.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/console/ComplexityReportGenerator.kt @@ -4,45 +4,45 @@ import io.gitlab.arturbosch.detekt.api.Detektion class ComplexityReportGenerator(private val complexityMetric: ComplexityMetric) { - private var numberOfSmells = 0 - private var smellPerThousandLines = 0 - private var mccPerThousandLines = 0 - private var commentSourceRatio = 0 + private var numberOfSmells = 0 + private var smellPerThousandLines = 0 + private var mccPerThousandLines = 0 + private var commentSourceRatio = 0 - companion object Factory { - fun create(detektion: Detektion): ComplexityReportGenerator = ComplexityReportGenerator(ComplexityMetric(detektion)) - } + companion object Factory { + fun create(detektion: Detektion): ComplexityReportGenerator = ComplexityReportGenerator(ComplexityMetric(detektion)) + } - fun generate(): String? { - if (cannotGenerate()) return null - return with(StringBuilder()) { - append("Complexity Report:".format()) - append("${complexityMetric.loc} lines of code (loc)".format(PREFIX)) - append("${complexityMetric.sloc} source lines of code (sloc)".format(PREFIX)) - append("${complexityMetric.lloc} logical lines of code (lloc)".format(PREFIX)) - append("${complexityMetric.cloc} comment lines of code (cloc)".format(PREFIX)) - append("${complexityMetric.mcc} McCabe complexity (mcc)".format(PREFIX)) - append("$numberOfSmells number of total code smells".format(PREFIX)) - append("$commentSourceRatio % comment source ratio".format(PREFIX)) - append("$mccPerThousandLines mcc per 1000 lloc".format(PREFIX)) - append("$smellPerThousandLines code smells per 1000 lloc".format(PREFIX)) - toString() - } - } + fun generate(): String? { + if (cannotGenerate()) return null + return with(StringBuilder()) { + append("Complexity Report:".format()) + append("${complexityMetric.loc} lines of code (loc)".format(PREFIX)) + append("${complexityMetric.sloc} source lines of code (sloc)".format(PREFIX)) + append("${complexityMetric.lloc} logical lines of code (lloc)".format(PREFIX)) + append("${complexityMetric.cloc} comment lines of code (cloc)".format(PREFIX)) + append("${complexityMetric.mcc} McCabe complexity (mcc)".format(PREFIX)) + append("$numberOfSmells number of total code smells".format(PREFIX)) + append("$commentSourceRatio % comment source ratio".format(PREFIX)) + append("$mccPerThousandLines mcc per 1000 lloc".format(PREFIX)) + append("$smellPerThousandLines code smells per 1000 lloc".format(PREFIX)) + toString() + } + } - private fun cannotGenerate(): Boolean { - return when { - complexityMetric.mcc == null -> true - complexityMetric.lloc == null || complexityMetric.lloc == 0 -> true - complexityMetric.sloc == null || complexityMetric.sloc == 0 -> true - complexityMetric.cloc == null -> true - 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 - false - } - } - } + private fun cannotGenerate(): Boolean { + return when { + complexityMetric.mcc == null -> true + complexityMetric.lloc == null || complexityMetric.lloc == 0 -> true + complexityMetric.sloc == null || complexityMetric.sloc == 0 -> true + complexityMetric.cloc == null -> true + 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 + false + } + } + } } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/console/DebtSumming.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/console/DebtSumming.kt index 7193144a7..4600b33f2 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/console/DebtSumming.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/console/DebtSumming.kt @@ -4,37 +4,37 @@ import io.gitlab.arturbosch.detekt.api.Debt class DebtSumming { - private val debtList = mutableListOf() + private val debtList = mutableListOf() - fun add(debt: Debt) { - debtList.add(debt) - } + fun add(debt: Debt) { + debtList.add(debt) + } - fun calculateDebt(): Debt? { - if (debtList.isEmpty()) { - return null - } - return calculate() - } + fun calculateDebt(): Debt? { + if (debtList.isEmpty()) { + return null + } + return calculate() + } - private fun calculate(): Debt { - var minutes = 0 - var hours = 0 - var days = 0 - debtList.forEach { - minutes += it.mins - hours += it.hours - days += it.days - } - hours += minutes / MINUTES_PER_HOUR - minutes %= MINUTES_PER_HOUR - days += hours / HOURS_PER_DAY - hours %= HOURS_PER_DAY - return Debt(days, hours, minutes) - } + private fun calculate(): Debt { + var minutes = 0 + var hours = 0 + var days = 0 + debtList.forEach { + minutes += it.mins + hours += it.hours + days += it.days + } + hours += minutes / MINUTES_PER_HOUR + minutes %= MINUTES_PER_HOUR + days += hours / HOURS_PER_DAY + hours %= HOURS_PER_DAY + return Debt(days, hours, minutes) + } - companion object { - private const val HOURS_PER_DAY = 24 - private const val MINUTES_PER_HOUR = 60 - } + companion object { + private const val HOURS_PER_DAY = 24 + private const val MINUTES_PER_HOUR = 60 + } } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/console/FindingsReport.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/console/FindingsReport.kt index 3cc2cda73..7567597ee 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/console/FindingsReport.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/console/FindingsReport.kt @@ -9,34 +9,34 @@ import io.gitlab.arturbosch.detekt.api.Detektion */ class FindingsReport : ConsoleReport() { - override val priority: Int = 40 + override val priority: Int = 40 - override fun render(detektion: Detektion): String? { - val findings = detektion.findings - val totalDebt = DebtSumming() - return with(StringBuilder()) { - findings.forEach { rulesetFindings -> - val debtSumming = DebtSumming() - val issuesString = rulesetFindings.value.joinToString("") { - debtSumming.add(it.issue.debt) - it.compact().format("\t") - } - val debt = debtSumming.calculateDebt() - val debtString = - if (debt != null) { - totalDebt.add(debt) - " - $debt debt".format() - } else { - "\n" - } - append(rulesetFindings.key.format(prefix = "Ruleset: ", suffix = debtString)) - append(issuesString) - } - val debt = totalDebt.calculateDebt() - if (debt != null) { - append("Overall debt: $debt".format("\n")) - } - toString() - } - } + override fun render(detektion: Detektion): String? { + val findings = detektion.findings + val totalDebt = DebtSumming() + return with(StringBuilder()) { + findings.forEach { rulesetFindings -> + val debtSumming = DebtSumming() + val issuesString = rulesetFindings.value.joinToString("") { + debtSumming.add(it.issue.debt) + it.compact().format("\t") + } + val debt = debtSumming.calculateDebt() + val debtString = + if (debt != null) { + totalDebt.add(debt) + " - $debt debt".format() + } else { + "\n" + } + append(rulesetFindings.key.format(prefix = "Ruleset: ", suffix = debtString)) + append(issuesString) + } + val debt = totalDebt.calculateDebt() + if (debt != null) { + append("Overall debt: $debt".format("\n")) + } + toString() + } + } } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/console/NotificationReport.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/console/NotificationReport.kt index bde968cf8..0702a55c2 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/console/NotificationReport.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/console/NotificationReport.kt @@ -8,10 +8,10 @@ import io.gitlab.arturbosch.detekt.api.Detektion */ class NotificationReport : ConsoleReport() { - override val priority: Int = 50 + override val priority: Int = 50 - override fun render(detektion: Detektion): String? { - val notifications = detektion.notifications - return notifications.joinToString("\n") { it.message } - } + override fun render(detektion: Detektion): String? { + val notifications = detektion.notifications + return notifications.joinToString("\n") { it.message } + } } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/console/ProjectStatisticsReport.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/console/ProjectStatisticsReport.kt index f7f4a0316..51a33ced1 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/console/ProjectStatisticsReport.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/console/ProjectStatisticsReport.kt @@ -8,17 +8,17 @@ import io.gitlab.arturbosch.detekt.api.Detektion */ class ProjectStatisticsReport : ConsoleReport() { - override val priority: Int = 10 + override val priority: Int = 10 - override fun render(detektion: Detektion): String? { - val metrics = detektion.metrics - if (metrics.isEmpty()) return null - return with(StringBuilder()) { - append("Project Statistics:".format()) - metrics.sortedBy { it.priority } - .reversed() - .forEach { append(it.toString().format(PREFIX)) } - toString() - } - } + override fun render(detektion: Detektion): String? { + val metrics = detektion.metrics + if (metrics.isEmpty()) return null + return with(StringBuilder()) { + append("Project Statistics:".format()) + metrics.sortedBy { it.priority } + .reversed() + .forEach { append(it.toString().format(PREFIX)) } + toString() + } + } } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/out/HtmlOutputReport.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/out/HtmlOutputReport.kt index 58fa7d705..b40e1cce5 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/out/HtmlOutputReport.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/out/HtmlOutputReport.kt @@ -17,42 +17,42 @@ private const val PLACEHOLDER_FINDINGS = "@@@findings@@@" */ class HtmlOutputReport : OutputReport() { - override val ending = "html" + override val ending = "html" - override val name = "HTML report" + override val name = "HTML report" - override fun render(detektion: Detektion) = - ClasspathResourceConverter().convert(DEFAULT_TEMPLATE).openStream().bufferedReader().use { it.readText() } - .replace(PLACEHOLDER_METRICS, renderMetrics(detektion.metrics)) - .replace(PLACEHOLDER_FINDINGS, renderFindings(detektion.findings)) + override fun render(detektion: Detektion) = + ClasspathResourceConverter().convert(DEFAULT_TEMPLATE).openStream().bufferedReader().use { it.readText() } + .replace(PLACEHOLDER_METRICS, renderMetrics(detektion.metrics)) + .replace(PLACEHOLDER_FINDINGS, renderFindings(detektion.findings)) - private fun renderMetrics(metrics: Collection) = htmlSnippet { - list(metrics) { - text { "${it.type}: ${it.value}" } - } - } + private fun renderMetrics(metrics: Collection) = htmlSnippet { + list(metrics) { + text { "${it.type}: ${it.value}" } + } + } - private fun renderFindings(findings: Map>) = htmlSnippet { - for ((group, groupFindings) in findings.filter { !it.value.isEmpty() }) { - h3 { group } + private fun renderFindings(findings: Map>) = htmlSnippet { + for ((group, groupFindings) in findings.filter { !it.value.isEmpty() }) { + h3 { group } - groupFindings.groupBy { it.id }.forEach { rule, findings -> - if (!findings.isEmpty()) { - div("rule-container") { - span("rule") { rule } - span("description") { findings.first().issue.description } - } - } + groupFindings.groupBy { it.id }.forEach { rule, findings -> + if (!findings.isEmpty()) { + div("rule-container") { + span("rule") { rule } + span("description") { findings.first().issue.description } + } + } - list(findings) { - span("location") { "${it.file}:${it.location.source.line}:${it.location.source.column}" } + list(findings) { + span("location") { "${it.file}:${it.location.source.line}:${it.location.source.column}" } - if (!it.message.isEmpty()) { - br() - span("message") { it.message } - } - } - } - } - } + if (!it.message.isEmpty()) { + br() + span("message") { it.message } + } + } + } + } + } } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/out/HtmlSnippet.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/out/HtmlSnippet.kt index f0b9c6c4a..5d77d2fad 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/out/HtmlSnippet.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/out/HtmlSnippet.kt @@ -5,53 +5,53 @@ package io.gitlab.arturbosch.detekt.cli.out */ class HtmlSnippet { - private val lines = mutableListOf() + private val lines = mutableListOf() - fun h3(body: () -> String) { - lines.add("

${body()}

") - } + fun h3(body: () -> String) { + lines.add("

${body()}

") + } - fun div(cssClass: String, body: HtmlSnippet.() -> Unit) { - lines.add("
") + fun div(cssClass: String, body: HtmlSnippet.() -> Unit) { + lines.add("
") - body() + body() - lines.add("
") - } + lines.add("
") + } - fun text(body: () -> String) { - lines.add(body()) - } + fun text(body: () -> String) { + lines.add(body()) + } - fun br() { - lines.add("
") - } + fun br() { + lines.add("
") + } - fun span(cssClass: String, text: () -> String) { - lines.add("") - lines.add(text()) - lines.add("") - } + fun span(cssClass: String, text: () -> String) { + lines.add("") + lines.add(text()) + lines.add("") + } - fun list(collection: Collection, body: HtmlSnippet.(T) -> Unit) { - lines.add("
    ") + fun list(collection: Collection, body: HtmlSnippet.(T) -> Unit) { + lines.add("
      ") - collection.forEach { - lines.add("
    • ") - body(it) - lines.add("
    • ") - } + collection.forEach { + lines.add("
    • ") + body(it) + lines.add("
    • ") + } - lines.add("
    ") - } + lines.add("
") + } - override fun toString(): String { - return lines.joinToString("\n") - } + override fun toString(): String { + return lines.joinToString("\n") + } } fun htmlSnippet(init: HtmlSnippet.() -> Unit): String { - val snippet = HtmlSnippet() - snippet.init() - return snippet.toString() + val snippet = HtmlSnippet() + snippet.init() + return snippet.toString() } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/out/TxtOutputReport.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/out/TxtOutputReport.kt index c98f12006..43621c7a0 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/out/TxtOutputReport.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/out/TxtOutputReport.kt @@ -8,12 +8,12 @@ import io.gitlab.arturbosch.detekt.api.OutputReport */ class TxtOutputReport : OutputReport() { - override val ending: String = "txt" + override val ending: String = "txt" - override val name = "plain text report" + override val name = "plain text report" - override fun render(detektion: Detektion): String { - val smells = detektion.findings.flatMap { it.value } - return smells.joinToString("\n") { it.compactWithSignature() } - } + override fun render(detektion: Detektion): String { + val smells = detektion.findings.flatMap { it.value } + return smells.joinToString("\n") { it.compactWithSignature() } + } } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/out/XmlEscape.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/out/XmlEscape.kt index a4c40b385..627c73a01 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/out/XmlEscape.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/out/XmlEscape.kt @@ -1,20 +1,20 @@ /* * ============================================================================= - * + * * Copyright (c) 2014, The UNBESCAPE team (http://www.unbescape.org) - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * * ============================================================================= */ @file:Suppress("ALL") @@ -35,134 +35,134 @@ import java.util.Collections */ object XmlEscape { - private val REFERENCE_HEXA_PREFIX = "&#x".toCharArray() - private val REFERENCE_SUFFIX = ';' + private val REFERENCE_HEXA_PREFIX = "&#x".toCharArray() + private val REFERENCE_SUFFIX = ';' - /** - * Perform an XML 1.0 level 2 (markup-significant and all non-ASCII chars) **escape** operation - * on a String input. - * - * *Level 2* means this method will escape: - * * The five markup-significant characters: <, >, &, - * " and ' - * * All non ASCII characters. - * - * This escape will be performed by replacing those chars by the corresponding XML Character Entity References - * (e.g. '&lt;') when such CER exists for the replaced character, and replacing by a hexadecimal - * character reference (e.g. '&#x2430;') when there there is no CER for the replaced character. - * - * This method is **thread-safe**. + /** + * Perform an XML 1.0 level 2 (markup-significant and all non-ASCII chars) **escape** operation + * on a String input. + * + * *Level 2* means this method will escape: + * * The five markup-significant characters: <, >, &, + * " and ' + * * All non ASCII characters. + * + * This escape will be performed by replacing those chars by the corresponding XML Character Entity References + * (e.g. '&lt;') when such CER exists for the replaced character, and replacing by a hexadecimal + * character reference (e.g. '&#x2430;') when there there is no CER for the replaced character. + * + * This method is **thread-safe**. - * @param text the String to be escaped. - * * - * @return The escaped result String. As a memory-performance improvement, will return the exact - * * same object as the text input argument if no escaping modifications were required (and - * * no additional String objects will be created during processing). Will - * * return null if input is null. - */ - fun escapeXml(text: String): String { - val symbols = Xml10EscapeSymbolsInitializer.initializeXml10() - val level = 2 - var strBuilder: StringBuilder? = null - val offset = 0 - val max = text.length - var readOffset = offset + * @param text the String to be escaped. + * * + * @return The escaped result String. As a memory-performance improvement, will return the exact + * * same object as the text input argument if no escaping modifications were required (and + * * no additional String objects will be created during processing). Will + * * return null if input is null. + */ + fun escapeXml(text: String): String { + val symbols = Xml10EscapeSymbolsInitializer.initializeXml10() + val level = 2 + var strBuilder: StringBuilder? = null + val offset = 0 + val max = text.length + var readOffset = offset - var i = offset - while (i < max) { - val codepoint = Character.codePointAt(text, i) - val codepointValid = symbols.CODEPOINT_VALIDATOR.isValid(codepoint) + var i = offset + while (i < max) { + val codepoint = Character.codePointAt(text, i) + val codepointValid = symbols.CODEPOINT_VALIDATOR.isValid(codepoint) - /* - * Shortcut: most characters will be ASCII/Alphanumeric, and we won't need to do anything at - * all for them - */ - if (codepoint <= Xml10EscapeSymbolsInitializer.XmlEscapeSymbols.LEVELS_LEN - 2 - && level < symbols.ESCAPE_LEVELS[codepoint] - && codepointValid) { - i++ - continue - } + /* + * Shortcut: most characters will be ASCII/Alphanumeric, and we won't need to do anything at + * all for them + */ + if (codepoint <= Xml10EscapeSymbolsInitializer.XmlEscapeSymbols.LEVELS_LEN - 2 + && level < symbols.ESCAPE_LEVELS[codepoint] + && codepointValid) { + i++ + continue + } - /* - * Shortcut: we might not want to escape non-ASCII chars at all either. - */ - if (codepoint > Xml10EscapeSymbolsInitializer.XmlEscapeSymbols.LEVELS_LEN - 2 - && level < symbols.ESCAPE_LEVELS[Xml10EscapeSymbolsInitializer.XmlEscapeSymbols.LEVELS_LEN - 1] - && codepointValid) { - if (Character.charCount(codepoint) > 1) { - // This is to compensate that we are actually escaping two char[] positions with a single codepoint. - i++ - } - i++ - continue - } + /* + * Shortcut: we might not want to escape non-ASCII chars at all either. + */ + if (codepoint > Xml10EscapeSymbolsInitializer.XmlEscapeSymbols.LEVELS_LEN - 2 + && level < symbols.ESCAPE_LEVELS[Xml10EscapeSymbolsInitializer.XmlEscapeSymbols.LEVELS_LEN - 1] + && codepointValid) { + if (Character.charCount(codepoint) > 1) { + // This is to compensate that we are actually escaping two char[] positions with a single codepoint. + i++ + } + i++ + continue + } - /* - * At this point we know for sure we will need some kind of escape, so we - * can increase the offset and initialize the string builder if needed, along with - * copying to it all the contents pending up to this point. - */ - if (strBuilder == null) { - strBuilder = StringBuilder(max + 20) - } - if (i - readOffset > 0) { - strBuilder.append(text, readOffset, i) - } - if (Character.charCount(codepoint) > 1) { - // This is to compensate that we are actually reading two char[] positions with a single codepoint. - i++ - } - readOffset = i + 1 + /* + * At this point we know for sure we will need some kind of escape, so we + * can increase the offset and initialize the string builder if needed, along with + * copying to it all the contents pending up to this point. + */ + if (strBuilder == null) { + strBuilder = StringBuilder(max + 20) + } + if (i - readOffset > 0) { + strBuilder.append(text, readOffset, i) + } + if (Character.charCount(codepoint) > 1) { + // This is to compensate that we are actually reading two char[] positions with a single codepoint. + i++ + } + readOffset = i + 1 - /* - * If the char is invalid, there is nothing to write, simply skip it (which we already did by - * incrementing the readOffset. - */ - if (!codepointValid) { - i++ - continue - } + /* + * If the char is invalid, there is nothing to write, simply skip it (which we already did by + * incrementing the readOffset. + */ + if (!codepointValid) { + i++ + continue + } - /* - * ----------------------------------------------------------------------------------------- - * - * Perform the real escape, attending the different combinations of NCR, DCR and HCR needs. - * - * ----------------------------------------------------------------------------------------- - */ - // We will try to use a CER - val codepointIndex = Arrays.binarySearch(symbols.SORTED_CODEPOINTS, codepoint) - if (codepointIndex >= 0) { - // CER found! just write it and go for the next char - strBuilder.append(symbols.SORTED_CERS_BY_CODEPOINT[codepointIndex]) - i++ - continue - } - /* - * No NCR-escape was possible (or allowed), so we need decimal/hexa escape. - */ - strBuilder.append(REFERENCE_HEXA_PREFIX) - strBuilder.append(Integer.toHexString(codepoint)) - strBuilder.append(REFERENCE_SUFFIX) - i++ - } + /* + * ----------------------------------------------------------------------------------------- + * + * Perform the real escape, attending the different combinations of NCR, DCR and HCR needs. + * + * ----------------------------------------------------------------------------------------- + */ + // We will try to use a CER + val codepointIndex = Arrays.binarySearch(symbols.SORTED_CODEPOINTS, codepoint) + if (codepointIndex >= 0) { + // CER found! just write it and go for the next char + strBuilder.append(symbols.SORTED_CERS_BY_CODEPOINT[codepointIndex]) + i++ + continue + } + /* + * No NCR-escape was possible (or allowed), so we need decimal/hexa escape. + */ + strBuilder.append(REFERENCE_HEXA_PREFIX) + strBuilder.append(Integer.toHexString(codepoint)) + strBuilder.append(REFERENCE_SUFFIX) + i++ + } - /* - * ----------------------------------------------------------------------------------------------- - * Final cleaning: return the original String object if no escape was actually needed. Otherwise - * append the remaining unescaped text to the string builder and return. - * ----------------------------------------------------------------------------------------------- - */ - if (strBuilder == null) { - return text - } - if (max - readOffset > 0) { - strBuilder.append(text, readOffset, max) - } - return strBuilder.toString() + /* + * ----------------------------------------------------------------------------------------------- + * Final cleaning: return the original String object if no escape was actually needed. Otherwise + * append the remaining unescaped text to the string builder and return. + * ----------------------------------------------------------------------------------------------- + */ + if (strBuilder == null) { + return text + } + if (max - readOffset > 0) { + strBuilder.append(text, readOffset, max) + } + return strBuilder.toString() - } + } } /** @@ -171,267 +171,267 @@ object XmlEscape { @Suppress("ALL") private object Xml10EscapeSymbolsInitializer { - internal class XmlCodepointValidator { + internal class XmlCodepointValidator { - /* - * XML 1.0 does not allow many control characters, nor unpaired surrogate chars - * (characters used for composing two-char codepoints, but appearing on their own). - */ - fun isValid(codepoint: Int): Boolean { - if (codepoint < 0x20) { - return codepoint == 0x9 || codepoint == 0xA || codepoint == 0xD - } - if (codepoint <= 0xD7FF) { // U+D800 - U+DFFF are reserved for low + high surrogates - return true - } - if (codepoint < 0xE000) { - return false - } - if (codepoint <= 0xFFFD) { // U+FFFE and U+FFFF are non-characters, and therefore not valid - return true - } - if (codepoint < 0x10000) { - return false - } - return true - } + /* + * XML 1.0 does not allow many control characters, nor unpaired surrogate chars + * (characters used for composing two-char codepoints, but appearing on their own). + */ + fun isValid(codepoint: Int): Boolean { + if (codepoint < 0x20) { + return codepoint == 0x9 || codepoint == 0xA || codepoint == 0xD + } + if (codepoint <= 0xD7FF) { // U+D800 - U+DFFF are reserved for low + high surrogates + return true + } + if (codepoint < 0xE000) { + return false + } + if (codepoint <= 0xFFFD) { // U+FFFE and U+FFFF are non-characters, and therefore not valid + return true + } + if (codepoint < 0x10000) { + return false + } + return true + } - } + } - fun initializeXml10(): XmlEscapeSymbols { + fun initializeXml10(): XmlEscapeSymbols { - val xml10References = XmlEscapeSymbols.References() + val xml10References = XmlEscapeSymbols.References() - /* - * -------------------------------------------------------------------------------------------------- - * XML 1.0 CHARACTER ENTITY REFERENCES - * See: http://www.w3.org/TR/xml - * -------------------------------------------------------------------------------------------------- - */ - xml10References.addReference(34, """) - xml10References.addReference(38, "&") - xml10References.addReference(39, "'") - xml10References.addReference(60, "<") - xml10References.addReference(62, ">") + /* + * -------------------------------------------------------------------------------------------------- + * XML 1.0 CHARACTER ENTITY REFERENCES + * See: http://www.w3.org/TR/xml + * -------------------------------------------------------------------------------------------------- + */ + xml10References.addReference(34, """) + xml10References.addReference(38, "&") + xml10References.addReference(39, "'") + xml10References.addReference(60, "<") + xml10References.addReference(62, ">") - /* - * Initialization of escape markup-significant characters plus all non-ASCII - */ - val escapeLevels = ByteArray(XmlEscapeSymbols.LEVELS_LEN) - /* - * Everything is level 3 unless contrary indication. - */ - Arrays.fill(escapeLevels, 3.toByte()) - /* - * Everything non-ASCII is level 2 unless contrary indication. - */ - for (c in 0x80..XmlEscapeSymbols.LEVELS_LEN - 1) { - escapeLevels[c] = 2 - } + /* + * Initialization of escape markup-significant characters plus all non-ASCII + */ + val escapeLevels = ByteArray(XmlEscapeSymbols.LEVELS_LEN) + /* + * Everything is level 3 unless contrary indication. + */ + Arrays.fill(escapeLevels, 3.toByte()) + /* + * Everything non-ASCII is level 2 unless contrary indication. + */ + for (c in 0x80..XmlEscapeSymbols.LEVELS_LEN - 1) { + escapeLevels[c] = 2 + } - /* - * Alphanumeric characters are level 4. - */ - run { - var c = 'A' - while (c <= 'Z') { - escapeLevels[c] = 4 - c++ - } - } - run { - var c = 'a' - while (c <= 'z') { - escapeLevels[c] = 4 - c++ - } - } - run { - var c = '0' - while (c <= '9') { - escapeLevels[c] = 4 - c++ - } - } + /* + * Alphanumeric characters are level 4. + */ + run { + var c = 'A' + while (c <= 'Z') { + escapeLevels[c] = 4 + c++ + } + } + run { + var c = 'a' + while (c <= 'z') { + escapeLevels[c] = 4 + c++ + } + } + run { + var c = '0' + while (c <= '9') { + escapeLevels[c] = 4 + c++ + } + } - /* - * The five XML predefined entities will be escaped always (level 1) - */ - escapeLevels['\''] = 1 - escapeLevels['"'] = 1 - escapeLevels['<'] = 1 - escapeLevels['>'] = 1 - escapeLevels['&'] = 1 + /* + * The five XML predefined entities will be escaped always (level 1) + */ + escapeLevels['\''] = 1 + escapeLevels['"'] = 1 + escapeLevels['<'] = 1 + escapeLevels['>'] = 1 + escapeLevels['&'] = 1 - /* - * XML 1.0 allows a series of control characters, but they should appear - * escaped: [#x7F-#x84] | [#x86-#x9F] - */ - for (c in 0x7F..0x84) { - escapeLevels[c] = 1 - } - for (c in 0x86..0x9F) { - escapeLevels[c] = 1 - } + /* + * XML 1.0 allows a series of control characters, but they should appear + * escaped: [#x7F-#x84] | [#x86-#x9F] + */ + for (c in 0x7F..0x84) { + escapeLevels[c] = 1 + } + for (c in 0x86..0x9F) { + escapeLevels[c] = 1 + } - /* - * Create the new symbols structure - */ - return XmlEscapeSymbols(xml10References, escapeLevels, XmlCodepointValidator()) - } + /* + * Create the new symbols structure + */ + return XmlEscapeSymbols(xml10References, escapeLevels, XmlCodepointValidator()) + } - private operator fun ByteArray.set(c: Char, value: Byte) { - set(c.toInt(), value) - } + private operator fun ByteArray.set(c: Char, value: Byte) { + set(c.toInt(), value) + } - /** - * Instances of this class group all the complex data structures needed to support escape and unescape - * operations for XML. - * - * In contrast with HTML escape operations, the entity references to be used for XML escape/unescape operations - * can be defined by the user by manually creating an instance of this class containing all the entities he/she - * wants to escape. - * - * It is **not** recommended to use this XML class for HTML escape/unescape operations. Use the methods - * in [org.unbescape.html.HtmlEscape] instead, as HTML escape rules include a series of tweaks not allowed in - * XML, as well as being less lenient with regard to aspects such as case-sensitivity. Besides, the HTML escape - * infrastructure is able to apply a series of performance optimizations not possible in XML due to the fact that - * the number of HTML Character Entity References (*Named Character References* in HTML5 jargon) is fixed - * and known in advance. - * - * Objects of this class are **thread-safe**. - */ - class XmlEscapeSymbols - /* - * Create a new XmlEscapeSymbols structure. This will initialize all the structures needed to cover the - * specified references and escape levels, including sorted arrays, overflow maps, etc. - */ - internal constructor(references: References, - escapeLevels: ByteArray, - /* - * This object will be in charge of validating each codepoint in input, in order to determine - * whether such codepoint will be allowed in escaped output (escaped or not). Invalid codepoints - * will be simply discarded. - */ - val CODEPOINT_VALIDATOR: XmlCodepointValidator) { + /** + * Instances of this class group all the complex data structures needed to support escape and unescape + * operations for XML. + * + * In contrast with HTML escape operations, the entity references to be used for XML escape/unescape operations + * can be defined by the user by manually creating an instance of this class containing all the entities he/she + * wants to escape. + * + * It is **not** recommended to use this XML class for HTML escape/unescape operations. Use the methods + * in [org.unbescape.html.HtmlEscape] instead, as HTML escape rules include a series of tweaks not allowed in + * XML, as well as being less lenient with regard to aspects such as case-sensitivity. Besides, the HTML escape + * infrastructure is able to apply a series of performance optimizations not possible in XML due to the fact that + * the number of HTML Character Entity References (*Named Character References* in HTML5 jargon) is fixed + * and known in advance. + * + * Objects of this class are **thread-safe**. + */ + class XmlEscapeSymbols + /* + * Create a new XmlEscapeSymbols structure. This will initialize all the structures needed to cover the + * specified references and escape levels, including sorted arrays, overflow maps, etc. + */ + internal constructor(references: References, + escapeLevels: ByteArray, + /* + * This object will be in charge of validating each codepoint in input, in order to determine + * whether such codepoint will be allowed in escaped output (escaped or not). Invalid codepoints + * will be simply discarded. + */ + val CODEPOINT_VALIDATOR: XmlCodepointValidator) { - /* - * This array will hold the 'escape level' assigned to chars (not codepoints) up to LEVELS_LEN. - * - The last position of this array will be used for determining the level of all codepoints >= (LEVELS_LEN - 1) - */ - val ESCAPE_LEVELS = ByteArray(LEVELS_LEN) + /* + * This array will hold the 'escape level' assigned to chars (not codepoints) up to LEVELS_LEN. + * - The last position of this array will be used for determining the level of all codepoints >= (LEVELS_LEN - 1) + */ + val ESCAPE_LEVELS = ByteArray(LEVELS_LEN) - /* - * This array will contain all the codepoints that might be escaped, numerically ordered. - * - Positions in this array will correspond to positions in the SORTED_CERS_BY_CODEPOINT array, so that one array - * (this one) holds the codepoints while the other one holds the CERs such codepoints refer to. - * - Gives the opportunity to store all codepoints in numerical order and therefore be able to perform - * binary search operations in order to quickly find codepoints (and translate to CERs) when escaping. - */ - val SORTED_CODEPOINTS: IntArray + /* + * This array will contain all the codepoints that might be escaped, numerically ordered. + * - Positions in this array will correspond to positions in the SORTED_CERS_BY_CODEPOINT array, so that one array + * (this one) holds the codepoints while the other one holds the CERs such codepoints refer to. + * - Gives the opportunity to store all codepoints in numerical order and therefore be able to perform + * binary search operations in order to quickly find codepoints (and translate to CERs) when escaping. + */ + val SORTED_CODEPOINTS: IntArray - /* - * This array contains all the CERs corresponding to the codepoints stored in SORTED_CODEPOINTS. This array is - * ordered so that each index in SORTED_CODEPOINTS can also be used to retrieve the corresponding CER when used - * on this array. - */ - val SORTED_CERS_BY_CODEPOINT: Array + /* + * This array contains all the CERs corresponding to the codepoints stored in SORTED_CODEPOINTS. This array is + * ordered so that each index in SORTED_CODEPOINTS can also be used to retrieve the corresponding CER when used + * on this array. + */ + val SORTED_CERS_BY_CODEPOINT: Array - /* - * This array will contain all the CERs that might be unescaped, alphabetically ordered. - * - Positions in this array will correspond to positions in the SORTED_CODEPOINTS_BY_CER array, so that one array - * (this one) holds the CERs while the other one holds the codepoint(s) such CERs refer to. - * - Gives the opportunity to store all CERs in alphabetical order and therefore be able to perform - * binary search operations in order to quickly find CERs (and translate to codepoints) when unescaping. - */ - val SORTED_CERS: Array + /* + * This array will contain all the CERs that might be unescaped, alphabetically ordered. + * - Positions in this array will correspond to positions in the SORTED_CODEPOINTS_BY_CER array, so that one array + * (this one) holds the CERs while the other one holds the codepoint(s) such CERs refer to. + * - Gives the opportunity to store all CERs in alphabetical order and therefore be able to perform + * binary search operations in order to quickly find CERs (and translate to codepoints) when unescaping. + */ + val SORTED_CERS: Array - /* - * This array contains all the codepoints corresponding to the CERs stored in SORTED_CERS. This array is - * ordered so that each index in SORTED_CERS can also be used to retrieve the corresponding CODEPOINT when used - * on this array. - */ - val SORTED_CODEPOINTS_BY_CER: IntArray + /* + * This array contains all the codepoints corresponding to the CERs stored in SORTED_CERS. This array is + * ordered so that each index in SORTED_CERS can also be used to retrieve the corresponding CODEPOINT when used + * on this array. + */ + val SORTED_CODEPOINTS_BY_CER: IntArray - init { + init { - // Initialize escape levels: just copy the array - System.arraycopy(escapeLevels, 0, ESCAPE_LEVELS, 0, LEVELS_LEN) + // Initialize escape levels: just copy the array + System.arraycopy(escapeLevels, 0, ESCAPE_LEVELS, 0, LEVELS_LEN) - // Initialize the length of the escaping structures - val structureLen = references.references.size + // Initialize the length of the escaping structures + val structureLen = references.references.size - // Initialize some auxiliary structures - val cers = ArrayList(structureLen + 5) - val codepoints = ArrayList(structureLen + 5) + // Initialize some auxiliary structures + val cers = ArrayList(structureLen + 5) + val codepoints = ArrayList(structureLen + 5) - // For each reference, initialize its corresponding codepoint -> CER and CER -> codepoint structures - for (reference in references.references) { - cers.add(reference.cer) // can be null - codepoints.add(Integer.valueOf(reference.codepoint)) - } + // For each reference, initialize its corresponding codepoint -> CER and CER -> codepoint structures + for (reference in references.references) { + cers.add(reference.cer) // can be null + codepoints.add(Integer.valueOf(reference.codepoint)) + } - // We can initialize now the arrays - SORTED_CODEPOINTS = IntArray(structureLen) - SORTED_CERS_BY_CODEPOINT = arrayOfNulls(structureLen) - SORTED_CERS = arrayOfNulls(structureLen) - SORTED_CODEPOINTS_BY_CER = IntArray(structureLen) + // We can initialize now the arrays + SORTED_CODEPOINTS = IntArray(structureLen) + SORTED_CERS_BY_CODEPOINT = arrayOfNulls(structureLen) + SORTED_CERS = arrayOfNulls(structureLen) + SORTED_CODEPOINTS_BY_CER = IntArray(structureLen) - val cersOrdered = ArrayList(cers) - Collections.sort(cersOrdered) { o1, o2 -> String(o1).compareTo(String(o2)) } + val cersOrdered = ArrayList(cers) + Collections.sort(cersOrdered) { o1, o2 -> String(o1).compareTo(String(o2)) } - val codepointsOrdered = ArrayList(codepoints) - Collections.sort(codepointsOrdered) + val codepointsOrdered = ArrayList(codepoints) + Collections.sort(codepointsOrdered) - // Order the CODEPOINT -> CERs (escape)structures - for (i in 0..structureLen - 1) { - val codepoint = codepointsOrdered[i] - SORTED_CODEPOINTS[i] = codepoint - for (j in 0..structureLen - 1) { - if (codepoint == codepoints[j]) { - SORTED_CERS_BY_CODEPOINT[i] = cers[j] - break - } - } - } + // Order the CODEPOINT -> CERs (escape)structures + for (i in 0..structureLen - 1) { + val codepoint = codepointsOrdered[i] + SORTED_CODEPOINTS[i] = codepoint + for (j in 0..structureLen - 1) { + if (codepoint == codepoints[j]) { + SORTED_CERS_BY_CODEPOINT[i] = cers[j] + break + } + } + } - // Order the CERs -> CODEPOINT (unescape)structures - for (i in 0..structureLen - 1) { - val cer = cersOrdered[i] - SORTED_CERS[i] = cer - for (j in 0..structureLen - 1) { - if (Arrays.equals(cer, cers[j])) { - SORTED_CODEPOINTS_BY_CER[i] = codepoints[j] - break - } - } - } - } + // Order the CERs -> CODEPOINT (unescape)structures + for (i in 0..structureLen - 1) { + val cer = cersOrdered[i] + SORTED_CERS[i] = cer + for (j in 0..structureLen - 1) { + if (Arrays.equals(cer, cers[j])) { + SORTED_CODEPOINTS_BY_CER[i] = codepoints[j] + break + } + } + } + } - /* - * Inner utility classes that model the named character references to be included in an initialized - * instance of the XmlEscapeSymbols class. - */ - class References { + /* + * Inner utility classes that model the named character references to be included in an initialized + * instance of the XmlEscapeSymbols class. + */ + class References { - internal val references = ArrayList(200) + internal val references = ArrayList(200) - fun addReference(codepoint: Int, cer: String) { - this.references.add(Reference(cer, codepoint)) - } - } + fun addReference(codepoint: Int, cer: String) { + this.references.add(Reference(cer, codepoint)) + } + } - class Reference internal constructor(cer: String, internal val codepoint: Int) { - // cer CAN be null -> codepoint should be removed from escaped output. - internal val cer: CharArray = cer.toCharArray() - } + class Reference internal constructor(cer: String, internal val codepoint: Int) { + // cer CAN be null -> codepoint should be removed from escaped output. + internal val cer: CharArray = cer.toCharArray() + } - companion object { - /* - * Size of the array specifying the escape levels. - */ - val LEVELS_LEN = (0x9f + 2) - } - } + companion object { + /* + * Size of the array specifying the escape levels. + */ + val LEVELS_LEN = (0x9f + 2) + } + } } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/out/XmlOutputReport.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/out/XmlOutputReport.kt index 0b5377011..8d4774b1a 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/out/XmlOutputReport.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/out/XmlOutputReport.kt @@ -12,53 +12,53 @@ import io.gitlab.arturbosch.detekt.api.Severity */ class XmlOutputReport : OutputReport() { - override val ending: String = "xml" + override val ending: String = "xml" - override val name = "Checkstyle XML report" + override val name = "Checkstyle XML report" - private sealed class MessageType(val label: String) { - class Warning : MessageType("warning") - class Info : MessageType("info") - class Fatal : MessageType("fatal") - class Error : MessageType("error") - } + private sealed class MessageType(val label: String) { + class Warning : MessageType("warning") + class Info : MessageType("info") + class Fatal : MessageType("fatal") + class Error : MessageType("error") + } - override fun render(detektion: Detektion): String { - val smells = detektion.findings.flatMap { it.value } + override fun render(detektion: Detektion): String { + val smells = detektion.findings.flatMap { it.value } - val lines = ArrayList() - lines += "" - lines += "" + val lines = ArrayList() + lines += "" + lines += "" - smells.groupBy { it.location.file }.forEach { fileName, findings -> - lines += "" - findings.forEach { - lines += arrayOf( - "\t" - ).joinToString(separator = " ") - } - lines += "" - } + smells.groupBy { it.location.file }.forEach { fileName, findings -> + lines += "" + findings.forEach { + lines += arrayOf( + "\t" + ).joinToString(separator = " ") + } + lines += "" + } - lines += "" - return lines.joinToString(separator = "\n") - } + lines += "" + return lines.joinToString(separator = "\n") + } - private val Finding.messageType: MessageType - get() = when (issue.severity) { - Severity.CodeSmell -> MessageType.Warning() - Severity.Style -> MessageType.Warning() - Severity.Warning -> MessageType.Warning() - Severity.Maintainability -> MessageType.Warning() - Severity.Defect -> MessageType.Error() - Severity.Minor -> MessageType.Info() - Severity.Security -> MessageType.Fatal() - Severity.Performance -> MessageType.Warning() - } + private val Finding.messageType: MessageType + get() = when (issue.severity) { + Severity.CodeSmell -> MessageType.Warning() + Severity.Style -> MessageType.Warning() + Severity.Warning -> MessageType.Warning() + Severity.Maintainability -> MessageType.Warning() + Severity.Defect -> MessageType.Error() + Severity.Minor -> MessageType.Info() + Severity.Security -> MessageType.Fatal() + Severity.Performance -> MessageType.Warning() + } - private fun Any.toXmlString() = XmlEscape.escapeXml(toString().trim()) + private fun Any.toXmlString() = XmlEscape.escapeXml(toString().trim()) } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/runners/AstPrinter.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/runners/AstPrinter.kt index b548da7e2..d57e35543 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/runners/AstPrinter.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/runners/AstPrinter.kt @@ -16,69 +16,69 @@ import org.jetbrains.kotlin.psi.KtStatementExpression */ class AstPrinter(private val arguments: CliArgs) : Executable { - override fun execute() { - require(arguments.inputPaths.size == 1) { - "More than one input path specified. Printing AST is only supported for single files." - } - require(arguments.inputPaths.first().isFile()) { - "Input path must be a kotlin file and not a directory." - } + override fun execute() { + require(arguments.inputPaths.size == 1) { + "More than one input path specified. Printing AST is only supported for single files." + } + require(arguments.inputPaths.first().isFile()) { + "Input path must be a kotlin file and not a directory." + } - val input = arguments.inputPaths.first() - val ktFile = KtCompiler().compile(input, input) - println(ElementPrinter.dump(ktFile)) - } + val input = arguments.inputPaths.first() + val ktFile = KtCompiler().compile(input, input) + println(ElementPrinter.dump(ktFile)) + } } class ElementPrinter : DetektVisitor() { - companion object { - fun dump(file: KtFile): String = ElementPrinter().run { - sb.appendln("0: " + file.javaClass.simpleName) - visitKtFile(file) - sb.toString() - } - } + companion object { + fun dump(file: KtFile): String = ElementPrinter().run { + sb.appendln("0: " + file.javaClass.simpleName) + visitKtFile(file) + sb.toString() + } + } - private val sb = StringBuilder() + private val sb = StringBuilder() - private val indentation - get() = (0..indent).joinToString("") { " " } + private val indentation + get() = (0..indent).joinToString("") { " " } - private val KtElement.line - get() = PsiDiagnosticUtils.offsetToLineAndColumn( - containingFile.viewProvider.document, - textRange.startOffset).line + private val KtElement.line + get() = PsiDiagnosticUtils.offsetToLineAndColumn( + containingFile.viewProvider.document, + textRange.startOffset).line - private val KtElement.dump - get() = indentation + line + ": " + javaClass.simpleName + private val KtElement.dump + get() = indentation + line + ": " + javaClass.simpleName - private var indent: Int = 0 - private var lastLine = 0 + private var indent: Int = 0 + private var lastLine = 0 - override fun visitKtElement(element: KtElement) { - val currentLine = element.line - if (element.isContainer()) { - indent++ - sb.appendln(element.dump) - } else { - if (lastLine == currentLine) { - indent++ - sb.appendln(element.dump) - indent-- - } else { - sb.appendln(element.dump) - } - } - lastLine = currentLine - super.visitKtElement(element) - if (element.isContainer()) { - indent-- - } - } + override fun visitKtElement(element: KtElement) { + val currentLine = element.line + if (element.isContainer()) { + indent++ + sb.appendln(element.dump) + } else { + if (lastLine == currentLine) { + indent++ + sb.appendln(element.dump) + indent-- + } else { + sb.appendln(element.dump) + } + } + lastLine = currentLine + super.visitKtElement(element) + if (element.isContainer()) { + indent-- + } + } - private fun KtElement.isContainer() = - this is KtStatementExpression || - this is KtDeclarationContainer || - this is KtContainerNode + private fun KtElement.isContainer() = + this is KtStatementExpression || + this is KtDeclarationContainer || + this is KtContainerNode } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/runners/ConfigExporter.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/runners/ConfigExporter.kt index bccaad10e..e7dd35486 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/runners/ConfigExporter.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/runners/ConfigExporter.kt @@ -9,9 +9,9 @@ import java.io.File */ class ConfigExporter : Executable { - override fun execute() { - val defaultConfig = ClasspathResourceConverter().convert(DEFAULT_CONFIG).openStream() - defaultConfig.copyTo(File(DEFAULT_CONFIG).outputStream()) - println("\nSuccessfully copied $DEFAULT_CONFIG to project location.") - } + override fun execute() { + val defaultConfig = ClasspathResourceConverter().convert(DEFAULT_CONFIG).openStream() + defaultConfig.copyTo(File(DEFAULT_CONFIG).outputStream()) + println("\nSuccessfully copied $DEFAULT_CONFIG to project location.") + } } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/runners/Executable.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/runners/Executable.kt index c71f4a11f..0d0b38d24 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/runners/Executable.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/runners/Executable.kt @@ -4,5 +4,5 @@ package io.gitlab.arturbosch.detekt.cli.runners * @author Artur Bosch */ interface Executable { - fun execute() + fun execute() } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/runners/Runner.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/runners/Runner.kt index aec2a1da2..cfe846c72 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/runners/Runner.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/runners/Runner.kt @@ -15,30 +15,30 @@ import kotlin.system.measureTimeMillis */ class Runner(private val arguments: CliArgs) : Executable { - override fun execute() { - val settings = createSettings() + override fun execute() { + val settings = createSettings() - val time = measureTimeMillis { - val detektion = DetektFacade.create(settings).run() - OutputFacade(arguments, detektion, settings).run() - } + val time = measureTimeMillis { + val detektion = DetektFacade.create(settings).run() + OutputFacade(arguments, detektion, settings).run() + } - println("\ndetekt finished in $time ms.") - } + println("\ndetekt finished in $time ms.") + } - private fun createSettings(): ProcessingSettings { - with(arguments) { - val pathFilters = createPathFilters() - val plugins = createPlugins() - val config = loadConfiguration() + private fun createSettings(): ProcessingSettings { + with(arguments) { + val pathFilters = createPathFilters() + val plugins = createPlugins() + val config = loadConfiguration() - return ProcessingSettings( - inputPaths = inputPaths, - config = config, - pathFilters = pathFilters, - parallelCompilation = parallel, - excludeDefaultRuleSets = disableDefaultRuleSets, - pluginPaths = plugins) - } - } + return ProcessingSettings( + inputPaths = inputPaths, + config = config, + pathFilters = pathFilters, + parallelCompilation = parallel, + excludeDefaultRuleSets = disableDefaultRuleSets, + pluginPaths = plugins) + } + } } diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/runners/SingleRuleRunner.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/runners/SingleRuleRunner.kt index fdfda8baf..fb2e52cec 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/runners/SingleRuleRunner.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/runners/SingleRuleRunner.kt @@ -20,45 +20,46 @@ import io.gitlab.arturbosch.detekt.core.RuleSetLocator */ class SingleRuleRunner(private val arguments: CliArgs) : Executable { - override fun execute() { - val (ruleSet, rule: RuleId) = arguments.runRule?.split(":") - ?: throw IllegalStateException("Unexpected empty 'runRule' argument.") + override fun execute() { + val (ruleSet, rule: RuleId) = arguments.runRule?.split(":") + ?: throw IllegalStateException("Unexpected empty 'runRule' argument.") - val settings = ProcessingSettings( - arguments.inputPaths, - arguments.loadConfiguration(), - arguments.createPathFilters(), - arguments.parallel, - arguments.disableDefaultRuleSets, - arguments.createPlugins()) + val settings = ProcessingSettings( + arguments.inputPaths, + arguments.loadConfiguration(), + arguments.createPathFilters(), + arguments.parallel, + arguments.disableDefaultRuleSets, + arguments.createPlugins()) - val realProvider = RuleSetLocator(settings).load() - .find { it.ruleSetId == ruleSet } - ?: throw IllegalArgumentException("There was no rule set with id '$ruleSet'.") + val realProvider = RuleSetLocator(settings).load() + .find { it.ruleSetId == ruleSet } + ?: throw IllegalArgumentException("There was no rule set with id '$ruleSet'.") - val provider = RuleProducingProvider(rule, realProvider) - val detektion = DetektFacade.create( - settings, - listOf(provider), - listOf(DetektProgressListener()) - ).run() - OutputFacade(arguments, detektion, settings).run() - } + val provider = RuleProducingProvider(rule, realProvider) + val detektion = DetektFacade.create( + settings, + listOf(provider), + listOf(DetektProgressListener()) + ).run() + OutputFacade(arguments, detektion, settings).run() + } } private class RuleProducingProvider( - private val ruleId: RuleId, - private val provider: RuleSetProvider) : RuleSetProvider { + private val ruleId: RuleId, + private val provider: RuleSetProvider +) : RuleSetProvider { - override val ruleSetId: String = provider.ruleSetId + "-" + ruleId + override val ruleSetId: String = provider.ruleSetId + "-" + ruleId - override fun instance(config: Config): RuleSet = RuleSet( - ruleSetId, - listOf(produceRule()) - ) + override fun instance(config: Config): RuleSet = RuleSet( + ruleSetId, + listOf(produceRule()) + ) - private fun produceRule(): BaseRule = (provider.buildRuleset(Config.empty) - ?.rules - ?.find { it.ruleId == ruleId } - ?: throw IllegalArgumentException("There was no rule '$ruleId' in rule set '${provider.ruleSetId}'.")) + private fun produceRule(): BaseRule = (provider.buildRuleset(Config.empty) + ?.rules + ?.find { it.ruleId == ruleId } + ?: throw IllegalArgumentException("There was no rule '$ruleId' in rule set '${provider.ruleSetId}'.")) } diff --git a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/CliArgsSpec.kt b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/CliArgsSpec.kt index 8a70161d7..e2f86f1ca 100644 --- a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/CliArgsSpec.kt +++ b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/CliArgsSpec.kt @@ -2,49 +2,49 @@ package io.gitlab.arturbosch.detekt.cli import com.beust.jcommander.ParameterException import io.gitlab.arturbosch.detekt.test.resource +import java.nio.file.Path +import java.nio.file.Paths import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThatExceptionOfType import org.jetbrains.spek.api.Spek import org.jetbrains.spek.api.dsl.describe import org.jetbrains.spek.api.dsl.it -import java.nio.file.Path -import java.nio.file.Paths internal class CliArgsSpec : Spek({ - val projectPath = Paths.get(resource("/empty.txt")).parent.parent.parent.parent.toAbsolutePath() + val projectPath = Paths.get(resource("/empty.txt")).parent.parent.parent.parent.toAbsolutePath() - describe("Parsing the input path") { + describe("Parsing the input path") { - it("the current working directory is used if parameter is not set") { - val (cli, _) = parseArguments(emptyArray()) - assertThat(cli.inputPaths).hasSize(1) - assertThat(cli.inputPaths.first()).isEqualTo(Paths.get(System.getProperty("user.dir"))) - } + it("the current working directory is used if parameter is not set") { + val (cli, _) = parseArguments(emptyArray()) + assertThat(cli.inputPaths).hasSize(1) + assertThat(cli.inputPaths.first()).isEqualTo(Paths.get(System.getProperty("user.dir"))) + } - it("a single value is converted to a path") { - val (cli, _) = parseArguments(arrayOf("--input", "$projectPath")) - assertThat(cli.inputPaths).hasSize(1) - assertThat(cli.inputPaths.first().toAbsolutePath()).isEqualTo(projectPath) - } + it("a single value is converted to a path") { + val (cli, _) = parseArguments(arrayOf("--input", "$projectPath")) + assertThat(cli.inputPaths).hasSize(1) + assertThat(cli.inputPaths.first().toAbsolutePath()).isEqualTo(projectPath) + } - it("multiple imput paths can be separated by comma") { - val mainPath = projectPath.resolve("src/main").toAbsolutePath() - val testPath = projectPath.resolve("src/test").toAbsolutePath() - val (cli, _) = parseArguments(arrayOf( - "--input", "$mainPath,$testPath") - ) - assertThat(cli.inputPaths).hasSize(2) - assertThat(cli.inputPaths.map(Path::toAbsolutePath)).containsExactlyInAnyOrder(mainPath, testPath) - } + it("multiple imput paths can be separated by comma") { + val mainPath = projectPath.resolve("src/main").toAbsolutePath() + val testPath = projectPath.resolve("src/test").toAbsolutePath() + val (cli, _) = parseArguments(arrayOf( + "--input", "$mainPath,$testPath") + ) + assertThat(cli.inputPaths).hasSize(2) + assertThat(cli.inputPaths.map(Path::toAbsolutePath)).containsExactlyInAnyOrder(mainPath, testPath) + } - it("reports an error if the input path does not exist") { - val pathToNonExistentDirectory = projectPath.resolve("nonExistent") - val params = arrayOf("--input", "$pathToNonExistentDirectory") + it("reports an error if the input path does not exist") { + val pathToNonExistentDirectory = projectPath.resolve("nonExistent") + val params = arrayOf("--input", "$pathToNonExistentDirectory") - assertThatExceptionOfType(ParameterException::class.java) - .isThrownBy { parseArguments(params).first.inputPaths } - .withMessageContaining("does not exist") - } - } + assertThatExceptionOfType(ParameterException::class.java) + .isThrownBy { parseArguments(params).first.inputPaths } + .withMessageContaining("does not exist") + } + } }) diff --git a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/ConfigAssert.kt b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/ConfigAssert.kt index cebf09640..746551c83 100644 --- a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/ConfigAssert.kt +++ b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/ConfigAssert.kt @@ -3,69 +3,70 @@ package io.gitlab.arturbosch.detekt.cli import io.gitlab.arturbosch.detekt.api.Config import io.gitlab.arturbosch.detekt.api.Rule import io.gitlab.arturbosch.detekt.api.YamlConfig +import java.lang.reflect.Field +import java.lang.reflect.Modifier import org.assertj.core.api.Assertions import org.assertj.core.api.Assertions.assertThat import org.reflections.Reflections -import java.lang.reflect.Field -import java.lang.reflect.Modifier class ConfigAssert( - private val config: Config, - private val name: String, - private val packageName: String) { + private val config: Config, + private val name: String, + private val packageName: String +) { - fun assert() { - val ymlDeclarations = getYmlRuleConfig().properties.filter { it.key != "active" } - assertThat(ymlDeclarations).isNotEmpty - val ruleClasses = getRuleClasses() - assertThat(ruleClasses).isNotEmpty - assertThat(ruleClasses).hasSize(ymlDeclarations.size) + fun assert() { + val ymlDeclarations = getYmlRuleConfig().properties.filter { it.key != "active" } + assertThat(ymlDeclarations).isNotEmpty + val ruleClasses = getRuleClasses() + assertThat(ruleClasses).isNotEmpty + assertThat(ruleClasses).hasSize(ymlDeclarations.size) - checkRules(ruleClasses, ymlDeclarations) - } + checkRules(ruleClasses, ymlDeclarations) + } - private fun checkRules(ruleClasses: List>, ymlDeclarations: Map) { - for (ruleClass in ruleClasses) { - val ymlDeclaration = ymlDeclarations.filter { it.key == ruleClass.simpleName } - if (ymlDeclaration.keys.size != 1) { - Assertions.fail("${ruleClass.simpleName} rule is not correctly defined in $CONFIG_FILE") - } + private fun checkRules(ruleClasses: List>, ymlDeclarations: Map) { + for (ruleClass in ruleClasses) { + val ymlDeclaration = ymlDeclarations.filter { it.key == ruleClass.simpleName } + if (ymlDeclaration.keys.size != 1) { + Assertions.fail("${ruleClass.simpleName} rule is not correctly defined in $CONFIG_FILE") + } - @Suppress("UNCHECKED_CAST") - val options = ymlDeclaration.iterator().next().value as HashMap - checkOptions(options, ruleClass) - } - } + @Suppress("UNCHECKED_CAST") + val options = ymlDeclaration.iterator().next().value as HashMap + checkOptions(options, ruleClass) + } + } - private fun checkOptions(ymlOptions: HashMap, ruleClass: Class) { - val configFields = ruleClass.declaredFields.filter { isPublicStaticFinal(it) && it.name != "Companion" } - var filter = ymlOptions.filterKeys { it != "active" } - if (filter.containsKey(THRESHOLD)) { - assertThat(ruleClass.superclass.simpleName).isEqualTo(THRESHOLD_RULE) - filter = filter.filterKeys { it != THRESHOLD } - } - for (ymlOption in filter) { - val configField = configFields.singleOrNull { ymlOption.key == it.get(null) } - if (configField == null) { - Assertions.fail("${ymlOption.key} option for ${ruleClass.simpleName} rule is not correctly " + - "defined") - } - } - } + private fun checkOptions(ymlOptions: HashMap, ruleClass: Class) { + val configFields = ruleClass.declaredFields.filter { isPublicStaticFinal(it) && it.name != "Companion" } + var filter = ymlOptions.filterKeys { it != "active" } + if (filter.containsKey(THRESHOLD)) { + assertThat(ruleClass.superclass.simpleName).isEqualTo(THRESHOLD_RULE) + filter = filter.filterKeys { it != THRESHOLD } + } + for (ymlOption in filter) { + val configField = configFields.singleOrNull { ymlOption.key == it.get(null) } + if (configField == null) { + Assertions.fail("${ymlOption.key} option for ${ruleClass.simpleName} rule is not correctly " + + "defined") + } + } + } - private fun getYmlRuleConfig() = config.subConfig(name) as? YamlConfig - ?: throw IllegalStateException("yaml config expected but got ${config.javaClass}") + private fun getYmlRuleConfig() = config.subConfig(name) as? YamlConfig + ?: throw IllegalStateException("yaml config expected but got ${config.javaClass}") - private fun getRuleClasses(): List> { - return Reflections(packageName) - .getSubTypesOf(Rule::class.java) - .filter { !Modifier.isAbstract(it.modifiers) } - } + private fun getRuleClasses(): List> { + return Reflections(packageName) + .getSubTypesOf(Rule::class.java) + .filter { !Modifier.isAbstract(it.modifiers) } + } - private fun isPublicStaticFinal(it: Field): Boolean { - val modifiers = it.modifiers - return Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers) && Modifier.isFinal(modifiers) - } + private fun isPublicStaticFinal(it: Field): Boolean { + val modifiers = it.modifiers + return Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers) && Modifier.isFinal(modifiers) + } } private const val THRESHOLD_RULE = "ThresholdRule" diff --git a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/ConfigurationsSpec.kt b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/ConfigurationsSpec.kt index 4354b9d49..e242fa7b2 100644 --- a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/ConfigurationsSpec.kt +++ b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/ConfigurationsSpec.kt @@ -16,194 +16,194 @@ import org.jetbrains.spek.api.dsl.it */ internal class ConfigurationsSpec : Spek({ - it("should be an empty config") { - val config = CliArgs().loadConfiguration() - assertThat(config.valueOrDefault("one", -1)).isEqualTo(-1) - assertThat(config.valueOrDefault("two", -1)).isEqualTo(-1) - assertThat(config.valueOrDefault("three", -1)).isEqualTo(-1) - } + it("should be an empty config") { + val config = CliArgs().loadConfiguration() + assertThat(config.valueOrDefault("one", -1)).isEqualTo(-1) + assertThat(config.valueOrDefault("two", -1)).isEqualTo(-1) + assertThat(config.valueOrDefault("three", -1)).isEqualTo(-1) + } - describe("parse different path based configuration settings") { - val pathOne = resource("/configs/one.yml").path - val pathTwo = resource("/configs/two.yml").path - val pathThree = resource("/configs/three.yml").path + describe("parse different path based configuration settings") { + val pathOne = resource("/configs/one.yml").path + val pathTwo = resource("/configs/two.yml").path + val pathThree = resource("/configs/three.yml").path - it("should load single config") { - val config = CliArgs().apply { config = pathOne }.loadConfiguration() - assertThat(config.valueOrDefault("one", -1)).isEqualTo(1) - } + it("should load single config") { + val config = CliArgs().apply { config = pathOne }.loadConfiguration() + assertThat(config.valueOrDefault("one", -1)).isEqualTo(1) + } - it("should load two configs") { - val config = CliArgs().apply { config = "$pathOne, $pathTwo" }.loadConfiguration() - assertThat(config.valueOrDefault("one", -1)).isEqualTo(1) - assertThat(config.valueOrDefault("two", -1)).isEqualTo(2) - } + it("should load two configs") { + val config = CliArgs().apply { config = "$pathOne, $pathTwo" }.loadConfiguration() + assertThat(config.valueOrDefault("one", -1)).isEqualTo(1) + assertThat(config.valueOrDefault("two", -1)).isEqualTo(2) + } - it("should load three configs") { - val config = CliArgs().apply { config = "$pathOne, $pathTwo;$pathThree" }.loadConfiguration() - assertThat(config.valueOrDefault("one", -1)).isEqualTo(1) - assertThat(config.valueOrDefault("two", -1)).isEqualTo(2) - assertThat(config.valueOrDefault("three", -1)).isEqualTo(3) - } + it("should load three configs") { + val config = CliArgs().apply { config = "$pathOne, $pathTwo;$pathThree" }.loadConfiguration() + assertThat(config.valueOrDefault("one", -1)).isEqualTo(1) + assertThat(config.valueOrDefault("two", -1)).isEqualTo(2) + assertThat(config.valueOrDefault("three", -1)).isEqualTo(3) + } - it("should fail on invalid config value") { - assertThatIllegalArgumentException().isThrownBy { CliArgs().apply { config = "," }.loadConfiguration() } - assertThatExceptionOfType(ParameterException::class.java).isThrownBy { CliArgs().apply { config = "sfsjfsdkfsd" }.loadConfiguration() } - assertThatExceptionOfType(ParameterException::class.java).isThrownBy { CliArgs().apply { config = "./i.do.not.exist.yml" }.loadConfiguration() } - } - } + it("should fail on invalid config value") { + assertThatIllegalArgumentException().isThrownBy { CliArgs().apply { config = "," }.loadConfiguration() } + assertThatExceptionOfType(ParameterException::class.java).isThrownBy { CliArgs().apply { config = "sfsjfsdkfsd" }.loadConfiguration() } + assertThatExceptionOfType(ParameterException::class.java).isThrownBy { CliArgs().apply { config = "./i.do.not.exist.yml" }.loadConfiguration() } + } + } - describe("parse different resource based configuration settings") { + describe("parse different resource based configuration settings") { - it("should load single config") { - val config = CliArgs().apply { configResource = "/configs/one.yml" }.loadConfiguration() - assertThat(config.valueOrDefault("one", -1)).isEqualTo(1) - } + it("should load single config") { + val config = CliArgs().apply { configResource = "/configs/one.yml" }.loadConfiguration() + assertThat(config.valueOrDefault("one", -1)).isEqualTo(1) + } - it("should load two configs") { - val config = CliArgs().apply { configResource = "/configs/one.yml, /configs/two.yml" }.loadConfiguration() - assertThat(config.valueOrDefault("one", -1)).isEqualTo(1) - assertThat(config.valueOrDefault("two", -1)).isEqualTo(2) - } + it("should load two configs") { + val config = CliArgs().apply { configResource = "/configs/one.yml, /configs/two.yml" }.loadConfiguration() + assertThat(config.valueOrDefault("one", -1)).isEqualTo(1) + assertThat(config.valueOrDefault("two", -1)).isEqualTo(2) + } - it("should load three configs") { - val config = CliArgs().apply { - configResource = "/configs/one.yml, /configs/two.yml;configs/three.yml" - }.loadConfiguration() - assertThat(config.valueOrDefault("one", -1)).isEqualTo(1) - assertThat(config.valueOrDefault("two", -1)).isEqualTo(2) - assertThat(config.valueOrDefault("three", -1)).isEqualTo(3) - } + it("should load three configs") { + val config = CliArgs().apply { + configResource = "/configs/one.yml, /configs/two.yml;configs/three.yml" + }.loadConfiguration() + assertThat(config.valueOrDefault("one", -1)).isEqualTo(1) + assertThat(config.valueOrDefault("two", -1)).isEqualTo(2) + assertThat(config.valueOrDefault("three", -1)).isEqualTo(3) + } - it("should fail on invalid config value") { - assertThatExceptionOfType(Config.InvalidConfigurationError::class.java).isThrownBy { CliArgs().apply { configResource = "," }.loadConfiguration() } - assertThatExceptionOfType(ParameterException::class.java).isThrownBy { CliArgs().apply { configResource = "sfsjfsdkfsd" }.loadConfiguration() } - assertThatExceptionOfType(ParameterException::class.java).isThrownBy { CliArgs().apply { configResource = "./i.do.not.exist.yml" }.loadConfiguration() } - } - } + it("should fail on invalid config value") { + assertThatExceptionOfType(Config.InvalidConfigurationError::class.java).isThrownBy { CliArgs().apply { configResource = "," }.loadConfiguration() } + assertThatExceptionOfType(ParameterException::class.java).isThrownBy { CliArgs().apply { configResource = "sfsjfsdkfsd" }.loadConfiguration() } + assertThatExceptionOfType(ParameterException::class.java).isThrownBy { CliArgs().apply { configResource = "./i.do.not.exist.yml" }.loadConfiguration() } + } + } - describe("parse different filter settings") { + describe("parse different filter settings") { - it("should load single filter") { - val filters = CliArgs().apply { filters = ".*/one/.*" }.createPathFilters() - assertThat(filters).containsExactly(PathFilter(".*/one/.*")) - } + it("should load single filter") { + val filters = CliArgs().apply { filters = ".*/one/.*" }.createPathFilters() + assertThat(filters).containsExactly(PathFilter(".*/one/.*")) + } - it("should load multiple comma-separated filters with no spaces around commas") { - val filters = CliArgs().apply { filters = ".*/one/.*,.*/two/.*,.*/three" }.createPathFilters() - assertThat(filters).containsExactly( - PathFilter(".*/one/.*"), - PathFilter(".*/two/.*"), - PathFilter(".*/three") - ) - } + it("should load multiple comma-separated filters with no spaces around commas") { + val filters = CliArgs().apply { filters = ".*/one/.*,.*/two/.*,.*/three" }.createPathFilters() + assertThat(filters).containsExactly( + PathFilter(".*/one/.*"), + PathFilter(".*/two/.*"), + PathFilter(".*/three") + ) + } - it("should load multiple semicolon-separated filters with no spaces around semicolons") { - val filters = CliArgs().apply { filters = ".*/one/.*;.*/two/.*;.*/three" }.createPathFilters() - assertThat(filters).containsExactly( - PathFilter(".*/one/.*"), - PathFilter(".*/two/.*"), - PathFilter(".*/three") - ) - } + it("should load multiple semicolon-separated filters with no spaces around semicolons") { + val filters = CliArgs().apply { filters = ".*/one/.*;.*/two/.*;.*/three" }.createPathFilters() + assertThat(filters).containsExactly( + PathFilter(".*/one/.*"), + PathFilter(".*/two/.*"), + PathFilter(".*/three") + ) + } - it("should load multiple comma-separated filters with spaces around commas") { - val filters = CliArgs().apply { filters = ".*/one/.* ,.*/two/.*, .*/three" }.createPathFilters() - assertThat(filters).containsExactly( - PathFilter(".*/one/.*"), - PathFilter(".*/two/.*"), - PathFilter(".*/three") - ) - } + it("should load multiple comma-separated filters with spaces around commas") { + val filters = CliArgs().apply { filters = ".*/one/.* ,.*/two/.*, .*/three" }.createPathFilters() + assertThat(filters).containsExactly( + PathFilter(".*/one/.*"), + PathFilter(".*/two/.*"), + PathFilter(".*/three") + ) + } - it("should load multiple semicolon-separated filters with spaces around semicolons") { - val filters = CliArgs().apply { filters = ".*/one/.* ;.*/two/.*; .*/three" }.createPathFilters() - assertThat(filters).containsExactly( - PathFilter(".*/one/.*"), - PathFilter(".*/two/.*"), - PathFilter(".*/three") - ) - } + it("should load multiple semicolon-separated filters with spaces around semicolons") { + val filters = CliArgs().apply { filters = ".*/one/.* ;.*/two/.*; .*/three" }.createPathFilters() + assertThat(filters).containsExactly( + PathFilter(".*/one/.*"), + PathFilter(".*/two/.*"), + PathFilter(".*/three") + ) + } - it("should load multiple mixed-separated filters with no spaces around separators") { - val filters = CliArgs().apply { filters = ".*/one/.*,.*/two/.*;.*/three" }.createPathFilters() - assertThat(filters).containsExactly( - PathFilter(".*/one/.*"), - PathFilter(".*/two/.*"), - PathFilter(".*/three") - ) - } + it("should load multiple mixed-separated filters with no spaces around separators") { + val filters = CliArgs().apply { filters = ".*/one/.*,.*/two/.*;.*/three" }.createPathFilters() + assertThat(filters).containsExactly( + PathFilter(".*/one/.*"), + PathFilter(".*/two/.*"), + PathFilter(".*/three") + ) + } - it("should load multiple mixed-separated filters with spaces around separators") { - val filters = CliArgs().apply { filters = ".*/one/.* ,.*/two/.*; .*/three" }.createPathFilters() - assertThat(filters).containsExactly( - PathFilter(".*/one/.*"), - PathFilter(".*/two/.*"), - PathFilter(".*/three") - ) - } + it("should load multiple mixed-separated filters with spaces around separators") { + val filters = CliArgs().apply { filters = ".*/one/.* ,.*/two/.*; .*/three" }.createPathFilters() + assertThat(filters).containsExactly( + PathFilter(".*/one/.*"), + PathFilter(".*/two/.*"), + PathFilter(".*/three") + ) + } - it("should ignore empty and blank filters") { - val filters = CliArgs().apply { filters = " ,,.*/three" }.createPathFilters() - assertThat(filters).containsExactly(PathFilter(".*/three")) - } + it("should ignore empty and blank filters") { + val filters = CliArgs().apply { filters = " ,,.*/three" }.createPathFilters() + assertThat(filters).containsExactly(PathFilter(".*/three")) + } - it("should fail on invalid filters values") { - assertThatIllegalArgumentException().isThrownBy { CliArgs().apply { filters = "*." }.createPathFilters() } - assertThatIllegalArgumentException().isThrownBy { CliArgs().apply { filters = "(ahel" }.createPathFilters() } - } - } + it("should fail on invalid filters values") { + assertThatIllegalArgumentException().isThrownBy { CliArgs().apply { filters = "*." }.createPathFilters() } + assertThatIllegalArgumentException().isThrownBy { CliArgs().apply { filters = "(ahel" }.createPathFilters() } + } + } - describe("fail fast only") { - val config = CliArgs().apply { configResource = "/configs/fail-fast-only.yml" }.loadConfiguration() + describe("fail fast only") { + val config = CliArgs().apply { configResource = "/configs/fail-fast-only.yml" }.loadConfiguration() - it("should override active to true by default") { - assertThat(config.subConfig("comments").subConfig("UndocumentedPublicClass").valueOrDefault("active", false)).isEqualTo(true) - } + it("should override active to true by default") { + assertThat(config.subConfig("comments").subConfig("UndocumentedPublicClass").valueOrDefault("active", false)).isEqualTo(true) + } - it("should override maxIssues to 0 by default") { - assertThat(config.subConfig("build").valueOrDefault("maxIssues", -1)).isEqualTo(0) - } + it("should override maxIssues to 0 by default") { + assertThat(config.subConfig("build").valueOrDefault("maxIssues", -1)).isEqualTo(0) + } - it("should keep config from default") { - assertThat(config.subConfig("style").subConfig("MaxLineLength").valueOrDefault("maxLineLength", -1)).isEqualTo(120) - } - } + it("should keep config from default") { + assertThat(config.subConfig("style").subConfig("MaxLineLength").valueOrDefault("maxLineLength", -1)).isEqualTo(120) + } + } - describe("fail fast override") { - val config = CliArgs().apply { configResource = "/configs/fail-fast-override.yml" }.loadConfiguration() + describe("fail fast override") { + val config = CliArgs().apply { configResource = "/configs/fail-fast-override.yml" }.loadConfiguration() - it("should override config when specified") { - assertThat(config.subConfig("style").subConfig("MaxLineLength").valueOrDefault("maxLineLength", -1)).isEqualTo(100) - } + it("should override config when specified") { + assertThat(config.subConfig("style").subConfig("MaxLineLength").valueOrDefault("maxLineLength", -1)).isEqualTo(100) + } - it("should override active when specified") { - assertThat(config.subConfig("comments").subConfig("CommentOverPrivateMethod").valueOrDefault("active", true)).isEqualTo(false) - } + it("should override active when specified") { + assertThat(config.subConfig("comments").subConfig("CommentOverPrivateMethod").valueOrDefault("active", true)).isEqualTo(false) + } - it("should override maxIssues when specified") { - assertThat(config.subConfig("build").valueOrDefault("maxIssues", -1)).isEqualTo(1) - } - } + it("should override maxIssues when specified") { + assertThat(config.subConfig("build").valueOrDefault("maxIssues", -1)).isEqualTo(1) + } + } - describe("build upon default config") { + describe("build upon default config") { - val config = CliArgs { - buildUponDefaultConfig = true - configResource = "/configs/no-fail-fast-override.yml" - }.loadConfiguration() + val config = CliArgs { + buildUponDefaultConfig = true + configResource = "/configs/no-fail-fast-override.yml" + }.loadConfiguration() - it("should override config when specified") { - assertThat(config.subConfig("style").subConfig("MaxLineLength").valueOrDefault("maxLineLength", -1)).isEqualTo(100) - assertThat(config.subConfig("style").subConfig("MaxLineLength").valueOrDefault("excludeCommentStatements", false)).isTrue() - } + it("should override config when specified") { + assertThat(config.subConfig("style").subConfig("MaxLineLength").valueOrDefault("maxLineLength", -1)).isEqualTo(100) + assertThat(config.subConfig("style").subConfig("MaxLineLength").valueOrDefault("excludeCommentStatements", false)).isTrue() + } - it("should be active=false by default") { - assertThat(config.subConfig("comments").subConfig("CommentOverPrivateFunction").valueOrDefault("active", true)).isFalse() - } + it("should be active=false by default") { + assertThat(config.subConfig("comments").subConfig("CommentOverPrivateFunction").valueOrDefault("active", true)).isFalse() + } - it("should be maxIssues=10 by default") { - assertThat(config.subConfig("build").valueOrDefault("maxIssues", -1)).isEqualTo(10) - } - } + it("should be maxIssues=10 by default") { + assertThat(config.subConfig("build").valueOrDefault("maxIssues", -1)).isEqualTo(10) + } + } }) diff --git a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/DetektYmlConfigTest.kt b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/DetektYmlConfigTest.kt index 4d0499b5e..a0beb9dc4 100644 --- a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/DetektYmlConfigTest.kt +++ b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/DetektYmlConfigTest.kt @@ -2,77 +2,77 @@ package io.gitlab.arturbosch.detekt.cli import io.gitlab.arturbosch.detekt.api.Config import io.gitlab.arturbosch.detekt.api.YamlConfig -import org.jetbrains.spek.api.Spek -import org.jetbrains.spek.api.dsl.it import java.io.File import java.nio.file.Paths +import org.jetbrains.spek.api.Spek +import org.jetbrains.spek.api.dsl.it class DetektYmlConfigTest : Spek({ - val config = loadConfig() + val config = loadConfig() - it("complexitySection") { - ConfigAssert( - config, - "complexity", - "io.gitlab.arturbosch.detekt.rules.complexity" - ).assert() - } + it("complexitySection") { + ConfigAssert( + config, + "complexity", + "io.gitlab.arturbosch.detekt.rules.complexity" + ).assert() + } - it("documentationSection") { - ConfigAssert( - config, - "comments", - "io.gitlab.arturbosch.detekt.rules.documentation" - ).assert() - } + it("documentationSection") { + ConfigAssert( + config, + "comments", + "io.gitlab.arturbosch.detekt.rules.documentation" + ).assert() + } - it("emptyBlocksSection") { - ConfigAssert( - config, - "empty-blocks", - "io.gitlab.arturbosch.detekt.rules.empty" - ).assert() - } + it("emptyBlocksSection") { + ConfigAssert( + config, + "empty-blocks", + "io.gitlab.arturbosch.detekt.rules.empty" + ).assert() + } - it("exceptionsSection") { - ConfigAssert( - config, - "exceptions", - "io.gitlab.arturbosch.detekt.rules.exceptions" - ).assert() - } + it("exceptionsSection") { + ConfigAssert( + config, + "exceptions", + "io.gitlab.arturbosch.detekt.rules.exceptions" + ).assert() + } - it("performanceSection") { - ConfigAssert( - config, - "performance", - "io.gitlab.arturbosch.detekt.rules.performance" - ).assert() - } + it("performanceSection") { + ConfigAssert( + config, + "performance", + "io.gitlab.arturbosch.detekt.rules.performance" + ).assert() + } - it("potentialBugsSection") { - ConfigAssert( - config, - "potential-bugs", - "io.gitlab.arturbosch.detekt.rules.bugs" - ).assert() - } + it("potentialBugsSection") { + ConfigAssert( + config, + "potential-bugs", + "io.gitlab.arturbosch.detekt.rules.bugs" + ).assert() + } - it("styleSection") { - ConfigAssert( - config, - "style", - "io.gitlab.arturbosch.detekt.rules.style" - ).assert() - } + it("styleSection") { + ConfigAssert( + config, + "style", + "io.gitlab.arturbosch.detekt.rules.style" + ).assert() + } }) internal const val CONFIG_FILE = "default-detekt-config.yml" private fun loadConfig(): Config { - val workingDirectory = Paths.get(".").toAbsolutePath().normalize().toString() - val file = File("$workingDirectory/src/main/resources/$CONFIG_FILE") - val url = file.toURI().toURL() - return YamlConfig.loadResource(url) + val workingDirectory = Paths.get(".").toAbsolutePath().normalize().toString() + val file = File("$workingDirectory/src/main/resources/$CONFIG_FILE") + val url = file.toURI().toURL() + return YamlConfig.loadResource(url) } diff --git a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/FileProcessorLocatorTest.kt b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/FileProcessorLocatorTest.kt index 579d10e24..cd691b5b0 100644 --- a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/FileProcessorLocatorTest.kt +++ b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/FileProcessorLocatorTest.kt @@ -4,34 +4,34 @@ import io.gitlab.arturbosch.detekt.api.FileProcessListener import io.gitlab.arturbosch.detekt.core.FileProcessorLocator import io.gitlab.arturbosch.detekt.core.ProcessingSettings import io.gitlab.arturbosch.detekt.test.resource +import java.lang.reflect.Modifier +import java.nio.file.Paths import org.assertj.core.api.Assertions import org.assertj.core.api.Assertions.assertThat import org.jetbrains.spek.api.Spek import org.jetbrains.spek.api.dsl.it import org.reflections.Reflections -import java.lang.reflect.Modifier -import java.nio.file.Paths /** * This tests the existence of all metric processors in the META-INF config file in the core package */ class FileProcessorLocatorTest : Spek({ - it("containsAllProcessors") { - val path = Paths.get(resource("")) - val locator = FileProcessorLocator(ProcessingSettings(path)) - val processors = locator.load() - val processorClasses = getProcessorClasses() + it("containsAllProcessors") { + val path = Paths.get(resource("")) + val locator = FileProcessorLocator(ProcessingSettings(path)) + val processors = locator.load() + val processorClasses = getProcessorClasses() - assertThat(processorClasses).isNotEmpty - processorClasses - .filter { clazz -> processors.firstOrNull { clazz == it.javaClass } == null } - .forEach { Assertions.fail("$it processor is not loaded by the FileProcessorLocator") } - } + assertThat(processorClasses).isNotEmpty + processorClasses + .filter { clazz -> processors.firstOrNull { clazz == it.javaClass } == null } + .forEach { Assertions.fail("$it processor is not loaded by the FileProcessorLocator") } + } }) private fun getProcessorClasses(): List> { - return Reflections("io.gitlab.arturbosch.detekt.core.processors") - .getSubTypesOf(FileProcessListener::class.java) - .filter { !Modifier.isAbstract(it.modifiers) } + return Reflections("io.gitlab.arturbosch.detekt.core.processors") + .getSubTypesOf(FileProcessListener::class.java) + .filter { !Modifier.isAbstract(it.modifiers) } } diff --git a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/OutputFacadeSpec.kt b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/OutputFacadeSpec.kt index dd469f227..49af74638 100644 --- a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/OutputFacadeSpec.kt +++ b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/OutputFacadeSpec.kt @@ -8,87 +8,86 @@ import io.gitlab.arturbosch.detekt.cli.out.XmlOutputReport import io.gitlab.arturbosch.detekt.core.DetektResult import io.gitlab.arturbosch.detekt.core.ProcessingSettings import io.gitlab.arturbosch.detekt.test.resource +import java.io.ByteArrayOutputStream +import java.io.File +import java.io.PrintStream +import java.nio.file.Path +import java.nio.file.Paths import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThatCode import org.assertj.core.api.Assertions.assertThatExceptionOfType import org.jetbrains.spek.api.Spek import org.jetbrains.spek.api.dsl.describe import org.jetbrains.spek.api.dsl.it -import java.io.ByteArrayOutputStream -import java.io.File -import java.io.PrintStream -import java.nio.file.Path -import java.nio.file.Paths /** * @author Sebastiano Poggi */ internal class OutputFacadeSpec : Spek({ - val outputStream = ByteArrayOutputStream() - val inputPath: Path = Paths.get(resource("/cases")) - val plainOutputPath = File.createTempFile("detekt", ".txt") - val htmlOutputPath = File.createTempFile("detekt", ".html") - val xmlOutputPath = File.createTempFile("detekt", ".xml") + val outputStream = ByteArrayOutputStream() + val inputPath: Path = Paths.get(resource("/cases")) + val plainOutputPath = File.createTempFile("detekt", ".txt") + val htmlOutputPath = File.createTempFile("detekt", ".html") + val xmlOutputPath = File.createTempFile("detekt", ".xml") - val defaultDetektion = DetektResult(mapOf(Pair("Key", listOf(createFinding())))) - val defaultSettings = ProcessingSettings(inputPath, outPrinter = PrintStream(outputStream)) + val defaultDetektion = DetektResult(mapOf(Pair("Key", listOf(createFinding())))) + val defaultSettings = ProcessingSettings(inputPath, outPrinter = PrintStream(outputStream)) + describe("Running the output facade") { - describe("Running the output facade") { + describe("with multiple reports") { + val cliArgs = listOf( + "--input", inputPath.toString(), + "--report", "xml:$xmlOutputPath", + "--report", "txt:$plainOutputPath", + "--report", "html:$htmlOutputPath" + ).toCliArgs() - describe("with multiple reports") { - val cliArgs = listOf( - "--input", inputPath.toString(), - "--report", "xml:$xmlOutputPath", - "--report", "txt:$plainOutputPath", - "--report", "html:$htmlOutputPath" - ).toCliArgs() + it("creates all output files") { + val subject = OutputFacade(cliArgs, defaultDetektion, defaultSettings) - it("creates all output files") { - val subject = OutputFacade(cliArgs, defaultDetektion, defaultSettings) + subject.run() - subject.run() + outputStream.assertThatItPrintsReportPath(TxtOutputReport().name) + outputStream.assertThatItPrintsReportPath(XmlOutputReport().name) + outputStream.assertThatItPrintsReportPath(HtmlOutputReport().name) + } + } - outputStream.assertThatItPrintsReportPath(TxtOutputReport().name) - outputStream.assertThatItPrintsReportPath(XmlOutputReport().name) - outputStream.assertThatItPrintsReportPath(HtmlOutputReport().name) - } - } + describe("with more findings than issues allowed") { + it("reports build failure for default task") { + val cliArgs = listOf("--input", inputPath.toString()).toCliArgs() + val subject = OutputFacade(cliArgs, defaultDetektion, ProcessingSettings(inputPath, config = ZeroMaxIssuesConfig)) - describe("with more findings than issues allowed") { - it("reports build failure for default task") { - val cliArgs = listOf("--input", inputPath.toString()).toCliArgs() - val subject = OutputFacade(cliArgs, defaultDetektion, ProcessingSettings(inputPath, config = ZeroMaxIssuesConfig)) + assertThatExceptionOfType(BuildFailure::class.java).isThrownBy { subject.run() } + } + it("does not throw an exception for createBaseline task") { + val cliArgs = listOf("--create-baseline", "--input", inputPath.toString()).toCliArgs() + val subject = OutputFacade(cliArgs, defaultDetektion, ProcessingSettings(inputPath, config = ZeroMaxIssuesConfig)) - assertThatExceptionOfType(BuildFailure::class.java).isThrownBy { subject.run() } - } - it("does not throw an exception for createBaseline task") { - val cliArgs = listOf("--create-baseline", "--input", inputPath.toString()).toCliArgs() - val subject = OutputFacade(cliArgs, defaultDetektion, ProcessingSettings(inputPath, config = ZeroMaxIssuesConfig)) - - assertThatCode { subject.run() }.doesNotThrowAnyException() - } - } - } + assertThatCode { subject.run() }.doesNotThrowAnyException() + } + } + } }) private fun List.toCliArgs(): CliArgs { - val (cliArgs, _) = parseArguments(this.toTypedArray()) - return cliArgs + val (cliArgs, _) = parseArguments(this.toTypedArray()) + return cliArgs } private object ZeroMaxIssuesConfig : Config { - override fun valueOrNull(key: String): T? = Config.empty.valueOrNull(key) - override fun subConfig(key: String) = this - @Suppress("UNCHECKED_CAST") - override fun valueOrDefault(key: String, default: T): T = when (key) { - "maxIssues" -> 0 as T - else -> Config.empty.valueOrDefault(key, default) - } + override fun valueOrNull(key: String): T? = Config.empty.valueOrNull(key) + override fun subConfig(key: String) = this + @Suppress("UNCHECKED_CAST") + override fun valueOrDefault(key: String, default: T): T = when (key) { + "maxIssues" -> 0 as T + else -> Config.empty.valueOrDefault(key, default) + } } private fun ByteArrayOutputStream.assertThatItPrintsReportPath(reportName: String) { - val outputString = toString(Charsets.UTF_8.name()) - assertThat(outputString.contains("Successfully generated $reportName at ")).isTrue() + val outputString = toString(Charsets.UTF_8.name()) + assertThat(outputString.contains("Successfully generated $reportName at ")).isTrue() } diff --git a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/ReportPathSpec.kt b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/ReportPathSpec.kt index 096130631..3cdc16f27 100644 --- a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/ReportPathSpec.kt +++ b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/ReportPathSpec.kt @@ -1,101 +1,101 @@ package io.gitlab.arturbosch.detekt.cli import io.gitlab.arturbosch.detekt.core.PathFilter +import java.nio.file.Paths import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThatIllegalArgumentException import org.jetbrains.spek.api.Spek import org.jetbrains.spek.api.dsl.given import org.jetbrains.spek.api.dsl.it -import java.nio.file.Paths class ReportPathSpec : Spek({ - if (IS_WINDOWS) { - given("a Windows path") { - it("parses a valid absolute path correctly") { - val reportPath = ReportPath.from("test:C:\\tmp\\valid\\report") + if (IS_WINDOWS) { + given("a Windows path") { + it("parses a valid absolute path correctly") { + val reportPath = ReportPath.from("test:C:\\tmp\\valid\\report") - assertThat(reportPath.path).isEqualTo(Paths.get("C:\\tmp\\valid\\report")) - } + assertThat(reportPath.path).isEqualTo(Paths.get("C:\\tmp\\valid\\report")) + } - it("parses a valid relative path correctly") { - val reportPath = ReportPath.from("test:valid\\report") + it("parses a valid relative path correctly") { + val reportPath = ReportPath.from("test:valid\\report") - assertThat(reportPath.path).isEqualTo(Paths.get("valid\\report")) - } + assertThat(reportPath.path).isEqualTo(Paths.get("valid\\report")) + } - it("fails when the path is empty") { - assertThatIllegalArgumentException() - .isThrownBy { ReportPath.from("test:") } - } + it("fails when the path is empty") { + assertThatIllegalArgumentException() + .isThrownBy { ReportPath.from("test:") } + } - it("fails when the path is malformed") { - assertThatIllegalArgumentException() - .isThrownBy { ReportPath.from("test:a*a") } - } - } - } else { - given("a POSIX path") { - it("parses a valid absolute path correctly") { - val reportPath = ReportPath.from("test:/tmp/valid/report") + it("fails when the path is malformed") { + assertThatIllegalArgumentException() + .isThrownBy { ReportPath.from("test:a*a") } + } + } + } else { + given("a POSIX path") { + it("parses a valid absolute path correctly") { + val reportPath = ReportPath.from("test:/tmp/valid/report") - assertThat(reportPath.path).isEqualTo(Paths.get("/tmp/valid/report")) - } + assertThat(reportPath.path).isEqualTo(Paths.get("/tmp/valid/report")) + } - it("parses a valid relative path correctly") { - val reportPath = ReportPath.from("test:valid/report") + it("parses a valid relative path correctly") { + val reportPath = ReportPath.from("test:valid/report") - assertThat(reportPath.path).isEqualTo(Paths.get("valid/report")) - } + assertThat(reportPath.path).isEqualTo(Paths.get("valid/report")) + } - it("fails when the path is empty") { - assertThatIllegalArgumentException() - .isThrownBy { ReportPath.from("test:") } - } + it("fails when the path is empty") { + assertThatIllegalArgumentException() + .isThrownBy { ReportPath.from("test:") } + } - it("fails when the path is malformed") { - assertThatIllegalArgumentException() - .isThrownBy { ReportPath.from("test:a${0.toChar()}a") } - } - } - } + it("fails when the path is malformed") { + assertThatIllegalArgumentException() + .isThrownBy { ReportPath.from("test:a${0.toChar()}a") } + } + } + } - given("a kind") { - it("parses and maps the txt kind correctly") { - val reportPath = ReportPath.from("txt:/tmp/valid/report") + given("a kind") { + it("parses and maps the txt kind correctly") { + val reportPath = ReportPath.from("txt:/tmp/valid/report") - assertThat(reportPath.kind).isEqualTo("TxtOutputReport") - } + assertThat(reportPath.kind).isEqualTo("TxtOutputReport") + } - it("parses and maps the xml kind correctly") { - val reportPath = ReportPath.from("xml:/tmp/valid/report") + it("parses and maps the xml kind correctly") { + val reportPath = ReportPath.from("xml:/tmp/valid/report") - assertThat(reportPath.kind).isEqualTo("XmlOutputReport") - } + assertThat(reportPath.kind).isEqualTo("XmlOutputReport") + } - it("parses and maps the html kind correctly") { - val reportPath = ReportPath.from("html:/tmp/valid/report") + it("parses and maps the html kind correctly") { + val reportPath = ReportPath.from("html:/tmp/valid/report") - assertThat(reportPath.kind).isEqualTo("HtmlOutputReport") - } + assertThat(reportPath.kind).isEqualTo("HtmlOutputReport") + } - it("parses and maps the txt kind correctly") { - val reportPath = ReportPath.from("txt:/tmp/valid/report") + it("parses and maps the txt kind correctly") { + val reportPath = ReportPath.from("txt:/tmp/valid/report") - assertThat(reportPath.kind).isEqualTo("TxtOutputReport") - } + assertThat(reportPath.kind).isEqualTo("TxtOutputReport") + } - it("parses a non-default kind correctly") { - val reportPath = ReportPath.from("test:/tmp/valid/report") + it("parses a non-default kind correctly") { + val reportPath = ReportPath.from("test:/tmp/valid/report") - assertThat(reportPath.kind).isEqualTo("test") - } + assertThat(reportPath.kind).isEqualTo("test") + } - it("fails when the kind is empty") { - assertThatIllegalArgumentException() - .isThrownBy { ReportPath.from(":/tmp/anything") } - } - } + it("fails when the kind is empty") { + assertThatIllegalArgumentException() + .isThrownBy { ReportPath.from(":/tmp/anything") } + } + } }) private val IS_WINDOWS = PathFilter.IS_WINDOWS diff --git a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/TestDetektion.kt b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/TestDetektion.kt index 6a81b4ac8..c75bad267 100644 --- a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/TestDetektion.kt +++ b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/TestDetektion.kt @@ -12,13 +12,13 @@ import org.jetbrains.kotlin.com.intellij.openapi.util.Key */ open class TestDetektion(vararg findings: Finding) : Detektion { - override val metrics: Collection = listOf() - override val findings: Map> = findings.groupBy { it.id } - override val notifications: List = listOf() + override val metrics: Collection = listOf() + override val findings: Map> = findings.groupBy { it.id } + override val notifications: List = listOf() - override fun add(notification: Notification) = throw UnsupportedOperationException("not implemented") - override fun add(projectMetric: ProjectMetric) = throw UnsupportedOperationException("not implemented") + override fun add(notification: Notification) = throw UnsupportedOperationException("not implemented") + override fun add(projectMetric: ProjectMetric) = throw UnsupportedOperationException("not implemented") - override fun getData(key: Key) = throw UnsupportedOperationException("not implemented") - override fun addData(key: Key, value: V) = throw UnsupportedOperationException("not implemented") + override fun getData(key: Key) = throw UnsupportedOperationException("not implemented") + override fun addData(key: Key, value: V) = throw UnsupportedOperationException("not implemented") } diff --git a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/BaselineFacadeTest.kt b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/BaselineFacadeTest.kt index d4ed01c09..042291a16 100644 --- a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/BaselineFacadeTest.kt +++ b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/BaselineFacadeTest.kt @@ -3,16 +3,16 @@ package io.gitlab.arturbosch.detekt.cli.baseline import io.gitlab.arturbosch.detekt.api.Finding import io.gitlab.arturbosch.detekt.cli.createFinding import io.gitlab.arturbosch.detekt.test.resource -import org.assertj.core.api.Assertions.assertThat -import org.assertj.core.api.ListAssert -import org.jetbrains.spek.api.Spek -import org.jetbrains.spek.api.dsl.it import java.io.BufferedReader import java.io.InputStream import java.io.InputStreamReader import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths +import org.assertj.core.api.Assertions.assertThat +import org.assertj.core.api.ListAssert +import org.jetbrains.spek.api.Spek +import org.jetbrains.spek.api.dsl.it /** * @author Artur Bosch @@ -20,30 +20,30 @@ import java.nio.file.Paths */ class BaselineFacadeTest : Spek({ - val dir = Files.createTempDirectory("baseline_format") + val dir = Files.createTempDirectory("baseline_format") - it("create") { - val fullPath = dir.resolve("baseline.xml") - val baselineFacade = BaselineFacade(fullPath) - baselineFacade.create(emptyList()) - Files.newInputStream(fullPath).use?> { - val reader = BufferedReader(InputStreamReader(it)) - assertThat(reader.lines()).isNotEmpty - } - } + it("create") { + val fullPath = dir.resolve("baseline.xml") + val baselineFacade = BaselineFacade(fullPath) + baselineFacade.create(emptyList()) + Files.newInputStream(fullPath).use?> { + val reader = BufferedReader(InputStreamReader(it)) + assertThat(reader.lines()).isNotEmpty + } + } - it("filterWithExistingBaseline") { - assertFilter(dir) - } + it("filterWithExistingBaseline") { + assertFilter(dir) + } - it("filterWithoutExistingBaseline") { - val path = Paths.get(resource("/smell-baseline.xml")) - assertFilter(path) - } + it("filterWithoutExistingBaseline") { + val path = Paths.get(resource("/smell-baseline.xml")) + assertFilter(path) + } }) private fun assertFilter(path: Path) { - val findings = listOf(createFinding()) - val result = BaselineFacade(path).filter(findings) - assertThat(result).isEqualTo(findings) + val findings = listOf(createFinding()) + val result = BaselineFacade(path).filter(findings) + assertThat(result).isEqualTo(findings) } diff --git a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/BaselineFormatTest.kt b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/BaselineFormatTest.kt index fe91bbc54..b60c2e496 100644 --- a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/BaselineFormatTest.kt +++ b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/baseline/BaselineFormatTest.kt @@ -1,13 +1,13 @@ package io.gitlab.arturbosch.detekt.cli.baseline import io.gitlab.arturbosch.detekt.test.resource +import java.nio.file.Files +import java.nio.file.Paths +import java.time.Instant import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThatThrownBy import org.jetbrains.spek.api.Spek import org.jetbrains.spek.api.dsl.it -import java.nio.file.Files -import java.nio.file.Paths -import java.time.Instant /** * @author Artur Bosch @@ -15,36 +15,36 @@ import java.time.Instant */ class BaselineFormatTest : Spek({ - it("loadBaseline") { - val path = Paths.get(resource("/smell-baseline.xml")) - val (blacklist, whitelist) = BaselineFormat().read(path) + it("loadBaseline") { + val path = Paths.get(resource("/smell-baseline.xml")) + val (blacklist, whitelist) = BaselineFormat().read(path) - assertThat(blacklist.ids).hasSize(2) - assertThat(blacklist.ids).anySatisfy { it.startsWith("LongParameterList") } - assertThat(blacklist.ids).anySatisfy { it.startsWith("LongMethod") } - assertThat(blacklist.timestamp).isEqualTo("123456789") - assertThat(whitelist.ids).hasSize(1) - assertThat(whitelist.ids).anySatisfy { it.startsWith("FeatureEnvy") } - assertThat(whitelist.timestamp).isEqualTo("987654321") - } + assertThat(blacklist.ids).hasSize(2) + assertThat(blacklist.ids).anySatisfy { it.startsWith("LongParameterList") } + assertThat(blacklist.ids).anySatisfy { it.startsWith("LongMethod") } + assertThat(blacklist.timestamp).isEqualTo("123456789") + assertThat(whitelist.ids).hasSize(1) + assertThat(whitelist.ids).anySatisfy { it.startsWith("FeatureEnvy") } + assertThat(whitelist.timestamp).isEqualTo("987654321") + } - it("savedAndLoadedXmlAreEqual") { - val now = Instant.now().toEpochMilli().toString() - val tempFile = Files.createTempFile("baseline", now) + it("savedAndLoadedXmlAreEqual") { + val now = Instant.now().toEpochMilli().toString() + val tempFile = Files.createTempFile("baseline", now) - val savedBaseline = Baseline( - Blacklist(setOf("4", "2", "2"), now), - Whitelist(setOf("1", "2", "3"), now)) + val savedBaseline = Baseline( + Blacklist(setOf("4", "2", "2"), now), + Whitelist(setOf("1", "2", "3"), now)) - val format = BaselineFormat() - format.write(savedBaseline, tempFile) - val loadedBaseline = format.read(tempFile) + val format = BaselineFormat() + format.write(savedBaseline, tempFile) + val loadedBaseline = format.read(tempFile) - assertThat(loadedBaseline).isEqualTo(savedBaseline) - } + assertThat(loadedBaseline).isEqualTo(savedBaseline) + } - it("loadInvalidBaseline") { - val path = Paths.get(resource("/invalid-smell-baseline.txt")) - assertThatThrownBy { BaselineFormat().read(path) }.isInstanceOf(InvalidBaselineState::class.java) - } + it("loadInvalidBaseline") { + val path = Paths.get(resource("/invalid-smell-baseline.txt")) + assertThatThrownBy { BaselineFormat().read(path) }.isInstanceOf(InvalidBaselineState::class.java) + } }) diff --git a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/console/BuildFailureReportSpec.kt b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/console/BuildFailureReportSpec.kt index a0e7bed01..1cd3455bf 100644 --- a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/console/BuildFailureReportSpec.kt +++ b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/console/BuildFailureReportSpec.kt @@ -17,70 +17,70 @@ import org.jetbrains.spek.subject.SubjectSpek */ internal class BuildFailureReportSpec : SubjectSpek({ - subject { BuildFailureReport() } + subject { BuildFailureReport() } - describe("build failure threshold is configurable by configuration") { + describe("build failure threshold is configurable by configuration") { - describe("empty code smell result") { - val detektion = TestDetektion(createFinding()) + describe("empty code smell result") { + val detektion = TestDetektion(createFinding()) - it("should fail because no config is provided for configurable console reporter") { - assertThatIllegalStateException().isThrownBy { subject.render(detektion) } - } + it("should fail because no config is provided for configurable console reporter") { + assertThatIllegalStateException().isThrownBy { subject.render(detektion) } + } - it("should return no report if build failure not configured") { - subject.init(Config.empty) - val report = subject.render(detektion) - assertThat(report).isNull() - } + it("should return no report if build failure not configured") { + subject.init(Config.empty) + val report = subject.render(detektion) + assertThat(report).isNull() + } - it("should print a warning if threshold met") { - subject.init(TestConfig(mapOf("warningThreshold" to "1"))) - val report = subject.render(detektion) - assertThat(report).isEqualTo("Warning: 1 weighted code smells found." + - " Warning threshold is 1 and fail threshold is -1!") - } + it("should print a warning if threshold met") { + subject.init(TestConfig(mapOf("warningThreshold" to "1"))) + val report = subject.render(detektion) + assertThat(report).isEqualTo("Warning: 1 weighted code smells found." + + " Warning threshold is 1 and fail threshold is -1!") + } - it("should throw a build failure error") { - subject.init(TestConfig(mapOf("failThreshold" to "-2"))) - assertThatExceptionOfType(BuildFailure::class.java).isThrownBy { subject.render(detektion) } - } + it("should throw a build failure error") { + subject.init(TestConfig(mapOf("failThreshold" to "-2"))) + assertThatExceptionOfType(BuildFailure::class.java).isThrownBy { subject.render(detektion) } + } - it("should throw a build failure error when maxIssues met") { - subject.init(TestConfig(mapOf("maxIssues" to "-2"))) - assertThatExceptionOfType(BuildFailure::class.java).isThrownBy { subject.render(detektion) } - } + it("should throw a build failure error when maxIssues met") { + subject.init(TestConfig(mapOf("maxIssues" to "-2"))) + assertThatExceptionOfType(BuildFailure::class.java).isThrownBy { subject.render(detektion) } + } - it("should throw a build failure error even if warning threshold is also met") { - subject.init(TestConfig(mapOf("failThreshold" to "-2", "warningThreshold" to "-2"))) - assertThatExceptionOfType(BuildFailure::class.java).isThrownBy { subject.render(detektion) } - } + it("should throw a build failure error even if warning threshold is also met") { + subject.init(TestConfig(mapOf("failThreshold" to "-2", "warningThreshold" to "-2"))) + assertThatExceptionOfType(BuildFailure::class.java).isThrownBy { subject.render(detektion) } + } - it("should contain no stacktrace on fail") { - subject.init(TestConfig(mapOf("maxIssues" to "-2"))) - try { - subject.render(detektion) - fail("Render should throw") - } catch (e: BuildFailure) { - assertThat(e.stackTrace).isEmpty() - } - } - } - } + it("should contain no stacktrace on fail") { + subject.init(TestConfig(mapOf("maxIssues" to "-2"))) + try { + subject.render(detektion) + fail("Render should throw") + } catch (e: BuildFailure) { + assertThat(e.stackTrace).isEmpty() + } + } + } + } - describe("reached extension function tests") { - subject.apply { - assertThat(0.reached(0)).isEqualTo(false) + describe("reached extension function tests") { + subject.apply { + assertThat(0.reached(0)).isEqualTo(false) - assertThat((-1).reached(0)).isEqualTo(false) + assertThat((-1).reached(0)).isEqualTo(false) - assertThat(1.reached(0)).isEqualTo(false) - assertThat(1.reached(1)).isEqualTo(true) - assertThat(1.reached(2)).isEqualTo(true) + assertThat(1.reached(0)).isEqualTo(false) + assertThat(1.reached(1)).isEqualTo(true) + assertThat(1.reached(2)).isEqualTo(true) - assertThat(12.reached(11)).isEqualTo(false) - assertThat(12.reached(12)).isEqualTo(true) - assertThat(12.reached(13)).isEqualTo(true) - } - } + assertThat(12.reached(11)).isEqualTo(false) + assertThat(12.reached(12)).isEqualTo(true) + assertThat(12.reached(13)).isEqualTo(true) + } + } }) diff --git a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/console/ComplexityReportSpec.kt b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/console/ComplexityReportSpec.kt index eaa03a7bf..cb92be5ac 100644 --- a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/console/ComplexityReportSpec.kt +++ b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/console/ComplexityReportSpec.kt @@ -15,42 +15,42 @@ import org.jetbrains.spek.subject.SubjectSpek internal class ComplexityReportSpec : SubjectSpek({ - subject { ComplexityReport() } + subject { ComplexityReport() } - given("several complexity metrics") { + given("several complexity metrics") { - it("successfully generates a complexity report") { - val expectedContent = readResource("complexity-report.txt") - val detektion = createDetektion() - addData(detektion) - assertThat(generateComplexityReport(detektion)).isEqualTo(expectedContent) - } + it("successfully generates a complexity report") { + val expectedContent = readResource("complexity-report.txt") + val detektion = createDetektion() + addData(detektion) + assertThat(generateComplexityReport(detektion)).isEqualTo(expectedContent) + } - it("returns null for missing complexity metrics") { - val detektion = createDetektion() - assertThat(generateComplexityReport(detektion)).isNull() - } + it("returns null for missing complexity metrics") { + val detektion = createDetektion() + assertThat(generateComplexityReport(detektion)).isNull() + } - it("returns null for missing complexity metrics in report") { - val report = ComplexityReport() - val detektion = createDetektion() - assertThat(report.render(detektion)).isNull() - } - } + it("returns null for missing complexity metrics in report") { + val report = ComplexityReport() + val detektion = createDetektion() + assertThat(report.render(detektion)).isNull() + } + } }) private fun createDetektion(): Detektion = DetektResult(mapOf(Pair("Key", listOf(createFinding())))) private fun addData(detektion: Detektion) { - detektion.addData(complexityKey, 2) - detektion.addData(linesKey, 10) - detektion.addData(sourceLinesKey, 6) - detektion.addData(logicalLinesKey, 5) - detektion.addData(commentLinesKey, 4) + detektion.addData(complexityKey, 2) + detektion.addData(linesKey, 10) + detektion.addData(sourceLinesKey, 6) + detektion.addData(logicalLinesKey, 5) + detektion.addData(commentLinesKey, 4) } private fun generateComplexityReport(detektion: Detektion): String? { - val complexityMetric = ComplexityMetric(detektion) - val generator = ComplexityReportGenerator(complexityMetric) - return generator.generate()?.trimEnd() + val complexityMetric = ComplexityMetric(detektion) + val generator = ComplexityReportGenerator(complexityMetric) + return generator.generate()?.trimEnd() } diff --git a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/console/DebtSummingSpec.kt b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/console/DebtSummingSpec.kt index 987078667..ad29a9739 100644 --- a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/console/DebtSummingSpec.kt +++ b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/console/DebtSummingSpec.kt @@ -8,29 +8,29 @@ import org.jetbrains.spek.api.dsl.it internal class DebtSummingSpec : Spek({ - given("debt minutes, hours and days") { + given("debt minutes, hours and days") { - it("outputs correct minutes, hours and days") { - assertThat(createDebtSumming(1, 23, 62).toString()).isEqualTo("2d 2min") - } + it("outputs correct minutes, hours and days") { + assertThat(createDebtSumming(1, 23, 62).toString()).isEqualTo("2d 2min") + } - it("outputs correct minutes and hours") { - assertThat(createDebtSumming(hours = 0, mins = 62).toString()).isEqualTo("1h 2min") - } + it("outputs correct minutes and hours") { + assertThat(createDebtSumming(hours = 0, mins = 62).toString()).isEqualTo("1h 2min") + } - it("outputs correct minutes") { - assertThat(createDebtSumming(mins = 42).toString()).isEqualTo("42min") - } + it("outputs correct minutes") { + assertThat(createDebtSumming(mins = 42).toString()).isEqualTo("42min") + } - it("outputs no debt") { - assertThat(DebtSumming().calculateDebt()).isNull() - } - } + it("outputs no debt") { + assertThat(DebtSumming().calculateDebt()).isNull() + } + } }) private fun createDebtSumming(days: Int = 0, hours: Int = 0, mins: Int): Debt? { - val debt = Debt(days, hours, mins) - val debtReport = DebtSumming() - debtReport.add(debt) - return debtReport.calculateDebt() + val debt = Debt(days, hours, mins) + val debtReport = DebtSumming() + debtReport.add(debt) + return debtReport.calculateDebt() } diff --git a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/console/FindingsReportSpec.kt b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/console/FindingsReportSpec.kt index c84375e1e..a2440fff6 100644 --- a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/console/FindingsReportSpec.kt +++ b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/console/FindingsReportSpec.kt @@ -10,23 +10,23 @@ import org.jetbrains.spek.subject.SubjectSpek class FindingsReportSpec : SubjectSpek({ - subject { FindingsReport() } + subject { FindingsReport() } - given("several detekt findings") { + given("several detekt findings") { - it("reports the debt per ruleset and the overall debt") { - val expectedContent = readResource("findings-report.txt") - val detektion = object : TestDetektion() { - override val findings: Map> = mapOf( - Pair("TestSmell", listOf(createFinding(), createFinding())), - Pair("EmptySmells", emptyList())) - } - assertThat(subject.render(detektion)?.trimEnd()).isEqualTo(expectedContent) - } + it("reports the debt per ruleset and the overall debt") { + val expectedContent = readResource("findings-report.txt") + val detektion = object : TestDetektion() { + override val findings: Map> = mapOf( + Pair("TestSmell", listOf(createFinding(), createFinding())), + Pair("EmptySmells", emptyList())) + } + assertThat(subject.render(detektion)?.trimEnd()).isEqualTo(expectedContent) + } - it("reports no findings") { - val detektion = TestDetektion() - assertThat(subject.render(detektion)) - } - } + it("reports no findings") { + val detektion = TestDetektion() + assertThat(subject.render(detektion)) + } + } }) diff --git a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/console/NotificationReportSpec.kt b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/console/NotificationReportSpec.kt index f1e56c81e..418ef6a55 100644 --- a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/console/NotificationReportSpec.kt +++ b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/console/NotificationReportSpec.kt @@ -3,24 +3,24 @@ package io.gitlab.arturbosch.detekt.cli.console import io.gitlab.arturbosch.detekt.cli.TestDetektion import io.gitlab.arturbosch.detekt.cli.createNotification import io.gitlab.arturbosch.detekt.test.resource +import java.nio.file.Paths import org.assertj.core.api.Assertions.assertThat import org.jetbrains.spek.api.dsl.given import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek -import java.nio.file.Paths class NotificationReportSpec : SubjectSpek({ - subject { NotificationReport() } + subject { NotificationReport() } - given("several notfications") { + given("several notfications") { - it("reports two notifications") { - val path = Paths.get(resource("empty.txt")) - val detektion = object : TestDetektion() { - override val notifications = listOf(createNotification(), createNotification()) - } - assertThat(subject.render(detektion)).isEqualTo("File $path was modified.\nFile $path was modified.") - } - } + it("reports two notifications") { + val path = Paths.get(resource("empty.txt")) + val detektion = object : TestDetektion() { + override val notifications = listOf(createNotification(), createNotification()) + } + assertThat(subject.render(detektion)).isEqualTo("File $path was modified.\nFile $path was modified.") + } + } }) diff --git a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/console/ProjectStatisticsReportSpec.kt b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/console/ProjectStatisticsReportSpec.kt index 5bee4c326..c25029a6e 100644 --- a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/console/ProjectStatisticsReportSpec.kt +++ b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/console/ProjectStatisticsReportSpec.kt @@ -9,21 +9,21 @@ import org.jetbrains.spek.subject.SubjectSpek class ProjectStatisticsReportSpec : SubjectSpek({ - subject { ProjectStatisticsReport() } + subject { ProjectStatisticsReport() } - given("several metrics") { + given("several metrics") { - it("reports the project statistics") { - val expected = "Project Statistics:\n\t- M2: 2\n\t- M1: 1\n" - val detektion = object : TestDetektion() { - override val metrics: Collection = listOf( - ProjectMetric("M1", 1), ProjectMetric("M2", 2)) - } - assertThat(subject.render(detektion)).isEqualTo(expected) - } + it("reports the project statistics") { + val expected = "Project Statistics:\n\t- M2: 2\n\t- M1: 1\n" + val detektion = object : TestDetektion() { + override val metrics: Collection = listOf( + ProjectMetric("M1", 1), ProjectMetric("M2", 2)) + } + assertThat(subject.render(detektion)).isEqualTo(expected) + } - it("does not report anything for zero metrics") { - assertThat(subject.render(TestDetektion())).isNull() - } - } + it("does not report anything for zero metrics") { + assertThat(subject.render(TestDetektion())).isNull() + } + } }) diff --git a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/console/ResourceReader.kt b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/console/ResourceReader.kt index c1cd003e3..6463af172 100644 --- a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/console/ResourceReader.kt +++ b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/console/ResourceReader.kt @@ -5,6 +5,6 @@ import java.nio.file.Files import java.nio.file.Paths internal fun readResource(filename: String): String { - val path = Paths.get(resource(filename)) - return Files.readAllLines(path).joinToString("\n").trimEnd() + val path = Paths.get(resource(filename)) + return Files.readAllLines(path).joinToString("\n").trimEnd() } diff --git a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/out/HtmlOutputFormatTest.kt b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/out/HtmlOutputFormatTest.kt index c8293e8ec..c432bf031 100644 --- a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/out/HtmlOutputFormatTest.kt +++ b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/out/HtmlOutputFormatTest.kt @@ -1,6 +1,14 @@ package io.gitlab.arturbosch.detekt.cli.out -import io.gitlab.arturbosch.detekt.api.* +import io.gitlab.arturbosch.detekt.api.CodeSmell +import io.gitlab.arturbosch.detekt.api.Debt +import io.gitlab.arturbosch.detekt.api.Detektion +import io.gitlab.arturbosch.detekt.api.Entity +import io.gitlab.arturbosch.detekt.api.Issue +import io.gitlab.arturbosch.detekt.api.Location +import io.gitlab.arturbosch.detekt.api.Severity +import io.gitlab.arturbosch.detekt.api.SourceLocation +import io.gitlab.arturbosch.detekt.api.TextLocation import io.gitlab.arturbosch.detekt.cli.TestDetektion import org.assertj.core.api.Assertions.assertThat import org.jetbrains.spek.api.Spek @@ -8,65 +16,65 @@ import org.jetbrains.spek.api.dsl.it class HtmlOutputFormatTest : Spek({ - val outputFormat = HtmlOutputReport() + val outputFormat = HtmlOutputReport() - it("testRenderResultLooksLikeHtml") { - val result = outputFormat.render(TestDetektion()) + it("testRenderResultLooksLikeHtml") { + val result = outputFormat.render(TestDetektion()) - assertThat(result).startsWith("\n") - assertThat(result).endsWith("\n") + assertThat(result).startsWith("\n") + assertThat(result).endsWith("\n") - assertThat(result).contains("

detekt report

") - assertThat(result).contains("

Metrics

") - assertThat(result).contains("

Findings

") - } + assertThat(result).contains("

detekt report

") + assertThat(result).contains("

Metrics

") + assertThat(result).contains("

Findings

") + } - it("testRenderResultContainsFileLocations") { - val result = outputFormat.render(createTestDetektionWithMultipleSmells()) + it("testRenderResultContainsFileLocations") { + val result = outputFormat.render(createTestDetektionWithMultipleSmells()) - assertThat(result).contains("\nsrc/main/com/sample/Sample1.kt:11:1\n") - assertThat(result).contains("\nsrc/main/com/sample/Sample2.kt:22:2\n") - assertThat(result).contains("\nsrc/main/com/sample/Sample3.kt:33:3\n") - } + assertThat(result).contains("\nsrc/main/com/sample/Sample1.kt:11:1\n") + assertThat(result).contains("\nsrc/main/com/sample/Sample2.kt:22:2\n") + assertThat(result).contains("\nsrc/main/com/sample/Sample3.kt:33:3\n") + } - it("testRenderResultContainsRules") { - val result = outputFormat.render(createTestDetektionWithMultipleSmells()) + it("testRenderResultContainsRules") { + val result = outputFormat.render(createTestDetektionWithMultipleSmells()) - assertThat(result).contains("\nid_a\n") - assertThat(result).contains("\nid_a\n") - assertThat(result).contains("\nid_a\n") - } + assertThat(result).contains("\nid_a\n") + assertThat(result).contains("\nid_a\n") + assertThat(result).contains("\nid_a\n") + } - it("testRenderResultContainsMessages") { - val result = outputFormat.render(createTestDetektionWithMultipleSmells()) + it("testRenderResultContainsMessages") { + val result = outputFormat.render(createTestDetektionWithMultipleSmells()) - assertThat(result).contains("\nB1\n") - assertThat(result).contains("\nB2\n") - assertThat(result).contains("\nB3\n") - } + assertThat(result).contains("\nB1\n") + assertThat(result).contains("\nB2\n") + assertThat(result).contains("\nB3\n") + } - it("testRenderResultContainsDescriptions") { - val result = outputFormat.render(createTestDetektionWithMultipleSmells()) + it("testRenderResultContainsDescriptions") { + val result = outputFormat.render(createTestDetektionWithMultipleSmells()) - assertThat(result).contains("\nA1\n") - assertThat(result).contains("\nA2\n") - assertThat(result).contains("\nA3\n") - } + assertThat(result).contains("\nA1\n") + assertThat(result).contains("\nA2\n") + assertThat(result).contains("\nA3\n") + } }) private fun createTestDetektionWithMultipleSmells(): Detektion { - val entity1 = Entity("Sample1", "com.sample.Sample1", "", - Location(SourceLocation(11, 1), TextLocation(0, 10), - "abcd", "src/main/com/sample/Sample1.kt")) - val entity2 = Entity("Sample2", "com.sample.Sample2", "", - Location(SourceLocation(22, 2), TextLocation(0, 20), - "efgh", "src/main/com/sample/Sample2.kt")) - val entity3 = Entity("Sample3", "com.sample.Sample3", "", - Location(SourceLocation(33, 3), TextLocation(0, 30), - "ijkl", "src/main/com/sample/Sample3.kt")) + val entity1 = Entity("Sample1", "com.sample.Sample1", "", + Location(SourceLocation(11, 1), TextLocation(0, 10), + "abcd", "src/main/com/sample/Sample1.kt")) + val entity2 = Entity("Sample2", "com.sample.Sample2", "", + Location(SourceLocation(22, 2), TextLocation(0, 20), + "efgh", "src/main/com/sample/Sample2.kt")) + val entity3 = Entity("Sample3", "com.sample.Sample3", "", + Location(SourceLocation(33, 3), TextLocation(0, 30), + "ijkl", "src/main/com/sample/Sample3.kt")) - return TestDetektion( - CodeSmell(Issue("id_a", Severity.CodeSmell, "A1", Debt.TWENTY_MINS), entity1, message = "B1"), - CodeSmell(Issue("id_b", Severity.CodeSmell, "A2", Debt.TWENTY_MINS), entity2, message = "B2"), - CodeSmell(Issue("id_c", Severity.CodeSmell, "A3", Debt.TWENTY_MINS), entity3, message = "B3")) + return TestDetektion( + CodeSmell(Issue("id_a", Severity.CodeSmell, "A1", Debt.TWENTY_MINS), entity1, message = "B1"), + CodeSmell(Issue("id_b", Severity.CodeSmell, "A2", Debt.TWENTY_MINS), entity2, message = "B2"), + CodeSmell(Issue("id_c", Severity.CodeSmell, "A3", Debt.TWENTY_MINS), entity3, message = "B3")) } diff --git a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/out/HtmlSnippetTest.kt b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/out/HtmlSnippetTest.kt index 438551a3c..691feef95 100644 --- a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/out/HtmlSnippetTest.kt +++ b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/out/HtmlSnippetTest.kt @@ -6,27 +6,27 @@ import org.jetbrains.spek.api.dsl.it class HtmlSnippetTest : Spek({ - it("testGeneratingSimpleHtmlSnippet") { - val snippet = htmlSnippet { - h3 { "Hello World" } - div("box") { - text { "Test" } - br() - } - } + it("testGeneratingSimpleHtmlSnippet") { + val snippet = htmlSnippet { + h3 { "Hello World" } + div("box") { + text { "Test" } + br() + } + } - assertThat(snippet).isEqualTo("

Hello World

\n
\nTest\n
\n
") - } + assertThat(snippet).isEqualTo("

Hello World

\n
\nTest\n
\n
") + } - it("testGeneratingList") { - val items = listOf("Apple", "Banana", "Orange") + it("testGeneratingList") { + val items = listOf("Apple", "Banana", "Orange") - val snippet = htmlSnippet { - list(items) { - span("fruit") { it } - } - } + val snippet = htmlSnippet { + list(items) { + span("fruit") { it } + } + } - assertThat(snippet).isEqualTo("
    \n
  • \n\nApple\n\n
  • \n
  • \n\nBanana\n\n
  • \n
  • \n\nOrange\n\n
  • \n
") - } + assertThat(snippet).isEqualTo("
    \n
  • \n\nApple\n\n
  • \n
  • \n\nBanana\n\n
  • \n
  • \n\nOrange\n\n
  • \n
") + } }) diff --git a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/out/ReportsSpec.kt b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/out/ReportsSpec.kt index 11e587984..45962dfe1 100644 --- a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/out/ReportsSpec.kt +++ b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/out/ReportsSpec.kt @@ -6,82 +6,82 @@ import io.gitlab.arturbosch.detekt.cli.CliArgs import io.gitlab.arturbosch.detekt.cli.ReportLocator import io.gitlab.arturbosch.detekt.cli.parseArguments import io.gitlab.arturbosch.detekt.core.ProcessingSettings +import java.nio.file.Paths +import java.util.function.Predicate import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Condition import org.jetbrains.spek.api.Spek import org.jetbrains.spek.api.dsl.given import org.jetbrains.spek.api.dsl.it -import java.nio.file.Paths -import java.util.function.Predicate /** * @author Artur Bosch */ internal class ReportsSpec : Spek({ - given("arguments for jcommander") { + given("arguments for jcommander") { - val reportUnderTest = TestOutputReport::class.java.simpleName - val args = arrayOf( - "--report", "xml:/tmp/path1", - "--report", "txt:/tmp/path2", - "--report", "$reportUnderTest:/tmp/path3", - "--report", "html:D:_Gradle\\xxx\\xxx\\build\\reports\\detekt\\detekt.html" - ) - val (cli, _) = parseArguments(args) + val reportUnderTest = TestOutputReport::class.java.simpleName + val args = arrayOf( + "--report", "xml:/tmp/path1", + "--report", "txt:/tmp/path2", + "--report", "$reportUnderTest:/tmp/path3", + "--report", "html:D:_Gradle\\xxx\\xxx\\build\\reports\\detekt\\detekt.html" + ) + val (cli, _) = parseArguments(args) - val reports = cli.reportPaths + val reports = cli.reportPaths - it("should parse multiple report entries") { - assertThat(reports).hasSize(4) - } + it("should parse multiple report entries") { + assertThat(reports).hasSize(4) + } - it("it should properly parse XML report entry") { - val xmlReport = reports[0] - assertThat(xmlReport.kind).isEqualTo(XmlOutputReport::class.java.simpleName) - assertThat(xmlReport.path).isEqualTo(Paths.get("/tmp/path1")) - } + it("it should properly parse XML report entry") { + val xmlReport = reports[0] + assertThat(xmlReport.kind).isEqualTo(XmlOutputReport::class.java.simpleName) + assertThat(xmlReport.path).isEqualTo(Paths.get("/tmp/path1")) + } - it("it should properly parse TXT report entry") { - val txtRepot = reports[1] - assertThat(txtRepot.kind).isEqualTo(TxtOutputReport::class.java.simpleName) - assertThat(txtRepot.path).isEqualTo(Paths.get("/tmp/path2")) - } + it("it should properly parse TXT report entry") { + val txtRepot = reports[1] + assertThat(txtRepot.kind).isEqualTo(TxtOutputReport::class.java.simpleName) + assertThat(txtRepot.path).isEqualTo(Paths.get("/tmp/path2")) + } - it("it should properly parse custom report entry") { - val customReport = reports[2] - assertThat(customReport.kind).isEqualTo(reportUnderTest) - assertThat(customReport.path).isEqualTo(Paths.get("/tmp/path3")) - } + it("it should properly parse custom report entry") { + val customReport = reports[2] + assertThat(customReport.kind).isEqualTo(reportUnderTest) + assertThat(customReport.path).isEqualTo(Paths.get("/tmp/path3")) + } - it("it should properly parse HTML report entry") { - val htmlReport = reports[3] - assertThat(htmlReport.kind).isEqualTo(HtmlOutputReport::class.java.simpleName) - assertThat(htmlReport.path).isEqualTo(Paths.get("D:_Gradle\\xxx\\xxx\\build\\reports\\detekt\\detekt.html")) - } + it("it should properly parse HTML report entry") { + val htmlReport = reports[3] + assertThat(htmlReport.kind).isEqualTo(HtmlOutputReport::class.java.simpleName) + assertThat(htmlReport.path).isEqualTo(Paths.get("D:_Gradle\\xxx\\xxx\\build\\reports\\detekt\\detekt.html")) + } - val extensions = ReportLocator(ProcessingSettings(listOf())).load() - val extensionsIds = extensions.mapTo(HashSet()) { it.id } + val extensions = ReportLocator(ProcessingSettings(listOf())).load() + val extensionsIds = extensions.mapTo(HashSet()) { it.id } - it("should be able to convert to output reports") { - assertThat(reports).allMatch { it.kind in extensionsIds } - } + it("should be able to convert to output reports") { + assertThat(reports).allMatch { it.kind in extensionsIds } + } - it("should recognize custom output format") { - assertThat(reports).haveExactly(1, - Condition(Predicate { it.kind == reportUnderTest }, - "Corresponds exactly to the test output report.")) + it("should recognize custom output format") { + assertThat(reports).haveExactly(1, + Condition(Predicate { it.kind == reportUnderTest }, + "Corresponds exactly to the test output report.")) - assertThat(extensions).haveExactly(1, - Condition(Predicate { it is TestOutputReport && it.ending == "yml" }, - "Is exactly the test output report.")) - } - } + assertThat(extensions).haveExactly(1, + Condition(Predicate { it is TestOutputReport && it.ending == "yml" }, + "Is exactly the test output report.")) + } + } }) internal class TestOutputReport : OutputReport() { - override val ending: String = "yml" - override fun render(detektion: Detektion): String? { - throw UnsupportedOperationException("not implemented") - } + override val ending: String = "yml" + override fun render(detektion: Detektion): String? { + throw UnsupportedOperationException("not implemented") + } } diff --git a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/out/TxtOutputReportTest.kt b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/out/TxtOutputReportTest.kt index f6433cde3..d33198097 100644 --- a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/out/TxtOutputReportTest.kt +++ b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/out/TxtOutputReportTest.kt @@ -8,10 +8,10 @@ import org.jetbrains.spek.api.dsl.it class TxtOutputReportTest : Spek({ - it("render") { - val report = TxtOutputReport() - val detektion = TestDetektion(createFinding()) - val renderedText = "TestSmell - [TestEntity] at TestFile.kt:1:1 - Signature=S1" - assertThat(report.render(detektion)).isEqualTo(renderedText) - } + it("render") { + val report = TxtOutputReport() + val detektion = TestDetektion(createFinding()) + val renderedText = "TestSmell - [TestEntity] at TestFile.kt:1:1 - Signature=S1" + assertThat(report.render(detektion)).isEqualTo(renderedText) + } }) diff --git a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/out/XmlOutputFormatTest.kt b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/out/XmlOutputFormatTest.kt index 4db2c6b8f..be19773b8 100644 --- a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/out/XmlOutputFormatTest.kt +++ b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/out/XmlOutputFormatTest.kt @@ -15,55 +15,55 @@ import org.jetbrains.spek.api.dsl.it class XmlOutputFormatTest : Spek({ - val entity1 = Entity("Sample1", "com.sample.Sample1", "", - Location(SourceLocation(11, 1), TextLocation(0, 10), - "abcd", "src/main/com/sample/Sample1.kt")) - val entity2 = Entity("Sample2", "com.sample.Sample2", "", - Location(SourceLocation(22, 2), TextLocation(0, 20), - "efgh", "src/main/com/sample/Sample2.kt")) + val entity1 = Entity("Sample1", "com.sample.Sample1", "", + Location(SourceLocation(11, 1), TextLocation(0, 10), + "abcd", "src/main/com/sample/Sample1.kt")) + val entity2 = Entity("Sample2", "com.sample.Sample2", "", + Location(SourceLocation(22, 2), TextLocation(0, 20), + "efgh", "src/main/com/sample/Sample2.kt")) - val outputFormat = XmlOutputReport() + val outputFormat = XmlOutputReport() - it("renderEmpty") { - val result = outputFormat.render(TestDetektion()) + it("renderEmpty") { + val result = outputFormat.render(TestDetektion()) - assertThat(result).isEqualTo("\n\n") - } + assertThat(result).isEqualTo("\n\n") + } - it("renderOneForSingleFile") { - val smell = CodeSmell(Issue("id_a", Severity.CodeSmell, "", Debt.TWENTY_MINS), entity1, message = "") + it("renderOneForSingleFile") { + val smell = CodeSmell(Issue("id_a", Severity.CodeSmell, "", Debt.TWENTY_MINS), entity1, message = "") - val result = outputFormat.render(TestDetektion(smell)) + val result = outputFormat.render(TestDetektion(smell)) - assertThat(result).isEqualTo("\n\n\n\t\n\n") - } + assertThat(result).isEqualTo("\n\n\n\t\n\n") + } - it("renderTwoForSingleFile") { - val smell1 = CodeSmell(Issue("id_a", Severity.CodeSmell, "", Debt.TWENTY_MINS), entity1, message = "") - val smell2 = CodeSmell(Issue("id_b", Severity.CodeSmell, "", Debt.TWENTY_MINS), entity1, message = "") + it("renderTwoForSingleFile") { + val smell1 = CodeSmell(Issue("id_a", Severity.CodeSmell, "", Debt.TWENTY_MINS), entity1, message = "") + val smell2 = CodeSmell(Issue("id_b", Severity.CodeSmell, "", Debt.TWENTY_MINS), entity1, message = "") - val result = outputFormat.render(TestDetektion(smell1, smell2)) + val result = outputFormat.render(TestDetektion(smell1, smell2)) - assertThat(result).isEqualTo("\n\n\n\t\n\t\n\n") - } + assertThat(result).isEqualTo("\n\n\n\t\n\t\n\n") + } - it("renderOneForMultipleFiles") { - val smell1 = CodeSmell(Issue("id_a", Severity.CodeSmell, "", Debt.TWENTY_MINS), entity1, message = "") - val smell2 = CodeSmell(Issue("id_a", Severity.CodeSmell, "", Debt.TWENTY_MINS), entity2, message = "") + it("renderOneForMultipleFiles") { + val smell1 = CodeSmell(Issue("id_a", Severity.CodeSmell, "", Debt.TWENTY_MINS), entity1, message = "") + val smell2 = CodeSmell(Issue("id_a", Severity.CodeSmell, "", Debt.TWENTY_MINS), entity2, message = "") - val result = outputFormat.render(TestDetektion(smell1, smell2)) + val result = outputFormat.render(TestDetektion(smell1, smell2)) - assertThat(result).isEqualTo("\n\n\n\t\n\n\n\t\n\n") - } + assertThat(result).isEqualTo("\n\n\n\t\n\n\n\t\n\n") + } - it("renderTwoForMultipleFiles") { - val smell1 = CodeSmell(Issue("id_a", Severity.CodeSmell, "", Debt.TWENTY_MINS), entity1, message = "") - val smell2 = CodeSmell(Issue("id_b", Severity.CodeSmell, "", Debt.TWENTY_MINS), entity1, message = "") - val smell3 = CodeSmell(Issue("id_a", Severity.CodeSmell, "", Debt.TWENTY_MINS), entity2, message = "") - val smell4 = CodeSmell(Issue("id_b", Severity.CodeSmell, "", Debt.TWENTY_MINS), entity2, message = "") + it("renderTwoForMultipleFiles") { + val smell1 = CodeSmell(Issue("id_a", Severity.CodeSmell, "", Debt.TWENTY_MINS), entity1, message = "") + val smell2 = CodeSmell(Issue("id_b", Severity.CodeSmell, "", Debt.TWENTY_MINS), entity1, message = "") + val smell3 = CodeSmell(Issue("id_a", Severity.CodeSmell, "", Debt.TWENTY_MINS), entity2, message = "") + val smell4 = CodeSmell(Issue("id_b", Severity.CodeSmell, "", Debt.TWENTY_MINS), entity2, message = "") - val result = outputFormat.render(TestDetektion(smell1, smell2, smell3, smell4)) + val result = outputFormat.render(TestDetektion(smell1, smell2, smell3, smell4)) - assertThat(result).isEqualTo("\n\n\n\t\n\t\n\n\n\t\n\t\n\n") - } + assertThat(result).isEqualTo("\n\n\n\t\n\t\n\n\n\t\n\t\n\n") + } }) diff --git a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/runners/AstPrinterSpec.kt b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/runners/AstPrinterSpec.kt index 14d6ead82..ddd2311e0 100644 --- a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/runners/AstPrinterSpec.kt +++ b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/runners/AstPrinterSpec.kt @@ -2,24 +2,24 @@ package io.gitlab.arturbosch.detekt.cli.runners import io.gitlab.arturbosch.detekt.test.compileForTest import io.gitlab.arturbosch.detekt.test.resource +import java.nio.file.Paths import org.assertj.core.api.Assertions.assertThat import org.jetbrains.spek.api.Spek import org.jetbrains.spek.api.dsl.it -import java.nio.file.Paths /** * @author Artur Bosch */ class AstPrinterSpec : Spek({ - it("should print the ast as string") { - val case = Paths.get(resource("cases/Poko.kt")) - val ktFile = compileForTest(case) + it("should print the ast as string") { + val case = Paths.get(resource("cases/Poko.kt")) + val ktFile = compileForTest(case) - val dump = ElementPrinter.dump(ktFile) + val dump = ElementPrinter.dump(ktFile) - assertThat(dump.trimIndent()).isEqualTo(expected) - } + assertThat(dump.trimIndent()).isEqualTo(expected) + } }) private val expected = """0: KtFile diff --git a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/runners/SingleRuleRunnerSpec.kt b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/runners/SingleRuleRunnerSpec.kt index 72c7d343e..6bbe1a378 100644 --- a/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/runners/SingleRuleRunnerSpec.kt +++ b/detekt-cli/src/test/kotlin/io/gitlab/arturbosch/detekt/cli/runners/SingleRuleRunnerSpec.kt @@ -13,46 +13,46 @@ import io.gitlab.arturbosch.detekt.api.RuleSetProvider import io.gitlab.arturbosch.detekt.api.Severity import io.gitlab.arturbosch.detekt.cli.CliArgs import io.gitlab.arturbosch.detekt.test.resource +import java.nio.file.Paths import org.assertj.core.api.Assertions import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.spek.api.Spek import org.jetbrains.spek.api.dsl.it -import java.nio.file.Paths /** * @author Artur Bosch */ class SingleRuleRunnerSpec : Spek({ - it("should load and run custom rule") { - val case = Paths.get(resource("cases/Poko.kt")) + it("should load and run custom rule") { + val case = Paths.get(resource("cases/Poko.kt")) - val args = CliArgs().apply { - val field = this.javaClass.getDeclaredField("input") - field.isAccessible = true - field.set(this, case.toString()) - runRule = "test:test" - } - // assertion is made inside the custom console report - SingleRuleRunner(args).execute() // also indirect assertion that test:test exists - } + val args = CliArgs().apply { + val field = this.javaClass.getDeclaredField("input") + field.isAccessible = true + field.set(this, case.toString()) + runRule = "test:test" + } + // assertion is made inside the custom console report + SingleRuleRunner(args).execute() // also indirect assertion that test:test exists + } }) class TestConsoleReport : ConsoleReport() { - override fun render(detektion: Detektion): String? { - Assertions.assertThat(detektion.findings).hasSize(1) - return "I've run!" - } + override fun render(detektion: Detektion): String? { + Assertions.assertThat(detektion.findings).hasSize(1) + return "I've run!" + } } class TestProvider : RuleSetProvider { - override val ruleSetId: String = "test" - override fun instance(config: Config): RuleSet = RuleSet(ruleSetId, listOf(TestRule())) + override val ruleSetId: String = "test" + override fun instance(config: Config): RuleSet = RuleSet(ruleSetId, listOf(TestRule())) } class TestRule : Rule() { - override val issue = Issue("test", Severity.Minor, "", Debt.FIVE_MINS) - override fun visitClass(klass: KtClass) { - report(CodeSmell(issue, Entity.from(klass), issue.description)) - } + override val issue = Issue("test", Severity.Minor, "", Debt.FIVE_MINS) + override fun visitClass(klass: KtClass) { + report(CodeSmell(issue, Entity.from(klass), issue.description)) + } } diff --git a/detekt-cli/src/test/resources/cases/Poko.kt b/detekt-cli/src/test/resources/cases/Poko.kt index 90cabaa5a..8bbe733cf 100644 --- a/detekt-cli/src/test/resources/cases/Poko.kt +++ b/detekt-cli/src/test/resources/cases/Poko.kt @@ -2,6 +2,6 @@ package cases class Poko { - val name: String = "Poko" - fun hello() = "Hello, $name" + val name: String = "Poko" + fun hello() = "Hello, $name" } diff --git a/detekt-core/build.gradle.kts b/detekt-core/build.gradle.kts index 7d711430d..4218822d5 100644 --- a/detekt-core/build.gradle.kts +++ b/detekt-core/build.gradle.kts @@ -5,12 +5,12 @@ val spekVersion: String by project val reflectionsVersion: String by project dependencies { - implementation(kotlin("compiler-embeddable")) - api(project(":detekt-api")) + implementation(kotlin("compiler-embeddable")) + api(project(":detekt-api")) - testImplementation(project(":detekt-rules")) - testImplementation(project(":detekt-test")) - testImplementation("org.reflections:reflections:$reflectionsVersion") - testRuntimeOnly("org.junit.platform:junit-platform-launcher:$junitPlatformVersion") - testRuntimeOnly("org.jetbrains.spek:spek-junit-platform-engine:$spekVersion") + testImplementation(project(":detekt-rules")) + testImplementation(project(":detekt-test")) + testImplementation("org.reflections:reflections:$reflectionsVersion") + testRuntimeOnly("org.junit.platform:junit-platform-launcher:$junitPlatformVersion") + testRuntimeOnly("org.jetbrains.spek:spek-junit-platform-engine:$spekVersion") } diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/DebugUtils.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/DebugUtils.kt index 813e03110..9340f4c94 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/DebugUtils.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/DebugUtils.kt @@ -13,21 +13,21 @@ fun whichOS(): String = System.getProperty("os.name") fun whichJava(): String = System.getProperty("java.runtime.version") fun whichDetekt(): String { - for (resource in Detektor::class.java.classLoader.getResources("META-INF/MANIFEST.MF")) { - try { - val version = readDetektVersionInManifest(resource) - if (version != null) { - return version - } - } catch (_: IOException) { - // we search for the manifest with the detekt version - } - } - return "unknown" + for (resource in Detektor::class.java.classLoader.getResources("META-INF/MANIFEST.MF")) { + try { + val version = readDetektVersionInManifest(resource) + if (version != null) { + return version + } + } catch (_: IOException) { + // we search for the manifest with the detekt version + } + } + return "unknown" } private fun readDetektVersionInManifest(resource: URL) = - resource.openStream().use { - Manifest(it).mainAttributes - .getValue("DetektVersion") - } + resource.openStream().use { + Manifest(it).mainAttributes + .getValue("DetektVersion") + } diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/DetektFacade.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/DetektFacade.kt index 8f36e185f..652a5b586 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/DetektFacade.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/DetektFacade.kt @@ -5,82 +5,85 @@ import io.gitlab.arturbosch.detekt.api.FileProcessListener import io.gitlab.arturbosch.detekt.api.Finding import io.gitlab.arturbosch.detekt.api.Notification import io.gitlab.arturbosch.detekt.api.RuleSetProvider -import org.jetbrains.kotlin.psi.KtFile import java.nio.file.Path +import org.jetbrains.kotlin.psi.KtFile /** * @author Artur Bosch */ class DetektFacade( - private val detektor: Detektor, - settings: ProcessingSettings, - private val processors: List) { + private val detektor: Detektor, + settings: ProcessingSettings, + private val processors: List +) { - private val saveSupported = settings.config.valueOrDefault("autoCorrect", false) - private val pathsToAnalyze = settings.inputPaths - private val compiler = KtTreeCompiler.instance(settings) + private val saveSupported = settings.config.valueOrDefault("autoCorrect", false) + private val pathsToAnalyze = settings.inputPaths + private val compiler = KtTreeCompiler.instance(settings) - fun run(): Detektion { - val notifications = mutableListOf() - val ktFiles = mutableListOf() - val findings = HashMap>() + fun run(): Detektion { + val notifications = mutableListOf() + val ktFiles = mutableListOf() + val findings = HashMap>() - for (current in pathsToAnalyze) { - val files = compiler.compile(current) + for (current in pathsToAnalyze) { + val files = compiler.compile(current) - processors.forEach { it.onStart(files) } - findings.mergeSmells(detektor.run(files)) - if (saveSupported) { - KtFileModifier(current).saveModifiedFiles(files) { - notifications.add(it) - } - } + processors.forEach { it.onStart(files) } + findings.mergeSmells(detektor.run(files)) + if (saveSupported) { + KtFileModifier(current).saveModifiedFiles(files) { + notifications.add(it) + } + } - ktFiles.addAll(files) - } + ktFiles.addAll(files) + } - val result = DetektResult(findings.toSortedMap()) - processors.forEach { it.onFinish(ktFiles, result) } - return result - } + val result = DetektResult(findings.toSortedMap()) + processors.forEach { it.onFinish(ktFiles, result) } + return result + } - fun run(project: Path, files: List): Detektion = runOnFiles(project, files) + fun run(project: Path, files: List): Detektion = runOnFiles(project, files) - private fun runOnFiles(current: Path, files: List): DetektResult { - processors.forEach { it.onStart(files) } + private fun runOnFiles(current: Path, files: List): DetektResult { + processors.forEach { it.onStart(files) } - val findings = detektor.run(files) - val detektion = DetektResult(findings.toSortedMap()) - if (saveSupported) { - KtFileModifier(current).saveModifiedFiles(files) { - detektion.add(it) - } - } + val findings = detektor.run(files) + val detektion = DetektResult(findings.toSortedMap()) + if (saveSupported) { + KtFileModifier(current).saveModifiedFiles(files) { + detektion.add(it) + } + } - processors.forEach { it.onFinish(files, detektion) } - return detektion - } + processors.forEach { it.onFinish(files, detektion) } + return detektion + } - companion object { + companion object { - fun create(settings: ProcessingSettings): DetektFacade { - val providers = RuleSetLocator(settings).load() - val processors = FileProcessorLocator(settings).load() - return create(settings, providers, processors) - } + fun create(settings: ProcessingSettings): DetektFacade { + val providers = RuleSetLocator(settings).load() + val processors = FileProcessorLocator(settings).load() + return create(settings, providers, processors) + } - fun create(settings: ProcessingSettings, vararg providers: RuleSetProvider): DetektFacade { - return create(settings, providers.toList(), emptyList()) - } + fun create(settings: ProcessingSettings, vararg providers: RuleSetProvider): DetektFacade { + return create(settings, providers.toList(), emptyList()) + } - fun create(settings: ProcessingSettings, vararg processors: FileProcessListener): DetektFacade { - return create(settings, emptyList(), processors.toList()) - } + fun create(settings: ProcessingSettings, vararg processors: FileProcessListener): DetektFacade { + return create(settings, emptyList(), processors.toList()) + } - fun create(settings: ProcessingSettings, - providers: List, - processors: List): DetektFacade { - return DetektFacade(Detektor(settings, providers, processors), settings, processors) - } - } + fun create( + settings: ProcessingSettings, + providers: List, + processors: List + ): DetektFacade { + return DetektFacade(Detektor(settings, providers, processors), settings, processors) + } + } } diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/DetektResult.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/DetektResult.kt index 9fcb45846..aa7364765 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/DetektResult.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/DetektResult.kt @@ -13,22 +13,22 @@ import org.jetbrains.kotlin.com.intellij.util.keyFMap.KeyFMap */ data class DetektResult(override val findings: Map>) : Detektion { - override val notifications: MutableCollection = ArrayList() - private var userData = KeyFMap.EMPTY_MAP - private val _metrics = ArrayList() - override val metrics: Collection = _metrics + override val notifications: MutableCollection = ArrayList() + private var userData = KeyFMap.EMPTY_MAP + private val _metrics = ArrayList() + override val metrics: Collection = _metrics - override fun add(projectMetric: ProjectMetric) { - _metrics.add(projectMetric) - } + override fun add(projectMetric: ProjectMetric) { + _metrics.add(projectMetric) + } - override fun add(notification: Notification) { - notifications.add(notification) - } + override fun add(notification: Notification) { + notifications.add(notification) + } - override fun getData(key: Key): V? = userData.get(key) + override fun getData(key: Key): V? = userData.get(key) - override fun addData(key: Key, value: V) { - userData = userData.plus(key, value) - } + override fun addData(key: Key, value: V) { + userData = userData.plus(key, value) + } } diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/Detektor.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/Detektor.kt index f73661c52..ec95f5809 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/Detektor.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/Detektor.kt @@ -5,60 +5,61 @@ import io.gitlab.arturbosch.detekt.api.FileProcessListener import io.gitlab.arturbosch.detekt.api.Finding import io.gitlab.arturbosch.detekt.api.RuleSetId import io.gitlab.arturbosch.detekt.api.RuleSetProvider -import org.jetbrains.kotlin.psi.KtFile import java.util.concurrent.ExecutorService +import org.jetbrains.kotlin.psi.KtFile /** * @author Artur Bosch */ -class Detektor(settings: ProcessingSettings, - private val providers: List, - private val processors: List = emptyList()) { +class Detektor( + settings: ProcessingSettings, + private val providers: List, + private val processors: List = emptyList()) { - private val config: Config = settings.config - private val testPattern: TestPattern = settings.loadTestPattern() - private val executor: ExecutorService = settings.executorService - private val logger = settings.errorPrinter + private val config: Config = settings.config + private val testPattern: TestPattern = settings.loadTestPattern() + private val executor: ExecutorService = settings.executorService + private val logger = settings.errorPrinter - fun run(ktFiles: List): Map> = withExecutor(executor) { + fun run(ktFiles: List): Map> = withExecutor(executor) { - val futures = ktFiles.map { file -> - runAsync { - processors.forEach { it.onProcess(file) } - file.analyze().apply { - processors.forEach { it.onProcessComplete(file, this) } - } - }.exceptionally { error -> - logger.println("Analyzing '${file.absolutePath()}' led to an exception.\n" + - "The original exception message was: ${error.localizedMessage}\n" + - "Running detekt '${whichDetekt()}' on Java '${whichJava()}' on OS '${whichOS()}'.\n" + - "If the exception message does not help, please feel free to create an issue on our github page." - ) - error.printStacktraceRecursively(logger) - emptyMap() - } - } + val futures = ktFiles.map { file -> + runAsync { + processors.forEach { it.onProcess(file) } + file.analyze().apply { + processors.forEach { it.onProcessComplete(file, this) } + } + }.exceptionally { error -> + logger.println("Analyzing '${file.absolutePath()}' led to an exception.\n" + + "The original exception message was: ${error.localizedMessage}\n" + + "Running detekt '${whichDetekt()}' on Java '${whichJava()}' on OS '${whichOS()}'.\n" + + "If the exception message does not help, please feel free to create an issue on our github page." + ) + error.printStacktraceRecursively(logger) + emptyMap() + } + } - val result = HashMap>() - for (map in awaitAll(futures)) { - result.mergeSmells(map) - } + val result = HashMap>() + for (map in awaitAll(futures)) { + result.mergeSmells(map) + } - result - } + result + } - private fun KtFile.analyze(): Map> { - var ruleSets = providers.asSequence() - .mapNotNull { it.buildRuleset(config) } - .sortedBy { it.id } - .distinctBy { it.id } - .toList() + private fun KtFile.analyze(): Map> { + var ruleSets = providers.asSequence() + .mapNotNull { it.buildRuleset(config) } + .sortedBy { it.id } + .distinctBy { it.id } + .toList() - return if (testPattern.isTestSource(this)) { - ruleSets = ruleSets.filterNot { testPattern.matchesRuleSet(it.id) } - ruleSets.map { ruleSet -> ruleSet.id to ruleSet.accept(this, testPattern.excludingRules) } - } else { - ruleSets.map { ruleSet -> ruleSet.id to ruleSet.accept(this) } - }.toMergedMap() - } + return if (testPattern.isTestSource(this)) { + ruleSets = ruleSets.filterNot { testPattern.matchesRuleSet(it.id) } + ruleSets.map { ruleSet -> ruleSet.id to ruleSet.accept(this, testPattern.excludingRules) } + } else { + ruleSets.map { ruleSet -> ruleSet.id to ruleSet.accept(this) } + }.toMergedMap() + } } diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/FileProcessorLocator.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/FileProcessorLocator.kt index 06779143b..e08155e6e 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/FileProcessorLocator.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/FileProcessorLocator.kt @@ -11,20 +11,20 @@ import java.util.ServiceLoader */ class FileProcessorLocator(settings: ProcessingSettings) { - private val plugins: Array = settings.pluginUrls - private val config: Config = settings.config - private val subConfig = config.subConfig("processors") - private val processorsActive = subConfig.valueOrDefault("active", true) - private val excludes = subConfig.valueOrDefault("exclude", emptyList()) + private val plugins: Array = settings.pluginUrls + private val config: Config = settings.config + private val subConfig = config.subConfig("processors") + private val processorsActive = subConfig.valueOrDefault("active", true) + private val excludes = subConfig.valueOrDefault("exclude", emptyList()) - fun load(): List { - val detektLoader = URLClassLoader(plugins, javaClass.classLoader) - return if (processorsActive) - ServiceLoader.load(FileProcessListener::class.java, detektLoader) - .filter { it.id !in excludes } - .onEach { it.init(config) } - .toList() - else - emptyList() - } + fun load(): List { + val detektLoader = URLClassLoader(plugins, javaClass.classLoader) + return if (processorsActive) + ServiceLoader.load(FileProcessListener::class.java, detektLoader) + .filter { it.id !in excludes } + .onEach { it.init(config) } + .toList() + else + emptyList() + } } diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/Junk.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/Junk.kt index a4b1cf507..934d56cf0 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/Junk.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/Junk.kt @@ -1,13 +1,13 @@ package io.gitlab.arturbosch.detekt.core import io.gitlab.arturbosch.detekt.api.Finding -import org.jetbrains.kotlin.psi.KtFile import java.io.PrintStream import java.nio.file.Files import java.nio.file.Path import java.util.HashMap import java.util.stream.Collectors import java.util.stream.Stream +import org.jetbrains.kotlin.psi.KtFile /** * @author Artur Bosch @@ -23,22 +23,22 @@ fun KtFile.relativePath(): String? = getUserData(KtCompiler.RELATIVE_PATH) fun KtFile.absolutePath(): String? = getUserData(KtCompiler.ABSOLUTE_PATH) fun MutableMap>.mergeSmells(other: Map>) { - for ((key, findings) in other.entries) { - merge(key, findings) { f1, f2 -> f1.plus(f2) } - } + for ((key, findings) in other.entries) { + merge(key, findings) { f1, f2 -> f1.plus(f2) } + } } fun Throwable.printStacktraceRecursively(logger: PrintStream) { - stackTrace.forEach { logger.println(it) } - cause?.printStacktraceRecursively(logger) + stackTrace.forEach { logger.println(it) } + cause?.printStacktraceRecursively(logger) } fun List>>.toMergedMap(): Map> { - val map = HashMap>() - for ((key, values) in this) { - map.merge(key, values.toMutableList()) { l1, l2 -> - l1.apply { addAll(l2) } - } - } - return map + val map = HashMap>() + for ((key, values) in this) { + map.merge(key, values.toMutableList()) { l1, l2 -> + l1.apply { addAll(l2) } + } + } + return map } diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/KtCompiler.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/KtCompiler.kt index 78b0addea..cdcba9135 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/KtCompiler.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/KtCompiler.kt @@ -1,62 +1,62 @@ package io.gitlab.arturbosch.detekt.core import io.gitlab.arturbosch.detekt.api.psiProject +import java.nio.file.Path import org.jetbrains.kotlin.com.intellij.openapi.util.Key import org.jetbrains.kotlin.com.intellij.openapi.util.text.StringUtilRt import org.jetbrains.kotlin.com.intellij.psi.PsiFileFactory import org.jetbrains.kotlin.com.intellij.testFramework.LightVirtualFile import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.psi.KtFile -import java.nio.file.Path /** * @author Artur Bosch */ open class KtCompiler { - protected val psiFileFactory: PsiFileFactory = PsiFileFactory.getInstance(psiProject) + protected val psiFileFactory: PsiFileFactory = PsiFileFactory.getInstance(psiProject) - fun compile(root: Path, subPath: Path): KtFile { - require(subPath.isFile()) { "Given sub path should be a regular file!" } - val relativePath = - (if (root == subPath) subPath.fileName - else root.fileName.resolve(root.relativize(subPath))).normalize() - val absolutePath = - (if (root == subPath) subPath - else subPath).toAbsolutePath().normalize() - val content = subPath.toFile().readText() - val lineSeparator = content.determineLineSeparator() - val normalizedContent = StringUtilRt.convertLineSeparators(content) - val ktFile = createKtFile(normalizedContent, absolutePath) + fun compile(root: Path, subPath: Path): KtFile { + require(subPath.isFile()) { "Given sub path should be a regular file!" } + val relativePath = + (if (root == subPath) subPath.fileName + else root.fileName.resolve(root.relativize(subPath))).normalize() + val absolutePath = + (if (root == subPath) subPath + else subPath).toAbsolutePath().normalize() + val content = subPath.toFile().readText() + val lineSeparator = content.determineLineSeparator() + val normalizedContent = StringUtilRt.convertLineSeparators(content) + val ktFile = createKtFile(normalizedContent, absolutePath) - return ktFile.apply { - putUserData(LINE_SEPARATOR, lineSeparator) - putUserData(RELATIVE_PATH, relativePath.toString()) - putUserData(ABSOLUTE_PATH, absolutePath.toString()) - } - } + return ktFile.apply { + putUserData(LINE_SEPARATOR, lineSeparator) + putUserData(RELATIVE_PATH, relativePath.toString()) + putUserData(ABSOLUTE_PATH, absolutePath.toString()) + } + } - private fun createKtFile(content: String, path: Path): KtFile { - val psiFile = psiFileFactory.createFileFromText( - path.fileName.toString(), - KotlinLanguage.INSTANCE, - StringUtilRt.convertLineSeparators(content), - true, true, false, - LightVirtualFile(path.toString())) - return psiFile as? KtFile ?: throw IllegalStateException("kotlin file expected") - } + private fun createKtFile(content: String, path: Path): KtFile { + val psiFile = psiFileFactory.createFileFromText( + path.fileName.toString(), + KotlinLanguage.INSTANCE, + StringUtilRt.convertLineSeparators(content), + true, true, false, + LightVirtualFile(path.toString())) + return psiFile as? KtFile ?: throw IllegalStateException("kotlin file expected") + } - private fun String.determineLineSeparator(): String { - val i = this.lastIndexOf('\n') - if (i == -1) { - return if (this.lastIndexOf('\r') == -1) System.getProperty("line.separator") else "\r" - } - return if (i != 0 && this[i] == '\r') "\r\n" else "\n" - } + private fun String.determineLineSeparator(): String { + val i = this.lastIndexOf('\n') + if (i == -1) { + return if (this.lastIndexOf('\r') == -1) System.getProperty("line.separator") else "\r" + } + return if (i != 0 && this[i] == '\r') "\r\n" else "\n" + } - companion object { - val LINE_SEPARATOR: Key = Key("lineSeparator") - val RELATIVE_PATH: Key = Key("relativePath") - val ABSOLUTE_PATH: Key = Key("absolutePath") - } + companion object { + val LINE_SEPARATOR: Key = Key("lineSeparator") + val RELATIVE_PATH: Key = Key("relativePath") + val ABSOLUTE_PATH: Key = Key("absolutePath") + } } diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/KtFileModifier.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/KtFileModifier.kt index 3b7ce0136..e5e2ded64 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/KtFileModifier.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/KtFileModifier.kt @@ -1,33 +1,33 @@ package io.gitlab.arturbosch.detekt.core import io.gitlab.arturbosch.detekt.api.Notification +import java.nio.file.Files +import java.nio.file.Path import org.jetbrains.kotlin.com.intellij.openapi.util.text.StringUtilRt import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName import org.jetbrains.kotlin.psi.KtFile -import java.nio.file.Files -import java.nio.file.Path /** * @author Artur Bosch */ class KtFileModifier(private val project: Path) { - fun saveModifiedFiles(ktFiles: List, notification: (Notification) -> Unit) { - ktFiles.filter { it.modificationStamp > 0 } - .map { it.absolutePath() to it.unnormalizeContent() } - .filter { it.first != null } - .map { project.resolve(it.first) to it.second } - .forEach { - notification.invoke(ModificationNotification(it.first)) - Files.write(it.first, it.second.toByteArray()) - } - } + fun saveModifiedFiles(ktFiles: List, notification: (Notification) -> Unit) { + ktFiles.filter { it.modificationStamp > 0 } + .map { it.absolutePath() to it.unnormalizeContent() } + .filter { it.first != null } + .map { project.resolve(it.first) to it.second } + .forEach { + notification.invoke(ModificationNotification(it.first)) + Files.write(it.first, it.second.toByteArray()) + } + } - private fun KtFile.unnormalizeContent(): String { - val lineSeparator = getUserData(KtCompiler.LINE_SEPARATOR) - require(lineSeparator != null) { - "No line separator entry for ktFile ${javaFileFacadeFqName.asString()}" - } - return StringUtilRt.convertLineSeparators(text, lineSeparator) - } + private fun KtFile.unnormalizeContent(): String { + val lineSeparator = getUserData(KtCompiler.LINE_SEPARATOR) + require(lineSeparator != null) { + "No line separator entry for ktFile ${javaFileFacadeFqName.asString()}" + } + return StringUtilRt.convertLineSeparators(text, lineSeparator) + } } diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/KtTreeCompiler.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/KtTreeCompiler.kt index ff46c352f..9a432b579 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/KtTreeCompiler.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/KtTreeCompiler.kt @@ -1,52 +1,54 @@ package io.gitlab.arturbosch.detekt.core -import org.jetbrains.kotlin.psi.KtFile import java.nio.file.Files import java.nio.file.Path +import org.jetbrains.kotlin.psi.KtFile /** * @author Artur Bosch * @author Marvin Ramin */ -class KtTreeCompiler(private val compiler: KtCompiler = KtCompiler(), - private val filters: List = listOf(), - private val parallel: Boolean = false, - private val debug: Boolean = false) { +class KtTreeCompiler( + private val compiler: KtCompiler = KtCompiler(), + private val filters: List = listOf(), + private val parallel: Boolean = false, + private val debug: Boolean = false +) { - companion object { - fun instance(settings: ProcessingSettings) = with(settings) { - KtTreeCompiler(KtCompiler(), pathFilters, parallelCompilation) - } - } + companion object { + fun instance(settings: ProcessingSettings) = with(settings) { + KtTreeCompiler(KtCompiler(), pathFilters, parallelCompilation) + } + } - fun compile(path: Path): List { - require(Files.exists(path)) { "Given path $path does not exist!" } - return when { - path.isFile() && path.isKotlinFile() -> listOf(compiler.compile(path, path)) - path.isDirectory() -> compileInternal(path) - else -> { - if (debug) { - println("Ignoring a file detekt cannot handle: $path") - } - listOf() - } - } - } + fun compile(path: Path): List { + require(Files.exists(path)) { "Given path $path does not exist!" } + return when { + path.isFile() && path.isKotlinFile() -> listOf(compiler.compile(path, path)) + path.isDirectory() -> compileInternal(path) + else -> { + if (debug) { + println("Ignoring a file detekt cannot handle: $path") + } + listOf() + } + } + } - private fun streamFor(project: Path) = Files.walk(project).apply { if (parallel) parallel() } + private fun streamFor(project: Path) = Files.walk(project).apply { if (parallel) parallel() } - private fun compileInternal(project: Path): List = streamFor(project) - .filter(Path::isFile) - .filter { it.isKotlinFile() } - .filter { notIgnored(it) } - .map { compiler.compile(project, it) } - .toList() + private fun compileInternal(project: Path): List = streamFor(project) + .filter(Path::isFile) + .filter { it.isKotlinFile() } + .filter { notIgnored(it) } + .map { compiler.compile(project, it) } + .toList() - private fun Path.isKotlinFile(): Boolean { - val fullPath = toAbsolutePath().toString() - val kotlinEnding = fullPath.substring(fullPath.lastIndexOf('.') + 1) - return kotlinEnding == "kt" || kotlinEnding == "kts" - } + private fun Path.isKotlinFile(): Boolean { + val fullPath = toAbsolutePath().toString() + val kotlinEnding = fullPath.substring(fullPath.lastIndexOf('.') + 1) + return kotlinEnding == "kt" || kotlinEnding == "kts" + } - private fun notIgnored(path: Path) = !filters.any { it.matches(path) } + private fun notIgnored(path: Path) = !filters.any { it.matches(path) } } diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/ModificationNotification.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/ModificationNotification.kt index 1de5767d3..cdd540cab 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/ModificationNotification.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/ModificationNotification.kt @@ -8,6 +8,6 @@ import java.nio.file.Path */ class ModificationNotification(path: Path) : Notification { - override val message: String = "File $path was modified." - override fun toString(): String = message + override val message: String = "File $path was modified." + override fun toString(): String = message } diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/PathFilter.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/PathFilter.kt index 67265ea04..99fb473ec 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/PathFilter.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/PathFilter.kt @@ -13,60 +13,60 @@ import java.util.regex.PatternSyntaxException */ class PathFilter(pattern: String, private val root: Path = Paths.get("").toAbsolutePath()) { - companion object { - val IS_WINDOWS = System.getProperty("os.name").contains("Windows") - } + companion object { + val IS_WINDOWS = System.getProperty("os.name").contains("Windows") + } - private val regex: Regex + private val regex: Regex - init { - if (pattern.isBlank()) { - throw IllegalArgumentException("Empty patterns aren't acceptable") - } + init { + if (pattern.isBlank()) { + throw IllegalArgumentException("Empty patterns aren't acceptable") + } - try { - val independentPattern = if (IS_WINDOWS) pattern.replace("/", "\\\\") else pattern - regex = Regex(independentPattern) - } catch (exception: PatternSyntaxException) { - throw IllegalArgumentException("Provided regex is not valid: $pattern") - } - } + try { + val independentPattern = if (IS_WINDOWS) pattern.replace("/", "\\\\") else pattern + regex = Regex(independentPattern) + } catch (exception: PatternSyntaxException) { + throw IllegalArgumentException("Provided regex is not valid: $pattern") + } + } - fun matches(path: Path): Boolean { - val prefix = if (IS_WINDOWS) { - "\\" - } else { - "./" - } - val relativePath = if (path.isAbsolute) { - "$prefix${root.relativize(path)}" - } else { - if (!path.startsWith(prefix)) { - "$prefix$path" - } else { - path.toString() - } - } - return relativePath.matches(regex) - } + fun matches(path: Path): Boolean { + val prefix = if (IS_WINDOWS) { + "\\" + } else { + "./" + } + val relativePath = if (path.isAbsolute) { + "$prefix${root.relativize(path)}" + } else { + if (!path.startsWith(prefix)) { + "$prefix$path" + } else { + path.toString() + } + } + return relativePath.matches(regex) + } - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other !is PathFilter) return false + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is PathFilter) return false - // We compare the patterns — there is no meaningful way to compare equality for regexes, - // but we control the creation of the regexes and we can say that all else is equal, so - // that's good enough in this case. - if (regex.pattern != other.regex.pattern) return false + // We compare the patterns — there is no meaningful way to compare equality for regexes, + // but we control the creation of the regexes and we can say that all else is equal, so + // that's good enough in this case. + if (regex.pattern != other.regex.pattern) return false - return true - } + return true + } - override fun hashCode(): Int { - return regex.hashCode() - } + override fun hashCode(): Int { + return regex.hashCode() + } - override fun toString(): String { - return "PathFilter(regex=$regex)" - } + override fun toString(): String { + return "PathFilter(regex=$regex)" + } } diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/ProcessingSettings.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/ProcessingSettings.kt index 39778e295..0f563668c 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/ProcessingSettings.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/ProcessingSettings.kt @@ -15,42 +15,44 @@ import java.util.concurrent.ForkJoinPool * @author Marvin Ramin */ @Suppress("LongParameterList") -data class ProcessingSettings(val inputPaths: List, - val config: Config = Config.empty, - val pathFilters: List = listOf(), - val parallelCompilation: Boolean = false, - val excludeDefaultRuleSets: Boolean = false, - val pluginPaths: List = emptyList(), - val executorService: ExecutorService = ForkJoinPool.commonPool(), - val outPrinter: PrintStream = System.out, - val errorPrinter: PrintStream = System.err) { +data class ProcessingSettings( + val inputPaths: List, + val config: Config = Config.empty, + val pathFilters: List = listOf(), + val parallelCompilation: Boolean = false, + val excludeDefaultRuleSets: Boolean = false, + val pluginPaths: List = emptyList(), + val executorService: ExecutorService = ForkJoinPool.commonPool(), + val outPrinter: PrintStream = System.out, + val errorPrinter: PrintStream = System.err +) { - /** - * Single project input path constructor. - */ - constructor( - inputPath: Path, - config: Config = Config.empty, - pathFilters: List = listOf(), - parallelCompilation: Boolean = false, - excludeDefaultRuleSets: Boolean = false, - pluginPaths: List = emptyList(), - executorService: ExecutorService = ForkJoinPool.commonPool(), - outPrinter: PrintStream = System.out, - errorPrinter: PrintStream = System.err - ) : this( - listOf(inputPath), config, pathFilters, parallelCompilation, - excludeDefaultRuleSets, pluginPaths, executorService, outPrinter, errorPrinter - ) + /** + * Single project input path constructor. + */ + constructor( + inputPath: Path, + config: Config = Config.empty, + pathFilters: List = listOf(), + parallelCompilation: Boolean = false, + excludeDefaultRuleSets: Boolean = false, + pluginPaths: List = emptyList(), + executorService: ExecutorService = ForkJoinPool.commonPool(), + outPrinter: PrintStream = System.out, + errorPrinter: PrintStream = System.err + ) : this( + listOf(inputPath), config, pathFilters, parallelCompilation, + excludeDefaultRuleSets, pluginPaths, executorService, outPrinter, errorPrinter + ) - init { - pluginPaths.forEach { - require(Files.exists(it)) { "Given plugin ‘$it’ does not exist." } - require(it.toString().endsWith("jar")) { "Given plugin ‘$it’ is not a JAR." } - } - } + init { + pluginPaths.forEach { + require(Files.exists(it)) { "Given plugin ‘$it’ does not exist." } + require(it.toString().endsWith("jar")) { "Given plugin ‘$it’ is not a JAR." } + } + } - val pluginUrls = pluginPaths.map { it.toUri().toURL() }.toTypedArray() + val pluginUrls = pluginPaths.map { it.toUri().toURL() }.toTypedArray() - fun loadTestPattern() = createTestPattern(config) + fun loadTestPattern() = createTestPattern(config) } diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/RuleSetLocator.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/RuleSetLocator.kt index d9fe92e51..c9eeb4ba2 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/RuleSetLocator.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/RuleSetLocator.kt @@ -10,20 +10,20 @@ import java.util.ServiceLoader */ class RuleSetLocator(settings: ProcessingSettings) { - private val excludeDefaultRuleSets: Boolean = settings.excludeDefaultRuleSets - private val plugins: Array = settings.pluginUrls + private val excludeDefaultRuleSets: Boolean = settings.excludeDefaultRuleSets + private val plugins: Array = settings.pluginUrls - fun load(): List { - val detektLoader = URLClassLoader(plugins, javaClass.classLoader) - return ServiceLoader.load(RuleSetProvider::class.java, detektLoader).asIterable() - .mapNotNull { it.nullIfDefaultAndExcluded() } - .toList() - } + fun load(): List { + val detektLoader = URLClassLoader(plugins, javaClass.classLoader) + return ServiceLoader.load(RuleSetProvider::class.java, detektLoader).asIterable() + .mapNotNull { it.nullIfDefaultAndExcluded() } + .toList() + } - private fun RuleSetProvider.nullIfDefaultAndExcluded() = if (excludeDefaultRuleSets && provided()) null else this + private fun RuleSetProvider.nullIfDefaultAndExcluded() = if (excludeDefaultRuleSets && provided()) null else this - private fun RuleSetProvider.provided() = ruleSetId in defaultRuleSetIds + private fun RuleSetProvider.provided() = ruleSetId in defaultRuleSetIds - private val defaultRuleSetIds = listOf("comments", "complexity", "empty-blocks", - "exceptions", "potential-bugs", "performance", "style", "naming") + private val defaultRuleSetIds = listOf("comments", "complexity", "empty-blocks", + "exceptions", "potential-bugs", "performance", "style", "naming") } diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/Tasks.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/Tasks.kt index 761af9c87..c5c6a8751 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/Tasks.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/Tasks.kt @@ -10,21 +10,21 @@ import java.util.function.Supplier */ fun withExecutor(executor: Executor? = null, block: Executor.() -> T): T { - if (executor == null) { - val defaultExecutor = ForkJoinPool.commonPool() - return block.invoke(defaultExecutor).apply { - defaultExecutor.shutdown() - } - } - return block.invoke(executor) + if (executor == null) { + val defaultExecutor = ForkJoinPool.commonPool() + return block.invoke(defaultExecutor).apply { + defaultExecutor.shutdown() + } + } + return block.invoke(executor) } fun Executor.runAsync(block: () -> T): CompletableFuture { - return task(this) { block() } + return task(this) { block() } } fun task(executor: Executor, task: () -> T): CompletableFuture { - return CompletableFuture.supplyAsync(Supplier { task() }, executor) + return CompletableFuture.supplyAsync(Supplier { task() }, executor) } fun awaitAll(futures: List>) = futures.map { it.join() } diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/TestPattern.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/TestPattern.kt index 0566c4432..5cad94695 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/TestPattern.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/TestPattern.kt @@ -3,44 +3,47 @@ package io.gitlab.arturbosch.detekt.core import io.gitlab.arturbosch.detekt.api.Config import io.gitlab.arturbosch.detekt.api.RuleId import io.gitlab.arturbosch.detekt.core.TestPattern.Companion.TEST_PATTERN_SUB_CONFIG -import org.jetbrains.kotlin.psi.KtFile import java.nio.file.Path import java.nio.file.Paths +import org.jetbrains.kotlin.psi.KtFile /** * @author Artur Bosch */ -fun createTestPattern(config: Config, - root: Path = Paths.get("").toAbsolutePath()): TestPattern { - return with(config.subConfig(TEST_PATTERN_SUB_CONFIG)) { - TestPattern(valueOrDefault(TestPattern.ACTIVE, false), - valueOrDefault(TestPattern.PATTERNS, TestPattern.DEFAULT_PATTERNS).toSet(), - valueOrDefault(TestPattern.EXCLUDE_RULES, emptyList()).toSet(), - valueOrDefault(TestPattern.EXCLUDE_RULE_SETS, emptyList()).toSet(), - root) - } +fun createTestPattern( + config: Config, + root: Path = Paths.get("").toAbsolutePath()): TestPattern { + return with(config.subConfig(TEST_PATTERN_SUB_CONFIG)) { + TestPattern(valueOrDefault(TestPattern.ACTIVE, false), + valueOrDefault(TestPattern.PATTERNS, TestPattern.DEFAULT_PATTERNS).toSet(), + valueOrDefault(TestPattern.EXCLUDE_RULES, emptyList()).toSet(), + valueOrDefault(TestPattern.EXCLUDE_RULE_SETS, emptyList()).toSet(), + root) + } } -data class TestPattern(val active: Boolean, - val patterns: Set, - val excludingRules: Set, - private val excludingRuleSets: Set, - private val root: Path) { +data class TestPattern( + val active: Boolean, + val patterns: Set, + val excludingRules: Set, + private val excludingRuleSets: Set, + private val root: Path +) { - private val _patterns = patterns.map { PathFilter(it, root) } + private val _patterns = patterns.map { PathFilter(it, root) } - fun matches(path: String) = _patterns.any { it.matches(Paths.get(path)) } - fun matchesRuleSet(ruleSet: String) = excludingRuleSets.any { it == ruleSet } - fun isTestSource(file: KtFile) = active && file.absolutePath()?.let { matches(it) } == true + fun matches(path: String) = _patterns.any { it.matches(Paths.get(path)) } + fun matchesRuleSet(ruleSet: String) = excludingRuleSets.any { it == ruleSet } + fun isTestSource(file: KtFile) = active && file.absolutePath()?.let { matches(it) } == true - companion object { - const val TEST_PATTERN_SUB_CONFIG = "test-pattern" - const val ACTIVE = "active" - const val PATTERNS = "patterns" - const val EXCLUDE_RULES = "exclude-rules" - const val EXCLUDE_RULE_SETS = "exclude-rule-sets" + companion object { + const val TEST_PATTERN_SUB_CONFIG = "test-pattern" + const val ACTIVE = "active" + const val PATTERNS = "patterns" + const val EXCLUDE_RULES = "exclude-rules" + const val EXCLUDE_RULE_SETS = "exclude-rule-sets" - val DEFAULT_PATTERNS = listOf(".*/test/.*Test.kt") - } + val DEFAULT_PATTERNS = listOf(".*/test/.*Test.kt") + } } diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/AbstractProcessor.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/AbstractProcessor.kt index f3a670144..46c10e8e6 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/AbstractProcessor.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/AbstractProcessor.kt @@ -8,17 +8,17 @@ import org.jetbrains.kotlin.psi.KtFile abstract class AbstractProcessor : FileProcessListener { - protected abstract val visitor: DetektVisitor - protected abstract val key: Key + protected abstract val visitor: DetektVisitor + protected abstract val key: Key - override fun onProcess(file: KtFile) { - file.accept(visitor) - } + override fun onProcess(file: KtFile) { + file.accept(visitor) + } - override fun onFinish(files: List, result: Detektion) { - val count = files - .mapNotNull { it.getUserData(key) } - .sum() - result.addData(key, count) - } + override fun onFinish(files: List, result: Detektion) { + val count = files + .mapNotNull { it.getUserData(key) } + .sum() + result.addData(key, count) + } } diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/AbstractProjectMetricProcessor.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/AbstractProjectMetricProcessor.kt index 94afc2106..d0326ca90 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/AbstractProjectMetricProcessor.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/AbstractProjectMetricProcessor.kt @@ -9,12 +9,12 @@ import org.jetbrains.kotlin.psi.KtFile */ abstract class AbstractProjectMetricProcessor : AbstractProcessor() { - val type: String get() = key.toString() + val type: String get() = key.toString() - override fun onFinish(files: List, result: Detektion) { - val count = files - .mapNotNull { it.getUserData(key) } - .sum() - result.add(ProjectMetric(type, count)) - } + override fun onFinish(files: List, result: Detektion) { + val count = files + .mapNotNull { it.getUserData(key) } + .sum() + result.add(ProjectMetric(type, count)) + } } diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/ClassCountProcessor.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/ClassCountProcessor.kt index ea19ac75c..250dbb0c5 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/ClassCountProcessor.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/ClassCountProcessor.kt @@ -8,16 +8,16 @@ import org.jetbrains.kotlin.psi.KtFile class ClassCountProcessor : AbstractProjectMetricProcessor() { - override val visitor = ClassCountVisitor() - override val key = numberOfClassesKey + override val visitor = ClassCountVisitor() + override val key = numberOfClassesKey } val numberOfClassesKey = Key("number of classes") class ClassCountVisitor : DetektVisitor() { - override fun visitKtFile(file: KtFile) { - super.visitKtFile(file) - file.putUserData(numberOfClassesKey, file.collectByType().size) - } + override fun visitKtFile(file: KtFile) { + super.visitKtFile(file) + file.putUserData(numberOfClassesKey, file.collectByType().size) + } } diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/FunctionCountProcessor.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/FunctionCountProcessor.kt index 04720a408..7d96be2a9 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/FunctionCountProcessor.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/FunctionCountProcessor.kt @@ -8,16 +8,16 @@ import org.jetbrains.kotlin.psi.KtNamedFunction class FunctionCountProcessor : AbstractProjectMetricProcessor() { - override val visitor = FunctionCountVisitor() - override val key = numberOfFunctionsKey + override val visitor = FunctionCountVisitor() + override val key = numberOfFunctionsKey } val numberOfFunctionsKey = Key("number of functions") class FunctionCountVisitor : DetektVisitor() { - override fun visitKtFile(file: KtFile) { - super.visitKtFile(file) - file.putUserData(numberOfFunctionsKey, file.collectByType().size) - } + override fun visitKtFile(file: KtFile) { + super.visitKtFile(file) + file.putUserData(numberOfFunctionsKey, file.collectByType().size) + } } diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/KtFileCountProcessor.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/KtFileCountProcessor.kt index 3eee31d98..fd516a43a 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/KtFileCountProcessor.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/KtFileCountProcessor.kt @@ -6,14 +6,14 @@ import org.jetbrains.kotlin.psi.KtFile class KtFileCountProcessor : AbstractProjectMetricProcessor() { - override val visitor = KtFileCountVisitor() - override val key = numberOfFilesKey + override val visitor = KtFileCountVisitor() + override val key = numberOfFilesKey } val numberOfFilesKey = Key("number of kt files") class KtFileCountVisitor : DetektVisitor() { - override fun visitKtFile(file: KtFile) { - file.putUserData(numberOfFilesKey, 1) - } + override fun visitKtFile(file: KtFile) { + file.putUserData(numberOfFilesKey, 1) + } } diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/PackageCountProcessor.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/PackageCountProcessor.kt index 12cdc93cd..7b757d6ec 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/PackageCountProcessor.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/PackageCountProcessor.kt @@ -9,28 +9,28 @@ import org.jetbrains.kotlin.psi.KtFile class PackageCountProcessor : FileProcessListener { - private val visitor = PackageCountVisitor() - private val key = numberOfPackagesKey + private val visitor = PackageCountVisitor() + private val key = numberOfPackagesKey - override fun onProcess(file: KtFile) { - file.accept(visitor) - } + override fun onProcess(file: KtFile) { + file.accept(visitor) + } - override fun onFinish(files: List, result: Detektion) { - val count = files - .mapNotNull { it.getUserData(key) } - .distinct() - .size - result.add(ProjectMetric(key.toString(), count)) - } + override fun onFinish(files: List, result: Detektion) { + val count = files + .mapNotNull { it.getUserData(key) } + .distinct() + .size + result.add(ProjectMetric(key.toString(), count)) + } } val numberOfPackagesKey = Key("number of packages") class PackageCountVisitor : DetektVisitor() { - override fun visitKtFile(file: KtFile) { - val packageName = file.packageFqNameByTree.toString() - file.putUserData(numberOfPackagesKey, packageName) - } + override fun visitKtFile(file: KtFile) { + val packageName = file.packageFqNameByTree.toString() + file.putUserData(numberOfPackagesKey, packageName) + } } diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/ProjectCLOCProcessor.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/ProjectCLOCProcessor.kt index a2e44c761..8717d7179 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/ProjectCLOCProcessor.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/ProjectCLOCProcessor.kt @@ -8,41 +8,41 @@ import org.jetbrains.kotlin.psi.KtFile class ProjectCLOCProcessor : AbstractProcessor() { - override val key = commentLinesKey - override val visitor = CLOCVisitor() + override val key = commentLinesKey + override val visitor = CLOCVisitor() } val commentLinesKey = Key("cloc") class CLOCVisitor : DetektVisitor() { - override fun visitKtFile(file: KtFile) { - with(CLOCCountVisitor()) { - file.accept(this) - file.putUserData(commentLinesKey, count) - } - } + override fun visitKtFile(file: KtFile) { + with(CLOCCountVisitor()) { + file.accept(this) + file.putUserData(commentLinesKey, count) + } + } } internal class CLOCCountVisitor : DetektVisitor() { - internal var count = 0 + internal var count = 0 - private fun increment(value: Int) { - count += value - } + private fun increment(value: Int) { + count += value + } - override fun visitComment(comment: PsiComment?) { - if (comment != null) { - increment(comment.text.split('\n').size) - } - } + override fun visitComment(comment: PsiComment?) { + if (comment != null) { + increment(comment.text.split('\n').size) + } + } - override fun visitDeclaration(dcl: KtDeclaration) { - val text = dcl.docComment?.text - if (text != null) { - increment(text.split('\n').size) - } - super.visitDeclaration(dcl) - } + override fun visitDeclaration(dcl: KtDeclaration) { + val text = dcl.docComment?.text + if (text != null) { + increment(text.split('\n').size) + } + super.visitDeclaration(dcl) + } } diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/ProjectComplexityProcessor.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/ProjectComplexityProcessor.kt index 7cff05dc4..9ecd98d85 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/ProjectComplexityProcessor.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/ProjectComplexityProcessor.kt @@ -7,18 +7,18 @@ import org.jetbrains.kotlin.psi.KtFile class ProjectComplexityProcessor : AbstractProcessor() { - override val visitor = ComplexityVisitor() - override val key = complexityKey + override val visitor = ComplexityVisitor() + override val key = complexityKey } val complexityKey = Key("complexity") class ComplexityVisitor : DetektVisitor() { - override fun visitKtFile(file: KtFile) { - with(McCabeVisitor(ignoreSimpleWhenEntries = false)) { - file.accept(this) - file.putUserData(complexityKey, mcc) - } - } + override fun visitKtFile(file: KtFile) { + with(McCabeVisitor(ignoreSimpleWhenEntries = false)) { + file.accept(this) + file.putUserData(complexityKey, mcc) + } + } } diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/ProjectLLOCProcessor.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/ProjectLLOCProcessor.kt index 2412b5467..794088252 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/ProjectLLOCProcessor.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/ProjectLLOCProcessor.kt @@ -7,17 +7,17 @@ import org.jetbrains.kotlin.psi.KtFile class ProjectLLOCProcessor : AbstractProcessor() { - override val visitor = LLOCVisitor() - override val key = logicalLinesKey + override val visitor = LLOCVisitor() + override val key = logicalLinesKey } val logicalLinesKey = Key("lloc") class LLOCVisitor : DetektVisitor() { - override fun visitKtFile(file: KtFile) { - val lines = file.text.split("\n") - val value = LLOC.analyze(lines) - file.putUserData(logicalLinesKey, value) - } + override fun visitKtFile(file: KtFile) { + val lines = file.text.split("\n") + val value = LLOC.analyze(lines) + file.putUserData(logicalLinesKey, value) + } } diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/ProjectLOCProcessor.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/ProjectLOCProcessor.kt index 206a4a74f..0b75a714c 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/ProjectLOCProcessor.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/ProjectLOCProcessor.kt @@ -6,16 +6,16 @@ import org.jetbrains.kotlin.psi.KtFile class ProjectLOCProcessor : AbstractProcessor() { - override val visitor: DetektVisitor = LOCVisitor() - override val key = linesKey + override val visitor: DetektVisitor = LOCVisitor() + override val key = linesKey } class LOCVisitor : DetektVisitor() { - override fun visitKtFile(file: KtFile) { - val lines = file.text.count { it == '\n' } + 1 - file.putUserData(linesKey, lines) - } + override fun visitKtFile(file: KtFile) { + val lines = file.text.count { it == '\n' } + 1 + file.putUserData(linesKey, lines) + } } val linesKey = Key("loc") diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/ProjectSLOCProcessor.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/ProjectSLOCProcessor.kt index f5c5396f7..1df47a387 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/ProjectSLOCProcessor.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/ProjectSLOCProcessor.kt @@ -6,29 +6,29 @@ import org.jetbrains.kotlin.psi.KtFile class ProjectSLOCProcessor : AbstractProcessor() { - override val visitor: DetektVisitor = SLOCVisitor() - override val key: Key = sourceLinesKey + override val visitor: DetektVisitor = SLOCVisitor() + override val key: Key = sourceLinesKey } class SLOCVisitor : DetektVisitor() { - override fun visitKtFile(file: KtFile) { - val lines = file.text.split('\n') - val sloc = SLOC().count(lines) - file.putUserData(sourceLinesKey, sloc) - } + override fun visitKtFile(file: KtFile) { + val lines = file.text.split('\n') + val sloc = SLOC().count(lines) + file.putUserData(sourceLinesKey, sloc) + } - private class SLOC { + private class SLOC { - private val comments = arrayOf("//", "/*", "*/", "*") + private val comments = arrayOf("//", "/*", "*/", "*") - fun count(lines: List): Int { - return lines - .map { it.trim() } - .filter { trim -> trim.isNotEmpty() && !comments.any { trim.startsWith(it) } } - .size - } - } + fun count(lines: List): Int { + return lines + .map { it.trim() } + .filter { trim -> trim.isNotEmpty() && !comments.any { trim.startsWith(it) } } + .size + } + } } val sourceLinesKey = Key("sloc") diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/PropertyCountProcessor.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/PropertyCountProcessor.kt index 014e1691c..58b9e3db6 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/PropertyCountProcessor.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/PropertyCountProcessor.kt @@ -8,16 +8,16 @@ import org.jetbrains.kotlin.psi.KtProperty class PropertyCountProcessor : AbstractProjectMetricProcessor() { - override val visitor = PropertyCountVisitor() - override val key = numberOfFieldsKey + override val visitor = PropertyCountVisitor() + override val key = numberOfFieldsKey } val numberOfFieldsKey = Key("number of properties") class PropertyCountVisitor : DetektVisitor() { - override fun visitKtFile(file: KtFile) { - super.visitKtFile(file) - file.putUserData(numberOfFieldsKey, file.collectByType().size) - } + override fun visitKtFile(file: KtFile) { + super.visitKtFile(file) + file.putUserData(numberOfFieldsKey, file.collectByType().size) + } } diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/util/Junk.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/util/Junk.kt index 75d09abdc..df5db575e 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/util/Junk.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/util/Junk.kt @@ -7,14 +7,14 @@ import org.jetbrains.kotlin.psi.KtElement * @author Artur Bosch */ inline fun KtElement.collectByType(): List { - val list = mutableListOf() - this.accept(object : DetektVisitor() { - override fun visitKtElement(element: KtElement) { - if (element is T) { - list.add(element) - } - element.children.forEach { it.accept(this) } - } - }) - return list + val list = mutableListOf() + this.accept(object : DetektVisitor() { + override fun visitKtElement(element: KtElement) { + if (element is T) { + list.add(element) + } + element.children.forEach { it.accept(this) } + } + }) + return list } diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/util/LLOC.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/util/LLOC.kt index 4e4cba66d..8dbb06e4a 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/util/LLOC.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/processors/util/LLOC.kt @@ -5,96 +5,100 @@ package io.gitlab.arturbosch.detekt.core.processors.util */ object LLOC { - private val comments = arrayOf("//", "/*", "*/", "*") - private val escapes = arrayOf("import", "package") + private val comments = arrayOf("//", "/*", "*/", "*") + private val escapes = arrayOf("import", "package") - fun analyze(lines: List, - isCommentMode: Boolean = false, - isFullMode: Boolean = false): Int = Counter(lines, isCommentMode, isFullMode).run() + fun analyze( + lines: List, + isCommentMode: Boolean = false, + isFullMode: Boolean = false + ): Int = Counter(lines, isCommentMode, isFullMode).run() - private class Counter(private val lines: List, - private val isCommentMode: Boolean = false, - private val isFullMode: Boolean = false) { + private class Counter( + private val lines: List, + private val isCommentMode: Boolean = false, + private val isFullMode: Boolean = false + ) { - private var counter = 0 - private var openedBrackets = 0 - private var closedBrackets = 0 - private var escape: Boolean = false + private var counter = 0 + private var openedBrackets = 0 + private var closedBrackets = 0 + private var escape: Boolean = false - internal fun run(): Int { - for (line in lines) { + internal fun run(): Int { + for (line in lines) { - val trimmed = line.trim() + val trimmed = line.trim() - if (trimmed.isEmpty()) { - continue - } + if (trimmed.isEmpty()) { + continue + } - countOrEscapeComment(trimmed) - if (escape) { - continue - } + countOrEscapeComment(trimmed) + if (escape) { + continue + } - countOrEscapeAdditionalStatements(trimmed) - if (escape) { - continue - } + countOrEscapeAdditionalStatements(trimmed) + if (escape) { + continue + } - countStatementsAndDeclarations(trimmed) - } + countStatementsAndDeclarations(trimmed) + } - return counter + if (openedBrackets - closedBrackets == 0) openedBrackets else -1 - } + return counter + if (openedBrackets - closedBrackets == 0) openedBrackets else -1 + } - private fun countStatementsAndDeclarations(trimmed: String) { - if (trimmed.contains(";")) { - counter++ - } + private fun countStatementsAndDeclarations(trimmed: String) { + if (trimmed.contains(";")) { + counter++ + } - if (trimmed.contains("{")) { - openedBrackets += frequency(trimmed, "{") - } else if (trimmed.length != 1) { - counter++ - } + if (trimmed.contains("{")) { + openedBrackets += frequency(trimmed, "{") + } else if (trimmed.length != 1) { + counter++ + } - if (trimmed.contains("}")) { - closedBrackets += frequency(trimmed, "}") - } - } + if (trimmed.contains("}")) { + closedBrackets += frequency(trimmed, "}") + } + } - private fun countOrEscapeAdditionalStatements(trimmed: String) { - escape = isEscaped(trimmed, escapes) - if (escape && isFullMode) { - counter++ - } - } + private fun countOrEscapeAdditionalStatements(trimmed: String) { + escape = isEscaped(trimmed, escapes) + if (escape && isFullMode) { + counter++ + } + } - private fun countOrEscapeComment(trimmed: String) { - escape = isEscaped(trimmed, comments) - if (isCommentMode && escape) { - counter++ - } - } + private fun countOrEscapeComment(trimmed: String) { + escape = isEscaped(trimmed, comments) + if (isCommentMode && escape) { + counter++ + } + } - private fun isEscaped(trimmed: String, rules: Array): Boolean { - return rules.any { trimmed.startsWith(it) } - } + private fun isEscaped(trimmed: String, rules: Array): Boolean { + return rules.any { trimmed.startsWith(it) } + } - private fun frequency(source: String, part: String): Int { + private fun frequency(source: String, part: String): Int { - if (source.isEmpty() || part.isEmpty()) { - return 0 - } + if (source.isEmpty() || part.isEmpty()) { + return 0 + } - var count = 0 - var pos = source.indexOf(part, 0) - while (pos != -1) { - pos += part.length - count++ - pos = source.indexOf(part, pos) - } + var count = 0 + var pos = source.indexOf(part, 0) + while (pos != -1) { + pos += part.length + count++ + pos = source.indexOf(part, pos) + } - return count - } - } + return count + } + } } diff --git a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/api/internal/McCabeVisitorSpec.kt b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/api/internal/McCabeVisitorSpec.kt index d965a579d..3a7989450 100644 --- a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/api/internal/McCabeVisitorSpec.kt +++ b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/api/internal/McCabeVisitorSpec.kt @@ -10,10 +10,10 @@ private const val FUN_MCC = 1 class McCabeVisitorSpec : Spek({ - given("ignoreSimpleWhenEntries is false") { + given("ignoreSimpleWhenEntries is false") { - it("counts simple when branches as 1") { - val code = """ + it("counts simple when branches as 1") { + val code = """ fun test() { when (System.currentTimeMillis()) { 0 -> println("Epoch!") @@ -22,15 +22,15 @@ class McCabeVisitorSpec : Spek({ } } """ - val subject = McCabeVisitor(ignoreSimpleWhenEntries = false) + val subject = McCabeVisitor(ignoreSimpleWhenEntries = false) - subject.visitFile(code.compile()) + subject.visitFile(code.compile()) - assertThat(subject.mcc).isEqualTo(FUN_MCC + 3) - } + assertThat(subject.mcc).isEqualTo(FUN_MCC + 3) + } - it("counts block when branches as 1") { - val code = """ + it("counts block when branches as 1") { + val code = """ fun test() { when (System.currentTimeMillis()) { 0 -> { @@ -41,18 +41,18 @@ class McCabeVisitorSpec : Spek({ } } """ - val subject = McCabeVisitor(ignoreSimpleWhenEntries = false) + val subject = McCabeVisitor(ignoreSimpleWhenEntries = false) - subject.visitFile(code.compile()) + subject.visitFile(code.compile()) - assertThat(subject.mcc).isEqualTo(FUN_MCC + 3) - } - } + assertThat(subject.mcc).isEqualTo(FUN_MCC + 3) + } + } - given("ignoreSimpleWhenEntries is true") { + given("ignoreSimpleWhenEntries is true") { - it("counts a when with only simple branches as 1") { - val code = """ + it("counts a when with only simple branches as 1") { + val code = """ fun test() { when (System.currentTimeMillis()) { 0 -> println("Epoch!") @@ -61,15 +61,15 @@ class McCabeVisitorSpec : Spek({ } } """ - val subject = McCabeVisitor(ignoreSimpleWhenEntries = true) + val subject = McCabeVisitor(ignoreSimpleWhenEntries = true) - subject.visitFile(code.compile()) + subject.visitFile(code.compile()) - assertThat(subject.mcc).isEqualTo(FUN_MCC + 1) - } + assertThat(subject.mcc).isEqualTo(FUN_MCC + 1) + } - it("does not count simple when branches") { - val code = """ + it("does not count simple when branches") { + val code = """ fun test() { when (System.currentTimeMillis()) { 0 -> { @@ -83,16 +83,16 @@ class McCabeVisitorSpec : Spek({ } } """ - val subject = McCabeVisitor(ignoreSimpleWhenEntries = true) + val subject = McCabeVisitor(ignoreSimpleWhenEntries = true) - subject.visitFile(code.compile()) + subject.visitFile(code.compile()) - assertThat(subject.mcc).isEqualTo(FUN_MCC + 2) - } + assertThat(subject.mcc).isEqualTo(FUN_MCC + 2) + } - it("counts block when branches as 1") { - val subject = McCabeVisitor(ignoreSimpleWhenEntries = true) - val code = """ + it("counts block when branches as 1") { + val subject = McCabeVisitor(ignoreSimpleWhenEntries = true) + val code = """ fun test() { when (System.currentTimeMillis()) { 0 -> { @@ -109,11 +109,11 @@ class McCabeVisitorSpec : Spek({ } """ - subject.visitFile(code.compile()) + subject.visitFile(code.compile()) - assertThat(subject.mcc).isEqualTo(FUN_MCC + 2) - } - } + assertThat(subject.mcc).isEqualTo(FUN_MCC + 2) + } + } }) private fun String.compile() = KtTestCompiler.compileFromContent(this.trimIndent()) diff --git a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/CustomRuleSetProviderSpec.kt b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/CustomRuleSetProviderSpec.kt index 70bcd1d1b..553594909 100644 --- a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/CustomRuleSetProviderSpec.kt +++ b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/CustomRuleSetProviderSpec.kt @@ -1,11 +1,11 @@ package io.gitlab.arturbosch.detekt.core import io.gitlab.arturbosch.detekt.test.resource +import java.nio.file.Paths import org.assertj.core.api.Assertions.assertThat import org.jetbrains.spek.api.Spek import org.jetbrains.spek.api.dsl.describe import org.jetbrains.spek.api.dsl.it -import java.nio.file.Paths /** * This test runs a precompiled jar with a custom rule provider. @@ -21,16 +21,16 @@ import java.nio.file.Paths */ class CustomRuleSetProviderSpec : Spek({ - describe("custom rule sets should be loadable through jars") { + describe("custom rule sets should be loadable through jars") { - val sampleRuleSet = Paths.get(resource("sample-rule-set.jar")) + val sampleRuleSet = Paths.get(resource("sample-rule-set.jar")) - it("should load the sample provider") { - val settings = ProcessingSettings(path, excludeDefaultRuleSets = true, pluginPaths = listOf(sampleRuleSet)) - val detekt = DetektFacade.create(settings) - val result = detekt.run() + it("should load the sample provider") { + val settings = ProcessingSettings(path, excludeDefaultRuleSets = true, pluginPaths = listOf(sampleRuleSet)) + val detekt = DetektFacade.create(settings) + val result = detekt.run() - assertThat(result.findings.keys).contains("sample") - } - } + assertThat(result.findings.keys).contains("sample") + } + } }) diff --git a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/DetektSpec.kt b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/DetektSpec.kt index 402d24462..7a1da4c6c 100644 --- a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/DetektSpec.kt +++ b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/DetektSpec.kt @@ -10,12 +10,12 @@ import org.jetbrains.spek.api.dsl.it */ class DetektSpec : Spek({ - describe("default providers must be registered in META-INF/services") { + describe("default providers must be registered in META-INF/services") { - val detekt = DetektFacade.create(ProcessingSettings(path)) + val detekt = DetektFacade.create(ProcessingSettings(path)) - it("should detect findings from more than one provider") { - assertThat(detekt.run().findings).isNotEmpty - } - } + it("should detect findings from more than one provider") { + assertThat(detekt.run().findings).isNotEmpty + } + } }) diff --git a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/DetektorTest.kt b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/DetektorTest.kt index eb26aeed4..3afcf3f99 100644 --- a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/DetektorTest.kt +++ b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/DetektorTest.kt @@ -10,20 +10,20 @@ import org.jetbrains.spek.api.dsl.it */ class DetektorTest : Spek({ - it("TestProvider gets excluded as RuleSet") { - runDetektWithPattern("patterns/test-pattern.yml") - } + it("TestProvider gets excluded as RuleSet") { + runDetektWithPattern("patterns/test-pattern.yml") + } - it("FindName rule gets excluded") { - runDetektWithPattern("patterns/exclude-FindName.yml") - } + it("FindName rule gets excluded") { + runDetektWithPattern("patterns/exclude-FindName.yml") + } }) private fun runDetektWithPattern(patternToUse: String) { - val instance = DetektFacade.create(ProcessingSettings(path, - config = yamlConfig(patternToUse)), - listOf(TestProvider(), TestProvider2()), emptyList()) + val instance = DetektFacade.create(ProcessingSettings(path, + config = yamlConfig(patternToUse)), + listOf(TestProvider(), TestProvider2()), emptyList()) - val run = instance.run() - assertThat(run.findings["Test"]?.none { "Test.kt" in it.file } ?: true).isTrue() + val run = instance.run() + assertThat(run.findings["Test"]?.none { "Test.kt" in it.file } ?: true).isTrue() } diff --git a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/KT.kt b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/KT.kt index fef5cd6d1..7badd4987 100644 --- a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/KT.kt +++ b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/KT.kt @@ -10,9 +10,9 @@ import io.gitlab.arturbosch.detekt.api.RuleSet import io.gitlab.arturbosch.detekt.api.RuleSetProvider import io.gitlab.arturbosch.detekt.api.Severity import io.gitlab.arturbosch.detekt.test.resource -import org.jetbrains.kotlin.psi.KtClassOrObject import java.nio.file.Path import java.nio.file.Paths +import org.jetbrains.kotlin.psi.KtClassOrObject /** * @author Artur Bosch @@ -21,20 +21,20 @@ import java.nio.file.Paths val path: Path = Paths.get(resource("/cases")) class TestProvider(override val ruleSetId: String = "Test") : RuleSetProvider { - override fun instance(config: Config): RuleSet { - return RuleSet("Test", listOf(FindName())) - } + override fun instance(config: Config): RuleSet { + return RuleSet("Test", listOf(FindName())) + } } class TestProvider2(override val ruleSetId: String = "Test2") : RuleSetProvider { - override fun instance(config: Config): RuleSet { - return RuleSet("Test", listOf()) - } + override fun instance(config: Config): RuleSet { + return RuleSet("Test", listOf()) + } } class FindName : Rule() { - override val issue: Issue = Issue(javaClass.simpleName, Severity.Minor, "", Debt.TWENTY_MINS) - override fun visitClassOrObject(classOrObject: KtClassOrObject) { - report(CodeSmell(issue, Entity.from(classOrObject), message = "")) - } + override val issue: Issue = Issue(javaClass.simpleName, Severity.Minor, "", Debt.TWENTY_MINS) + override fun visitClassOrObject(classOrObject: KtClassOrObject) { + report(CodeSmell(issue, Entity.from(classOrObject), message = "")) + } } diff --git a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/KtCompilerTest.kt b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/KtCompilerTest.kt index 30efef658..57adafe29 100644 --- a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/KtCompilerTest.kt +++ b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/KtCompilerTest.kt @@ -9,13 +9,13 @@ import org.jetbrains.spek.api.dsl.it */ class KtCompilerTest : Spek({ - it("ktFileHasExtraUserData") { - val ktCompiler = KtCompiler() + it("ktFileHasExtraUserData") { + val ktCompiler = KtCompiler() - val ktFile = ktCompiler.compile(path, path.resolve("Default.kt")) + val ktFile = ktCompiler.compile(path, path.resolve("Default.kt")) - assertThat(ktFile.getUserData(KtCompiler.LINE_SEPARATOR)).isEqualTo("\n") - assertThat(ktFile.getUserData(KtCompiler.RELATIVE_PATH)) - .isEqualTo(path.fileName.resolve("Default.kt").toString()) - } + assertThat(ktFile.getUserData(KtCompiler.LINE_SEPARATOR)).isEqualTo("\n") + assertThat(ktFile.getUserData(KtCompiler.RELATIVE_PATH)) + .isEqualTo(path.fileName.resolve("Default.kt").toString()) + } }) diff --git a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/KtTreeCompilerSpec.kt b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/KtTreeCompilerSpec.kt index d0915e6d6..d08602b1c 100644 --- a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/KtTreeCompilerSpec.kt +++ b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/KtTreeCompilerSpec.kt @@ -10,33 +10,33 @@ import org.jetbrains.spek.api.dsl.it */ class KtTreeCompilerSpec : Spek({ - describe("tree compiler functionality") { + describe("tree compiler functionality") { - it("should compile all files") { - val ktFiles = KtTreeCompiler().compile(path) - assertThat(ktFiles.size) - .describedAs("It should compile at least three files, but did ${ktFiles.size}") - .isGreaterThanOrEqualTo(3) - } + it("should compile all files") { + val ktFiles = KtTreeCompiler().compile(path) + assertThat(ktFiles.size) + .describedAs("It should compile at least three files, but did ${ktFiles.size}") + .isGreaterThanOrEqualTo(3) + } - it("should filter the file 'Default.kt'") { - val filter = PathFilter(".*Default.kt") - val ktFiles = KtTreeCompiler(filters = listOf(filter)).compile(path) - val ktFile = ktFiles.find { it.name == "Default.kt" } - assertThat(ktFile).describedAs("It should have no Default.kt file").isNull() - } + it("should filter the file 'Default.kt'") { + val filter = PathFilter(".*Default.kt") + val ktFiles = KtTreeCompiler(filters = listOf(filter)).compile(path) + val ktFile = ktFiles.find { it.name == "Default.kt" } + assertThat(ktFile).describedAs("It should have no Default.kt file").isNull() + } - it("should work with two or more filters") { - val filter = PathFilter(".*Default.kt") - val filterTwo = PathFilter(".*Test.*") - val filterThree = PathFilter(".*Complex.*") - val filterFour = PathFilter(".*KotlinScript.*") - val ktFiles = KtTreeCompiler(filters = listOf(filter, filterTwo, filterThree, filterFour)).compile(path) - assertThat(ktFiles).isEmpty() - } + it("should work with two or more filters") { + val filter = PathFilter(".*Default.kt") + val filterTwo = PathFilter(".*Test.*") + val filterThree = PathFilter(".*Complex.*") + val filterFour = PathFilter(".*KotlinScript.*") + val ktFiles = KtTreeCompiler(filters = listOf(filter, filterTwo, filterThree, filterFour)).compile(path) + assertThat(ktFiles).isEmpty() + } - it("should also compile regular files") { - assertThat(KtTreeCompiler().compile(path.resolve("Default.kt")).size).isEqualTo(1) - } - } + it("should also compile regular files") { + assertThat(KtTreeCompiler().compile(path.resolve("Default.kt")).size).isEqualTo(1) + } + } }) diff --git a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/PathFilterSpec.kt b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/PathFilterSpec.kt index 02f1421ef..7e36da366 100644 --- a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/PathFilterSpec.kt +++ b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/PathFilterSpec.kt @@ -1,66 +1,66 @@ package io.gitlab.arturbosch.detekt.core +import java.nio.file.Paths import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThatIllegalArgumentException import org.jetbrains.spek.api.Spek import org.jetbrains.spek.api.dsl.given import org.jetbrains.spek.api.dsl.it -import java.nio.file.Paths internal class PathFilterSpec : Spek({ - given("an invalid regex pattern") { - it("throws an IllegalArgumentException") { - assertThatIllegalArgumentException().isThrownBy { PathFilter("*.") } - } - } + given("an invalid regex pattern") { + it("throws an IllegalArgumentException") { + assertThatIllegalArgumentException().isThrownBy { PathFilter("*.") } + } + } - given("an empty pattern") { - it("throws an IllegalArgumentException") { - assertThatIllegalArgumentException().isThrownBy { PathFilter("") } - } - } + given("an empty pattern") { + it("throws an IllegalArgumentException") { + assertThatIllegalArgumentException().isThrownBy { PathFilter("") } + } + } - given("an blank pattern") { - it("throws an IllegalArgumentException") { - assertThatIllegalArgumentException().isThrownBy { PathFilter(" ") } - } - } + given("an blank pattern") { + it("throws an IllegalArgumentException") { + assertThatIllegalArgumentException().isThrownBy { PathFilter(" ") } + } + } - given("a single regex pattern on Unix systems") { - val filter = ".*/build/.*" - val defaultRoot = Paths.get("").toAbsolutePath() + given("a single regex pattern on Unix systems") { + val filter = ".*/build/.*" + val defaultRoot = Paths.get("").toAbsolutePath() - it("matches a corresponding relative path") { - val path = defaultRoot.resolve("some/build/path/should/match") + it("matches a corresponding relative path") { + val path = defaultRoot.resolve("some/build/path/should/match") - assertThat(PathFilter(filter).matches(path)).isTrue() - } + assertThat(PathFilter(filter).matches(path)).isTrue() + } - it("matches a corresponding relative path with the filter in the beginning") { - val path = defaultRoot.resolve("build/path/should/match") + it("matches a corresponding relative path with the filter in the beginning") { + val path = defaultRoot.resolve("build/path/should/match") - assertThat(PathFilter(filter).matches(path)).isTrue() - } + assertThat(PathFilter(filter).matches(path)).isTrue() + } - it("does not match an unrelated path") { - val path = defaultRoot.resolve("this/should/NOT/match") + it("does not match an unrelated path") { + val path = defaultRoot.resolve("this/should/NOT/match") - assertThat(PathFilter(filter).matches(path)).isFalse() - } + assertThat(PathFilter(filter).matches(path)).isFalse() + } - it("does not match the pattern in the absolute path") { - val root = Paths.get("/tmp/build/detekt").toAbsolutePath() - val path = root.resolve("should/not/match") + it("does not match the pattern in the absolute path") { + val root = Paths.get("/tmp/build/detekt").toAbsolutePath() + val path = root.resolve("should/not/match") - assertThat(PathFilter(filter, root).matches(path)).isFalse() - } + assertThat(PathFilter(filter, root).matches(path)).isFalse() + } - it("does not match the pattern in the absolute path but the relative path") { - val root = Paths.get("/tmp/detekt").toAbsolutePath() - val path = root.resolve("should/match/build/path") + it("does not match the pattern in the absolute path but the relative path") { + val root = Paths.get("/tmp/detekt").toAbsolutePath() + val path = root.resolve("should/match/build/path") - assertThat(PathFilter(filter, root).matches(path)).isTrue() - } - } + assertThat(PathFilter(filter, root).matches(path)).isTrue() + } + } }) diff --git a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/RuleSetLocatorTest.kt b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/RuleSetLocatorTest.kt index 1a1f540cc..8b4703633 100644 --- a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/RuleSetLocatorTest.kt +++ b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/RuleSetLocatorTest.kt @@ -1,29 +1,29 @@ package io.gitlab.arturbosch.detekt.core import io.gitlab.arturbosch.detekt.api.RuleSetProvider +import java.lang.reflect.Modifier import org.assertj.core.api.Assertions import org.assertj.core.api.Assertions.assertThat import org.jetbrains.spek.api.Spek import org.jetbrains.spek.api.dsl.it import org.reflections.Reflections -import java.lang.reflect.Modifier class RuleSetLocatorTest : Spek({ - it("containsAllRuleProviders") { - val locator = RuleSetLocator(ProcessingSettings(path)) - val providers = locator.load() - val providerClasses = getProviderClasses() + it("containsAllRuleProviders") { + val locator = RuleSetLocator(ProcessingSettings(path)) + val providers = locator.load() + val providerClasses = getProviderClasses() - assertThat(providerClasses).isNotEmpty - providerClasses - .filter { clazz -> providers.firstOrNull { it.javaClass == clazz } == null } - .forEach { Assertions.fail("$it rule set is not loaded by the RuleSetLocator") } - } + assertThat(providerClasses).isNotEmpty + providerClasses + .filter { clazz -> providers.firstOrNull { it.javaClass == clazz } == null } + .forEach { Assertions.fail("$it rule set is not loaded by the RuleSetLocator") } + } }) private fun getProviderClasses(): List> { - return Reflections("io.gitlab.arturbosch.detekt.rules.providers") - .getSubTypesOf(RuleSetProvider::class.java) - .filter { !Modifier.isAbstract(it.modifiers) } + return Reflections("io.gitlab.arturbosch.detekt.rules.providers") + .getSubTypesOf(RuleSetProvider::class.java) + .filter { !Modifier.isAbstract(it.modifiers) } } diff --git a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/TestPatternTest.kt b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/TestPatternTest.kt index 1227a44c8..f49a36e5e 100644 --- a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/TestPatternTest.kt +++ b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/TestPatternTest.kt @@ -1,71 +1,71 @@ package io.gitlab.arturbosch.detekt.core import io.gitlab.arturbosch.detekt.test.yamlConfig +import java.nio.file.Path +import java.nio.file.Paths import org.assertj.core.api.Assertions.assertThat import org.jetbrains.spek.api.Spek import org.jetbrains.spek.api.dsl.given import org.jetbrains.spek.api.dsl.it -import java.nio.file.Path -import java.nio.file.Paths /** * @author Artur Bosch */ class TestPatternTest : Spek({ - given("a test pattern for paths") { + given("a test pattern for paths") { - fun splitSources(pattern: TestPattern, path: Path): Pair, List> = - listOf(path).partition { pattern.matches(it.toString()) } + fun splitSources(pattern: TestPattern, path: Path): Pair, List> = + listOf(path).partition { pattern.matches(it.toString()) } - val defaultPattern = createTestPattern(yamlConfig("patterns/test-pattern.yml")) + val defaultPattern = createTestPattern(yamlConfig("patterns/test-pattern.yml")) - it("should identify a kt file in test path as test source with test as the first directory") { - val path = "./test/SomeFile.kt" - val (testSources, mainSources) = splitSources(defaultPattern, Paths.get(path)) + it("should identify a kt file in test path as test source with test as the first directory") { + val path = "./test/SomeFile.kt" + val (testSources, mainSources) = splitSources(defaultPattern, Paths.get(path)) - assertThat(testSources).allMatch { it.toString().endsWith(path.toFile()) } - assertThat(testSources).isNotEmpty() - assertThat(mainSources).isEmpty() - } + assertThat(testSources).allMatch { it.toString().endsWith(path.toFile()) } + assertThat(testSources).isNotEmpty() + assertThat(mainSources).isEmpty() + } - it("should identify a kt file in test path as test source") { - val path = "./path/test/SomeFile.kt" - val (testSources, mainSources) = splitSources(defaultPattern, Paths.get(path)) + it("should identify a kt file in test path as test source") { + val path = "./path/test/SomeFile.kt" + val (testSources, mainSources) = splitSources(defaultPattern, Paths.get(path)) - assertThat(testSources).allMatch { it.toString().endsWith(path.toFile()) } - assertThat(testSources).isNotEmpty() - assertThat(mainSources).isEmpty() - } + assertThat(testSources).allMatch { it.toString().endsWith(path.toFile()) } + assertThat(testSources).isNotEmpty() + assertThat(mainSources).isEmpty() + } - it("should identify kt Test file as test source") { - val path = "./some/path/abcTest.kt" - val (testSources, mainSources) = splitSources(defaultPattern, Paths.get(path)) + it("should identify kt Test file as test source") { + val path = "./some/path/abcTest.kt" + val (testSources, mainSources) = splitSources(defaultPattern, Paths.get(path)) - assertThat(testSources).allMatch { it.toString().endsWith(path.toFile()) } - assertThat(testSources).isNotEmpty() - assertThat(mainSources).isEmpty() - } + assertThat(testSources).allMatch { it.toString().endsWith(path.toFile()) } + assertThat(testSources).isNotEmpty() + assertThat(mainSources).isEmpty() + } - it("should not identify kt files in an absolute path containing test as test source") { - val pattern = createTestPattern(yamlConfig("patterns/test-pattern.yml"), Paths.get("/path/test/detekt")) - val path = "./some/path/SomeFile.kt" - val (testSources, mainSources) = splitSources(pattern, Paths.get(path)) + it("should not identify kt files in an absolute path containing test as test source") { + val pattern = createTestPattern(yamlConfig("patterns/test-pattern.yml"), Paths.get("/path/test/detekt")) + val path = "./some/path/SomeFile.kt" + val (testSources, mainSources) = splitSources(pattern, Paths.get(path)) - assertThat(testSources).isEmpty() - assertThat(mainSources).allMatch { it.toString().endsWith(path.toFile()) } - assertThat(mainSources).isNotEmpty() - } + assertThat(testSources).isEmpty() + assertThat(mainSources).allMatch { it.toString().endsWith(path.toFile()) } + assertThat(mainSources).isNotEmpty() + } - it("should not identify a non-test kt file as test source") { - val path = "./some/path/abc.kt" - val (testSources, mainSources) = splitSources(defaultPattern, Paths.get(path)) + it("should not identify a non-test kt file as test source") { + val path = "./some/path/abc.kt" + val (testSources, mainSources) = splitSources(defaultPattern, Paths.get(path)) - assertThat(testSources).isEmpty() - assertThat(mainSources).allMatch { it.toString().endsWith(path.toFile()) } - assertThat(mainSources).isNotEmpty() - } - } + assertThat(testSources).isEmpty() + assertThat(mainSources).allMatch { it.toString().endsWith(path.toFile()) } + assertThat(mainSources).isNotEmpty() + } + } }) private fun String.toFile() = this.split('/').last() diff --git a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/CLOCVisitorTest.kt b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/CLOCVisitorTest.kt index 6b72874dc..68b4f6f9e 100644 --- a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/CLOCVisitorTest.kt +++ b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/CLOCVisitorTest.kt @@ -8,12 +8,12 @@ import org.jetbrains.spek.api.dsl.it class CLOCVisitorTest : Spek({ - it("commentCases") { - val file = compileForTest(path.resolve("../comments/CommentsClass.kt")) - val commentLines = with(file) { - accept(CLOCVisitor()) - getUserData(commentLinesKey) - } - assertThat(commentLines).isEqualTo(10) - } + it("commentCases") { + val file = compileForTest(path.resolve("../comments/CommentsClass.kt")) + val commentLines = with(file) { + accept(CLOCVisitor()) + getUserData(commentLinesKey) + } + assertThat(commentLines).isEqualTo(10) + } }) diff --git a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/ClassCountVisitorTest.kt b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/ClassCountVisitorTest.kt index f2e048ef6..a411a612d 100644 --- a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/ClassCountVisitorTest.kt +++ b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/ClassCountVisitorTest.kt @@ -9,40 +9,40 @@ import org.jetbrains.spek.api.dsl.it class ClassCountVisitorTest : Spek({ - it("twoClassesInSeparateFile") { - val files = arrayOf( - compileForTest(path.resolve("Test.kt")), - compileForTest(path.resolve("Default.kt")) - ) - val count = getClassCount(files) - assertThat(count).isEqualTo(2) - } + it("twoClassesInSeparateFile") { + val files = arrayOf( + compileForTest(path.resolve("Test.kt")), + compileForTest(path.resolve("Default.kt")) + ) + val count = getClassCount(files) + assertThat(count).isEqualTo(2) + } - it("oneClassWithOneNestedClass") { - val file = compileForTest(path.resolve("ComplexClass.kt")) - val count = getClassCount(arrayOf(file)) - assertThat(count).isEqualTo(2) - } + it("oneClassWithOneNestedClass") { + val file = compileForTest(path.resolve("ComplexClass.kt")) + val count = getClassCount(arrayOf(file)) + assertThat(count).isEqualTo(2) + } - it("testEnumAndInterface") { - val files = arrayOf( - compileForTest(path.resolve("../empty/EmptyEnum.kt")), - compileForTest(path.resolve("../empty/EmptyInterface.kt")) - ) - val count = getClassCount(files) - assertThat(count).isEqualTo(2) - } + it("testEnumAndInterface") { + val files = arrayOf( + compileForTest(path.resolve("../empty/EmptyEnum.kt")), + compileForTest(path.resolve("../empty/EmptyInterface.kt")) + ) + val count = getClassCount(files) + assertThat(count).isEqualTo(2) + } }) private fun getClassCount(files: Array): Int { - return files - .map { getData(it) } - .sum() + return files + .map { getData(it) } + .sum() } private fun getData(file: KtFile): Int { - return with(file) { - accept(ClassCountVisitor()) - getUserData(numberOfClassesKey)!! - } + return with(file) { + accept(ClassCountVisitor()) + getUserData(numberOfClassesKey)!! + } } diff --git a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/ComplexityVisitorTest.kt b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/ComplexityVisitorTest.kt index 3e9578dd0..eef16dee8 100644 --- a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/ComplexityVisitorTest.kt +++ b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/ComplexityVisitorTest.kt @@ -2,34 +2,34 @@ package io.gitlab.arturbosch.detekt.core.processors import io.gitlab.arturbosch.detekt.core.path import io.gitlab.arturbosch.detekt.test.compileForTest +import java.nio.file.Path import org.assertj.core.api.Assertions.assertThat import org.jetbrains.spek.api.Spek import org.jetbrains.spek.api.dsl.it -import java.nio.file.Path /** * @author Artur Bosch */ class ComplexityVisitorTest : Spek({ - it("complexityOfDefaultCaseIsOne") { - val path = path.resolve("Default.kt") + it("complexityOfDefaultCaseIsOne") { + val path = path.resolve("Default.kt") - val mcc = calcComplexity(path) + val mcc = calcComplexity(path) - assertThat(mcc).isEqualTo(0) - } + assertThat(mcc).isEqualTo(0) + } - it("complexityOfComplexAndNestedClass") { - val path = path.resolve("ComplexClass.kt") + it("complexityOfComplexAndNestedClass") { + val path = path.resolve("ComplexClass.kt") - val mcc = calcComplexity(path) + val mcc = calcComplexity(path) - assertThat(mcc).isEqualTo(56) - } + assertThat(mcc).isEqualTo(56) + } }) private fun calcComplexity(path: Path) = with(compileForTest(path)) { - accept(ComplexityVisitor()) - getUserData(complexityKey) + accept(ComplexityVisitor()) + getUserData(complexityKey) } diff --git a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/FieldCountVisitorTest.kt b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/FieldCountVisitorTest.kt index 205b21db8..200cafbb5 100644 --- a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/FieldCountVisitorTest.kt +++ b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/FieldCountVisitorTest.kt @@ -8,12 +8,12 @@ import org.jetbrains.spek.api.dsl.it class FieldCountVisitorTest : Spek({ - it("defaultFieldCount") { - val file = compileForTest(path.resolve("../fields/ClassWithFields.kt")) - val count = with(file) { - accept(PropertyCountVisitor()) - getUserData(numberOfFieldsKey) - } - assertThat(count).isEqualTo(2) - } + it("defaultFieldCount") { + val file = compileForTest(path.resolve("../fields/ClassWithFields.kt")) + val count = with(file) { + accept(PropertyCountVisitor()) + getUserData(numberOfFieldsKey) + } + assertThat(count).isEqualTo(2) + } }) diff --git a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/KtFileCountVisitorTest.kt b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/KtFileCountVisitorTest.kt index 098f587e5..df3646555 100644 --- a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/KtFileCountVisitorTest.kt +++ b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/KtFileCountVisitorTest.kt @@ -9,21 +9,21 @@ import org.jetbrains.spek.api.dsl.it class KtFileCountVisitorTest : Spek({ - it("twoFiles") { - val files = arrayOf( - compileForTest(path.resolve("Default.kt")), - compileForTest(path.resolve("Test.kt")) - ) - val count = files - .map { getData(it) } - .sum() - Assertions.assertThat(count).isEqualTo(2) - } + it("twoFiles") { + val files = arrayOf( + compileForTest(path.resolve("Default.kt")), + compileForTest(path.resolve("Test.kt")) + ) + val count = files + .map { getData(it) } + .sum() + Assertions.assertThat(count).isEqualTo(2) + } }) private fun getData(file: KtFile): Int { - return with(file) { - accept(KtFileCountVisitor()) - getUserData(numberOfFilesKey)!! - } + return with(file) { + accept(KtFileCountVisitor()) + getUserData(numberOfFilesKey)!! + } } diff --git a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/LLOCVisitorTest.kt b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/LLOCVisitorTest.kt index cd53795eb..6d6d4b58c 100644 --- a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/LLOCVisitorTest.kt +++ b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/LLOCVisitorTest.kt @@ -11,25 +11,25 @@ import org.jetbrains.spek.api.dsl.it */ class LLOCVisitorTest : Spek({ - it("defaultCaseHasOneClassAndAnnotationLine") { - val file = compileForTest(path.resolve("Default.kt")) + it("defaultCaseHasOneClassAndAnnotationLine") { + val file = compileForTest(path.resolve("Default.kt")) - val lloc = with(file) { - accept(LLOCVisitor()) - getUserData(logicalLinesKey) - } + val lloc = with(file) { + accept(LLOCVisitor()) + getUserData(logicalLinesKey) + } - assertThat(lloc).isEqualTo(2) - } + assertThat(lloc).isEqualTo(2) + } - it("llocOfComplexClass") { - val file = compileForTest(path.resolve("ComplexClass.kt")) + it("llocOfComplexClass") { + val file = compileForTest(path.resolve("ComplexClass.kt")) - val lloc = with(file) { - accept(LLOCVisitor()) - getUserData(logicalLinesKey) - } + val lloc = with(file) { + accept(LLOCVisitor()) + getUserData(logicalLinesKey) + } - assertThat(lloc).isEqualTo(85) - } + assertThat(lloc).isEqualTo(85) + } }) diff --git a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/LOCVisitorTest.kt b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/LOCVisitorTest.kt index 30cc2d687..3883ab47a 100644 --- a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/LOCVisitorTest.kt +++ b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/LOCVisitorTest.kt @@ -8,12 +8,12 @@ import org.jetbrains.spek.api.dsl.it class LOCVisitorTest : Spek({ - it("defaultClass") { - val file = compileForTest(path.resolve("Default.kt")) - val loc = with(file) { - accept(LOCVisitor()) - getUserData(linesKey) - } - Assertions.assertThat(loc).isEqualTo(8) - } + it("defaultClass") { + val file = compileForTest(path.resolve("Default.kt")) + val loc = with(file) { + accept(LOCVisitor()) + getUserData(linesKey) + } + Assertions.assertThat(loc).isEqualTo(8) + } }) diff --git a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/MethodCountVisitorTest.kt b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/MethodCountVisitorTest.kt index fcab22fa4..b4335d361 100644 --- a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/MethodCountVisitorTest.kt +++ b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/MethodCountVisitorTest.kt @@ -9,17 +9,16 @@ import org.jetbrains.spek.api.dsl.it class MethodCountVisitorTest : Spek({ - it("defaultMethodCount") { - val file = compileForTest(path.resolve("ComplexClass.kt")) - val count = getMethodCount(file) - assertThat(count).isEqualTo(6) - } - + it("defaultMethodCount") { + val file = compileForTest(path.resolve("ComplexClass.kt")) + val count = getMethodCount(file) + assertThat(count).isEqualTo(6) + } }) private fun getMethodCount(file: KtFile): Int { - return with(file) { - accept(FunctionCountVisitor()) - getUserData(numberOfFunctionsKey)!! - } + return with(file) { + accept(FunctionCountVisitor()) + getUserData(numberOfFunctionsKey)!! + } } diff --git a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/PackageCountVisitorTest.kt b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/PackageCountVisitorTest.kt index ab4a416a1..352d41c1c 100644 --- a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/PackageCountVisitorTest.kt +++ b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/PackageCountVisitorTest.kt @@ -9,23 +9,22 @@ import org.jetbrains.spek.api.dsl.it class PackageCountVisitorTest : Spek({ - it("twoClassesInSeparatePackage") { - val files = arrayOf( - compileForTest(path.resolve("Default.kt")), - compileForTest(path.resolve("../empty/EmptyEnum.kt")) - ) - val count = files - .map { getData(it) } - .distinct() - .count() - Assertions.assertThat(count).isEqualTo(2) - } - + it("twoClassesInSeparatePackage") { + val files = arrayOf( + compileForTest(path.resolve("Default.kt")), + compileForTest(path.resolve("../empty/EmptyEnum.kt")) + ) + val count = files + .map { getData(it) } + .distinct() + .count() + Assertions.assertThat(count).isEqualTo(2) + } }) private fun getData(file: KtFile): String { - return with(file) { - accept(PackageCountVisitor()) - getUserData(numberOfPackagesKey)!! - } + return with(file) { + accept(PackageCountVisitor()) + getUserData(numberOfPackagesKey)!! + } } diff --git a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/SLOCVisitorTest.kt b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/SLOCVisitorTest.kt index 9534e1d31..8538e605b 100644 --- a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/SLOCVisitorTest.kt +++ b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/processors/SLOCVisitorTest.kt @@ -8,12 +8,12 @@ import org.jetbrains.spek.api.dsl.it class SLOCVisitorTest : Spek({ - it("defaultClass") { - val file = compileForTest(path.resolve("Default.kt")) - val loc = with(file) { - accept(SLOCVisitor()) - getUserData(sourceLinesKey) - } - Assertions.assertThat(loc).isEqualTo(3) - } + it("defaultClass") { + val file = compileForTest(path.resolve("Default.kt")) + val loc = with(file) { + accept(SLOCVisitor()) + getUserData(sourceLinesKey) + } + Assertions.assertThat(loc).isEqualTo(3) + } }) diff --git a/detekt-core/src/test/resources/cases/ComplexClass.kt b/detekt-core/src/test/resources/cases/ComplexClass.kt index f93393fc1..b6c3b2820 100644 --- a/detekt-core/src/test/resources/cases/ComplexClass.kt +++ b/detekt-core/src/test/resources/cases/ComplexClass.kt @@ -8,139 +8,141 @@ import org.jetbrains.kotlin.utils.sure @Suppress("unused") class ComplexClass {// McCabe: 56, LLOC: 20 + 20 + 4x4 - class NestedClass { //20 - fun complex() { //1 + - try {//5 - while (true) { - if (true) { - when ("string") { - "" -> println() - else -> println() - } - } - } - } catch (ex: Exception) { //1 + 5 - try { - println() - } catch (ex: Exception) { - while (true) { - if (false) { - println() - } else { - println() - } - } - } - } finally { // 6 - try { - println() - } catch (ex: Exception) { - while (true) { - if (false) { - println() - } else { - println() - } - } - } - } - (1..10).forEach { //1 - println() - } - for (i in 1..10) { //1 - println() - } - } - } + class NestedClass { //20 + fun complex() { //1 + + try {//5 + while (true) { + if (true) { + when ("string") { + "" -> println() + else -> println() + } + } + } + } catch (ex: Exception) { //1 + 5 + try { + println() + } catch (ex: Exception) { + while (true) { + if (false) { + println() + } else { + println() + } + } + } + } finally { // 6 + try { + println() + } catch (ex: Exception) { + while (true) { + if (false) { + println() + } else { + println() + } + } + } + } + (1..10).forEach { + //1 + println() + } + for (i in 1..10) { //1 + println() + } + } + } - fun complex() { //1 + - try {//5 - while (true) { - if (true) { - when ("string") { - "" -> println() - else -> println() - } - } - } - } catch (ex: Exception) { //1 + 5 - try { - println() - } catch (ex: Exception) { - while (true) { - if (false) { - println() - } else { - println() - } - } - } - } finally { // 6 - try { - println() - } catch (ex: Exception) { - while (true) { - if (false) { - println() - } else { - println() - } - } - } - } - (1..10).forEach { //1 - println() - } - for (i in 1..10) { //1 - println() - } - } + fun complex() { //1 + + try {//5 + while (true) { + if (true) { + when ("string") { + "" -> println() + else -> println() + } + } + } + } catch (ex: Exception) { //1 + 5 + try { + println() + } catch (ex: Exception) { + while (true) { + if (false) { + println() + } else { + println() + } + } + } + } finally { // 6 + try { + println() + } catch (ex: Exception) { + while (true) { + if (false) { + println() + } else { + println() + } + } + } + } + (1..10).forEach { + //1 + println() + } + for (i in 1..10) { //1 + println() + } + } - fun manyClosures() {//4 - true.let { - true.apply { - true.run { - true.sure { - "" - } - } - } - } - } + fun manyClosures() {//4 + true.let { + true.apply { + true.run { + true.sure { + "" + } + } + } + } + } - fun manyClosures2() {//4 - true.let { - true.apply { - true.run { - true.sure { - "" - } - } - } - } - } + fun manyClosures2() {//4 + true.let { + true.apply { + true.run { + true.sure { + "" + } + } + } + } + } - fun manyClosures3() {//4 - true.let { - true.apply { - true.run { - true.sure { - "" - } - } - } - } - } + fun manyClosures3() {//4 + true.let { + true.apply { + true.run { + true.sure { + "" + } + } + } + } + } - fun manyClosures4() {//4 - true.let { - true.apply { - true.run { - true.sure { - "" - } - } - } - } - } + fun manyClosures4() {//4 + true.let { + true.apply { + true.run { + true.sure { + "" + } + } + } + } + } } diff --git a/detekt-core/src/test/resources/comments/CommentsClass.kt b/detekt-core/src/test/resources/comments/CommentsClass.kt index d213f188d..7b8fcaa88 100644 --- a/detekt-core/src/test/resources/comments/CommentsClass.kt +++ b/detekt-core/src/test/resources/comments/CommentsClass.kt @@ -3,20 +3,20 @@ package comments @Suppress("Unused") class CommentsClass { - /** - * Doc comment - * - * @param args - */ - fun x(args: String) { // comment total: 10 - /* - comment - */ - //Comment + /** + * Doc comment + * + * @param args + */ + fun x(args: String) { // comment total: 10 + /* + comment + */ + //Comment - println(args) + println(args) - println("/* no comment */") - println("// no comment //") - } + println("/* no comment */") + println("// no comment //") + } } diff --git a/detekt-formatting/build.gradle.kts b/detekt-formatting/build.gradle.kts index 50248365e..33d60eed8 100644 --- a/detekt-formatting/build.gradle.kts +++ b/detekt-formatting/build.gradle.kts @@ -8,25 +8,25 @@ val junitPlatformVersion: String by project val spekVersion: String by project dependencies { - implementation(kotlin("compiler-embeddable")) - implementation(project(":detekt-api")) - implementation("com.github.shyiko.ktlint:ktlint-ruleset-standard:$ktlintVersion") { - exclude(group = "org.jetbrains.kotlin") - } - implementation("com.github.shyiko.ktlint:ktlint-core:$ktlintVersion") { - exclude(group = "org.jetbrains.kotlin") - } + implementation(kotlin("compiler-embeddable")) + implementation(project(":detekt-api")) + implementation("com.github.shyiko.ktlint:ktlint-ruleset-standard:$ktlintVersion") { + exclude(group = "org.jetbrains.kotlin") + } + implementation("com.github.shyiko.ktlint:ktlint-core:$ktlintVersion") { + exclude(group = "org.jetbrains.kotlin") + } - testImplementation(project(":detekt-test")) - testImplementation(project(":detekt-core")) - testRuntimeOnly("org.junit.platform:junit-platform-launcher:$junitPlatformVersion") - testRuntimeOnly("org.jetbrains.spek:spek-junit-platform-engine:$spekVersion") + testImplementation(project(":detekt-test")) + testImplementation(project(":detekt-core")) + testRuntimeOnly("org.junit.platform:junit-platform-launcher:$junitPlatformVersion") + testRuntimeOnly("org.jetbrains.spek:spek-junit-platform-engine:$spekVersion") } tasks.withType { - from(Callable { - configurations["compile"].map { - if (it.isDirectory) it else zipTree(it) - } - }) + from(Callable { + configurations["compile"].map { + if (it.isDirectory) it else zipTree(it) + } + }) } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/EditorConfigMerge.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/EditorConfigMerge.kt index 984635e92..127aa1e7b 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/EditorConfigMerge.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/EditorConfigMerge.kt @@ -9,27 +9,27 @@ import com.github.shyiko.ktlint.core.EditorConfig * @author Lukasz Jazgar */ fun EditorConfig.Companion.merge( - sourceEditorConfig: EditorConfig?, - indentSize: Int? = null, - continuationIndentSize: Int? = null, - maxLineLength: Int? = null, - insertFinalNewline: Boolean? = null + sourceEditorConfig: EditorConfig?, + indentSize: Int? = null, + continuationIndentSize: Int? = null, + maxLineLength: Int? = null, + insertFinalNewline: Boolean? = null ): EditorConfig = - EditorConfig.fromMap( - HashMap().also { - copyProperty(it, "indent_size", indentSize, sourceEditorConfig) - copyProperty(it, "continuation_indent_size", continuationIndentSize, sourceEditorConfig) - copyProperty(it, "max_line_length", maxLineLength, sourceEditorConfig) - copyProperty(it, "insert_final_newline", insertFinalNewline, sourceEditorConfig) - } - ) + EditorConfig.fromMap( + HashMap().also { + copyProperty(it, "indent_size", indentSize, sourceEditorConfig) + copyProperty(it, "continuation_indent_size", continuationIndentSize, sourceEditorConfig) + copyProperty(it, "max_line_length", maxLineLength, sourceEditorConfig) + copyProperty(it, "insert_final_newline", insertFinalNewline, sourceEditorConfig) + } + ) private fun copyProperty( - map: MutableMap, - property: String, - value: Any?, - sourceEditorConfig: EditorConfig? + map: MutableMap, + property: String, + value: Any?, + sourceEditorConfig: EditorConfig? ) { - val newValue: String? = value?.toString() ?: sourceEditorConfig?.get(property) - newValue?.let { map[property] = it } + val newValue: String? = value?.toString() ?: sourceEditorConfig?.get(property) + newValue?.let { map[property] = it } } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/FormattingProvider.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/FormattingProvider.kt index 3fb7f0365..69b9edeb0 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/FormattingProvider.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/FormattingProvider.kt @@ -20,8 +20,8 @@ import io.gitlab.arturbosch.detekt.api.RuleSetProvider */ class FormattingProvider : RuleSetProvider { - override val ruleSetId: String = "formatting" + override val ruleSetId: String = "formatting" - override fun instance(config: Config) = - RuleSet(ruleSetId, listOf(KtLintMultiRule(config))) + override fun instance(config: Config) = + RuleSet(ruleSetId, listOf(KtLintMultiRule(config))) } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/FormattingRule.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/FormattingRule.kt index 0b7ab90d4..127c69216 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/FormattingRule.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/FormattingRule.kt @@ -27,56 +27,56 @@ import org.jetbrains.kotlin.psi.psiUtil.endOffset */ abstract class FormattingRule(config: Config) : Rule(config) { - abstract val wrapping: com.github.shyiko.ktlint.core.Rule + abstract val wrapping: com.github.shyiko.ktlint.core.Rule - protected fun issueFor(description: String) = - Issue(javaClass.simpleName, Severity.Style, description, Debt.FIVE_MINS) + protected fun issueFor(description: String) = + Issue(javaClass.simpleName, Severity.Style, description, Debt.FIVE_MINS) - /** - * Should the android style guide be enforced? - * This property is read from the ruleSet config. - */ - protected val isAndroid - get() = ruleSetConfig.valueOrDefault("android", false) + /** + * Should the android style guide be enforced? + * This property is read from the ruleSet config. + */ + protected val isAndroid + get() = ruleSetConfig.valueOrDefault("android", false) - private var positionByOffset: (offset: Int) -> Pair by SingleAssign() - private var root: KtFile by SingleAssign() + private var positionByOffset: (offset: Int) -> Pair by SingleAssign() + private var root: KtFile by SingleAssign() - override fun visit(root: KtFile) { - this.root = root - root.node.putUserData(KtLint.ANDROID_USER_DATA_KEY, isAndroid) - positionByOffset = calculateLineColByOffset(root.text).let { - val offsetDueToLineBreakNormalization = calculateLineBreakOffset(root.text) - return@let { offset: Int -> it(offset + offsetDueToLineBreakNormalization(offset)) } - } - editorConfigUpdater()?.let { updateFunc -> - val oldEditorConfig = root.node.getUserData(KtLint.EDITOR_CONFIG_USER_DATA_KEY) - root.node.putUserData(KtLint.EDITOR_CONFIG_USER_DATA_KEY, updateFunc(oldEditorConfig)) - } - } + override fun visit(root: KtFile) { + this.root = root + root.node.putUserData(KtLint.ANDROID_USER_DATA_KEY, isAndroid) + positionByOffset = calculateLineColByOffset(root.text).let { + val offsetDueToLineBreakNormalization = calculateLineBreakOffset(root.text) + return@let { offset: Int -> it(offset + offsetDueToLineBreakNormalization(offset)) } + } + editorConfigUpdater()?.let { updateFunc -> + val oldEditorConfig = root.node.getUserData(KtLint.EDITOR_CONFIG_USER_DATA_KEY) + root.node.putUserData(KtLint.EDITOR_CONFIG_USER_DATA_KEY, updateFunc(oldEditorConfig)) + } + } - open fun editorConfigUpdater(): ((oldEditorConfig: EditorConfig?) -> EditorConfig)? = null + open fun editorConfigUpdater(): ((oldEditorConfig: EditorConfig?) -> EditorConfig)? = null - fun apply(node: ASTNode) { - if (ruleShouldOnlyRunOnFileNode(node)) { - return - } - wrapping.visit(node, autoCorrect) { _, message, _ -> - val (line, column) = positionByOffset(node.startOffset) - report(CodeSmell(issue, - Entity(node.toString(), "", "", - Location(SourceLocation(line, column), - TextLocation(node.startOffset, node.psi.endOffset), - "($line, $column)", - root.originalFilePath() ?: root.containingFile.name)), - message)) - } - } + fun apply(node: ASTNode) { + if (ruleShouldOnlyRunOnFileNode(node)) { + return + } + wrapping.visit(node, autoCorrect) { _, message, _ -> + val (line, column) = positionByOffset(node.startOffset) + report(CodeSmell(issue, + Entity(node.toString(), "", "", + Location(SourceLocation(line, column), + TextLocation(node.startOffset, node.psi.endOffset), + "($line, $column)", + root.originalFilePath() ?: root.containingFile.name)), + message)) + } + } - private fun ruleShouldOnlyRunOnFileNode(node: ASTNode) = - wrapping is com.github.shyiko.ktlint.core.Rule.Modifier.RestrictToRoot && - node !is FileASTNode + private fun ruleShouldOnlyRunOnFileNode(node: ASTNode) = + wrapping is com.github.shyiko.ktlint.core.Rule.Modifier.RestrictToRoot && + node !is FileASTNode - private fun PsiElement.originalFilePath() = - (this.containingFile.viewProvider.virtualFile as? LightVirtualFile)?.originalFile?.name + private fun PsiElement.originalFilePath() = + (this.containingFile.viewProvider.virtualFile as? LightVirtualFile)?.originalFile?.name } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/KtLintMultiRule.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/KtLintMultiRule.kt index 8f53e9c4d..6f459e026 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/KtLintMultiRule.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/KtLintMultiRule.kt @@ -43,57 +43,57 @@ import org.jetbrains.kotlin.psi.KtFile */ class KtLintMultiRule(config: Config = Config.empty) : MultiRule() { - override val rules: List = listOf( - ChainWrapping(config), - CommentSpacing(config), - Filename(config), - FinalNewline(config), - ImportOrdering(config), - Indentation(config), - MaximumLineLength(config), - ModifierOrdering(config), - NoBlankLineBeforeRbrace(config), - NoConsecutiveBlankLines(config), - NoEmptyClassBody(config), - NoItParamInMultilineLambda(config), - NoLineBreakAfterElse(config), - NoLineBreakBeforeAssignment(config), - NoMultipleSpaces(config), - NoSemicolons(config), - NoTrailingSpaces(config), - NoUnitReturn(config), - NoUnusedImports(config), - NoWildcardImports(config), - PackageName(config), - ParameterListWrapping(config), - SpacingAroundColon(config), - SpacingAroundComma(config), - SpacingAroundCurly(config), - SpacingAroundKeyword(config), - SpacingAroundOperators(config), - SpacingAroundParens(config), - SpacingAroundRangeOperator(config), - StringTemplate(config) - ) + override val rules: List = listOf( + ChainWrapping(config), + CommentSpacing(config), + Filename(config), + FinalNewline(config), + ImportOrdering(config), + Indentation(config), + MaximumLineLength(config), + ModifierOrdering(config), + NoBlankLineBeforeRbrace(config), + NoConsecutiveBlankLines(config), + NoEmptyClassBody(config), + NoItParamInMultilineLambda(config), + NoLineBreakAfterElse(config), + NoLineBreakBeforeAssignment(config), + NoMultipleSpaces(config), + NoSemicolons(config), + NoTrailingSpaces(config), + NoUnitReturn(config), + NoUnusedImports(config), + NoWildcardImports(config), + PackageName(config), + ParameterListWrapping(config), + SpacingAroundColon(config), + SpacingAroundComma(config), + SpacingAroundCurly(config), + SpacingAroundKeyword(config), + SpacingAroundOperators(config), + SpacingAroundParens(config), + SpacingAroundRangeOperator(config), + StringTemplate(config) + ) - override fun visit(root: KtFile) { - val sortedRules = activeRules.sortedBy { it.lastModifier() } - sortedRules.forEach { it.visit(root) } - root.node.visitTokens { node -> - sortedRules.forEach { rule -> - (rule as? FormattingRule)?.runIfActive { this.apply(node) } - } - } - } + override fun visit(root: KtFile) { + val sortedRules = activeRules.sortedBy { it.lastModifier() } + sortedRules.forEach { it.visit(root) } + root.node.visitTokens { node -> + sortedRules.forEach { rule -> + (rule as? FormattingRule)?.runIfActive { this.apply(node) } + } + } + } - private fun Rule.lastModifier(): Boolean { - val rule = (this as? FormattingRule)?.wrapping ?: return false - return rule is com.github.shyiko.ktlint.core.Rule.Modifier.Last || - rule is com.github.shyiko.ktlint.core.Rule.Modifier.RestrictToRootLast - } + private fun Rule.lastModifier(): Boolean { + val rule = (this as? FormattingRule)?.wrapping ?: return false + return rule is com.github.shyiko.ktlint.core.Rule.Modifier.Last || + rule is com.github.shyiko.ktlint.core.Rule.Modifier.RestrictToRootLast + } - private fun ASTNode.visitTokens(currentNode: (node: ASTNode) -> Unit) { - currentNode(this) - getChildren(null).forEach { it.visitTokens(currentNode) } - } + private fun ASTNode.visitTokens(currentNode: (node: ASTNode) -> Unit) { + currentNode(this) + getChildren(null).forEach { it.visitTokens(currentNode) } + } } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/OffsetsToLineColumn.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/OffsetsToLineColumn.kt index 5f35d2871..1e555c5de 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/OffsetsToLineColumn.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/OffsetsToLineColumn.kt @@ -9,64 +9,64 @@ import java.util.ArrayList */ internal fun calculateLineColByOffset(text: String): (offset: Int) -> Pair { - var i = -1 - val e = text.length - val arr = ArrayList() - do { - arr.add(i + 1) - i = text.indexOf('\n', i + 1) - } while (i != -1) - arr.add(e + if (arr.last() == e) 1 else 0) - val segmentTree = SegmentTree(arr.toTypedArray()) - return { offset -> - val line = segmentTree.indexOf(offset) - if (line != -1) { - val col = offset - segmentTree.get(line).left - line + 1 to col + 1 - } else { - 1 to 1 - } - } + var i = -1 + val e = text.length + val arr = ArrayList() + do { + arr.add(i + 1) + i = text.indexOf('\n', i + 1) + } while (i != -1) + arr.add(e + if (arr.last() == e) 1 else 0) + val segmentTree = SegmentTree(arr.toTypedArray()) + return { offset -> + val line = segmentTree.indexOf(offset) + if (line != -1) { + val col = offset - segmentTree.get(line).left + line + 1 to col + 1 + } else { + 1 to 1 + } + } } internal fun calculateLineBreakOffset(fileContent: String): (offset: Int) -> Int { - val arr = ArrayList() - var i = 0 - do { - arr.add(i) - i = fileContent.indexOf("\r\n", i + 1) - } while (i != -1) - arr.add(fileContent.length) - return if (arr.size != 2) { - SegmentTree(arr.toTypedArray()).let { return { offset -> it.indexOf(offset) } } - } else { _ -> - 0 - } + val arr = ArrayList() + var i = 0 + do { + arr.add(i) + i = fileContent.indexOf("\r\n", i + 1) + } while (i != -1) + arr.add(fileContent.length) + return if (arr.size != 2) { + SegmentTree(arr.toTypedArray()).let { return { offset -> it.indexOf(offset) } } + } else { _ -> + 0 + } } internal class SegmentTree(sortedArray: Array) { - private val segments: List + private val segments: List - fun get(i: Int): Segment = segments[i] - fun indexOf(v: Int): Int = binarySearch(v, 0, this.segments.size - 1) + fun get(i: Int): Segment = segments[i] + fun indexOf(v: Int): Int = binarySearch(v, 0, this.segments.size - 1) - private fun binarySearch(v: Int, l: Int, r: Int): Int = when { - l > r -> -1 - else -> { - val i = l + (r - l) / 2 - val s = segments[i] - if (v < s.left) binarySearch(v, l, i - 1) - else (if (s.right < v) binarySearch(v, i + 1, r) else i) - } - } + private fun binarySearch(v: Int, l: Int, r: Int): Int = when { + l > r -> -1 + else -> { + val i = l + (r - l) / 2 + val s = segments[i] + if (v < s.left) binarySearch(v, l, i - 1) + else (if (s.right < v) binarySearch(v, i + 1, r) else i) + } + } - init { - require(sortedArray.size > 1) { "At least two data points are required" } - sortedArray.reduce { r, v -> require(r <= v) { "Data points are not sorted (ASC)" }; v } - segments = sortedArray.take(sortedArray.size - 1) - .mapIndexed { i: Int, v: Int -> Segment(v, sortedArray[i + 1] - 1) } - } + init { + require(sortedArray.size > 1) { "At least two data points are required" } + sortedArray.reduce { r, v -> require(r <= v) { "Data points are not sorted (ASC)" }; v } + segments = sortedArray.take(sortedArray.size - 1) + .mapIndexed { i: Int, v: Int -> Segment(v, sortedArray[i + 1] - 1) } + } } internal data class Segment(val left: Int, val right: Int) diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ChainWrapping.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ChainWrapping.kt index 0600642a2..51e22a32f 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ChainWrapping.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ChainWrapping.kt @@ -13,6 +13,6 @@ import io.gitlab.arturbosch.detekt.formatting.FormattingRule */ class ChainWrapping(config: Config) : FormattingRule(config) { - override val wrapping = ChainWrappingRule() - override val issue = issueFor("Checks if condition chaining is wrapped right") + override val wrapping = ChainWrappingRule() + override val issue = issueFor("Checks if condition chaining is wrapped right") } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/CommentSpacing.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/CommentSpacing.kt index 044b9a802..9052eb9bf 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/CommentSpacing.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/CommentSpacing.kt @@ -13,6 +13,6 @@ import io.gitlab.arturbosch.detekt.formatting.FormattingRule */ class CommentSpacing(config: Config) : FormattingRule(config) { - override val wrapping = CommentSpacingRule() - override val issue = issueFor("Checks if comments have the right spacing") + override val wrapping = CommentSpacingRule() + override val issue = issueFor("Checks if comments have the right spacing") } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/Filename.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/Filename.kt index a805ac238..ba323dc2f 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/Filename.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/Filename.kt @@ -12,6 +12,6 @@ import io.gitlab.arturbosch.detekt.formatting.FormattingRule */ class Filename(config: Config) : FormattingRule(config) { - override val wrapping = FilenameRule() - override val issue = issueFor("Checks if top level class matches the filename") + override val wrapping = FilenameRule() + override val issue = issueFor("Checks if top level class matches the filename") } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/FinalNewline.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/FinalNewline.kt index ecd918d67..efe775165 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/FinalNewline.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/FinalNewline.kt @@ -13,6 +13,6 @@ import io.gitlab.arturbosch.detekt.formatting.FormattingRule */ class FinalNewline(config: Config) : FormattingRule(config) { - override val wrapping = FinalNewlineRule() - override val issue = issueFor("Detects missing final newlines") + override val wrapping = FinalNewlineRule() + override val issue = issueFor("Detects missing final newlines") } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ImportOrdering.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ImportOrdering.kt index f7fdb155f..38918f690 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ImportOrdering.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ImportOrdering.kt @@ -13,6 +13,6 @@ import io.gitlab.arturbosch.detekt.formatting.FormattingRule */ class ImportOrdering(config: Config) : FormattingRule(config) { - override val wrapping = ImportOrderingRule() - override val issue = issueFor("Detects imports in non default order") + override val wrapping = ImportOrderingRule() + override val issue = issueFor("Detects imports in non default order") } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/Indentation.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/Indentation.kt index a9637b7c5..6d7b8b289 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/Indentation.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/Indentation.kt @@ -20,17 +20,17 @@ import io.gitlab.arturbosch.detekt.formatting.merge */ class Indentation(config: Config) : FormattingRule(config) { - override val wrapping = IndentationRule() - override val issue = issueFor("Reports mis-indented code") + override val wrapping = IndentationRule() + override val issue = issueFor("Reports mis-indented code") - private val indentSize = valueOrDefault(INDENT_SIZE, DEFAULT_INDENT) - private val continuationIndentSize = valueOrDefault(CONTINUATION_INDENT_SIZE, DEFAULT_CONTINUATION_INDENT) + private val indentSize = valueOrDefault(INDENT_SIZE, DEFAULT_INDENT) + private val continuationIndentSize = valueOrDefault(CONTINUATION_INDENT_SIZE, DEFAULT_CONTINUATION_INDENT) - override fun editorConfigUpdater(): ((oldEditorConfig: EditorConfig?) -> EditorConfig)? = { - EditorConfig.merge(it, - indentSize = indentSize, - continuationIndentSize = continuationIndentSize) - } + override fun editorConfigUpdater(): ((oldEditorConfig: EditorConfig?) -> EditorConfig)? = { + EditorConfig.merge(it, + indentSize = indentSize, + continuationIndentSize = continuationIndentSize) + } } private const val INDENT_SIZE = "indentSize" diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/MaximumLineLength.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/MaximumLineLength.kt index 4b4a837dd..3a40bae6d 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/MaximumLineLength.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/MaximumLineLength.kt @@ -18,18 +18,18 @@ import io.gitlab.arturbosch.detekt.formatting.merge */ class MaximumLineLength(config: Config) : FormattingRule(config) { - override val wrapping = MaxLineLengthRule() - override val issue = issueFor("Reports lines with exceeded length") + override val wrapping = MaxLineLengthRule() + override val issue = issueFor("Reports lines with exceeded length") - private val defaultMaxLineLength = - if (isAndroid) ANDROID_MAX_LINE_LENGTH - else DEFAULT_IDEA_LINE_LENGTH - private val maxLineLength: Int = valueOrDefault(MAX_LINE_LENGTH, defaultMaxLineLength) + private val defaultMaxLineLength = + if (isAndroid) ANDROID_MAX_LINE_LENGTH + else DEFAULT_IDEA_LINE_LENGTH + private val maxLineLength: Int = valueOrDefault(MAX_LINE_LENGTH, defaultMaxLineLength) - override fun editorConfigUpdater(): ((oldEditorConfig: EditorConfig?) -> EditorConfig)? = { - EditorConfig.merge(it, - maxLineLength = maxLineLength) - } + override fun editorConfigUpdater(): ((oldEditorConfig: EditorConfig?) -> EditorConfig)? = { + EditorConfig.merge(it, + maxLineLength = maxLineLength) + } } private const val MAX_LINE_LENGTH = "maxLineLength" diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ModifierOrdering.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ModifierOrdering.kt index 43c9fb960..cd9b76a8b 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ModifierOrdering.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ModifierOrdering.kt @@ -13,6 +13,6 @@ import io.gitlab.arturbosch.detekt.formatting.FormattingRule */ class ModifierOrdering(config: Config) : FormattingRule(config) { - override val wrapping = ModifierOrderRule() - override val issue = issueFor("Detects modifiers in non default order") + override val wrapping = ModifierOrderRule() + override val issue = issueFor("Detects modifiers in non default order") } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoBlankLineBeforeRbrace.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoBlankLineBeforeRbrace.kt index ccdfb1ee7..5b6552c44 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoBlankLineBeforeRbrace.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoBlankLineBeforeRbrace.kt @@ -13,6 +13,6 @@ import io.gitlab.arturbosch.detekt.formatting.FormattingRule */ class NoBlankLineBeforeRbrace(config: Config) : FormattingRule(config) { - override val wrapping = NoBlankLineBeforeRbraceRule() - override val issue = issueFor("Detects blank lines before rbraces") + override val wrapping = NoBlankLineBeforeRbraceRule() + override val issue = issueFor("Detects blank lines before rbraces") } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoConsecutiveBlankLines.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoConsecutiveBlankLines.kt index ac5b8c547..01cdc3741 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoConsecutiveBlankLines.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoConsecutiveBlankLines.kt @@ -13,6 +13,6 @@ import io.gitlab.arturbosch.detekt.formatting.FormattingRule */ class NoConsecutiveBlankLines(config: Config) : FormattingRule(config) { - override val wrapping = NoConsecutiveBlankLinesRule() - override val issue = issueFor("Reports consecutive blank lines") + override val wrapping = NoConsecutiveBlankLinesRule() + override val issue = issueFor("Reports consecutive blank lines") } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoEmptyClassBody.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoEmptyClassBody.kt index 9c705ac91..e8d91d252 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoEmptyClassBody.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoEmptyClassBody.kt @@ -13,6 +13,6 @@ import io.gitlab.arturbosch.detekt.formatting.FormattingRule */ class NoEmptyClassBody(config: Config) : FormattingRule(config) { - override val wrapping = NoEmptyClassBodyRule() - override val issue = issueFor("Reports empty class bodies") + override val wrapping = NoEmptyClassBodyRule() + override val issue = issueFor("Reports empty class bodies") } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoItParamInMultilineLambda.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoItParamInMultilineLambda.kt index 1ec522f46..43532094f 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoItParamInMultilineLambda.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoItParamInMultilineLambda.kt @@ -12,6 +12,6 @@ import io.gitlab.arturbosch.detekt.formatting.FormattingRule */ class NoItParamInMultilineLambda(config: Config) : FormattingRule(config) { - override val wrapping = NoItParamInMultilineLambdaRule() - override val issue = issueFor("Reports 'it' variable usages in multiline lambdas") + override val wrapping = NoItParamInMultilineLambdaRule() + override val issue = issueFor("Reports 'it' variable usages in multiline lambdas") } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoLineBreakAfterElse.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoLineBreakAfterElse.kt index 93f6e7120..0380fdb53 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoLineBreakAfterElse.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoLineBreakAfterElse.kt @@ -13,6 +13,6 @@ import io.gitlab.arturbosch.detekt.formatting.FormattingRule */ class NoLineBreakAfterElse(config: Config) : FormattingRule(config) { - override val wrapping = NoLineBreakAfterElseRule() - override val issue = issueFor("Reports line breaks after else") + override val wrapping = NoLineBreakAfterElseRule() + override val issue = issueFor("Reports line breaks after else") } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoLineBreakBeforeAssignment.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoLineBreakBeforeAssignment.kt index dbe0e01d1..9415b663c 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoLineBreakBeforeAssignment.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoLineBreakBeforeAssignment.kt @@ -13,6 +13,6 @@ import io.gitlab.arturbosch.detekt.formatting.FormattingRule */ class NoLineBreakBeforeAssignment(config: Config) : FormattingRule(config) { - override val wrapping = NoLineBreakBeforeAssignmentRule() - override val issue = issueFor("Reports line breaks after else") + override val wrapping = NoLineBreakBeforeAssignmentRule() + override val issue = issueFor("Reports line breaks after else") } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoMultipleSpaces.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoMultipleSpaces.kt index cf934f3ef..57e1f7f3b 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoMultipleSpaces.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoMultipleSpaces.kt @@ -13,6 +13,6 @@ import io.gitlab.arturbosch.detekt.formatting.FormattingRule */ class NoMultipleSpaces(config: Config) : FormattingRule(config) { - override val wrapping = NoMultipleSpacesRule() - override val issue = issueFor("Reports multiple space usages") + override val wrapping = NoMultipleSpacesRule() + override val issue = issueFor("Reports multiple space usages") } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoSemicolons.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoSemicolons.kt index 933be6e24..3d37d0fc8 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoSemicolons.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoSemicolons.kt @@ -13,6 +13,6 @@ import io.gitlab.arturbosch.detekt.formatting.FormattingRule */ class NoSemicolons(config: Config) : FormattingRule(config) { - override val wrapping = NoSemicolonsRule() - override val issue = issueFor("Detects semicolons") + override val wrapping = NoSemicolonsRule() + override val issue = issueFor("Detects semicolons") } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoTrailingSpaces.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoTrailingSpaces.kt index eeae01d17..27bc8814c 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoTrailingSpaces.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoTrailingSpaces.kt @@ -13,6 +13,6 @@ import io.gitlab.arturbosch.detekt.formatting.FormattingRule */ class NoTrailingSpaces(config: Config) : FormattingRule(config) { - override val wrapping = NoTrailingSpacesRule() - override val issue = issueFor("Detects trailing spaces") + override val wrapping = NoTrailingSpacesRule() + override val issue = issueFor("Detects trailing spaces") } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoUnitReturn.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoUnitReturn.kt index ba1e58a95..9a42399fe 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoUnitReturn.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoUnitReturn.kt @@ -13,6 +13,6 @@ import io.gitlab.arturbosch.detekt.formatting.FormattingRule */ class NoUnitReturn(config: Config) : FormattingRule(config) { - override val wrapping = NoUnitReturnRule() - override val issue = issueFor("Detects optional 'Unit' return types") + override val wrapping = NoUnitReturnRule() + override val issue = issueFor("Detects optional 'Unit' return types") } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoUnusedImports.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoUnusedImports.kt index 455f20a8e..94e325c89 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoUnusedImports.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoUnusedImports.kt @@ -13,6 +13,6 @@ import io.gitlab.arturbosch.detekt.formatting.FormattingRule */ class NoUnusedImports(config: Config) : FormattingRule(config) { - override val wrapping = NoUnusedImportsRule() - override val issue = issueFor("Detects unused imports") + override val wrapping = NoUnusedImportsRule() + override val issue = issueFor("Detects unused imports") } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoWildcardImports.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoWildcardImports.kt index 584c22218..c03416966 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoWildcardImports.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoWildcardImports.kt @@ -13,6 +13,6 @@ import io.gitlab.arturbosch.detekt.formatting.FormattingRule */ class NoWildcardImports(config: Config) : FormattingRule(config) { - override val wrapping = NoWildcardImportsRule() - override val issue = issueFor("Detects wildcast import usages") + override val wrapping = NoWildcardImportsRule() + override val issue = issueFor("Detects wildcast import usages") } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/PackageName.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/PackageName.kt index d5bcca15e..ff02a155a 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/PackageName.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/PackageName.kt @@ -13,6 +13,6 @@ import io.gitlab.arturbosch.detekt.formatting.FormattingRule */ class PackageName(config: Config) : FormattingRule(config) { - override val wrapping = PackageNameRule() - override val issue = issueFor("Checks package name is formatted correctly") + override val wrapping = PackageNameRule() + override val issue = issueFor("Checks package name is formatted correctly") } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ParameterListWrapping.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ParameterListWrapping.kt index 7eb9a5868..99ef83d97 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ParameterListWrapping.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ParameterListWrapping.kt @@ -18,15 +18,15 @@ import io.gitlab.arturbosch.detekt.formatting.merge */ class ParameterListWrapping(config: Config) : FormattingRule(config) { - override val wrapping = ParameterListWrappingRule() - override val issue = issueFor("Detects mis-aligned parameter lists") + override val wrapping = ParameterListWrappingRule() + override val issue = issueFor("Detects mis-aligned parameter lists") - private val indentSize = valueOrDefault(INDENT_SIZE, DEFAULT_INDENT) + private val indentSize = valueOrDefault(INDENT_SIZE, DEFAULT_INDENT) - override fun editorConfigUpdater(): ((oldEditorConfig: EditorConfig?) -> EditorConfig)? = { - EditorConfig.merge(it, - indentSize = indentSize) - } + override fun editorConfigUpdater(): ((oldEditorConfig: EditorConfig?) -> EditorConfig)? = { + EditorConfig.merge(it, + indentSize = indentSize) + } } private const val INDENT_SIZE = "indentSize" diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundColon.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundColon.kt index 7f2301a88..d58ead1c4 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundColon.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundColon.kt @@ -13,6 +13,6 @@ import io.gitlab.arturbosch.detekt.formatting.FormattingRule */ class SpacingAroundColon(config: Config) : FormattingRule(config) { - override val wrapping = SpacingAroundColonRule() - override val issue = issueFor("Reports spaces around colons") + override val wrapping = SpacingAroundColonRule() + override val issue = issueFor("Reports spaces around colons") } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundComma.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundComma.kt index 34ba7488a..c6d1a4f2a 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundComma.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundComma.kt @@ -13,6 +13,6 @@ import io.gitlab.arturbosch.detekt.formatting.FormattingRule */ class SpacingAroundComma(config: Config) : FormattingRule(config) { - override val wrapping = SpacingAroundCommaRule() - override val issue = issueFor("Reports spaces around commas") + override val wrapping = SpacingAroundCommaRule() + override val issue = issueFor("Reports spaces around commas") } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundCurly.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundCurly.kt index 6ebfb56bc..f3e7758f0 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundCurly.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundCurly.kt @@ -13,6 +13,6 @@ import io.gitlab.arturbosch.detekt.formatting.FormattingRule */ class SpacingAroundCurly(config: Config) : FormattingRule(config) { - override val wrapping = SpacingAroundCurlyRule() - override val issue = issueFor("Reports spaces around curly braces") + override val wrapping = SpacingAroundCurlyRule() + override val issue = issueFor("Reports spaces around curly braces") } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundKeyword.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundKeyword.kt index 1efd93350..240fffc97 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundKeyword.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundKeyword.kt @@ -13,6 +13,6 @@ import io.gitlab.arturbosch.detekt.formatting.FormattingRule */ class SpacingAroundKeyword(config: Config) : FormattingRule(config) { - override val wrapping = SpacingAroundKeywordRule() - override val issue = issueFor("Reports spaces around keywords") + override val wrapping = SpacingAroundKeywordRule() + override val issue = issueFor("Reports spaces around keywords") } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundOperators.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundOperators.kt index e8b135310..459ec410f 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundOperators.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundOperators.kt @@ -13,6 +13,6 @@ import io.gitlab.arturbosch.detekt.formatting.FormattingRule */ class SpacingAroundOperators(config: Config) : FormattingRule(config) { - override val wrapping = SpacingAroundOperatorsRule() - override val issue = issueFor("Reports spaces around operators") + override val wrapping = SpacingAroundOperatorsRule() + override val issue = issueFor("Reports spaces around operators") } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundParens.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundParens.kt index d9d876488..72c10befb 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundParens.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundParens.kt @@ -13,6 +13,6 @@ import io.gitlab.arturbosch.detekt.formatting.FormattingRule */ class SpacingAroundParens(config: Config) : FormattingRule(config) { - override val wrapping = SpacingAroundParensRule() - override val issue = issueFor("Reports spaces around parentheses") + override val wrapping = SpacingAroundParensRule() + override val issue = issueFor("Reports spaces around parentheses") } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundRangeOperator.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundRangeOperator.kt index 2372450d0..f3f69eef2 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundRangeOperator.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundRangeOperator.kt @@ -13,6 +13,6 @@ import io.gitlab.arturbosch.detekt.formatting.FormattingRule */ class SpacingAroundRangeOperator(config: Config) : FormattingRule(config) { - override val wrapping = SpacingAroundRangeOperatorRule() - override val issue = issueFor("Reports spaces around range operator") + override val wrapping = SpacingAroundRangeOperatorRule() + override val issue = issueFor("Reports spaces around range operator") } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/StringTemplate.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/StringTemplate.kt index 3b3796147..a20417015 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/StringTemplate.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/StringTemplate.kt @@ -13,6 +13,6 @@ import io.gitlab.arturbosch.detekt.formatting.FormattingRule */ class StringTemplate(config: Config) : FormattingRule(config) { - override val wrapping = StringTemplateRule() - override val issue = issueFor("Detects simplifications in template strings") + override val wrapping = StringTemplateRule() + override val issue = issueFor("Detects simplifications in template strings") } diff --git a/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/AutoCorrectLevelSpec.kt b/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/AutoCorrectLevelSpec.kt index 831c40836..c6d542850 100644 --- a/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/AutoCorrectLevelSpec.kt +++ b/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/AutoCorrectLevelSpec.kt @@ -7,90 +7,90 @@ import io.gitlab.arturbosch.detekt.core.ProcessingSettings import io.gitlab.arturbosch.detekt.test.loadRuleSet import io.gitlab.arturbosch.detekt.test.resource import io.gitlab.arturbosch.detekt.test.yamlConfig +import java.nio.file.Paths import org.assertj.core.api.Assertions.assertThat import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.spek.api.Spek import org.jetbrains.spek.api.dsl.describe import org.jetbrains.spek.api.dsl.given import org.jetbrains.spek.api.dsl.it -import java.nio.file.Paths /** * @author Artur Bosch */ class AutoCorrectLevelSpec : Spek({ - describe("test different autoCorrect levels in configuration") { + describe("test different autoCorrect levels in configuration") { - given("autoCorrect: true on all levels") { + given("autoCorrect: true on all levels") { - val config = yamlConfig("/autocorrect/autocorrect-all-true.yml") + val config = yamlConfig("/autocorrect/autocorrect-all-true.yml") - it("should reformat the test file") { - val (file, findings) = runAnalysis(config) - assertThat(wasLinted(findings)).isTrue() - assertThat(wasFormatted(file)).isTrue() - } - } + it("should reformat the test file") { + val (file, findings) = runAnalysis(config) + assertThat(wasLinted(findings)).isTrue() + assertThat(wasFormatted(file)).isTrue() + } + } - given("autoCorrect: false on top level") { + given("autoCorrect: false on top level") { - val config = yamlConfig("/autocorrect/autocorrect-toplevel-false.yml") + val config = yamlConfig("/autocorrect/autocorrect-toplevel-false.yml") - it("should format the test file but not print to disc") { - val project = Paths.get(resource("before.kt")) - val detekt = DetektFacade.create(ProcessingSettings(project, config)) - val file = loadFile("before.kt") - val expected = file.text - val findings = detekt.run(project, listOf(file)) - .findings.flatMap { it.value } + it("should format the test file but not print to disc") { + val project = Paths.get(resource("before.kt")) + val detekt = DetektFacade.create(ProcessingSettings(project, config)) + val file = loadFile("before.kt") + val expected = file.text + val findings = detekt.run(project, listOf(file)) + .findings.flatMap { it.value } - assertThat(wasLinted(findings)).isTrue() - assertThat(wasFormatted(file)).isTrue() - assertThat(loadFileContent("before.kt")).isEqualTo(expected) - } - } + assertThat(wasLinted(findings)).isTrue() + assertThat(wasFormatted(file)).isTrue() + assertThat(loadFileContent("before.kt")).isEqualTo(expected) + } + } - given("autoCorrect: false on ruleSet level") { + given("autoCorrect: false on ruleSet level") { - val config = yamlConfig("/autocorrect/autocorrect-ruleset-false.yml") + val config = yamlConfig("/autocorrect/autocorrect-ruleset-false.yml") - it("should not reformat the test file") { - val (file, findings) = runAnalysis(config) - assertThat(wasLinted(findings)).isTrue() - assertThat(wasFormatted(file)).isFalse() - } - } + it("should not reformat the test file") { + val (file, findings) = runAnalysis(config) + assertThat(wasLinted(findings)).isTrue() + assertThat(wasFormatted(file)).isFalse() + } + } - given("autoCorrect: false on rule level") { + given("autoCorrect: false on rule level") { - val config = yamlConfig("/autocorrect/autocorrect-rule-false.yml") + val config = yamlConfig("/autocorrect/autocorrect-rule-false.yml") - it("should not reformat the test file") { - val (file, findings) = runAnalysis(config) - assertThat(wasLinted(findings)).isTrue() - assertThat(wasFormatted(file)).isFalse() - } - } + it("should not reformat the test file") { + val (file, findings) = runAnalysis(config) + assertThat(wasLinted(findings)).isTrue() + assertThat(wasFormatted(file)).isFalse() + } + } - given("autoCorrect: true but rule active false") { + given("autoCorrect: true but rule active false") { - val config = yamlConfig("/autocorrect/autocorrect-true-rule-active-false.yml") + val config = yamlConfig("/autocorrect/autocorrect-true-rule-active-false.yml") - it("should not reformat the test file") { - val (file, findings) = runAnalysis(config) - assertThat(wasLinted(findings)).isFalse() - assertThat(wasFormatted(file)).isFalse() - } - } - } + it("should not reformat the test file") { + val (file, findings) = runAnalysis(config) + assertThat(wasLinted(findings)).isFalse() + assertThat(wasFormatted(file)).isFalse() + } + } + } }) private fun runAnalysis(config: Config): Pair> { - val testFile = loadFile("before.kt") - val ruleSet = loadRuleSet(config) - val findings = ruleSet.accept(testFile) - return testFile to findings + val testFile = loadFile("before.kt") + val ruleSet = loadRuleSet(config) + val findings = ruleSet.accept(testFile) + return testFile to findings } private fun wasLinted(findings: List): Boolean = findings.isNotEmpty() diff --git a/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/KtLintIntegrationSpec.kt b/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/KtLintIntegrationSpec.kt index 3c3a8a565..c5a40b8e6 100644 --- a/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/KtLintIntegrationSpec.kt +++ b/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/KtLintIntegrationSpec.kt @@ -12,18 +12,18 @@ import org.jetbrains.spek.api.dsl.it */ class KtLintIntegrationSpec : Spek({ - describe("tests integration of formatting") { + describe("tests integration of formatting") { - it("should work like KtLint") { - val fileBefore = loadFile("before.kt") - val expected = loadFileContent("after.kt") + it("should work like KtLint") { + val fileBefore = loadFile("before.kt") + val expected = loadFileContent("after.kt") - val ruleSet = loadRuleSet( - TestConfig(mapOf("autoCorrect" to "true"))) - val findings = ruleSet.accept(fileBefore) + val ruleSet = loadRuleSet( + TestConfig(mapOf("autoCorrect" to "true"))) + val findings = ruleSet.accept(fileBefore) - assertThat(findings).isNotEmpty - assertThat(fileBefore.text).isEqualTo(expected) - } - } + assertThat(findings).isNotEmpty + assertThat(fileBefore.text).isEqualTo(expected) + } + } }) diff --git a/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/TestFiles.kt b/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/TestFiles.kt index 07ab45050..10c2412b7 100644 --- a/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/TestFiles.kt +++ b/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/TestFiles.kt @@ -2,9 +2,9 @@ package io.gitlab.arturbosch.detekt.formatting import io.gitlab.arturbosch.detekt.test.compileForTest import io.gitlab.arturbosch.detekt.test.resource -import org.jetbrains.kotlin.com.intellij.openapi.util.text.StringUtilRt import java.io.File import java.nio.file.Paths +import org.jetbrains.kotlin.com.intellij.openapi.util.text.StringUtilRt /** * @author Artur Bosch @@ -13,7 +13,7 @@ import java.nio.file.Paths fun loadFile(resourceName: String) = compileForTest(Paths.get(resource(resourceName))) fun loadFileContent(resourceName: String) = - StringUtilRt.convertLineSeparators(File(resource(resourceName)).readText()) + StringUtilRt.convertLineSeparators(File(resource(resourceName)).readText()) val contentAfterChainWrapping = """ fun main() { diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/DetektProgressListener.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/DetektProgressListener.kt index 405a0381a..ef272387b 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/DetektProgressListener.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/DetektProgressListener.kt @@ -8,12 +8,12 @@ import org.jetbrains.kotlin.psi.KtFile */ class DetektProgressListener : FileProcessListener { - override fun onStart(files: List) { - val name = if (files.size == 1) "file" else "files" - print("Analyzing ${files.size} kotlin $name: ") - } + override fun onStart(files: List) { + val name = if (files.size == 1) "file" else "files" + print("Analyzing ${files.size} kotlin $name: ") + } - override fun onProcess(file: KtFile) { - print(".") - } + override fun onProcess(file: KtFile) { + print(".") + } } diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/GeneratorArgs.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/GeneratorArgs.kt index ccf8f48dc..0d31937e5 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/GeneratorArgs.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/GeneratorArgs.kt @@ -12,33 +12,33 @@ import java.nio.file.Path */ class GeneratorArgs : Args { - @Parameter(names = ["--input", "-i"], - required = true, - description = "Input paths to analyze.") - private var input: String? = null + @Parameter(names = ["--input", "-i"], + required = true, + description = "Input paths to analyze.") + private var input: String? = null - @Parameter(names = ["--documentation", "-d"], - required = true, - converter = ExistingPathConverter::class, description = "Output path for generated documentation.") - private var documentation: Path? = null + @Parameter(names = ["--documentation", "-d"], + required = true, + converter = ExistingPathConverter::class, description = "Output path for generated documentation.") + private var documentation: Path? = null - @Parameter(names = ["--config", "-c"], - required = true, - converter = ExistingPathConverter::class, description = "Output path for generated detekt config.") - private var config: Path? = null + @Parameter(names = ["--config", "-c"], + required = true, + converter = ExistingPathConverter::class, description = "Output path for generated detekt config.") + private var config: Path? = null - @Parameter(names = ["--help", "-h"], - help = true, description = "Shows the usage.") - override var help: Boolean = false + @Parameter(names = ["--help", "-h"], + help = true, description = "Shows the usage.") + override var help: Boolean = false - val inputPath: List by lazy { - MultipleExistingPathConverter().convert(input - ?: throw IllegalStateException("Input parameter was not initialized by jcommander!")) - } - val documentationPath: Path - get() = documentation - ?: throw IllegalStateException("Documentation output path was not initialized by jcommander!") + val inputPath: List by lazy { + MultipleExistingPathConverter().convert(input + ?: throw IllegalStateException("Input parameter was not initialized by jcommander!")) + } + val documentationPath: Path + get() = documentation + ?: throw IllegalStateException("Documentation output path was not initialized by jcommander!") - val configPath: Path - get() = config ?: throw IllegalStateException("Configuration output path was not initialized by jcommander!") + val configPath: Path + get() = config ?: throw IllegalStateException("Configuration output path was not initialized by jcommander!") } diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/Main.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/Main.kt index e48c1fa19..ca2fbd64b 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/Main.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/Main.kt @@ -5,39 +5,39 @@ package io.gitlab.arturbosch.detekt.generator import io.gitlab.arturbosch.detekt.cli.failWithErrorMessages import io.gitlab.arturbosch.detekt.cli.parseArguments import io.gitlab.arturbosch.detekt.core.isFile -import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty import java.nio.file.Files +import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty /** * @author Marvin Ramin * @author Artur Bosch */ fun main(args: Array) { - val arguments = parseArgumentsCheckingReportDirectory(args) - val executable = Runner(arguments) - executable.execute() + val arguments = parseArgumentsCheckingReportDirectory(args) + val executable = Runner(arguments) + executable.execute() } private fun parseArgumentsCheckingReportDirectory(args: Array): GeneratorArgs { - val (arguments, jcommander) = parseArguments(args) - val messages = validateCli(arguments) - messages.ifNotEmpty { - jcommander.failWithErrorMessages(messages) - } - return arguments + val (arguments, jcommander) = parseArguments(args) + val messages = validateCli(arguments) + messages.ifNotEmpty { + jcommander.failWithErrorMessages(messages) + } + return arguments } private fun validateCli(arguments: GeneratorArgs): List { - val violations = ArrayList() - with(arguments) { - if (Files.exists(documentationPath) && documentationPath.isFile()) { - violations += "Documentation path must be a directory." - } + val violations = ArrayList() + with(arguments) { + if (Files.exists(documentationPath) && documentationPath.isFile()) { + violations += "Documentation path must be a directory." + } - if (Files.exists(configPath) && configPath.isFile()) { - violations += "Config path must be a directory." - } - // input paths are validated by MultipleExistingPathConverter - } - return violations + if (Files.exists(configPath) && configPath.isFile()) { + violations += "Config path must be a directory." + } + // input paths are validated by MultipleExistingPathConverter + } + return violations } diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/Runner.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/Runner.kt index 20cfa5dde..97631a8bd 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/Runner.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/Runner.kt @@ -10,25 +10,25 @@ import kotlin.system.measureTimeMillis * @author Artur Bosch */ class Runner(private val arguments: GeneratorArgs) { - private val listeners = listOf(DetektProgressListener()) - private val collector = DetektCollector() - private val printer = DetektPrinter(arguments) + private val listeners = listOf(DetektProgressListener()) + private val collector = DetektCollector() + private val printer = DetektPrinter(arguments) - fun execute() { - val time = measureTimeMillis { - val compiler = KtTreeCompiler() - val ktFiles = arguments.inputPath - .flatMap { compiler.compile(it) } - listeners.forEach { it.onStart(ktFiles) } + fun execute() { + val time = measureTimeMillis { + val compiler = KtTreeCompiler() + val ktFiles = arguments.inputPath + .flatMap { compiler.compile(it) } + listeners.forEach { it.onStart(ktFiles) } - ktFiles.forEach { file -> - listeners.forEach { it.onProcess(file) } - collector.visit(file) - } + ktFiles.forEach { file -> + listeners.forEach { it.onProcess(file) } + collector.visit(file) + } - printer.print(collector.items) - } + printer.print(collector.items) + } - println("\nGenerated all detekt documentation in $time ms.") - } + println("\nGenerated all detekt documentation in $time ms.") + } } diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/Collector.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/Collector.kt index 4fa850ad0..e36063b56 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/Collector.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/Collector.kt @@ -6,7 +6,7 @@ import org.jetbrains.kotlin.psi.KtFile * @author Marvin Ramin */ interface Collector { - val items: List + val items: List - fun visit(file: KtFile) + fun visit(file: KtFile) } diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/Configuration.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/Configuration.kt index bbc308185..43ee56ff7 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/Configuration.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/Configuration.kt @@ -4,7 +4,7 @@ package io.gitlab.arturbosch.detekt.generator.collection * @author Marvin Ramin */ data class Configuration( - val name: String, - val description: String, - val defaultValue: String + val name: String, + val description: String, + val defaultValue: String ) diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/DetektCollector.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/DetektCollector.kt index 2f14427fc..a86895ab3 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/DetektCollector.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/DetektCollector.kt @@ -9,51 +9,51 @@ import org.jetbrains.kotlin.psi.KtFile */ class DetektCollector : Collector { - private val ruleSetProviderCollector = RuleSetProviderCollector() - private val ruleCollector = RuleCollector() - private val multiRuleCollector = MultiRuleCollector() + private val ruleSetProviderCollector = RuleSetProviderCollector() + private val ruleCollector = RuleCollector() + private val multiRuleCollector = MultiRuleCollector() - private val collectors = listOf( - ruleSetProviderCollector, - multiRuleCollector, - ruleCollector - ) - override val items: List - get() = buildRuleSetPages() + private val collectors = listOf( + ruleSetProviderCollector, + multiRuleCollector, + ruleCollector + ) + override val items: List + get() = buildRuleSetPages() - private fun buildRuleSetPages(): List { - val rules = ruleCollector.items - val multiRules = multiRuleCollector.items.associateBy({ it.name }, { it.rules }) - val ruleSets = ruleSetProviderCollector.items + private fun buildRuleSetPages(): List { + val rules = ruleCollector.items + val multiRules = multiRuleCollector.items.associateBy({ it.name }, { it.rules }) + val ruleSets = ruleSetProviderCollector.items - return ruleSets.map { ruleSet -> - val consolidatedRules = ruleSet.rules - .flatMap { ruleName -> multiRules[ruleName] ?: listOf(ruleName) } - .map { rules.findRuleByName(it) } - .sortedBy { rule -> rule.name } + return ruleSets.map { ruleSet -> + val consolidatedRules = ruleSet.rules + .flatMap { ruleName -> multiRules[ruleName] ?: listOf(ruleName) } + .map { rules.findRuleByName(it) } + .sortedBy { rule -> rule.name } - consolidatedRules.resolveParentRule(rules) - RuleSetPage(ruleSet, consolidatedRules) - } - } + consolidatedRules.resolveParentRule(rules) + RuleSetPage(ruleSet, consolidatedRules) + } + } - private fun List.findRuleByName(ruleName: String): Rule { - return find { it.name == ruleName } - ?: throw InvalidDocumentationException("Rule $ruleName was specified in a provider but it was not defined.") - } + private fun List.findRuleByName(ruleName: String): Rule { + return find { it.name == ruleName } + ?: throw InvalidDocumentationException("Rule $ruleName was specified in a provider but it was not defined.") + } - private fun List.resolveParentRule(rules: List) { - this.filter { it.debt.isEmpty() && it.severity.isEmpty() } - .forEach { - val parentRule = rules.findRuleByName(it.parent) - it.debt = parentRule.debt - it.severity = parentRule.severity - } - } + private fun List.resolveParentRule(rules: List) { + this.filter { it.debt.isEmpty() && it.severity.isEmpty() } + .forEach { + val parentRule = rules.findRuleByName(it.parent) + it.debt = parentRule.debt + it.severity = parentRule.severity + } + } - override fun visit(file: KtFile) { - collectors.forEach { - it.visit(file) - } - } + override fun visit(file: KtFile) { + collectors.forEach { + it.visit(file) + } + } } diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/KDocTags.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/KDocTags.kt index 08183b1a2..406468076 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/KDocTags.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/KDocTags.kt @@ -11,44 +11,44 @@ import org.jetbrains.kotlin.psi.KtClassOrObject */ fun KtClassOrObject.parseConfigurationTags() = - kDocSection()?.findTagsByName(TAG_CONFIGURATION) - ?.filter { it.isValidConfigurationTag() } - ?.map { it.parseConfigTag() } - ?: emptyList() + kDocSection()?.findTagsByName(TAG_CONFIGURATION) + ?.filter { it.isValidConfigurationTag() } + ?.map { it.parseConfigTag() } + ?: emptyList() fun KtClassOrObject.kDocSection(): KDocSection? = docComment?.getDefaultSection() fun KDocTag.parseConfigTag(): Configuration { - val content: String = getContent() - val delimiterIndex = content.indexOf('-') - val name = content.substring(0, delimiterIndex - 1) - val defaultValue = configurationDefaultValueRegex.find(content) - ?.groupValues - ?.get(1) - ?.trim() ?: "" - val description = content.substring(delimiterIndex + 1) - .replace(configurationDefaultValueRegex, "") - .trim() - return Configuration(name, description, defaultValue) + val content: String = getContent() + val delimiterIndex = content.indexOf('-') + val name = content.substring(0, delimiterIndex - 1) + val defaultValue = configurationDefaultValueRegex.find(content) + ?.groupValues + ?.get(1) + ?.trim() ?: "" + val description = content.substring(delimiterIndex + 1) + .replace(configurationDefaultValueRegex, "") + .trim() + return Configuration(name, description, defaultValue) } private const val EXPECTED_CONFIGURATION_FORMAT = - "Expected format: @configuration {paramName} - {paramDescription} (default: {defaultValue})." + "Expected format: @configuration {paramName} - {paramDescription} (default: {defaultValue})." fun KDocTag.isValidConfigurationTag(entity: String = "Rule"): Boolean { - val content: String = getContent() - if (!content.contains(" - ")) { - throw InvalidDocumentationException( - "[${containingFile.name}] $entity '$content' doesn't seem to contain a description.\n" + - EXPECTED_CONFIGURATION_FORMAT) - } - if (!content.contains(configurationDefaultValueRegex)) { - val parameterName = content.substringBefore(" - ") - throw InvalidDocumentationException( - "[${containingFile.name}] $entity '$parameterName' doesn't seem to contain a default value.\n" + - EXPECTED_CONFIGURATION_FORMAT) - } - return true + val content: String = getContent() + if (!content.contains(" - ")) { + throw InvalidDocumentationException( + "[${containingFile.name}] $entity '$content' doesn't seem to contain a description.\n" + + EXPECTED_CONFIGURATION_FORMAT) + } + if (!content.contains(configurationDefaultValueRegex)) { + val parameterName = content.substringBefore(" - ") + throw InvalidDocumentationException( + "[${containingFile.name}] $entity '$parameterName' doesn't seem to contain a default value.\n" + + EXPECTED_CONFIGURATION_FORMAT) + } + return true } val configurationDefaultValueRegex = "\\(default: (.+)\\)".toRegex(RegexOption.DOT_MATCHES_ALL) diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/MultiRuleCollector.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/MultiRuleCollector.kt index 8de5cd005..ed873e2f3 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/MultiRuleCollector.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/MultiRuleCollector.kt @@ -17,108 +17,108 @@ import org.jetbrains.kotlin.psi.psiUtil.referenceExpression * @author Marvin Ramin */ data class MultiRule( - val name: String, - val rules: List = listOf() + val name: String, + val rules: List = listOf() ) private val multiRule = io.gitlab.arturbosch.detekt.api.MultiRule::class.simpleName ?: "" class MultiRuleCollector : Collector { - override val items = mutableListOf() + override val items = mutableListOf() - override fun visit(file: KtFile) { - val visitor = MultiRuleVisitor() - file.accept(visitor) + override fun visit(file: KtFile) { + val visitor = MultiRuleVisitor() + file.accept(visitor) - if (visitor.containsMultiRule) { - items.add(visitor.getMultiRule()) - } - } + if (visitor.containsMultiRule) { + items.add(visitor.getMultiRule()) + } + } } class MultiRuleVisitor : DetektVisitor() { - val containsMultiRule - get() = classesMap.any { it.value } - private var classesMap = mutableMapOf() - private var name = "" - private val rulesVisitor = RuleListVisitor() - private val properties: MutableMap = mutableMapOf() + val containsMultiRule + get() = classesMap.any { it.value } + private var classesMap = mutableMapOf() + private var name = "" + private val rulesVisitor = RuleListVisitor() + private val properties: MutableMap = mutableMapOf() - fun getMultiRule(): MultiRule { - val rules = mutableListOf() + fun getMultiRule(): MultiRule { + val rules = mutableListOf() - val ruleProperties = rulesVisitor.ruleProperties - .mapNotNull { properties[it] } - rules.addAll(ruleProperties) - rules.addAll(rulesVisitor.ruleNames) + val ruleProperties = rulesVisitor.ruleProperties + .mapNotNull { properties[it] } + rules.addAll(ruleProperties) + rules.addAll(rulesVisitor.ruleNames) - if (name.isEmpty()) { - throw InvalidDocumentationException("MultiRule without name found.") - } - if (rules.isEmpty()) { - throw InvalidDocumentationException("MultiRule $name contains no rules.") - } - return MultiRule(name, rules) - } + if (name.isEmpty()) { + throw InvalidDocumentationException("MultiRule without name found.") + } + if (rules.isEmpty()) { + throw InvalidDocumentationException("MultiRule $name contains no rules.") + } + return MultiRule(name, rules) + } - override fun visitSuperTypeList(list: KtSuperTypeList) { - val isMultiRule = list.entries - ?.mapNotNull { it.typeAsUserType?.referencedName } - ?.any { it == multiRule } ?: false + override fun visitSuperTypeList(list: KtSuperTypeList) { + val isMultiRule = list.entries + ?.mapNotNull { it.typeAsUserType?.referencedName } + ?.any { it == multiRule } ?: false - val containingClass = list.containingClass() - val className = containingClass?.name - if (containingClass != null && className != null && !classesMap.containsKey(className)) { - classesMap[className] = isMultiRule - } - super.visitSuperTypeList(list) - } + val containingClass = list.containingClass() + val className = containingClass?.name + if (containingClass != null && className != null && !classesMap.containsKey(className)) { + classesMap[className] = isMultiRule + } + super.visitSuperTypeList(list) + } - override fun visitClassOrObject(classOrObject: KtClassOrObject) { - super.visitClassOrObject(classOrObject) - if (classesMap[classOrObject.name] != true) { - return - } + override fun visitClassOrObject(classOrObject: KtClassOrObject) { + super.visitClassOrObject(classOrObject) + if (classesMap[classOrObject.name] != true) { + return + } - name = classOrObject.name?.trim() ?: "" - } + name = classOrObject.name?.trim() ?: "" + } - override fun visitProperty(property: KtProperty) { - super.visitProperty(property) - if (classesMap[property.containingClass()?.name] != true) { - return - } + override fun visitProperty(property: KtProperty) { + super.visitProperty(property) + if (classesMap[property.containingClass()?.name] != true) { + return + } - if (property.isOverride() && property.name != null && property.name == "rules") { - property.accept(rulesVisitor) - } else { - val name = property.name - val initializer = property.initializer?.referenceExpression()?.text - if (name != null && initializer != null) { - properties[name] = initializer - } - } - } + if (property.isOverride() && property.name != null && property.name == "rules") { + property.accept(rulesVisitor) + } else { + val name = property.name + val initializer = property.initializer?.referenceExpression()?.text + if (name != null && initializer != null) { + properties[name] = initializer + } + } + } } class RuleListVisitor : DetektVisitor() { - var ruleNames: MutableSet = mutableSetOf() - private set - var ruleProperties: MutableSet = mutableSetOf() - private set + var ruleNames: MutableSet = mutableSetOf() + private set + var ruleProperties: MutableSet = mutableSetOf() + private set - override fun visitValueArgumentList(list: KtValueArgumentList) { - super.visitValueArgumentList(list) - val argumentExpressions = list.arguments.map { it.getArgumentExpression() } + override fun visitValueArgumentList(list: KtValueArgumentList) { + super.visitValueArgumentList(list) + val argumentExpressions = list.arguments.map { it.getArgumentExpression() } - // Call Expression = Constructor of rule - ruleNames.addAll(argumentExpressions - .filter { it is KtCallExpression } - .map { (it as? KtCallExpression)?.calleeExpression?.text ?: "" }) + // Call Expression = Constructor of rule + ruleNames.addAll(argumentExpressions + .filter { it is KtCallExpression } + .map { (it as? KtCallExpression)?.calleeExpression?.text ?: "" }) - // Reference Expression = variable we need to search for - ruleProperties.addAll(argumentExpressions - .filter { it is KtReferenceExpression } - .map { it?.text ?: "" }) - } + // Reference Expression = variable we need to search for + ruleProperties.addAll(argumentExpressions + .filter { it is KtReferenceExpression } + .map { it?.text ?: "" }) + } } diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/Rule.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/Rule.kt index 5cf689acd..14f4c6989 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/Rule.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/Rule.kt @@ -4,15 +4,15 @@ package io.gitlab.arturbosch.detekt.generator.collection * @author Marvin Ramin */ data class Rule( - val name: String, - val description: String, - val nonCompliantCodeExample: String, - val compliantCodeExample: String, - val active: Boolean, - var severity: String, - var debt: String, - var aliases: String?, - val parent: String, - val configuration: List = listOf(), - val autoCorrect: Boolean = false + val name: String, + val description: String, + val nonCompliantCodeExample: String, + val compliantCodeExample: String, + val active: Boolean, + var severity: String, + var debt: String, + var aliases: String?, + val parent: String, + val configuration: List = listOf(), + val autoCorrect: Boolean = false ) diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/RuleCollector.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/RuleCollector.kt index 38aadd928..c52602960 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/RuleCollector.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/RuleCollector.kt @@ -6,14 +6,14 @@ import org.jetbrains.kotlin.psi.KtFile * @author Marvin Ramin */ class RuleCollector : Collector { - override val items = mutableListOf() + override val items = mutableListOf() - override fun visit(file: KtFile) { - val visitor = RuleVisitor() - file.accept(visitor) + override fun visit(file: KtFile) { + val visitor = RuleVisitor() + file.accept(visitor) - if (visitor.containsRule) { - items.add(visitor.getRule()) - } - } + if (visitor.containsRule) { + items.add(visitor.getRule()) + } + } } diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/RuleSetProviderCollector.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/RuleSetProviderCollector.kt index 3c9be7b9b..a6bb47a53 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/RuleSetProviderCollector.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/RuleSetProviderCollector.kt @@ -17,88 +17,88 @@ import org.jetbrains.kotlin.psi.psiUtil.referenceExpression * @author Artur Bosch */ data class RuleSetProvider( - val name: String, - val description: String, - val active: Boolean, - val rules: List = listOf(), - val configuration: List = listOf() + val name: String, + val description: String, + val active: Boolean, + val rules: List = listOf(), + val configuration: List = listOf() ) class RuleSetProviderCollector : Collector { - override val items = mutableListOf() + override val items = mutableListOf() - override fun visit(file: KtFile) { - val visitor = RuleSetProviderVisitor() - file.accept(visitor) + override fun visit(file: KtFile) { + val visitor = RuleSetProviderVisitor() + file.accept(visitor) - if (visitor.containsRuleSetProvider) { - items.add(visitor.getRuleSetProvider()) - } - } + if (visitor.containsRuleSetProvider) { + items.add(visitor.getRuleSetProvider()) + } + } } private const val TAG_ACTIVE = "active" private const val PROPERTY_RULE_SET_ID = "ruleSetId" class RuleSetProviderVisitor : DetektVisitor() { - var containsRuleSetProvider = false - private var name: String = "" - private var description: String = "" - private var active: Boolean = false - private val ruleNames: MutableList = mutableListOf() - private val configuration = mutableListOf() + var containsRuleSetProvider = false + private var name: String = "" + private var description: String = "" + private var active: Boolean = false + private val ruleNames: MutableList = mutableListOf() + private val configuration = mutableListOf() - fun getRuleSetProvider(): RuleSetProvider { - if (name.isEmpty()) { - throw InvalidDocumentationException("RuleSetProvider without name found.") - } + fun getRuleSetProvider(): RuleSetProvider { + if (name.isEmpty()) { + throw InvalidDocumentationException("RuleSetProvider without name found.") + } - if (description.isEmpty()) { - throw InvalidDocumentationException("Missing description for RuleSet $name.") - } + if (description.isEmpty()) { + throw InvalidDocumentationException("Missing description for RuleSet $name.") + } - return RuleSetProvider(name, description, active, ruleNames, configuration) - } + return RuleSetProvider(name, description, active, ruleNames, configuration) + } - override fun visitSuperTypeList(list: KtSuperTypeList) { - containsRuleSetProvider = list.entries - ?.map { it.typeAsUserType?.referencedName } - ?.contains(RuleSetProvider::class.simpleName) ?: false - super.visitSuperTypeList(list) - } + override fun visitSuperTypeList(list: KtSuperTypeList) { + containsRuleSetProvider = list.entries + ?.map { it.typeAsUserType?.referencedName } + ?.contains(RuleSetProvider::class.simpleName) ?: false + super.visitSuperTypeList(list) + } - override fun visitClassOrObject(classOrObject: KtClassOrObject) { - description = classOrObject.docComment?.getDefaultSection()?.getContent()?.trim() ?: "" - active = classOrObject.docComment?.getDefaultSection()?.findTagByName(TAG_ACTIVE) != null - configuration.addAll(classOrObject.parseConfigurationTags()) - super.visitClassOrObject(classOrObject) - } + override fun visitClassOrObject(classOrObject: KtClassOrObject) { + description = classOrObject.docComment?.getDefaultSection()?.getContent()?.trim() ?: "" + active = classOrObject.docComment?.getDefaultSection()?.findTagByName(TAG_ACTIVE) != null + configuration.addAll(classOrObject.parseConfigurationTags()) + super.visitClassOrObject(classOrObject) + } - override fun visitProperty(property: KtProperty) { - super.visitProperty(property) - if (property.isOverride() && property.name != null && property.name == PROPERTY_RULE_SET_ID) { - name = (property.initializer as? KtStringTemplateExpression)?.entries?.get(0)?.text - ?: throw InvalidDocumentationException("RuleSetProvider class " + - "${property.containingClass()?.name ?: ""} doesn't provide list of rules.") - } - } + override fun visitProperty(property: KtProperty) { + super.visitProperty(property) + if (property.isOverride() && property.name != null && property.name == PROPERTY_RULE_SET_ID) { + name = (property.initializer as? KtStringTemplateExpression)?.entries?.get(0)?.text + ?: throw InvalidDocumentationException("RuleSetProvider class " + + "${property.containingClass()?.name ?: ""} doesn't provide list of rules.") + } + } - override fun visitCallExpression(expression: KtCallExpression) { - super.visitCallExpression(expression) + override fun visitCallExpression(expression: KtCallExpression) { + super.visitCallExpression(expression) - if (expression.calleeExpression?.text == "RuleSet") { - val ruleListExpression = expression.valueArguments - .map { it.getArgumentExpression() } - .firstOrNull { it?.referenceExpression()?.text == "listOf" } - ?: throw InvalidDocumentationException("RuleSetProvider $name doesn't provide list of rules.") + if (expression.calleeExpression?.text == "RuleSet") { + val ruleListExpression = expression.valueArguments + .map { it.getArgumentExpression() } + .firstOrNull { it?.referenceExpression()?.text == "listOf" } + ?: throw InvalidDocumentationException("RuleSetProvider $name doesn't provide list of rules.") - val ruleArgumentNames = (ruleListExpression as? KtCallExpression) - ?.valueArguments - ?.map { it.getArgumentExpression() } - ?.mapNotNull { it?.referenceExpression()?.text } - ?: emptyList() + val ruleArgumentNames = (ruleListExpression as? KtCallExpression) + ?.valueArguments + ?.map { it.getArgumentExpression() } + ?.mapNotNull { it?.referenceExpression()?.text } + ?: emptyList() - ruleNames.addAll(ruleArgumentNames) - } - } + ruleNames.addAll(ruleArgumentNames) + } + } } diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/RuleVisitor.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/RuleVisitor.kt index 9e237f052..7db89fe4e 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/RuleVisitor.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/RuleVisitor.kt @@ -9,6 +9,7 @@ import io.gitlab.arturbosch.detekt.generator.collection.exception.InvalidCodeExa import io.gitlab.arturbosch.detekt.generator.collection.exception.InvalidDocumentationException import io.gitlab.arturbosch.detekt.generator.collection.exception.InvalidIssueDeclaration import io.gitlab.arturbosch.detekt.rules.empty.EmptyRule +import java.lang.reflect.Modifier import org.jetbrains.kotlin.psi.KtCallExpression import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtClassOrObject @@ -16,7 +17,6 @@ import org.jetbrains.kotlin.psi.KtSuperTypeList import org.jetbrains.kotlin.psi.KtValueArgument import org.jetbrains.kotlin.psi.psiUtil.containingClass import org.jetbrains.kotlin.psi.psiUtil.getSuperNames -import java.lang.reflect.Modifier /** * @author Marvin Ramin @@ -25,164 +25,164 @@ import java.lang.reflect.Modifier */ internal class RuleVisitor : DetektVisitor() { - val containsRule - get() = classesMap.any { it.value } - private var description = "" - private var nonCompliant = "" - private var compliant = "" - private var name = "" - private var active = false - private var autoCorrect = false - private var severity = "" - private var debt = "" - private var aliases: String? = null - private var parent = "" - private val configuration = mutableListOf() - private val classesMap = mutableMapOf() + val containsRule + get() = classesMap.any { it.value } + private var description = "" + private var nonCompliant = "" + private var compliant = "" + private var name = "" + private var active = false + private var autoCorrect = false + private var severity = "" + private var debt = "" + private var aliases: String? = null + private var parent = "" + private val configuration = mutableListOf() + private val classesMap = mutableMapOf() - fun getRule(): Rule { - if (description.isEmpty()) { - throw InvalidDocumentationException("Rule $name is missing a description in its KDoc.") - } + fun getRule(): Rule { + if (description.isEmpty()) { + throw InvalidDocumentationException("Rule $name is missing a description in its KDoc.") + } - return Rule(name, description, nonCompliant, compliant, - active, severity, debt, aliases, parent, configuration, autoCorrect) - } + return Rule(name, description, nonCompliant, compliant, + active, severity, debt, aliases, parent, configuration, autoCorrect) + } - override fun visitSuperTypeList(list: KtSuperTypeList) { - val isRule = list.entries - ?.asSequence() - ?.map { it.typeAsUserType?.referencedName } - ?.any { ruleClasses.contains(it) } ?: false + override fun visitSuperTypeList(list: KtSuperTypeList) { + val isRule = list.entries + ?.asSequence() + ?.map { it.typeAsUserType?.referencedName } + ?.any { ruleClasses.contains(it) } ?: false - val containingClass = list.containingClass() - val className = containingClass?.name - if (containingClass != null && className != null && !classesMap.containsKey(className)) { - classesMap[className] = isRule - parent = containingClass.getSuperNames().firstOrNull { ruleClasses.contains(it) } ?: "" - extractIssueSeverityAndDebt(containingClass) - extractAliases(containingClass) - } - super.visitSuperTypeList(list) - } + val containingClass = list.containingClass() + val className = containingClass?.name + if (containingClass != null && className != null && !classesMap.containsKey(className)) { + classesMap[className] = isRule + parent = containingClass.getSuperNames().firstOrNull { ruleClasses.contains(it) } ?: "" + extractIssueSeverityAndDebt(containingClass) + extractAliases(containingClass) + } + super.visitSuperTypeList(list) + } - override fun visitClassOrObject(classOrObject: KtClassOrObject) { - super.visitClassOrObject(classOrObject) - if (classesMap[classOrObject.name] != true) { - return - } + override fun visitClassOrObject(classOrObject: KtClassOrObject) { + super.visitClassOrObject(classOrObject) + if (classesMap[classOrObject.name] != true) { + return + } - name = classOrObject.name?.trim() ?: "" - active = classOrObject.kDocSection()?.findTagByName(TAG_ACTIVE) != null - autoCorrect = classOrObject.kDocSection()?.findTagByName(TAG_AUTO_CORRECT) != null + name = classOrObject.name?.trim() ?: "" + active = classOrObject.kDocSection()?.findTagByName(TAG_ACTIVE) != null + autoCorrect = classOrObject.kDocSection()?.findTagByName(TAG_AUTO_CORRECT) != null - val comment = classOrObject.kDocSection()?.getContent()?.trim() ?: return - extractRuleDocumentation(comment) - configuration.addAll(classOrObject.parseConfigurationTags()) - } + val comment = classOrObject.kDocSection()?.getContent()?.trim() ?: return + extractRuleDocumentation(comment) + configuration.addAll(classOrObject.parseConfigurationTags()) + } - private fun extractRuleDocumentation(comment: String) { - val nonCompliantIndex = comment.indexOf(TAG_NONCOMPLIANT) - val compliantIndex = comment.indexOf(TAG_COMPLIANT) - when { - nonCompliantIndex != -1 -> { - extractNonCompliantDocumentation(comment, nonCompliantIndex) - extractCompliantDocumentation(comment, compliantIndex) - } - compliantIndex != -1 -> throw InvalidCodeExampleDocumentationException( - "Rule $name contains a compliant without a noncompliant code definition.") - else -> description = comment - } - } + private fun extractRuleDocumentation(comment: String) { + val nonCompliantIndex = comment.indexOf(TAG_NONCOMPLIANT) + val compliantIndex = comment.indexOf(TAG_COMPLIANT) + when { + nonCompliantIndex != -1 -> { + extractNonCompliantDocumentation(comment, nonCompliantIndex) + extractCompliantDocumentation(comment, compliantIndex) + } + compliantIndex != -1 -> throw InvalidCodeExampleDocumentationException( + "Rule $name contains a compliant without a noncompliant code definition.") + else -> description = comment + } + } - private fun extractNonCompliantDocumentation(comment: String, nonCompliantIndex: Int) { - val nonCompliantEndIndex = comment.indexOf(ENDTAG_NONCOMPLIANT) - if (nonCompliantEndIndex == -1) { - throw InvalidCodeExampleDocumentationException( - "Rule $name contains a incorrect noncompliant code definition.") - } - description = comment.substring(0, nonCompliantIndex).trim() - nonCompliant = comment.substring(nonCompliantIndex + TAG_NONCOMPLIANT.length, nonCompliantEndIndex) - .trimStartingLineBreaks() - .trimEnd() - } + private fun extractNonCompliantDocumentation(comment: String, nonCompliantIndex: Int) { + val nonCompliantEndIndex = comment.indexOf(ENDTAG_NONCOMPLIANT) + if (nonCompliantEndIndex == -1) { + throw InvalidCodeExampleDocumentationException( + "Rule $name contains a incorrect noncompliant code definition.") + } + description = comment.substring(0, nonCompliantIndex).trim() + nonCompliant = comment.substring(nonCompliantIndex + TAG_NONCOMPLIANT.length, nonCompliantEndIndex) + .trimStartingLineBreaks() + .trimEnd() + } - private fun extractCompliantDocumentation(comment: String, compliantIndex: Int) { - val compliantEndIndex = comment.indexOf(ENDTAG_COMPLIANT) - if (compliantIndex != -1) { - if (compliantEndIndex == -1) { - throw InvalidCodeExampleDocumentationException( - "Rule $name contains a incorrect compliant code definition.") - } - compliant = comment.substring(compliantIndex + TAG_COMPLIANT.length, compliantEndIndex) - .trimStartingLineBreaks() - .trimEnd() - } - } + private fun extractCompliantDocumentation(comment: String, compliantIndex: Int) { + val compliantEndIndex = comment.indexOf(ENDTAG_COMPLIANT) + if (compliantIndex != -1) { + if (compliantEndIndex == -1) { + throw InvalidCodeExampleDocumentationException( + "Rule $name contains a incorrect compliant code definition.") + } + compliant = comment.substring(compliantIndex + TAG_COMPLIANT.length, compliantEndIndex) + .trimStartingLineBreaks() + .trimEnd() + } + } - private fun extractAliases(klass: KtClass) { - val initializer = klass.getProperties() - .singleOrNull { it.name == "defaultRuleIdAliases" } - ?.initializer - if (initializer != null) { - aliases = (initializer as? KtCallExpression - ?: throw InvalidAliasesDeclaration()) - .valueArguments - .joinToString(", ") { it.text.replace("\"", "") } - } - } + private fun extractAliases(klass: KtClass) { + val initializer = klass.getProperties() + .singleOrNull { it.name == "defaultRuleIdAliases" } + ?.initializer + if (initializer != null) { + aliases = (initializer as? KtCallExpression + ?: throw InvalidAliasesDeclaration()) + .valueArguments + .joinToString(", ") { it.text.replace("\"", "") } + } + } - private fun extractIssueSeverityAndDebt(klass: KtClass) { - val arguments = (klass.getProperties() - .singleOrNull { it.name == "issue" } - ?.initializer as? KtCallExpression) - ?.valueArguments ?: emptyList() + private fun extractIssueSeverityAndDebt(klass: KtClass) { + val arguments = (klass.getProperties() + .singleOrNull { it.name == "issue" } + ?.initializer as? KtCallExpression) + ?.valueArguments ?: emptyList() - if (arguments.size >= ISSUE_ARGUMENT_SIZE) { - severity = getArgument(arguments[1], "Severity") - val debtName = getArgument(arguments[DEBT_ARGUMENT_INDEX], "Debt") - val debtDeclarations = Debt::class.java.declaredFields.filter { Modifier.isStatic(it.modifiers) } - val debtDeclaration = debtDeclarations.singleOrNull { it.name == debtName } - if (debtDeclaration != null) { - debtDeclaration.isAccessible = true - debt = debtDeclaration.get(Debt::class.java).toString() - } - } - } + if (arguments.size >= ISSUE_ARGUMENT_SIZE) { + severity = getArgument(arguments[1], "Severity") + val debtName = getArgument(arguments[DEBT_ARGUMENT_INDEX], "Debt") + val debtDeclarations = Debt::class.java.declaredFields.filter { Modifier.isStatic(it.modifiers) } + val debtDeclaration = debtDeclarations.singleOrNull { it.name == debtName } + if (debtDeclaration != null) { + debtDeclaration.isAccessible = true + debt = debtDeclaration.get(Debt::class.java).toString() + } + } + } - private fun getArgument(argument: KtValueArgument, name: String): String { - val text = argument.text - val type = text.split('.') - if (text.startsWith(name, true) && type.size == 2) { - return type[1] - } - throw InvalidIssueDeclaration(name) - } + private fun getArgument(argument: KtValueArgument, name: String): String { + val text = argument.text + val type = text.split('.') + if (text.startsWith(name, true) && type.size == 2) { + return type[1] + } + throw InvalidIssueDeclaration(name) + } - companion object { - private val ruleClasses = listOf( - io.gitlab.arturbosch.detekt.api.Rule::class.simpleName, - FormattingRule::class.simpleName, - ThresholdRule::class.simpleName, - EmptyRule::class.simpleName - ) + companion object { + private val ruleClasses = listOf( + io.gitlab.arturbosch.detekt.api.Rule::class.simpleName, + FormattingRule::class.simpleName, + ThresholdRule::class.simpleName, + EmptyRule::class.simpleName + ) - private const val TAG_ACTIVE = "active" - private const val TAG_AUTO_CORRECT = "autoCorrect" - private const val TAG_NONCOMPLIANT = "" - private const val ENDTAG_NONCOMPLIANT = "" - private const val TAG_COMPLIANT = "" - private const val ENDTAG_COMPLIANT = "" + private const val TAG_ACTIVE = "active" + private const val TAG_AUTO_CORRECT = "autoCorrect" + private const val TAG_NONCOMPLIANT = "" + private const val ENDTAG_NONCOMPLIANT = "" + private const val TAG_COMPLIANT = "" + private const val ENDTAG_COMPLIANT = "" - private const val ISSUE_ARGUMENT_SIZE = 4 - private const val DEBT_ARGUMENT_INDEX = 3 - } + private const val ISSUE_ARGUMENT_SIZE = 4 + private const val DEBT_ARGUMENT_INDEX = 3 + } } private fun String.trimStartingLineBreaks(): String { - var i = 0 - while (i < this.length && (this[i] == '\n' || this[i] == '\r')) { - i++ - } - return this.substring(i) + var i = 0 + while (i < this.length && (this[i] == '\n' || this[i] == '\r')) { + i++ + } + return this.substring(i) } diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/exception/InvalidAliasesDeclaration.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/exception/InvalidAliasesDeclaration.kt index c3a7d83a9..15db6979b 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/exception/InvalidAliasesDeclaration.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/exception/InvalidAliasesDeclaration.kt @@ -1,5 +1,5 @@ package io.gitlab.arturbosch.detekt.generator.collection.exception class InvalidAliasesDeclaration : RuntimeException( - "Invalid aliases declaration. Example: override val defaultRuleIdAliases = setOf(\"Name1\", \"Name2\")" + "Invalid aliases declaration. Example: override val defaultRuleIdAliases = setOf(\"Name1\", \"Name2\")" ) diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/exception/InvalidCodeExampleDocumentationException.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/exception/InvalidCodeExampleDocumentationException.kt index 5f45d502b..bada04db6 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/exception/InvalidCodeExampleDocumentationException.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/exception/InvalidCodeExampleDocumentationException.kt @@ -1,4 +1,4 @@ package io.gitlab.arturbosch.detekt.generator.collection.exception class InvalidCodeExampleDocumentationException(ruleName: String) - : RuntimeException("Invalid rule documentation for noncompliant and compliant code examples in $ruleName.") + : RuntimeException("Invalid rule documentation for noncompliant and compliant code examples in $ruleName.") diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/exception/InvalidDocumentationException.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/exception/InvalidDocumentationException.kt index 417dcef39..540f9b537 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/exception/InvalidDocumentationException.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/exception/InvalidDocumentationException.kt @@ -6,4 +6,4 @@ package io.gitlab.arturbosch.detekt.generator.collection.exception * @author Marvin Ramin */ class InvalidDocumentationException(message: String) - : RuntimeException(message) + : RuntimeException(message) diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/exception/InvalidIssueDeclaration.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/exception/InvalidIssueDeclaration.kt index a4f6aeafb..362b9a14c 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/exception/InvalidIssueDeclaration.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/exception/InvalidIssueDeclaration.kt @@ -1,4 +1,4 @@ package io.gitlab.arturbosch.detekt.generator.collection.exception class InvalidIssueDeclaration(attributeName: String) - : RuntimeException("Invalid issue declaration attribute $attributeName.") + : RuntimeException("Invalid issue declaration attribute $attributeName.") diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/out/AbstractWriter.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/out/AbstractWriter.kt index a2b5aa318..621f8a224 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/out/AbstractWriter.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/out/AbstractWriter.kt @@ -8,22 +8,22 @@ import java.nio.file.Path */ internal abstract class AbstractWriter { - protected abstract val ending: String + protected abstract val ending: String - fun write(path: Path, fileName: String, content: () -> String) { - val filePath = path.resolve("$fileName.$ending") - filePath.parent?.let { Files.createDirectories(it) } - Files.write(filePath, content().toByteArray()) - println("Wrote: $fileName.$ending") - } + fun write(path: Path, fileName: String, content: () -> String) { + val filePath = path.resolve("$fileName.$ending") + filePath.parent?.let { Files.createDirectories(it) } + Files.write(filePath, content().toByteArray()) + println("Wrote: $fileName.$ending") + } } internal class MarkdownWriter : AbstractWriter() { - override val ending = "md" + override val ending = "md" } internal class YamlWriter : AbstractWriter() { - override val ending = "yml" + override val ending = "yml" } diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/out/Markdown.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/out/Markdown.kt index 4602a3951..38e391d85 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/out/Markdown.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/out/Markdown.kt @@ -6,23 +6,23 @@ package io.gitlab.arturbosch.detekt.generator.out * @author Marvin Ramin */ sealed class Markdown(open var content: String = "") { - fun append(value: String) { - content = if (content.isEmpty()) { - value - } else { - "$content\n$value" - } - } + fun append(value: String) { + content = if (content.isEmpty()) { + value + } else { + "$content\n$value" + } + } } data class MarkdownContent(override var content: String = "") : Markdown() data class MarkdownList(override var content: String = "") : Markdown() inline fun markdown(content: MarkdownContent.() -> Unit): String { - return MarkdownContent().let { markdown -> - content(markdown) - markdown.content - } + return MarkdownContent().let { markdown -> + content(markdown) + markdown.content + } } inline fun MarkdownContent.markdown(markdown: () -> String) = append(markdown()) @@ -36,13 +36,13 @@ inline fun MarkdownContent.h3(heading: () -> String) = append("### ${heading()}\ inline fun MarkdownContent.h4(heading: () -> String) = append("#### ${heading()}\n") inline fun MarkdownContent.orderedList(sectionList: () -> List) { - for (i in 0 until sectionList().size) { - append("${i + 1}. ${sectionList()[i]}") - } + for (i in 0 until sectionList().size) { + append("${i + 1}. ${sectionList()[i]}") + } } inline fun MarkdownContent.referenceToHeading(reference: () -> String) = - "[${reference()}](#${reference().replace(' ', '-').toLowerCase()})" + "[${reference()}](#${reference().replace(' ', '-').toLowerCase()})" inline fun MarkdownContent.code(code: () -> String) = "`${code()}`" inline fun MarkdownContent.codeBlock(code: () -> String) = "```kotlin\n${code()}\n```" @@ -50,12 +50,12 @@ inline fun MarkdownContent.codeBlock(code: () -> String) = "```kotlin\n${code()} fun MarkdownContent.emptyLine() = append("") inline fun MarkdownContent.list(listContent: MarkdownList.() -> Unit) { - return MarkdownList().let { list -> - listContent(list) - if (list.content.isNotEmpty()) { - append(list.content) - } - } + return MarkdownList().let { list -> + listContent(list) + if (list.content.isNotEmpty()) { + append(list.content) + } + } } inline fun MarkdownList.item(item: () -> String) = append("* ${item()}\n") diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/out/Yaml.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/out/Yaml.kt index 18611d87d..506f1c23b 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/out/Yaml.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/out/Yaml.kt @@ -4,60 +4,60 @@ package io.gitlab.arturbosch.detekt.generator.out * @author Marvin Ramin */ sealed class YML(open val indent: Int = 0, open var content: String = "") { - fun append(value: String) { - content = if (content.isEmpty()) { - "${getIndent()}$value" - } else { - "$content\n${getIndent()}$value" - } - } + fun append(value: String) { + content = if (content.isEmpty()) { + "${getIndent()}$value" + } else { + "$content\n${getIndent()}$value" + } + } - fun emptyLine() { - content = "$content\n" - } + fun emptyLine() { + content = "$content\n" + } - private fun getIndent(): String { - var spaces = "" - indent times { - spaces += " " - } - return spaces - } + private fun getIndent(): String { + var spaces = "" + indent times { + spaces += " " + } + return spaces + } } data class YamlNode(override val indent: Int = 0, override var content: String = "") : YML() infix fun Int.times(function: () -> Unit) { - var i = this - while (i > 0) { - function() - i-- - } + var i = this + while (i > 0) { + function() + i-- + } } inline fun yaml(content: YamlNode.() -> Unit): String { - return YamlNode().let { yaml -> - content(yaml) - yaml.content - } + return YamlNode().let { yaml -> + content(yaml) + yaml.content + } } fun YamlNode.node(name: String, node: YamlNode.() -> Unit) { - val yamlNode = YamlNode(indent = indent + 1, content = "$name:") - node(yamlNode) - append(yamlNode.content) + val yamlNode = YamlNode(indent = indent + 1, content = "$name:") + node(yamlNode) + append(yamlNode.content) } inline fun YamlNode.keyValue(keyValue: () -> Pair) { - val (key, value) = keyValue() - append("$key: $value") + val (key, value) = keyValue() + append("$key: $value") } fun YamlNode.list(name: String, list: List) { - append("$name:") - list.forEach { - append(" - $it") - } + append("$name:") + list.forEach { + append(" - $it") + } } inline fun YamlNode.yaml(yaml: () -> String) = append(yaml()) diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/DetektPrinter.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/DetektPrinter.kt index 6a1644939..53d4d5d62 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/DetektPrinter.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/DetektPrinter.kt @@ -13,21 +13,21 @@ import io.gitlab.arturbosch.detekt.generator.printer.rulesetpage.RuleSetPagePrin */ class DetektPrinter(private val arguments: GeneratorArgs) { - private val markdownWriter = MarkdownWriter() - private val yamlWriter = YamlWriter() + private val markdownWriter = MarkdownWriter() + private val yamlWriter = YamlWriter() - fun print(pages: List) { - pages.forEach { - markdownWriter.write(arguments.documentationPath, it.ruleSet.name) { - jekyllHeader(it.ruleSet.name) + "\n" + RuleSetPagePrinter.print(it) - } - } - yamlWriter.write(arguments.configPath, "default-detekt-config") { ConfigPrinter.print(pages) } - } + fun print(pages: List) { + pages.forEach { + markdownWriter.write(arguments.documentationPath, it.ruleSet.name) { + jekyllHeader(it.ruleSet.name) + "\n" + RuleSetPagePrinter.print(it) + } + } + yamlWriter.write(arguments.configPath, "default-detekt-config") { ConfigPrinter.print(pages) } + } - private fun jekyllHeader(ruleSet: String): String { - check(ruleSet.length > 1) { "Rule set name must be not empty or less than two symbols." } - return """ + private fun jekyllHeader(ruleSet: String): String { + check(ruleSet.length > 1) { "Rule set name must be not empty or less than two symbols." } + return """ |--- |title: ${ruleSet[0].toUpperCase()}${ruleSet.substring(1)} Rule Set |sidebar: home_sidebar @@ -37,5 +37,5 @@ class DetektPrinter(private val arguments: GeneratorArgs) { |folder: documentation |--- """.trimMargin() - } + } } diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/DocumentationPrinter.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/DocumentationPrinter.kt index 4de2231a5..6ecbfaea1 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/DocumentationPrinter.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/DocumentationPrinter.kt @@ -4,5 +4,5 @@ package io.gitlab.arturbosch.detekt.generator.printer * @author Marvin Ramin */ interface DocumentationPrinter { - fun print(item: T): String + fun print(item: T): String } diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/rulesetpage/ConfigPrinter.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/rulesetpage/ConfigPrinter.kt index 59b6a04a5..344ec4c9a 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/rulesetpage/ConfigPrinter.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/rulesetpage/ConfigPrinter.kt @@ -14,62 +14,62 @@ import io.gitlab.arturbosch.detekt.generator.printer.DocumentationPrinter */ object ConfigPrinter : DocumentationPrinter> { - override fun print(item: List): String { - return yaml { - yaml { defaultGenericConfiguration() } - emptyLine() - yaml { defaultTestPatternConfiguration() } - emptyLine() - yaml { defaultBuildConfiguration() } - emptyLine() - yaml { defaultProcessorsConfiguration() } - emptyLine() - yaml { defaultConsoleReportsConfiguration() } - emptyLine() + override fun print(item: List): String { + return yaml { + yaml { defaultGenericConfiguration() } + emptyLine() + yaml { defaultTestPatternConfiguration() } + emptyLine() + yaml { defaultBuildConfiguration() } + emptyLine() + yaml { defaultProcessorsConfiguration() } + emptyLine() + yaml { defaultConsoleReportsConfiguration() } + emptyLine() - item.sortedBy { it.ruleSet.name } - .forEach { printRuleSet(it.ruleSet, it.rules) } - } - } + item.sortedBy { it.ruleSet.name } + .forEach { printRuleSet(it.ruleSet, it.rules) } + } + } - private fun YamlNode.printRuleSet(ruleSet: RuleSetProvider, rules: List) { - node(ruleSet.name) { - keyValue { "active" to "${ruleSet.active}" } - ruleSet.configuration.forEach { configuration -> - if (configuration.defaultValue.isYamlList()) { - list(configuration.name, configuration.defaultValue.toList()) - } else { - keyValue { configuration.name to configuration.defaultValue } - } - } - rules.forEach { rule -> - node(rule.name) { - keyValue { "active" to "${rule.active}" } - if (rule.autoCorrect) { - keyValue { "autoCorrect" to "true" } - } - rule.configuration.forEach { configuration -> - if (configuration.defaultValue.isYamlList()) { - list(configuration.name, configuration.defaultValue.toList()) - } else { - keyValue { configuration.name to configuration.defaultValue } - } - } - } - } - emptyLine() - } - } + private fun YamlNode.printRuleSet(ruleSet: RuleSetProvider, rules: List) { + node(ruleSet.name) { + keyValue { "active" to "${ruleSet.active}" } + ruleSet.configuration.forEach { configuration -> + if (configuration.defaultValue.isYamlList()) { + list(configuration.name, configuration.defaultValue.toList()) + } else { + keyValue { configuration.name to configuration.defaultValue } + } + } + rules.forEach { rule -> + node(rule.name) { + keyValue { "active" to "${rule.active}" } + if (rule.autoCorrect) { + keyValue { "autoCorrect" to "true" } + } + rule.configuration.forEach { configuration -> + if (configuration.defaultValue.isYamlList()) { + list(configuration.name, configuration.defaultValue.toList()) + } else { + keyValue { configuration.name to configuration.defaultValue } + } + } + } + } + emptyLine() + } + } - private fun defaultGenericConfiguration(): String { - return """ + private fun defaultGenericConfiguration(): String { + return """ autoCorrect: true failFast: false """.trimIndent() - } + } - private fun defaultTestPatternConfiguration(): String { - return """ + private fun defaultTestPatternConfiguration(): String { + return """ test-pattern: # Configure exclusions for test sources active: true patterns: # Test file regexes @@ -94,10 +94,10 @@ object ConfigPrinter : DocumentationPrinter> { - 'TooGenericExceptionCaught' - 'InstanceOfCheckForException' """.trimIndent() - } + } - private fun defaultBuildConfiguration(): String { - return """ + private fun defaultBuildConfiguration(): String { + return """ build: maxIssues: 10 weights: @@ -106,10 +106,10 @@ object ConfigPrinter : DocumentationPrinter> { # style: 1 # comments: 1 """.trimIndent() - } + } - private fun defaultProcessorsConfiguration(): String { - return """ + private fun defaultProcessorsConfiguration(): String { + return """ processors: active: true exclude: @@ -119,10 +119,10 @@ object ConfigPrinter : DocumentationPrinter> { # - 'PackageCountProcessor' # - 'KtFileCountProcessor' """.trimIndent() - } + } - private fun defaultConsoleReportsConfiguration(): String { - return """ + private fun defaultConsoleReportsConfiguration(): String { + return """ console-reports: active: true exclude: @@ -132,11 +132,11 @@ object ConfigPrinter : DocumentationPrinter> { # - 'FindingsReport' # - 'BuildFailureReport' """.trimIndent() - } + } - private fun String.isYamlList() = trim().startsWith("-") + private fun String.isYamlList() = trim().startsWith("-") - private fun String.toList(): List { - return split("\n").map { it.replace("-", "") }.map { it.trim() } - } + private fun String.toList(): List { + return split("\n").map { it.replace("-", "") }.map { it.trim() } + } } diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/rulesetpage/RuleSetPage.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/rulesetpage/RuleSetPage.kt index 428ddcb9c..01767f70b 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/rulesetpage/RuleSetPage.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/rulesetpage/RuleSetPage.kt @@ -4,6 +4,6 @@ import io.gitlab.arturbosch.detekt.generator.collection.Rule import io.gitlab.arturbosch.detekt.generator.collection.RuleSetProvider data class RuleSetPage( - val ruleSet: RuleSetProvider, - val rules: List + val ruleSet: RuleSetProvider, + val rules: List ) diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/rulesetpage/RuleSetPagePrinter.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/rulesetpage/RuleSetPagePrinter.kt index 19693fa70..eb907eb66 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/rulesetpage/RuleSetPagePrinter.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/rulesetpage/RuleSetPagePrinter.kt @@ -20,70 +20,70 @@ import io.gitlab.arturbosch.detekt.generator.printer.DocumentationPrinter */ object RuleSetPagePrinter : DocumentationPrinter { - override fun print(item: RuleSetPage): String { - return markdown { - if (item.ruleSet.description.isNotEmpty()) { - paragraph { item.ruleSet.description } - } else { - paragraph { "TODO: Specify description" } - } - item.rules.forEach { - markdown { printRule(it) } - } - } - } + override fun print(item: RuleSetPage): String { + return markdown { + if (item.ruleSet.description.isNotEmpty()) { + paragraph { item.ruleSet.description } + } else { + paragraph { "TODO: Specify description" } + } + item.rules.forEach { + markdown { printRule(it) } + } + } + } - private fun printRule(rule: Rule): String { - return markdown { - h3 { rule.name } + private fun printRule(rule: Rule): String { + return markdown { + h3 { rule.name } - if (rule.description.isNotEmpty()) { - paragraph { rule.description } - } else { - paragraph { "TODO: Specify description" } - } + if (rule.description.isNotEmpty()) { + paragraph { rule.description } + } else { + paragraph { "TODO: Specify description" } + } - if (rule.severity.isNotEmpty()) { - paragraph { - "${bold { "Severity" }}: ${rule.severity}" - } - } + if (rule.severity.isNotEmpty()) { + paragraph { + "${bold { "Severity" }}: ${rule.severity}" + } + } - if (rule.debt.isNotEmpty()) { - paragraph { - "${bold { "Debt" }}: ${rule.debt}" - } - } + if (rule.debt.isNotEmpty()) { + paragraph { + "${bold { "Debt" }}: ${rule.debt}" + } + } - if (!rule.aliases.isNullOrEmpty()) { - paragraph { - "${bold { "Aliases" }}: ${rule.aliases}" - } - } + if (!rule.aliases.isNullOrEmpty()) { + paragraph { + "${bold { "Aliases" }}: ${rule.aliases}" + } + } - if (rule.configuration.isNotEmpty()) { - h4 { "Configuration options:" } - list { - rule.configuration.forEach { - item { "${code { it.name }} (default: ${code { it.defaultValue }})" } - description { it.description } - } - } - } + if (rule.configuration.isNotEmpty()) { + h4 { "Configuration options:" } + list { + rule.configuration.forEach { + item { "${code { it.name }} (default: ${code { it.defaultValue }})" } + description { it.description } + } + } + } - printRuleCodeExamples(rule) - } - } + printRuleCodeExamples(rule) + } + } - private fun MarkdownContent.printRuleCodeExamples(rule: Rule) { - if (rule.nonCompliantCodeExample.isNotEmpty()) { - h4 { "Noncompliant Code:" } - paragraph { codeBlock { rule.nonCompliantCodeExample } } - } + private fun MarkdownContent.printRuleCodeExamples(rule: Rule) { + if (rule.nonCompliantCodeExample.isNotEmpty()) { + h4 { "Noncompliant Code:" } + paragraph { codeBlock { rule.nonCompliantCodeExample } } + } - if (rule.compliantCodeExample.isNotEmpty()) { - h4 { "Compliant Code:" } - paragraph { codeBlock { rule.compliantCodeExample } } - } - } + if (rule.compliantCodeExample.isNotEmpty()) { + h4 { "Compliant Code:" } + paragraph { codeBlock { rule.compliantCodeExample } } + } + } } diff --git a/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/collection/MultiRuleCollectorSpec.kt b/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/collection/MultiRuleCollectorSpec.kt index 63f54a14f..57ff5925a 100644 --- a/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/collection/MultiRuleCollectorSpec.kt +++ b/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/collection/MultiRuleCollectorSpec.kt @@ -10,48 +10,48 @@ import org.jetbrains.spek.subject.SubjectSpek class MultiRuleCollectorSpec : SubjectSpek({ - subject { MultiRuleCollector() } + subject { MultiRuleCollector() } - describe("a MultiRuleCollector") { + describe("a MultiRuleCollector") { - it("collects no multirule when no class is extended") { - val code = """ + it("collects no multirule when no class is extended") { + val code = """ package foo class SomeRandomClass { } """ - val items = subject.run(code) - assertThat(items).isEmpty() - } + val items = subject.run(code) + assertThat(items).isEmpty() + } - it("collects no rules when no multirule class is extended") { - val code = """ + it("collects no rules when no multirule class is extended") { + val code = """ package foo class SomeRandomClass: SomeOtherClass { } """ - val items = subject.run(code) - assertThat(items).isEmpty() - } + val items = subject.run(code) + assertThat(items).isEmpty() + } - it("throws when no rules are added") { - val name = "SomeRandomClass" - val code = """ + it("throws when no rules are added") { + val name = "SomeRandomClass" + val code = """ package foo class $name: MultiRule { } """ - assertThatExceptionOfType(InvalidDocumentationException::class.java).isThrownBy { - subject.run(code) - } - } + assertThatExceptionOfType(InvalidDocumentationException::class.java).isThrownBy { + subject.run(code) + } + } - it("collects all rules in fields and in the rule property") { - val name = "SomeRandomClass" - val code = """ + it("collects all rules in fields and in the rule property") { + val name = "SomeRandomClass" + val code = """ package foo class $name: MultiRule { @@ -66,9 +66,9 @@ class MultiRuleCollectorSpec : SubjectSpek({ ) } """ - val items = subject.run(code) - assertThat(items[0].rules).hasSize(4) - assertThat(items[0].rules).contains("FirstRule", "SecondRule", "RuleOne", "RuleTwo") - } - } + val items = subject.run(code) + assertThat(items[0].rules).hasSize(4) + assertThat(items[0].rules).contains("FirstRule", "SecondRule", "RuleOne", "RuleTwo") + } + } }) diff --git a/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/collection/RuleCollectorSpec.kt b/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/collection/RuleCollectorSpec.kt index 8cfdd3868..d048be3b2 100644 --- a/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/collection/RuleCollectorSpec.kt +++ b/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/collection/RuleCollectorSpec.kt @@ -13,68 +13,68 @@ import org.jetbrains.spek.subject.SubjectSpek class RuleCollectorSpec : SubjectSpek({ - subject { RuleCollector() } + subject { RuleCollector() } - describe("a RuleCollector") { + describe("a RuleCollector") { - it("collects no rules when no class is extended") { - val code = """ + it("collects no rules when no class is extended") { + val code = """ package foo class SomeRandomClass { } """ - val items = subject.run(code) - assertThat(items).isEmpty() - } + val items = subject.run(code) + assertThat(items).isEmpty() + } - it("collects no rules when no rule class is extended") { - val code = """ + it("collects no rules when no rule class is extended") { + val code = """ package foo class SomeRandomClass: SomeOtherClass { } """ - val items = subject.run(code) - assertThat(items).isEmpty() - } + val items = subject.run(code) + assertThat(items).isEmpty() + } - it("throws when a class extends Rule but has no valid documentation") { - val code = """ + it("throws when a class extends Rule but has no valid documentation") { + val code = """ package foo class SomeRandomClass: Rule { } """ - assertThatExceptionOfType(InvalidDocumentationException::class.java) - .isThrownBy { subject.run(code) } - } + assertThatExceptionOfType(InvalidDocumentationException::class.java) + .isThrownBy { subject.run(code) } + } - it("throws when a class extends ThresholdRule but has no valid documentation") { - val code = """ + it("throws when a class extends ThresholdRule but has no valid documentation") { + val code = """ package foo class SomeRandomClass: ThresholdRule { } """ - assertThatExceptionOfType(InvalidDocumentationException::class.java) - .isThrownBy { subject.run(code) } - } + assertThatExceptionOfType(InvalidDocumentationException::class.java) + .isThrownBy { subject.run(code) } + } - it("throws when a class extends ThresholdRule but has no valid documentation") { - val code = """ + it("throws when a class extends ThresholdRule but has no valid documentation") { + val code = """ package foo class SomeRandomClass: FormattingRule { } """ - assertThatExceptionOfType(InvalidDocumentationException::class.java) - .isThrownBy { subject.run(code) } - } + assertThatExceptionOfType(InvalidDocumentationException::class.java) + .isThrownBy { subject.run(code) } + } - it("collects the formatting rule name") { - val name = "UnusedImport" - val code = """ + it("collects the formatting rule name") { + val name = "UnusedImport" + val code = """ package foo /** @@ -83,14 +83,14 @@ class RuleCollectorSpec : SubjectSpek({ class $name: FormattingRule { } """ - val items = subject.run(code) - assertThat(items[0].name).isEqualTo(name) - } + val items = subject.run(code) + assertThat(items[0].name).isEqualTo(name) + } - it("collects the rule name") { - val name = "SomeRandomClass" - val description = "some description" - val code = """ + it("collects the rule name") { + val name = "SomeRandomClass" + val description = "some description" + val code = """ package foo /** @@ -99,14 +99,14 @@ class RuleCollectorSpec : SubjectSpek({ class $name: Rule { } """ - val items = subject.run(code) - assertThat(items[0].name).isEqualTo(name) - } + val items = subject.run(code) + assertThat(items[0].name).isEqualTo(name) + } - it("collects the rule description") { - val name = "SomeRandomClass" - val description = "some description" - val code = """ + it("collects the rule description") { + val name = "SomeRandomClass" + val description = "some description" + val code = """ package foo /** @@ -115,14 +115,14 @@ class RuleCollectorSpec : SubjectSpek({ class $name: Rule { } """ - val items = subject.run(code) - assertThat(items[0].description).isEqualTo(description) - } + val items = subject.run(code) + assertThat(items[0].description).isEqualTo(description) + } - it("has a multi paragraph description") { - val name = "SomeRandomClass" - val description = "some description" - val code = """ + it("has a multi paragraph description") { + val name = "SomeRandomClass" + val description = "some description" + val code = """ package foo /** @@ -133,15 +133,15 @@ class RuleCollectorSpec : SubjectSpek({ class $name: Rule { } """ - val items = subject.run(code) - assertThat(items[0].description).startsWith(description) - assertThat(items[0].description).contains("more...") - } + val items = subject.run(code) + assertThat(items[0].description).startsWith(description) + assertThat(items[0].description).contains("more...") + } - it("does not include tags in the description") { - val name = "SomeRandomClass" - val description = "some description" - val code = """ + it("does not include tags in the description") { + val name = "SomeRandomClass" + val description = "some description" + val code = """ package foo /** @@ -151,14 +151,14 @@ class RuleCollectorSpec : SubjectSpek({ class $name: Rule { } """ - val items = subject.run(code) - assertThat(items[0].description).isEqualTo(description) - } + val items = subject.run(code) + assertThat(items[0].description).isEqualTo(description) + } - it("is not active") { - val name = "SomeRandomClass" - val description = "some description" - val code = """ + it("is not active") { + val name = "SomeRandomClass" + val description = "some description" + val code = """ package foo /** @@ -168,12 +168,12 @@ class RuleCollectorSpec : SubjectSpek({ class $name: Rule { } """ - val items = subject.run(code) - assertThat(items[0].active).isFalse() - } + val items = subject.run(code) + assertThat(items[0].active).isFalse() + } - it("is active tag is present") { - val code = """ + it("is active tag is present") { + val code = """ package foo /** @@ -183,12 +183,12 @@ class RuleCollectorSpec : SubjectSpek({ class SomeRandomClass: Rule { } """ - val items = subject.run(code) - assertThat(items[0].active).isTrue() - } + val items = subject.run(code) + assertThat(items[0].active).isTrue() + } - it("is auto-correctable tag is present") { - val code = """ + it("is auto-correctable tag is present") { + val code = """ package foo /** @@ -198,14 +198,14 @@ class RuleCollectorSpec : SubjectSpek({ class SomeRandomClass: Rule { } """ - val items = subject.run(code) - assertThat(items[0].autoCorrect).isTrue() - } + val items = subject.run(code) + assertThat(items[0].autoCorrect).isTrue() + } - it("is active if the tag is there and has a description") { - val name = "SomeRandomClass" - val description = "some description" - val code = """ + it("is active if the tag is there and has a description") { + val name = "SomeRandomClass" + val description = "some description" + val code = """ package foo /** @@ -215,14 +215,14 @@ class RuleCollectorSpec : SubjectSpek({ class $name: Rule { } """ - val items = subject.run(code) - assertThat(items[0].active).isTrue() - } + val items = subject.run(code) + assertThat(items[0].active).isTrue() + } - it("collects the issue property") { - val name = "SomeRandomClass" - val description = "some description" - val code = """ + it("collects the issue property") { + val name = "SomeRandomClass" + val description = "some description" + val code = """ package foo /** @@ -238,16 +238,16 @@ class RuleCollectorSpec : SubjectSpek({ debt = Debt.TEN_MINS) } """ - val items = subject.run(code) - assertThat(items[0].severity).isEqualTo("Style") - assertThat(items[0].debt).isEqualTo("10min") - assertThat(items[0].aliases).isEqualTo("RULE, RULE2") - } + val items = subject.run(code) + assertThat(items[0].severity).isEqualTo("Style") + assertThat(items[0].debt).isEqualTo("10min") + assertThat(items[0].aliases).isEqualTo("RULE, RULE2") + } - it("contains no configuration options by default") { - val name = "SomeRandomClass" - val description = "some description" - val code = """ + it("contains no configuration options by default") { + val name = "SomeRandomClass" + val description = "some description" + val code = """ package foo /** @@ -256,14 +256,14 @@ class RuleCollectorSpec : SubjectSpek({ class $name: Rule { } """ - val items = subject.run(code) - assertThat(items[0].configuration).isEmpty() - } + val items = subject.run(code) + assertThat(items[0].configuration).isEmpty() + } - it("contains one configuration option with correct formatting") { - val name = "SomeRandomClass" - val description = "some description" - val code = """ + it("contains one configuration option with correct formatting") { + val name = "SomeRandomClass" + val description = "some description" + val code = """ package foo /** @@ -273,17 +273,17 @@ class RuleCollectorSpec : SubjectSpek({ class $name: Rule { } """ - val items = subject.run(code) - assertThat(items[0].configuration).hasSize(1) - assertThat(items[0].configuration[0].name).isEqualTo("config") - assertThat(items[0].configuration[0].description).isEqualTo("description") - assertThat(items[0].configuration[0].defaultValue).isEqualTo("'[A-Z$]'") - } + val items = subject.run(code) + assertThat(items[0].configuration).hasSize(1) + assertThat(items[0].configuration[0].name).isEqualTo("config") + assertThat(items[0].configuration[0].description).isEqualTo("description") + assertThat(items[0].configuration[0].defaultValue).isEqualTo("'[A-Z$]'") + } - it("contains multiple configuration options") { - val name = "SomeRandomClass" - val description = "some description" - val code = """ + it("contains multiple configuration options") { + val name = "SomeRandomClass" + val description = "some description" + val code = """ package foo /** @@ -294,14 +294,14 @@ class RuleCollectorSpec : SubjectSpek({ class $name: Rule { } """ - val items = subject.run(code) - assertThat(items[0].configuration).hasSize(2) - } + val items = subject.run(code) + assertThat(items[0].configuration).hasSize(2) + } - it("contains a misconfigured configuration option") { - val name = "SomeRandomClass" - val description = "some description" - val code = """ + it("contains a misconfigured configuration option") { + val name = "SomeRandomClass" + val description = "some description" + val code = """ package foo /** @@ -311,12 +311,12 @@ class RuleCollectorSpec : SubjectSpek({ class $name: Rule { } """ - assertThatExceptionOfType(InvalidDocumentationException::class.java) - .isThrownBy { subject.run(code) } - } + assertThatExceptionOfType(InvalidDocumentationException::class.java) + .isThrownBy { subject.run(code) } + } - it("contains compliant and noncompliant code examples") { - val code = """ + it("contains compliant and noncompliant code examples") { + val code = """ package foo /** @@ -333,13 +333,13 @@ class RuleCollectorSpec : SubjectSpek({ class RandomClass : Rule { } """ - val items = subject.run(code) - assertThat(items[0].nonCompliantCodeExample).isEqualTo("val one = 2") - assertThat(items[0].compliantCodeExample).isEqualTo("val one = 1") - } + val items = subject.run(code) + assertThat(items[0].nonCompliantCodeExample).isEqualTo("val one = 2") + assertThat(items[0].compliantCodeExample).isEqualTo("val one = 1") + } - it("has wrong noncompliant code example declaration") { - val code = """ + it("has wrong noncompliant code example declaration") { + val code = """ package foo /** @@ -350,12 +350,12 @@ class RuleCollectorSpec : SubjectSpek({ class RandomClass : Rule { } """ - assertThatExceptionOfType(InvalidCodeExampleDocumentationException::class.java) - .isThrownBy { subject.run(code) } - } + assertThatExceptionOfType(InvalidCodeExampleDocumentationException::class.java) + .isThrownBy { subject.run(code) } + } - it("has wrong compliant code example declaration") { - val code = """ + it("has wrong compliant code example declaration") { + val code = """ package foo /** @@ -369,12 +369,12 @@ class RuleCollectorSpec : SubjectSpek({ class RandomClass : Rule { } """ - assertThatExceptionOfType(InvalidCodeExampleDocumentationException::class.java) - .isThrownBy { subject.run(code) } - } + assertThatExceptionOfType(InvalidCodeExampleDocumentationException::class.java) + .isThrownBy { subject.run(code) } + } - it("has wrong compliant without noncompliant code example declaration") { - val code = """ + it("has wrong compliant without noncompliant code example declaration") { + val code = """ package foo /** @@ -387,14 +387,14 @@ class RuleCollectorSpec : SubjectSpek({ class RandomClass : Rule { } """ - assertThatExceptionOfType(InvalidCodeExampleDocumentationException::class.java) - .isThrownBy { subject.run(code) } - } + assertThatExceptionOfType(InvalidCodeExampleDocumentationException::class.java) + .isThrownBy { subject.run(code) } + } - it("has wrong issue style property") { - val name = "SomeRandomClass" - val description = "some description" - val code = """ + it("has wrong issue style property") { + val name = "SomeRandomClass" + val description = "some description" + val code = """ package foo /** @@ -409,14 +409,14 @@ class RuleCollectorSpec : SubjectSpek({ debt = Debt.TEN_MINS) } """ - assertThatExceptionOfType(InvalidIssueDeclaration::class.java) - .isThrownBy { subject.run(code) } - } + assertThatExceptionOfType(InvalidIssueDeclaration::class.java) + .isThrownBy { subject.run(code) } + } - it("has wrong aliases property structure") { - val name = "SomeRandomClass" - val description = "some description" - val code = """ + it("has wrong aliases property structure") { + val name = "SomeRandomClass" + val description = "some description" + val code = """ package foo /** @@ -432,8 +432,8 @@ class RuleCollectorSpec : SubjectSpek({ debt = Debt.TEN_MINS) } """ - assertThatExceptionOfType(InvalidAliasesDeclaration::class.java) - .isThrownBy { subject.run(code) } - } - } + assertThatExceptionOfType(InvalidAliasesDeclaration::class.java) + .isThrownBy { subject.run(code) } + } + } }) diff --git a/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/collection/RuleSetProviderCollectorSpec.kt b/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/collection/RuleSetProviderCollectorSpec.kt index ae544f092..e496af7a8 100644 --- a/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/collection/RuleSetProviderCollectorSpec.kt +++ b/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/collection/RuleSetProviderCollectorSpec.kt @@ -10,10 +10,10 @@ import org.jetbrains.spek.subject.SubjectSpek class RuleSetProviderCollectorSpec : SubjectSpek({ - subject { RuleSetProviderCollector() } + subject { RuleSetProviderCollector() } - given("a non-RuleSetProvider class extending nothing") { - val code = """ + given("a non-RuleSetProvider class extending nothing") { + val code = """ package foo class SomeRandomClass { @@ -22,14 +22,14 @@ class RuleSetProviderCollectorSpec : SubjectSpek({ } } """ - it("collects no rulesets") { - val items = subject.run(code) - assertThat(items).isEmpty() - } - } + it("collects no rulesets") { + val items = subject.run(code) + assertThat(items).isEmpty() + } + } - given("a non-RuleSetProvider class extending a class that is not related to rules") { - val code = """ + given("a non-RuleSetProvider class extending a class that is not related to rules") { + val code = """ package foo class SomeRandomClass: SomeOtherClass { @@ -38,14 +38,14 @@ class RuleSetProviderCollectorSpec : SubjectSpek({ } } """ - it("collects no rulesets") { - val items = subject.run(code) - assertThat(items).isEmpty() - } - } + it("collects no rulesets") { + val items = subject.run(code) + assertThat(items).isEmpty() + } + } - given("a RuleSetProvider without documentation") { - val code = """ + given("a RuleSetProvider without documentation") { + val code = """ package foo class TestProvider: RuleSetProvider { @@ -54,14 +54,14 @@ class RuleSetProviderCollectorSpec : SubjectSpek({ } } """ - it("throws an exception") { - assertThatExceptionOfType(InvalidDocumentationException::class.java) - .isThrownBy { subject.run(code) } - } - } + it("throws an exception") { + assertThatExceptionOfType(InvalidDocumentationException::class.java) + .isThrownBy { subject.run(code) } + } + } - given("a correct RuleSetProvider class extending RuleSetProvider but missing parameters") { - val code = """ + given("a correct RuleSetProvider class extending RuleSetProvider but missing parameters") { + val code = """ package foo class TestProvider: RuleSetProvider { @@ -71,17 +71,17 @@ class RuleSetProviderCollectorSpec : SubjectSpek({ } """ - it("throws an exception") { - assertThatExceptionOfType(InvalidDocumentationException::class.java) - .isThrownBy { subject.run(code) } - } - } + it("throws an exception") { + assertThatExceptionOfType(InvalidDocumentationException::class.java) + .isThrownBy { subject.run(code) } + } + } - given("a correct RuleSetProvider class with full parameters") { - val description = "This is a description" - val ruleSetId = "test" - val ruleName = "TestRule" - val code = """ + given("a correct RuleSetProvider class with full parameters") { + val description = "This is a description" + val ruleSetId = "test" + val ruleName = "TestRule" + val code = """ package foo /** @@ -100,42 +100,42 @@ class RuleSetProviderCollectorSpec : SubjectSpek({ } """ - it("collects a RuleSetProvider") { - val items = subject.run(code) - assertThat(items).hasSize(1) - } + it("collects a RuleSetProvider") { + val items = subject.run(code) + assertThat(items).hasSize(1) + } - it("has one rule") { - val items = subject.run(code) - val provider = items[0] - assertThat(provider.rules).hasSize(1) - assertThat(provider.rules[0]).isEqualTo(ruleName) - } + it("has one rule") { + val items = subject.run(code) + val provider = items[0] + assertThat(provider.rules).hasSize(1) + assertThat(provider.rules[0]).isEqualTo(ruleName) + } - it("has correct name") { - val items = subject.run(code) - val provider = items[0] - assertThat(provider.name).isEqualTo(ruleSetId) - } + it("has correct name") { + val items = subject.run(code) + val provider = items[0] + assertThat(provider.name).isEqualTo(ruleSetId) + } - it("has correct description") { - val items = subject.run(code) - val provider = items[0] - assertThat(provider.description).isEqualTo(description) - } + it("has correct description") { + val items = subject.run(code) + val provider = items[0] + assertThat(provider.description).isEqualTo(description) + } - it("is active") { - val items = subject.run(code) - val provider = items[0] - assertThat(provider.active).isTrue() - } - } + it("is active") { + val items = subject.run(code) + val provider = items[0] + assertThat(provider.active).isTrue() + } + } - given("an inactive RuleSetProvider") { - val description = "This is a description" - val ruleSetId = "test" - val ruleName = "TestRule" - val code = """ + given("an inactive RuleSetProvider") { + val description = "This is a description" + val ruleSetId = "test" + val ruleName = "TestRule" + val code = """ package foo /** @@ -152,17 +152,17 @@ class RuleSetProviderCollectorSpec : SubjectSpek({ } """ - it("is not active") { - val items = subject.run(code) - val provider = items[0] - assertThat(provider.active).isFalse() - } - } + it("is not active") { + val items = subject.run(code) + val provider = items[0] + assertThat(provider.active).isFalse() + } + } - given("a RuleSetProvider with missing name") { - val description = "This is a description" - val ruleName = "TestRule" - val code = """ + given("a RuleSetProvider with missing name") { + val description = "This is a description" + val ruleName = "TestRule" + val code = """ package foo /** @@ -177,16 +177,16 @@ class RuleSetProviderCollectorSpec : SubjectSpek({ } """ - it("throws an exception") { - assertThatExceptionOfType(InvalidDocumentationException::class.java) - .isThrownBy { subject.run(code) } - } - } + it("throws an exception") { + assertThatExceptionOfType(InvalidDocumentationException::class.java) + .isThrownBy { subject.run(code) } + } + } - given("a RuleSetProvider with missing description") { - val ruleSetId = "test" - val ruleName = "TestRule" - val code = """ + given("a RuleSetProvider with missing description") { + val ruleSetId = "test" + val ruleName = "TestRule" + val code = """ package foo class TestProvider: RuleSetProvider { @@ -200,15 +200,15 @@ class RuleSetProviderCollectorSpec : SubjectSpek({ } """ - it("throws an exception") { - assertThatExceptionOfType(InvalidDocumentationException::class.java) - .isThrownBy { subject.run(code) } - } - } + it("throws an exception") { + assertThatExceptionOfType(InvalidDocumentationException::class.java) + .isThrownBy { subject.run(code) } + } + } - given("a RuleSetProvider with no rules") { - val ruleSetId = "test" - val code = """ + given("a RuleSetProvider with no rules") { + val ruleSetId = "test" + val code = """ package foo class TestProvider: RuleSetProvider { @@ -220,18 +220,18 @@ class RuleSetProviderCollectorSpec : SubjectSpek({ } """ - it("throws an exception") { - assertThatExceptionOfType(InvalidDocumentationException::class.java) - .isThrownBy { subject.run(code) } - } - } + it("throws an exception") { + assertThatExceptionOfType(InvalidDocumentationException::class.java) + .isThrownBy { subject.run(code) } + } + } - given("a correct RuleSetProvider class with full parameters") { - val description = "This is a description" - val ruleSetId = "test" - val ruleName = "TestRule" - val secondRuleName = "SecondRule" - val code = """ + given("a correct RuleSetProvider class with full parameters") { + val description = "This is a description" + val ruleSetId = "test" + val ruleName = "TestRule" + val secondRuleName = "SecondRule" + val code = """ package foo /** @@ -251,9 +251,9 @@ class RuleSetProviderCollectorSpec : SubjectSpek({ } """ - it("collects multiple rules") { - val items = subject.run(code) - assertThat(items[0].rules).containsExactly(ruleName, secondRuleName) - } - } + it("collects multiple rules") { + val items = subject.run(code) + assertThat(items[0].rules).containsExactly(ruleName, secondRuleName) + } + } }) diff --git a/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/printer/ConfigPrinterSpec.kt b/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/printer/ConfigPrinterSpec.kt index 61e9c57c5..eca86b8fc 100644 --- a/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/printer/ConfigPrinterSpec.kt +++ b/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/printer/ConfigPrinterSpec.kt @@ -3,21 +3,21 @@ package io.gitlab.arturbosch.detekt.generator.printer import io.gitlab.arturbosch.detekt.generator.printer.rulesetpage.ConfigPrinter import io.gitlab.arturbosch.detekt.generator.util.createRuleSetPage import io.gitlab.arturbosch.detekt.test.resource +import java.io.File import org.assertj.core.api.Assertions.assertThat import org.jetbrains.spek.api.Spek import org.jetbrains.spek.api.dsl.given import org.jetbrains.spek.api.dsl.it -import java.io.File class ConfigPrinterSpec : Spek({ - given("a config to print") { + given("a config to print") { - it("prints the correct yaml format") { - val ruleSetList = listOf(createRuleSetPage()) - val yamlString = ConfigPrinter.print(ruleSetList) - val expectedYamlString = File(resource("/RuleSetConfig.yml")).readText() - assertThat(yamlString).contains(expectedYamlString) - } - } + it("prints the correct yaml format") { + val ruleSetList = listOf(createRuleSetPage()) + val yamlString = ConfigPrinter.print(ruleSetList) + val expectedYamlString = File(resource("/RuleSetConfig.yml")).readText() + assertThat(yamlString).contains(expectedYamlString) + } + } }) diff --git a/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/printer/RuleSetPagePrinterSpec.kt b/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/printer/RuleSetPagePrinterSpec.kt index 0f8371360..1f9e7cd8d 100644 --- a/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/printer/RuleSetPagePrinterSpec.kt +++ b/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/printer/RuleSetPagePrinterSpec.kt @@ -3,20 +3,20 @@ package io.gitlab.arturbosch.detekt.generator.printer import io.gitlab.arturbosch.detekt.generator.printer.rulesetpage.RuleSetPagePrinter import io.gitlab.arturbosch.detekt.generator.util.createRuleSetPage import io.gitlab.arturbosch.detekt.test.resource +import java.io.File import org.assertj.core.api.Assertions.assertThat import org.jetbrains.spek.api.Spek import org.jetbrains.spek.api.dsl.given import org.jetbrains.spek.api.dsl.it -import java.io.File class RuleSetPagePrinterSpec : Spek({ - given("a config to print") { + given("a config to print") { - it("prints the correct markdown format") { - val markdownString = RuleSetPagePrinter.print(createRuleSetPage()) - val expectedMarkdownString = File(resource("/RuleSet.md")).readText() - assertThat(markdownString).isEqualTo(expectedMarkdownString) - } - } + it("prints the correct markdown format") { + val markdownString = RuleSetPagePrinter.print(createRuleSetPage()) + val expectedMarkdownString = File(resource("/RuleSet.md")).readText() + assertThat(markdownString).isEqualTo(expectedMarkdownString) + } + } }) diff --git a/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/util/CollectorTestExtensions.kt b/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/util/CollectorTestExtensions.kt index 6fbc31276..7db486bd4 100644 --- a/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/util/CollectorTestExtensions.kt +++ b/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/util/CollectorTestExtensions.kt @@ -4,7 +4,7 @@ import io.gitlab.arturbosch.detekt.generator.collection.Collector import io.gitlab.arturbosch.detekt.test.KtTestCompiler fun Collector.run(code: String): List { - val ktFile = KtTestCompiler.compileFromContent(code.trimIndent()) - visit(ktFile) - return items + val ktFile = KtTestCompiler.compileFromContent(code.trimIndent()) + visit(ktFile) + return items } diff --git a/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/util/RuleSetPageCreator.kt b/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/util/RuleSetPageCreator.kt index ab80327fe..7d2907995 100644 --- a/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/util/RuleSetPageCreator.kt +++ b/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/util/RuleSetPageCreator.kt @@ -6,17 +6,17 @@ import io.gitlab.arturbosch.detekt.generator.collection.RuleSetProvider import io.gitlab.arturbosch.detekt.generator.printer.rulesetpage.RuleSetPage internal fun createRuleSetPage(): RuleSetPage { - val rules = createRules() - val ruleSetProvider = RuleSetProvider("style", "style rule set", true, rules.map { it.name }) - return RuleSetPage(ruleSetProvider, rules) + val rules = createRules() + val ruleSetProvider = RuleSetProvider("style", "style rule set", true, rules.map { it.name }) + return RuleSetPage(ruleSetProvider, rules) } internal fun createRules(): List { - val rule1 = Rule("WildcardImport", "a wildcard import", "import foo.*", "import foo.bar", true, "Defect", - "10min", "alias1, alias2", "", listOf(Configuration("conf1", "a config option", "foo"))) - val rule2 = Rule("EqualsNull", "equals null", "", "", false, "", - "", null, "WildcardImport", emptyList()) - val rule3 = Rule("NoUnitKeyword", "removes :Unit", "fun stuff(): Unit {}", - "fun stuff() {}", true, "", "5m", null, "", emptyList(), true) - return listOf(rule1, rule2, rule3) + val rule1 = Rule("WildcardImport", "a wildcard import", "import foo.*", "import foo.bar", true, "Defect", + "10min", "alias1, alias2", "", listOf(Configuration("conf1", "a config option", "foo"))) + val rule2 = Rule("EqualsNull", "equals null", "", "", false, "", + "", null, "WildcardImport", emptyList()) + val rule3 = Rule("NoUnitKeyword", "removes :Unit", "fun stuff(): Unit {}", + "fun stuff() {}", true, "", "5m", null, "", emptyList(), true) + return listOf(rule1, rule2, rule3) } diff --git a/detekt-gradle-plugin/build.gradle.kts b/detekt-gradle-plugin/build.gradle.kts index 21487898d..fed68b8ee 100644 --- a/detekt-gradle-plugin/build.gradle.kts +++ b/detekt-gradle-plugin/build.gradle.kts @@ -2,28 +2,28 @@ import org.gradle.api.tasks.testing.logging.TestExceptionFormat import org.gradle.api.tasks.testing.logging.TestLogEvent buildscript { - repositories { - mavenCentral() - mavenLocal() - jcenter() - } + repositories { + mavenCentral() + mavenLocal() + jcenter() + } } repositories { - gradlePluginPortal() - mavenLocal() - jcenter() + gradlePluginPortal() + mavenLocal() + jcenter() } plugins { - `java-gradle-plugin` - `maven-publish` - id("com.gradle.plugin-publish") version "0.10.0" - id("com.jfrog.bintray") version "1.8.4" - kotlin("jvm") version "1.3.21" - id("org.jetbrains.dokka") version "0.9.17" - id("com.github.ben-manes.versions") version "0.20.0" - id("io.gitlab.arturbosch.detekt") version "1.0.0-RC12" + `java-gradle-plugin` + `maven-publish` + id("com.gradle.plugin-publish") version "0.10.0" + id("com.jfrog.bintray") version "1.8.4" + kotlin("jvm") version "1.3.21" + id("org.jetbrains.dokka") version "0.9.17" + id("com.github.ben-manes.versions") version "0.20.0" + id("io.gitlab.arturbosch.detekt") version "1.0.0-RC12" } group = "io.gitlab.arturbosch.detekt" @@ -36,142 +36,143 @@ val junitPlatformVersion = "1.3.2" val assertjVersion = "3.11.1" dependencies { - implementation(kotlin("stdlib")) + implementation(kotlin("stdlib")) - testImplementation("org.assertj:assertj-core:$assertjVersion") - testImplementation("org.jetbrains.spek:spek-api:$spekVersion") - testImplementation("org.jetbrains.spek:spek-subject-extension:$spekVersion") - testRuntimeOnly("org.junit.platform:junit-platform-launcher:$junitPlatformVersion") - testRuntimeOnly("org.jetbrains.spek:spek-junit-platform-engine:$spekVersion") + testImplementation(kotlin("reflect")) + testImplementation("org.assertj:assertj-core:$assertjVersion") + testImplementation("org.jetbrains.spek:spek-api:$spekVersion") + testImplementation("org.jetbrains.spek:spek-subject-extension:$spekVersion") + testRuntimeOnly("org.junit.platform:junit-platform-launcher:$junitPlatformVersion") + testRuntimeOnly("org.jetbrains.spek:spek-junit-platform-engine:$spekVersion") } gradlePlugin { - plugins { - register("detektPlugin") { - id = "io.gitlab.arturbosch.detekt" - implementationClass = "io.gitlab.arturbosch.detekt.DetektPlugin" - } - } + plugins { + register("detektPlugin") { + id = "io.gitlab.arturbosch.detekt" + implementationClass = "io.gitlab.arturbosch.detekt.DetektPlugin" + } + } } tasks.test { - useJUnitPlatform() - testLogging { - // set options for log level LIFECYCLE - events = setOf( - TestLogEvent.FAILED, - TestLogEvent.PASSED, - TestLogEvent.SKIPPED, - TestLogEvent.STANDARD_OUT - ) - exceptionFormat = TestExceptionFormat.FULL - showExceptions = true - showCauses = true - showStackTraces = true - } + useJUnitPlatform() + testLogging { + // set options for log level LIFECYCLE + events = setOf( + TestLogEvent.FAILED, + TestLogEvent.PASSED, + TestLogEvent.SKIPPED, + TestLogEvent.STANDARD_OUT + ) + exceptionFormat = TestExceptionFormat.FULL + showExceptions = true + showCauses = true + showStackTraces = true + } } tasks.validateTaskProperties { - enableStricterValidation = true + enableStricterValidation = true } pluginBundle { - website = "https://arturbosch.github.io/detekt" - vcsUrl = "https://github.com/arturbosch/detekt" - description = "Static code analysis for Kotlin" - tags = listOf("kotlin", "detekt", "code-analysis", "badsmells", "codesmells") + website = "https://arturbosch.github.io/detekt" + vcsUrl = "https://github.com/arturbosch/detekt" + description = "Static code analysis for Kotlin" + tags = listOf("kotlin", "detekt", "code-analysis", "badsmells", "codesmells") - (plugins) { - "detektPlugin" { - id = "io.gitlab.arturbosch.detekt" - displayName = "Static code analysis for Kotlin" - } - } + (plugins) { + "detektPlugin" { + id = "io.gitlab.arturbosch.detekt" + displayName = "Static code analysis for Kotlin" + } + } } tasks.dokka { - // suppresses undocumented classes but not dokka warnings - // https://github.com/Kotlin/dokka/issues/229 && https://github.com/Kotlin/dokka/issues/319 - reportUndocumented = false - outputFormat = "javadoc" - outputDirectory = "$buildDir/javadoc" + // suppresses undocumented classes but not dokka warnings + // https://github.com/Kotlin/dokka/issues/229 && https://github.com/Kotlin/dokka/issues/319 + reportUndocumented = false + outputFormat = "javadoc" + outputDirectory = "$buildDir/javadoc" } val generateDefaultDetektVersionFile: Task by tasks.creating { - val defaultDetektVersionFile = - File("$buildDir/generated/src/io/gitlab/arturbosch/detekt", "PluginVersion.kt") + val defaultDetektVersionFile = + File("$buildDir/generated/src/io/gitlab/arturbosch/detekt", "PluginVersion.kt") - outputs.file(defaultDetektVersionFile) + outputs.file(defaultDetektVersionFile) - doFirst { - defaultDetektVersionFile.parentFile.mkdirs() - defaultDetektVersionFile.writeText(""" + doFirst { + defaultDetektVersionFile.parentFile.mkdirs() + defaultDetektVersionFile.writeText(""" package io.gitlab.arturbosch.detekt internal const val DEFAULT_DETEKT_VERSION = "$version" """ - .trimIndent() - ) - } + .trimIndent() + ) + } } sourceSets["main"].java.srcDir("$buildDir/generated/src") tasks.compileKotlin { - dependsOn(generateDefaultDetektVersionFile) + dependsOn(generateDefaultDetektVersionFile) } val sourcesJar by tasks.creating(Jar::class) { - dependsOn("classes") - archiveClassifier.set("sources") - from(sourceSets["main"].allSource) + dependsOn("classes") + archiveClassifier.set("sources") + from(sourceSets["main"].allSource) } val javadocJar by tasks.creating(Jar::class) { - dependsOn("dokka") - archiveClassifier.set("javadoc") - from(buildDir.resolve("javadoc")) + dependsOn("dokka") + archiveClassifier.set("javadoc") + from(buildDir.resolve("javadoc")) } artifacts { - archives(sourcesJar) - archives(javadocJar) + archives(sourcesJar) + archives(javadocJar) } detekt { - config = files( - project.rootDir.resolve("../detekt-cli/src/main/resources/default-detekt-config.yml"), - project.rootDir.resolve("../reports/failfast.yml") - ) - filters = ".*/resources/.*,.*/build/.*" + config = files( + project.rootDir.resolve("../detekt-cli/src/main/resources/default-detekt-config.yml"), + project.rootDir.resolve("../reports/failfast.yml") + ) + filters = ".*/resources/.*,.*/build/.*" } publishing { - publications.create("DetektPublication") { - from(components["java"]) - artifact(sourcesJar) - artifact(javadocJar) - groupId = rootProject.group as? String - artifactId = rootProject.name - version = rootProject.version as? String - pom.withXml { - asNode().apply { - appendNode("description", "Static code analysis for Kotlin") - appendNode("name", "detekt") - appendNode("url", "https://github.com/arturbosch/detekt") + publications.create("DetektPublication") { + from(components["java"]) + artifact(sourcesJar) + artifact(javadocJar) + groupId = rootProject.group as? String + artifactId = rootProject.name + version = rootProject.version as? String + pom.withXml { + asNode().apply { + appendNode("description", "Static code analysis for Kotlin") + appendNode("name", "detekt") + appendNode("url", "https://github.com/arturbosch/detekt") - val license = appendNode("licenses").appendNode("license") - license.appendNode("name", "The Apache Software License, Version 2.0") - license.appendNode("url", "http://www.apache.org/licenses/LICENSE-2.0.txt") - license.appendNode("distribution", "repo") + val license = appendNode("licenses").appendNode("license") + license.appendNode("name", "The Apache Software License, Version 2.0") + license.appendNode("url", "http://www.apache.org/licenses/LICENSE-2.0.txt") + license.appendNode("distribution", "repo") - val developer = appendNode("developers").appendNode("developer") - developer.appendNode("id", "Artur Bosch") - developer.appendNode("name", "Artur Bosch") - developer.appendNode("email", "arturbosch@gmx.de") + val developer = appendNode("developers").appendNode("developer") + developer.appendNode("id", "Artur Bosch") + developer.appendNode("name", "Artur Bosch") + developer.appendNode("email", "arturbosch@gmx.de") - appendNode("scm").appendNode("url", "https://github.com/arturbosch/detekt") - } - } - } + appendNode("scm").appendNode("url", "https://github.com/arturbosch/detekt") + } + } + } } diff --git a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/Detekt.kt b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/Detekt.kt index f81541bb6..7bd1ccaad 100644 --- a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/Detekt.kt +++ b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/Detekt.kt @@ -14,6 +14,7 @@ import io.gitlab.arturbosch.detekt.invoke.InputArgument import io.gitlab.arturbosch.detekt.invoke.ParallelArgument import io.gitlab.arturbosch.detekt.invoke.PluginsArgument import io.gitlab.arturbosch.detekt.invoke.XmlReportArgument +import java.io.File import org.gradle.api.Action import org.gradle.api.DefaultTask import org.gradle.api.file.ConfigurableFileCollection @@ -35,7 +36,6 @@ import org.gradle.api.tasks.PathSensitivity import org.gradle.api.tasks.SkipWhenEmpty import org.gradle.api.tasks.TaskAction import org.gradle.language.base.plugins.LifecycleBasePlugin -import java.io.File /** * @author Artur Bosch @@ -45,98 +45,98 @@ import java.io.File @CacheableTask open class Detekt : DefaultTask() { - @InputFiles - @PathSensitive(PathSensitivity.RELATIVE) - @SkipWhenEmpty - var input: ConfigurableFileCollection = project.layout.configurableFiles() + @InputFiles + @PathSensitive(PathSensitivity.RELATIVE) + @SkipWhenEmpty + var input: ConfigurableFileCollection = project.layout.configurableFiles() - @Input - @Optional - var filters: Property = project.objects.property(String::class.java) + @Input + @Optional + var filters: Property = project.objects.property(String::class.java) - @InputFile - @Optional - @PathSensitive(PathSensitivity.RELATIVE) - var baseline: RegularFileProperty = createNewInputFile() + @InputFile + @Optional + @PathSensitive(PathSensitivity.RELATIVE) + var baseline: RegularFileProperty = createNewInputFile() - @InputFiles - @Optional - @PathSensitive(PathSensitivity.RELATIVE) - var config: ConfigurableFileCollection = project.layout.configurableFiles() + @InputFiles + @Optional + @PathSensitive(PathSensitivity.RELATIVE) + var config: ConfigurableFileCollection = project.layout.configurableFiles() - @Input - @Optional - var plugins: Property = project.objects.property(String::class.java) + @Input + @Optional + var plugins: Property = project.objects.property(String::class.java) - @Internal - @Optional - val debugProp: Property = project.objects.property(Boolean::class.javaObjectType) - var debug: Boolean - @Internal - get() = debugProp.get() - set(value) = debugProp.set(value) + @Internal + @Optional + val debugProp: Property = project.objects.property(Boolean::class.javaObjectType) + var debug: Boolean + @Internal + get() = debugProp.get() + set(value) = debugProp.set(value) - @Internal - @Optional - val parallelProp: Property = project.objects.property(Boolean::class.javaObjectType) - var parallel: Boolean - @Internal - get() = parallelProp.get() - set(value) = parallelProp.set(value) + @Internal + @Optional + val parallelProp: Property = project.objects.property(Boolean::class.javaObjectType) + var parallel: Boolean + @Internal + get() = parallelProp.get() + set(value) = parallelProp.set(value) - @Optional - @Input - val disableDefaultRuleSetsProp: Property = project.objects.property(Boolean::class.javaObjectType) - var disableDefaultRuleSets: Boolean - @Internal - get() = disableDefaultRuleSetsProp.get() - set(value) = disableDefaultRuleSetsProp.set(value) + @Optional + @Input + val disableDefaultRuleSetsProp: Property = project.objects.property(Boolean::class.javaObjectType) + var disableDefaultRuleSets: Boolean + @Internal + get() = disableDefaultRuleSetsProp.get() + set(value) = disableDefaultRuleSetsProp.set(value) - @Internal - var reports = DetektReports(project) + @Internal + var reports = DetektReports(project) - fun reports(configure: Action) = configure.execute(reports) + fun reports(configure: Action) = configure.execute(reports) - @Internal - @Optional - var reportsDir: Property = project.objects.property(File::class.java) + @Internal + @Optional + var reportsDir: Property = project.objects.property(File::class.java) - val xmlReportFile: Provider - @OutputFile - @Optional - get() = reports.xml.getTargetFileProvider(effectiveReportsDir) + val xmlReportFile: Provider + @OutputFile + @Optional + get() = reports.xml.getTargetFileProvider(effectiveReportsDir) - val htmlReportFile: Provider - @OutputFile - @Optional - get() = reports.html.getTargetFileProvider(effectiveReportsDir) + val htmlReportFile: Provider + @OutputFile + @Optional + get() = reports.html.getTargetFileProvider(effectiveReportsDir) - private val defaultReportsDir: Directory = project.layout.buildDirectory.get() - .dir(ReportingExtension.DEFAULT_REPORTS_DIR_NAME) - .dir("detekt") + private val defaultReportsDir: Directory = project.layout.buildDirectory.get() + .dir(ReportingExtension.DEFAULT_REPORTS_DIR_NAME) + .dir("detekt") - private val effectiveReportsDir = project.provider { reportsDir.getOrElse(defaultReportsDir.asFile) } + private val effectiveReportsDir = project.provider { reportsDir.getOrElse(defaultReportsDir.asFile) } - init { - group = LifecycleBasePlugin.VERIFICATION_GROUP - } + init { + group = LifecycleBasePlugin.VERIFICATION_GROUP + } - @TaskAction - fun check() { - val arguments = mutableListOf() + - InputArgument(input) + - FiltersArgument(filters.orNull) + - ConfigArgument(config) + - PluginsArgument(plugins.orNull) + - BaselineArgument(baseline.orNull) + - XmlReportArgument(xmlReportFile.orNull) + - HtmlReportArgument(htmlReportFile.orNull) + - DebugArgument(debugProp.getOrElse(false)) + - ParallelArgument(parallelProp.getOrElse(false)) + - DisableDefaultRulesetArgument(disableDefaultRuleSetsProp.getOrElse(false)) + @TaskAction + fun check() { + val arguments = mutableListOf() + + InputArgument(input) + + FiltersArgument(filters.orNull) + + ConfigArgument(config) + + PluginsArgument(plugins.orNull) + + BaselineArgument(baseline.orNull) + + XmlReportArgument(xmlReportFile.orNull) + + HtmlReportArgument(htmlReportFile.orNull) + + DebugArgument(debugProp.getOrElse(false)) + + ParallelArgument(parallelProp.getOrElse(false)) + + DisableDefaultRulesetArgument(disableDefaultRuleSetsProp.getOrElse(false)) - DetektInvoker.invokeCli(project, arguments.toList(), debugProp.getOrElse(false)) - } + DetektInvoker.invokeCli(project, arguments.toList(), debugProp.getOrElse(false)) + } - private fun createNewInputFile() = project.fileProperty() + private fun createNewInputFile() = project.fileProperty() } diff --git a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/DetektCreateBaselineTask.kt b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/DetektCreateBaselineTask.kt index 42f69c881..086a4d152 100644 --- a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/DetektCreateBaselineTask.kt +++ b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/DetektCreateBaselineTask.kt @@ -34,57 +34,57 @@ import org.gradle.language.base.plugins.LifecycleBasePlugin */ open class DetektCreateBaselineTask : DefaultTask() { - init { - description = "Creates a detekt baseline on the given --baseline path." - group = LifecycleBasePlugin.VERIFICATION_GROUP - } + init { + description = "Creates a detekt baseline on the given --baseline path." + group = LifecycleBasePlugin.VERIFICATION_GROUP + } - @OutputFile - @PathSensitive(PathSensitivity.RELATIVE) - var baseline: RegularFileProperty = project.fileProperty() + @OutputFile + @PathSensitive(PathSensitivity.RELATIVE) + var baseline: RegularFileProperty = project.fileProperty() - @InputFiles - @PathSensitive(PathSensitivity.RELATIVE) - @SkipWhenEmpty - var input: ConfigurableFileCollection = project.layout.configurableFiles() + @InputFiles + @PathSensitive(PathSensitivity.RELATIVE) + @SkipWhenEmpty + var input: ConfigurableFileCollection = project.layout.configurableFiles() - @Input - @Optional - var filters: Property = project.objects.property(String::class.java) + @Input + @Optional + var filters: Property = project.objects.property(String::class.java) - @InputFiles - @Optional - @PathSensitive(PathSensitivity.RELATIVE) - var config: ConfigurableFileCollection = project.layout.configurableFiles() + @InputFiles + @Optional + @PathSensitive(PathSensitivity.RELATIVE) + var config: ConfigurableFileCollection = project.layout.configurableFiles() - @Input - @Optional - var plugins: Property = project.objects.property(String::class.java) + @Input + @Optional + var plugins: Property = project.objects.property(String::class.java) - @Internal - @Optional - var debug: Property = project.objects.property(Boolean::class.javaObjectType) + @Internal + @Optional + var debug: Property = project.objects.property(Boolean::class.javaObjectType) - @Internal - @Optional - var parallel: Property = project.objects.property(Boolean::class.javaObjectType) + @Internal + @Optional + var parallel: Property = project.objects.property(Boolean::class.javaObjectType) - @Internal - @Optional - var disableDefaultRuleSets: Property = project.objects.property(Boolean::class.javaObjectType) + @Internal + @Optional + var disableDefaultRuleSets: Property = project.objects.property(Boolean::class.javaObjectType) - @TaskAction - fun baseline() { - val arguments = mutableListOf(CreateBaselineArgument) + - BaselineArgument(baseline.get()) + - InputArgument(input) + - FiltersArgument(filters.orNull) + - ConfigArgument(config) + - PluginsArgument(plugins.orNull) + - DebugArgument(debug.getOrElse(false)) + - ParallelArgument(parallel.getOrElse(false)) + - DisableDefaultRulesetArgument(disableDefaultRuleSets.getOrElse(false)) + @TaskAction + fun baseline() { + val arguments = mutableListOf(CreateBaselineArgument) + + BaselineArgument(baseline.get()) + + InputArgument(input) + + FiltersArgument(filters.orNull) + + ConfigArgument(config) + + PluginsArgument(plugins.orNull) + + DebugArgument(debug.getOrElse(false)) + + ParallelArgument(parallel.getOrElse(false)) + + DisableDefaultRulesetArgument(disableDefaultRuleSets.getOrElse(false)) - DetektInvoker.invokeCli(project, arguments.toList(), debug.getOrElse(false)) - } + DetektInvoker.invokeCli(project, arguments.toList(), debug.getOrElse(false)) + } } diff --git a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/DetektGenerateConfigTask.kt b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/DetektGenerateConfigTask.kt index d43c4465a..41200eb4b 100644 --- a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/DetektGenerateConfigTask.kt +++ b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/DetektGenerateConfigTask.kt @@ -19,21 +19,21 @@ import org.gradle.language.base.plugins.LifecycleBasePlugin */ open class DetektGenerateConfigTask : DefaultTask() { - init { - description = "Generate a detekt configuration file inside your project." - group = LifecycleBasePlugin.VERIFICATION_GROUP - } + init { + description = "Generate a detekt configuration file inside your project." + group = LifecycleBasePlugin.VERIFICATION_GROUP + } - @InputFiles - @PathSensitive(PathSensitivity.RELATIVE) - @SkipWhenEmpty - var input: ConfigurableFileCollection = project.layout.configurableFiles() + @InputFiles + @PathSensitive(PathSensitivity.RELATIVE) + @SkipWhenEmpty + var input: ConfigurableFileCollection = project.layout.configurableFiles() - @TaskAction - fun generateConfig() { - val arguments = mutableListOf(GenerateConfigArgument) + - InputArgument(input) + @TaskAction + fun generateConfig() { + val arguments = mutableListOf(GenerateConfigArgument) + + InputArgument(input) - DetektInvoker.invokeCli(project, arguments.toList()) - } + DetektInvoker.invokeCli(project, arguments.toList()) + } } diff --git a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/DetektIdeaFormatTask.kt b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/DetektIdeaFormatTask.kt index c9183b88a..46d8fc41a 100644 --- a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/DetektIdeaFormatTask.kt +++ b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/DetektIdeaFormatTask.kt @@ -20,29 +20,29 @@ import org.gradle.language.base.plugins.LifecycleBasePlugin */ open class DetektIdeaFormatTask : DefaultTask() { - init { - description = "Uses an external idea installation to format your code." - group = LifecycleBasePlugin.VERIFICATION_GROUP - } + init { + description = "Uses an external idea installation to format your code." + group = LifecycleBasePlugin.VERIFICATION_GROUP + } - @InputFiles - @PathSensitive(PathSensitivity.RELATIVE) - @SkipWhenEmpty - var input: ConfigurableFileCollection = project.layout.configurableFiles() + @InputFiles + @PathSensitive(PathSensitivity.RELATIVE) + @SkipWhenEmpty + var input: ConfigurableFileCollection = project.layout.configurableFiles() - @Internal - @Optional - var debug: Property = project.objects.property(Boolean::class.javaObjectType) + @Internal + @Optional + var debug: Property = project.objects.property(Boolean::class.javaObjectType) - @Internal - lateinit var ideaExtension: IdeaExtension + @Internal + lateinit var ideaExtension: IdeaExtension - @TaskAction - fun format() { - val debugState = debug.getOrElse(false) - if (debugState) { - println("$ideaExtension") - } - startProcess(ideaExtension.formatArgs(input.asPath), debugState) - } + @TaskAction + fun format() { + val debugState = debug.getOrElse(false) + if (debugState) { + println("$ideaExtension") + } + startProcess(ideaExtension.formatArgs(input.asPath), debugState) + } } diff --git a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/DetektIdeaInspectionTask.kt b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/DetektIdeaInspectionTask.kt index 7bea40e09..9edf12421 100644 --- a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/DetektIdeaInspectionTask.kt +++ b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/DetektIdeaInspectionTask.kt @@ -20,30 +20,30 @@ import org.gradle.language.base.plugins.LifecycleBasePlugin */ open class DetektIdeaInspectionTask : DefaultTask() { - init { - description = "Uses an external idea installation to inspect your code." - group = LifecycleBasePlugin.VERIFICATION_GROUP - } + init { + description = "Uses an external idea installation to inspect your code." + group = LifecycleBasePlugin.VERIFICATION_GROUP + } - @InputFiles - @PathSensitive(PathSensitivity.RELATIVE) - @SkipWhenEmpty - var input: ConfigurableFileCollection = project.layout.configurableFiles() + @InputFiles + @PathSensitive(PathSensitivity.RELATIVE) + @SkipWhenEmpty + var input: ConfigurableFileCollection = project.layout.configurableFiles() - @Internal - @Optional - var debug: Property = project.objects.property(Boolean::class.javaObjectType) + @Internal + @Optional + var debug: Property = project.objects.property(Boolean::class.javaObjectType) - @Internal - lateinit var ideaExtension: IdeaExtension + @Internal + lateinit var ideaExtension: IdeaExtension - @TaskAction - fun inspect() { - val debugState = debug.getOrElse(false) - if (debugState) { - println("Running inspection task in debug mode") - println("$ideaExtension") - } - ProcessExecutor.startProcess(ideaExtension.inspectArgs(input.asPath), debugState) - } + @TaskAction + fun inspect() { + val debugState = debug.getOrElse(false) + if (debugState) { + println("Running inspection task in debug mode") + println("$ideaExtension") + } + ProcessExecutor.startProcess(ideaExtension.inspectArgs(input.asPath), debugState) + } } diff --git a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/DetektPlugin.kt b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/DetektPlugin.kt index b90b1df13..437de8856 100644 --- a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/DetektPlugin.kt +++ b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/DetektPlugin.kt @@ -16,102 +16,104 @@ import org.gradle.language.base.plugins.LifecycleBasePlugin */ class DetektPlugin : Plugin { - override fun apply(project: Project) { - val extension = project.extensions.create(DETEKT, DetektExtension::class.java, project) + override fun apply(project: Project) { + val extension = project.extensions.create(DETEKT, DetektExtension::class.java, project) - configurePluginDependencies(project, extension) + configurePluginDependencies(project, extension) - registerDetektTask(project, extension) - registerCreateBaselineTask(project, extension) - registerGenerateConfigTask(project, extension) + registerDetektTask(project, extension) + registerCreateBaselineTask(project, extension) + registerGenerateConfigTask(project, extension) - registerIdeaTasks(project, extension) - } + registerIdeaTasks(project, extension) + } - private fun registerDetektTask(project: Project, extension: DetektExtension) { - val detektTaskProvider = project.tasks.register(DETEKT, Detekt::class.java) { - it.debugProp.set(project.provider { extension.debug }) - it.parallelProp.set(project.provider { extension.parallel }) - it.disableDefaultRuleSetsProp.set(project.provider { extension.disableDefaultRuleSets }) - it.filters.set(project.provider { extension.filters }) - it.config.setFrom(project.provider { extension.config }) - it.baseline.set(project.layout.file(project.provider { extension.baseline })) - it.plugins.set(project.provider { extension.plugins }) - it.input.setFrom(existingInputDirectoriesProvider(project, extension)) - it.reportsDir.set(project.provider { extension.customReportsDir }) - it.reports = extension.reports - } + private fun registerDetektTask(project: Project, extension: DetektExtension) { + val detektTaskProvider = project.tasks.register(DETEKT, Detekt::class.java) { + it.debugProp.set(project.provider { extension.debug }) + it.parallelProp.set(project.provider { extension.parallel }) + it.disableDefaultRuleSetsProp.set(project.provider { extension.disableDefaultRuleSets }) + it.filters.set(project.provider { extension.filters }) + it.config.setFrom(project.provider { extension.config }) + it.baseline.set(project.layout.file(project.provider { extension.baseline })) + it.plugins.set(project.provider { extension.plugins }) + it.input.setFrom(existingInputDirectoriesProvider(project, extension)) + it.reportsDir.set(project.provider { extension.customReportsDir }) + it.reports = extension.reports + } - val checkTaskProvider = try { - project.tasks.named(LifecycleBasePlugin.CHECK_TASK_NAME) - } catch (ignored: UnknownTaskException) { - null - } + val checkTaskProvider = try { + project.tasks.named(LifecycleBasePlugin.CHECK_TASK_NAME) + } catch (ignored: UnknownTaskException) { + null + } - checkTaskProvider?.configure { it.dependsOn(detektTaskProvider) } - } + checkTaskProvider?.configure { it.dependsOn(detektTaskProvider) } + } - private fun registerCreateBaselineTask(project: Project, extension: DetektExtension) = - project.tasks.register(BASELINE, DetektCreateBaselineTask::class.java) { - it.baseline.set(project.layout.file(project.provider { extension.baseline })) - it.config.setFrom(project.provider { extension.config }) - it.debug.set(project.provider { extension.debug }) - it.parallel.set(project.provider { extension.parallel }) - it.disableDefaultRuleSets.set(project.provider { extension.disableDefaultRuleSets }) - it.filters.set(project.provider { extension.filters }) - it.plugins.set(project.provider { extension.plugins }) - it.input.setFrom(existingInputDirectoriesProvider(project, extension)) - } + private fun registerCreateBaselineTask(project: Project, extension: DetektExtension) = + project.tasks.register(BASELINE, DetektCreateBaselineTask::class.java) { + it.baseline.set(project.layout.file(project.provider { extension.baseline })) + it.config.setFrom(project.provider { extension.config }) + it.debug.set(project.provider { extension.debug }) + it.parallel.set(project.provider { extension.parallel }) + it.disableDefaultRuleSets.set(project.provider { extension.disableDefaultRuleSets }) + it.filters.set(project.provider { extension.filters }) + it.plugins.set(project.provider { extension.plugins }) + it.input.setFrom(existingInputDirectoriesProvider(project, extension)) + } - private fun registerGenerateConfigTask(project: Project, extension: DetektExtension) = - project.tasks.register(GENERATE_CONFIG, DetektGenerateConfigTask::class.java) { - it.input.setFrom(existingInputDirectoriesProvider(project, extension)) - } + private fun registerGenerateConfigTask(project: Project, extension: DetektExtension) = + project.tasks.register(GENERATE_CONFIG, DetektGenerateConfigTask::class.java) { + it.input.setFrom(existingInputDirectoriesProvider(project, extension)) + } - private fun registerIdeaTasks(project: Project, extension: DetektExtension) { - project.tasks.register(IDEA_FORMAT, DetektIdeaFormatTask::class.java) { - it.debug.set(project.provider { extension.debug }) - it.input.setFrom(existingInputDirectoriesProvider(project, extension)) - it.ideaExtension = extension.idea - } + private fun registerIdeaTasks(project: Project, extension: DetektExtension) { + project.tasks.register(IDEA_FORMAT, DetektIdeaFormatTask::class.java) { + it.debug.set(project.provider { extension.debug }) + it.input.setFrom(existingInputDirectoriesProvider(project, extension)) + it.ideaExtension = extension.idea + } - project.tasks.register(IDEA_INSPECT, DetektIdeaInspectionTask::class.java) { - it.debug.set(project.provider { extension.debug }) - it.input.setFrom(existingInputDirectoriesProvider(project, extension)) - it.ideaExtension = extension.idea - } - } + project.tasks.register(IDEA_INSPECT, DetektIdeaInspectionTask::class.java) { + it.debug.set(project.provider { extension.debug }) + it.input.setFrom(existingInputDirectoriesProvider(project, extension)) + it.ideaExtension = extension.idea + } + } - private fun existingInputDirectoriesProvider(project: Project, extension: DetektExtension): Provider = - project.provider { extension.input.filter { it.exists() } } + private fun existingInputDirectoriesProvider( + project: Project, + extension: DetektExtension + ): Provider = project.provider { extension.input.filter { it.exists() } } - private fun configurePluginDependencies(project: Project, extension: DetektExtension) { - project.configurations.create(CONFIGURATION_DETEKT_PLUGINS) { configuration -> - configuration.isVisible = false - configuration.isTransitive = true - configuration.description = "The $CONFIGURATION_DETEKT_PLUGINS libraries to be used for this project." - } + private fun configurePluginDependencies(project: Project, extension: DetektExtension) { + project.configurations.create(CONFIGURATION_DETEKT_PLUGINS) { configuration -> + configuration.isVisible = false + configuration.isTransitive = true + configuration.description = "The $CONFIGURATION_DETEKT_PLUGINS libraries to be used for this project." + } - project.configurations.create(CONFIGURATION_DETEKT) { configuration -> - configuration.isVisible = false - configuration.isTransitive = true - configuration.description = "The $CONFIGURATION_DETEKT dependencies to be used for this project." + project.configurations.create(CONFIGURATION_DETEKT) { configuration -> + configuration.isVisible = false + configuration.isTransitive = true + configuration.description = "The $CONFIGURATION_DETEKT dependencies to be used for this project." - configuration.defaultDependencies { dependencySet -> - @Suppress("USELESS_ELVIS") - val version = extension.toolVersion ?: DEFAULT_DETEKT_VERSION - dependencySet.add(project.dependencies.create("io.gitlab.arturbosch.detekt:detekt-cli:$version")) - } - } - } + configuration.defaultDependencies { dependencySet -> + @Suppress("USELESS_ELVIS") + val version = extension.toolVersion ?: DEFAULT_DETEKT_VERSION + dependencySet.add(project.dependencies.create("io.gitlab.arturbosch.detekt:detekt-cli:$version")) + } + } + } - companion object { - private const val DETEKT = "detekt" - private const val IDEA_FORMAT = "detektIdeaFormat" - private const val IDEA_INSPECT = "detektIdeaInspect" - private const val GENERATE_CONFIG = "detektGenerateConfig" - private const val BASELINE = "detektBaseline" - } + companion object { + private const val DETEKT = "detekt" + private const val IDEA_FORMAT = "detektIdeaFormat" + private const val IDEA_INSPECT = "detektIdeaInspect" + private const val GENERATE_CONFIG = "detektGenerateConfig" + private const val BASELINE = "detektBaseline" + } } const val CONFIGURATION_DETEKT = "detekt" diff --git a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/KotlinExtension.kt b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/KotlinExtension.kt index 6807a395d..9e598a550 100644 --- a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/KotlinExtension.kt +++ b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/KotlinExtension.kt @@ -4,4 +4,4 @@ import io.gitlab.arturbosch.detekt.extensions.DetektExtension import org.gradle.api.Project fun Project.detekt(configure: DetektExtension.() -> Unit) = - extensions.configure(DetektExtension::class.java, configure) + extensions.configure(DetektExtension::class.java, configure) diff --git a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/extensions/DetektExtension.kt b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/extensions/DetektExtension.kt index 06bdf70a5..a717e8f70 100644 --- a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/extensions/DetektExtension.kt +++ b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/extensions/DetektExtension.kt @@ -1,10 +1,10 @@ package io.gitlab.arturbosch.detekt.extensions +import java.io.File import org.gradle.api.Action import org.gradle.api.Project import org.gradle.api.file.ConfigurableFileCollection import org.gradle.api.plugins.quality.CodeQualityExtension -import java.io.File /** * @author Artur Bosch @@ -14,38 +14,38 @@ import java.io.File */ open class DetektExtension(project: Project) : CodeQualityExtension() { - val customReportsDir: File? - get() = reportsDir + val customReportsDir: File? + get() = reportsDir - val reports = DetektReports(project) - fun reports(configure: Action) = configure.execute(reports) + val reports = DetektReports(project) + fun reports(configure: Action) = configure.execute(reports) - val idea = IdeaExtension() - fun idea(configure: Action) = configure.execute(idea) + val idea = IdeaExtension() + fun idea(configure: Action) = configure.execute(idea) - var input: ConfigurableFileCollection = project.layout.configurableFiles(DEFAULT_SRC_DIR_JAVA, DEFAULT_SRC_DIR_KOTLIN) + var input: ConfigurableFileCollection = + project.layout.configurableFiles(DEFAULT_SRC_DIR_JAVA, DEFAULT_SRC_DIR_KOTLIN) - var baseline: File? = null + var baseline: File? = null - var config: ConfigurableFileCollection = project.layout.configurableFiles() + var config: ConfigurableFileCollection = project.layout.configurableFiles() - var debug: Boolean = DEFAULT_DEBUG_VALUE + var debug: Boolean = DEFAULT_DEBUG_VALUE - var parallel: Boolean = DEFAULT_PARALLEL_VALUE + var parallel: Boolean = DEFAULT_PARALLEL_VALUE - var disableDefaultRuleSets: Boolean = DEFAULT_DISABLE_RULESETS_VALUE + var disableDefaultRuleSets: Boolean = DEFAULT_DISABLE_RULESETS_VALUE - var filters: String? = null + var filters: String? = null - var plugins: String? = null + var plugins: String? = null - companion object { - const val DEFAULT_SRC_DIR_JAVA = "src/main/java" - const val DEFAULT_SRC_DIR_KOTLIN = "src/main/kotlin" - const val DEFAULT_DEBUG_VALUE = false - const val DEFAULT_PARALLEL_VALUE = false - const val DEFAULT_DISABLE_RULESETS_VALUE = false - const val DEFAULT_REPORT_ENABLED_VALUE = true - } + companion object { + const val DEFAULT_SRC_DIR_JAVA = "src/main/java" + const val DEFAULT_SRC_DIR_KOTLIN = "src/main/kotlin" + const val DEFAULT_DEBUG_VALUE = false + const val DEFAULT_PARALLEL_VALUE = false + const val DEFAULT_DISABLE_RULESETS_VALUE = false + const val DEFAULT_REPORT_ENABLED_VALUE = true + } } - diff --git a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/extensions/DetektReport.kt b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/extensions/DetektReport.kt index 6ef31409d..8644e4da9 100644 --- a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/extensions/DetektReport.kt +++ b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/extensions/DetektReport.kt @@ -1,42 +1,42 @@ package io.gitlab.arturbosch.detekt.extensions import io.gitlab.arturbosch.detekt.internal.fileProperty +import java.io.File import org.gradle.api.Project import org.gradle.api.file.RegularFile import org.gradle.api.provider.Provider -import java.io.File class DetektReport(val type: DetektReportType, private val project: Project) { - var enabled: Boolean? = null + var enabled: Boolean? = null - var destination: File? = null + var destination: File? = null - override fun toString(): String { - return "DetektReport(type='$type', enabled=$enabled, destination=$destination)" - } + override fun toString(): String { + return "DetektReport(type='$type', enabled=$enabled, destination=$destination)" + } - fun getTargetFileProvider(reportsDir: Provider): Provider { - return project.provider { - if (enabled ?: DetektExtension.DEFAULT_REPORT_ENABLED_VALUE) - getTargetFile(reportsDir.get()) - else - null - } - } + fun getTargetFileProvider(reportsDir: Provider): Provider { + return project.provider { + if (enabled ?: DetektExtension.DEFAULT_REPORT_ENABLED_VALUE) + getTargetFile(reportsDir.get()) + else + null + } + } - private fun getTargetFile(reportsDir: File): RegularFile { - val prop = project.fileProperty() - val customDestination = destination - if (customDestination != null) - prop.set(customDestination) - else - prop.set(File(reportsDir, "$DEFAULT_FILENAME.${type.extension}")) + private fun getTargetFile(reportsDir: File): RegularFile { + val prop = project.fileProperty() + val customDestination = destination + if (customDestination != null) + prop.set(customDestination) + else + prop.set(File(reportsDir, "$DEFAULT_FILENAME.${type.extension}")) - return prop.get() - } + return prop.get() + } - companion object { - const val DEFAULT_FILENAME = "detekt" - } + companion object { + const val DEFAULT_FILENAME = "detekt" + } } diff --git a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/extensions/DetektReportType.kt b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/extensions/DetektReportType.kt index 724d3d563..553a43e3b 100644 --- a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/extensions/DetektReportType.kt +++ b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/extensions/DetektReportType.kt @@ -2,6 +2,6 @@ package io.gitlab.arturbosch.detekt.extensions enum class DetektReportType(val extension: String) { - XML("xml"), - HTML("html") + XML("xml"), + HTML("html") } diff --git a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/extensions/DetektReports.kt b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/extensions/DetektReports.kt index 329fc09e8..f5285bfbe 100644 --- a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/extensions/DetektReports.kt +++ b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/extensions/DetektReports.kt @@ -8,13 +8,13 @@ import org.gradle.util.ConfigureUtil class DetektReports(project: Project) { - val xml = DetektReport(XML, project) + val xml = DetektReport(XML, project) - val html = DetektReport(HTML, project) + val html = DetektReport(HTML, project) - fun xml(configure: DetektReport.() -> Unit) = xml.configure() - fun xml(closure: Closure<*>): DetektReport = ConfigureUtil.configure(closure, xml) + fun xml(configure: DetektReport.() -> Unit) = xml.configure() + fun xml(closure: Closure<*>): DetektReport = ConfigureUtil.configure(closure, xml) - fun html(configure: DetektReport.() -> Unit) = html.configure() - fun html(closure: Closure<*>): DetektReport = ConfigureUtil.configure(closure, html) + fun html(configure: DetektReport.() -> Unit) = html.configure() + fun html(closure: Closure<*>): DetektReport = ConfigureUtil.configure(closure, html) } diff --git a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/extensions/IdeaExtension.kt b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/extensions/IdeaExtension.kt index 326cf036c..77c8da8ce 100644 --- a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/extensions/IdeaExtension.kt +++ b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/extensions/IdeaExtension.kt @@ -3,39 +3,41 @@ package io.gitlab.arturbosch.detekt.extensions /** * @author Artur Bosch */ -open class IdeaExtension(open var path: String? = null, - open var codeStyleScheme: String? = null, - open var inspectionsProfile: String? = null, - open var report: String? = null, - open var mask: String = "*.kt") { +open class IdeaExtension( + open var path: String? = null, + open var codeStyleScheme: String? = null, + open var inspectionsProfile: String? = null, + open var report: String? = null, + open var mask: String = "*.kt" +) { - fun formatArgs(input: String): Array { - require(path != null) { IDEA_PATH_ERROR } - return if (codeStyleScheme != null) { - arrayOf(formatScript(path!!), "-r", input, "-s", codeStyleScheme!!, "-m", mask) - } else { - arrayOf(formatScript(path!!), "-r", input, "-m", mask) - } - } + fun formatArgs(input: String): Array { + require(path != null) { IDEA_PATH_ERROR } + return if (codeStyleScheme != null) { + arrayOf(formatScript(path!!), "-r", input, "-s", codeStyleScheme!!, "-m", mask) + } else { + arrayOf(formatScript(path!!), "-r", input, "-m", mask) + } + } - fun inspectArgs(input: String): Array { - require(path != null) { IDEA_PATH_ERROR } - require(report != null) { REPORT_PATH_ERROR } - require(inspectionsProfile != null) { INSPECTION_PROFILE_ERROR } - return arrayOf(inspectScript(path!!), input, inspectionsProfile!!, report!!) - } + fun inspectArgs(input: String): Array { + require(path != null) { IDEA_PATH_ERROR } + require(report != null) { REPORT_PATH_ERROR } + require(inspectionsProfile != null) { INSPECTION_PROFILE_ERROR } + return arrayOf(inspectScript(path!!), input, inspectionsProfile!!, report!!) + } - override fun toString(): String = "IdeaExtension(path=$path, " + - "codeStyleScheme=$codeStyleScheme, inspectionsProfile=$inspectionsProfile, report=$report, mask='$mask')" + override fun toString(): String = "IdeaExtension(path=$path, " + + "codeStyleScheme=$codeStyleScheme, inspectionsProfile=$inspectionsProfile, report=$report, mask='$mask')" } private val isWindows: Boolean = System.getProperty("os.name").contains("Windows") private const val IDEA_PATH_ERROR = "Make sure the idea path is specified to run idea tasks!" private const val REPORT_PATH_ERROR = - "Make sure the report path is specified where idea inspections are stored!" + "Make sure the report path is specified where idea inspections are stored!" private const val INSPECTION_PROFILE_ERROR = - "Make sure the path to an inspection profile is provided!" + "Make sure the path to an inspection profile is provided!" private fun inspectScript(path: String): String = "$path/bin/" + if (isWindows) "inspect.bat" else "inspect.sh" private fun formatScript(path: String): String = "$path/bin/" + if (isWindows) "format.bat" else "format.sh" diff --git a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/internal/GradleCompat.kt b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/internal/GradleCompat.kt index d2abb9a67..72e173f51 100644 --- a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/internal/GradleCompat.kt +++ b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/internal/GradleCompat.kt @@ -5,11 +5,9 @@ import org.gradle.api.file.RegularFileProperty import org.gradle.util.GradleVersion fun Project.fileProperty(): RegularFileProperty { - return if (GradleVersion.current() < GradleVersion.version("5.0")) { - objects.fileProperty() - } else { - layout.fileProperty() - } + return if (GradleVersion.current() < GradleVersion.version("5.0")) { + objects.fileProperty() + } else { + layout.fileProperty() + } } - - diff --git a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/invoke/CliArgument.kt b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/invoke/CliArgument.kt index 18795bda4..829e144a5 100644 --- a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/invoke/CliArgument.kt +++ b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/invoke/CliArgument.kt @@ -16,57 +16,56 @@ private const val GENERATE_CONFIG_PARAMETER = "--generate-config" private const val CREATE_BASELINE_PARAMETER = "--create-baseline" internal sealed class CliArgument { - abstract fun toArgument(): List + abstract fun toArgument(): List } internal object CreateBaselineArgument : CliArgument() { - override fun toArgument() = listOf(CREATE_BASELINE_PARAMETER) + override fun toArgument() = listOf(CREATE_BASELINE_PARAMETER) } internal object GenerateConfigArgument : CliArgument() { - override fun toArgument() = listOf(GENERATE_CONFIG_PARAMETER) + override fun toArgument() = listOf(GENERATE_CONFIG_PARAMETER) } internal data class InputArgument(val fileCollection: FileCollection) : CliArgument() { - override fun toArgument() = listOf(INPUT_PARAMETER, fileCollection.joinToString(",") { it.absolutePath }) + override fun toArgument() = listOf(INPUT_PARAMETER, fileCollection.joinToString(",") { it.absolutePath }) } internal data class FiltersArgument(val filters: String?) : CliArgument() { - override fun toArgument() = filters?.let { listOf(FILTERS_PARAMETER, it) } ?: emptyList() + override fun toArgument() = filters?.let { listOf(FILTERS_PARAMETER, it) } ?: emptyList() } internal data class PluginsArgument(val plugins: String?) : CliArgument() { - override fun toArgument() = plugins?.let { listOf(PLUGINS_PARAMETER, it) } ?: emptyList() + override fun toArgument() = plugins?.let { listOf(PLUGINS_PARAMETER, it) } ?: emptyList() } internal data class BaselineArgument(val baseline: RegularFile?) : CliArgument() { - override fun toArgument() = baseline?.let { listOf(BASELINE_PARAMETER, it.asFile.absolutePath) } ?: emptyList() + override fun toArgument() = baseline?.let { listOf(BASELINE_PARAMETER, it.asFile.absolutePath) } ?: emptyList() } internal data class XmlReportArgument(val file: RegularFile?) : CliArgument() { - override fun toArgument() = file?.let { listOf(REPORT_PARAMETER, "xml:${it.asFile.absoluteFile}") } ?: emptyList() + override fun toArgument() = file?.let { listOf(REPORT_PARAMETER, "xml:${it.asFile.absoluteFile}") } ?: emptyList() } internal data class HtmlReportArgument(val file: RegularFile?) : CliArgument() { - override fun toArgument() = file?.let { listOf(REPORT_PARAMETER, "html:${it.asFile.absolutePath}") } ?: emptyList() + override fun toArgument() = file?.let { listOf(REPORT_PARAMETER, "html:${it.asFile.absolutePath}") } ?: emptyList() } internal data class ConfigArgument(val config: FileCollection) : CliArgument() { - override fun toArgument() = if (config.isEmpty) - emptyList() - else - listOf(CONFIG_PARAMETER, config.joinToString(",") { it.absolutePath }) + override fun toArgument() = if (config.isEmpty) + emptyList() + else + listOf(CONFIG_PARAMETER, config.joinToString(",") { it.absolutePath }) } internal data class DebugArgument(val value: Boolean) : CliArgument() { - override fun toArgument() = if (value) listOf(DEBUG_PARAMETER) else emptyList() + override fun toArgument() = if (value) listOf(DEBUG_PARAMETER) else emptyList() } internal data class ParallelArgument(val value: Boolean) : CliArgument() { - override fun toArgument() = if (value) listOf(PARALLEL_PARAMETER) else emptyList() + override fun toArgument() = if (value) listOf(PARALLEL_PARAMETER) else emptyList() } internal data class DisableDefaultRulesetArgument(val value: Boolean) : CliArgument() { - override fun toArgument() = if (value) listOf(DISABLE_DEFAULT_RULESETS_PARAMETER) else emptyList() + override fun toArgument() = if (value) listOf(DISABLE_DEFAULT_RULESETS_PARAMETER) else emptyList() } - diff --git a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/invoke/DetektInvoker.kt b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/invoke/DetektInvoker.kt index 5397fe2e9..2ddd3de83 100644 --- a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/invoke/DetektInvoker.kt +++ b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/invoke/DetektInvoker.kt @@ -9,25 +9,25 @@ import org.gradle.api.file.FileCollection * @author Marvin Ramin */ object DetektInvoker { - internal fun invokeCli(project: Project, arguments: List, debug: Boolean = false) { - val cliArguments = arguments.map(CliArgument::toArgument).flatten() + internal fun invokeCli(project: Project, arguments: List, debug: Boolean = false) { + val cliArguments = arguments.map(CliArgument::toArgument).flatten() - if (debug) println(cliArguments) - project.javaexec { - it.main = DETEKT_MAIN - it.classpath = getConfigurations(project, debug) - it.args = cliArguments - } - } + if (debug) println(cliArguments) + project.javaexec { + it.main = DETEKT_MAIN + it.classpath = getConfigurations(project, debug) + it.args = cliArguments + } + } - private fun getConfigurations(project: Project, debug: Boolean = false): FileCollection { - val detektConfigurations = setOf(CONFIGURATION_DETEKT_PLUGINS, CONFIGURATION_DETEKT) - val configurations = project.configurations.filter { detektConfigurations.contains(it.name) } + private fun getConfigurations(project: Project, debug: Boolean = false): FileCollection { + val detektConfigurations = setOf(CONFIGURATION_DETEKT_PLUGINS, CONFIGURATION_DETEKT) + val configurations = project.configurations.filter { detektConfigurations.contains(it.name) } - val files = project.files(configurations) - if (debug) files.forEach { println(it) } - return files - } + val files = project.files(configurations) + if (debug) files.forEach { println(it) } + return files + } } private const val DETEKT_MAIN = "io.gitlab.arturbosch.detekt.cli.Main" diff --git a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/invoke/ProcessExecutor.kt b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/invoke/ProcessExecutor.kt index 35c678272..a6502d0ad 100644 --- a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/invoke/ProcessExecutor.kt +++ b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/invoke/ProcessExecutor.kt @@ -10,21 +10,21 @@ import java.io.InputStreamReader * @author Marvin Ramin */ object ProcessExecutor { - fun startProcess(args: Array, debug: Boolean = false) { - val process = Runtime.getRuntime().exec(args) + fun startProcess(args: Array, debug: Boolean = false) { + val process = Runtime.getRuntime().exec(args) - BufferedReader(InputStreamReader(BufferedInputStream(process.inputStream))).use { - val inputs = it.readLines().joinToString("\n") - if (debug) println(inputs) - } + BufferedReader(InputStreamReader(BufferedInputStream(process.inputStream))).use { + val inputs = it.readLines().joinToString("\n") + if (debug) println(inputs) + } - BufferedReader(InputStreamReader(BufferedInputStream(process.errorStream))).use { - val errors = it.readLines().joinToString("\n") - if (errors.isNotEmpty()) { - throw BuildFailure(errors) - } - } + BufferedReader(InputStreamReader(BufferedInputStream(process.errorStream))).use { + val errors = it.readLines().joinToString("\n") + if (errors.isNotEmpty()) { + throw BuildFailure(errors) + } + } - process.destroy() - } + process.destroy() + } } diff --git a/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/CreateBaselineTaskDslTest.kt b/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/CreateBaselineTaskDslTest.kt index f4e5bcd2d..9f893b4a3 100644 --- a/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/CreateBaselineTaskDslTest.kt +++ b/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/CreateBaselineTaskDslTest.kt @@ -10,26 +10,25 @@ import org.jetbrains.spek.api.dsl.it * @author Markus Schwarz */ internal class CreateBaselineTaskDslTest : Spek({ - describe("The detektBaseline task of the Detekt Gradle plugin") { - listOf(DslTestBuilder.groovy(), DslTestBuilder.kotlin()).forEach { builder -> - describe("using ${builder.gradleBuildName}") { - it("can be executed when baseline file is specified") { - val detektConfig = """ + describe("The detektBaseline task of the Detekt Gradle plugin") { + listOf(DslTestBuilder.groovy(), DslTestBuilder.kotlin()).forEach { builder -> + describe("using ${builder.gradleBuildName}") { + it("can be executed when baseline file is specified") { + val detektConfig = """ |detekt { | baseline = file("build/baseline.xml") |} """ - val gradleRunner = builder - .withDetektConfig(detektConfig) - .build() + val gradleRunner = builder + .withDetektConfig(detektConfig) + .build() - gradleRunner.runTasksAndCheckResult("detektBaseline") { result -> - assertThat(result.task(":detektBaseline")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - assertThat(projectFile("build/baseline.xml")).exists() - } - - } - } - } - } + gradleRunner.runTasksAndCheckResult("detektBaseline") { result -> + assertThat(result.task(":detektBaseline")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(projectFile("build/baseline.xml")).exists() + } + } + } + } + } }) diff --git a/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/DetektTaskDslTest.kt b/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/DetektTaskDslTest.kt index 5694fb0aa..69e8495ad 100644 --- a/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/DetektTaskDslTest.kt +++ b/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/DetektTaskDslTest.kt @@ -14,135 +14,134 @@ import org.jetbrains.spek.api.dsl.it */ internal class DetektTaskDslTest : Spek({ - describe("When applying the detekt gradle plugin") { - listOf(groovy(), kotlin()).forEach { builder -> - describe("using ${builder.gradleBuildName}") { - it("can be applied without any configuration using its task name") { + describe("When applying the detekt gradle plugin") { + listOf(groovy(), kotlin()).forEach { builder -> + describe("using ${builder.gradleBuildName}") { + it("can be applied without any configuration using its task name") { - val gradleRunner = builder.build() - gradleRunner.runDetektTaskAndCheckResult { result -> - assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - assertThat(result.output).contains("number of classes: 1") - assertThat(projectFile("build/reports/detekt/detekt.xml")).exists() - assertThat(projectFile("build/reports/detekt/detekt.html")).exists() - } - } + val gradleRunner = builder.build() + gradleRunner.runDetektTaskAndCheckResult { result -> + assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(result.output).contains("number of classes: 1") + assertThat(projectFile("build/reports/detekt/detekt.xml")).exists() + assertThat(projectFile("build/reports/detekt/detekt.html")).exists() + } + } - it("can be applied without any configuration using the check task") { + it("can be applied without any configuration using the check task") { - val gradleRunner = builder.build() - gradleRunner.runTasksAndCheckResult("check") { result -> - assertThat(result.task(":check")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - assertThat(result.output).contains("number of classes: 1") - assertThat(result.output).contains("Ruleset: comments") - } + val gradleRunner = builder.build() + gradleRunner.runTasksAndCheckResult("check") { result -> + assertThat(result.task(":check")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(result.output).contains("number of classes: 1") + assertThat(result.output).contains("Ruleset: comments") + } + } - } + it("can use a custom tool version") { - it("can use a custom tool version") { - - val customVersion = "1.0.0.RC8" - val config = """ + val customVersion = "1.0.0.RC8" + val config = """ |detekt { | toolVersion = "$customVersion" |} """ - val gradleRunner = builder.withDetektConfig(config).build() - gradleRunner.runTasksAndCheckResult("dependencies", "--configuration", "detekt") { result -> - assertThat(result.task(":dependencies")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - assertThat(result.output).contains("io.gitlab.arturbosch.detekt:detekt-cli:$customVersion") - } - } + val gradleRunner = builder.withDetektConfig(config).build() + gradleRunner.runTasksAndCheckResult("dependencies", "--configuration", "detekt") { result -> + assertThat(result.task(":dependencies")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(result.output).contains("io.gitlab.arturbosch.detekt:detekt-cli:$customVersion") + } + } - it("can be applied with multiple config files") { + it("can be applied with multiple config files") { - val config = """ + val config = """ |detekt { | config = files("firstConfig.yml", "secondConfig.yml") |} """ - val gradleRunner = builder.withDetektConfig(config).build() + val gradleRunner = builder.withDetektConfig(config).build() - val firstConfig = gradleRunner.projectFile("firstConfig.yml").apply { createNewFile() } - val secondConfig = gradleRunner.projectFile("secondConfig.yml").apply { createNewFile() } + val firstConfig = gradleRunner.projectFile("firstConfig.yml").apply { createNewFile() } + val secondConfig = gradleRunner.projectFile("secondConfig.yml").apply { createNewFile() } - gradleRunner.runDetektTaskAndCheckResult { result -> - assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - val expectedConfigParam = "--config ${firstConfig.absolutePath},${secondConfig.absolutePath}" - assertThat(result.output).contains(expectedConfigParam) - } - } + gradleRunner.runDetektTaskAndCheckResult { result -> + assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + val expectedConfigParam = "--config ${firstConfig.absolutePath},${secondConfig.absolutePath}" + assertThat(result.output).contains(expectedConfigParam) + } + } - it("can be applied with custom input directories ignoring non existent") { + it("can be applied with custom input directories ignoring non existent") { - val customSrc = "gensrc/kotlin" - val config = """ + val customSrc = "gensrc/kotlin" + val config = """ |detekt { - | input = files("${customSrc}", "folder_that_does_not_exist") + | input = files("$customSrc", "folder_that_does_not_exist") |} """ - val gradleRunner = builder - .withProjectLayout(ProjectLayout(1, srcDirs = listOf(customSrc))) - .withDetektConfig(config) - .build() + val gradleRunner = builder + .withProjectLayout(ProjectLayout(1, srcDirs = listOf(customSrc))) + .withDetektConfig(config) + .build() - gradleRunner.runDetektTaskAndCheckResult() { result -> + gradleRunner.runDetektTaskAndCheckResult() { result -> - assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - val expectedInputParam = "--input ${projectFile(customSrc).absolutePath}" - assertThat(result.output).contains(expectedInputParam) - assertThat(result.output).doesNotContain("folder_that_does_not_exist") - } - } - it("can be applied with classes in multiple custom input directories") { + assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + val expectedInputParam = "--input ${projectFile(customSrc).absolutePath}" + assertThat(result.output).contains(expectedInputParam) + assertThat(result.output).doesNotContain("folder_that_does_not_exist") + } + } + it("can be applied with classes in multiple custom input directories") { - val customSrc1 = "gensrc/kotlin" - val customSrc2 = "src/main/kotlin" - val config = """ + val customSrc1 = "gensrc/kotlin" + val customSrc2 = "src/main/kotlin" + val config = """ |detekt { | input = files("$customSrc1", "$customSrc2") |} """ - val projectLayout = ProjectLayout(1, srcDirs = listOf(customSrc1, customSrc2)) - val gradleRunner = builder - .withProjectLayout(projectLayout) - .withDetektConfig(config) - .build() + val projectLayout = ProjectLayout(1, srcDirs = listOf(customSrc1, customSrc2)) + val gradleRunner = builder + .withProjectLayout(projectLayout) + .withDetektConfig(config) + .build() - gradleRunner.runDetektTaskAndCheckResult() { result -> + gradleRunner.runDetektTaskAndCheckResult() { result -> - assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - val expectedInputParam = - "--input ${projectFile(customSrc1).absolutePath},${projectFile(customSrc2).absolutePath}" - assertThat(result.output).contains(expectedInputParam) - assertThat(result.output).contains("number of classes: 2") - } - } - it("can change the general reports dir") { + assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + val expectedInputParam = + "--input ${projectFile(customSrc1).absolutePath},${projectFile(customSrc2).absolutePath}" + assertThat(result.output).contains(expectedInputParam) + assertThat(result.output).contains("number of classes: 2") + } + } + it("can change the general reports dir") { - val config = """ + val config = """ |detekt { | reportsDir = file("build/detekt-reports") |} """ - val gradleRunner = builder - .withDetektConfig(config) - .build() + val gradleRunner = builder + .withDetektConfig(config) + .build() - gradleRunner.runDetektTaskAndCheckResult() { result -> - assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - assertThat(projectFile("build/detekt-reports/detekt.xml")).exists() - assertThat(projectFile("build/detekt-reports/detekt.html")).exists() - } - } - it("can change the general reports dir but overwrite single report") { + gradleRunner.runDetektTaskAndCheckResult() { result -> + assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(projectFile("build/detekt-reports/detekt.xml")).exists() + assertThat(projectFile("build/detekt-reports/detekt.html")).exists() + } + } + it("can change the general reports dir but overwrite single report") { - val config = """ + val config = """ |detekt { | reportsDir = file("build/detekt-reports") | reports { @@ -151,19 +150,19 @@ internal class DetektTaskDslTest : Spek({ |} """ - val gradleRunner = builder - .withDetektConfig(config) - .build() + val gradleRunner = builder + .withDetektConfig(config) + .build() - gradleRunner.runDetektTaskAndCheckResult() { result -> - assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - assertThat(projectFile("build/xml-reports/custom-detekt.xml")).exists() - assertThat(projectFile("build/detekt-reports/detekt.html")).exists() - } - } - it("can disable reports") { + gradleRunner.runDetektTaskAndCheckResult() { result -> + assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(projectFile("build/xml-reports/custom-detekt.xml")).exists() + assertThat(projectFile("build/detekt-reports/detekt.html")).exists() + } + } + it("can disable reports") { - val config = """ + val config = """ |detekt { | reports { | xml.enabled = false @@ -174,19 +173,19 @@ internal class DetektTaskDslTest : Spek({ |} """ - val gradleRunner = builder - .withDetektConfig(config) - .build() + val gradleRunner = builder + .withDetektConfig(config) + .build() - gradleRunner.runDetektTaskAndCheckResult() { result -> - assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - assertThat(projectFile("build/reports/detekt/detekt.xml")).doesNotExist() - assertThat(projectFile("build/reports/detekt/detekt.html")).doesNotExist() - } - } - it("can change all flags") { + gradleRunner.runDetektTaskAndCheckResult() { result -> + assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(projectFile("build/reports/detekt/detekt.xml")).doesNotExist() + assertThat(projectFile("build/reports/detekt/detekt.html")).doesNotExist() + } + } + it("can change all flags") { - val config = """ + val config = """ |detekt { | debug = true | parallel = true @@ -194,82 +193,81 @@ internal class DetektTaskDslTest : Spek({ |} """ - val gradleRunner = builder - .withDetektConfig(config) - .build() + val gradleRunner = builder + .withDetektConfig(config) + .build() - gradleRunner.runDetektTaskAndCheckResult() { result -> - assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - assertThat(result.output).contains("--debug", "--parallel", "--disable-default-rulesets") - } - } - it("can ignore tests by using filters") { + gradleRunner.runDetektTaskAndCheckResult() { result -> + assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(result.output).contains("--debug", "--parallel", "--disable-default-rulesets") + } + } + it("can ignore tests by using filters") { - val config = """ + val config = """ |detekt { | input = files("${"$"}projectDir") | filters = ".*/test/.*" |} """ - val projectLayout = ProjectLayout(1, srcDirs = listOf("src/main/kotlin", "src/test/kotlin")) + val projectLayout = ProjectLayout(1, srcDirs = listOf("src/main/kotlin", "src/test/kotlin")) - val gradleRunner = builder - .withDetektConfig(config) - .withProjectLayout(projectLayout) - .build() + val gradleRunner = builder + .withDetektConfig(config) + .withProjectLayout(projectLayout) + .build() - gradleRunner.runDetektTaskAndCheckResult() { result -> - assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - assertThat(result.output).contains("number of classes: 1") - } - } - it("allows setting a baseline file") { + gradleRunner.runDetektTaskAndCheckResult() { result -> + assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(result.output).contains("number of classes: 1") + } + } + it("allows setting a baseline file") { - val baselineFilename = "detekt-baseline.xml" + val baselineFilename = "detekt-baseline.xml" - val config = """ + val config = """ |detekt { | baseline = file("$baselineFilename") |} """ - val gradleRunner = builder - .withDetektConfig(config) - .withBaseline(baselineFilename) - .build() + val gradleRunner = builder + .withDetektConfig(config) + .withBaseline(baselineFilename) + .build() - gradleRunner.runDetektTaskAndCheckResult() { result -> - assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - val expectedBaselineArgument = "--baseline ${projectFile(baselineFilename).absolutePath}" - assertThat(result.output).contains(expectedBaselineArgument) - } - } - it("can be used with formatting plugin") { + gradleRunner.runDetektTaskAndCheckResult() { result -> + assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + val expectedBaselineArgument = "--baseline ${projectFile(baselineFilename).absolutePath}" + assertThat(result.output).contains(expectedBaselineArgument) + } + } + it("can be used with formatting plugin") { - val config = """ + val config = """ |dependencies { - | detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:${VERSION_UNDER_TEST}") + | detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:$VERSION_UNDER_TEST") |} """ - val gradleRunner = builder - .withDetektConfig(config) - .build() + val gradleRunner = builder + .withDetektConfig(config) + .build() - gradleRunner.runTasksAndCheckResult("dependencies", "--configuration", "detektPlugins") { result -> - assertThat(result.task(":dependencies")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - assertThat(result.output).contains("io.gitlab.arturbosch.detekt:detekt-formatting:${VERSION_UNDER_TEST}") - } + gradleRunner.runTasksAndCheckResult("dependencies", "--configuration", "detektPlugins") { result -> + assertThat(result.task(":dependencies")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(result.output).contains("io.gitlab.arturbosch.detekt:detekt-formatting:$VERSION_UNDER_TEST") + } + } + } + } - } - } - } + describe("and creating a custom task") { + it("can be done using the groovy dsl") { - describe("and creating a custom task") { - it("can be done using the groovy dsl") { - - val config = """ + val config = """ |task detektFailFast(type: io.gitlab.arturbosch.detekt.Detekt) { | description = "Runs a failfast detekt build." | @@ -288,19 +286,19 @@ internal class DetektTaskDslTest : Spek({ |} """ - val gradleRunner = groovy().withDetektConfig(config).build() - gradleRunner.writeProjectFile("config.yml", "") + val gradleRunner = groovy().withDetektConfig(config).build() + gradleRunner.writeProjectFile("config.yml", "") - gradleRunner.runTasksAndCheckResult("detektFailFast") { result -> - assertThat(result.task(":detektFailFast")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - assertThat(projectFile("build/reports/failfast.xml")).exists() - assertThat(projectFile("build/reports/failfast.html")).exists() - } - } + gradleRunner.runTasksAndCheckResult("detektFailFast") { result -> + assertThat(result.task(":detektFailFast")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(projectFile("build/reports/failfast.xml")).exists() + assertThat(projectFile("build/reports/failfast.html")).exists() + } + } - it("can be done using the kotlin dsl") { + it("can be done using the kotlin dsl") { - val config = """ + val config = """ |task("detektFailFast") { | description = "Runs a failfast detekt build." | @@ -319,15 +317,14 @@ internal class DetektTaskDslTest : Spek({ |} """ - val gradleRunner = kotlin().withDetektConfig(config).build() - gradleRunner.writeProjectFile("config.yml", "") - gradleRunner.runTasksAndCheckResult("detektFailFast") { result -> - assertThat(result.task(":detektFailFast")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - assertThat(gradleRunner.projectFile("build/reports/failfast.xml")).exists() - assertThat(gradleRunner.projectFile("build/reports/failfast.html")).exists() - } - } - - } - } + val gradleRunner = kotlin().withDetektConfig(config).build() + gradleRunner.writeProjectFile("config.yml", "") + gradleRunner.runTasksAndCheckResult("detektFailFast") { result -> + assertThat(result.task(":detektFailFast")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(gradleRunner.projectFile("build/reports/failfast.xml")).exists() + assertThat(gradleRunner.projectFile("build/reports/failfast.html")).exists() + } + } + } + } }) diff --git a/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/DetektTaskMultiModuleTest.kt b/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/DetektTaskMultiModuleTest.kt index 01db479ec..9b35f45d9 100644 --- a/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/DetektTaskMultiModuleTest.kt +++ b/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/DetektTaskMultiModuleTest.kt @@ -14,36 +14,36 @@ const val SOURCE_DIRECTORY = "src/main/java" * @author Markus Schwarz */ internal class DetektTaskMultiModuleTest : Spek({ - describe("The Detekt Gradle plugin used in a multi module project") { - describe("is applied with defaults to all subprojects individually without sources in root project using the" + - " " + - "subprojects block") { - val projectLayout = ProjectLayout(0) - .withSubmodule("child1", 2) - .withSubmodule("child2", 4) + describe("The Detekt Gradle plugin used in a multi module project") { + describe("is applied with defaults to all subprojects individually without sources in root project using the" + + " " + + "subprojects block") { + val projectLayout = ProjectLayout(0) + .withSubmodule("child1", 2) + .withSubmodule("child2", 4) - lateinit var gradleRunner: DslGradleRunner + lateinit var gradleRunner: DslGradleRunner - afterEachTest { - gradleRunner.setupProject() - gradleRunner.runDetektTaskAndCheckResult { result -> - assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.NO_SOURCE) - projectLayout.submodules.forEach { submodule -> - assertThat(result.task(":${submodule.name}:detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - assertThat(result.output).contains("number of classes: ${submodule.numberOfSourceFiles}") - } + afterEachTest { + gradleRunner.setupProject() + gradleRunner.runDetektTaskAndCheckResult { result -> + assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.NO_SOURCE) + projectLayout.submodules.forEach { submodule -> + assertThat(result.task(":${submodule.name}:detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(result.output).contains("number of classes: ${submodule.numberOfSourceFiles}") + } - assertThat(projectFile("build/reports/detekt/detekt.xml")).doesNotExist() - assertThat(projectFile("build/reports/detekt/detekt.html")).doesNotExist() - projectLayout.submodules.forEach { - assertThat(projectFile("${it.name}/build/reports/detekt/detekt.xml")).exists() - assertThat(projectFile("${it.name}/build/reports/detekt/detekt.html")).exists() - } - } - } - it("can be done using the groovy dsl") { + assertThat(projectFile("build/reports/detekt/detekt.xml")).doesNotExist() + assertThat(projectFile("build/reports/detekt/detekt.html")).doesNotExist() + projectLayout.submodules.forEach { + assertThat(projectFile("${it.name}/build/reports/detekt/detekt.xml")).exists() + assertThat(projectFile("${it.name}/build/reports/detekt/detekt.html")).exists() + } + } + } + it("can be done using the groovy dsl") { - val mainBuildFileContent: String = """ + val mainBuildFileContent: String = """ |import io.gitlab.arturbosch.detekt.DetektPlugin | |plugins { @@ -63,11 +63,11 @@ internal class DetektTaskMultiModuleTest : Spek({ |} """.trimMargin() - gradleRunner = DslGradleRunner(projectLayout, "build.gradle", mainBuildFileContent) - } - it("can be done using the kotlin dsl") { + gradleRunner = DslGradleRunner(projectLayout, "build.gradle", mainBuildFileContent) + } + it("can be done using the kotlin dsl") { - val mainBuildFileContent: String = """ + val mainBuildFileContent: String = """ |import io.gitlab.arturbosch.detekt.detekt | |plugins { @@ -87,36 +87,36 @@ internal class DetektTaskMultiModuleTest : Spek({ |} """.trimMargin() - gradleRunner = DslGradleRunner(projectLayout, "build.gradle.kts", mainBuildFileContent) - } - } - describe("is applied with defaults to main project and subprojects individually using the allprojects block") { - val projectLayout = ProjectLayout(1) - .withSubmodule("child1", 2) - .withSubmodule("child2", 4) + gradleRunner = DslGradleRunner(projectLayout, "build.gradle.kts", mainBuildFileContent) + } + } + describe("is applied with defaults to main project and subprojects individually using the allprojects block") { + val projectLayout = ProjectLayout(1) + .withSubmodule("child1", 2) + .withSubmodule("child2", 4) - lateinit var gradleRunner: DslGradleRunner + lateinit var gradleRunner: DslGradleRunner - afterEachTest { - gradleRunner.setupProject() - gradleRunner.runDetektTaskAndCheckResult { result -> - assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - projectLayout.submodules.forEach { submodule -> - assertThat(result.task(":${submodule.name}:detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - assertThat(result.output).contains("number of classes: ${submodule.numberOfSourceFiles}") - } + afterEachTest { + gradleRunner.setupProject() + gradleRunner.runDetektTaskAndCheckResult { result -> + assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + projectLayout.submodules.forEach { submodule -> + assertThat(result.task(":${submodule.name}:detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(result.output).contains("number of classes: ${submodule.numberOfSourceFiles}") + } - assertThat(projectFile("build/reports/detekt/detekt.xml")).exists() - assertThat(projectFile("build/reports/detekt/detekt.html")).exists() - projectLayout.submodules.forEach { - assertThat(projectFile("${it.name}/build/reports/detekt/detekt.xml")).exists() - assertThat(projectFile("${it.name}/build/reports/detekt/detekt.html")).exists() - } - } - } - it("can be done using the groovy dsl") { + assertThat(projectFile("build/reports/detekt/detekt.xml")).exists() + assertThat(projectFile("build/reports/detekt/detekt.html")).exists() + projectLayout.submodules.forEach { + assertThat(projectFile("${it.name}/build/reports/detekt/detekt.xml")).exists() + assertThat(projectFile("${it.name}/build/reports/detekt/detekt.html")).exists() + } + } + } + it("can be done using the groovy dsl") { - val mainBuildFileContent: String = """ + val mainBuildFileContent: String = """ |import io.gitlab.arturbosch.detekt.DetektPlugin | |plugins { @@ -134,11 +134,11 @@ internal class DetektTaskMultiModuleTest : Spek({ |} """.trimMargin() - gradleRunner = DslGradleRunner(projectLayout, "build.gradle", mainBuildFileContent) - } - it("can be done using the kotlin dsl") { + gradleRunner = DslGradleRunner(projectLayout, "build.gradle", mainBuildFileContent) + } + it("can be done using the kotlin dsl") { - val mainBuildFileContent: String = """ + val mainBuildFileContent: String = """ |import io.gitlab.arturbosch.detekt.detekt | |plugins { @@ -156,35 +156,35 @@ internal class DetektTaskMultiModuleTest : Spek({ |} """.trimMargin() - gradleRunner = DslGradleRunner(projectLayout, "build.gradle.kts", mainBuildFileContent) - } - } - describe("uses custom configs when configured in allprojects block") { - val projectLayout = ProjectLayout(1) - .withSubmodule("child1", 2) - .withSubmodule("child2", 4) + gradleRunner = DslGradleRunner(projectLayout, "build.gradle.kts", mainBuildFileContent) + } + } + describe("uses custom configs when configured in allprojects block") { + val projectLayout = ProjectLayout(1) + .withSubmodule("child1", 2) + .withSubmodule("child2", 4) - lateinit var gradleRunner: DslGradleRunner + lateinit var gradleRunner: DslGradleRunner - afterEachTest { - gradleRunner.setupProject() - gradleRunner.runDetektTaskAndCheckResult { result -> - assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - projectLayout.submodules.forEach { submodule -> - assertThat(result.task(":${submodule.name}:detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - } + afterEachTest { + gradleRunner.setupProject() + gradleRunner.runDetektTaskAndCheckResult { result -> + assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + projectLayout.submodules.forEach { submodule -> + assertThat(result.task(":${submodule.name}:detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + } - assertThat(projectFile("build/detekt-reports/detekt.xml")).exists() - assertThat(projectFile("build/detekt-reports/detekt.html")).exists() - projectLayout.submodules.forEach { - assertThat(projectFile("${it.name}/build/detekt-reports/detekt.xml")).exists() - assertThat(projectFile("${it.name}/build/detekt-reports/detekt.html")).exists() - } - } - } - it("can be done using the groovy dsl") { + assertThat(projectFile("build/detekt-reports/detekt.xml")).exists() + assertThat(projectFile("build/detekt-reports/detekt.html")).exists() + projectLayout.submodules.forEach { + assertThat(projectFile("${it.name}/build/detekt-reports/detekt.xml")).exists() + assertThat(projectFile("${it.name}/build/detekt-reports/detekt.html")).exists() + } + } + } + it("can be done using the groovy dsl") { - val mainBuildFileContent: String = """ + val mainBuildFileContent: String = """ |import io.gitlab.arturbosch.detekt.DetektPlugin | |plugins { @@ -205,11 +205,11 @@ internal class DetektTaskMultiModuleTest : Spek({ |} """.trimMargin() - gradleRunner = DslGradleRunner(projectLayout, "build.gradle", mainBuildFileContent) - } - it("can be done using the kotlin dsl") { + gradleRunner = DslGradleRunner(projectLayout, "build.gradle", mainBuildFileContent) + } + it("can be done using the kotlin dsl") { - val mainBuildFileContent: String = """ + val mainBuildFileContent: String = """ |import io.gitlab.arturbosch.detekt.detekt | |plugins { @@ -230,40 +230,40 @@ internal class DetektTaskMultiModuleTest : Spek({ |} """.trimMargin() - gradleRunner = DslGradleRunner(projectLayout, "build.gradle.kts", mainBuildFileContent) - } - } - describe("allows changing defaults in allprojects block that can be overwritten in subprojects") { - val child2DetektConfig = """ + gradleRunner = DslGradleRunner(projectLayout, "build.gradle.kts", mainBuildFileContent) + } + } + describe("allows changing defaults in allprojects block that can be overwritten in subprojects") { + val child2DetektConfig = """ | detekt { | reportsDir = file("build/custom") | } """.trimMargin() - val projectLayout = ProjectLayout(1) - .withSubmodule("child1", 2) - .withSubmodule("child2", 4, detektConfig = child2DetektConfig) + val projectLayout = ProjectLayout(1) + .withSubmodule("child1", 2) + .withSubmodule("child2", 4, detektConfig = child2DetektConfig) - lateinit var gradleRunner: DslGradleRunner + lateinit var gradleRunner: DslGradleRunner - afterEachTest { - gradleRunner.setupProject() - gradleRunner.runDetektTaskAndCheckResult { result -> - assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - projectLayout.submodules.forEach { submodule -> - assertThat(result.task(":${submodule.name}:detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - } + afterEachTest { + gradleRunner.setupProject() + gradleRunner.runDetektTaskAndCheckResult { result -> + assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + projectLayout.submodules.forEach { submodule -> + assertThat(result.task(":${submodule.name}:detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + } - assertThat(projectFile("build/detekt-reports/detekt.xml")).exists() - assertThat(projectFile("build/detekt-reports/detekt.html")).exists() - assertThat(projectFile("child1/build/detekt-reports/detekt.xml")).exists() - assertThat(projectFile("child1/build/detekt-reports/detekt.html")).exists() - assertThat(projectFile("child2/build/custom/detekt.xml")).exists() - assertThat(projectFile("child2/build/custom/detekt.html")).exists() - } - } - it("can be done using the groovy dsl") { + assertThat(projectFile("build/detekt-reports/detekt.xml")).exists() + assertThat(projectFile("build/detekt-reports/detekt.html")).exists() + assertThat(projectFile("child1/build/detekt-reports/detekt.xml")).exists() + assertThat(projectFile("child1/build/detekt-reports/detekt.html")).exists() + assertThat(projectFile("child2/build/custom/detekt.xml")).exists() + assertThat(projectFile("child2/build/custom/detekt.html")).exists() + } + } + it("can be done using the groovy dsl") { - val mainBuildFileContent: String = """ + val mainBuildFileContent: String = """ |import io.gitlab.arturbosch.detekt.DetektPlugin | |plugins { @@ -284,11 +284,11 @@ internal class DetektTaskMultiModuleTest : Spek({ |} """.trimMargin() - gradleRunner = DslGradleRunner(projectLayout, "build.gradle", mainBuildFileContent) - } - it("can be done using the kotlin dsl") { + gradleRunner = DslGradleRunner(projectLayout, "build.gradle", mainBuildFileContent) + } + it("can be done using the kotlin dsl") { - val mainBuildFileContent: String = """ + val mainBuildFileContent: String = """ |import io.gitlab.arturbosch.detekt.detekt | |plugins { @@ -309,44 +309,44 @@ internal class DetektTaskMultiModuleTest : Spek({ |} """.trimMargin() - gradleRunner = DslGradleRunner(projectLayout, "build.gradle.kts", mainBuildFileContent) - } - } - listOf(groovy(), kotlin()).forEach { builder -> - val projectLayout = ProjectLayout(1) - .withSubmodule("child1", 2) - .withSubmodule("child2", 4) + gradleRunner = DslGradleRunner(projectLayout, "build.gradle.kts", mainBuildFileContent) + } + } + listOf(groovy(), kotlin()).forEach { builder -> + val projectLayout = ProjectLayout(1) + .withSubmodule("child1", 2) + .withSubmodule("child2", 4) - val detektConfig: String = """ + val detektConfig: String = """ |detekt { | input = files("${"$"}projectDir") | filters = ".*build.gradle.kts" |} """.trimMargin() - val gradleRunner = builder - .withProjectLayout(projectLayout) - .withDetektConfig(detektConfig) - .build() + val gradleRunner = builder + .withProjectLayout(projectLayout) + .withDetektConfig(detektConfig) + .build() - describe("can be used in ${builder.gradleBuildName}") { - it("can be applied to all files in entire project resulting in 1 report") { - gradleRunner.runDetektTaskAndCheckResult { result -> - assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - projectLayout.submodules.forEach { submodule -> - assertThat(result.task(":${submodule.name}:detekt")).isNull() - } + describe("can be used in ${builder.gradleBuildName}") { + it("can be applied to all files in entire project resulting in 1 report") { + gradleRunner.runDetektTaskAndCheckResult { result -> + assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + projectLayout.submodules.forEach { submodule -> + assertThat(result.task(":${submodule.name}:detekt")).isNull() + } - assertThat(result.output).contains("number of classes: 7") + assertThat(result.output).contains("number of classes: 7") - assertThat(projectFile("build/reports/detekt/detekt.xml")).exists() - assertThat(projectFile("build/reports/detekt/detekt.html")).exists() - projectLayout.submodules.forEach { submodule -> - assertThat(projectFile("${submodule.name}/build/reports/detekt/detekt.xml")).doesNotExist() - assertThat(projectFile("${submodule.name}/build/reports/detekt/detekt.html")).doesNotExist() - } - } - } - } - } - } + assertThat(projectFile("build/reports/detekt/detekt.xml")).exists() + assertThat(projectFile("build/reports/detekt/detekt.html")).exists() + projectLayout.submodules.forEach { submodule -> + assertThat(projectFile("${submodule.name}/build/reports/detekt/detekt.xml")).doesNotExist() + assertThat(projectFile("${submodule.name}/build/reports/detekt/detekt.html")).doesNotExist() + } + } + } + } + } + } }) diff --git a/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/DslGradleRunner.kt b/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/DslGradleRunner.kt index 4b4593e86..6514c6e70 100644 --- a/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/DslGradleRunner.kt +++ b/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/DslGradleRunner.kt @@ -1,105 +1,104 @@ package io.gitlab.arturbosch.detekt -import org.gradle.testkit.runner.BuildResult -import org.gradle.testkit.runner.GradleRunner import java.io.File import java.util.UUID +import org.gradle.testkit.runner.BuildResult +import org.gradle.testkit.runner.GradleRunner class DslGradleRunner( - val projectLayout: ProjectLayout, - val buildFileName: String, - val mainBuildFileContent: String, - val configFileOrNone: String? = null, - val baselineFileOrNone: String? = null + val projectLayout: ProjectLayout, + val buildFileName: String, + val mainBuildFileContent: String, + val configFileOrNone: String? = null, + val baselineFileOrNone: String? = null ) { - private val rootDir: File = createTempDir(prefix = "applyPlugin") - private val cacheDir = createTempDir(prefix = "cache") - private val randomString = UUID.randomUUID().toString() + private val rootDir: File = createTempDir(prefix = "applyPlugin") + private val cacheDir = createTempDir(prefix = "cache") + private val randomString = UUID.randomUUID().toString() - private val settingsContent = """ + private val settingsContent = """ |rootProject.name = "rootDir-project" |include(${projectLayout.submodules.map { "\"${it.name}\"" }.joinToString(",")}) | """.trimMargin() - private val baselineContent = """ + private val baselineContent = """ | | | """.trimMargin() - private val configFileContent = """ + private val configFileContent = """ |autoCorrect: true |failFast: false """.trimMargin() - /** - * Each generated file is different so the artifacts are not cached in between test runs - */ - private fun ktFileContent(className: String) = """ + /** + * Each generated file is different so the artifacts are not cached in between test runs + */ + private fun ktFileContent(className: String) = """ |internal class $className(val randomDefaultValue: String = "$randomString") | """.trimMargin() - fun setupProject() { - writeProjectFile(buildFileName, mainBuildFileContent) - writeProjectFile(SETTINGS_FILENAME, settingsContent) - configFileOrNone?.let { writeProjectFile(configFileOrNone, configFileContent) } - baselineFileOrNone?.let { writeProjectFile(baselineFileOrNone, baselineContent) } - projectLayout.srcDirs.forEach { sourceDir -> - (1..projectLayout.numberOfSourceFilesInRootPerSourceDir).forEach { - writeKtFile(File(rootDir, sourceDir), "MyRoot${it}Class.kt") - } - } + fun setupProject() { + writeProjectFile(buildFileName, mainBuildFileContent) + writeProjectFile(SETTINGS_FILENAME, settingsContent) + configFileOrNone?.let { writeProjectFile(configFileOrNone, configFileContent) } + baselineFileOrNone?.let { writeProjectFile(baselineFileOrNone, baselineContent) } + projectLayout.srcDirs.forEach { sourceDir -> + (1..projectLayout.numberOfSourceFilesInRootPerSourceDir).forEach { + writeKtFile(File(rootDir, sourceDir), "MyRoot${it}Class.kt") + } + } - projectLayout.submodules.forEach { submodule -> - val moduleRoot = File(rootDir, submodule.name) - moduleRoot.mkdirs() - File(moduleRoot, buildFileName).writeText(submodule.detektConfig ?: "") - submodule.srcDirs.forEach { moduleSourceDir -> - (1..submodule.numberOfSourceFiles).forEach { - writeKtFile(File(moduleRoot, moduleSourceDir), "My${submodule.name}${it}Class.kt") - } - } - } - } + projectLayout.submodules.forEach { submodule -> + val moduleRoot = File(rootDir, submodule.name) + moduleRoot.mkdirs() + File(moduleRoot, buildFileName).writeText(submodule.detektConfig ?: "") + submodule.srcDirs.forEach { moduleSourceDir -> + (1..submodule.numberOfSourceFiles).forEach { + writeKtFile(File(moduleRoot, moduleSourceDir), "My${submodule.name}${it}Class.kt") + } + } + } + } - fun writeProjectFile(filename: String, content: String) { - File(rootDir, filename).writeText(content) - } + fun writeProjectFile(filename: String, content: String) { + File(rootDir, filename).writeText(content) + } - fun writeKtFile(srcDir: String, className: String) { - writeKtFile(File(rootDir, srcDir), className) - } + fun writeKtFile(srcDir: String, className: String) { + writeKtFile(File(rootDir, srcDir), className) + } - private fun writeKtFile(dir: File, className: String) { - dir.mkdirs() - File(dir, className).writeText(ktFileContent(className)) - } + private fun writeKtFile(dir: File, className: String) { + dir.mkdirs() + File(dir, className).writeText(ktFileContent(className)) + } + fun runTasksAndCheckResult(vararg tasks: String, doAssert: DslGradleRunner.(BuildResult) -> Unit) { - fun runTasksAndCheckResult(vararg tasks: String, doAssert: DslGradleRunner.(BuildResult) -> Unit) { + // Using a custom "project-cache-dir" to avoid a Gradle error on Windows + val cacheArgs = listOf("--project-cache-dir", cacheDir.absolutePath, "--build-cache") - // Using a custom "project-cache-dir" to avoid a Gradle error on Windows - val cacheArgs = listOf("--project-cache-dir", cacheDir.absolutePath, "--build-cache") + val args = listOf("--stacktrace", "--info") + cacheArgs + tasks + val result = GradleRunner.create() + .withProjectDir(rootDir) + .withPluginClasspath() + .withArguments(args) + .build() + this.doAssert(result) + } - val args = listOf("--stacktrace", "--info") + cacheArgs + tasks - val result = GradleRunner.create() - .withProjectDir(rootDir) - .withPluginClasspath() - .withArguments(args) - .build() - this.doAssert(result) - } + fun runDetektTaskAndCheckResult(doAssert: DslGradleRunner.(BuildResult) -> Unit) { + runTasksAndCheckResult("detekt") { doAssert(it) } + } - fun runDetektTaskAndCheckResult(doAssert: DslGradleRunner.(BuildResult) -> Unit) { - runTasksAndCheckResult("detekt") { doAssert(it) } - } + fun projectFile(path: String): File = File(rootDir, path) - fun projectFile(path: String): File = File(rootDir, path) - - companion object { - const val SETTINGS_FILENAME = "settings.gradle" - } + companion object { + const val SETTINGS_FILENAME = "settings.gradle" + } } diff --git a/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/DslTestBuilder.kt b/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/DslTestBuilder.kt index 4fb9cd96f..06e8ade56 100644 --- a/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/DslTestBuilder.kt +++ b/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/DslTestBuilder.kt @@ -5,52 +5,52 @@ package io.gitlab.arturbosch.detekt */ abstract class DslTestBuilder { - abstract val gradleBuildConfig: String - abstract val gradleBuildName: String + abstract val gradleBuildConfig: String + abstract val gradleBuildName: String - private var detektConfig: String = "" - private var projectLayout: ProjectLayout = ProjectLayout(1) - private var baselineFile: String? = null - private var configFile: String? = null + private var detektConfig: String = "" + private var projectLayout: ProjectLayout = ProjectLayout(1) + private var baselineFile: String? = null + private var configFile: String? = null - fun withDetektConfig(config: String): DslTestBuilder { - detektConfig = config - return this - } + fun withDetektConfig(config: String): DslTestBuilder { + detektConfig = config + return this + } - fun withProjectLayout(layout: ProjectLayout): DslTestBuilder { - projectLayout = layout - return this - } + fun withProjectLayout(layout: ProjectLayout): DslTestBuilder { + projectLayout = layout + return this + } - fun withBaseline(filename: String): DslTestBuilder { - baselineFile = filename - return this - } + fun withBaseline(filename: String): DslTestBuilder { + baselineFile = filename + return this + } - fun withConfigFile(filename: String): DslTestBuilder { - configFile = filename - return this - } + fun withConfigFile(filename: String): DslTestBuilder { + configFile = filename + return this + } - fun build(): DslGradleRunner { - val mainBuildFileContent = """ + fun build(): DslGradleRunner { + val mainBuildFileContent = """ | $gradleBuildConfig | $detektConfig """.trimMargin() - val runner = DslGradleRunner( - projectLayout, - gradleBuildName, - mainBuildFileContent, - configFile, - baselineFile) - runner.setupProject() - return runner - } + val runner = DslGradleRunner( + projectLayout, + gradleBuildName, + mainBuildFileContent, + configFile, + baselineFile) + runner.setupProject() + return runner + } - private class GroovyBuilder : DslTestBuilder() { - override val gradleBuildName: String = "build.gradle" - override val gradleBuildConfig: String = """ + private class GroovyBuilder : DslTestBuilder() { + override val gradleBuildName: String = "build.gradle" + override val gradleBuildConfig: String = """ |import io.gitlab.arturbosch.detekt.DetektPlugin | |plugins { @@ -63,12 +63,11 @@ abstract class DslTestBuilder { | mavenLocal() |} """.trimMargin() + } - } - - private class KotlinBuilder : DslTestBuilder() { - override val gradleBuildName: String = "build.gradle.kts" - override val gradleBuildConfig: String = """ + private class KotlinBuilder : DslTestBuilder() { + override val gradleBuildName: String = "build.gradle.kts" + override val gradleBuildConfig: String = """ |import io.gitlab.arturbosch.detekt.detekt | |plugins { @@ -81,10 +80,10 @@ abstract class DslTestBuilder { | mavenLocal() |} """.trimMargin() - } + } - companion object { - fun kotlin(): DslTestBuilder = KotlinBuilder() - fun groovy(): DslTestBuilder = GroovyBuilder() - } + companion object { + fun kotlin(): DslTestBuilder = KotlinBuilder() + fun groovy(): DslTestBuilder = GroovyBuilder() + } } diff --git a/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/GenerateConfigTaskTest.kt b/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/GenerateConfigTaskTest.kt index 716b18ee1..f4034f4d9 100644 --- a/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/GenerateConfigTaskTest.kt +++ b/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/GenerateConfigTaskTest.kt @@ -7,18 +7,18 @@ import org.jetbrains.spek.api.dsl.describe import org.jetbrains.spek.api.dsl.it class GenerateConfigTaskTest : Spek({ - describe("The generate config task of the Detekt Gradle plugin") { - listOf(DslTestBuilder.groovy(), DslTestBuilder.kotlin()).forEach { builder -> - describe("using ${builder.gradleBuildName}") { - it("can be executed without any configuration") { - val gradleRunner = builder.build() + describe("The generate config task of the Detekt Gradle plugin") { + listOf(DslTestBuilder.groovy(), DslTestBuilder.kotlin()).forEach { builder -> + describe("using ${builder.gradleBuildName}") { + it("can be executed without any configuration") { + val gradleRunner = builder.build() - gradleRunner.runTasksAndCheckResult("detektGenerateConfig") { result -> - assertThat(result.task(":detektGenerateConfig")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - assertThat(projectFile("default-detekt-config.yml")).exists() - } - } - } - } - } + gradleRunner.runTasksAndCheckResult("detektGenerateConfig") { result -> + assertThat(result.task(":detektGenerateConfig")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(projectFile("default-detekt-config.yml")).exists() + } + } + } + } + } }) diff --git a/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/PluginTaskBehaviorTest.kt b/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/PluginTaskBehaviorTest.kt index da5b6e2a8..9e8e42614 100644 --- a/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/PluginTaskBehaviorTest.kt +++ b/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/PluginTaskBehaviorTest.kt @@ -16,10 +16,10 @@ import org.jetbrains.spek.api.dsl.it */ internal class PluginTaskBehaviorTest : Spek({ - val configFileName = "config.yml" - val baselineFileName = "baseline.xml" + val configFileName = "config.yml" + val baselineFileName = "baseline.xml" - val detektConfig = """ + val detektConfig = """ |detekt { | config = files("$configFileName") | baseline = file("$baselineFileName") @@ -27,96 +27,96 @@ internal class PluginTaskBehaviorTest : Spek({ |} """ - describe("The Detekt Gradle Plugin :detekt Task") { - lateinit var gradleRunner: DslGradleRunner + describe("The Detekt Gradle Plugin :detekt Task") { + lateinit var gradleRunner: DslGradleRunner - beforeEachTest { - gradleRunner = kotlin() - .withDetektConfig(detektConfig) - .withBaseline(baselineFileName) - .withConfigFile(configFileName) - .build() - } + beforeEachTest { + gradleRunner = kotlin() + .withDetektConfig(detektConfig) + .withBaseline(baselineFileName) + .withConfigFile(configFileName) + .build() + } - it("should be UP-TO-DATE the 2nd run without changes") { - gradleRunner.runDetektTaskAndCheckResult { result -> - assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - } - gradleRunner.runDetektTaskAndCheckResult { result -> - assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.UP_TO_DATE) - } - } - it("should pick up build artifacts from the build cache on a 2nd run after deleting the build/ dir") { - gradleRunner.runDetektTaskAndCheckResult { result -> - assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - } + it("should be UP-TO-DATE the 2nd run without changes") { + gradleRunner.runDetektTaskAndCheckResult { result -> + assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + } + gradleRunner.runDetektTaskAndCheckResult { result -> + assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.UP_TO_DATE) + } + } + it("should pick up build artifacts from the build cache on a 2nd run after deleting the build/ dir") { + gradleRunner.runDetektTaskAndCheckResult { result -> + assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + } - gradleRunner.projectFile("build").deleteRecursively() + gradleRunner.projectFile("build").deleteRecursively() - // Running detekt again should pick up artifacts from Build Cache - gradleRunner.runDetektTaskAndCheckResult { result -> - assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.FROM_CACHE) - } - } - it("should pick up build artifacts from the build cache on a 2nd run after running :clean") { - gradleRunner.runDetektTaskAndCheckResult { result -> - assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - } - gradleRunner.runTasksAndCheckResult("clean", "detekt") { result -> - assertThat(result.task(":clean")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.FROM_CACHE) - } - } - it("should run again after changing config") { - val configFileWithCommentsDisabled = """ + // Running detekt again should pick up artifacts from Build Cache + gradleRunner.runDetektTaskAndCheckResult { result -> + assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.FROM_CACHE) + } + } + it("should pick up build artifacts from the build cache on a 2nd run after running :clean") { + gradleRunner.runDetektTaskAndCheckResult { result -> + assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + } + gradleRunner.runTasksAndCheckResult("clean", "detekt") { result -> + assertThat(result.task(":clean")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.FROM_CACHE) + } + } + it("should run again after changing config") { + val configFileWithCommentsDisabled = """ |autoCorrect: true |failFast: false |comments: | active: false """.trimMargin() - gradleRunner.runDetektTaskAndCheckResult { result -> - assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - } + gradleRunner.runDetektTaskAndCheckResult { result -> + assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + } - // update config file - gradleRunner.writeProjectFile(configFileName, configFileWithCommentsDisabled) + // update config file + gradleRunner.writeProjectFile(configFileName, configFileWithCommentsDisabled) - gradleRunner.runTasksAndCheckResult("detekt") { result -> - assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - } - } - it("should run again after changing baseline") { - val changedBaselineContent = """ + gradleRunner.runTasksAndCheckResult("detekt") { result -> + assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + } + } + it("should run again after changing baseline") { + val changedBaselineContent = """ | | | | """.trimMargin() - gradleRunner.runDetektTaskAndCheckResult { result -> - assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - } + gradleRunner.runDetektTaskAndCheckResult { result -> + assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + } - // update baseline file - gradleRunner.writeProjectFile(baselineFileName, changedBaselineContent) + // update baseline file + gradleRunner.writeProjectFile(baselineFileName, changedBaselineContent) - gradleRunner.runTasksAndCheckResult("detekt") { result -> - assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - } - } - it("should run again after changing inputs") { + gradleRunner.runTasksAndCheckResult("detekt") { result -> + assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + } + } + it("should run again after changing inputs") { - gradleRunner.runDetektTaskAndCheckResult { result -> - assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - } + gradleRunner.runDetektTaskAndCheckResult { result -> + assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + } - // add a new File - gradleRunner.writeKtFile(gradleRunner.projectLayout.srcDirs.first(), "OtherKotlinClass") + // add a new File + gradleRunner.writeKtFile(gradleRunner.projectLayout.srcDirs.first(), "OtherKotlinClass") - gradleRunner.runTasksAndCheckResult("detekt") { result -> - assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - } - } - } + gradleRunner.runTasksAndCheckResult("detekt") { result -> + assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + } + } + } }) diff --git a/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/ProjectLayout.kt b/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/ProjectLayout.kt index 42b18cd79..4d8ea1970 100644 --- a/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/ProjectLayout.kt +++ b/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/ProjectLayout.kt @@ -1,14 +1,15 @@ package io.gitlab.arturbosch.detekt data class ProjectLayout( - val numberOfSourceFilesInRootPerSourceDir: Int, - val submodules: List = emptyList(), - val srcDirs: List = listOf("src/main/java") + val numberOfSourceFilesInRootPerSourceDir: Int, + val submodules: List = emptyList(), + val srcDirs: List = listOf("src/main/java") ) { - fun withSubmodule(name: String, - numberOfSourceFilesInRootPerSourceDir: Int, - detektConfig: String? = null, - srcDirs: List = this.srcDirs - ) = copy(submodules = (submodules + listOf(Submodule(name, numberOfSourceFilesInRootPerSourceDir, detektConfig, srcDirs)))) + fun withSubmodule( + name: String, + numberOfSourceFilesInRootPerSourceDir: Int, + detektConfig: String? = null, + srcDirs: List = this.srcDirs + ) = copy(submodules = (submodules + listOf(Submodule(name, numberOfSourceFilesInRootPerSourceDir, detektConfig, srcDirs)))) } diff --git a/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/Submodule.kt b/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/Submodule.kt index 6be800559..6aa65d714 100644 --- a/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/Submodule.kt +++ b/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/Submodule.kt @@ -1,8 +1,8 @@ package io.gitlab.arturbosch.detekt data class Submodule( - val name: String, - val numberOfSourceFiles: Int, - val detektConfig: String?, - val srcDirs: List + val name: String, + val numberOfSourceFiles: Int, + val detektConfig: String?, + val srcDirs: List ) diff --git a/detekt-rules/build.gradle.kts b/detekt-rules/build.gradle.kts index 324dc63f8..f0fd0f5ef 100644 --- a/detekt-rules/build.gradle.kts +++ b/detekt-rules/build.gradle.kts @@ -7,11 +7,11 @@ val spekVersion: String by project val reflectionsVersion: String by project dependencies { - implementation(project(":detekt-api")) - implementation(kotlin("compiler-embeddable")) + implementation(project(":detekt-api")) + implementation(kotlin("compiler-embeddable")) - testImplementation("org.reflections:reflections:$reflectionsVersion") - testImplementation(project(":detekt-test")) - testRuntimeOnly("org.junit.platform:junit-platform-launcher:$junitPlatformVersion") - testRuntimeOnly("org.jetbrains.spek:spek-junit-platform-engine:$spekVersion") + testImplementation("org.reflections:reflections:$reflectionsVersion") + testImplementation(project(":detekt-test")) + testRuntimeOnly("org.junit.platform:junit-platform-launcher:$junitPlatformVersion") + testRuntimeOnly("org.jetbrains.spek:spek-junit-platform-engine:$spekVersion") } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/IsPartOfUtils.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/IsPartOfUtils.kt index ae79df4bd..5ff0690a1 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/IsPartOfUtils.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/IsPartOfUtils.kt @@ -1,9 +1,9 @@ package io.gitlab.arturbosch.detekt.rules +import kotlin.reflect.KClass import org.jetbrains.kotlin.com.intellij.psi.PsiElement import org.jetbrains.kotlin.psi.KtStringTemplateEntry import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType -import kotlin.reflect.KClass /** * @author Artur Bosch diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/Junk.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/Junk.kt index f5bd867dd..608274841 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/Junk.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/Junk.kt @@ -22,25 +22,25 @@ import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType fun KtExpression?.asBlockExpression(): KtBlockExpression? = this as? KtBlockExpression fun KtClassOrObject.isObjectOfAnonymousClass() = - this.getNonStrictParentOfType() != null && this.name == null + this.getNonStrictParentOfType() != null && this.name == null fun KtCallExpression.isUsedForNesting(): Boolean = when (getCallNameExpression()?.text) { - "run", "let", "apply", "with", "use", "forEach" -> true - else -> false + "run", "let", "apply", "with", "use", "forEach" -> true + else -> false } fun KtBlockExpression.hasCommentInside(): Boolean { - val commentKey = Key("comment") - this.acceptChildren(object : DetektVisitor() { - override fun visitComment(comment: PsiComment?) { - if (comment != null) putUserData(commentKey, true) - } - }) - return getUserData(commentKey) == true + val commentKey = Key("comment") + this.acceptChildren(object : DetektVisitor() { + override fun visitComment(comment: PsiComment?) { + if (comment != null) putUserData(commentKey, true) + } + }) + return getUserData(commentKey) == true } fun getIntValueForPsiElement(element: PsiElement): Int? { - return (element as? KtConstantExpression)?.text?.toIntOrNull() + return (element as? KtConstantExpression)?.text?.toIntOrNull() } fun KtStringTemplateExpression.plainText() = text.substring(1, text.length - 1) diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/KtAnnotatedExtensions.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/KtAnnotatedExtensions.kt index 560168caa..9dd347fb7 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/KtAnnotatedExtensions.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/KtAnnotatedExtensions.kt @@ -8,53 +8,53 @@ import org.jetbrains.kotlin.psi.KtValueArgument import org.jetbrains.kotlin.psi.KtValueArgumentList fun KtAnnotated.hasAnnotation( - vararg annotationNames: String + vararg annotationNames: String ): Boolean { - val names = annotationNames.toHashSet() - val predicate: (KtAnnotationEntry) -> Boolean = { - it.typeReference - ?.typeElement - ?.safeAs() - ?.referencedName in names - } - return annotationEntries.any(predicate) + val names = annotationNames.toHashSet() + val predicate: (KtAnnotationEntry) -> Boolean = { + it.typeReference + ?.typeElement + ?.safeAs() + ?.referencedName in names + } + return annotationEntries.any(predicate) } fun KtAnnotated.hasAnnotationWithValue( - annotationName: String, - annotationValueText: String + annotationName: String, + annotationValueText: String ): Boolean { - return annotationEntries.any { it.isAnnotationWithValue(annotationName, annotationValueText) } + return annotationEntries.any { it.isAnnotationWithValue(annotationName, annotationValueText) } } private fun KtAnnotationEntry.isAnnotationWithValue( - annotationName: String, - annotationValueText: String + annotationName: String, + annotationValueText: String ): Boolean { - return typeReference.isAnnotationWithName(annotationName) && - valueArgumentList.containsAnnotationValue(annotationValueText) + return typeReference.isAnnotationWithName(annotationName) && + valueArgumentList.containsAnnotationValue(annotationValueText) } private fun KtTypeReference?.isAnnotationWithName(annotationName: String): Boolean { - if (this == null) { - return false - } + if (this == null) { + return false + } - val type = typeElement + val type = typeElement - return if (type is KtUserType) { - type.referencedName == annotationName - } else { - false - } + return if (type is KtUserType) { + type.referencedName == annotationName + } else { + false + } } private fun KtValueArgumentList?.containsAnnotationValue(annotationValueText: String): Boolean { - return this?.arguments - ?.any { it.hasValue(annotationValueText) } - ?: false + return this?.arguments + ?.any { it.hasValue(annotationValueText) } + ?: false } private fun KtValueArgument.hasValue(annotationValueText: String): Boolean { - return text == annotationValueText + return text == annotationValueText } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/KtClassOrObjectExtensions.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/KtClassOrObjectExtensions.kt index 3f382c230..c83a770fa 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/KtClassOrObjectExtensions.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/KtClassOrObjectExtensions.kt @@ -4,5 +4,5 @@ import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtClassOrObject fun KtClassOrObject.isInterface(): Boolean { - return (this as? KtClass)?.isInterface() == true + return (this as? KtClass)?.isInterface() == true } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/KtModifierList.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/KtModifierList.kt index fd7ba4fcc..f98b55c8b 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/KtModifierList.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/KtModifierList.kt @@ -5,7 +5,7 @@ import org.jetbrains.kotlin.psi.KtModifierListOwner import org.jetbrains.kotlin.psi.psiUtil.isPublic fun KtModifierListOwner.isPublicNotOverridden() = - isPublic && !isOverride() + isPublic && !isOverride() fun KtModifierListOwner.isAbstract() = hasModifier(KtTokens.ABSTRACT_KEYWORD) diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/LinesOfCode.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/LinesOfCode.kt index d4e36f280..1241d5c5d 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/LinesOfCode.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/LinesOfCode.kt @@ -1,5 +1,7 @@ package io.gitlab.arturbosch.detekt.rules +import java.util.ArrayDeque +import kotlin.reflect.KClass import org.jetbrains.kotlin.com.intellij.lang.ASTNode import org.jetbrains.kotlin.com.intellij.psi.PsiComment import org.jetbrains.kotlin.com.intellij.psi.PsiElement @@ -19,45 +21,43 @@ import org.jetbrains.kotlin.kdoc.psi.impl.KDocSection import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtFile -import java.util.ArrayDeque -import kotlin.reflect.KClass fun ASTNode.tokenSequence(skipTreesOf: Set>): Sequence = sequence { - val queue = ArrayDeque() - queue.add(this@tokenSequence) - do { - val curr = queue.pop() - if (curr.psi::class !in skipTreesOf) { - // Yields only tokens which can be identified in the source code. - // Composite elements, e.g. classes or files, are abstractions over many leaf nodes. - if (curr is LeafElement) { - yield(curr) - } - queue.addAll(curr.getChildren(null)) - } - } while (queue.isNotEmpty()) + val queue = ArrayDeque() + queue.add(this@tokenSequence) + do { + val curr = queue.pop() + if (curr.psi::class !in skipTreesOf) { + // Yields only tokens which can be identified in the source code. + // Composite elements, e.g. classes or files, are abstractions over many leaf nodes. + if (curr is LeafElement) { + yield(curr) + } + queue.addAll(curr.getChildren(null)) + } + } while (queue.isNotEmpty()) } fun KtFile.linesOfCode(): Int = linesOfCode(this) fun KtElement.linesOfCode(inFile: KtFile = this.containingKtFile): Int = node.tokenSequence(comments) - .map { it.line(inFile) } - .distinct() - .count() + .map { it.line(inFile) } + .distinct() + .count() fun ASTNode.line(inFile: KtFile) = DiagnosticUtils.getLineAndColumnInPsiFile(inFile, this.textRange).line private val comments: Set> = setOf( - PsiWhiteSpace::class, - PsiWhiteSpaceImpl::class, - PsiComment::class, - PsiCommentImpl::class, - PsiCoreCommentImpl::class, - KDoc::class, - KDocImpl::class, - KDocElementImpl::class, - KDocElement::class, - KDocLink::class, - KDocSection::class, - KDocTag::class, - KDocName::class + PsiWhiteSpace::class, + PsiWhiteSpaceImpl::class, + PsiComment::class, + PsiCommentImpl::class, + PsiCoreCommentImpl::class, + KDoc::class, + KDocImpl::class, + KDocElementImpl::class, + KDocElement::class, + KDocLink::class, + KDocSection::class, + KDocTag::class, + KDocName::class ) diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/MethodSignature.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/MethodSignature.kt index 47a59d3a4..624ca8728 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/MethodSignature.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/MethodSignature.kt @@ -5,25 +5,25 @@ import org.jetbrains.kotlin.psi.KtNamedFunction import org.jetbrains.kotlin.psi.KtObjectDeclaration fun KtFunction.isEqualsFunction() = - this.name == "equals" && hasCorrectEqualsParameter() && this.isOverride() + this.name == "equals" && hasCorrectEqualsParameter() && this.isOverride() fun KtFunction.isHashCodeFunction() = - this.name == "hashCode" && this.valueParameters.isEmpty() && this.isOverride() + this.name == "hashCode" && this.valueParameters.isEmpty() && this.isOverride() private val knownAnys = setOf("Any?", "kotlin.Any?") fun KtFunction.hasCorrectEqualsParameter() = - this.valueParameters.firstOrNull()?.typeReference?.text in knownAnys + this.valueParameters.firstOrNull()?.typeReference?.text in knownAnys fun KtNamedFunction.isMainFunction() = - this.isTopLevelMain() || this.isMainInsideObject() + this.isTopLevelMain() || this.isMainInsideObject() fun KtNamedFunction.isMainInsideObject() = - this.name == "main" && - this.isPublicNotOverridden() && - this.parent?.parent is KtObjectDeclaration && - this.hasAnnotation("JvmStatic", "kotlin.jvm.JvmStatic") + this.name == "main" && + this.isPublicNotOverridden() && + this.parent?.parent is KtObjectDeclaration && + this.hasAnnotation("JvmStatic", "kotlin.jvm.JvmStatic") fun KtNamedFunction.isTopLevelMain() = - this.name == "main" && - this.isPublicNotOverridden() && - this.isTopLevel + this.name == "main" && + this.isPublicNotOverridden() && + this.isTopLevel diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/StringExtensions.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/StringExtensions.kt index f8d10114f..85ba915cf 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/StringExtensions.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/StringExtensions.kt @@ -5,13 +5,13 @@ import java.net.URISyntaxException import java.net.URL internal fun String.lastArgumentMatchesUrl(): Boolean { - val lastArgument = trimEnd().split(Regex("\\s+")).last() - return try { - URL(lastArgument).toURI() - true - } catch (e: MalformedURLException) { - false - } catch (e: URISyntaxException) { - false - } + val lastArgument = trimEnd().split(Regex("\\s+")).last() + return try { + URL(lastArgument).toURI() + true + } catch (e: MalformedURLException) { + false + } catch (e: URISyntaxException) { + false + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/Traversing.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/Traversing.kt index dd1bc7408..68875e82c 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/Traversing.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/Traversing.kt @@ -9,39 +9,39 @@ import org.jetbrains.kotlin.psi.KtFile * Returns a list of all parents of type [T] before first occurrence of [S]. */ inline fun KtElement.parentsOfTypeUntil(strict: Boolean = true) = - sequence { - var current: PsiElement? = if (strict) this@parentsOfTypeUntil.parent else this@parentsOfTypeUntil - while (current != null && current !is S) { - if (current is T) { - yield(current) - } - current = current.parent - } - } + sequence { + var current: PsiElement? = if (strict) this@parentsOfTypeUntil.parent else this@parentsOfTypeUntil + while (current != null && current !is S) { + if (current is T) { + yield(current) + } + current = current.parent + } + } @Suppress("UnsafeCast") inline fun KtElement.parentsOfTypeUntil() = sequence { - var current: PsiElement? = this@parentsOfTypeUntil - while (current != null && current !is S) { - if (current is T) { - yield(current) - } - current = current.parent - } + var current: PsiElement? = this@parentsOfTypeUntil + while (current != null && current !is S) { + if (current is T) { + yield(current) + } + current = current.parent + } } inline fun KtElement.parentOfType(strict: Boolean = true) = - parentsOfTypeUntil(strict).firstOrNull() + parentsOfTypeUntil(strict).firstOrNull() inline fun KtElement.collectByType(): List { - val list = mutableListOf() - this.accept(object : DetektVisitor() { - override fun visitKtElement(element: KtElement) { - if (element is T) { - list.add(element) - } - element.children.forEach { it.accept(this) } - } - }) - return list + val list = mutableListOf() + this.accept(object : DetektVisitor() { + override fun visitKtElement(element: KtElement) { + if (element is T) { + list.add(element) + } + element.children.forEach { it.accept(this) } + } + }) + return list } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/DuplicateCaseInWhenExpression.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/DuplicateCaseInWhenExpression.kt index 95f0592b6..0abfecde6 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/DuplicateCaseInWhenExpression.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/DuplicateCaseInWhenExpression.kt @@ -36,34 +36,34 @@ import org.jetbrains.kotlin.psi.KtWhenExpression */ class DuplicateCaseInWhenExpression(config: Config) : Rule(config) { - override val issue = Issue("DuplicateCaseInWhenExpression", - Severity.Warning, - "Duplicated case statements in when expression. " + - "Both cases should be merged.", - Debt.TEN_MINS) + override val issue = Issue("DuplicateCaseInWhenExpression", + Severity.Warning, + "Duplicated case statements in when expression. " + + "Both cases should be merged.", + Debt.TEN_MINS) - override fun visitWhenExpression(expression: KtWhenExpression) { - val entries = expression.entries - .map { it.conditions } - .fold(mutableListOf()) { state, conditions -> - state.apply { add(conditions.joinToString { it.text }) } - } - val duplicates = findDuplicates(entries) - if (duplicates.isNotEmpty()) { - report(CodeSmell(issue, Entity.from(expression), - "When expression has multiple case statements " + "for ${duplicates.joinToString { ", " }}.")) - } - } + override fun visitWhenExpression(expression: KtWhenExpression) { + val entries = expression.entries + .map { it.conditions } + .fold(mutableListOf()) { state, conditions -> + state.apply { add(conditions.joinToString { it.text }) } + } + val duplicates = findDuplicates(entries) + if (duplicates.isNotEmpty()) { + report(CodeSmell(issue, Entity.from(expression), + "When expression has multiple case statements " + "for ${duplicates.joinToString { ", " }}.")) + } + } - private fun findDuplicates(list: List): MutableSet { - val duplicates = mutableSetOf() - for (i in 0 until list.size) { - for (j in i + 1 until list.size) { - if (list[i] == list[j]) { - duplicates.add(list[i]) - } - } - } - return duplicates - } + private fun findDuplicates(list: List): MutableSet { + val duplicates = mutableSetOf() + for (i in 0 until list.size) { + for (j in i + 1 until list.size) { + if (list[i] == list[j]) { + duplicates.add(list[i]) + } + } + } + return duplicates + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/EqualsAlwaysReturnsTrueOrFalse.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/EqualsAlwaysReturnsTrueOrFalse.kt index dd4701c55..5a7d7880a 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/EqualsAlwaysReturnsTrueOrFalse.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/EqualsAlwaysReturnsTrueOrFalse.kt @@ -41,40 +41,40 @@ import org.jetbrains.kotlin.psi.KtReturnExpression */ class EqualsAlwaysReturnsTrueOrFalse(config: Config = Config.empty) : Rule(config) { - override val issue = Issue("EqualsAlwaysReturnsTrueOrFalse", - Severity.Defect, - "Having an equals method which always returns true or false is not a good idea. " + - "It does not follow the contract of this method. " + - "Consider a good default implementation. " + - "For example this == other", - Debt.TWENTY_MINS) + override val issue = Issue("EqualsAlwaysReturnsTrueOrFalse", + Severity.Defect, + "Having an equals method which always returns true or false is not a good idea. " + + "It does not follow the contract of this method. " + + "Consider a good default implementation. " + + "For example this == other", + Debt.TWENTY_MINS) - override fun visitNamedFunction(function: KtNamedFunction) { - if (function.isEqualsFunction() && isReturningBooleanConstant(function)) { - report(CodeSmell(issue, Entity.from(function), "This equals function always returns the same " + - "result regardless on the input parameters.")) - } - } + override fun visitNamedFunction(function: KtNamedFunction) { + if (function.isEqualsFunction() && isReturningBooleanConstant(function)) { + report(CodeSmell(issue, Entity.from(function), "This equals function always returns the same " + + "result regardless on the input parameters.")) + } + } - private fun isReturningBooleanConstant(function: KtNamedFunction): Boolean { - val bodyExpression = function.bodyExpression ?: return false - return if (bodyExpression is KtConstantExpression) { - bodyExpression.isBooleanConstant() - } else { - isSingleReturnWithBooleanConstant(bodyExpression) - } - } + private fun isReturningBooleanConstant(function: KtNamedFunction): Boolean { + val bodyExpression = function.bodyExpression ?: return false + return if (bodyExpression is KtConstantExpression) { + bodyExpression.isBooleanConstant() + } else { + isSingleReturnWithBooleanConstant(bodyExpression) + } + } - private fun isSingleReturnWithBooleanConstant(bodyExpression: KtExpression): Boolean { - val returnExpressionsInBlock = bodyExpression.asBlockExpression()?.statements - ?.filterIsInstance() ?: return false - val lastValidReturnExpression = returnExpressionsInBlock.first().returnedExpression - val allReturnExpressions = bodyExpression.collectByType() - val hasNoNestedReturnExpression = allReturnExpressions.size == returnExpressionsInBlock.size - return lastValidReturnExpression?.isBooleanConstant() == true && - (hasNoNestedReturnExpression || - allReturnExpressions.all { it.returnedExpression?.text == lastValidReturnExpression.text }) - } + private fun isSingleReturnWithBooleanConstant(bodyExpression: KtExpression): Boolean { + val returnExpressionsInBlock = bodyExpression.asBlockExpression()?.statements + ?.filterIsInstance() ?: return false + val lastValidReturnExpression = returnExpressionsInBlock.first().returnedExpression + val allReturnExpressions = bodyExpression.collectByType() + val hasNoNestedReturnExpression = allReturnExpressions.size == returnExpressionsInBlock.size + return lastValidReturnExpression?.isBooleanConstant() == true && + (hasNoNestedReturnExpression || + allReturnExpressions.all { it.returnedExpression?.text == lastValidReturnExpression.text }) + } - private fun PsiElement.isBooleanConstant() = node.elementType == KtNodeTypes.BOOLEAN_CONSTANT + private fun PsiElement.isBooleanConstant() = node.elementType == KtNodeTypes.BOOLEAN_CONSTANT } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/EqualsWithHashCodeExist.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/EqualsWithHashCodeExist.kt index 26bc760b9..938b5436c 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/EqualsWithHashCodeExist.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/EqualsWithHashCodeExist.kt @@ -9,11 +9,11 @@ import io.gitlab.arturbosch.detekt.api.Rule import io.gitlab.arturbosch.detekt.api.Severity import io.gitlab.arturbosch.detekt.rules.isEqualsFunction import io.gitlab.arturbosch.detekt.rules.isHashCodeFunction +import java.util.ArrayDeque import org.jetbrains.kotlin.com.intellij.psi.PsiFile import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtNamedFunction -import java.util.ArrayDeque /** * When a class overrides the equals() method it should also override the hashCode() method. @@ -51,46 +51,46 @@ import java.util.ArrayDeque */ class EqualsWithHashCodeExist(config: Config = Config.empty) : Rule(config) { - override val issue = Issue("EqualsWithHashCodeExist", - Severity.Defect, - "Always override hashCode when you override equals. " + - "All hash-based collections depend on objects meeting the equals-contract. " + - "Two equal objects must produce the same hashcode. When inheriting equals or hashcode, " + - "override the inherited and call the super method for clarification.", - Debt.FIVE_MINS) + override val issue = Issue("EqualsWithHashCodeExist", + Severity.Defect, + "Always override hashCode when you override equals. " + + "All hash-based collections depend on objects meeting the equals-contract. " + + "Two equal objects must produce the same hashcode. When inheriting equals or hashcode, " + + "override the inherited and call the super method for clarification.", + Debt.FIVE_MINS) - private val queue = ArrayDeque(MAXIMUM_EXPECTED_NESTED_CLASSES) + private val queue = ArrayDeque(MAXIMUM_EXPECTED_NESTED_CLASSES) - private data class ViolationHolder(var equals: Boolean = false, var hashCode: Boolean = false) { - internal fun violation() = equals && !hashCode || !equals && hashCode - } + private data class ViolationHolder(var equals: Boolean = false, var hashCode: Boolean = false) { + internal fun violation() = equals && !hashCode || !equals && hashCode + } - override fun visitFile(file: PsiFile?) { - queue.clear() - super.visitFile(file) - } + override fun visitFile(file: PsiFile?) { + queue.clear() + super.visitFile(file) + } - override fun visitClassOrObject(classOrObject: KtClassOrObject) { - val klass = classOrObject as? KtClass - if (klass != null && klass.isData()) { - return - } - queue.push(ViolationHolder()) - super.visitClassOrObject(classOrObject) - if (queue.pop().violation()) { - report(CodeSmell(issue, Entity.from(classOrObject), "A class should always override hashCode " + - "when overriding equals and the other way around.")) - } - } + override fun visitClassOrObject(classOrObject: KtClassOrObject) { + val klass = classOrObject as? KtClass + if (klass != null && klass.isData()) { + return + } + queue.push(ViolationHolder()) + super.visitClassOrObject(classOrObject) + if (queue.pop().violation()) { + report(CodeSmell(issue, Entity.from(classOrObject), "A class should always override hashCode " + + "when overriding equals and the other way around.")) + } + } - override fun visitNamedFunction(function: KtNamedFunction) { - if (!function.isTopLevel) { - function.let { - if (it.isEqualsFunction()) queue.peek().equals = true - if (it.isHashCodeFunction()) queue.peek().hashCode = true - } - } - } + override fun visitNamedFunction(function: KtNamedFunction) { + if (!function.isTopLevel) { + function.let { + if (it.isEqualsFunction()) queue.peek().equals = true + if (it.isHashCodeFunction()) queue.peek().hashCode = true + } + } + } } private const val MAXIMUM_EXPECTED_NESTED_CLASSES = 5 diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/ExplicitGarbageCollectionCall.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/ExplicitGarbageCollectionCall.kt index 92c36a24f..808f92d72 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/ExplicitGarbageCollectionCall.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/ExplicitGarbageCollectionCall.kt @@ -29,27 +29,27 @@ import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression */ class ExplicitGarbageCollectionCall(config: Config) : Rule(config) { - override val issue = Issue("ExplicitGarbageCollectionCall", - Severity.Defect, - "Don't try to be smarter than the JVM. Your code should work independently if the garbage " + - "collector is disabled or not. If you face memory issues, " + - "try tuning the JVM options instead of relying on code itself.", - Debt.TWENTY_MINS) + override val issue = Issue("ExplicitGarbageCollectionCall", + Severity.Defect, + "Don't try to be smarter than the JVM. Your code should work independently if the garbage " + + "collector is disabled or not. If you face memory issues, " + + "try tuning the JVM options instead of relying on code itself.", + Debt.TWENTY_MINS) - override fun visitCallExpression(expression: KtCallExpression) { - expression.getCallNameExpression()?.let { - matchesGCCall(expression, it) - } - } + override fun visitCallExpression(expression: KtCallExpression) { + expression.getCallNameExpression()?.let { + matchesGCCall(expression, it) + } + } - private fun matchesGCCall(expression: KtCallExpression, it: KtSimpleNameExpression) { - if (it.textMatches("gc") || it.textMatches("runFinalization")) { - it.getReceiverExpression()?.let { - when (it.text) { - "System", "Runtime.getRuntime()" -> report(CodeSmell(issue, Entity.from(expression), - "An explicit call to the Garbage Collector as in ${it.text} should not be made.")) - } - } - } - } + private fun matchesGCCall(expression: KtCallExpression, it: KtSimpleNameExpression) { + if (it.textMatches("gc") || it.textMatches("runFinalization")) { + it.getReceiverExpression()?.let { + when (it.text) { + "System", "Runtime.getRuntime()" -> report(CodeSmell(issue, Entity.from(expression), + "An explicit call to the Garbage Collector as in ${it.text} should not be made.")) + } + } + } + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/InvalidRange.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/InvalidRange.kt index 15997b29a..c8972f5eb 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/InvalidRange.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/InvalidRange.kt @@ -35,39 +35,39 @@ import org.jetbrains.kotlin.psi.KtBinaryExpression */ class InvalidRange(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, - Severity.Defect, - "If a for loops condition is false before the first iteration, the loop will never get executed.", - Debt.TEN_MINS) + override val issue = Issue(javaClass.simpleName, + Severity.Defect, + "If a for loops condition is false before the first iteration, the loop will never get executed.", + Debt.TEN_MINS) - private val minimumSize = 3 + private val minimumSize = 3 - override fun visitBinaryExpression(expression: KtBinaryExpression) { - val range = expression.children - if (range.size >= minimumSize && hasInvalidLoopRange(range)) { - report(CodeSmell(issue, Entity.from(expression), - "This loop will never be executed due to its expression.")) - } - super.visitBinaryExpression(expression) - } + override fun visitBinaryExpression(expression: KtBinaryExpression) { + val range = expression.children + if (range.size >= minimumSize && hasInvalidLoopRange(range)) { + report(CodeSmell(issue, Entity.from(expression), + "This loop will never be executed due to its expression.")) + } + super.visitBinaryExpression(expression) + } - private fun hasInvalidLoopRange(range: Array): Boolean { - val lowerValue = getIntValueForPsiElement(range[0]) - val upperValue = getIntValueForPsiElement(range[2]) - if (lowerValue == null || upperValue == null) { - return false - } - return when (range[1].text) { - ".." -> checkRangeTo(lowerValue, upperValue) - "downTo" -> checkDownTo(lowerValue, upperValue) - "until" -> checkUntil(lowerValue, upperValue) - else -> false - } - } + private fun hasInvalidLoopRange(range: Array): Boolean { + val lowerValue = getIntValueForPsiElement(range[0]) + val upperValue = getIntValueForPsiElement(range[2]) + if (lowerValue == null || upperValue == null) { + return false + } + return when (range[1].text) { + ".." -> checkRangeTo(lowerValue, upperValue) + "downTo" -> checkDownTo(lowerValue, upperValue) + "until" -> checkUntil(lowerValue, upperValue) + else -> false + } + } - private fun checkRangeTo(lower: Int, upper: Int) = lower > upper + private fun checkRangeTo(lower: Int, upper: Int) = lower > upper - private fun checkDownTo(lower: Int, upper: Int) = lower < upper + private fun checkDownTo(lower: Int, upper: Int) = lower < upper - private fun checkUntil(lower: Int, upper: Int) = lower > upper + private fun checkUntil(lower: Int, upper: Int) = lower > upper } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/IteratorHasNextCallsNextMethod.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/IteratorHasNextCallsNextMethod.kt index e9d50232e..994cd4616 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/IteratorHasNextCallsNextMethod.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/IteratorHasNextCallsNextMethod.kt @@ -33,26 +33,26 @@ import org.jetbrains.kotlin.psi.KtNamedFunction */ class IteratorHasNextCallsNextMethod(config: Config = Config.empty) : Rule(config) { - override val issue = Issue("IteratorHasNextCallsNextMethod", Severity.Defect, - "The hasNext() method of an Iterator implementation should not call the next() method. " + - "The state of the iterator should not be changed inside the hasNext() method. " + - "The hasNext() method is not supposed to have any side effects.", - Debt.TEN_MINS) + override val issue = Issue("IteratorHasNextCallsNextMethod", Severity.Defect, + "The hasNext() method of an Iterator implementation should not call the next() method. " + + "The state of the iterator should not be changed inside the hasNext() method. " + + "The hasNext() method is not supposed to have any side effects.", + Debt.TEN_MINS) - override fun visitClassOrObject(classOrObject: KtClassOrObject) { - if (classOrObject.isImplementingIterator()) { - val hasNextMethod = classOrObject.getMethod("hasNext") - if (hasNextMethod != null && callsNextMethod(hasNextMethod)) { - report(CodeSmell(issue, Entity.from(classOrObject), "Calling hasNext() on an Iterator should " + - "have no side-effects. Calling next() is a side effect.")) - } - } - super.visitClassOrObject(classOrObject) - } + override fun visitClassOrObject(classOrObject: KtClassOrObject) { + if (classOrObject.isImplementingIterator()) { + val hasNextMethod = classOrObject.getMethod("hasNext") + if (hasNextMethod != null && callsNextMethod(hasNextMethod)) { + report(CodeSmell(issue, Entity.from(classOrObject), "Calling hasNext() on an Iterator should " + + "have no side-effects. Calling next() is a side effect.")) + } + } + super.visitClassOrObject(classOrObject) + } - private fun callsNextMethod(method: KtNamedFunction): Boolean { - return method.bodyExpression - ?.collectByType() - ?.any { it.calleeExpression?.text == "next" } == true - } + private fun callsNextMethod(method: KtNamedFunction): Boolean { + return method.bodyExpression + ?.collectByType() + ?.any { it.calleeExpression?.text == "next" } == true + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/IteratorNotThrowingNoSuchElementException.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/IteratorNotThrowingNoSuchElementException.kt index d5cb536ad..a8ed6f43d 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/IteratorNotThrowingNoSuchElementException.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/IteratorNotThrowingNoSuchElementException.kt @@ -45,20 +45,20 @@ import org.jetbrains.kotlin.psi.KtClassOrObject */ class IteratorNotThrowingNoSuchElementException(config: Config = Config.empty) : Rule(config) { - override val issue = Issue("IteratorNotThrowingNoSuchElementException", Severity.Defect, - "The next() method of an Iterator implementation should throw a NoSuchElementException " + - "when there are no more elements to return", - Debt.TEN_MINS) + override val issue = Issue("IteratorNotThrowingNoSuchElementException", Severity.Defect, + "The next() method of an Iterator implementation should throw a NoSuchElementException " + + "when there are no more elements to return", + Debt.TEN_MINS) - override fun visitClassOrObject(classOrObject: KtClassOrObject) { - if (classOrObject.isImplementingIterator()) { - val nextMethod = classOrObject.getMethod("next") - if (nextMethod != null && !nextMethod.throwsNoSuchElementExceptionThrown()) { - report(CodeSmell(issue, Entity.from(classOrObject), - "This implementation of Iterator does not correctly implement the next() method " + - "as it doesn't throw a NoSuchElementException when no elements remain in the Iterator.")) - } - } - super.visitClassOrObject(classOrObject) - } + override fun visitClassOrObject(classOrObject: KtClassOrObject) { + if (classOrObject.isImplementingIterator()) { + val nextMethod = classOrObject.getMethod("next") + if (nextMethod != null && !nextMethod.throwsNoSuchElementExceptionThrown()) { + report(CodeSmell(issue, Entity.from(classOrObject), + "This implementation of Iterator does not correctly implement the next() method " + + "as it doesn't throw a NoSuchElementException when no elements remain in the Iterator.")) + } + } + super.visitClassOrObject(classOrObject) + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/LateinitUsage.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/LateinitUsage.kt index adbfbc98f..a7ec7d606 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/LateinitUsage.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/LateinitUsage.kt @@ -6,10 +6,10 @@ import io.gitlab.arturbosch.detekt.api.Config import io.gitlab.arturbosch.detekt.api.Debt import io.gitlab.arturbosch.detekt.api.Entity import io.gitlab.arturbosch.detekt.api.Issue +import io.gitlab.arturbosch.detekt.api.LazyRegex import io.gitlab.arturbosch.detekt.api.Rule import io.gitlab.arturbosch.detekt.api.Severity import io.gitlab.arturbosch.detekt.api.SplitPattern -import io.gitlab.arturbosch.detekt.api.LazyRegex import io.gitlab.arturbosch.detekt.rules.isLateinit import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtProperty @@ -38,40 +38,40 @@ import org.jetbrains.kotlin.psi.psiUtil.containingClass */ class LateinitUsage(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, - Severity.Defect, - "Usage of lateinit detected. Using lateinit for property initialization " + - "is error prone, try using constructor injection or delegation.", - Debt.TWENTY_MINS) + override val issue = Issue(javaClass.simpleName, + Severity.Defect, + "Usage of lateinit detected. Using lateinit for property initialization " + + "is error prone, try using constructor injection or delegation.", + Debt.TWENTY_MINS) - private val excludeAnnotatedProperties = SplitPattern(valueOrDefault(EXCLUDE_ANNOTATED_PROPERTIES, "")) + private val excludeAnnotatedProperties = SplitPattern(valueOrDefault(EXCLUDE_ANNOTATED_PROPERTIES, "")) - private val ignoreOnClassesPattern by LazyRegex(key = IGNORE_ON_CLASSES_PATTERN, default = "") + private val ignoreOnClassesPattern by LazyRegex(key = IGNORE_ON_CLASSES_PATTERN, default = "") - private var properties = mutableListOf() + private var properties = mutableListOf() - override fun visitProperty(property: KtProperty) { - if (property.isLateinit()) { - properties.add(property) - } - } + override fun visitProperty(property: KtProperty) { + if (property.isLateinit()) { + properties.add(property) + } + } - override fun visit(root: KtFile) { - properties = mutableListOf() + override fun visit(root: KtFile) { + properties = mutableListOf() - super.visit(root) + super.visit(root) - val annotationExcluder = AnnotationExcluder(root, excludeAnnotatedProperties) + val annotationExcluder = AnnotationExcluder(root, excludeAnnotatedProperties) - properties.filterNot { annotationExcluder.shouldExclude(it.annotationEntries) } - .filterNot { it.containingClass()?.name?.matches(ignoreOnClassesPattern) == true } - .forEach { - report(CodeSmell(issue, Entity.from(it), "Usages of lateinit should be avoided.")) - } - } + properties.filterNot { annotationExcluder.shouldExclude(it.annotationEntries) } + .filterNot { it.containingClass()?.name?.matches(ignoreOnClassesPattern) == true } + .forEach { + report(CodeSmell(issue, Entity.from(it), "Usages of lateinit should be avoided.")) + } + } - companion object { - const val EXCLUDE_ANNOTATED_PROPERTIES = "excludeAnnotatedProperties" - const val IGNORE_ON_CLASSES_PATTERN = "ignoreOnClassesPattern" - } + companion object { + const val EXCLUDE_ANNOTATED_PROPERTIES = "excludeAnnotatedProperties" + const val IGNORE_ON_CLASSES_PATTERN = "ignoreOnClassesPattern" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnconditionalJumpStatementInLoop.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnconditionalJumpStatementInLoop.kt index be774ce65..e4b7d2d75 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnconditionalJumpStatementInLoop.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnconditionalJumpStatementInLoop.kt @@ -34,22 +34,22 @@ import org.jetbrains.kotlin.psi.KtReturnExpression */ class UnconditionalJumpStatementInLoop(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, Severity.Defect, - "An unconditional jump statement in a loop is useless. " + - "The loop itself is only executed once.", Debt.TEN_MINS) + override val issue = Issue(javaClass.simpleName, Severity.Defect, + "An unconditional jump statement in a loop is useless. " + + "The loop itself is only executed once.", Debt.TEN_MINS) - override fun visitLoopExpression(loopExpression: KtLoopExpression) { - if (hasJumpStatement(loopExpression.body)) { - report(CodeSmell(issue, Entity.from(loopExpression), "This loop contains an unconditional " + - "jump expression which " + - "essentially renders it useless as it will exit the loop during the first iteration.")) - } - super.visitLoopExpression(loopExpression) - } + override fun visitLoopExpression(loopExpression: KtLoopExpression) { + if (hasJumpStatement(loopExpression.body)) { + report(CodeSmell(issue, Entity.from(loopExpression), "This loop contains an unconditional " + + "jump expression which " + + "essentially renders it useless as it will exit the loop during the first iteration.")) + } + super.visitLoopExpression(loopExpression) + } - private fun hasJumpStatement(body: KtExpression?) = - isJumpStatement(body) || body?.children?.any { isJumpStatement(it) } == true + private fun hasJumpStatement(body: KtExpression?) = + isJumpStatement(body) || body?.children?.any { isJumpStatement(it) } == true - private fun isJumpStatement(element: PsiElement?) = - element is KtReturnExpression || element is KtBreakExpression || element is KtContinueExpression + private fun isJumpStatement(element: PsiElement?) = + element is KtReturnExpression || element is KtBreakExpression || element is KtContinueExpression } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnreachableCode.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnreachableCode.kt index 33b5e39b7..f21c8529d 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnreachableCode.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnreachableCode.kt @@ -40,33 +40,33 @@ import org.jetbrains.kotlin.psi.KtThrowExpression */ class UnreachableCode(config: Config = Config.empty) : Rule(config) { - override val issue = Issue("UnreachableCode", Severity.Warning, - "Unreachable code detected. This code should be removed", Debt.TEN_MINS) + override val issue = Issue("UnreachableCode", Severity.Warning, + "Unreachable code detected. This code should be removed", Debt.TEN_MINS) - override fun visitReturnExpression(expression: KtReturnExpression) { - followedByUnreachableCode(expression) - super.visitReturnExpression(expression) - } + override fun visitReturnExpression(expression: KtReturnExpression) { + followedByUnreachableCode(expression) + super.visitReturnExpression(expression) + } - override fun visitThrowExpression(expression: KtThrowExpression) { - followedByUnreachableCode(expression) - super.visitThrowExpression(expression) - } + override fun visitThrowExpression(expression: KtThrowExpression) { + followedByUnreachableCode(expression) + super.visitThrowExpression(expression) + } - override fun visitContinueExpression(expression: KtContinueExpression) { - followedByUnreachableCode(expression) - } + override fun visitContinueExpression(expression: KtContinueExpression) { + followedByUnreachableCode(expression) + } - override fun visitBreakExpression(expression: KtBreakExpression) { - followedByUnreachableCode(expression) - } + override fun visitBreakExpression(expression: KtBreakExpression) { + followedByUnreachableCode(expression) + } - private fun followedByUnreachableCode(expression: KtExpression) { - val statements = (expression.parent as? KtBlockExpression)?.statements ?: return - val indexOfStatement = statements.indexOf(expression) - if (indexOfStatement < statements.size - 1) { - report(CodeSmell(issue, Entity.from(expression), "This expression is followed by unreachable " + - "code which should either be used or removed.")) - } - } + private fun followedByUnreachableCode(expression: KtExpression) { + val statements = (expression.parent as? KtBlockExpression)?.statements ?: return + val indexOfStatement = statements.indexOf(expression) + if (indexOfStatement < statements.size - 1) { + report(CodeSmell(issue, Entity.from(expression), "This expression is followed by unreachable " + + "code which should either be used or removed.")) + } + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnsafeCallOnNullableType.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnsafeCallOnNullableType.kt index 73e23d239..f2431a348 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnsafeCallOnNullableType.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnsafeCallOnNullableType.kt @@ -31,16 +31,16 @@ import org.jetbrains.kotlin.psi.KtUnaryExpression * @author Marvin Ramin */ class UnsafeCallOnNullableType(config: Config = Config.empty) : Rule(config) { - override val issue: Issue = Issue("UnsafeCallOnNullableType", - Severity.Defect, - "It will throw a NullPointerException at runtime if your nullable value is null.", - Debt.TWENTY_MINS) + override val issue: Issue = Issue("UnsafeCallOnNullableType", + Severity.Defect, + "It will throw a NullPointerException at runtime if your nullable value is null.", + Debt.TWENTY_MINS) - override fun visitUnaryExpression(expression: KtUnaryExpression) { - super.visitUnaryExpression(expression) - if (expression.operationToken == KtTokens.EXCLEXCL) { - report(CodeSmell(issue, Entity.from(expression), "Calling !! on a nullable type will throw a " + - "NullPointerException at runtime in case the value is null. It should be avoided.")) - } - } + override fun visitUnaryExpression(expression: KtUnaryExpression) { + super.visitUnaryExpression(expression) + if (expression.operationToken == KtTokens.EXCLEXCL) { + report(CodeSmell(issue, Entity.from(expression), "Calling !! on a nullable type will throw a " + + "NullPointerException at runtime in case the value is null. It should be avoided.")) + } + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnsafeCast.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnsafeCast.kt index 485aff973..83285b365 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnsafeCast.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnsafeCast.kt @@ -30,17 +30,17 @@ import org.jetbrains.kotlin.psi.KtPsiUtil */ class UnsafeCast(config: Config = Config.empty) : Rule(config) { - override val defaultRuleIdAliases: Set = setOf("UNCHECKED_CAST") + override val defaultRuleIdAliases: Set = setOf("UNCHECKED_CAST") - override val issue: Issue = Issue("UnsafeCast", - Severity.Defect, - "Cast operator throws an exception if the cast is not possible.", - Debt.TWENTY_MINS) + override val issue: Issue = Issue("UnsafeCast", + Severity.Defect, + "Cast operator throws an exception if the cast is not possible.", + Debt.TWENTY_MINS) - override fun visitBinaryWithTypeRHSExpression(expression: KtBinaryExpressionWithTypeRHS) { - if (KtPsiUtil.isUnsafeCast(expression)) { - report(CodeSmell(issue, Entity.from(expression), - "${expression.left.text} cannot be safely cast to ${expression.right?.text ?: ""}.")) - } - } + override fun visitBinaryWithTypeRHSExpression(expression: KtBinaryExpressionWithTypeRHS) { + if (KtPsiUtil.isUnsafeCast(expression)) { + report(CodeSmell(issue, Entity.from(expression), + "${expression.left.text} cannot be safely cast to ${expression.right?.text ?: ""}.")) + } + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UselessPostfixExpression.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UselessPostfixExpression.kt index 57e2bbc06..bbca7ef4b 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UselessPostfixExpression.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UselessPostfixExpression.kt @@ -59,66 +59,66 @@ import org.jetbrains.kotlin.psi.psiUtil.isPropertyParameter */ class UselessPostfixExpression(config: Config = Config.empty) : Rule(config) { - override val issue: Issue = Issue("UselessPostfixExpression", Severity.Defect, - "The incremented or decremented value is unused. This value is replaced with the original value.", - Debt.TWENTY_MINS) + override val issue: Issue = Issue("UselessPostfixExpression", Severity.Defect, + "The incremented or decremented value is unused. This value is replaced with the original value.", + Debt.TWENTY_MINS) - var properties = setOf() + var properties = setOf() - override fun visitClass(klass: KtClass) { - properties = klass.getProperties() - .map { it.name } - .union(klass.primaryConstructorParameters.filter { it.isPropertyParameter() }.map { it.name }) - super.visitClass(klass) - } + override fun visitClass(klass: KtClass) { + properties = klass.getProperties() + .map { it.name } + .union(klass.primaryConstructorParameters.filter { it.isPropertyParameter() }.map { it.name }) + super.visitClass(klass) + } - override fun visitReturnExpression(expression: KtReturnExpression) { - val postfixExpression = expression.returnedExpression?.asPostFixExpression() + override fun visitReturnExpression(expression: KtReturnExpression) { + val postfixExpression = expression.returnedExpression?.asPostFixExpression() - if (postfixExpression != null && postfixExpression.shouldBeReported()) { - report(postfixExpression) - } + if (postfixExpression != null && postfixExpression.shouldBeReported()) { + report(postfixExpression) + } - getPostfixExpressionChilds(expression.returnedExpression) - ?.forEach { report(it) } - } + getPostfixExpressionChilds(expression.returnedExpression) + ?.forEach { report(it) } + } - override fun visitBinaryExpression(expression: KtBinaryExpression) { - val postfixExpression = expression.right?.asPostFixExpression() - val leftIdentifierText = expression.left?.text - checkPostfixExpression(postfixExpression, leftIdentifierText) - getPostfixExpressionChilds(expression.right) - ?.forEach { checkPostfixExpression(it, leftIdentifierText) } - } + override fun visitBinaryExpression(expression: KtBinaryExpression) { + val postfixExpression = expression.right?.asPostFixExpression() + val leftIdentifierText = expression.left?.text + checkPostfixExpression(postfixExpression, leftIdentifierText) + getPostfixExpressionChilds(expression.right) + ?.forEach { checkPostfixExpression(it, leftIdentifierText) } + } - private fun KtExpression.asPostFixExpression() = if (this is KtPostfixExpression && - (operationToken === PLUSPLUS || operationToken === MINUSMINUS)) this else null + private fun KtExpression.asPostFixExpression() = if (this is KtPostfixExpression && + (operationToken === PLUSPLUS || operationToken === MINUSMINUS)) this else null - private fun checkPostfixExpression(postfixExpression: KtPostfixExpression?, leftIdentifierText: String?) { - if (postfixExpression != null && leftIdentifierText == postfixExpression.firstChild?.text) { - report(postfixExpression) - } - } + private fun checkPostfixExpression(postfixExpression: KtPostfixExpression?, leftIdentifierText: String?) { + if (postfixExpression != null && leftIdentifierText == postfixExpression.firstChild?.text) { + report(postfixExpression) + } + } - private fun KtPostfixExpression.shouldBeReported(): Boolean { - val functionProperties = this.getNonStrictParentOfType() - ?.collectByType() - ?.map { it.name } - ?.toSet() - val postfixReceiverName = this.baseExpression?.text + private fun KtPostfixExpression.shouldBeReported(): Boolean { + val functionProperties = this.getNonStrictParentOfType() + ?.collectByType() + ?.map { it.name } + ?.toSet() + val postfixReceiverName = this.baseExpression?.text - if (functionProperties != null && functionProperties.contains(postfixReceiverName)) { - return true - } - return !properties.contains(postfixReceiverName) - } + if (functionProperties != null && functionProperties.contains(postfixReceiverName)) { + return true + } + return !properties.contains(postfixReceiverName) + } - private fun report(postfixExpression: KtPostfixExpression) { - report(CodeSmell(issue, Entity.from(postfixExpression), "The result of the postfix expression: " + - "${postfixExpression.text} will not be used and is therefore useless.")) - } + private fun report(postfixExpression: KtPostfixExpression) { + report(CodeSmell(issue, Entity.from(postfixExpression), "The result of the postfix expression: " + + "${postfixExpression.text} will not be used and is therefore useless.")) + } - private fun getPostfixExpressionChilds(expression: KtExpression?) = - expression?.children?.filterIsInstance() - ?.filter { it.operationToken === PLUSPLUS || it.operationToken === MINUSMINUS } + private fun getPostfixExpressionChilds(expression: KtExpression?) = + expression?.children?.filterIsInstance() + ?.filter { it.operationToken === PLUSPLUS || it.operationToken === MINUSMINUS } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/WrongEqualsTypeParameter.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/WrongEqualsTypeParameter.kt index 5161726ad..7bcd8d4e5 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/WrongEqualsTypeParameter.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/WrongEqualsTypeParameter.kt @@ -39,22 +39,22 @@ import org.jetbrains.kotlin.psi.KtNamedFunction */ class WrongEqualsTypeParameter(config: Config = Config.empty) : Rule(config) { - override val issue = Issue("WrongEqualsTypeParameter", Severity.Defect, - "Wrong parameter type for equals() method found. " + - "To correctly override the equals() method use Any?", - Debt.TEN_MINS) + override val issue = Issue("WrongEqualsTypeParameter", Severity.Defect, + "Wrong parameter type for equals() method found. " + + "To correctly override the equals() method use Any?", + Debt.TEN_MINS) - override fun visitClass(klass: KtClass) { - if (klass.isInterface()) { - return - } - super.visitClass(klass) - } + override fun visitClass(klass: KtClass) { + if (klass.isInterface()) { + return + } + super.visitClass(klass) + } - override fun visitNamedFunction(function: KtNamedFunction) { - if (function.name == "equals" && !function.hasCorrectEqualsParameter()) { - report(CodeSmell(issue, Entity.from(function), "equals() methods should only take one parameter " + - "of type Any?.")) - } - } + override fun visitNamedFunction(function: KtNamedFunction) { + if (function.name == "equals" && !function.hasCorrectEqualsParameter()) { + report(CodeSmell(issue, Entity.from(function), "equals() methods should only take one parameter " + + "of type Any?.")) + } + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/util/IteratorExtension.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/util/IteratorExtension.kt index 5f96d9ff9..d88c4f2e4 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/util/IteratorExtension.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/util/IteratorExtension.kt @@ -7,23 +7,23 @@ import org.jetbrains.kotlin.psi.KtNamedFunction import org.jetbrains.kotlin.psi.KtThrowExpression internal fun KtClassOrObject.isImplementingIterator(): Boolean { - val typeList = this.getSuperTypeList()?.entries - val name = typeList?.firstOrNull()?.typeAsUserType?.referencedName - return name == "Iterator" + val typeList = this.getSuperTypeList()?.entries + val name = typeList?.firstOrNull()?.typeAsUserType?.referencedName + return name == "Iterator" } internal fun KtClassOrObject.getMethod(name: String): KtNamedFunction? { - val functions = this.declarations.filterIsInstance() - return functions.firstOrNull { it.name == name && it.valueParameters.isEmpty() } + val functions = this.declarations.filterIsInstance() + return functions.firstOrNull { it.name == name && it.valueParameters.isEmpty() } } internal fun KtNamedFunction.throwsNoSuchElementExceptionThrown(): Boolean { - return this.bodyExpression - ?.collectByType() - ?.any { isNoSuchElementExpression(it) } ?: false + return this.bodyExpression + ?.collectByType() + ?.any { isNoSuchElementExpression(it) } ?: false } private fun isNoSuchElementExpression(expression: KtThrowExpression): Boolean { - val calleeExpression = (expression.thrownExpression as? KtCallExpression)?.calleeExpression - return calleeExpression?.text == "NoSuchElementException" + val calleeExpression = (expression.thrownExpression as? KtCallExpression)?.calleeExpression + return calleeExpression?.text == "NoSuchElementException" } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/ComplexCondition.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/ComplexCondition.kt index 0626a97ae..994b97b6e 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/ComplexCondition.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/ComplexCondition.kt @@ -42,67 +42,69 @@ import org.jetbrains.kotlin.psi.KtWhileExpression * @author Artur Bosch * @author Marvin Ramin */ -class ComplexCondition(config: Config = Config.empty, - threshold: Int = DEFAULT_CONDITIONS_COUNT) : ThresholdRule(config, threshold) { +class ComplexCondition( + config: Config = Config.empty, + threshold: Int = DEFAULT_CONDITIONS_COUNT +) : ThresholdRule(config, threshold) { - override val issue = Issue("ComplexCondition", Severity.Maintainability, - "Complex conditions should be simplified and extracted into well-named methods if necessary.", - Debt.TWENTY_MINS) + override val issue = Issue("ComplexCondition", Severity.Maintainability, + "Complex conditions should be simplified and extracted into well-named methods if necessary.", + Debt.TWENTY_MINS) - override fun visitIfExpression(expression: KtIfExpression) { - val condition = expression.condition - checkIfComplex(condition) - super.visitIfExpression(expression) - } + override fun visitIfExpression(expression: KtIfExpression) { + val condition = expression.condition + checkIfComplex(condition) + super.visitIfExpression(expression) + } - override fun visitDoWhileExpression(expression: KtDoWhileExpression) { - val condition = expression.condition - checkIfComplex(condition) - super.visitDoWhileExpression(expression) - } + override fun visitDoWhileExpression(expression: KtDoWhileExpression) { + val condition = expression.condition + checkIfComplex(condition) + super.visitDoWhileExpression(expression) + } - override fun visitWhileExpression(expression: KtWhileExpression) { - val condition = expression.condition - checkIfComplex(condition) - super.visitWhileExpression(expression) - } + override fun visitWhileExpression(expression: KtWhileExpression) { + val condition = expression.condition + checkIfComplex(condition) + super.visitWhileExpression(expression) + } - private fun checkIfComplex(condition: KtExpression?) { - val binaryExpressions = condition?.collectByType() + private fun checkIfComplex(condition: KtExpression?) { + val binaryExpressions = condition?.collectByType() - if (binaryExpressions != null && binaryExpressions.size > 1) { - val longestBinExpr = binaryExpressions.reduce { acc, binExpr -> - if (binExpr.text.length > acc.text.length) binExpr else acc - } - val conditionString = longestBinExpr.text - val count = frequency(conditionString, "&&") + frequency(conditionString, "||") + 1 - if (count >= threshold) { - report(ThresholdedCodeSmell(issue, - Entity.from(condition), - Metric("SIZE", count, threshold), - "This condition is too complex.")) - } - } - } + if (binaryExpressions != null && binaryExpressions.size > 1) { + val longestBinExpr = binaryExpressions.reduce { acc, binExpr -> + if (binExpr.text.length > acc.text.length) binExpr else acc + } + val conditionString = longestBinExpr.text + val count = frequency(conditionString, "&&") + frequency(conditionString, "||") + 1 + if (count >= threshold) { + report(ThresholdedCodeSmell(issue, + Entity.from(condition), + Metric("SIZE", count, threshold), + "This condition is too complex.")) + } + } + } - private fun frequency(source: String, part: String): Int { + private fun frequency(source: String, part: String): Int { - if (source.isEmpty() || part.isEmpty()) { - return 0 - } + if (source.isEmpty() || part.isEmpty()) { + return 0 + } - var count = 0 - var pos = source.indexOf(part, 0) - while (pos != -1) { - pos += part.length - count++ - pos = source.indexOf(part, pos) - } + var count = 0 + var pos = source.indexOf(part, 0) + while (pos != -1) { + pos += part.length + count++ + pos = source.indexOf(part, pos) + } - return count - } + return count + } - companion object { - const val DEFAULT_CONDITIONS_COUNT = 4 - } + companion object { + const val DEFAULT_CONDITIONS_COUNT = 4 + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/ComplexInterface.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/ComplexInterface.kt index 6e47ce435..4ad1d1068 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/ComplexInterface.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/ComplexInterface.kt @@ -29,44 +29,46 @@ import org.jetbrains.kotlin.psi.KtProperty * @author schalkms * @author Marvin Ramin */ -class ComplexInterface(config: Config = Config.empty, - threshold: Int = DEFAULT_LARGE_INTERFACE_COUNT) : ThresholdRule(config, threshold) { +class ComplexInterface( + config: Config = Config.empty, + threshold: Int = DEFAULT_LARGE_INTERFACE_COUNT +) : ThresholdRule(config, threshold) { - override val issue = Issue(javaClass.simpleName, Severity.Maintainability, - "An interface contains too many functions and properties. " + - "Large classes tend to handle many things at once. " + - "An interface should have one responsibility. " + - "Split up large interfaces into smaller ones that are easier to understand.", - Debt.TWENTY_MINS) + override val issue = Issue(javaClass.simpleName, Severity.Maintainability, + "An interface contains too many functions and properties. " + + "Large classes tend to handle many things at once. " + + "An interface should have one responsibility. " + + "Split up large interfaces into smaller ones that are easier to understand.", + Debt.TWENTY_MINS) - private val includeStaticDeclarations = valueOrDefault(INCLUDE_STATIC_DECLARATIONS, false) + private val includeStaticDeclarations = valueOrDefault(INCLUDE_STATIC_DECLARATIONS, false) - override fun visitClass(klass: KtClass) { - if (klass.isInterface()) { - val body = klass.body ?: return - var size = calculateMembers(body) - if (includeStaticDeclarations) { - size += countStaticDeclarations(klass.companionObject()) - } - if (size >= threshold) { - report(ThresholdedCodeSmell(issue, - Entity.from(klass), - Metric("SIZE: ", size, threshold), - "The interface ${klass.name} is too complex. Consider splitting it up.")) - } - } - super.visitClass(klass) - } + override fun visitClass(klass: KtClass) { + if (klass.isInterface()) { + val body = klass.body ?: return + var size = calculateMembers(body) + if (includeStaticDeclarations) { + size += countStaticDeclarations(klass.companionObject()) + } + if (size >= threshold) { + report(ThresholdedCodeSmell(issue, + Entity.from(klass), + Metric("SIZE: ", size, threshold), + "The interface ${klass.name} is too complex. Consider splitting it up.")) + } + } + super.visitClass(klass) + } - private fun countStaticDeclarations(companionObject: KtObjectDeclaration?): Int { - val body = companionObject?.body - return if (body != null) calculateMembers(body) else 0 - } + private fun countStaticDeclarations(companionObject: KtObjectDeclaration?): Int { + val body = companionObject?.body + return if (body != null) calculateMembers(body) else 0 + } - private fun calculateMembers(body: KtClassBody) = body.children.count { it is KtNamedFunction || it is KtProperty } + private fun calculateMembers(body: KtClassBody) = body.children.count { it is KtNamedFunction || it is KtProperty } - companion object { - const val INCLUDE_STATIC_DECLARATIONS = "includeStaticDeclarations" - const val DEFAULT_LARGE_INTERFACE_COUNT = 10 - } + companion object { + const val INCLUDE_STATIC_DECLARATIONS = "includeStaticDeclarations" + const val DEFAULT_LARGE_INTERFACE_COUNT = 10 + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/ComplexMethod.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/ComplexMethod.kt index 41008836f..16b2811e9 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/ComplexMethod.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/ComplexMethod.kt @@ -30,51 +30,53 @@ import org.jetbrains.kotlin.psi.KtWhenExpression * @author Marvin Ramin * @author schalkms */ -class ComplexMethod(config: Config = Config.empty, - threshold: Int = DEFAULT_ACCEPTED_METHOD_COMPLEXITY) : ThresholdRule(config, threshold) { +class ComplexMethod( + config: Config = Config.empty, + threshold: Int = DEFAULT_ACCEPTED_METHOD_COMPLEXITY +) : ThresholdRule(config, threshold) { - override val issue = Issue("ComplexMethod", - Severity.Maintainability, - "Prefer splitting up complex methods into smaller, easier to understand methods.", - Debt.TWENTY_MINS) + override val issue = Issue("ComplexMethod", + Severity.Maintainability, + "Prefer splitting up complex methods into smaller, easier to understand methods.", + Debt.TWENTY_MINS) - private val ignoreSingleWhenExpression = valueOrDefault(IGNORE_SINGLE_WHEN_EXPRESSION, false) - private val ignoreSimpleWhenEntries = valueOrDefault(IGNORE_SIMPLE_WHEN_ENTRIES, false) + private val ignoreSingleWhenExpression = valueOrDefault(IGNORE_SINGLE_WHEN_EXPRESSION, false) + private val ignoreSimpleWhenEntries = valueOrDefault(IGNORE_SIMPLE_WHEN_ENTRIES, false) - override fun visitNamedFunction(function: KtNamedFunction) { - if (hasSingleWhenExpression(function.bodyExpression)) { - return - } - val visitor = McCabeVisitor(ignoreSimpleWhenEntries) - visitor.visitNamedFunction(function) - val mcc = visitor.mcc - if (mcc >= threshold) { - report(ThresholdedCodeSmell(issue, - Entity.from(function), - Metric("MCC", mcc, threshold), - "The function ${function.nameAsSafeName} appears to be too complex.")) - } - } + override fun visitNamedFunction(function: KtNamedFunction) { + if (hasSingleWhenExpression(function.bodyExpression)) { + return + } + val visitor = McCabeVisitor(ignoreSimpleWhenEntries) + visitor.visitNamedFunction(function) + val mcc = visitor.mcc + if (mcc >= threshold) { + report(ThresholdedCodeSmell(issue, + Entity.from(function), + Metric("MCC", mcc, threshold), + "The function ${function.nameAsSafeName} appears to be too complex.")) + } + } - private fun hasSingleWhenExpression(bodyExpression: KtExpression?): Boolean { - if (ignoreSingleWhenExpression) { - return when { - bodyExpression is KtBlockExpression && bodyExpression.statements.size == 1 -> { - val statement = bodyExpression.statements.single() - statement is KtWhenExpression || - (statement is KtReturnExpression && statement.returnedExpression is KtWhenExpression) - } - // the case where function-expression syntax is used: `fun test() = when { ... }` - bodyExpression is KtWhenExpression -> true - else -> false - } - } - return false - } + private fun hasSingleWhenExpression(bodyExpression: KtExpression?): Boolean { + if (ignoreSingleWhenExpression) { + return when { + bodyExpression is KtBlockExpression && bodyExpression.statements.size == 1 -> { + val statement = bodyExpression.statements.single() + statement is KtWhenExpression || + (statement is KtReturnExpression && statement.returnedExpression is KtWhenExpression) + } + // the case where function-expression syntax is used: `fun test() = when { ... }` + bodyExpression is KtWhenExpression -> true + else -> false + } + } + return false + } - companion object { - const val DEFAULT_ACCEPTED_METHOD_COMPLEXITY = 10 - const val IGNORE_SINGLE_WHEN_EXPRESSION = "ignoreSingleWhenExpression" - const val IGNORE_SIMPLE_WHEN_ENTRIES = "ignoreSimpleWhenEntries" - } + companion object { + const val DEFAULT_ACCEPTED_METHOD_COMPLEXITY = 10 + const val IGNORE_SINGLE_WHEN_EXPRESSION = "ignoreSingleWhenExpression" + const val IGNORE_SIMPLE_WHEN_ENTRIES = "ignoreSimpleWhenEntries" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LabeledExpression.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LabeledExpression.kt index 1559c345f..5aefa285a 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LabeledExpression.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LabeledExpression.kt @@ -67,46 +67,46 @@ import org.jetbrains.kotlin.psi.psiUtil.parents */ class LabeledExpression(config: Config = Config.empty) : Rule(config) { - override val issue: Issue = Issue("LabeledExpression", - Severity.Maintainability, - "Expression with labels increase complexity and affect maintainability.", - Debt.TWENTY_MINS) + override val issue: Issue = Issue("LabeledExpression", + Severity.Maintainability, + "Expression with labels increase complexity and affect maintainability.", + Debt.TWENTY_MINS) - private val ignoredLabels = SplitPattern(valueOrDefault(IGNORED_LABELS, "")) + private val ignoredLabels = SplitPattern(valueOrDefault(IGNORED_LABELS, "")) - override fun visitExpressionWithLabel(expression: KtExpressionWithLabel) { - super.visitExpressionWithLabel(expression) - if (expression !is KtThisExpression || isNotReferencingOuterClass(expression)) { - expression.getLabelName()?.let { - if (!ignoredLabels.contains(it)) { - report(CodeSmell(issue, Entity.from(expression), issue.description)) - } - } - } - } - - private fun isNotReferencingOuterClass(expression: KtExpressionWithLabel): Boolean { - val containingClasses = mutableListOf() - val containingClass = expression.containingClass() ?: return false - if (isAllowedToReferenceContainingClass(containingClass, expression)) { - containingClasses.add(containingClass) - } - getClassHierarchy(containingClass, containingClasses) - return !containingClasses.any { it.name == expression.getLabelName() } - } - - private fun isAllowedToReferenceContainingClass(klass: KtClass, expression: KtExpressionWithLabel): Boolean { - return !klass.isInner() || - expression.parents.filterIsInstance().any { it.isExtensionDeclaration() } + override fun visitExpressionWithLabel(expression: KtExpressionWithLabel) { + super.visitExpressionWithLabel(expression) + if (expression !is KtThisExpression || isNotReferencingOuterClass(expression)) { + expression.getLabelName()?.let { + if (!ignoredLabels.contains(it)) { + report(CodeSmell(issue, Entity.from(expression), issue.description)) + } + } + } } - private fun getClassHierarchy(element: KtElement, classes: MutableList) { - val containingClass = element.containingClass() ?: return - classes.add(containingClass) - getClassHierarchy(containingClass, classes) - } + private fun isNotReferencingOuterClass(expression: KtExpressionWithLabel): Boolean { + val containingClasses = mutableListOf() + val containingClass = expression.containingClass() ?: return false + if (isAllowedToReferenceContainingClass(containingClass, expression)) { + containingClasses.add(containingClass) + } + getClassHierarchy(containingClass, containingClasses) + return !containingClasses.any { it.name == expression.getLabelName() } + } - companion object { - const val IGNORED_LABELS = "ignoredLabels" - } + private fun isAllowedToReferenceContainingClass(klass: KtClass, expression: KtExpressionWithLabel): Boolean { + return !klass.isInner() || + expression.parents.filterIsInstance().any { it.isExtensionDeclaration() } + } + + private fun getClassHierarchy(element: KtElement, classes: MutableList) { + val containingClass = element.containingClass() ?: return + classes.add(containingClass) + getClassHierarchy(containingClass, classes) + } + + companion object { + const val IGNORED_LABELS = "ignoredLabels" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LargeClass.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LargeClass.kt index 4dc610088..6da8fd3a7 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LargeClass.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LargeClass.kt @@ -10,10 +10,10 @@ import io.gitlab.arturbosch.detekt.api.ThresholdRule import io.gitlab.arturbosch.detekt.api.ThresholdedCodeSmell import io.gitlab.arturbosch.detekt.rules.linesOfCode import io.gitlab.arturbosch.detekt.rules.parentOfType +import java.util.IdentityHashMap import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.utils.addToStdlib.flattenTo -import java.util.IdentityHashMap /** * This rule reports large classes. Classes should generally have one responsibility. Large classes can indicate that @@ -27,55 +27,57 @@ import java.util.IdentityHashMap * @author Artur Bosch * @author Marvin Ramin */ -class LargeClass(config: Config = Config.empty, - threshold: Int = DEFAULT_ACCEPTED_CLASS_LENGTH) : ThresholdRule(config, threshold) { +class LargeClass( + config: Config = Config.empty, + threshold: Int = DEFAULT_ACCEPTED_CLASS_LENGTH +) : ThresholdRule(config, threshold) { - override val issue = Issue("LargeClass", - Severity.Maintainability, - "One class should have one responsibility. Large classes tend to handle many things at once. " + - "Split up large classes into smaller classes that are easier to understand.", - Debt.TWENTY_MINS) + override val issue = Issue("LargeClass", + Severity.Maintainability, + "One class should have one responsibility. Large classes tend to handle many things at once. " + + "Split up large classes into smaller classes that are easier to understand.", + Debt.TWENTY_MINS) - private val classToLinesCache = IdentityHashMap() - private val nestedClassTracking = IdentityHashMap>() + private val classToLinesCache = IdentityHashMap() + private val nestedClassTracking = IdentityHashMap>() - override fun preVisit(root: KtFile) { - classToLinesCache.clear() - nestedClassTracking.clear() - } + override fun preVisit(root: KtFile) { + classToLinesCache.clear() + nestedClassTracking.clear() + } - override fun postVisit(root: KtFile) { - for ((clazz, lines) in classToLinesCache) { - if (lines >= threshold) { - report(ThresholdedCodeSmell(issue, - Entity.from(clazz), - Metric("SIZE", lines, threshold), - "Class ${clazz.name} is too large. Consider splitting it into smaller pieces.")) - } - } - } + override fun postVisit(root: KtFile) { + for ((clazz, lines) in classToLinesCache) { + if (lines >= threshold) { + report(ThresholdedCodeSmell(issue, + Entity.from(clazz), + Metric("SIZE", lines, threshold), + "Class ${clazz.name} is too large. Consider splitting it into smaller pieces.")) + } + } + } - override fun visitClassOrObject(classOrObject: KtClassOrObject) { - val lines = classOrObject.linesOfCode() - classToLinesCache[classOrObject] = lines - classOrObject.parentOfType() - ?.let { nestedClassTracking.getOrPut(it) { HashSet() }.add(classOrObject) } - super.visitClassOrObject(classOrObject) - findAllNestedClasses(classOrObject) - .fold(0) { acc, next -> acc + (classToLinesCache[next] ?: 0) } - .takeIf { it > 0 } - ?.let { classToLinesCache[classOrObject] = lines - it } - } + override fun visitClassOrObject(classOrObject: KtClassOrObject) { + val lines = classOrObject.linesOfCode() + classToLinesCache[classOrObject] = lines + classOrObject.parentOfType() + ?.let { nestedClassTracking.getOrPut(it) { HashSet() }.add(classOrObject) } + super.visitClassOrObject(classOrObject) + findAllNestedClasses(classOrObject) + .fold(0) { acc, next -> acc + (classToLinesCache[next] ?: 0) } + .takeIf { it > 0 } + ?.let { classToLinesCache[classOrObject] = lines - it } + } - private fun findAllNestedClasses(startClass: KtClassOrObject): Sequence = sequence { - var nestedClasses = nestedClassTracking[startClass] - while (!nestedClasses.isNullOrEmpty()) { - yieldAll(nestedClasses) - nestedClasses = nestedClasses.mapNotNull { nestedClassTracking[it] }.flattenTo(HashSet()) - } - } + private fun findAllNestedClasses(startClass: KtClassOrObject): Sequence = sequence { + var nestedClasses = nestedClassTracking[startClass] + while (!nestedClasses.isNullOrEmpty()) { + yieldAll(nestedClasses) + nestedClasses = nestedClasses.mapNotNull { nestedClassTracking[it] }.flattenTo(HashSet()) + } + } - companion object { - const val DEFAULT_ACCEPTED_CLASS_LENGTH = 600 - } + companion object { + const val DEFAULT_ACCEPTED_CLASS_LENGTH = 600 + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LongMethod.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LongMethod.kt index 24776f4bc..edbfabc11 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LongMethod.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LongMethod.kt @@ -10,10 +10,10 @@ import io.gitlab.arturbosch.detekt.api.ThresholdRule import io.gitlab.arturbosch.detekt.api.ThresholdedCodeSmell import io.gitlab.arturbosch.detekt.rules.linesOfCode import io.gitlab.arturbosch.detekt.rules.parentOfType +import java.util.IdentityHashMap import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtNamedFunction import org.jetbrains.kotlin.utils.addToStdlib.flattenTo -import java.util.IdentityHashMap /** * Methods should have one responsibility. Long methods can indicate that a method handles too many cases at once. @@ -27,56 +27,58 @@ import java.util.IdentityHashMap * @author Artur Bosch * @author Marvin Ramin */ -class LongMethod(config: Config = Config.empty, - threshold: Int = DEFAULT_ACCEPTED_METHOD_LENGTH) : ThresholdRule(config, threshold) { +class LongMethod( + config: Config = Config.empty, + threshold: Int = DEFAULT_ACCEPTED_METHOD_LENGTH +) : ThresholdRule(config, threshold) { - override val issue = Issue("LongMethod", - Severity.Maintainability, - "One method should have one responsibility. Long methods tend to handle many things at once. " + - "Prefer smaller methods to make them easier to understand.", - Debt.TWENTY_MINS) + override val issue = Issue("LongMethod", + Severity.Maintainability, + "One method should have one responsibility. Long methods tend to handle many things at once. " + + "Prefer smaller methods to make them easier to understand.", + Debt.TWENTY_MINS) - private val functionToLinesCache = HashMap() - private val nestedFunctionTracking = IdentityHashMap>() + private val functionToLinesCache = HashMap() + private val nestedFunctionTracking = IdentityHashMap>() - override fun preVisit(root: KtFile) { - functionToLinesCache.clear() - nestedFunctionTracking.clear() - } + override fun preVisit(root: KtFile) { + functionToLinesCache.clear() + nestedFunctionTracking.clear() + } - override fun postVisit(root: KtFile) { - for ((function, lines) in functionToLinesCache) { - if (lines >= threshold) { - report(ThresholdedCodeSmell(issue, - Entity.from(function), - Metric("SIZE", lines, threshold), - "The function ${function.nameAsSafeName} is too long. " + - "The maximum length is $threshold.")) - } - } - } + override fun postVisit(root: KtFile) { + for ((function, lines) in functionToLinesCache) { + if (lines >= threshold) { + report(ThresholdedCodeSmell(issue, + Entity.from(function), + Metric("SIZE", lines, threshold), + "The function ${function.nameAsSafeName} is too long. " + + "The maximum length is $threshold.")) + } + } + } - override fun visitNamedFunction(function: KtNamedFunction) { - val lines = function.linesOfCode() - functionToLinesCache[function] = lines - function.parentOfType() - ?.let { nestedFunctionTracking.getOrPut(it) { HashSet() }.add(function) } - super.visitNamedFunction(function) - findAllNestedFunctions(function) - .fold(0) { acc, next -> acc + (functionToLinesCache[next] ?: 0) } - .takeIf { it > 0 } - ?.let { functionToLinesCache[function] = lines - it } - } + override fun visitNamedFunction(function: KtNamedFunction) { + val lines = function.linesOfCode() + functionToLinesCache[function] = lines + function.parentOfType() + ?.let { nestedFunctionTracking.getOrPut(it) { HashSet() }.add(function) } + super.visitNamedFunction(function) + findAllNestedFunctions(function) + .fold(0) { acc, next -> acc + (functionToLinesCache[next] ?: 0) } + .takeIf { it > 0 } + ?.let { functionToLinesCache[function] = lines - it } + } - private fun findAllNestedFunctions(startFunction: KtNamedFunction): Sequence = sequence { - var nestedFunctions = nestedFunctionTracking[startFunction] - while (!nestedFunctions.isNullOrEmpty()) { - yieldAll(nestedFunctions) - nestedFunctions = nestedFunctions.mapNotNull { nestedFunctionTracking[it] }.flattenTo(HashSet()) - } - } + private fun findAllNestedFunctions(startFunction: KtNamedFunction): Sequence = sequence { + var nestedFunctions = nestedFunctionTracking[startFunction] + while (!nestedFunctions.isNullOrEmpty()) { + yieldAll(nestedFunctions) + nestedFunctions = nestedFunctions.mapNotNull { nestedFunctionTracking[it] }.flattenTo(HashSet()) + } + } - companion object { - const val DEFAULT_ACCEPTED_METHOD_LENGTH = 60 - } + companion object { + const val DEFAULT_ACCEPTED_METHOD_LENGTH = 60 + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LongParameterList.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LongParameterList.kt index 85d5bdc5b..96623bc6a 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LongParameterList.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LongParameterList.kt @@ -23,42 +23,44 @@ import org.jetbrains.kotlin.psi.KtParameterList * @author Marvin Ramin * @author Serj Lotutovici */ -class LongParameterList(config: Config = Config.empty, - threshold: Int = DEFAULT_ACCEPTED_PARAMETER_LENGTH) : ThresholdRule(config, threshold) { +class LongParameterList( + config: Config = Config.empty, + threshold: Int = DEFAULT_ACCEPTED_PARAMETER_LENGTH +) : ThresholdRule(config, threshold) { - override val issue = Issue("LongParameterList", - Severity.Maintainability, - "The more parameters a method has the more complex it is. Long parameter lists are often " + - "used to control complex algorithms and violate the Single Responsibility Principle. " + - "Prefer methods with short parameter lists.", - Debt.TWENTY_MINS) + override val issue = Issue("LongParameterList", + Severity.Maintainability, + "The more parameters a method has the more complex it is. Long parameter lists are often " + + "used to control complex algorithms and violate the Single Responsibility Principle. " + + "Prefer methods with short parameter lists.", + Debt.TWENTY_MINS) - private val ignoreDefaultParameters = valueOrDefault(IGNORE_DEFAULT_PARAMETERS, false) + private val ignoreDefaultParameters = valueOrDefault(IGNORE_DEFAULT_PARAMETERS, false) - override fun visitNamedFunction(function: KtNamedFunction) { - if (function.isOverride()) return - val parameterList = function.valueParameterList - val parameters = parameterList?.parameterCount() + override fun visitNamedFunction(function: KtNamedFunction) { + if (function.isOverride()) return + val parameterList = function.valueParameterList + val parameters = parameterList?.parameterCount() - if (parameters != null && parameters >= threshold) { - report(ThresholdedCodeSmell(issue, - Entity.from(parameterList), - Metric("SIZE", parameters, threshold), - "The function ${function.nameAsSafeName} has too many parameters. The current threshold" + - " is set to $threshold.")) - } - } + if (parameters != null && parameters >= threshold) { + report(ThresholdedCodeSmell(issue, + Entity.from(parameterList), + Metric("SIZE", parameters, threshold), + "The function ${function.nameAsSafeName} has too many parameters. The current threshold" + + " is set to $threshold.")) + } + } - private fun KtParameterList.parameterCount(): Int { - return if (ignoreDefaultParameters) { - parameters.filter { !it.hasDefaultValue() }.size - } else { - parameters.size - } - } + private fun KtParameterList.parameterCount(): Int { + return if (ignoreDefaultParameters) { + parameters.filter { !it.hasDefaultValue() }.size + } else { + parameters.size + } + } - companion object { - const val IGNORE_DEFAULT_PARAMETERS = "ignoreDefaultParameters" - const val DEFAULT_ACCEPTED_PARAMETER_LENGTH = 6 - } + companion object { + const val IGNORE_DEFAULT_PARAMETERS = "ignoreDefaultParameters" + const val DEFAULT_ACCEPTED_PARAMETER_LENGTH = 6 + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/MethodOverloading.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/MethodOverloading.kt index 813f9c48d..da18fe1b7 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/MethodOverloading.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/MethodOverloading.kt @@ -26,53 +26,55 @@ import org.jetbrains.kotlin.psi.psiUtil.isExtensionDeclaration * @author schalkms * @author Marvin Ramin */ -class MethodOverloading(config: Config = Config.empty, - threshold: Int = DEFAULT_ACCEPTED_OVERLOAD_COUNT) : ThresholdRule(config, threshold) { +class MethodOverloading( + config: Config = Config.empty, + threshold: Int = DEFAULT_ACCEPTED_OVERLOAD_COUNT +) : ThresholdRule(config, threshold) { - override val issue = Issue("MethodOverloading", Severity.Maintainability, - "Methods which are overloaded often might be harder to maintain. " + - "Furthermore, these methods are tightly coupled. " + - "Refactor these methods and try to use optional parameters.", - Debt.TWENTY_MINS) + override val issue = Issue("MethodOverloading", Severity.Maintainability, + "Methods which are overloaded often might be harder to maintain. " + + "Furthermore, these methods are tightly coupled. " + + "Refactor these methods and try to use optional parameters.", + Debt.TWENTY_MINS) - override fun visitClass(klass: KtClass) { - val visitor = OverloadedMethodVisitor() - klass.accept(visitor) - visitor.reportIfThresholdExceeded(klass) - super.visitClass(klass) - } + override fun visitClass(klass: KtClass) { + val visitor = OverloadedMethodVisitor() + klass.accept(visitor) + visitor.reportIfThresholdExceeded(klass) + super.visitClass(klass) + } - override fun visitKtFile(file: KtFile) { - val visitor = OverloadedMethodVisitor() - file.children.filterIsInstance().forEach { it.accept(visitor) } - visitor.reportIfThresholdExceeded(file) - super.visitKtFile(file) - } + override fun visitKtFile(file: KtFile) { + val visitor = OverloadedMethodVisitor() + file.children.filterIsInstance().forEach { it.accept(visitor) } + visitor.reportIfThresholdExceeded(file) + super.visitKtFile(file) + } - internal inner class OverloadedMethodVisitor : DetektVisitor() { + internal inner class OverloadedMethodVisitor : DetektVisitor() { - private var methods = HashMap() + private var methods = HashMap() - fun reportIfThresholdExceeded(element: PsiElement) { - methods.filterValues { it >= threshold }.forEach { - report(ThresholdedCodeSmell(issue, - Entity.from(element), - Metric("OVERLOAD SIZE: ", it.value, threshold), - message = "The method '${it.key}' is overloaded ${it.value} times.")) - } - } + fun reportIfThresholdExceeded(element: PsiElement) { + methods.filterValues { it >= threshold }.forEach { + report(ThresholdedCodeSmell(issue, + Entity.from(element), + Metric("OVERLOAD SIZE: ", it.value, threshold), + message = "The method '${it.key}' is overloaded ${it.value} times.")) + } + } - override fun visitNamedFunction(function: KtNamedFunction) { - var name = function.name ?: return - val receiver = function.receiverTypeReference - if (function.isExtensionDeclaration() && receiver != null) { - name = receiver.text + '.' + name - } - methods[name] = methods.getOrDefault(name, 0) + 1 - } - } + override fun visitNamedFunction(function: KtNamedFunction) { + var name = function.name ?: return + val receiver = function.receiverTypeReference + if (function.isExtensionDeclaration() && receiver != null) { + name = receiver.text + '.' + name + } + methods[name] = methods.getOrDefault(name, 0) + 1 + } + } - companion object { - const val DEFAULT_ACCEPTED_OVERLOAD_COUNT = 6 - } + companion object { + const val DEFAULT_ACCEPTED_OVERLOAD_COUNT = 6 + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/NestedBlockDepth.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/NestedBlockDepth.kt index 7180a2275..7f13a57b6 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/NestedBlockDepth.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/NestedBlockDepth.kt @@ -31,89 +31,91 @@ import org.jetbrains.kotlin.psi.KtWhenExpression * @author Artur Bosch * @author Marvin Ramin */ -class NestedBlockDepth(config: Config = Config.empty, - threshold: Int = DEFAULT_ACCEPTED_NESTING) : ThresholdRule(config, threshold) { +class NestedBlockDepth( + config: Config = Config.empty, + threshold: Int = DEFAULT_ACCEPTED_NESTING +) : ThresholdRule(config, threshold) { - override val issue = Issue("NestedBlockDepth", - Severity.Maintainability, - "Excessive nesting leads to hidden complexity. " + - "Prefer extracting code to make it easier to understand.", - Debt.TWENTY_MINS) + override val issue = Issue("NestedBlockDepth", + Severity.Maintainability, + "Excessive nesting leads to hidden complexity. " + + "Prefer extracting code to make it easier to understand.", + Debt.TWENTY_MINS) - override fun visitNamedFunction(function: KtNamedFunction) { - val visitor = FunctionDepthVisitor(threshold) - visitor.visitNamedFunction(function) - if (visitor.isTooDeep) - report(ThresholdedCodeSmell(issue, - Entity.from(function), - Metric("SIZE", visitor.maxDepth, threshold), - "Function ${function.name} is nested too deeply.")) - } + override fun visitNamedFunction(function: KtNamedFunction) { + val visitor = FunctionDepthVisitor(threshold) + visitor.visitNamedFunction(function) + if (visitor.isTooDeep) + report(ThresholdedCodeSmell(issue, + Entity.from(function), + Metric("SIZE", visitor.maxDepth, threshold), + "Function ${function.name} is nested too deeply.")) + } - private class FunctionDepthVisitor(val threshold: Int) : DetektVisitor() { + private class FunctionDepthVisitor(val threshold: Int) : DetektVisitor() { - internal var depth = 0 - internal var maxDepth = 0 - internal var isTooDeep = false - private fun inc() { - depth++ - if (depth >= threshold) { - isTooDeep = true - if (depth > maxDepth) maxDepth = depth - } - } + internal var depth = 0 + internal var maxDepth = 0 + internal var isTooDeep = false + private fun inc() { + depth++ + if (depth >= threshold) { + isTooDeep = true + if (depth > maxDepth) maxDepth = depth + } + } - private fun dec() { - depth-- - } + private fun dec() { + depth-- + } - override fun visitIfExpression(expression: KtIfExpression) { - // Prevents else if (...) to count as two - #51 - if (expression.parent !is KtContainerNodeForControlStructureBody) { - inc() - super.visitIfExpression(expression) - dec() - } - } + override fun visitIfExpression(expression: KtIfExpression) { + // Prevents else if (...) to count as two - #51 + if (expression.parent !is KtContainerNodeForControlStructureBody) { + inc() + super.visitIfExpression(expression) + dec() + } + } - override fun visitLoopExpression(loopExpression: KtLoopExpression) { - inc() - super.visitLoopExpression(loopExpression) - dec() - } + override fun visitLoopExpression(loopExpression: KtLoopExpression) { + inc() + super.visitLoopExpression(loopExpression) + dec() + } - override fun visitWhenExpression(expression: KtWhenExpression) { - inc() - super.visitWhenExpression(expression) - dec() - } + override fun visitWhenExpression(expression: KtWhenExpression) { + inc() + super.visitWhenExpression(expression) + dec() + } - override fun visitTryExpression(expression: KtTryExpression) { - inc() - super.visitTryExpression(expression) - dec() - } + override fun visitTryExpression(expression: KtTryExpression) { + inc() + super.visitTryExpression(expression) + dec() + } - override fun visitCallExpression(expression: KtCallExpression) { - val lambdaArguments = expression.lambdaArguments - if (expression.isUsedForNesting()) { - insideLambdaDo(lambdaArguments) { inc() } - super.visitCallExpression(expression) - insideLambdaDo(lambdaArguments) { dec() } - } - } + override fun visitCallExpression(expression: KtCallExpression) { + val lambdaArguments = expression.lambdaArguments + if (expression.isUsedForNesting()) { + insideLambdaDo(lambdaArguments) { inc() } + super.visitCallExpression(expression) + insideLambdaDo(lambdaArguments) { dec() } + } + } - private fun insideLambdaDo(lambdaArguments: List, function: () -> Unit) { - if (lambdaArguments.isNotEmpty()) { - val lambdaArgument = lambdaArguments[0] - lambdaArgument.getLambdaExpression()?.bodyExpression?.let { - function() - } - } - } - } + private fun insideLambdaDo(lambdaArguments: List, function: () -> Unit) { + if (lambdaArguments.isNotEmpty()) { + val lambdaArgument = lambdaArguments[0] + lambdaArgument.getLambdaExpression()?.bodyExpression?.let { + function() + } + } + } + } - companion object { - const val DEFAULT_ACCEPTED_NESTING = 4 - } + companion object { + const val DEFAULT_ACCEPTED_NESTING = 4 + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/StringLiteralDuplication.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/StringLiteralDuplication.kt index a2f51be1b..6526aa644 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/StringLiteralDuplication.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/StringLiteralDuplication.kt @@ -52,71 +52,71 @@ import org.jetbrains.kotlin.psi.KtStringTemplateExpression * @author Marvin Ramin */ class StringLiteralDuplication( - config: Config = Config.empty, - threshold: Int = DEFAULT_DUPLICATION + config: Config = Config.empty, + threshold: Int = DEFAULT_DUPLICATION ) : ThresholdRule(config, threshold) { - override val issue = Issue(javaClass.simpleName, Severity.Maintainability, - "Multiple occurrences of the same string literal within a single file detected.", - Debt.FIVE_MINS) + override val issue = Issue(javaClass.simpleName, Severity.Maintainability, + "Multiple occurrences of the same string literal within a single file detected.", + Debt.FIVE_MINS) - private val ignoreAnnotation = valueOrDefault(IGNORE_ANNOTATION, true) - private val excludeStringsWithLessThan5Characters = valueOrDefault(EXCLUDE_SHORT_STRING, true) - private val ignoreStringsRegex by LazyRegex(IGNORE_STRINGS_REGEX, "$^") + private val ignoreAnnotation = valueOrDefault(IGNORE_ANNOTATION, true) + private val excludeStringsWithLessThan5Characters = valueOrDefault(EXCLUDE_SHORT_STRING, true) + private val ignoreStringsRegex by LazyRegex(IGNORE_STRINGS_REGEX, "$^") - override fun visitKtFile(file: KtFile) { - val visitor = StringLiteralVisitor() - file.accept(visitor) - val type = "SIZE: " - for ((name, value) in visitor.getLiteralsOverThreshold()) { - val (main, references) = visitor.entitiesForLiteral(name) - report(ThresholdedCodeSmell(issue, - main, - Metric(type + name, value, threshold), - issue.description, - references)) - } - } + override fun visitKtFile(file: KtFile) { + val visitor = StringLiteralVisitor() + file.accept(visitor) + val type = "SIZE: " + for ((name, value) in visitor.getLiteralsOverThreshold()) { + val (main, references) = visitor.entitiesForLiteral(name) + report(ThresholdedCodeSmell(issue, + main, + Metric(type + name, value, threshold), + issue.description, + references)) + } + } - internal inner class StringLiteralVisitor : DetektVisitor() { + internal inner class StringLiteralVisitor : DetektVisitor() { - private var literals = HashMap() - private var literalReferences = HashMap>() - private val pass: Unit = Unit + private var literals = HashMap() + private var literalReferences = HashMap>() + private val pass: Unit = Unit - fun getLiteralsOverThreshold(): Map = literals.filterValues { it >= threshold } - fun entitiesForLiteral(literal: String): Pair> { - val references = literalReferences[literal] - if (references != null && references.isNotEmpty()) { - val mainEntity = references[0] - val referenceEntities = references.subList(1, references.size) - return Entity.from(mainEntity) to referenceEntities.map { Entity.from(it) } - } - throw IllegalStateException("No KtElements for literal '$literal' found!") - } + fun getLiteralsOverThreshold(): Map = literals.filterValues { it >= threshold } + fun entitiesForLiteral(literal: String): Pair> { + val references = literalReferences[literal] + if (references != null && references.isNotEmpty()) { + val mainEntity = references[0] + val referenceEntities = references.subList(1, references.size) + return Entity.from(mainEntity) to referenceEntities.map { Entity.from(it) } + } + throw IllegalStateException("No KtElements for literal '$literal' found!") + } - override fun visitStringTemplateExpression(expression: KtStringTemplateExpression) { - val text = expression.plainText() - when { - ignoreAnnotation && expression.isPartOf(KtAnnotationEntry::class) -> pass - excludeStringsWithLessThan5Characters && text.length < STRING_EXCLUSION_LENGTH -> pass - text.matches(ignoreStringsRegex) -> pass - else -> add(expression) - } - } + override fun visitStringTemplateExpression(expression: KtStringTemplateExpression) { + val text = expression.plainText() + when { + ignoreAnnotation && expression.isPartOf(KtAnnotationEntry::class) -> pass + excludeStringsWithLessThan5Characters && text.length < STRING_EXCLUSION_LENGTH -> pass + text.matches(ignoreStringsRegex) -> pass + else -> add(expression) + } + } - private fun add(str: KtStringTemplateExpression) { - val text = str.plainText() - literals.compute(text) { _, oldValue -> oldValue?.plus(1) ?: 1 } - literalReferences.compute(text) { _, entries -> entries?.add(str); entries ?: mutableListOf(str) } - } - } + private fun add(str: KtStringTemplateExpression) { + val text = str.plainText() + literals.compute(text) { _, oldValue -> oldValue?.plus(1) ?: 1 } + literalReferences.compute(text) { _, entries -> entries?.add(str); entries ?: mutableListOf(str) } + } + } - companion object { - const val DEFAULT_DUPLICATION = 3 - const val STRING_EXCLUSION_LENGTH = 5 - const val IGNORE_ANNOTATION = "ignoreAnnotation" - const val EXCLUDE_SHORT_STRING = "excludeStringsWithLessThan5Characters" - const val IGNORE_STRINGS_REGEX = "ignoreStringsRegex" - } + companion object { + const val DEFAULT_DUPLICATION = 3 + const val STRING_EXCLUSION_LENGTH = 5 + const val IGNORE_ANNOTATION = "ignoreAnnotation" + const val EXCLUDE_SHORT_STRING = "excludeStringsWithLessThan5Characters" + const val IGNORE_STRINGS_REGEX = "ignoreStringsRegex" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/TooManyFunctions.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/TooManyFunctions.kt index de3ef2ff1..115ac2d83 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/TooManyFunctions.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/TooManyFunctions.kt @@ -37,105 +37,105 @@ import org.jetbrains.kotlin.psi.psiUtil.isPrivate */ class TooManyFunctions(config: Config = Config.empty) : Rule(config) { - override val issue = Issue("TooManyFunctions", - Severity.Maintainability, - "Too many functions inside a/an file/class/object/interface always indicate a violation of " + - "the single responsibility principle. Maybe the file/class/object/interface wants to manage too " + - "many things at once. Extract functionality which clearly belongs together.", - Debt.TWENTY_MINS) + override val issue = Issue("TooManyFunctions", + Severity.Maintainability, + "Too many functions inside a/an file/class/object/interface always indicate a violation of " + + "the single responsibility principle. Maybe the file/class/object/interface wants to manage too " + + "many things at once. Extract functionality which clearly belongs together.", + Debt.TWENTY_MINS) - private val thresholdInFiles = valueOrDefault(THRESHOLD_IN_FILES, DEFAULT_THRESHOLD) - private val thresholdInClasses = valueOrDefault(THRESHOLD_IN_CLASSES, DEFAULT_THRESHOLD) - private val thresholdInObjects = valueOrDefault(THRESHOLD_IN_OBJECTS, DEFAULT_THRESHOLD) - private val thresholdInInterfaces = valueOrDefault(THRESHOLD_IN_INTERFACES, DEFAULT_THRESHOLD) - private val thresholdInEnums = valueOrDefault(THRESHOLD_IN_ENUMS, DEFAULT_THRESHOLD) - private val ignoreDeprecated = valueOrDefault(IGNORE_DEPRECATED, false) - private val ignorePrivate = valueOrDefault(IGNORE_PRIVATE, false) + private val thresholdInFiles = valueOrDefault(THRESHOLD_IN_FILES, DEFAULT_THRESHOLD) + private val thresholdInClasses = valueOrDefault(THRESHOLD_IN_CLASSES, DEFAULT_THRESHOLD) + private val thresholdInObjects = valueOrDefault(THRESHOLD_IN_OBJECTS, DEFAULT_THRESHOLD) + private val thresholdInInterfaces = valueOrDefault(THRESHOLD_IN_INTERFACES, DEFAULT_THRESHOLD) + private val thresholdInEnums = valueOrDefault(THRESHOLD_IN_ENUMS, DEFAULT_THRESHOLD) + private val ignoreDeprecated = valueOrDefault(IGNORE_DEPRECATED, false) + private val ignorePrivate = valueOrDefault(IGNORE_PRIVATE, false) - private var amountOfTopLevelFunctions: Int = 0 + private var amountOfTopLevelFunctions: Int = 0 - override fun visitKtFile(file: KtFile) { - super.visitKtFile(file) - if (amountOfTopLevelFunctions >= thresholdInFiles) { - report(ThresholdedCodeSmell(issue, - Entity.from(file), - Metric("SIZE", amountOfTopLevelFunctions, thresholdInFiles), - "File '${file.name}' with '$amountOfTopLevelFunctions' functions detected. " + - "Defined threshold inside files is set to '$thresholdInFiles'")) - } - amountOfTopLevelFunctions = 0 - } + override fun visitKtFile(file: KtFile) { + super.visitKtFile(file) + if (amountOfTopLevelFunctions >= thresholdInFiles) { + report(ThresholdedCodeSmell(issue, + Entity.from(file), + Metric("SIZE", amountOfTopLevelFunctions, thresholdInFiles), + "File '${file.name}' with '$amountOfTopLevelFunctions' functions detected. " + + "Defined threshold inside files is set to '$thresholdInFiles'")) + } + amountOfTopLevelFunctions = 0 + } - override fun visitNamedFunction(function: KtNamedFunction) { - if (function.isTopLevel && !isIgnoredFunction(function)) { - amountOfTopLevelFunctions++ - } - } + override fun visitNamedFunction(function: KtNamedFunction) { + if (function.isTopLevel && !isIgnoredFunction(function)) { + amountOfTopLevelFunctions++ + } + } - override fun visitClass(klass: KtClass) { - val amount = calcFunctions(klass) - when { - klass.isInterface() && amount >= thresholdInInterfaces -> { - report(ThresholdedCodeSmell(issue, - Entity.from(klass), - Metric("SIZE", amount, thresholdInInterfaces), - "Interface '${klass.name}' with '$amount' functions detected. " + - "Defined threshold inside interfaces is set to " + - "'$thresholdInInterfaces'")) - } - klass.isEnum() && amount >= thresholdInEnums -> { - report(ThresholdedCodeSmell(issue, - Entity.from(klass), - Metric("SIZE", amount, thresholdInEnums), - "Enum class '${klass.name}' with '$amount' functions detected. " + - "Defined threshold inside enum classes is set to " + - "'$thresholdInEnums'")) - } - else -> { - if (amount >= thresholdInClasses) { - report(ThresholdedCodeSmell(issue, - Entity.from(klass), - Metric("SIZE", amount, thresholdInClasses), - "Class '${klass.name}' with '$amount' functions detected. " + - "Defined threshold inside classes is set to '$thresholdInClasses'")) - } - } - } - super.visitClass(klass) - } + override fun visitClass(klass: KtClass) { + val amount = calcFunctions(klass) + when { + klass.isInterface() && amount >= thresholdInInterfaces -> { + report(ThresholdedCodeSmell(issue, + Entity.from(klass), + Metric("SIZE", amount, thresholdInInterfaces), + "Interface '${klass.name}' with '$amount' functions detected. " + + "Defined threshold inside interfaces is set to " + + "'$thresholdInInterfaces'")) + } + klass.isEnum() && amount >= thresholdInEnums -> { + report(ThresholdedCodeSmell(issue, + Entity.from(klass), + Metric("SIZE", amount, thresholdInEnums), + "Enum class '${klass.name}' with '$amount' functions detected. " + + "Defined threshold inside enum classes is set to " + + "'$thresholdInEnums'")) + } + else -> { + if (amount >= thresholdInClasses) { + report(ThresholdedCodeSmell(issue, + Entity.from(klass), + Metric("SIZE", amount, thresholdInClasses), + "Class '${klass.name}' with '$amount' functions detected. " + + "Defined threshold inside classes is set to '$thresholdInClasses'")) + } + } + } + super.visitClass(klass) + } - override fun visitObjectDeclaration(declaration: KtObjectDeclaration) { - val amount = calcFunctions(declaration) - if (amount >= thresholdInObjects) { - report(ThresholdedCodeSmell(issue, - Entity.from(declaration), - Metric("SIZE", amount, thresholdInObjects), - "Object '${declaration.name}' with '$amount' functions detected. " + - "Defined threshold inside objects is set to '$thresholdInObjects'")) - } - super.visitObjectDeclaration(declaration) - } + override fun visitObjectDeclaration(declaration: KtObjectDeclaration) { + val amount = calcFunctions(declaration) + if (amount >= thresholdInObjects) { + report(ThresholdedCodeSmell(issue, + Entity.from(declaration), + Metric("SIZE", amount, thresholdInObjects), + "Object '${declaration.name}' with '$amount' functions detected. " + + "Defined threshold inside objects is set to '$thresholdInObjects'")) + } + super.visitObjectDeclaration(declaration) + } - private fun calcFunctions(classOrObject: KtClassOrObject): Int = classOrObject.body?.declarations - ?.filterIsInstance() - ?.filter { !isIgnoredFunction(it) } - ?.size ?: 0 + private fun calcFunctions(classOrObject: KtClassOrObject): Int = classOrObject.body?.declarations + ?.filterIsInstance() + ?.filter { !isIgnoredFunction(it) } + ?.size ?: 0 - private fun isIgnoredFunction(function: KtNamedFunction): Boolean = when { - ignoreDeprecated && function.annotationEntries.any { it.typeReference?.text == DEPRECATED } -> true - ignorePrivate && function.isPrivate() -> true - else -> false - } + private fun isIgnoredFunction(function: KtNamedFunction): Boolean = when { + ignoreDeprecated && function.annotationEntries.any { it.typeReference?.text == DEPRECATED } -> true + ignorePrivate && function.isPrivate() -> true + else -> false + } - companion object { - const val DEFAULT_THRESHOLD = 11 - const val THRESHOLD_IN_FILES = "thresholdInFiles" - const val THRESHOLD_IN_CLASSES = "thresholdInClasses" - const val THRESHOLD_IN_INTERFACES = "thresholdInInterfaces" - const val THRESHOLD_IN_OBJECTS = "thresholdInObjects" - const val THRESHOLD_IN_ENUMS = "thresholdInEnums" - const val IGNORE_DEPRECATED = "ignoreDeprecated" - const val IGNORE_PRIVATE = "ignorePrivate" - private const val DEPRECATED = "Deprecated" - } + companion object { + const val DEFAULT_THRESHOLD = 11 + const val THRESHOLD_IN_FILES = "thresholdInFiles" + const val THRESHOLD_IN_CLASSES = "thresholdInClasses" + const val THRESHOLD_IN_INTERFACES = "thresholdInInterfaces" + const val THRESHOLD_IN_OBJECTS = "thresholdInObjects" + const val THRESHOLD_IN_ENUMS = "thresholdInEnums" + const val IGNORE_DEPRECATED = "ignoreDeprecated" + const val IGNORE_PRIVATE = "ignorePrivate" + private const val DEPRECATED = "Deprecated" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/CommentOverPrivateFunction.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/CommentOverPrivateFunction.kt index 9219fa628..a6520470d 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/CommentOverPrivateFunction.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/CommentOverPrivateFunction.kt @@ -24,17 +24,17 @@ import org.jetbrains.kotlin.psi.KtNamedFunction */ class CommentOverPrivateFunction(config: Config = Config.empty) : Rule(config) { - override val issue = Issue("CommentOverPrivateFunction", - Severity.Maintainability, - "Comments for private functions should be avoided. " + - "Prefer giving the function an expressive name. " + - "Split it up in smaller, self-explaining functions if necessary.", - Debt.TWENTY_MINS) + override val issue = Issue("CommentOverPrivateFunction", + Severity.Maintainability, + "Comments for private functions should be avoided. " + + "Prefer giving the function an expressive name. " + + "Split it up in smaller, self-explaining functions if necessary.", + Debt.TWENTY_MINS) - override fun visitNamedFunction(function: KtNamedFunction) { - if (function.hasCommentInPrivateMember()) { - report(CodeSmell(issue, Entity.from(function.docComment!!), "The function ${function.nameAsSafeName} " + - "has a comment. Prefer renaming the function giving it a more self-explanatory name.")) - } - } + override fun visitNamedFunction(function: KtNamedFunction) { + if (function.hasCommentInPrivateMember()) { + report(CodeSmell(issue, Entity.from(function.docComment!!), "The function ${function.nameAsSafeName} " + + "has a comment. Prefer renaming the function giving it a more self-explanatory name.")) + } + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/CommentOverPrivateProperty.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/CommentOverPrivateProperty.kt index 21ee5ee1b..53b356392 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/CommentOverPrivateProperty.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/CommentOverPrivateProperty.kt @@ -24,14 +24,14 @@ import org.jetbrains.kotlin.psi.KtProperty */ class CommentOverPrivateProperty(config: Config = Config.empty) : Rule(config) { - override val issue = Issue("CommentOverPrivateProperty", - Severity.Maintainability, - "Private properties should be named such that they explain themselves even without a comment.", - Debt.TWENTY_MINS) + override val issue = Issue("CommentOverPrivateProperty", + Severity.Maintainability, + "Private properties should be named such that they explain themselves even without a comment.", + Debt.TWENTY_MINS) - override fun visitProperty(property: KtProperty) { - if (property.hasCommentInPrivateMember()) { - report(CodeSmell(issue, Entity.from(property.docComment!!), issue.description)) - } - } + override fun visitProperty(property: KtProperty) { + if (property.hasCommentInPrivateMember()) { + report(CodeSmell(issue, Entity.from(property.docComment!!), issue.description)) + } + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/EndOfSentenceFormat.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/EndOfSentenceFormat.kt index c3fce9cf5..38992f9c3 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/EndOfSentenceFormat.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/EndOfSentenceFormat.kt @@ -13,16 +13,16 @@ import org.jetbrains.kotlin.psi.KtDeclaration class KDocStyle(config: Config = Config.empty) : MultiRule() { - private val endOfSentenceFormat = EndOfSentenceFormat(config) + private val endOfSentenceFormat = EndOfSentenceFormat(config) - override val rules = listOf( - endOfSentenceFormat - ) + override val rules = listOf( + endOfSentenceFormat + ) - override fun visitDeclaration(dcl: KtDeclaration) { - super.visitDeclaration(dcl) - endOfSentenceFormat.verify(dcl) - } + override fun visitDeclaration(dcl: KtDeclaration) { + super.visitDeclaration(dcl) + endOfSentenceFormat.verify(dcl) + } } /** @@ -37,31 +37,31 @@ class KDocStyle(config: Config = Config.empty) : MultiRule() { */ class EndOfSentenceFormat(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, - Severity.Maintainability, - "The first sentence in a KDoc comment should end with correct punctuation.", - Debt.FIVE_MINS) + override val issue = Issue(javaClass.simpleName, + Severity.Maintainability, + "The first sentence in a KDoc comment should end with correct punctuation.", + Debt.FIVE_MINS) - private val endOfSentenceFormat = - Regex(valueOrDefault(END_OF_SENTENCE_FORMAT, "([.?!][ \\t\\n\\r\\f<])|([.?!]\$)")) - private val htmlTag = Regex("<.+>") + private val endOfSentenceFormat = + Regex(valueOrDefault(END_OF_SENTENCE_FORMAT, "([.?!][ \\t\\n\\r\\f<])|([.?!]\$)")) + private val htmlTag = Regex("<.+>") - fun verify(declaration: KtDeclaration) { - declaration.docComment?.let { - val text = it.getDefaultSection().getContent() - if (text.isEmpty() || text.startsWithHtmlTag()) { - return - } - if (!endOfSentenceFormat.containsMatchIn(text) && !text.lastArgumentMatchesUrl()) { - report(CodeSmell(issue, Entity.from(declaration), - "The first sentence of this KDoc does not end with the correct punctuation.")) - } - } - } + fun verify(declaration: KtDeclaration) { + declaration.docComment?.let { + val text = it.getDefaultSection().getContent() + if (text.isEmpty() || text.startsWithHtmlTag()) { + return + } + if (!endOfSentenceFormat.containsMatchIn(text) && !text.lastArgumentMatchesUrl()) { + report(CodeSmell(issue, Entity.from(declaration), + "The first sentence of this KDoc does not end with the correct punctuation.")) + } + } + } - private fun String.startsWithHtmlTag() = startsWith("<") && contains(htmlTag) + private fun String.startsWithHtmlTag() = startsWith("<") && contains(htmlTag) - companion object { - const val END_OF_SENTENCE_FORMAT = "endOfSentenceFormat" - } + companion object { + const val END_OF_SENTENCE_FORMAT = "endOfSentenceFormat" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicClass.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicClass.kt index c845752e8..04a397f71 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicClass.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicClass.kt @@ -30,58 +30,59 @@ import org.jetbrains.kotlin.psi.KtObjectDeclaration */ class UndocumentedPublicClass(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, - Severity.Maintainability, - "Public classes, interfaces and objects require documentation.", - Debt.TWENTY_MINS) + override val issue = Issue(javaClass.simpleName, + Severity.Maintainability, + "Public classes, interfaces and objects require documentation.", + Debt.TWENTY_MINS) - private val searchInNestedClass = valueOrDefault(SEARCH_IN_NESTED_CLASS, true) - private val searchInInnerClass = valueOrDefault(SEARCH_IN_INNER_CLASS, true) - private val searchInInnerObject = valueOrDefault(SEARCH_IN_INNER_OBJECT, true) - private val searchInInnerInterface = valueOrDefault(SEARCH_IN_INNER_INTERFACE, true) + private val searchInNestedClass = valueOrDefault(SEARCH_IN_NESTED_CLASS, true) + private val searchInInnerClass = valueOrDefault(SEARCH_IN_INNER_CLASS, true) + private val searchInInnerObject = valueOrDefault(SEARCH_IN_INNER_OBJECT, true) + private val searchInInnerInterface = valueOrDefault(SEARCH_IN_INNER_INTERFACE, true) - override fun visitClass(klass: KtClass) { - if (requiresDocumentation(klass)) { - reportIfUndocumented(klass) - } + override fun visitClass(klass: KtClass) { + if (requiresDocumentation(klass)) { + reportIfUndocumented(klass) + } - super.visitClass(klass) - } + super.visitClass(klass) + } - private fun requiresDocumentation( - klass: KtClass) = klass.isTopLevel() || klass.isInnerClass() || klass.isNestedClass() || klass.isInnerInterface() + private fun requiresDocumentation( + klass: KtClass + ) = klass.isTopLevel() || klass.isInnerClass() || klass.isNestedClass() || klass.isInnerInterface() - override fun visitObjectDeclaration(declaration: KtObjectDeclaration) { - if (declaration.isCompanionWithoutName() || declaration.isLocal || !searchInInnerObject) { - return - } + override fun visitObjectDeclaration(declaration: KtObjectDeclaration) { + if (declaration.isCompanionWithoutName() || declaration.isLocal || !searchInInnerObject) { + return + } - reportIfUndocumented(declaration) - super.visitObjectDeclaration(declaration) - } + reportIfUndocumented(declaration) + super.visitObjectDeclaration(declaration) + } - private fun reportIfUndocumented(element: KtClassOrObject) { - if (element.isPublicNotOverridden() && element.notEnumEntry() && element.docComment == null) { - report(CodeSmell(issue, Entity.from(element), - "${element.nameAsSafeName} is missing required documentation.")) - } - } + private fun reportIfUndocumented(element: KtClassOrObject) { + if (element.isPublicNotOverridden() && element.notEnumEntry() && element.docComment == null) { + report(CodeSmell(issue, Entity.from(element), + "${element.nameAsSafeName} is missing required documentation.")) + } + } - private fun KtObjectDeclaration.isCompanionWithoutName() = - isCompanion() && nameAsSafeName.asString() == "Companion" + private fun KtObjectDeclaration.isCompanionWithoutName() = + isCompanion() && nameAsSafeName.asString() == "Companion" - private fun KtClass.isNestedClass() = !isInterface() && !isTopLevel() && !isInner() && searchInNestedClass + private fun KtClass.isNestedClass() = !isInterface() && !isTopLevel() && !isInner() && searchInNestedClass - private fun KtClass.isInnerClass() = !isInterface() && isInner() && searchInInnerClass + private fun KtClass.isInnerClass() = !isInterface() && isInner() && searchInInnerClass - private fun KtClass.isInnerInterface() = !isTopLevel() && isInterface() && searchInInnerInterface + private fun KtClass.isInnerInterface() = !isTopLevel() && isInterface() && searchInInnerInterface - private fun KtClassOrObject.notEnumEntry() = this::class != KtEnumEntry::class + private fun KtClassOrObject.notEnumEntry() = this::class != KtEnumEntry::class - companion object { - const val SEARCH_IN_NESTED_CLASS = "searchInNestedClass" - const val SEARCH_IN_INNER_CLASS = "searchInInnerClass" - const val SEARCH_IN_INNER_OBJECT = "searchInInnerObject" - const val SEARCH_IN_INNER_INTERFACE = "searchInInnerInterface" - } + companion object { + const val SEARCH_IN_NESTED_CLASS = "searchInNestedClass" + const val SEARCH_IN_INNER_CLASS = "searchInInnerClass" + const val SEARCH_IN_INNER_OBJECT = "searchInInnerObject" + const val SEARCH_IN_INNER_INTERFACE = "searchInInnerInterface" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicFunction.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicFunction.kt index 0f90bb46f..0585a2611 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicFunction.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicFunction.kt @@ -22,20 +22,20 @@ import org.jetbrains.kotlin.psi.psiUtil.isPublic */ class UndocumentedPublicFunction(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, - Severity.Maintainability, - "Public functions require documentation.", Debt.TWENTY_MINS) + override val issue = Issue(javaClass.simpleName, + Severity.Maintainability, + "Public functions require documentation.", Debt.TWENTY_MINS) - override fun visitNamedFunction(function: KtNamedFunction) { - if (function.funKeyword == null && function.isLocal) return + override fun visitNamedFunction(function: KtNamedFunction) { + if (function.funKeyword == null && function.isLocal) return - if (function.docComment == null && function.shouldBeDocumented()) { - report(CodeSmell(issue, Entity.from(function), - "The function ${function.nameAsSafeName} is missing documentation.")) - } - } + if (function.docComment == null && function.shouldBeDocumented()) { + report(CodeSmell(issue, Entity.from(function), + "The function ${function.nameAsSafeName} is missing documentation.")) + } + } - private fun KtNamedFunction.shouldBeDocumented() = isContainingClassPublic() && isPublicNotOverridden() + private fun KtNamedFunction.shouldBeDocumented() = isContainingClassPublic() && isPublicNotOverridden() - private fun KtNamedFunction.isContainingClassPublic() = containingClass().let { it == null || it.isPublic } + private fun KtNamedFunction.isContainingClassPublic() = containingClass().let { it == null || it.isPublic } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyBlocks.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyBlocks.kt index 71febdc97..b0d5388c9 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyBlocks.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyBlocks.kt @@ -32,101 +32,101 @@ import org.jetbrains.kotlin.psi.KtWhileExpression @Suppress("TooManyFunctions") class EmptyBlocks(val config: Config = Config.empty) : MultiRule() { - private val emptyCatchBlock = EmptyCatchBlock(config) - private val emptyClassBlock = EmptyClassBlock(config) - private val emptyDefaultConstructor = EmptyDefaultConstructor(config) - private val emptyDoWhileBlock = EmptyDoWhileBlock(config) - private val emptyElseBlock = EmptyElseBlock(config) - private val emptyFinallyBlock = EmptyFinallyBlock(config) - private val emptyForBlock = EmptyForBlock(config) - private val emptyFunctionBlock = EmptyFunctionBlock(config) - private val emptyIfBlock = EmptyIfBlock(config) - private val emptyInitBlock = EmptyInitBlock(config) - private val emptyKtFile = EmptyKtFile(config) - private val emptySecondaryConstructorBlock = EmptySecondaryConstructor(config) - private val emptyWhenBlock = EmptyWhenBlock(config) - private val emptyWhileBlock = EmptyWhileBlock(config) + private val emptyCatchBlock = EmptyCatchBlock(config) + private val emptyClassBlock = EmptyClassBlock(config) + private val emptyDefaultConstructor = EmptyDefaultConstructor(config) + private val emptyDoWhileBlock = EmptyDoWhileBlock(config) + private val emptyElseBlock = EmptyElseBlock(config) + private val emptyFinallyBlock = EmptyFinallyBlock(config) + private val emptyForBlock = EmptyForBlock(config) + private val emptyFunctionBlock = EmptyFunctionBlock(config) + private val emptyIfBlock = EmptyIfBlock(config) + private val emptyInitBlock = EmptyInitBlock(config) + private val emptyKtFile = EmptyKtFile(config) + private val emptySecondaryConstructorBlock = EmptySecondaryConstructor(config) + private val emptyWhenBlock = EmptyWhenBlock(config) + private val emptyWhileBlock = EmptyWhileBlock(config) - override val rules: List = listOf( - emptyCatchBlock, - emptyClassBlock, - emptyDefaultConstructor, - emptyDoWhileBlock, - emptyElseBlock, - emptyFinallyBlock, - emptyForBlock, - emptyFunctionBlock, - emptyIfBlock, - emptyInitBlock, - emptyKtFile, - emptySecondaryConstructorBlock, - emptyWhenBlock, - emptyWhileBlock - ) + override val rules: List = listOf( + emptyCatchBlock, + emptyClassBlock, + emptyDefaultConstructor, + emptyDoWhileBlock, + emptyElseBlock, + emptyFinallyBlock, + emptyForBlock, + emptyFunctionBlock, + emptyIfBlock, + emptyInitBlock, + emptyKtFile, + emptySecondaryConstructorBlock, + emptyWhenBlock, + emptyWhileBlock + ) - override fun visitKtFile(file: KtFile) { - emptyKtFile.runIfActive { visitFile(file) } - super.visitKtFile(file) - } + override fun visitKtFile(file: KtFile) { + emptyKtFile.runIfActive { visitFile(file) } + super.visitKtFile(file) + } - override fun visitCatchSection(catchClause: KtCatchClause) { - emptyCatchBlock.runIfActive { visitCatchSection(catchClause) } - super.visitCatchSection(catchClause) - } + override fun visitCatchSection(catchClause: KtCatchClause) { + emptyCatchBlock.runIfActive { visitCatchSection(catchClause) } + super.visitCatchSection(catchClause) + } - override fun visitClassOrObject(classOrObject: KtClassOrObject) { - emptyClassBlock.runIfActive { visitClassOrObject(classOrObject) } - super.visitClassOrObject(classOrObject) - } + override fun visitClassOrObject(classOrObject: KtClassOrObject) { + emptyClassBlock.runIfActive { visitClassOrObject(classOrObject) } + super.visitClassOrObject(classOrObject) + } - override fun visitPrimaryConstructor(constructor: KtPrimaryConstructor) { - emptyDefaultConstructor.runIfActive { visitPrimaryConstructor(constructor) } - super.visitPrimaryConstructor(constructor) - } + override fun visitPrimaryConstructor(constructor: KtPrimaryConstructor) { + emptyDefaultConstructor.runIfActive { visitPrimaryConstructor(constructor) } + super.visitPrimaryConstructor(constructor) + } - override fun visitDoWhileExpression(expression: KtDoWhileExpression) { - emptyDoWhileBlock.runIfActive { visitDoWhileExpression(expression) } - super.visitDoWhileExpression(expression) - } + override fun visitDoWhileExpression(expression: KtDoWhileExpression) { + emptyDoWhileBlock.runIfActive { visitDoWhileExpression(expression) } + super.visitDoWhileExpression(expression) + } - override fun visitIfExpression(expression: KtIfExpression) { - emptyIfBlock.runIfActive { visitIfExpression(expression) } - emptyElseBlock.runIfActive { visitIfExpression(expression) } - super.visitIfExpression(expression) - } + override fun visitIfExpression(expression: KtIfExpression) { + emptyIfBlock.runIfActive { visitIfExpression(expression) } + emptyElseBlock.runIfActive { visitIfExpression(expression) } + super.visitIfExpression(expression) + } - override fun visitFinallySection(finallySection: KtFinallySection) { - emptyFinallyBlock.runIfActive { visitFinallySection(finallySection) } - super.visitFinallySection(finallySection) - } + override fun visitFinallySection(finallySection: KtFinallySection) { + emptyFinallyBlock.runIfActive { visitFinallySection(finallySection) } + super.visitFinallySection(finallySection) + } - override fun visitForExpression(expression: KtForExpression) { - emptyForBlock.runIfActive { visitForExpression(expression) } - super.visitForExpression(expression) - } + override fun visitForExpression(expression: KtForExpression) { + emptyForBlock.runIfActive { visitForExpression(expression) } + super.visitForExpression(expression) + } - override fun visitNamedFunction(function: KtNamedFunction) { - emptyFinallyBlock.runIfActive { visitNamedFunction(function) } - super.visitNamedFunction(function) - } + override fun visitNamedFunction(function: KtNamedFunction) { + emptyFinallyBlock.runIfActive { visitNamedFunction(function) } + super.visitNamedFunction(function) + } - override fun visitClassInitializer(initializer: KtClassInitializer) { - emptyInitBlock.runIfActive { visitClassInitializer(initializer) } - super.visitClassInitializer(initializer) - } + override fun visitClassInitializer(initializer: KtClassInitializer) { + emptyInitBlock.runIfActive { visitClassInitializer(initializer) } + super.visitClassInitializer(initializer) + } - override fun visitSecondaryConstructor(constructor: KtSecondaryConstructor) { - emptySecondaryConstructorBlock.runIfActive { visitSecondaryConstructor(constructor) } - super.visitSecondaryConstructor(constructor) - } + override fun visitSecondaryConstructor(constructor: KtSecondaryConstructor) { + emptySecondaryConstructorBlock.runIfActive { visitSecondaryConstructor(constructor) } + super.visitSecondaryConstructor(constructor) + } - override fun visitWhenExpression(expression: KtWhenExpression) { - emptyWhenBlock.runIfActive { visitWhenExpression(expression) } - super.visitWhenExpression(expression) - } + override fun visitWhenExpression(expression: KtWhenExpression) { + emptyWhenBlock.runIfActive { visitWhenExpression(expression) } + super.visitWhenExpression(expression) + } - override fun visitWhileExpression(expression: KtWhileExpression) { - emptyWhileBlock.runIfActive { visitWhileExpression(expression) } - super.visitWhileExpression(expression) - } + override fun visitWhileExpression(expression: KtWhileExpression) { + emptyWhileBlock.runIfActive { visitWhileExpression(expression) } + super.visitWhileExpression(expression) + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyCatchBlock.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyCatchBlock.kt index 79c2625d9..d18163888 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyCatchBlock.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyCatchBlock.kt @@ -18,18 +18,18 @@ import org.jetbrains.kotlin.psi.KtCatchClause */ class EmptyCatchBlock(config: Config) : EmptyRule(config = config) { - private val allowedExceptionNameRegex by LazyRegex(ALLOWED_EXCEPTION_NAME_REGEX, ALLOWED_EXCEPTION_NAME) + private val allowedExceptionNameRegex by LazyRegex(ALLOWED_EXCEPTION_NAME_REGEX, ALLOWED_EXCEPTION_NAME) - override fun visitCatchSection(catchClause: KtCatchClause) { - super.visitCatchSection(catchClause) - val name = catchClause.catchParameter?.identifierName() - if (name != null && name.matches(allowedExceptionNameRegex)) { - return - } - catchClause.catchBody?.addFindingIfBlockExprIsEmpty() - } + override fun visitCatchSection(catchClause: KtCatchClause) { + super.visitCatchSection(catchClause) + val name = catchClause.catchParameter?.identifierName() + if (name != null && name.matches(allowedExceptionNameRegex)) { + return + } + catchClause.catchBody?.addFindingIfBlockExprIsEmpty() + } - companion object { - const val ALLOWED_EXCEPTION_NAME_REGEX = "allowedExceptionNameRegex" - } + companion object { + const val ALLOWED_EXCEPTION_NAME_REGEX = "allowedExceptionNameRegex" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyClassBlock.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyClassBlock.kt index 75ab971a4..cffd5c9f7 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyClassBlock.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyClassBlock.kt @@ -16,13 +16,13 @@ import org.jetbrains.kotlin.psi.KtClassOrObject */ class EmptyClassBlock(config: Config) : EmptyRule(config) { - override fun visitClassOrObject(classOrObject: KtClassOrObject) { - super.visitClassOrObject(classOrObject) - if (classOrObject.isObjectOfAnonymousClass()) return + override fun visitClassOrObject(classOrObject: KtClassOrObject) { + super.visitClassOrObject(classOrObject) + if (classOrObject.isObjectOfAnonymousClass()) return - classOrObject.body?.declarations?.let { - if (it.isEmpty()) report(CodeSmell(issue, Entity.from(classOrObject), "The class or object " + - " ${classOrObject.name} is empty.")) - } - } + classOrObject.body?.declarations?.let { + if (it.isEmpty()) report(CodeSmell(issue, Entity.from(classOrObject), "The class or object " + + " ${classOrObject.name} is empty.")) + } + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyDefaultConstructor.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyDefaultConstructor.kt index df0d75f17..3a24142d4 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyDefaultConstructor.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyDefaultConstructor.kt @@ -20,37 +20,37 @@ import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierType */ class EmptyDefaultConstructor(config: Config) : EmptyRule(config = config) { - override fun visitPrimaryConstructor(constructor: KtPrimaryConstructor) { - if (hasSuitableSignature(constructor) && - isNotCalled(constructor) && - !isExpectedAnnotationClass(constructor)) { - report(CodeSmell(issue, Entity.from(constructor), "An empty default constructor can be removed.")) - } - } + override fun visitPrimaryConstructor(constructor: KtPrimaryConstructor) { + if (hasSuitableSignature(constructor) && + isNotCalled(constructor) && + !isExpectedAnnotationClass(constructor)) { + report(CodeSmell(issue, Entity.from(constructor), "An empty default constructor can be removed.")) + } + } - /** - * Annotations with the 'expect' or 'actual' keyword need the explicit default constructor - #1362 - */ - private fun isExpectedAnnotationClass(constructor: KtPrimaryConstructor): Boolean { - val parent = constructor.parent - if (parent is KtClass && parent.isAnnotation()) { - return parent.hasExpectModifier() || parent.hasActualModifier() - } - return false - } + /** + * Annotations with the 'expect' or 'actual' keyword need the explicit default constructor - #1362 + */ + private fun isExpectedAnnotationClass(constructor: KtPrimaryConstructor): Boolean { + val parent = constructor.parent + if (parent is KtClass && parent.isAnnotation()) { + return parent.hasExpectModifier() || parent.hasActualModifier() + } + return false + } - private fun hasSuitableSignature(constructor: KtPrimaryConstructor) = - hasPublicVisibility(constructor.visibilityModifierType()) && - constructor.annotationEntries.isEmpty() && - constructor.valueParameters.isEmpty() + private fun hasSuitableSignature(constructor: KtPrimaryConstructor) = + hasPublicVisibility(constructor.visibilityModifierType()) && + constructor.annotationEntries.isEmpty() && + constructor.valueParameters.isEmpty() - private fun hasPublicVisibility(visibility: KtModifierKeywordToken?): Boolean { - return visibility == null || visibility == KtTokens.PUBLIC_KEYWORD - } + private fun hasPublicVisibility(visibility: KtModifierKeywordToken?): Boolean { + return visibility == null || visibility == KtTokens.PUBLIC_KEYWORD + } - private fun isNotCalled(constructor: KtPrimaryConstructor): Boolean { - return constructor.getContainingClassOrObject().secondaryConstructors.none { - it.getDelegationCall().isCallToThis && it.getDelegationCall().valueArguments.isEmpty() - } - } + private fun isNotCalled(constructor: KtPrimaryConstructor): Boolean { + return constructor.getContainingClassOrObject().secondaryConstructors.none { + it.getDelegationCall().isCallToThis && it.getDelegationCall().valueArguments.isEmpty() + } + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyDoWhileBlock.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyDoWhileBlock.kt index 40fed9582..7ad6d53cf 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyDoWhileBlock.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyDoWhileBlock.kt @@ -12,8 +12,8 @@ import org.jetbrains.kotlin.psi.KtDoWhileExpression */ class EmptyDoWhileBlock(config: Config) : EmptyRule(config) { - override fun visitDoWhileExpression(expression: KtDoWhileExpression) { - super.visitDoWhileExpression(expression) - expression.body?.addFindingIfBlockExprIsEmpty() - } + override fun visitDoWhileExpression(expression: KtDoWhileExpression) { + super.visitDoWhileExpression(expression) + expression.body?.addFindingIfBlockExprIsEmpty() + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyElseBlock.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyElseBlock.kt index 3b15752d8..719a4efa5 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyElseBlock.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyElseBlock.kt @@ -12,8 +12,8 @@ import org.jetbrains.kotlin.psi.KtIfExpression */ class EmptyElseBlock(config: Config) : EmptyRule(config) { - override fun visitIfExpression(expression: KtIfExpression) { - super.visitIfExpression(expression) - expression.`else`?.addFindingIfBlockExprIsEmpty() - } + override fun visitIfExpression(expression: KtIfExpression) { + super.visitIfExpression(expression) + expression.`else`?.addFindingIfBlockExprIsEmpty() + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyFinallyBlock.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyFinallyBlock.kt index a3a1aed04..2e581c2fb 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyFinallyBlock.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyFinallyBlock.kt @@ -12,8 +12,8 @@ import org.jetbrains.kotlin.psi.KtFinallySection */ class EmptyFinallyBlock(config: Config) : EmptyRule(config) { - override fun visitFinallySection(finallySection: KtFinallySection) { - super.visitFinallySection(finallySection) - finallySection.finalExpression?.addFindingIfBlockExprIsEmpty() - } + override fun visitFinallySection(finallySection: KtFinallySection) { + super.visitFinallySection(finallySection) + finallySection.finalExpression?.addFindingIfBlockExprIsEmpty() + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyForBlock.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyForBlock.kt index c0347d8b0..1c4d75fd4 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyForBlock.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyForBlock.kt @@ -12,8 +12,8 @@ import org.jetbrains.kotlin.psi.KtForExpression */ class EmptyForBlock(config: Config) : EmptyRule(config) { - override fun visitForExpression(expression: KtForExpression) { - super.visitForExpression(expression) - expression.body?.addFindingIfBlockExprIsEmpty() - } + override fun visitForExpression(expression: KtForExpression) { + super.visitForExpression(expression) + expression.body?.addFindingIfBlockExprIsEmpty() + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyFunctionBlock.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyFunctionBlock.kt index c84c64773..b8b53e670 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyFunctionBlock.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyFunctionBlock.kt @@ -18,26 +18,26 @@ import org.jetbrains.kotlin.psi.KtNamedFunction */ class EmptyFunctionBlock(config: Config) : EmptyRule(config) { - private val ignoreOverriddenFunctions = valueOrDefault(IGNORE_OVERRIDDEN_FUNCTIONS, false) + private val ignoreOverriddenFunctions = valueOrDefault(IGNORE_OVERRIDDEN_FUNCTIONS, false) - override fun visitNamedFunction(function: KtNamedFunction) { - super.visitNamedFunction(function) - if (function.isOpen()) { - return - } - val bodyExpression = function.bodyExpression - if (!ignoreOverriddenFunctions) { - if (function.isOverride()) { - bodyExpression?.addFindingIfBlockExprIsEmptyAndNotCommented() - } else { - bodyExpression?.addFindingIfBlockExprIsEmpty() - } - } else if (!function.isOverride()) { - bodyExpression?.addFindingIfBlockExprIsEmpty() - } - } + override fun visitNamedFunction(function: KtNamedFunction) { + super.visitNamedFunction(function) + if (function.isOpen()) { + return + } + val bodyExpression = function.bodyExpression + if (!ignoreOverriddenFunctions) { + if (function.isOverride()) { + bodyExpression?.addFindingIfBlockExprIsEmptyAndNotCommented() + } else { + bodyExpression?.addFindingIfBlockExprIsEmpty() + } + } else if (!function.isOverride()) { + bodyExpression?.addFindingIfBlockExprIsEmpty() + } + } - companion object { - const val IGNORE_OVERRIDDEN_FUNCTIONS = "ignoreOverriddenFunctions" - } + companion object { + const val IGNORE_OVERRIDDEN_FUNCTIONS = "ignoreOverriddenFunctions" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyIfBlock.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyIfBlock.kt index 810c6ca8d..c09ca7a8a 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyIfBlock.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyIfBlock.kt @@ -16,16 +16,16 @@ import org.jetbrains.kotlin.psi.KtIfExpression */ class EmptyIfBlock(config: Config) : EmptyRule(config) { - override fun visitIfExpression(expression: KtIfExpression) { - super.visitIfExpression(expression) - expression.then?.addFindingIfBlockExprIsEmpty() - checkThenBodyForLoneSemicolon(expression) - } + override fun visitIfExpression(expression: KtIfExpression) { + super.visitIfExpression(expression) + expression.then?.addFindingIfBlockExprIsEmpty() + checkThenBodyForLoneSemicolon(expression) + } - private fun checkThenBodyForLoneSemicolon(expression: KtIfExpression) { - val valueOfNextSibling = (expression.nextSibling as? LeafPsiElement)?.elementType as? KtSingleValueToken - if (valueOfNextSibling?.value?.trim() == ";") { - report(CodeSmell(issue, Entity.from(expression), "This if block is empty and can be removed.")) - } - } + private fun checkThenBodyForLoneSemicolon(expression: KtIfExpression) { + val valueOfNextSibling = (expression.nextSibling as? LeafPsiElement)?.elementType as? KtSingleValueToken + if (valueOfNextSibling?.value?.trim() == ";") { + report(CodeSmell(issue, Entity.from(expression), "This if block is empty and can be removed.")) + } + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyInitBlock.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyInitBlock.kt index 114defd74..39b9500e7 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyInitBlock.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyInitBlock.kt @@ -12,7 +12,7 @@ import org.jetbrains.kotlin.psi.KtClassInitializer */ class EmptyInitBlock(config: Config) : EmptyRule(config) { - override fun visitClassInitializer(initializer: KtClassInitializer) { - initializer.body?.addFindingIfBlockExprIsEmpty() - } + override fun visitClassInitializer(initializer: KtClassInitializer) { + initializer.body?.addFindingIfBlockExprIsEmpty() + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyKtFile.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyKtFile.kt index aa0742fb7..961050df0 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyKtFile.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyKtFile.kt @@ -14,9 +14,9 @@ import org.jetbrains.kotlin.psi.KtFile */ class EmptyKtFile(config: Config) : EmptyRule(config) { - override fun visitKtFile(file: KtFile) { - if (file.text.isNullOrBlank()) { - report(CodeSmell(issue, Entity.from(file), "The empty Kotlin file ${file.name} can be removed.")) - } - } + override fun visitKtFile(file: KtFile) { + if (file.text.isNullOrBlank()) { + report(CodeSmell(issue, Entity.from(file), "The empty Kotlin file ${file.name} can be removed.")) + } + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyRule.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyRule.kt index c1883d2e2..13abee8b5 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyRule.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyRule.kt @@ -20,25 +20,25 @@ import org.jetbrains.kotlin.psi.KtExpression */ abstract class EmptyRule(config: Config) : Rule(config) { - override val issue = Issue(javaClass.simpleName, - Severity.Minor, - "Empty block of code detected. As they serve no purpose they should be removed.", - Debt.FIVE_MINS) + override val issue = Issue(javaClass.simpleName, + Severity.Minor, + "Empty block of code detected. As they serve no purpose they should be removed.", + Debt.FIVE_MINS) - fun KtExpression.addFindingIfBlockExprIsEmpty() { - checkBlockExpr(false) - } + fun KtExpression.addFindingIfBlockExprIsEmpty() { + checkBlockExpr(false) + } - fun KtExpression.addFindingIfBlockExprIsEmptyAndNotCommented() { - checkBlockExpr(true) - } + fun KtExpression.addFindingIfBlockExprIsEmptyAndNotCommented() { + checkBlockExpr(true) + } - private fun KtExpression.checkBlockExpr(hasComment: Boolean) { - val blockExpression = this.asBlockExpression() - blockExpression?.statements?.let { - if (it.isEmpty() && blockExpression.hasCommentInside() == hasComment) { - report(CodeSmell(issue, Entity.from(this), "This empty block of code can be removed.")) - } - } - } + private fun KtExpression.checkBlockExpr(hasComment: Boolean) { + val blockExpression = this.asBlockExpression() + blockExpression?.statements?.let { + if (it.isEmpty() && blockExpression.hasCommentInside() == hasComment) { + report(CodeSmell(issue, Entity.from(this), "This empty block of code can be removed.")) + } + } + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptySecondaryConstructor.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptySecondaryConstructor.kt index f2f48954d..49f28a446 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptySecondaryConstructor.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptySecondaryConstructor.kt @@ -12,7 +12,7 @@ import org.jetbrains.kotlin.psi.KtSecondaryConstructor */ class EmptySecondaryConstructor(config: Config) : EmptyRule(config) { - override fun visitSecondaryConstructor(constructor: KtSecondaryConstructor) { - constructor.bodyExpression?.addFindingIfBlockExprIsEmpty() - } + override fun visitSecondaryConstructor(constructor: KtSecondaryConstructor) { + constructor.bodyExpression?.addFindingIfBlockExprIsEmpty() + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyWhenBlock.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyWhenBlock.kt index ee5e276d0..4e9173642 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyWhenBlock.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyWhenBlock.kt @@ -14,10 +14,10 @@ import org.jetbrains.kotlin.psi.KtWhenExpression */ class EmptyWhenBlock(config: Config) : EmptyRule(config) { - override fun visitWhenExpression(expression: KtWhenExpression) { - super.visitWhenExpression(expression) - if (expression.entries.isEmpty()) { - report(CodeSmell(issue, Entity.from(expression), "This when block is empty.")) - } - } + override fun visitWhenExpression(expression: KtWhenExpression) { + super.visitWhenExpression(expression) + if (expression.entries.isEmpty()) { + report(CodeSmell(issue, Entity.from(expression), "This when block is empty.")) + } + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyWhileBlock.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyWhileBlock.kt index 857fe0769..9fdf13816 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyWhileBlock.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyWhileBlock.kt @@ -12,8 +12,8 @@ import org.jetbrains.kotlin.psi.KtWhileExpression */ class EmptyWhileBlock(config: Config) : EmptyRule(config) { - override fun visitWhileExpression(expression: KtWhileExpression) { - super.visitWhileExpression(expression) - expression.body?.addFindingIfBlockExprIsEmpty() - } + override fun visitWhileExpression(expression: KtWhileExpression) { + super.visitWhileExpression(expression) + expression.body?.addFindingIfBlockExprIsEmpty() + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ExceptionRaisedInUnexpectedLocation.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ExceptionRaisedInUnexpectedLocation.kt index 84e185188..5977a6a32 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ExceptionRaisedInUnexpectedLocation.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ExceptionRaisedInUnexpectedLocation.kt @@ -37,24 +37,24 @@ import org.jetbrains.kotlin.psi.KtThrowExpression */ class ExceptionRaisedInUnexpectedLocation(config: Config = Config.empty) : Rule(config) { - override val issue = Issue("ExceptionRaisedInUnexpectedLocation", Severity.CodeSmell, - "This method is not expected to throw exceptions. This can cause weird behavior.", - Debt.TWENTY_MINS) + override val issue = Issue("ExceptionRaisedInUnexpectedLocation", Severity.CodeSmell, + "This method is not expected to throw exceptions. This can cause weird behavior.", + Debt.TWENTY_MINS) - private val methods = SplitPattern(valueOrDefault(METHOD_NAMES, "")) + private val methods = SplitPattern(valueOrDefault(METHOD_NAMES, "")) - override fun visitNamedFunction(function: KtNamedFunction) { - if (isPotentialMethod(function) && hasThrowExpression(function.bodyExpression)) { - report(CodeSmell(issue, Entity.from(function), issue.description)) - } - } + override fun visitNamedFunction(function: KtNamedFunction) { + if (isPotentialMethod(function) && hasThrowExpression(function.bodyExpression)) { + report(CodeSmell(issue, Entity.from(function), issue.description)) + } + } - private fun isPotentialMethod(function: KtNamedFunction) = methods.equals(function.name) + private fun isPotentialMethod(function: KtNamedFunction) = methods.equals(function.name) - private fun hasThrowExpression(declaration: KtExpression?) = - declaration?.collectByType()?.any() == true + private fun hasThrowExpression(declaration: KtExpression?) = + declaration?.collectByType()?.any() == true - companion object { - const val METHOD_NAMES = "methodNames" - } + companion object { + const val METHOD_NAMES = "methodNames" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/InstanceOfCheckForException.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/InstanceOfCheckForException.kt index d6c9541be..6c7d1547f 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/InstanceOfCheckForException.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/InstanceOfCheckForException.kt @@ -45,24 +45,24 @@ import org.jetbrains.kotlin.psi.KtPsiUtil */ class InstanceOfCheckForException(config: Config = Config.empty) : Rule(config) { - override val issue = Issue("InstanceOfCheckForException", Severity.CodeSmell, - "Instead of checking for a general exception type and checking for a specific exception type " + - "use multiple catch blocks.", - Debt.TWENTY_MINS) + override val issue = Issue("InstanceOfCheckForException", Severity.CodeSmell, + "Instead of checking for a general exception type and checking for a specific exception type " + + "use multiple catch blocks.", + Debt.TWENTY_MINS) - override fun visitCatchSection(catchClause: KtCatchClause) { - catchClause.catchBody?.collectByType()?.forEach { - if (isExceptionReferenced(it.leftHandSide, catchClause)) { - report(CodeSmell(issue, Entity.from(it), issue.description)) - } - } - catchClause.catchBody?.collectByType()?.forEach { - if (KtPsiUtil.isUnsafeCast(it) && isExceptionReferenced(it.left, catchClause)) { - report(CodeSmell(issue, Entity.from(it), issue.description)) - } - } - } + override fun visitCatchSection(catchClause: KtCatchClause) { + catchClause.catchBody?.collectByType()?.forEach { + if (isExceptionReferenced(it.leftHandSide, catchClause)) { + report(CodeSmell(issue, Entity.from(it), issue.description)) + } + } + catchClause.catchBody?.collectByType()?.forEach { + if (KtPsiUtil.isUnsafeCast(it) && isExceptionReferenced(it.left, catchClause)) { + report(CodeSmell(issue, Entity.from(it), issue.description)) + } + } + } - private fun isExceptionReferenced(expression: KtExpression, catchClause: KtCatchClause) = - expression is KtNameReferenceExpression && expression.text == catchClause.catchParameter?.name + private fun isExceptionReferenced(expression: KtExpression, catchClause: KtCatchClause) = + expression is KtNameReferenceExpression && expression.text == catchClause.catchParameter?.name } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/NotImplementedDeclaration.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/NotImplementedDeclaration.kt index 21b7aec15..fdf5ea260 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/NotImplementedDeclaration.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/NotImplementedDeclaration.kt @@ -32,26 +32,26 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny */ class NotImplementedDeclaration(config: Config = Config.empty) : Rule(config) { - override val issue = Issue("NotImplementedDeclaration", Severity.CodeSmell, - "The NotImplementedDeclaration should only be used when a method stub is necessary. " + - "This defers the development of the functionality of this function. " + - "Hence, the NotImplementedDeclaration should only serve as a temporary declaration. " + - "Before releasing, this type of declaration should be removed.", - Debt.TWENTY_MINS) + override val issue = Issue("NotImplementedDeclaration", Severity.CodeSmell, + "The NotImplementedDeclaration should only be used when a method stub is necessary. " + + "This defers the development of the functionality of this function. " + + "Hence, the NotImplementedDeclaration should only serve as a temporary declaration. " + + "Before releasing, this type of declaration should be removed.", + Debt.TWENTY_MINS) - override fun visitThrowExpression(expression: KtThrowExpression) { - val calleeExpression = expression.thrownExpression?.getCalleeExpressionIfAny() - if (calleeExpression?.text == "NotImplementedError") { - report(CodeSmell(issue, Entity.from(expression), issue.description)) - } - } + override fun visitThrowExpression(expression: KtThrowExpression) { + val calleeExpression = expression.thrownExpression?.getCalleeExpressionIfAny() + if (calleeExpression?.text == "NotImplementedError") { + report(CodeSmell(issue, Entity.from(expression), issue.description)) + } + } - override fun visitCallExpression(expression: KtCallExpression) { - if (expression.calleeExpression?.text == "TODO") { - val size = expression.valueArguments.size - if (size == 0 || size == 1) { - report(CodeSmell(issue, Entity.from(expression), issue.description)) - } - } - } + override fun visitCallExpression(expression: KtCallExpression) { + if (expression.calleeExpression?.text == "TODO") { + val size = expression.valueArguments.size + if (size == 0 || size == 1) { + report(CodeSmell(issue, Entity.from(expression), issue.description)) + } + } + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/PrintStackTrace.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/PrintStackTrace.kt index af2f77008..eaa0cac78 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/PrintStackTrace.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/PrintStackTrace.kt @@ -49,29 +49,29 @@ import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression */ class PrintStackTrace(config: Config = Config.empty) : Rule(config) { - override val issue = Issue("PrintStackTrace", Severity.CodeSmell, - "Do not print an stack trace. " + - "These debug statements should be replaced with a logger or removed.", - Debt.TWENTY_MINS) + override val issue = Issue("PrintStackTrace", Severity.CodeSmell, + "Do not print an stack trace. " + + "These debug statements should be replaced with a logger or removed.", + Debt.TWENTY_MINS) - override fun visitCallExpression(expression: KtCallExpression) { - val callNameExpression = expression.getCallNameExpression() - if (callNameExpression?.text == "dumpStack" && - callNameExpression.getReceiverExpression()?.text == "Thread") { - report(CodeSmell(issue, Entity.from(expression), issue.description)) - } - } + override fun visitCallExpression(expression: KtCallExpression) { + val callNameExpression = expression.getCallNameExpression() + if (callNameExpression?.text == "dumpStack" && + callNameExpression.getReceiverExpression()?.text == "Thread") { + report(CodeSmell(issue, Entity.from(expression), issue.description)) + } + } - override fun visitCatchSection(catchClause: KtCatchClause) { - catchClause.catchBody?.collectByType()?.forEach { - if (it.text == catchClause.catchParameter?.name && hasPrintStacktraceCallExpression(it)) { - report(CodeSmell(issue, Entity.from(it), issue.description)) - } - } - } + override fun visitCatchSection(catchClause: KtCatchClause) { + catchClause.catchBody?.collectByType()?.forEach { + if (it.text == catchClause.catchParameter?.name && hasPrintStacktraceCallExpression(it)) { + report(CodeSmell(issue, Entity.from(it), issue.description)) + } + } + } - private fun hasPrintStacktraceCallExpression(expression: KtNameReferenceExpression): Boolean { - val methodCall = expression.nextSibling?.nextSibling - return methodCall is KtCallExpression && methodCall.text.startsWith("printStackTrace(") - } + private fun hasPrintStacktraceCallExpression(expression: KtNameReferenceExpression): Boolean { + val methodCall = expression.nextSibling?.nextSibling + return methodCall is KtCallExpression && methodCall.text.startsWith("printStackTrace(") + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/RethrowCaughtException.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/RethrowCaughtException.kt index 377080d64..1c9441426 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/RethrowCaughtException.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/RethrowCaughtException.kt @@ -52,17 +52,17 @@ import org.jetbrains.kotlin.psi.KtThrowExpression */ class RethrowCaughtException(config: Config = Config.empty) : Rule(config) { - override val issue = Issue("RethrowCaughtException", Severity.CodeSmell, - "Do not rethrow a caught exception of the same type.", - Debt.FIVE_MINS) + override val issue = Issue("RethrowCaughtException", Severity.CodeSmell, + "Do not rethrow a caught exception of the same type.", + Debt.FIVE_MINS) - override fun visitCatchSection(catchClause: KtCatchClause) { - val exceptionName = catchClause.catchParameter?.name ?: return - val statements = catchClause.catchBody.asBlockExpression()?.statements ?: return - val throwExpression = statements.firstOrNull() as? KtThrowExpression - if (throwExpression != null && throwExpression.thrownExpression?.text == exceptionName) { - report(CodeSmell(issue, Entity.from(throwExpression), issue.description)) - } - super.visitCatchSection(catchClause) - } + override fun visitCatchSection(catchClause: KtCatchClause) { + val exceptionName = catchClause.catchParameter?.name ?: return + val statements = catchClause.catchBody.asBlockExpression()?.statements ?: return + val throwExpression = statements.firstOrNull() as? KtThrowExpression + if (throwExpression != null && throwExpression.thrownExpression?.text == exceptionName) { + report(CodeSmell(issue, Entity.from(throwExpression), issue.description)) + } + super.visitCatchSection(catchClause) + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ReturnFromFinally.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ReturnFromFinally.kt index b8c41a904..8c6c9edc5 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ReturnFromFinally.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ReturnFromFinally.kt @@ -32,20 +32,20 @@ import org.jetbrains.kotlin.psi.psiUtil.parents */ class ReturnFromFinally(config: Config = Config.empty) : Rule(config) { - override val issue = Issue("ReturnFromFinally", Severity.Defect, - "Do not return within a finally statement. This can discard exceptions.", Debt.TWENTY_MINS) + override val issue = Issue("ReturnFromFinally", Severity.Defect, + "Do not return within a finally statement. This can discard exceptions.", Debt.TWENTY_MINS) - override fun visitFinallySection(finallySection: KtFinallySection) { - val returnExpressions = finallySection.finalExpression.collectByType() - val innerFunctions = finallySection.finalExpression.collectByType() - returnExpressions.forEach { - if (isNotInInnerFunction(it, innerFunctions)) { - report(CodeSmell(issue, Entity.from(it), issue.description)) - } - } - } + override fun visitFinallySection(finallySection: KtFinallySection) { + val returnExpressions = finallySection.finalExpression.collectByType() + val innerFunctions = finallySection.finalExpression.collectByType() + returnExpressions.forEach { + if (isNotInInnerFunction(it, innerFunctions)) { + report(CodeSmell(issue, Entity.from(it), issue.description)) + } + } + } - private fun isNotInInnerFunction(it: KtReturnExpression, childFunctions: List): Boolean { - return !it.parents.any { childFunctions.contains(it) } - } + private fun isNotInInnerFunction(it: KtReturnExpression, childFunctions: List): Boolean { + return !it.parents.any { childFunctions.contains(it) } + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/SwallowedException.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/SwallowedException.kt index 354963d24..c27a0b669 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/SwallowedException.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/SwallowedException.kt @@ -60,52 +60,52 @@ import org.jetbrains.kotlin.psi.KtThrowExpression */ class SwallowedException(config: Config = Config.empty) : Rule(config) { - override val issue = Issue("SwallowedException", Severity.CodeSmell, - "The caught exception is swallowed. The original exception could be lost.", - Debt.TWENTY_MINS) + override val issue = Issue("SwallowedException", Severity.CodeSmell, + "The caught exception is swallowed. The original exception could be lost.", + Debt.TWENTY_MINS) - private val ignoredExceptionTypes = SplitPattern(valueOrDefault(IGNORED_EXCEPTION_TYPES, "")) + private val ignoredExceptionTypes = SplitPattern(valueOrDefault(IGNORED_EXCEPTION_TYPES, "")) - override fun visitCatchSection(catchClause: KtCatchClause) { - val exceptionType = catchClause.catchParameter?.typeReference?.text - if (!ignoredExceptionTypes.contains(exceptionType) && - isExceptionUnused(catchClause) || - isExceptionSwallowed(catchClause)) { - report(CodeSmell(issue, Entity.from(catchClause), issue.description)) - } - } + override fun visitCatchSection(catchClause: KtCatchClause) { + val exceptionType = catchClause.catchParameter?.typeReference?.text + if (!ignoredExceptionTypes.contains(exceptionType) && + isExceptionUnused(catchClause) || + isExceptionSwallowed(catchClause)) { + report(CodeSmell(issue, Entity.from(catchClause), issue.description)) + } + } - private fun isExceptionUnused(catchClause: KtCatchClause): Boolean { - val parameterName = catchClause.catchParameter?.name - val catchBody = catchClause.catchBody ?: return true - return !catchBody - .collectByType() - .any { it.text == parameterName } - } + private fun isExceptionUnused(catchClause: KtCatchClause): Boolean { + val parameterName = catchClause.catchParameter?.name + val catchBody = catchClause.catchBody ?: return true + return !catchBody + .collectByType() + .any { it.text == parameterName } + } - private fun isExceptionSwallowed(catchClause: KtCatchClause): Boolean { - val parameterName = catchClause.catchParameter?.name - val throwExpressions = catchClause.catchBody?.collectByType() - throwExpressions?.forEach { throwExpr -> - val parameterNameReferences = throwExpr.thrownExpression?.collectByType()?.filter { - it.text == parameterName - } - return hasParameterReferences(parameterNameReferences) - } - return false - } + private fun isExceptionSwallowed(catchClause: KtCatchClause): Boolean { + val parameterName = catchClause.catchParameter?.name + val throwExpressions = catchClause.catchBody?.collectByType() + throwExpressions?.forEach { throwExpr -> + val parameterNameReferences = throwExpr.thrownExpression?.collectByType()?.filter { + it.text == parameterName + } + return hasParameterReferences(parameterNameReferences) + } + return false + } - private fun hasParameterReferences(parameterNameReferences: List?): Boolean { - return parameterNameReferences != null && - parameterNameReferences.isNotEmpty() && - parameterNameReferences.all { callsMemberOfCaughtException(it) } - } + private fun hasParameterReferences(parameterNameReferences: List?): Boolean { + return parameterNameReferences != null && + parameterNameReferences.isNotEmpty() && + parameterNameReferences.all { callsMemberOfCaughtException(it) } + } - private fun callsMemberOfCaughtException(expression: KtNameReferenceExpression): Boolean { - return expression.nextSibling?.text == "." - } + private fun callsMemberOfCaughtException(expression: KtNameReferenceExpression): Boolean { + return expression.nextSibling?.text == "." + } - companion object { - const val IGNORED_EXCEPTION_TYPES = "ignoredExceptionTypes" - } + companion object { + const val IGNORED_EXCEPTION_TYPES = "ignoredExceptionTypes" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ThrowingExceptionFromFinally.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ThrowingExceptionFromFinally.kt index 5f2be92f1..4601f2a0f 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ThrowingExceptionFromFinally.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ThrowingExceptionFromFinally.kt @@ -30,14 +30,14 @@ import org.jetbrains.kotlin.psi.KtThrowExpression */ class ThrowingExceptionFromFinally(config: Config = Config.empty) : Rule(config) { - override val issue = Issue("ThrowingExceptionFromFinally", Severity.Defect, - "Do not throw an exception within a finally statement. This can discard exceptions and is confusing.", - Debt.TWENTY_MINS) + override val issue = Issue("ThrowingExceptionFromFinally", Severity.Defect, + "Do not throw an exception within a finally statement. This can discard exceptions and is confusing.", + Debt.TWENTY_MINS) - override fun visitFinallySection(finallySection: KtFinallySection) { - val throwExpressions = finallySection.finalExpression.collectByType() - throwExpressions.forEach { - report(CodeSmell(issue, Entity.from(it), issue.description)) - } - } + override fun visitFinallySection(finallySection: KtFinallySection) { + val throwExpressions = finallySection.finalExpression.collectByType() + throwExpressions.forEach { + report(CodeSmell(issue, Entity.from(it), issue.description)) + } + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ThrowingExceptionInMain.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ThrowingExceptionInMain.kt index a7a012261..5c2d60665 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ThrowingExceptionInMain.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ThrowingExceptionInMain.kt @@ -30,24 +30,24 @@ import org.jetbrains.kotlin.psi.KtTypeReference */ class ThrowingExceptionInMain(config: Config = Config.empty) : Rule(config) { - override val issue = Issue("ThrowingExceptionInMain", Severity.CodeSmell, - "The main method should not throw an exception.", Debt.TWENTY_MINS) + override val issue = Issue("ThrowingExceptionInMain", Severity.CodeSmell, + "The main method should not throw an exception.", Debt.TWENTY_MINS) - override fun visitNamedFunction(function: KtNamedFunction) { - if (function.isMainFunction() && hasArgsParameter(function.valueParameters) && containsThrowExpression(function)) { - report(CodeSmell(issue, Entity.from(function), issue.description)) - } - } + override fun visitNamedFunction(function: KtNamedFunction) { + if (function.isMainFunction() && hasArgsParameter(function.valueParameters) && containsThrowExpression(function)) { + report(CodeSmell(issue, Entity.from(function), issue.description)) + } + } - private fun hasArgsParameter(parameters: List): Boolean { - return parameters.size == 1 && isStringArrayParameter(parameters.first().typeReference) - } + private fun hasArgsParameter(parameters: List): Boolean { + return parameters.size == 1 && isStringArrayParameter(parameters.first().typeReference) + } - private fun isStringArrayParameter(typeReference: KtTypeReference?): Boolean { - return typeReference?.text?.replace("\\s+", "") == "Array" - } + private fun isStringArrayParameter(typeReference: KtTypeReference?): Boolean { + return typeReference?.text?.replace("\\s+", "") == "Array" + } - private fun containsThrowExpression(function: KtNamedFunction): Boolean { - return function.bodyExpression?.collectByType()?.any() == true - } + private fun containsThrowExpression(function: KtNamedFunction): Boolean { + return function.bodyExpression?.collectByType()?.any() == true + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ThrowingExceptionsWithoutMessageOrCause.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ThrowingExceptionsWithoutMessageOrCause.kt index 9c194caf7..5c3004819 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ThrowingExceptionsWithoutMessageOrCause.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ThrowingExceptionsWithoutMessageOrCause.kt @@ -42,23 +42,23 @@ import org.jetbrains.kotlin.psi.KtCallExpression */ class ThrowingExceptionsWithoutMessageOrCause(config: Config = Config.empty) : Rule(config) { - override val issue = Issue("ThrowingExceptionsWithoutMessageOrCause", Severity.Warning, - "A call to the default constructor of an exception was detected. " + - "Instead one of the constructor overloads should be called. " + - "This allows to provide more meaningful exceptions.", - Debt.FIVE_MINS) + override val issue = Issue("ThrowingExceptionsWithoutMessageOrCause", Severity.Warning, + "A call to the default constructor of an exception was detected. " + + "Instead one of the constructor overloads should be called. " + + "This allows to provide more meaningful exceptions.", + Debt.FIVE_MINS) - private val exceptions = SplitPattern(valueOrDefault(EXCEPTIONS, "")) + private val exceptions = SplitPattern(valueOrDefault(EXCEPTIONS, "")) - override fun visitCallExpression(expression: KtCallExpression) { - val calleeExpressionText = expression.calleeExpression?.text - if (exceptions.equals(calleeExpressionText) && expression.valueArguments.isEmpty()) { - report(CodeSmell(issue, Entity.from(expression), issue.description)) - } - super.visitCallExpression(expression) - } + override fun visitCallExpression(expression: KtCallExpression) { + val calleeExpressionText = expression.calleeExpression?.text + if (exceptions.equals(calleeExpressionText) && expression.valueArguments.isEmpty()) { + report(CodeSmell(issue, Entity.from(expression), issue.description)) + } + super.visitCallExpression(expression) + } - companion object { - const val EXCEPTIONS = "exceptions" - } + companion object { + const val EXCEPTIONS = "exceptions" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ThrowingNewInstanceOfSameException.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ThrowingNewInstanceOfSameException.kt index 7e0bd57be..e86380db0 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ThrowingNewInstanceOfSameException.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ThrowingNewInstanceOfSameException.kt @@ -42,29 +42,29 @@ import org.jetbrains.kotlin.psi.KtValueArgument */ class ThrowingNewInstanceOfSameException(config: Config = Config.empty) : Rule(config) { - override val issue = Issue("ThrowingNewInstanceOfSameException", Severity.Defect, - "Avoid catch blocks that rethrow a caught exception wrapped inside a new instance of the same exception.", - Debt.FIVE_MINS) + override val issue = Issue("ThrowingNewInstanceOfSameException", Severity.Defect, + "Avoid catch blocks that rethrow a caught exception wrapped inside a new instance of the same exception.", + Debt.FIVE_MINS) - override fun visitCatchSection(catchClause: KtCatchClause) { - val parameterName = catchClause.catchParameter?.name - val typeReference = catchClause.catchParameter?.typeReference?.text - val throwExpression = catchClause.catchBody?.collectByType()?.firstOrNull { - val thrownExpression = it.thrownExpression as? KtCallExpression - thrownExpression != null && - createsSameExceptionType(thrownExpression, typeReference) && - hasSameExceptionParameter(thrownExpression.valueArguments, parameterName) - } - if (throwExpression != null) { - report(CodeSmell(issue, Entity.from(throwExpression), issue.description)) - } - } + override fun visitCatchSection(catchClause: KtCatchClause) { + val parameterName = catchClause.catchParameter?.name + val typeReference = catchClause.catchParameter?.typeReference?.text + val throwExpression = catchClause.catchBody?.collectByType()?.firstOrNull { + val thrownExpression = it.thrownExpression as? KtCallExpression + thrownExpression != null && + createsSameExceptionType(thrownExpression, typeReference) && + hasSameExceptionParameter(thrownExpression.valueArguments, parameterName) + } + if (throwExpression != null) { + report(CodeSmell(issue, Entity.from(throwExpression), issue.description)) + } + } - private fun createsSameExceptionType(thrownExpression: KtCallExpression, typeReference: String?): Boolean { - return thrownExpression.calleeExpression?.text == typeReference - } + private fun createsSameExceptionType(thrownExpression: KtCallExpression, typeReference: String?): Boolean { + return thrownExpression.calleeExpression?.text == typeReference + } - private fun hasSameExceptionParameter(valueArguments: List, parameterName: String?): Boolean { - return valueArguments.size == 1 && valueArguments.first().text == parameterName - } + private fun hasSameExceptionParameter(valueArguments: List, parameterName: String?): Boolean { + return valueArguments.size == 1 && valueArguments.first().text == parameterName + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/TooGenericExceptionCaught.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/TooGenericExceptionCaught.kt index 1d8e510ec..a41e4a4e6 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/TooGenericExceptionCaught.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/TooGenericExceptionCaught.kt @@ -54,46 +54,46 @@ import org.jetbrains.kotlin.psi.KtTypeReference */ class TooGenericExceptionCaught(config: Config) : Rule(config) { - override val issue = Issue(javaClass.simpleName, - Severity.Defect, - "Caught exception is too generic. " + - "Prefer catching specific exceptions to the case that is currently handled.", - Debt.TWENTY_MINS) + override val issue = Issue(javaClass.simpleName, + Severity.Defect, + "Caught exception is too generic. " + + "Prefer catching specific exceptions to the case that is currently handled.", + Debt.TWENTY_MINS) - private val exceptions: Set = valueOrDefault( - CAUGHT_EXCEPTIONS_PROPERTY, caughtExceptionDefaults).toHashSet() + private val exceptions: Set = valueOrDefault( + CAUGHT_EXCEPTIONS_PROPERTY, caughtExceptionDefaults).toHashSet() - private val allowedExceptionNameRegex by LazyRegex(ALLOWED_EXCEPTION_NAME_REGEX, ALLOWED_EXCEPTION_NAME) + private val allowedExceptionNameRegex by LazyRegex(ALLOWED_EXCEPTION_NAME_REGEX, ALLOWED_EXCEPTION_NAME) - override fun visitCatchSection(catchClause: KtCatchClause) { - catchClause.catchParameter?.let { - if (isTooGenericException(it.typeReference) && !isAllowedExceptionName(it)) { - report(CodeSmell(issue, Entity.from(it), issue.description)) - } - } - super.visitCatchSection(catchClause) - } + override fun visitCatchSection(catchClause: KtCatchClause) { + catchClause.catchParameter?.let { + if (isTooGenericException(it.typeReference) && !isAllowedExceptionName(it)) { + report(CodeSmell(issue, Entity.from(it), issue.description)) + } + } + super.visitCatchSection(catchClause) + } - private fun isTooGenericException(typeReference: KtTypeReference?): Boolean { - return typeReference?.text in exceptions - } + private fun isTooGenericException(typeReference: KtTypeReference?): Boolean { + return typeReference?.text in exceptions + } - private fun isAllowedExceptionName(catchParameter: KtParameter) = - catchParameter.identifierName().matches(allowedExceptionNameRegex) + private fun isAllowedExceptionName(catchParameter: KtParameter) = + catchParameter.identifierName().matches(allowedExceptionNameRegex) - companion object { - const val CAUGHT_EXCEPTIONS_PROPERTY = "exceptionNames" - const val ALLOWED_EXCEPTION_NAME_REGEX = "allowedExceptionNameRegex" - } + companion object { + const val CAUGHT_EXCEPTIONS_PROPERTY = "exceptionNames" + const val ALLOWED_EXCEPTION_NAME_REGEX = "allowedExceptionNameRegex" + } } val caughtExceptionDefaults = listOf( - "ArrayIndexOutOfBoundsException", - "Error", - "Exception", - "IllegalMonitorStateException", - "NullPointerException", - "IndexOutOfBoundsException", - "RuntimeException", - "Throwable" + "ArrayIndexOutOfBoundsException", + "Error", + "Exception", + "IllegalMonitorStateException", + "NullPointerException", + "IndexOutOfBoundsException", + "RuntimeException", + "Throwable" ) diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/TooGenericExceptionThrown.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/TooGenericExceptionThrown.kt index ec92875da..8d8d8fb89 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/TooGenericExceptionThrown.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/TooGenericExceptionThrown.kt @@ -45,29 +45,29 @@ import org.jetbrains.kotlin.psi.psiUtil.referenceExpression */ class TooGenericExceptionThrown(config: Config) : Rule(config) { - override val issue = Issue(javaClass.simpleName, - Severity.Defect, - "Thrown exception is too generic. Prefer throwing project specific exceptions to handle error cases.", - Debt.TWENTY_MINS) + override val issue = Issue(javaClass.simpleName, + Severity.Defect, + "Thrown exception is too generic. Prefer throwing project specific exceptions to handle error cases.", + Debt.TWENTY_MINS) - private val exceptions: Set = valueOrDefault(THROWN_EXCEPTIONS_PROPERTY, thrownExceptionDefaults).toHashSet() + private val exceptions: Set = valueOrDefault(THROWN_EXCEPTIONS_PROPERTY, thrownExceptionDefaults).toHashSet() - override fun visitThrowExpression(expression: KtThrowExpression) { - expression.thrownExpression?.referenceExpression()?.text?.let { - if (it in exceptions) report(CodeSmell(issue, Entity.from(expression), "$it is a too generic " + - "Exception. Prefer throwing specific exceptions that indicate a specific error case.")) - } - super.visitThrowExpression(expression) - } + override fun visitThrowExpression(expression: KtThrowExpression) { + expression.thrownExpression?.referenceExpression()?.text?.let { + if (it in exceptions) report(CodeSmell(issue, Entity.from(expression), "$it is a too generic " + + "Exception. Prefer throwing specific exceptions that indicate a specific error case.")) + } + super.visitThrowExpression(expression) + } - companion object { - const val THROWN_EXCEPTIONS_PROPERTY = "exceptionNames" - } + companion object { + const val THROWN_EXCEPTIONS_PROPERTY = "exceptionNames" + } } val thrownExceptionDefaults = listOf( - "Error", - "Exception", - "Throwable", - "RuntimeException" + "Error", + "Exception", + "Throwable", + "RuntimeException" ) diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/ClassNaming.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/ClassNaming.kt index 824ba4989..5af238f8a 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/ClassNaming.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/ClassNaming.kt @@ -20,22 +20,22 @@ import org.jetbrains.kotlin.psi.KtClassOrObject */ class ClassNaming(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, - Severity.Style, - "A class or object's name should fit the naming pattern defined in the projects configuration.", - debt = Debt.FIVE_MINS) - private val classPattern by LazyRegex(CLASS_PATTERN, "^[A-Z$][a-zA-Z0-9$]*") + override val issue = Issue(javaClass.simpleName, + Severity.Style, + "A class or object's name should fit the naming pattern defined in the projects configuration.", + debt = Debt.FIVE_MINS) + private val classPattern by LazyRegex(CLASS_PATTERN, "^[A-Z$][a-zA-Z0-9$]*") - override fun visitClassOrObject(classOrObject: KtClassOrObject) { - if (!classOrObject.identifierName().matches(classPattern)) { - report(CodeSmell( - issue, - Entity.from(classOrObject), - message = "Class and Object names should match the pattern: $classPattern")) - } - } + override fun visitClassOrObject(classOrObject: KtClassOrObject) { + if (!classOrObject.identifierName().matches(classPattern)) { + report(CodeSmell( + issue, + Entity.from(classOrObject), + message = "Class and Object names should match the pattern: $classPattern")) + } + } - companion object { - const val CLASS_PATTERN = "classPattern" - } + companion object { + const val CLASS_PATTERN = "classPattern" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/ConstructorParameterNaming.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/ConstructorParameterNaming.kt index 461b34389..191b19602 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/ConstructorParameterNaming.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/ConstructorParameterNaming.kt @@ -25,41 +25,41 @@ import org.jetbrains.kotlin.psi.psiUtil.isPrivate */ class ConstructorParameterNaming(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, - Severity.Style, - "Constructor parameter names should follow the naming convention set in the projects configuration.", - debt = Debt.FIVE_MINS) + override val issue = Issue(javaClass.simpleName, + Severity.Style, + "Constructor parameter names should follow the naming convention set in the projects configuration.", + debt = Debt.FIVE_MINS) - private val parameterPattern by LazyRegex(PARAMETER_PATTERN, "[a-z][A-Za-z\\d]*") - private val privateParameterPattern by LazyRegex(PRIVATE_PARAMETER_PATTERN, "[a-z][A-Za-z\\d]*") - private val excludeClassPattern by LazyRegex(EXCLUDE_CLASS_PATTERN, "$^") + private val parameterPattern by LazyRegex(PARAMETER_PATTERN, "[a-z][A-Za-z\\d]*") + private val privateParameterPattern by LazyRegex(PRIVATE_PARAMETER_PATTERN, "[a-z][A-Za-z\\d]*") + private val excludeClassPattern by LazyRegex(EXCLUDE_CLASS_PATTERN, "$^") - override fun visitParameter(parameter: KtParameter) { - if (parameter.isContainingExcludedClassOrObject(excludeClassPattern)) { - return - } + override fun visitParameter(parameter: KtParameter) { + if (parameter.isContainingExcludedClassOrObject(excludeClassPattern)) { + return + } - val identifier = parameter.identifierName() - if (parameter.isPrivate()) { - if (!identifier.matches(privateParameterPattern)) { - report(CodeSmell( - issue, - Entity.from(parameter), - message = "Constructor private parameter names should match the pattern: $privateParameterPattern")) - } - } else { - if (!identifier.matches(parameterPattern)) { - report(CodeSmell( - issue, - Entity.from(parameter), - message = "Constructor parameter names should match the pattern: $parameterPattern")) - } - } - } + val identifier = parameter.identifierName() + if (parameter.isPrivate()) { + if (!identifier.matches(privateParameterPattern)) { + report(CodeSmell( + issue, + Entity.from(parameter), + message = "Constructor private parameter names should match the pattern: $privateParameterPattern")) + } + } else { + if (!identifier.matches(parameterPattern)) { + report(CodeSmell( + issue, + Entity.from(parameter), + message = "Constructor parameter names should match the pattern: $parameterPattern")) + } + } + } - companion object { - const val PARAMETER_PATTERN = "parameterPattern" - const val PRIVATE_PARAMETER_PATTERN = "privateParameterPattern" - const val EXCLUDE_CLASS_PATTERN = "excludeClassPattern" - } + companion object { + const val PARAMETER_PATTERN = "parameterPattern" + const val PRIVATE_PARAMETER_PATTERN = "privateParameterPattern" + const val EXCLUDE_CLASS_PATTERN = "excludeClassPattern" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/EnumNaming.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/EnumNaming.kt index 6238c0947..6e0f763e2 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/EnumNaming.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/EnumNaming.kt @@ -20,23 +20,23 @@ import org.jetbrains.kotlin.psi.KtEnumEntry */ class EnumNaming(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, - Severity.Style, - "Enum names should follow the naming convention set in the projects configuration.", - debt = Debt.FIVE_MINS) + override val issue = Issue(javaClass.simpleName, + Severity.Style, + "Enum names should follow the naming convention set in the projects configuration.", + debt = Debt.FIVE_MINS) - private val enumEntryPattern by LazyRegex(ENUM_PATTERN, "^[A-Z][_a-zA-Z0-9]*") + private val enumEntryPattern by LazyRegex(ENUM_PATTERN, "^[A-Z][_a-zA-Z0-9]*") - override fun visitEnumEntry(enumEntry: KtEnumEntry) { - if (!enumEntry.identifierName().matches(enumEntryPattern)) { - report(CodeSmell( - issue, - Entity.from(enumEntry), - message = "Enum entry names should match the pattern: $enumEntryPattern")) - } - } + override fun visitEnumEntry(enumEntry: KtEnumEntry) { + if (!enumEntry.identifierName().matches(enumEntryPattern)) { + report(CodeSmell( + issue, + Entity.from(enumEntry), + message = "Enum entry names should match the pattern: $enumEntryPattern")) + } + } - companion object { - const val ENUM_PATTERN = "enumEntryPattern" - } + companion object { + const val ENUM_PATTERN = "enumEntryPattern" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/ForbiddenClassName.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/ForbiddenClassName.kt index af1182438..8ceb8096f 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/ForbiddenClassName.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/ForbiddenClassName.kt @@ -20,25 +20,25 @@ import org.jetbrains.kotlin.psi.KtClassOrObject */ class ForbiddenClassName(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, Severity.Style, - "Forbidden class name as per configuration detected.", - Debt.FIVE_MINS) - private val forbiddenNames = SplitPattern(valueOrDefault(FORBIDDEN_NAME, "")) + override val issue = Issue(javaClass.simpleName, Severity.Style, + "Forbidden class name as per configuration detected.", + Debt.FIVE_MINS) + private val forbiddenNames = SplitPattern(valueOrDefault(FORBIDDEN_NAME, "")) - override fun visitClassOrObject(classOrObject: KtClassOrObject) { - val name = classOrObject.name ?: "" - val forbiddenEntries = forbiddenNames.matches(name) + override fun visitClassOrObject(classOrObject: KtClassOrObject) { + val name = classOrObject.name ?: "" + val forbiddenEntries = forbiddenNames.matches(name) - if (forbiddenEntries.isNotEmpty()) { - var message = "Class name $name is forbidden as it contains:" - forbiddenEntries.forEach { message += " $it," } - message.trimEnd { it == ',' } + if (forbiddenEntries.isNotEmpty()) { + var message = "Class name $name is forbidden as it contains:" + forbiddenEntries.forEach { message += " $it," } + message.trimEnd { it == ',' } - report(CodeSmell(issue, Entity.from(classOrObject), message)) - } - } + report(CodeSmell(issue, Entity.from(classOrObject), message)) + } + } - companion object { - const val FORBIDDEN_NAME = "forbiddenName" - } + companion object { + const val FORBIDDEN_NAME = "forbiddenName" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/FunctionMaxLength.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/FunctionMaxLength.kt index 5c736fc5c..16e2d5194 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/FunctionMaxLength.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/FunctionMaxLength.kt @@ -18,24 +18,24 @@ import org.jetbrains.kotlin.psi.KtNamedFunction */ class FunctionMaxLength(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, - Severity.Style, - "Function names should not be longer than the maximum set in the project configuration.", - debt = Debt.FIVE_MINS) - private val maximumFunctionNameLength = - valueOrDefault(MAXIMUM_FUNCTION_NAME_LENGTH, DEFAULT_MAXIMUM_FUNCTION_NAME_LENGTH) + override val issue = Issue(javaClass.simpleName, + Severity.Style, + "Function names should not be longer than the maximum set in the project configuration.", + debt = Debt.FIVE_MINS) + private val maximumFunctionNameLength = + valueOrDefault(MAXIMUM_FUNCTION_NAME_LENGTH, DEFAULT_MAXIMUM_FUNCTION_NAME_LENGTH) - override fun visitNamedFunction(function: KtNamedFunction) { - if (function.identifierName().length > maximumFunctionNameLength) { - report(CodeSmell( - issue, - Entity.from(function), - message = "Function names should be at most $maximumFunctionNameLength characters long.")) - } - } + override fun visitNamedFunction(function: KtNamedFunction) { + if (function.identifierName().length > maximumFunctionNameLength) { + report(CodeSmell( + issue, + Entity.from(function), + message = "Function names should be at most $maximumFunctionNameLength characters long.")) + } + } - companion object { - const val MAXIMUM_FUNCTION_NAME_LENGTH = "maximumFunctionNameLength" - private const val DEFAULT_MAXIMUM_FUNCTION_NAME_LENGTH = 30 - } + companion object { + const val MAXIMUM_FUNCTION_NAME_LENGTH = "maximumFunctionNameLength" + private const val DEFAULT_MAXIMUM_FUNCTION_NAME_LENGTH = 30 + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/FunctionMinLength.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/FunctionMinLength.kt index 4b52f3fc3..cd87e578f 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/FunctionMinLength.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/FunctionMinLength.kt @@ -18,24 +18,24 @@ import org.jetbrains.kotlin.psi.KtNamedFunction */ class FunctionMinLength(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, - Severity.Style, - "Function names should not be shorter than the minimum defined in the configuration.", - debt = Debt.FIVE_MINS) - private val minimumFunctionNameLength = - valueOrDefault(MINIMUM_FUNCTION_NAME_LENGTH, DEFAULT_MINIMUM_FUNCTION_NAME_LENGTH) + override val issue = Issue(javaClass.simpleName, + Severity.Style, + "Function names should not be shorter than the minimum defined in the configuration.", + debt = Debt.FIVE_MINS) + private val minimumFunctionNameLength = + valueOrDefault(MINIMUM_FUNCTION_NAME_LENGTH, DEFAULT_MINIMUM_FUNCTION_NAME_LENGTH) - override fun visitNamedFunction(function: KtNamedFunction) { - if (function.identifierName().length < minimumFunctionNameLength) { - report(CodeSmell( - issue, - Entity.from(function), - message = "Function names should be at least $minimumFunctionNameLength characters long.")) - } - } + override fun visitNamedFunction(function: KtNamedFunction) { + if (function.identifierName().length < minimumFunctionNameLength) { + report(CodeSmell( + issue, + Entity.from(function), + message = "Function names should be at least $minimumFunctionNameLength characters long.")) + } + } - companion object { - const val MINIMUM_FUNCTION_NAME_LENGTH = "minimumFunctionNameLength" - private const val DEFAULT_MINIMUM_FUNCTION_NAME_LENGTH = 3 - } + companion object { + const val MINIMUM_FUNCTION_NAME_LENGTH = "minimumFunctionNameLength" + private const val DEFAULT_MINIMUM_FUNCTION_NAME_LENGTH = 3 + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/FunctionNaming.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/FunctionNaming.kt index 868bfe70f..3d9792326 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/FunctionNaming.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/FunctionNaming.kt @@ -26,36 +26,36 @@ import org.jetbrains.kotlin.psi.KtNamedFunction */ class FunctionNaming(config: Config = Config.empty) : Rule(config) { - override val defaultRuleIdAliases: Set = setOf("FunctionName") + override val defaultRuleIdAliases: Set = setOf("FunctionName") - override val issue = Issue(javaClass.simpleName, - Severity.Style, - "Function names should follow the naming convention set in the configuration.", - debt = Debt.FIVE_MINS) + override val issue = Issue(javaClass.simpleName, + Severity.Style, + "Function names should follow the naming convention set in the configuration.", + debt = Debt.FIVE_MINS) - private val functionPattern by LazyRegex(FUNCTION_PATTERN, "^([a-z$][a-zA-Z$0-9]*)|(`.*`)$") - private val excludeClassPattern by LazyRegex(EXCLUDE_CLASS_PATTERN, "$^") - private val ignoreOverridden = valueOrDefault(IGNORE_OVERRIDDEN, true) + private val functionPattern by LazyRegex(FUNCTION_PATTERN, "^([a-z$][a-zA-Z$0-9]*)|(`.*`)$") + private val excludeClassPattern by LazyRegex(EXCLUDE_CLASS_PATTERN, "$^") + private val ignoreOverridden = valueOrDefault(IGNORE_OVERRIDDEN, true) - override fun visitNamedFunction(function: KtNamedFunction) { - super.visitNamedFunction(function) + override fun visitNamedFunction(function: KtNamedFunction) { + super.visitNamedFunction(function) - if (ignoreOverridden && function.isOverride()) { - return - } + if (ignoreOverridden && function.isOverride()) { + return + } - if (!function.isContainingExcludedClassOrObject(excludeClassPattern) && - !function.identifierName().matches(functionPattern)) { - report(CodeSmell( - issue, - Entity.from(function), - message = "Function names should match the pattern: $functionPattern")) - } - } + if (!function.isContainingExcludedClassOrObject(excludeClassPattern) && + !function.identifierName().matches(functionPattern)) { + report(CodeSmell( + issue, + Entity.from(function), + message = "Function names should match the pattern: $functionPattern")) + } + } - companion object { - const val FUNCTION_PATTERN = "functionPattern" - const val EXCLUDE_CLASS_PATTERN = "excludeClassPattern" - const val IGNORE_OVERRIDDEN = "ignoreOverridden" - } + companion object { + const val FUNCTION_PATTERN = "functionPattern" + const val EXCLUDE_CLASS_PATTERN = "excludeClassPattern" + const val IGNORE_OVERRIDDEN = "ignoreOverridden" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/FunctionParameterNaming.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/FunctionParameterNaming.kt index 830304152..27b1babfa 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/FunctionParameterNaming.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/FunctionParameterNaming.kt @@ -27,36 +27,36 @@ import org.jetbrains.kotlin.psi.KtParameter */ class FunctionParameterNaming(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, - Severity.Style, - "Function parameter names should follow the naming convention set in the projects configuration.", - debt = Debt.FIVE_MINS) + override val issue = Issue(javaClass.simpleName, + Severity.Style, + "Function parameter names should follow the naming convention set in the projects configuration.", + debt = Debt.FIVE_MINS) - private val parameterPattern by LazyRegex(PARAMETER_PATTERN, "[a-z][A-Za-z\\d]*") - private val excludeClassPattern by LazyRegex(EXCLUDE_CLASS_PATTERN, "$^") - private val ignoreOverriddenFunctions = valueOrDefault(IGNORE_OVERRIDDEN_FUNCTIONS, true) + private val parameterPattern by LazyRegex(PARAMETER_PATTERN, "[a-z][A-Za-z\\d]*") + private val excludeClassPattern by LazyRegex(EXCLUDE_CLASS_PATTERN, "$^") + private val ignoreOverriddenFunctions = valueOrDefault(IGNORE_OVERRIDDEN_FUNCTIONS, true) - override fun visitParameter(parameter: KtParameter) { - if (parameter.isContainingExcludedClass(excludeClassPattern)) { - return - } + override fun visitParameter(parameter: KtParameter) { + if (parameter.isContainingExcludedClass(excludeClassPattern)) { + return + } - if (ignoreOverriddenFunctions && parameter.ownerFunction?.isOverride() == true) { - return - } + if (ignoreOverriddenFunctions && parameter.ownerFunction?.isOverride() == true) { + return + } - val identifier = parameter.identifierName() - if (!identifier.matches(parameterPattern)) { - report(CodeSmell( - issue, - Entity.from(parameter), - message = "Function parameter names should match the pattern: $parameterPattern")) - } - } + val identifier = parameter.identifierName() + if (!identifier.matches(parameterPattern)) { + report(CodeSmell( + issue, + Entity.from(parameter), + message = "Function parameter names should match the pattern: $parameterPattern")) + } + } - companion object { - const val PARAMETER_PATTERN = "parameterPattern" - const val EXCLUDE_CLASS_PATTERN = "excludeClassPattern" - const val IGNORE_OVERRIDDEN_FUNCTIONS = "ignoreOverriddenFunctions" - } + companion object { + const val PARAMETER_PATTERN = "parameterPattern" + const val EXCLUDE_CLASS_PATTERN = "excludeClassPattern" + const val IGNORE_OVERRIDDEN_FUNCTIONS = "ignoreOverriddenFunctions" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/MatchingDeclarationName.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/MatchingDeclarationName.kt index ee16417cc..7534953d0 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/MatchingDeclarationName.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/MatchingDeclarationName.kt @@ -49,26 +49,26 @@ import org.jetbrains.kotlin.psi.psiUtil.isPrivate */ class MatchingDeclarationName(config: Config = Config.empty) : Rule(config) { - override val issue: Issue = Issue(javaClass.simpleName, Severity.Style, - "If a source file contains only a single non-private top-level class or object, " + - "the file name should reflect the case-sensitive name plus the .kt extension.", - Debt.FIVE_MINS) + override val issue: Issue = Issue(javaClass.simpleName, Severity.Style, + "If a source file contains only a single non-private top-level class or object, " + + "the file name should reflect the case-sensitive name plus the .kt extension.", + Debt.FIVE_MINS) - override fun visitKtFile(file: KtFile) { - val declarations = file.declarations - .filterIsInstance() - .filterNot { it.isPrivate() } - if (declarations.size == 1) { - val declaration = declarations[0] as? KtClassOrObject - val declarationName = declaration?.name ?: return - val filename = file.name.removeSuffix(KOTLIN_SUFFIX) - if (declarationName != filename && - file.declarations.filterIsInstance().all { it.name != filename }) { - report(CodeSmell(issue, Entity.from(file), "The file name '${file.name}' " + - "does not match the name of the single top-level declaration '$declarationName'.")) - } - } - } + override fun visitKtFile(file: KtFile) { + val declarations = file.declarations + .filterIsInstance() + .filterNot { it.isPrivate() } + if (declarations.size == 1) { + val declaration = declarations[0] as? KtClassOrObject + val declarationName = declaration?.name ?: return + val filename = file.name.removeSuffix(KOTLIN_SUFFIX) + if (declarationName != filename && + file.declarations.filterIsInstance().all { it.name != filename }) { + report(CodeSmell(issue, Entity.from(file), "The file name '${file.name}' " + + "does not match the name of the single top-level declaration '$declarationName'.")) + } + } + } } private const val KOTLIN_SUFFIX = ".kt" diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/MemberNameEqualsClassName.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/MemberNameEqualsClassName.kt index c0c725a35..0f2adbdb7 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/MemberNameEqualsClassName.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/MemberNameEqualsClassName.kt @@ -54,61 +54,61 @@ import org.jetbrains.kotlin.util.collectionUtils.concat */ class MemberNameEqualsClassName(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, Severity.Style, - "A member should not be given the same name as its parent class or object.", - Debt.FIVE_MINS) + override val issue = Issue(javaClass.simpleName, Severity.Style, + "A member should not be given the same name as its parent class or object.", + Debt.FIVE_MINS) - private val classMessage = "A member is named after the class. This might result in confusion. " + - "Either rename the member or change it to a constructor." - private val objectMessage = "A member is named after the object. " + - "This might result in confusion. Please rename the member." + private val classMessage = "A member is named after the class. This might result in confusion. " + + "Either rename the member or change it to a constructor." + private val objectMessage = "A member is named after the object. " + + "This might result in confusion. Please rename the member." - private val ignoreOverriddenFunction = valueOrDefault(IGNORE_OVERRIDDEN_FUNCTION, true) + private val ignoreOverriddenFunction = valueOrDefault(IGNORE_OVERRIDDEN_FUNCTION, true) - override fun visitClass(klass: KtClass) { - if (!klass.isInterface()) { - getMisnamedMembers(klass, klass.name) - .concat(getMisnamedCompanionObjectMembers(klass)) - ?.forEach { report(CodeSmell(issue, Entity.from(it), classMessage)) } - } - super.visitClass(klass) - } + override fun visitClass(klass: KtClass) { + if (!klass.isInterface()) { + getMisnamedMembers(klass, klass.name) + .concat(getMisnamedCompanionObjectMembers(klass)) + ?.forEach { report(CodeSmell(issue, Entity.from(it), classMessage)) } + } + super.visitClass(klass) + } - override fun visitObjectDeclaration(declaration: KtObjectDeclaration) { - if (!declaration.isCompanion()) { - getMisnamedMembers(declaration, declaration.name) - .forEach { report(CodeSmell(issue, Entity.from(it), objectMessage)) } - } - super.visitObjectDeclaration(declaration) - } + override fun visitObjectDeclaration(declaration: KtObjectDeclaration) { + if (!declaration.isCompanion()) { + getMisnamedMembers(declaration, declaration.name) + .forEach { report(CodeSmell(issue, Entity.from(it), objectMessage)) } + } + super.visitObjectDeclaration(declaration) + } - private fun getMisnamedMembers(klassOrObject: KtClassOrObject, name: String?): List { - val body = klassOrObject.body ?: return emptyList() - val declarations = getFunctions(body).concat(body.properties) - return declarations?.filter { it.name?.equals(name, ignoreCase = true) == true }.orEmpty() - } + private fun getMisnamedMembers(klassOrObject: KtClassOrObject, name: String?): List { + val body = klassOrObject.body ?: return emptyList() + val declarations = getFunctions(body).concat(body.properties) + return declarations?.filter { it.name?.equals(name, ignoreCase = true) == true }.orEmpty() + } - private fun getFunctions(body: KtClassBody): List { - var functions = body.children.filterIsInstance() - if (ignoreOverriddenFunction) { - functions = functions.filter { !it.isOverride() } - } - return functions - } + private fun getFunctions(body: KtClassBody): List { + var functions = body.children.filterIsInstance() + if (ignoreOverriddenFunction) { + functions = functions.filter { !it.isOverride() } + } + return functions + } - private fun getMisnamedCompanionObjectMembers(klass: KtClass): List { - return klass.companionObjects - .flatMap { getMisnamedMembers(it, klass.name) } - .filterNot { it is KtNamedFunction && isFactoryMethod(it, klass) } - } + private fun getMisnamedCompanionObjectMembers(klass: KtClass): List { + return klass.companionObjects + .flatMap { getMisnamedMembers(it, klass.name) } + .filterNot { it is KtNamedFunction && isFactoryMethod(it, klass) } + } - private fun isFactoryMethod(function: KtNamedFunction, klass: KtClass): Boolean { - val typeReference = function.typeReference - return typeReference == null && function.bodyExpression !is KtBlockExpression || - typeReference?.text?.equals(klass.name) == true - } + private fun isFactoryMethod(function: KtNamedFunction, klass: KtClass): Boolean { + val typeReference = function.typeReference + return typeReference == null && function.bodyExpression !is KtBlockExpression || + typeReference?.text?.equals(klass.name) == true + } - companion object { - const val IGNORE_OVERRIDDEN_FUNCTION = "ignoreOverriddenFunction" - } + companion object { + const val IGNORE_OVERRIDDEN_FUNCTION = "ignoreOverriddenFunction" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/NamingRules.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/NamingRules.kt index df53044dd..5f64ef7a1 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/NamingRules.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/NamingRules.kt @@ -20,88 +20,88 @@ import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType */ class NamingRules(config: Config = Config.empty) : MultiRule() { - private val variableNamingRule = VariableNaming(config) - private val variableMinNameLengthRule = VariableMinLength(config) - private val variableMaxNameLengthRule = VariableMaxLength(config) - private val topLevelPropertyRule = TopLevelPropertyNaming(config) - private val objectConstantNamingRule = ObjectPropertyNaming(config) - private val packageNamingRule = PackageNaming(config) - private val classOrObjectNamingRule = ClassNaming(config) - private val enumEntryNamingRule = EnumNaming(config) - private val functionNamingRule = FunctionNaming(config) - private val functionMaxNameLengthRule = FunctionMaxLength(config) - private val functionMinNameLengthRule = FunctionMinLength(config) - private val forbiddenClassNameRule = ForbiddenClassName(config) - private val constructorParameterNamingRule = ConstructorParameterNaming(config) - private val functionParameterNamingRule = FunctionParameterNaming(config) + private val variableNamingRule = VariableNaming(config) + private val variableMinNameLengthRule = VariableMinLength(config) + private val variableMaxNameLengthRule = VariableMaxLength(config) + private val topLevelPropertyRule = TopLevelPropertyNaming(config) + private val objectConstantNamingRule = ObjectPropertyNaming(config) + private val packageNamingRule = PackageNaming(config) + private val classOrObjectNamingRule = ClassNaming(config) + private val enumEntryNamingRule = EnumNaming(config) + private val functionNamingRule = FunctionNaming(config) + private val functionMaxNameLengthRule = FunctionMaxLength(config) + private val functionMinNameLengthRule = FunctionMinLength(config) + private val forbiddenClassNameRule = ForbiddenClassName(config) + private val constructorParameterNamingRule = ConstructorParameterNaming(config) + private val functionParameterNamingRule = FunctionParameterNaming(config) - override val rules: List = listOf( - variableNamingRule, - variableMinNameLengthRule, - variableMaxNameLengthRule, - topLevelPropertyRule, - objectConstantNamingRule, - packageNamingRule, - classOrObjectNamingRule, - enumEntryNamingRule, - functionNamingRule, - functionMaxNameLengthRule, - functionMinNameLengthRule, - forbiddenClassNameRule, - constructorParameterNamingRule, - functionParameterNamingRule - ) + override val rules: List = listOf( + variableNamingRule, + variableMinNameLengthRule, + variableMaxNameLengthRule, + topLevelPropertyRule, + objectConstantNamingRule, + packageNamingRule, + classOrObjectNamingRule, + enumEntryNamingRule, + functionNamingRule, + functionMaxNameLengthRule, + functionMinNameLengthRule, + forbiddenClassNameRule, + constructorParameterNamingRule, + functionParameterNamingRule + ) - override fun visitPackageDirective(directive: KtPackageDirective) { - super.visitPackageDirective(directive) - packageNamingRule.runIfActive { visitPackageDirective(directive) } - } + override fun visitPackageDirective(directive: KtPackageDirective) { + super.visitPackageDirective(directive) + packageNamingRule.runIfActive { visitPackageDirective(directive) } + } - override fun visitNamedDeclaration(declaration: KtNamedDeclaration) { - if (declaration.nameAsSafeName.isSpecial) { - return - } - declaration.nameIdentifier?.parent?.javaClass?.let { - when (declaration) { - is KtProperty -> handleProperty(declaration) - is KtNamedFunction -> handleFunction(declaration) - is KtEnumEntry -> enumEntryNamingRule.runIfActive { visitEnumEntry(declaration) } - is KtClassOrObject -> handleClassOrObject(declaration) - is KtParameter -> handleParameter(declaration) - } - } - super.visitNamedDeclaration(declaration) - } + override fun visitNamedDeclaration(declaration: KtNamedDeclaration) { + if (declaration.nameAsSafeName.isSpecial) { + return + } + declaration.nameIdentifier?.parent?.javaClass?.let { + when (declaration) { + is KtProperty -> handleProperty(declaration) + is KtNamedFunction -> handleFunction(declaration) + is KtEnumEntry -> enumEntryNamingRule.runIfActive { visitEnumEntry(declaration) } + is KtClassOrObject -> handleClassOrObject(declaration) + is KtParameter -> handleParameter(declaration) + } + } + super.visitNamedDeclaration(declaration) + } - private fun handleClassOrObject(declaration: KtClassOrObject) { - classOrObjectNamingRule.runIfActive { visitClassOrObject(declaration) } - forbiddenClassNameRule.runIfActive { visitClassOrObject(declaration) } - } + private fun handleClassOrObject(declaration: KtClassOrObject) { + classOrObjectNamingRule.runIfActive { visitClassOrObject(declaration) } + forbiddenClassNameRule.runIfActive { visitClassOrObject(declaration) } + } - private fun handleFunction(declaration: KtNamedFunction) { - functionNamingRule.runIfActive { visitNamedFunction(declaration) } - functionMaxNameLengthRule.runIfActive { visitNamedFunction(declaration) } - functionMinNameLengthRule.runIfActive { visitNamedFunction(declaration) } - } + private fun handleFunction(declaration: KtNamedFunction) { + functionNamingRule.runIfActive { visitNamedFunction(declaration) } + functionMaxNameLengthRule.runIfActive { visitNamedFunction(declaration) } + functionMinNameLengthRule.runIfActive { visitNamedFunction(declaration) } + } - private fun handleProperty(declaration: KtProperty) { - variableMaxNameLengthRule.runIfActive { visitProperty(declaration) } - variableMinNameLengthRule.runIfActive { visitProperty(declaration) } + private fun handleProperty(declaration: KtProperty) { + variableMaxNameLengthRule.runIfActive { visitProperty(declaration) } + variableMinNameLengthRule.runIfActive { visitProperty(declaration) } - when { - declaration.isTopLevel -> topLevelPropertyRule.runIfActive { visitProperty(declaration) } - declaration.withinObjectDeclaration() -> objectConstantNamingRule.runIfActive { visitProperty(declaration) } - else -> variableNamingRule.runIfActive { visitProperty(declaration) } - } - } + when { + declaration.isTopLevel -> topLevelPropertyRule.runIfActive { visitProperty(declaration) } + declaration.withinObjectDeclaration() -> objectConstantNamingRule.runIfActive { visitProperty(declaration) } + else -> variableNamingRule.runIfActive { visitProperty(declaration) } + } + } - private fun handleParameter(declaration: KtParameter) { - when (declaration.ownerFunction) { - is KtConstructor<*> -> constructorParameterNamingRule.runIfActive { visitParameter(declaration) } - is KtNamedFunction -> functionParameterNamingRule.runIfActive { visitParameter(declaration) } - } - } + private fun handleParameter(declaration: KtParameter) { + when (declaration.ownerFunction) { + is KtConstructor<*> -> constructorParameterNamingRule.runIfActive { visitParameter(declaration) } + is KtNamedFunction -> functionParameterNamingRule.runIfActive { visitParameter(declaration) } + } + } - private fun KtVariableDeclaration.withinObjectDeclaration(): Boolean = - this.getNonStrictParentOfType() != null + private fun KtVariableDeclaration.withinObjectDeclaration(): Boolean = + this.getNonStrictParentOfType() != null } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/ObjectPropertyNaming.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/ObjectPropertyNaming.kt index 155e4c76b..ebf60731d 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/ObjectPropertyNaming.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/ObjectPropertyNaming.kt @@ -25,51 +25,51 @@ import org.jetbrains.kotlin.psi.psiUtil.isPrivate */ class ObjectPropertyNaming(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, - Severity.Style, - "Property names inside objects should follow the naming convention set in the projects configuration.", - debt = Debt.FIVE_MINS) + override val issue = Issue(javaClass.simpleName, + Severity.Style, + "Property names inside objects should follow the naming convention set in the projects configuration.", + debt = Debt.FIVE_MINS) - private val constantPattern by LazyRegex(CONSTANT_PATTERN, "[A-Za-z][_A-Za-z0-9]*") - private val propertyPattern by LazyRegex(PROPERTY_PATTERN, "[A-Za-z][_A-Za-z0-9]*") - private val privatePropertyPattern by LazyRegex(PRIVATE_PROPERTY_PATTERN, "(_)?[A-Za-z][_A-Za-z0-9]*") + private val constantPattern by LazyRegex(CONSTANT_PATTERN, "[A-Za-z][_A-Za-z0-9]*") + private val propertyPattern by LazyRegex(PROPERTY_PATTERN, "[A-Za-z][_A-Za-z0-9]*") + private val privatePropertyPattern by LazyRegex(PRIVATE_PROPERTY_PATTERN, "(_)?[A-Za-z][_A-Za-z0-9]*") - override fun visitProperty(property: KtProperty) { - if (property.isConstant()) { - handleConstant(property) - } else { - handleProperty(property) - } - } + override fun visitProperty(property: KtProperty) { + if (property.isConstant()) { + handleConstant(property) + } else { + handleProperty(property) + } + } - private fun handleConstant(property: KtProperty) { - if (!property.identifierName().matches(constantPattern)) { - report(CodeSmell( - issue, - Entity.from(property), - message = "Object constant names should match the pattern: $constantPattern")) - } - } + private fun handleConstant(property: KtProperty) { + if (!property.identifierName().matches(constantPattern)) { + report(CodeSmell( + issue, + Entity.from(property), + message = "Object constant names should match the pattern: $constantPattern")) + } + } - private fun handleProperty(property: KtProperty) { - if (property.isPrivate()) { - if (!property.identifierName().matches(privatePropertyPattern)) { - report(CodeSmell( - issue, - Entity.from(property), - message = "Private object property names should match the pattern: $privatePropertyPattern")) - } - } else if (!property.identifierName().matches(propertyPattern)) { - report(CodeSmell( - issue, - Entity.from(property), - message = "Object property names should match the pattern: $propertyPattern")) - } - } + private fun handleProperty(property: KtProperty) { + if (property.isPrivate()) { + if (!property.identifierName().matches(privatePropertyPattern)) { + report(CodeSmell( + issue, + Entity.from(property), + message = "Private object property names should match the pattern: $privatePropertyPattern")) + } + } else if (!property.identifierName().matches(propertyPattern)) { + report(CodeSmell( + issue, + Entity.from(property), + message = "Object property names should match the pattern: $propertyPattern")) + } + } - companion object { - const val CONSTANT_PATTERN = "constantPattern" - const val PROPERTY_PATTERN = "propertyPattern" - const val PRIVATE_PROPERTY_PATTERN = "privatePropertyPattern" - } + companion object { + const val CONSTANT_PATTERN = "constantPattern" + const val PROPERTY_PATTERN = "propertyPattern" + const val PRIVATE_PROPERTY_PATTERN = "privatePropertyPattern" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/PackageNaming.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/PackageNaming.kt index bcabf3c89..f947ac4ad 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/PackageNaming.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/PackageNaming.kt @@ -19,23 +19,23 @@ import org.jetbrains.kotlin.psi.KtPackageDirective */ class PackageNaming(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, - Severity.Style, - "Package names should match the naming convention set in the configuration.", - debt = Debt.FIVE_MINS) - private val packagePattern by LazyRegex(PACKAGE_PATTERN, "^[a-z]+(\\.[a-z][A-Za-z0-9]*)*$") + override val issue = Issue(javaClass.simpleName, + Severity.Style, + "Package names should match the naming convention set in the configuration.", + debt = Debt.FIVE_MINS) + private val packagePattern by LazyRegex(PACKAGE_PATTERN, "^[a-z]+(\\.[a-z][A-Za-z0-9]*)*$") - override fun visitPackageDirective(directive: KtPackageDirective) { - val name = directive.qualifiedName - if (name.isNotEmpty() && !name.matches(packagePattern)) { - report(CodeSmell( - issue, - Entity.from(directive), - message = "Package name should match the pattern: $packagePattern")) - } - } + override fun visitPackageDirective(directive: KtPackageDirective) { + val name = directive.qualifiedName + if (name.isNotEmpty() && !name.matches(packagePattern)) { + report(CodeSmell( + issue, + Entity.from(directive), + message = "Package name should match the pattern: $packagePattern")) + } + } - companion object { - const val PACKAGE_PATTERN = "packagePattern" - } + companion object { + const val PACKAGE_PATTERN = "packagePattern" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/TopLevelPropertyNaming.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/TopLevelPropertyNaming.kt index 1f9a278dd..b7439b134 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/TopLevelPropertyNaming.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/TopLevelPropertyNaming.kt @@ -25,51 +25,51 @@ import org.jetbrains.kotlin.psi.psiUtil.isPrivate */ class TopLevelPropertyNaming(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, - Severity.Style, - "Top level property names should follow the naming convention set in the projects configuration.", - debt = Debt.FIVE_MINS) + override val issue = Issue(javaClass.simpleName, + Severity.Style, + "Top level property names should follow the naming convention set in the projects configuration.", + debt = Debt.FIVE_MINS) - private val constantPattern by LazyRegex(CONSTANT_PATTERN, "[A-Z][_A-Z0-9]*") - private val propertyPattern by LazyRegex(PROPERTY_PATTERN, "[A-Za-z][_A-Za-z0-9]*") - private val privatePropertyPattern by LazyRegex(PRIVATE_PROPERTY_PATTERN, "(_)?[A-Za-z][A-Za-z0-9]*") + private val constantPattern by LazyRegex(CONSTANT_PATTERN, "[A-Z][_A-Z0-9]*") + private val propertyPattern by LazyRegex(PROPERTY_PATTERN, "[A-Za-z][_A-Za-z0-9]*") + private val privatePropertyPattern by LazyRegex(PRIVATE_PROPERTY_PATTERN, "(_)?[A-Za-z][A-Za-z0-9]*") - override fun visitProperty(property: KtProperty) { - if (property.isConstant()) { - handleConstant(property) - } else { - handleProperty(property) - } - } + override fun visitProperty(property: KtProperty) { + if (property.isConstant()) { + handleConstant(property) + } else { + handleProperty(property) + } + } - private fun handleConstant(property: KtProperty) { - if (!property.identifierName().matches(constantPattern)) { - report(CodeSmell( - issue, - Entity.from(property), - message = "Top level constant names should match the pattern: $constantPattern")) - } - } + private fun handleConstant(property: KtProperty) { + if (!property.identifierName().matches(constantPattern)) { + report(CodeSmell( + issue, + Entity.from(property), + message = "Top level constant names should match the pattern: $constantPattern")) + } + } - private fun handleProperty(property: KtProperty) { - if (property.isPrivate()) { - if (!property.identifierName().matches(privatePropertyPattern)) { - report(CodeSmell( - issue, - Entity.from(property), - message = "Private top level property names should match the pattern: $privatePropertyPattern")) - } - } else if (!property.identifierName().matches(propertyPattern)) { - report(CodeSmell( - issue, - Entity.from(property), - message = "Top level property names should match the pattern: $propertyPattern")) - } - } + private fun handleProperty(property: KtProperty) { + if (property.isPrivate()) { + if (!property.identifierName().matches(privatePropertyPattern)) { + report(CodeSmell( + issue, + Entity.from(property), + message = "Private top level property names should match the pattern: $privatePropertyPattern")) + } + } else if (!property.identifierName().matches(propertyPattern)) { + report(CodeSmell( + issue, + Entity.from(property), + message = "Top level property names should match the pattern: $propertyPattern")) + } + } - companion object { - const val CONSTANT_PATTERN = "constantPattern" - const val PROPERTY_PATTERN = "propertyPattern" - const val PRIVATE_PROPERTY_PATTERN = "privatePropertyPattern" - } + companion object { + const val CONSTANT_PATTERN = "constantPattern" + const val PROPERTY_PATTERN = "propertyPattern" + const val PRIVATE_PROPERTY_PATTERN = "privatePropertyPattern" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/VariableMaxLength.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/VariableMaxLength.kt index fa79d5f63..691d2face 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/VariableMaxLength.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/VariableMaxLength.kt @@ -18,24 +18,24 @@ import org.jetbrains.kotlin.psi.KtProperty */ class VariableMaxLength(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, - Severity.Style, - "Variable names should not be longer than the maximum set in the configuration.", - debt = Debt.FIVE_MINS) - private val maximumVariableNameLength = - valueOrDefault(MAXIMUM_VARIABLE_NAME_LENGTH, DEFAULT_MAXIMUM_VARIABLE_NAME_LENGTH) + override val issue = Issue(javaClass.simpleName, + Severity.Style, + "Variable names should not be longer than the maximum set in the configuration.", + debt = Debt.FIVE_MINS) + private val maximumVariableNameLength = + valueOrDefault(MAXIMUM_VARIABLE_NAME_LENGTH, DEFAULT_MAXIMUM_VARIABLE_NAME_LENGTH) - override fun visitProperty(property: KtProperty) { - if (property.identifierName().length > maximumVariableNameLength) { - report(CodeSmell( - issue, - Entity.from(property), - message = "Variable names should be at most $maximumVariableNameLength characters long.")) - } - } + override fun visitProperty(property: KtProperty) { + if (property.identifierName().length > maximumVariableNameLength) { + report(CodeSmell( + issue, + Entity.from(property), + message = "Variable names should be at most $maximumVariableNameLength characters long.")) + } + } - companion object { - const val MAXIMUM_VARIABLE_NAME_LENGTH = "maximumVariableNameLength" - private const val DEFAULT_MAXIMUM_VARIABLE_NAME_LENGTH = 64 - } + companion object { + const val MAXIMUM_VARIABLE_NAME_LENGTH = "maximumVariableNameLength" + private const val DEFAULT_MAXIMUM_VARIABLE_NAME_LENGTH = 64 + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/VariableMinLength.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/VariableMinLength.kt index ebaee9a9e..339f52c0b 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/VariableMinLength.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/VariableMinLength.kt @@ -19,28 +19,28 @@ import org.jetbrains.kotlin.resolve.calls.util.isSingleUnderscore */ class VariableMinLength(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, - Severity.Style, - "Variable names should not be shorter than the minimum defined in the configuration.", - debt = Debt.FIVE_MINS) - private val minimumVariableNameLength = - valueOrDefault(MINIMUM_VARIABLE_NAME_LENGTH, DEFAULT_MINIMUM_VARIABLE_NAME_LENGTH) + override val issue = Issue(javaClass.simpleName, + Severity.Style, + "Variable names should not be shorter than the minimum defined in the configuration.", + debt = Debt.FIVE_MINS) + private val minimumVariableNameLength = + valueOrDefault(MINIMUM_VARIABLE_NAME_LENGTH, DEFAULT_MINIMUM_VARIABLE_NAME_LENGTH) - override fun visitProperty(property: KtProperty) { - if (property.isSingleUnderscore) { - return - } + override fun visitProperty(property: KtProperty) { + if (property.isSingleUnderscore) { + return + } - if (property.identifierName().length < minimumVariableNameLength) { - report(CodeSmell( - issue, - Entity.from(property), - message = "Variable names should be at least $minimumVariableNameLength characters long.")) - } - } + if (property.identifierName().length < minimumVariableNameLength) { + report(CodeSmell( + issue, + Entity.from(property), + message = "Variable names should be at least $minimumVariableNameLength characters long.")) + } + } - companion object { - const val MINIMUM_VARIABLE_NAME_LENGTH = "minimumVariableNameLength" - private const val DEFAULT_MINIMUM_VARIABLE_NAME_LENGTH = 1 - } + companion object { + const val MINIMUM_VARIABLE_NAME_LENGTH = "minimumVariableNameLength" + private const val DEFAULT_MINIMUM_VARIABLE_NAME_LENGTH = 1 + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/VariableNaming.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/VariableNaming.kt index 595ab626a..9965afc36 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/VariableNaming.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/VariableNaming.kt @@ -29,47 +29,47 @@ import org.jetbrains.kotlin.resolve.calls.util.isSingleUnderscore */ class VariableNaming(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, - Severity.Style, - "Variable names should follow the naming convention set in the projects configuration.", - debt = Debt.FIVE_MINS) + override val issue = Issue(javaClass.simpleName, + Severity.Style, + "Variable names should follow the naming convention set in the projects configuration.", + debt = Debt.FIVE_MINS) - private val variablePattern by LazyRegex(VARIABLE_PATTERN, "[a-z][A-Za-z0-9]*") - private val privateVariablePattern by LazyRegex(PRIVATE_VARIABLE_PATTERN, "(_)?[a-z][A-Za-z0-9]*") - private val excludeClassPattern by LazyRegex(EXCLUDE_CLASS_PATTERN, "$^") - private val ignoreOverridden = valueOrDefault(IGNORE_OVERRIDDEN, true) + private val variablePattern by LazyRegex(VARIABLE_PATTERN, "[a-z][A-Za-z0-9]*") + private val privateVariablePattern by LazyRegex(PRIVATE_VARIABLE_PATTERN, "(_)?[a-z][A-Za-z0-9]*") + private val excludeClassPattern by LazyRegex(EXCLUDE_CLASS_PATTERN, "$^") + private val ignoreOverridden = valueOrDefault(IGNORE_OVERRIDDEN, true) - override fun visitProperty(property: KtProperty) { - if (property.isSingleUnderscore || property.isContainingExcludedClassOrObject(excludeClassPattern)) { - return - } + override fun visitProperty(property: KtProperty) { + if (property.isSingleUnderscore || property.isContainingExcludedClassOrObject(excludeClassPattern)) { + return + } - if (ignoreOverridden && property.isOverride()) { - return - } + if (ignoreOverridden && property.isOverride()) { + return + } - val identifier = property.identifierName() - if (property.isPrivate()) { - if (!identifier.matches(privateVariablePattern)) { - report(CodeSmell( - issue, - Entity.from(property), - message = "Private variable names should match the pattern: $privateVariablePattern")) - } - } else { - if (!identifier.matches(variablePattern)) { - report(CodeSmell( - issue, - Entity.from(property), - message = "Variable names should match the pattern: $variablePattern")) - } - } - } + val identifier = property.identifierName() + if (property.isPrivate()) { + if (!identifier.matches(privateVariablePattern)) { + report(CodeSmell( + issue, + Entity.from(property), + message = "Private variable names should match the pattern: $privateVariablePattern")) + } + } else { + if (!identifier.matches(variablePattern)) { + report(CodeSmell( + issue, + Entity.from(property), + message = "Variable names should match the pattern: $variablePattern")) + } + } + } - companion object { - const val VARIABLE_PATTERN = "variablePattern" - const val PRIVATE_VARIABLE_PATTERN = "privateVariablePattern" - const val EXCLUDE_CLASS_PATTERN = "excludeClassPattern" - const val IGNORE_OVERRIDDEN = "ignoreOverridden" - } + companion object { + const val VARIABLE_PATTERN = "variablePattern" + const val PRIVATE_VARIABLE_PATTERN = "privateVariablePattern" + const val EXCLUDE_CLASS_PATTERN = "excludeClassPattern" + const val IGNORE_OVERRIDDEN = "ignoreOverridden" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/util/ExcludeClass.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/util/ExcludeClass.kt index 3a661188e..65a072995 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/util/ExcludeClass.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/util/ExcludeClass.kt @@ -6,7 +6,7 @@ import org.jetbrains.kotlin.psi.psiUtil.containingClass import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject internal fun KtDeclaration.isContainingExcludedClassOrObject(pattern: Regex) = - containingClassOrObject?.identifierName()?.matches(pattern) == true + containingClassOrObject?.identifierName()?.matches(pattern) == true internal fun KtDeclaration.isContainingExcludedClass(pattern: Regex) = - containingClass()?.identifierName()?.matches(pattern) == true + containingClass()?.identifierName()?.matches(pattern) == true diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/performance/ArrayPrimitive.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/performance/ArrayPrimitive.kt index bc1066feb..caddd4651 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/performance/ArrayPrimitive.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/performance/ArrayPrimitive.kt @@ -38,51 +38,51 @@ import org.jetbrains.kotlin.psi.KtTypeReference */ class ArrayPrimitive(config: Config = Config.empty) : Rule(config) { - override val issue = Issue("ArrayPrimitive", - Severity.Performance, - "Using Array leads to implicit boxing and a performance hit", - Debt.FIVE_MINS) + override val issue = Issue("ArrayPrimitive", + Severity.Performance, + "Using Array leads to implicit boxing and a performance hit", + Debt.FIVE_MINS) - private val primitiveTypes = hashSetOf( - "Int", - "Double", - "Float", - "Short", - "Byte", - "Long", - "Char" - ) + private val primitiveTypes = hashSetOf( + "Int", + "Double", + "Float", + "Short", + "Byte", + "Long", + "Char" + ) - override fun visitParameter(parameter: KtParameter) { - val typeReference = parameter.typeReference - if (typeReference != null) { - reportArrayPrimitives(typeReference) - } - super.visitParameter(parameter) - } + override fun visitParameter(parameter: KtParameter) { + val typeReference = parameter.typeReference + if (typeReference != null) { + reportArrayPrimitives(typeReference) + } + super.visitParameter(parameter) + } - override fun visitNamedFunction(function: KtNamedFunction) { - if (function.hasDeclaredReturnType()) { - val typeReference = function.typeReference - if (typeReference != null) { - reportArrayPrimitives(typeReference) - } - } - super.visitNamedFunction(function) - } + override fun visitNamedFunction(function: KtNamedFunction) { + if (function.hasDeclaredReturnType()) { + val typeReference = function.typeReference + if (typeReference != null) { + reportArrayPrimitives(typeReference) + } + } + super.visitNamedFunction(function) + } - private fun reportArrayPrimitives(element: KtElement) { - return element - .collectByType() - .filter { isArrayPrimitive(it) } - .forEach { report(CodeSmell(issue, Entity.from(it), issue.description)) } - } + private fun reportArrayPrimitives(element: KtElement) { + return element + .collectByType() + .filter { isArrayPrimitive(it) } + .forEach { report(CodeSmell(issue, Entity.from(it), issue.description)) } + } - private fun isArrayPrimitive(it: KtTypeReference): Boolean { - if (it.text?.startsWith("Array<") == true) { - val genericTypeArguments = it.typeElement?.typeArgumentsAsTypes - return genericTypeArguments?.size == 1 && primitiveTypes.contains(genericTypeArguments[0].text) - } - return false - } + private fun isArrayPrimitive(it: KtTypeReference): Boolean { + if (it.text?.startsWith("Array<") == true) { + val genericTypeArguments = it.typeElement?.typeArgumentsAsTypes + return genericTypeArguments?.size == 1 && primitiveTypes.contains(genericTypeArguments[0].text) + } + return false + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/performance/ForEachOnRange.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/performance/ForEachOnRange.kt index 16a62a2bf..5e6b5b6db 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/performance/ForEachOnRange.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/performance/ForEachOnRange.kt @@ -49,47 +49,47 @@ import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression */ class ForEachOnRange(config: Config = Config.empty) : Rule(config) { - override val issue = Issue("ForEachOnRange", - Severity.Performance, - "Using the forEach method on ranges has a heavy performance cost. Prefer using simple for loops.", - Debt.FIVE_MINS) + override val issue = Issue("ForEachOnRange", + Severity.Performance, + "Using the forEach method on ranges has a heavy performance cost. Prefer using simple for loops.", + Debt.FIVE_MINS) - private val minimumRangeSize = 3 - private val rangeOperators = setOf("..", "downTo", "until", "step") + private val minimumRangeSize = 3 + private val rangeOperators = setOf("..", "downTo", "until", "step") - override fun visitCallExpression(expression: KtCallExpression) { - super.visitCallExpression(expression) + override fun visitCallExpression(expression: KtCallExpression) { + super.visitCallExpression(expression) - expression.getCallNameExpression()?.let { - if (!it.textMatches("forEach")) { - return - } - val parenthesizedExpression = it.getReceiverExpression() as? KtParenthesizedExpression - val binaryExpression = parenthesizedExpression?.expression as? KtBinaryExpression - if (binaryExpression != null && isRangeOperator(binaryExpression)) { - report(CodeSmell(issue, Entity.from(expression), issue.description)) - } - } - } + expression.getCallNameExpression()?.let { + if (!it.textMatches("forEach")) { + return + } + val parenthesizedExpression = it.getReceiverExpression() as? KtParenthesizedExpression + val binaryExpression = parenthesizedExpression?.expression as? KtBinaryExpression + if (binaryExpression != null && isRangeOperator(binaryExpression)) { + report(CodeSmell(issue, Entity.from(expression), issue.description)) + } + } + } - private fun isRangeOperator(binaryExpression: KtBinaryExpression): Boolean { - val range = binaryExpression.children - if (range.size >= minimumRangeSize) { - val hasCorrectLowerValue = hasCorrectLowerValue(range[0]) - val hasCorrectUpperValue = getIntValueForPsiElement(range[2]) != null - return hasCorrectLowerValue && hasCorrectUpperValue && rangeOperators.contains(range[1].text) - } - return false - } + private fun isRangeOperator(binaryExpression: KtBinaryExpression): Boolean { + val range = binaryExpression.children + if (range.size >= minimumRangeSize) { + val hasCorrectLowerValue = hasCorrectLowerValue(range[0]) + val hasCorrectUpperValue = getIntValueForPsiElement(range[2]) != null + return hasCorrectLowerValue && hasCorrectUpperValue && rangeOperators.contains(range[1].text) + } + return false + } - private fun hasCorrectLowerValue(element: PsiElement): Boolean { - var lowerValue = getIntValueForPsiElement(element) != null - if (!lowerValue) { - val expression = element as? KtBinaryExpression - if (expression != null) { - lowerValue = isRangeOperator(expression) - } - } - return lowerValue - } + private fun hasCorrectLowerValue(element: PsiElement): Boolean { + var lowerValue = getIntValueForPsiElement(element) != null + if (!lowerValue) { + val expression = element as? KtBinaryExpression + if (expression != null) { + lowerValue = isRangeOperator(expression) + } + } + return lowerValue + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/performance/SpreadOperator.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/performance/SpreadOperator.kt index 961b6d2ed..48e5e3444 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/performance/SpreadOperator.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/performance/SpreadOperator.kt @@ -30,16 +30,16 @@ import org.jetbrains.kotlin.psi.KtValueArgumentList */ class SpreadOperator(config: Config = Config.empty) : Rule(config) { - override val issue: Issue = Issue("SpreadOperator", Severity.Performance, - "Using a spread operator causes a full copy of the array to be created before calling a method " + - "has a very high performance penalty.", - Debt.TWENTY_MINS) + override val issue: Issue = Issue("SpreadOperator", Severity.Performance, + "Using a spread operator causes a full copy of the array to be created before calling a method " + + "has a very high performance penalty.", + Debt.TWENTY_MINS) - override fun visitValueArgumentList(list: KtValueArgumentList) { - super.visitValueArgumentList(list) - list.arguments.filter { it.getSpreadElement() != null } - .onEach { - report(CodeSmell(issue, Entity.from(list), issue.description)) - } - } + override fun visitValueArgumentList(list: KtValueArgumentList) { + super.visitValueArgumentList(list) + list.arguments.filter { it.getSpreadElement() != null } + .onEach { + report(CodeSmell(issue, Entity.from(list), issue.description)) + } + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/performance/UnnecessaryTemporaryInstantiation.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/performance/UnnecessaryTemporaryInstantiation.kt index 48af26cd9..6abd86b06 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/performance/UnnecessaryTemporaryInstantiation.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/performance/UnnecessaryTemporaryInstantiation.kt @@ -31,20 +31,20 @@ import org.jetbrains.kotlin.psi.KtExpression */ class UnnecessaryTemporaryInstantiation(config: Config = Config.empty) : Rule(config) { - override val issue: Issue = Issue("UnnecessaryTemporaryInstantiation", Severity.Performance, - "Avoid temporary objects when converting primitive types to String.", - Debt.FIVE_MINS) + override val issue: Issue = Issue("UnnecessaryTemporaryInstantiation", Severity.Performance, + "Avoid temporary objects when converting primitive types to String.", + Debt.FIVE_MINS) - private val types: Set = hashSetOf("Boolean", "Byte", "Short", "Integer", "Long", "Float", "Double") + private val types: Set = hashSetOf("Boolean", "Byte", "Short", "Integer", "Long", "Float", "Double") - override fun visitCallExpression(expression: KtCallExpression) { - if (isPrimitiveWrapperType(expression.calleeExpression) && - isToStringMethod(expression.nextSibling?.nextSibling)) { - report(CodeSmell(issue, Entity.from(expression), issue.description)) - } - } + override fun visitCallExpression(expression: KtCallExpression) { + if (isPrimitiveWrapperType(expression.calleeExpression) && + isToStringMethod(expression.nextSibling?.nextSibling)) { + report(CodeSmell(issue, Entity.from(expression), issue.description)) + } + } - private fun isPrimitiveWrapperType(expression: KtExpression?) = types.contains(expression?.text) + private fun isPrimitiveWrapperType(expression: KtExpression?) = types.contains(expression?.text) - private fun isToStringMethod(element: PsiElement?) = element?.text == "toString()" + private fun isToStringMethod(element: PsiElement?) = element?.text == "toString()" } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/providers/CommentSmellProvider.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/providers/CommentSmellProvider.kt index 7134cfc84..e579475fa 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/providers/CommentSmellProvider.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/providers/CommentSmellProvider.kt @@ -18,15 +18,15 @@ import io.gitlab.arturbosch.detekt.rules.documentation.UndocumentedPublicFunctio */ class CommentSmellProvider : RuleSetProvider { - override val ruleSetId: String = "comments" + override val ruleSetId: String = "comments" - override fun instance(config: Config): RuleSet { - return RuleSet(ruleSetId, listOf( - CommentOverPrivateFunction(config), - CommentOverPrivateProperty(config), - KDocStyle(config), - UndocumentedPublicClass(config), - UndocumentedPublicFunction(config) - )) - } + override fun instance(config: Config): RuleSet { + return RuleSet(ruleSetId, listOf( + CommentOverPrivateFunction(config), + CommentOverPrivateProperty(config), + KDocStyle(config), + UndocumentedPublicClass(config), + UndocumentedPublicFunction(config) + )) + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/providers/ComplexityProvider.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/providers/ComplexityProvider.kt index d112469c1..76a4acda2 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/providers/ComplexityProvider.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/providers/ComplexityProvider.kt @@ -23,21 +23,21 @@ import io.gitlab.arturbosch.detekt.rules.complexity.TooManyFunctions */ class ComplexityProvider : RuleSetProvider { - override val ruleSetId: String = "complexity" + override val ruleSetId: String = "complexity" - override fun instance(config: Config): RuleSet { - return RuleSet(ruleSetId, listOf( - LongParameterList(config), - LongMethod(config), - LargeClass(config), - ComplexInterface(config), - ComplexMethod(config), - StringLiteralDuplication(config), - MethodOverloading(config), - NestedBlockDepth(config), - TooManyFunctions(config), - ComplexCondition(config), - LabeledExpression(config) - )) - } + override fun instance(config: Config): RuleSet { + return RuleSet(ruleSetId, listOf( + LongParameterList(config), + LongMethod(config), + LargeClass(config), + ComplexInterface(config), + ComplexMethod(config), + StringLiteralDuplication(config), + MethodOverloading(config), + NestedBlockDepth(config), + TooManyFunctions(config), + ComplexCondition(config), + LabeledExpression(config) + )) + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/providers/EmptyCodeProvider.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/providers/EmptyCodeProvider.kt index b0bdc6530..fea14a8c8 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/providers/EmptyCodeProvider.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/providers/EmptyCodeProvider.kt @@ -14,11 +14,11 @@ import io.gitlab.arturbosch.detekt.rules.empty.EmptyBlocks */ class EmptyCodeProvider : RuleSetProvider { - override val ruleSetId: String = "empty-blocks" + override val ruleSetId: String = "empty-blocks" - override fun instance(config: Config): RuleSet { - return RuleSet(ruleSetId, listOf( - EmptyBlocks(config) - )) - } + override fun instance(config: Config): RuleSet { + return RuleSet(ruleSetId, listOf( + EmptyBlocks(config) + )) + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/providers/ExceptionsProvider.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/providers/ExceptionsProvider.kt index 6d82a0f68..81564c117 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/providers/ExceptionsProvider.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/providers/ExceptionsProvider.kt @@ -25,23 +25,23 @@ import io.gitlab.arturbosch.detekt.rules.exceptions.TooGenericExceptionThrown */ class ExceptionsProvider : RuleSetProvider { - override val ruleSetId: String = "exceptions" + override val ruleSetId: String = "exceptions" - override fun instance(config: Config): RuleSet { - return RuleSet(ruleSetId, listOf( - TooGenericExceptionCaught(config), - ExceptionRaisedInUnexpectedLocation(config), - TooGenericExceptionThrown(config), - NotImplementedDeclaration(config), - PrintStackTrace(config), - InstanceOfCheckForException(config), - ThrowingExceptionsWithoutMessageOrCause(config), - ReturnFromFinally(config), - ThrowingExceptionFromFinally(config), - ThrowingExceptionInMain(config), - RethrowCaughtException(config), - ThrowingNewInstanceOfSameException(config), - SwallowedException(config) - )) - } + override fun instance(config: Config): RuleSet { + return RuleSet(ruleSetId, listOf( + TooGenericExceptionCaught(config), + ExceptionRaisedInUnexpectedLocation(config), + TooGenericExceptionThrown(config), + NotImplementedDeclaration(config), + PrintStackTrace(config), + InstanceOfCheckForException(config), + ThrowingExceptionsWithoutMessageOrCause(config), + ReturnFromFinally(config), + ThrowingExceptionFromFinally(config), + ThrowingExceptionInMain(config), + RethrowCaughtException(config), + ThrowingNewInstanceOfSameException(config), + SwallowedException(config) + )) + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/providers/NamingProvider.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/providers/NamingProvider.kt index 7caef8c1c..51a42cf2a 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/providers/NamingProvider.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/providers/NamingProvider.kt @@ -15,13 +15,13 @@ import io.gitlab.arturbosch.detekt.rules.naming.NamingRules */ class NamingProvider : RuleSetProvider { - override val ruleSetId: String = "naming" + override val ruleSetId: String = "naming" - override fun instance(config: Config): RuleSet { - return RuleSet(ruleSetId, listOf( - MatchingDeclarationName(config), - MemberNameEqualsClassName(config), - NamingRules(config) - )) - } + override fun instance(config: Config): RuleSet { + return RuleSet(ruleSetId, listOf( + MatchingDeclarationName(config), + MemberNameEqualsClassName(config), + NamingRules(config) + )) + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/providers/PerformanceProvider.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/providers/PerformanceProvider.kt index 5f78ff5f3..c81821dab 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/providers/PerformanceProvider.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/providers/PerformanceProvider.kt @@ -16,14 +16,14 @@ import io.gitlab.arturbosch.detekt.rules.performance.UnnecessaryTemporaryInstant */ class PerformanceProvider : RuleSetProvider { - override val ruleSetId: String = "performance" + override val ruleSetId: String = "performance" - override fun instance(config: Config): RuleSet { - return RuleSet(ruleSetId, listOf( - ForEachOnRange(config), - SpreadOperator(config), - UnnecessaryTemporaryInstantiation(config), - ArrayPrimitive(config) - )) - } + override fun instance(config: Config): RuleSet { + return RuleSet(ruleSetId, listOf( + ForEachOnRange(config), + SpreadOperator(config), + UnnecessaryTemporaryInstantiation(config), + ArrayPrimitive(config) + )) + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/providers/PotentialBugProvider.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/providers/PotentialBugProvider.kt index fbd9b6801..0b6ab30e3 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/providers/PotentialBugProvider.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/providers/PotentialBugProvider.kt @@ -26,24 +26,24 @@ import io.gitlab.arturbosch.detekt.rules.bugs.WrongEqualsTypeParameter */ class PotentialBugProvider : RuleSetProvider { - override val ruleSetId: String = "potential-bugs" + override val ruleSetId: String = "potential-bugs" - override fun instance(config: Config): RuleSet { - return RuleSet(ruleSetId, listOf( - DuplicateCaseInWhenExpression(config), - EqualsAlwaysReturnsTrueOrFalse(config), - EqualsWithHashCodeExist(config), - IteratorNotThrowingNoSuchElementException(config), - IteratorHasNextCallsNextMethod(config), - UselessPostfixExpression(config), - InvalidRange(config), - WrongEqualsTypeParameter(config), - ExplicitGarbageCollectionCall(config), - LateinitUsage(config), - UnconditionalJumpStatementInLoop(config), - UnreachableCode(config), - UnsafeCallOnNullableType(config), - UnsafeCast(config) - )) - } + override fun instance(config: Config): RuleSet { + return RuleSet(ruleSetId, listOf( + DuplicateCaseInWhenExpression(config), + EqualsAlwaysReturnsTrueOrFalse(config), + EqualsWithHashCodeExist(config), + IteratorNotThrowingNoSuchElementException(config), + IteratorHasNextCallsNextMethod(config), + UselessPostfixExpression(config), + InvalidRange(config), + WrongEqualsTypeParameter(config), + ExplicitGarbageCollectionCall(config), + LateinitUsage(config), + UnconditionalJumpStatementInLoop(config), + UnreachableCode(config), + UnsafeCallOnNullableType(config), + UnsafeCast(config) + )) + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/providers/StyleGuideProvider.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/providers/StyleGuideProvider.kt index 16ca56179..95b6dfe5d 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/providers/StyleGuideProvider.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/providers/StyleGuideProvider.kt @@ -5,8 +5,8 @@ import io.gitlab.arturbosch.detekt.api.RuleSet import io.gitlab.arturbosch.detekt.api.RuleSetProvider import io.gitlab.arturbosch.detekt.rules.style.CollapsibleIfStatements import io.gitlab.arturbosch.detekt.rules.style.DataClassContainsFunctions -import io.gitlab.arturbosch.detekt.rules.style.EqualsOnSignatureLine import io.gitlab.arturbosch.detekt.rules.style.EqualsNullCall +import io.gitlab.arturbosch.detekt.rules.style.EqualsOnSignatureLine import io.gitlab.arturbosch.detekt.rules.style.ExplicitItLambdaParameter import io.gitlab.arturbosch.detekt.rules.style.ExpressionBodySyntax import io.gitlab.arturbosch.detekt.rules.style.FileParsingRule @@ -56,52 +56,52 @@ import io.gitlab.arturbosch.detekt.rules.style.optional.PreferToOverPairSyntax */ class StyleGuideProvider : RuleSetProvider { - override val ruleSetId: String = "style" + override val ruleSetId: String = "style" - override fun instance(config: Config): RuleSet { - return RuleSet(ruleSetId, listOf( - CollapsibleIfStatements(config), - ReturnCount(config), - ThrowsCount(config), - NewLineAtEndOfFile(config), - WildcardImport(config), - FileParsingRule(config), - EqualsOnSignatureLine(config), - EqualsNullCall(config), - ForbiddenComment(config), - ForbiddenImport(config), - FunctionOnlyReturningConstant(config), - SpacingBetweenPackageAndImports(config), - LoopWithTooManyJumpStatements(config), - SafeCast(config), - UnnecessaryAbstractClass(config), - UnnecessaryParentheses(config), - UnnecessaryInheritance(config), - UtilityClassWithPublicConstructor(config), - OptionalAbstractKeyword(config), - OptionalWhenBraces(config), - OptionalUnit(config), - ProtectedMemberInFinalClass(config), - SerialVersionUIDInSerializableClass(config), - MagicNumber(config), - ModifierOrder(config), - DataClassContainsFunctions(config), - UseDataClass(config), - UnusedImports(config), - UnusedPrivateClass(config), - UnusedPrivateMember(config), - ExpressionBodySyntax(config), - NestedClassesVisibility(config), - RedundantVisibilityModifierRule(config), - UntilInsteadOfRangeTo(config), - UnnecessaryApply(config), - UnnecessaryLet(config), - MayBeConst(config), - PreferToOverPairSyntax(config), - MandatoryBracesIfStatements(config), - VarCouldBeVal(config), - ForbiddenVoid(config), - ExplicitItLambdaParameter(config) - )) - } + override fun instance(config: Config): RuleSet { + return RuleSet(ruleSetId, listOf( + CollapsibleIfStatements(config), + ReturnCount(config), + ThrowsCount(config), + NewLineAtEndOfFile(config), + WildcardImport(config), + FileParsingRule(config), + EqualsOnSignatureLine(config), + EqualsNullCall(config), + ForbiddenComment(config), + ForbiddenImport(config), + FunctionOnlyReturningConstant(config), + SpacingBetweenPackageAndImports(config), + LoopWithTooManyJumpStatements(config), + SafeCast(config), + UnnecessaryAbstractClass(config), + UnnecessaryParentheses(config), + UnnecessaryInheritance(config), + UtilityClassWithPublicConstructor(config), + OptionalAbstractKeyword(config), + OptionalWhenBraces(config), + OptionalUnit(config), + ProtectedMemberInFinalClass(config), + SerialVersionUIDInSerializableClass(config), + MagicNumber(config), + ModifierOrder(config), + DataClassContainsFunctions(config), + UseDataClass(config), + UnusedImports(config), + UnusedPrivateClass(config), + UnusedPrivateMember(config), + ExpressionBodySyntax(config), + NestedClassesVisibility(config), + RedundantVisibilityModifierRule(config), + UntilInsteadOfRangeTo(config), + UnnecessaryApply(config), + UnnecessaryLet(config), + MayBeConst(config), + PreferToOverPairSyntax(config), + MandatoryBracesIfStatements(config), + VarCouldBeVal(config), + ForbiddenVoid(config), + ExplicitItLambdaParameter(config) + )) + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/CollapsibleIfStatements.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/CollapsibleIfStatements.kt index 109510539..5983c894f 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/CollapsibleIfStatements.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/CollapsibleIfStatements.kt @@ -39,28 +39,28 @@ import org.jetbrains.kotlin.psi.KtIfExpression */ class CollapsibleIfStatements(config: Config = Config.empty) : Rule(config) { - override val issue = Issue("CollapsibleIfStatements", Severity.Style, - "Two if statements which could be collapsed were detected. " + - "These statements can be merged to improve readability.", - Debt.FIVE_MINS) + override val issue = Issue("CollapsibleIfStatements", Severity.Style, + "Two if statements which could be collapsed were detected. " + + "These statements can be merged to improve readability.", + Debt.FIVE_MINS) - override fun visitIfExpression(expression: KtIfExpression) { - if (isNotElseIfOrElse(expression) && hasOneKtIfExpression(expression)) { - report(CodeSmell(issue, Entity.from(expression), issue.description)) - } - super.visitIfExpression(expression) - } + override fun visitIfExpression(expression: KtIfExpression) { + if (isNotElseIfOrElse(expression) && hasOneKtIfExpression(expression)) { + report(CodeSmell(issue, Entity.from(expression), issue.description)) + } + super.visitIfExpression(expression) + } - private fun isNotElseIfOrElse(expression: KtIfExpression) = - expression.`else` == null && expression.parent !is KtContainerNodeForControlStructureBody + private fun isNotElseIfOrElse(expression: KtIfExpression) = + expression.`else` == null && expression.parent !is KtContainerNodeForControlStructureBody - private fun hasOneKtIfExpression(expression: KtIfExpression): Boolean { - val statements = expression.then?.children?.filterNot { it is PsiComment } - return statements != null && statements.size == 1 && isLoneIfExpression(statements[0]) - } + private fun hasOneKtIfExpression(expression: KtIfExpression): Boolean { + val statements = expression.then?.children?.filterNot { it is PsiComment } + return statements != null && statements.size == 1 && isLoneIfExpression(statements[0]) + } - private fun isLoneIfExpression(statement: PsiElement): Boolean { - val ifExpression = statement as? KtIfExpression - return ifExpression != null && ifExpression.`else` == null - } + private fun isLoneIfExpression(statement: PsiElement): Boolean { + val ifExpression = statement as? KtIfExpression + return ifExpression != null && ifExpression.`else` == null + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/DataClassContainsFunctions.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/DataClassContainsFunctions.kt index f2a26a4d5..84603a76d 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/DataClassContainsFunctions.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/DataClassContainsFunctions.kt @@ -32,32 +32,32 @@ import org.jetbrains.kotlin.psi.KtNamedFunction */ class DataClassContainsFunctions(config: Config = Config.empty) : Rule(config) { - override val issue: Issue = Issue("DataClassContainsFunctions", - Severity.Style, - "Data classes should mainly be used to store data and should not have any extra functions. " + - "(Compiler will automatically generate equals, toString and hashCode functions)", - Debt.TWENTY_MINS) + override val issue: Issue = Issue("DataClassContainsFunctions", + Severity.Style, + "Data classes should mainly be used to store data and should not have any extra functions. " + + "(Compiler will automatically generate equals, toString and hashCode functions)", + Debt.TWENTY_MINS) - private val conversionFunctionPrefix = SplitPattern(valueOrDefault(CONVERSION_FUNCTION_PREFIX, "")) + private val conversionFunctionPrefix = SplitPattern(valueOrDefault(CONVERSION_FUNCTION_PREFIX, "")) - override fun visitClass(klass: KtClass) { - if (klass.isData()) { - klass.body?.declarations - ?.filterIsInstance() - ?.forEach { checkFunction(klass, it) } - } - super.visitClass(klass) - } + override fun visitClass(klass: KtClass) { + if (klass.isData()) { + klass.body?.declarations + ?.filterIsInstance() + ?.forEach { checkFunction(klass, it) } + } + super.visitClass(klass) + } - private fun checkFunction(klass: KtClass, function: KtNamedFunction) { - if (!function.isOverride() && !conversionFunctionPrefix.startWith(function.name)) { - report(CodeSmell(issue, Entity.from(function), - "The data class ${klass.name} contains functions which are not registered " + - "conversion functions. The offending method is called ${function.name}")) - } - } + private fun checkFunction(klass: KtClass, function: KtNamedFunction) { + if (!function.isOverride() && !conversionFunctionPrefix.startWith(function.name)) { + report(CodeSmell(issue, Entity.from(function), + "The data class ${klass.name} contains functions which are not registered " + + "conversion functions. The offending method is called ${function.name}")) + } + } - companion object { - const val CONVERSION_FUNCTION_PREFIX = "conversionFunctionPrefix" - } + companion object { + const val CONVERSION_FUNCTION_PREFIX = "conversionFunctionPrefix" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/EqualsNullCall.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/EqualsNullCall.kt index 032449ae2..af9c1baaf 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/EqualsNullCall.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/EqualsNullCall.kt @@ -26,20 +26,20 @@ import org.jetbrains.kotlin.psi.KtCallExpression */ class EqualsNullCall(config: Config = Config.empty) : Rule(config) { - override val issue = Issue("EqualsNullCall", Severity.Style, - "Equals() method is called with null as parameter. Consider using == to compare to null.", - Debt.FIVE_MINS) + override val issue = Issue("EqualsNullCall", Severity.Style, + "Equals() method is called with null as parameter. Consider using == to compare to null.", + Debt.FIVE_MINS) - override fun visitCallExpression(expression: KtCallExpression) { - if (expression.calleeExpression?.text == "equals" && hasNullParameter(expression)) { - report(CodeSmell(issue, Entity.from(expression), issue.description)) - } else { - super.visitCallExpression(expression) - } - } + override fun visitCallExpression(expression: KtCallExpression) { + if (expression.calleeExpression?.text == "equals" && hasNullParameter(expression)) { + report(CodeSmell(issue, Entity.from(expression), issue.description)) + } else { + super.visitCallExpression(expression) + } + } - private fun hasNullParameter(expression: KtCallExpression): Boolean { - val valueArguments = expression.valueArguments - return valueArguments.size == 1 && valueArguments.first().text == "null" - } + private fun hasNullParameter(expression: KtCallExpression): Boolean { + val valueArguments = expression.valueArguments + return valueArguments.size == 1 && valueArguments.first().text == "null" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/EqualsOnSignatureLine.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/EqualsOnSignatureLine.kt index 4560e7254..e4b936af5 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/EqualsOnSignatureLine.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/EqualsOnSignatureLine.kt @@ -34,29 +34,29 @@ import org.jetbrains.kotlin.psi.psiUtil.siblings */ class EqualsOnSignatureLine(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, Severity.Style, MESSAGE, Debt.FIVE_MINS) + override val issue = Issue(javaClass.simpleName, Severity.Style, MESSAGE, Debt.FIVE_MINS) - override fun visitNamedFunction(function: KtNamedFunction) { - val equals = function.equalsToken ?: return + override fun visitNamedFunction(function: KtNamedFunction) { + val equals = function.equalsToken ?: return - // Get the tokens after the parameter list (but not including) - val afterParams = function.valueParameterList?.siblings(forward = true, withItself = false) ?: return + // Get the tokens after the parameter list (but not including) + val afterParams = function.valueParameterList?.siblings(forward = true, withItself = false) ?: return - // Collect tokens until we find the equals sign - val untilEquals = afterParams.takeWhile { it !== equals }.toList() + // Collect tokens until we find the equals sign + val untilEquals = afterParams.takeWhile { it !== equals }.toList() - // Walk backwards from the '=' to find the whitespace right behind it - val whitespace = untilEquals.takeLastWhile { it is PsiWhiteSpace } + // Walk backwards from the '=' to find the whitespace right behind it + val whitespace = untilEquals.takeLastWhile { it is PsiWhiteSpace } - // Search the whitespace tokens to see if they contain newlines - whitespace.forEach { - if (it.textContains('\n')) { - report(CodeSmell(issue, Entity.from(equals), MESSAGE)) - } - } - } + // Search the whitespace tokens to see if they contain newlines + whitespace.forEach { + if (it.textContains('\n')) { + report(CodeSmell(issue, Entity.from(equals), MESSAGE)) + } + } + } - private companion object { - const val MESSAGE = "Equals signs for expression style functions should be on the same line as the signature" - } + private companion object { + const val MESSAGE = "Equals signs for expression style functions should be on the same line as the signature" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ExplicitItLambdaParameter.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ExplicitItLambdaParameter.kt index d452be6ae..02122a20b 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ExplicitItLambdaParameter.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ExplicitItLambdaParameter.kt @@ -40,17 +40,17 @@ import org.jetbrains.kotlin.psi.KtLambdaExpression * @author mishkun */ class ExplicitItLambdaParameter(val config: Config) : Rule(config) { - override val issue = Issue(javaClass.simpleName, Severity.Style, - "Declaring lambda parameters as `it` is redundant.", Debt.FIVE_MINS) + override val issue = Issue(javaClass.simpleName, Severity.Style, + "Declaring lambda parameters as `it` is redundant.", Debt.FIVE_MINS) - override fun visitLambdaExpression(lambdaExpression: KtLambdaExpression) { - super.visitLambdaExpression(lambdaExpression) - val parameterNames = lambdaExpression.valueParameters.map { it.name } - if (IT_LITERAL in parameterNames) { - report(CodeSmell( - issue, Entity.from(lambdaExpression), - "This explicit usage of `it` as the lambda parameter name can be omitted." - )) - } - } + override fun visitLambdaExpression(lambdaExpression: KtLambdaExpression) { + super.visitLambdaExpression(lambdaExpression) + val parameterNames = lambdaExpression.valueParameters.map { it.name } + if (IT_LITERAL in parameterNames) { + report(CodeSmell( + issue, Entity.from(lambdaExpression), + "This explicit usage of `it` as the lambda parameter name can be omitted." + )) + } + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ExpressionBodySyntax.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ExpressionBodySyntax.kt index f2dda7d86..b6b404e6f 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ExpressionBodySyntax.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ExpressionBodySyntax.kt @@ -41,40 +41,40 @@ import org.jetbrains.kotlin.psi.KtReturnExpression */ class ExpressionBodySyntax(config: Config = Config.empty) : Rule(config) { - override val issue = Issue( - javaClass.simpleName, - Severity.Style, - "Functions with exact one statement, the return statement," + - " can be rewritten with ExpressionBodySyntax.", - Debt.FIVE_MINS) + override val issue = Issue( + javaClass.simpleName, + Severity.Style, + "Functions with exact one statement, the return statement," + + " can be rewritten with ExpressionBodySyntax.", + Debt.FIVE_MINS) - private val includeLineWrapping = valueOrDefault(INCLUDE_LINE_WRAPPING, false) + private val includeLineWrapping = valueOrDefault(INCLUDE_LINE_WRAPPING, false) - override fun visitNamedFunction(function: KtNamedFunction) { - if (function.bodyExpression != null) { - val body = function.bodyExpression!! - body.singleReturnStatement()?.run { - if (includeLineWrapping || !isLineWrapped(body)) { - report(CodeSmell(issue, Entity.from(body), issue.description)) - } - } - } - } + override fun visitNamedFunction(function: KtNamedFunction) { + if (function.bodyExpression != null) { + val body = function.bodyExpression!! + body.singleReturnStatement()?.run { + if (includeLineWrapping || !isLineWrapped(body)) { + report(CodeSmell(issue, Entity.from(body), issue.description)) + } + } + } + } - private fun KtExpression.singleReturnStatement(): KtReturnExpression? { - val statements = (this as? KtBlockExpression)?.statements - return statements - ?.takeIf { it.size == 1 } - ?.let { it[0] as? KtReturnExpression } - } + private fun KtExpression.singleReturnStatement(): KtReturnExpression? { + val statements = (this as? KtBlockExpression)?.statements + return statements + ?.takeIf { it.size == 1 } + ?.let { it[0] as? KtReturnExpression } + } - private fun isLineWrapped(expression: KtExpression): Boolean { - return expression.children.any { - it.text.contains('\n') - } - } + private fun isLineWrapped(expression: KtExpression): Boolean { + return expression.children.any { + it.text.contains('\n') + } + } - companion object { - const val INCLUDE_LINE_WRAPPING = "includeLineWrapping" - } + companion object { + const val INCLUDE_LINE_WRAPPING = "includeLineWrapping" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/FileParsingRule.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/FileParsingRule.kt index 457682153..1f1938578 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/FileParsingRule.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/FileParsingRule.kt @@ -6,17 +6,17 @@ import org.jetbrains.kotlin.psi.KtFile class FileParsingRule(val config: Config = Config.empty) : MultiRule() { - private val maxLineLength = MaxLineLength(config) - private val trailingWhitespace = TrailingWhitespace(config) - private val noTabs = NoTabs(config) - override val rules = listOf(maxLineLength, trailingWhitespace, noTabs) + private val maxLineLength = MaxLineLength(config) + private val trailingWhitespace = TrailingWhitespace(config) + private val noTabs = NoTabs(config) + override val rules = listOf(maxLineLength, trailingWhitespace, noTabs) - override fun visitKtFile(file: KtFile) { - val lines = file.text.splitToSequence("\n") - val fileContents = KtFileContent(file, lines) + override fun visitKtFile(file: KtFile) { + val lines = file.text.splitToSequence("\n") + val fileContents = KtFileContent(file, lines) - maxLineLength.runIfActive { visit(fileContents) } - trailingWhitespace.runIfActive { visit(fileContents) } - noTabs.runIfActive { findTabs(file) } - } + maxLineLength.runIfActive { visit(fileContents) } + trailingWhitespace.runIfActive { visit(fileContents) } + noTabs.runIfActive { findTabs(file) } + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenComment.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenComment.kt index b270512f2..8b2973986 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenComment.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenComment.kt @@ -26,30 +26,30 @@ import org.jetbrains.kotlin.com.intellij.psi.PsiComment */ class ForbiddenComment(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, - Severity.Style, - "Flags a forbidden comment. Defaults values are TODO:, FIXME: or STOPSHIP:", - Debt.TEN_MINS) + override val issue = Issue(javaClass.simpleName, + Severity.Style, + "Flags a forbidden comment. Defaults values are TODO:, FIXME: or STOPSHIP:", + Debt.TEN_MINS) - private val values: List = - valueOrDefault(VALUES, "TODO:,FIXME:,STOPSHIP:") - .split(",") - .filter { it.isNotBlank() } + private val values: List = + valueOrDefault(VALUES, "TODO:,FIXME:,STOPSHIP:") + .split(",") + .filter { it.isNotBlank() } - override fun visitComment(comment: PsiComment) { - super.visitComment(comment) + override fun visitComment(comment: PsiComment) { + super.visitComment(comment) - val text = comment.text + val text = comment.text - values.forEach { - if (text.contains(it, ignoreCase = true)) { - report(CodeSmell(issue, Entity.from(comment), "This comment contains text that has been " + - "defined as forbidden in detekt.")) - } - } - } + values.forEach { + if (text.contains(it, ignoreCase = true)) { + report(CodeSmell(issue, Entity.from(comment), "This comment contains text that has been " + + "defined as forbidden in detekt.")) + } + } + } - companion object { - const val VALUES = "values" - } + companion object { + const val VALUES = "values" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenImport.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenImport.kt index 21bee68aa..b91adb22a 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenImport.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenImport.kt @@ -28,23 +28,23 @@ import org.jetbrains.kotlin.psi.KtImportDirective */ class ForbiddenImport(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, Severity.Style, - "Mark forbidden imports. A forbidden import could be an import for an unstable / experimental api" + - "and hence you might want to mark it as forbidden in order to get warned about the usage.", Debt.TEN_MINS) + override val issue = Issue(javaClass.simpleName, Severity.Style, + "Mark forbidden imports. A forbidden import could be an import for an unstable / experimental api" + + "and hence you might want to mark it as forbidden in order to get warned about the usage.", Debt.TEN_MINS) - private val forbiddenImports = SplitPattern(valueOrDefault(IMPORTS, "")) + private val forbiddenImports = SplitPattern(valueOrDefault(IMPORTS, "")) - override fun visitImportDirective(importDirective: KtImportDirective) { - super.visitImportDirective(importDirective) + override fun visitImportDirective(importDirective: KtImportDirective) { + super.visitImportDirective(importDirective) - val import = importDirective.importedFqName?.asString() ?: "" - if (forbiddenImports.contains(import)) { - report(CodeSmell(issue, Entity.from(importDirective), "The import " + - "$import has been forbidden in the Detekt config.")) - } - } + val import = importDirective.importedFqName?.asString() ?: "" + if (forbiddenImports.contains(import)) { + report(CodeSmell(issue, Entity.from(importDirective), "The import " + + "$import has been forbidden in the Detekt config.")) + } + } - companion object { - const val IMPORTS = "imports" - } + companion object { + const val IMPORTS = "imports" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenVoid.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenVoid.kt index 55a8d02bd..c9c80abc8 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenVoid.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenVoid.kt @@ -30,20 +30,20 @@ import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType */ class ForbiddenVoid(config: Config = Config.empty) : Rule(config) { - override val issue = Issue( - javaClass.simpleName, - Severity.Style, - "`Unit` should be used instead of `Void`.", - Debt.FIVE_MINS) + override val issue = Issue( + javaClass.simpleName, + Severity.Style, + "`Unit` should be used instead of `Void`.", + Debt.FIVE_MINS) - override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) { - if (expression.getReferencedName() == Void::class.java.simpleName && !expression.isClassLiteral) { - report(CodeSmell(issue, Entity.from(expression), message = "'Void' should be replaced with 'Unit'.")) - } + override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) { + if (expression.getReferencedName() == Void::class.java.simpleName && !expression.isClassLiteral) { + report(CodeSmell(issue, Entity.from(expression), message = "'Void' should be replaced with 'Unit'.")) + } - super.visitSimpleNameExpression(expression) - } + super.visitSimpleNameExpression(expression) + } - private val KtSimpleNameExpression.isClassLiteral: Boolean - get() = getStrictParentOfType() != null + private val KtSimpleNameExpression.isClassLiteral: Boolean + get() = getStrictParentOfType() != null } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/FunctionOnlyReturningConstant.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/FunctionOnlyReturningConstant.kt index b4a0d33f3..8c3c629f4 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/FunctionOnlyReturningConstant.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/FunctionOnlyReturningConstant.kt @@ -36,58 +36,58 @@ import org.jetbrains.kotlin.psi.psiUtil.containingClass */ class FunctionOnlyReturningConstant(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, Severity.Style, - "A function that only returns a constant is misleading. " + - "Consider declaring a constant instead", - Debt.TEN_MINS) + override val issue = Issue(javaClass.simpleName, Severity.Style, + "A function that only returns a constant is misleading. " + + "Consider declaring a constant instead", + Debt.TEN_MINS) - private val ignoreOverridableFunction = valueOrDefault(IGNORE_OVERRIDABLE_FUNCTION, true) - private val excludedFunctions = SplitPattern(valueOrDefault(EXCLUDED_FUNCTIONS, "")) + private val ignoreOverridableFunction = valueOrDefault(IGNORE_OVERRIDABLE_FUNCTION, true) + private val excludedFunctions = SplitPattern(valueOrDefault(EXCLUDED_FUNCTIONS, "")) - override fun visitNamedFunction(function: KtNamedFunction) { - if (checkOverridableFunction(function) && isNotExcluded(function) && isReturningAConstant(function)) { - report(CodeSmell(issue, Entity.from(function), - "${function.nameAsSafeName} is returning a constant. Prefer declaring a constant instead.")) - } - super.visitNamedFunction(function) - } + override fun visitNamedFunction(function: KtNamedFunction) { + if (checkOverridableFunction(function) && isNotExcluded(function) && isReturningAConstant(function)) { + report(CodeSmell(issue, Entity.from(function), + "${function.nameAsSafeName} is returning a constant. Prefer declaring a constant instead.")) + } + super.visitNamedFunction(function) + } - private fun checkOverridableFunction(function: KtNamedFunction): Boolean { - return if (ignoreOverridableFunction) - !function.isOverride() && !function.isOpen() && !checkContainingInterface(function) - else true - } + private fun checkOverridableFunction(function: KtNamedFunction): Boolean { + return if (ignoreOverridableFunction) + !function.isOverride() && !function.isOpen() && !checkContainingInterface(function) + else true + } - private fun checkContainingInterface(function: KtNamedFunction): Boolean { - val containingClass = function.containingClass() - return containingClass != null && containingClass.isInterface() - } + private fun checkContainingInterface(function: KtNamedFunction): Boolean { + val containingClass = function.containingClass() + return containingClass != null && containingClass.isInterface() + } - private fun isNotExcluded(function: KtNamedFunction) = - !excludedFunctions.contains(function.name) + private fun isNotExcluded(function: KtNamedFunction) = + !excludedFunctions.contains(function.name) - private fun isReturningAConstant(function: KtNamedFunction) = - isConstantExpression(function.bodyExpression) || returnsConstant(function) + private fun isReturningAConstant(function: KtNamedFunction) = + isConstantExpression(function.bodyExpression) || returnsConstant(function) - private fun isConstantExpression(expression: KtExpression?): Boolean { - if (expression is KtConstantExpression) { - return true - } - val stringTemplate = expression as? KtStringTemplateExpression - return stringTemplate?.hasInterpolation() == false - } + private fun isConstantExpression(expression: KtExpression?): Boolean { + if (expression is KtConstantExpression) { + return true + } + val stringTemplate = expression as? KtStringTemplateExpression + return stringTemplate?.hasInterpolation() == false + } - private fun returnsConstant(function: KtNamedFunction): Boolean { - val children = function.bodyExpression?.children - if (children?.size == 1) { - val returnExpression = children[0] as? KtReturnExpression - return isConstantExpression(returnExpression?.returnedExpression) - } - return false - } + private fun returnsConstant(function: KtNamedFunction): Boolean { + val children = function.bodyExpression?.children + if (children?.size == 1) { + val returnExpression = children[0] as? KtReturnExpression + return isConstantExpression(returnExpression?.returnedExpression) + } + return false + } - companion object { - const val IGNORE_OVERRIDABLE_FUNCTION = "ignoreOverridableFunction" - const val EXCLUDED_FUNCTIONS = "excludedFunctions" - } + companion object { + const val IGNORE_OVERRIDABLE_FUNCTION = "ignoreOverridableFunction" + const val EXCLUDED_FUNCTIONS = "excludedFunctions" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/Junk.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/Junk.kt index c04f0dedf..bd747606d 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/Junk.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/Junk.kt @@ -7,7 +7,7 @@ import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.psiUtil.elementsInRange internal fun findAnnotatedStatementInLine(file: KtFile, offset: Int, line: String): PsiElement? { - return file.elementsInRange(TextRange.create(offset - line.length, offset)) - .mapNotNull { it as? KtAnnotated ?: if (it.parent is KtAnnotated) it.parent else null } - .firstOrNull() + return file.elementsInRange(TextRange.create(offset - line.length, offset)) + .mapNotNull { it as? KtAnnotated ?: if (it.parent is KtAnnotated) it.parent else null } + .firstOrNull() } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/LoopWithTooManyJumpStatements.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/LoopWithTooManyJumpStatements.kt index c3a0563e4..5dd5dc94d 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/LoopWithTooManyJumpStatements.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/LoopWithTooManyJumpStatements.kt @@ -36,38 +36,38 @@ import org.jetbrains.kotlin.psi.KtLoopExpression */ class LoopWithTooManyJumpStatements(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, Severity.Style, - "The loop contains more than one break or continue statement. " + - "The code should be refactored to increase readability.", Debt.TEN_MINS) + override val issue = Issue(javaClass.simpleName, Severity.Style, + "The loop contains more than one break or continue statement. " + + "The code should be refactored to increase readability.", Debt.TEN_MINS) - private val maxJumpCount = valueOrDefault(MAX_JUMP_COUNT, 1) + private val maxJumpCount = valueOrDefault(MAX_JUMP_COUNT, 1) - override fun visitLoopExpression(loopExpression: KtLoopExpression) { - if (countBreakAndReturnStatements(loopExpression.body) > maxJumpCount) { - report(CodeSmell(issue, Entity.from(loopExpression), issue.description)) - } - super.visitLoopExpression(loopExpression) - } + override fun visitLoopExpression(loopExpression: KtLoopExpression) { + if (countBreakAndReturnStatements(loopExpression.body) > maxJumpCount) { + report(CodeSmell(issue, Entity.from(loopExpression), issue.description)) + } + super.visitLoopExpression(loopExpression) + } - private fun countBreakAndReturnStatements(body: KtExpression?) = body?.countBreakAndReturnStatementsInLoop() ?: 0 + private fun countBreakAndReturnStatements(body: KtExpression?) = body?.countBreakAndReturnStatementsInLoop() ?: 0 - private fun KtElement.countBreakAndReturnStatementsInLoop(): Int { - var count = 0 - this.accept(object : DetektVisitor() { - override fun visitKtElement(element: KtElement) { - if (element is KtLoopExpression) { - return - } - if (element is KtBreakExpression || element is KtContinueExpression) { - count++ - } - element.children.forEach { it.accept(this) } - } - }) - return count - } + private fun KtElement.countBreakAndReturnStatementsInLoop(): Int { + var count = 0 + this.accept(object : DetektVisitor() { + override fun visitKtElement(element: KtElement) { + if (element is KtLoopExpression) { + return + } + if (element is KtBreakExpression || element is KtContinueExpression) { + count++ + } + element.children.forEach { it.accept(this) } + } + }) + return count + } - companion object { - const val MAX_JUMP_COUNT = "maxJumpCount" - } + companion object { + const val MAX_JUMP_COUNT = "maxJumpCount" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/MagicNumber.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/MagicNumber.kt index 7a24f42f6..a08cf6c47 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/MagicNumber.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/MagicNumber.kt @@ -10,6 +10,7 @@ import io.gitlab.arturbosch.detekt.api.Severity import io.gitlab.arturbosch.detekt.rules.isConstant import io.gitlab.arturbosch.detekt.rules.isHashCodeFunction import io.gitlab.arturbosch.detekt.rules.isPartOf +import java.util.Locale import org.jetbrains.kotlin.com.intellij.psi.PsiElement import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.KtAnnotationEntry @@ -27,7 +28,6 @@ import org.jetbrains.kotlin.psi.KtReturnExpression import org.jetbrains.kotlin.psi.KtSecondaryConstructor import org.jetbrains.kotlin.psi.KtValueArgument import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType -import java.util.Locale /** * This rule detects and reports usages of magic numbers in the code. Prefer defining constants with clear names @@ -82,129 +82,129 @@ import java.util.Locale */ class MagicNumber(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, Severity.Style, - "Report magic numbers. Magic number is a numeric literal that is not defined as a constant " + - "and hence it's unclear what the purpose of this number is. " + - "It's better to declare such numbers as constants and give them a proper name. " + - "By default, -1, 0, 1, and 2 are not considered to be magic numbers.", Debt.TEN_MINS) + override val issue = Issue(javaClass.simpleName, Severity.Style, + "Report magic numbers. Magic number is a numeric literal that is not defined as a constant " + + "and hence it's unclear what the purpose of this number is. " + + "It's better to declare such numbers as constants and give them a proper name. " + + "By default, -1, 0, 1, and 2 are not considered to be magic numbers.", Debt.TEN_MINS) - private val ignoredNumbers = valueOrDefault(IGNORE_NUMBERS, "-1,0,1,2") - .splitToSequence(",") - .filterNot { it.isEmpty() } - .map { parseAsDouble(it) } - .sorted() - .toList() + private val ignoredNumbers = valueOrDefault(IGNORE_NUMBERS, "-1,0,1,2") + .splitToSequence(",") + .filterNot { it.isEmpty() } + .map { parseAsDouble(it) } + .sorted() + .toList() - private val ignoreAnnotation = valueOrDefault(IGNORE_ANNOTATION, false) - private val ignoreHashCodeFunction = valueOrDefault(IGNORE_HASH_CODE, true) - private val ignorePropertyDeclaration = valueOrDefault(IGNORE_PROPERTY_DECLARATION, false) - private val ignoreNamedArgument = valueOrDefault(IGNORE_NAMED_ARGUMENT, false) - private val ignoreEnums = valueOrDefault(IGNORE_ENUMS, false) - private val ignoreConstantDeclaration = valueOrDefault(IGNORE_CONSTANT_DECLARATION, true) - private val ignoreCompanionObjectPropertyDeclaration = - valueOrDefault(IGNORE_COMPANION_OBJECT_PROPERTY_DECLARATION, true) + private val ignoreAnnotation = valueOrDefault(IGNORE_ANNOTATION, false) + private val ignoreHashCodeFunction = valueOrDefault(IGNORE_HASH_CODE, true) + private val ignorePropertyDeclaration = valueOrDefault(IGNORE_PROPERTY_DECLARATION, false) + private val ignoreNamedArgument = valueOrDefault(IGNORE_NAMED_ARGUMENT, false) + private val ignoreEnums = valueOrDefault(IGNORE_ENUMS, false) + private val ignoreConstantDeclaration = valueOrDefault(IGNORE_CONSTANT_DECLARATION, true) + private val ignoreCompanionObjectPropertyDeclaration = + valueOrDefault(IGNORE_COMPANION_OBJECT_PROPERTY_DECLARATION, true) - override fun visitConstantExpression(expression: KtConstantExpression) { - if (isIgnoredByConfig(expression) || expression.isPartOfFunctionReturnConstant() || - expression.isPartOfConstructorOrFunctionConstant()) { - return - } + override fun visitConstantExpression(expression: KtConstantExpression) { + if (isIgnoredByConfig(expression) || expression.isPartOfFunctionReturnConstant() || + expression.isPartOfConstructorOrFunctionConstant()) { + return + } - val parent = expression.parent - val rawNumber = if (parent.hasUnaryMinusPrefix()) { - parent.text - } else { - expression.text - } + val parent = expression.parent + val rawNumber = if (parent.hasUnaryMinusPrefix()) { + parent.text + } else { + expression.text + } - val number = parseAsDoubleOrNull(rawNumber) ?: return - if (!ignoredNumbers.contains(number)) { - report(CodeSmell(issue, Entity.from(expression), "This expression contains a magic number." + - " Consider defining it to a well named constant.")) - } - } + val number = parseAsDoubleOrNull(rawNumber) ?: return + if (!ignoredNumbers.contains(number)) { + report(CodeSmell(issue, Entity.from(expression), "This expression contains a magic number." + + " Consider defining it to a well named constant.")) + } + } - private fun isIgnoredByConfig(expression: KtConstantExpression) = when { - ignorePropertyDeclaration && expression.isProperty() -> true - ignoreConstantDeclaration && expression.isConstantProperty() -> true - ignoreCompanionObjectPropertyDeclaration && expression.isCompanionObjectProperty() -> true - ignoreAnnotation && expression.isPartOf(KtAnnotationEntry::class) -> true - ignoreHashCodeFunction && expression.isPartOfHashCode() -> true - ignoreEnums && expression.isPartOf(KtEnumEntry::class) -> true - ignoreNamedArgument && expression.isNamedArgument() -> true - else -> false - } + private fun isIgnoredByConfig(expression: KtConstantExpression) = when { + ignorePropertyDeclaration && expression.isProperty() -> true + ignoreConstantDeclaration && expression.isConstantProperty() -> true + ignoreCompanionObjectPropertyDeclaration && expression.isCompanionObjectProperty() -> true + ignoreAnnotation && expression.isPartOf(KtAnnotationEntry::class) -> true + ignoreHashCodeFunction && expression.isPartOfHashCode() -> true + ignoreEnums && expression.isPartOf(KtEnumEntry::class) -> true + ignoreNamedArgument && expression.isNamedArgument() -> true + else -> false + } - private fun parseAsDoubleOrNull(rawToken: String?): Double? = try { - rawToken?.let { parseAsDouble(it) } - } catch (e: NumberFormatException) { - null - } + private fun parseAsDoubleOrNull(rawToken: String?): Double? = try { + rawToken?.let { parseAsDouble(it) } + } catch (e: NumberFormatException) { + null + } - private fun parseAsDouble(rawNumber: String): Double { - val normalizedText = normalizeForParsingAsDouble(rawNumber) - return when { - normalizedText.startsWith("0x") || normalizedText.startsWith("0X") -> - normalizedText.substring(2).toLong(HEX_RADIX).toDouble() - normalizedText.startsWith("0b") || normalizedText.startsWith("0B") -> - normalizedText.substring(2).toLong(BINARY_RADIX).toDouble() - else -> normalizedText.toDouble() - } - } + private fun parseAsDouble(rawNumber: String): Double { + val normalizedText = normalizeForParsingAsDouble(rawNumber) + return when { + normalizedText.startsWith("0x") || normalizedText.startsWith("0X") -> + normalizedText.substring(2).toLong(HEX_RADIX).toDouble() + normalizedText.startsWith("0b") || normalizedText.startsWith("0B") -> + normalizedText.substring(2).toLong(BINARY_RADIX).toDouble() + else -> normalizedText.toDouble() + } + } - private fun normalizeForParsingAsDouble(text: String): String { - return text.trim() - .toLowerCase(Locale.US) - .replace("_", "") - .removeSuffix("l") - .removeSuffix("d") - .removeSuffix("f") - } + private fun normalizeForParsingAsDouble(text: String): String { + return text.trim() + .toLowerCase(Locale.US) + .replace("_", "") + .removeSuffix("l") + .removeSuffix("d") + .removeSuffix("f") + } - companion object { - const val IGNORE_NUMBERS = "ignoreNumbers" - const val IGNORE_HASH_CODE = "ignoreHashCodeFunction" - const val IGNORE_PROPERTY_DECLARATION = "ignorePropertyDeclaration" - const val IGNORE_CONSTANT_DECLARATION = "ignoreConstantDeclaration" - const val IGNORE_COMPANION_OBJECT_PROPERTY_DECLARATION = "ignoreCompanionObjectPropertyDeclaration" - const val IGNORE_ANNOTATION = "ignoreAnnotation" - const val IGNORE_NAMED_ARGUMENT = "ignoreNamedArgument" - const val IGNORE_ENUMS = "ignoreEnums" + companion object { + const val IGNORE_NUMBERS = "ignoreNumbers" + const val IGNORE_HASH_CODE = "ignoreHashCodeFunction" + const val IGNORE_PROPERTY_DECLARATION = "ignorePropertyDeclaration" + const val IGNORE_CONSTANT_DECLARATION = "ignoreConstantDeclaration" + const val IGNORE_COMPANION_OBJECT_PROPERTY_DECLARATION = "ignoreCompanionObjectPropertyDeclaration" + const val IGNORE_ANNOTATION = "ignoreAnnotation" + const val IGNORE_NAMED_ARGUMENT = "ignoreNamedArgument" + const val IGNORE_ENUMS = "ignoreEnums" - private const val HEX_RADIX = 16 - private const val BINARY_RADIX = 2 - } + private const val HEX_RADIX = 16 + private const val BINARY_RADIX = 2 + } } private fun KtConstantExpression.isNamedArgument() = - parent is KtValueArgument && (parent as? KtValueArgument)?.isNamed() == true && isPartOf(KtCallElement::class) + parent is KtValueArgument && (parent as? KtValueArgument)?.isNamed() == true && isPartOf(KtCallElement::class) private fun KtConstantExpression.isPartOfFunctionReturnConstant() = - parent is KtNamedFunction || parent is KtReturnExpression && parent.parent.children.size == 1 + parent is KtNamedFunction || parent is KtReturnExpression && parent.parent.children.size == 1 private fun KtConstantExpression.isPartOfConstructorOrFunctionConstant(): Boolean { - return parent is KtParameter && - when (parent.parent.parent) { - is KtNamedFunction, is KtPrimaryConstructor, is KtSecondaryConstructor -> true - else -> false - } + return parent is KtParameter && + when (parent.parent.parent) { + is KtNamedFunction, is KtPrimaryConstructor, is KtSecondaryConstructor -> true + else -> false + } } private fun KtConstantExpression.isPartOfHashCode(): Boolean { - val containingFunction = getNonStrictParentOfType() - return containingFunction?.isHashCodeFunction() == true + val containingFunction = getNonStrictParentOfType() + return containingFunction?.isHashCodeFunction() == true } private fun KtConstantExpression.isProperty() = - getNonStrictParentOfType()?.let { !it.isLocal } ?: false + getNonStrictParentOfType()?.let { !it.isLocal } ?: false private fun KtConstantExpression.isCompanionObjectProperty() = isProperty() && isInCompanionObject() private fun KtConstantExpression.isInCompanionObject() = - getNonStrictParentOfType()?.isCompanion() ?: false + getNonStrictParentOfType()?.isCompanion() ?: false private fun KtConstantExpression.isConstantProperty(): Boolean = - isProperty() && getNonStrictParentOfType()?.isConstant() ?: false + isProperty() && getNonStrictParentOfType()?.isConstant() ?: false private fun PsiElement.hasUnaryMinusPrefix(): Boolean = this is KtPrefixExpression && - (this.firstChild as? KtOperationReferenceExpression)?.operationSignTokenType == KtTokens.MINUS + (this.firstChild as? KtOperationReferenceExpression)?.operationSignTokenType == KtTokens.MINUS diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/MaxLineLength.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/MaxLineLength.kt index 9ed84be0a..bc060605a 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/MaxLineLength.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/MaxLineLength.kt @@ -30,76 +30,76 @@ data class KtFileContent(val file: KtFile, val content: Sequence) */ class MaxLineLength(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, - Severity.Style, - "Line detected that is longer than the defined maximum line length in the code style.", - Debt.FIVE_MINS) + override val issue = Issue(javaClass.simpleName, + Severity.Style, + "Line detected that is longer than the defined maximum line length in the code style.", + Debt.FIVE_MINS) - private val maxLineLength: Int = - valueOrDefault(MaxLineLength.MAX_LINE_LENGTH, MaxLineLength.DEFAULT_IDEA_LINE_LENGTH) - private val excludePackageStatements: Boolean = - valueOrDefault(MaxLineLength.EXCLUDE_PACKAGE_STATEMENTS, true) - private val excludeImportStatements: Boolean = - valueOrDefault(MaxLineLength.EXCLUDE_IMPORT_STATEMENTS, true) - private val excludeCommentStatements: Boolean = - valueOrDefault(MaxLineLength.EXCLUDE_COMMENT_STATEMENTS, false) + private val maxLineLength: Int = + valueOrDefault(MaxLineLength.MAX_LINE_LENGTH, MaxLineLength.DEFAULT_IDEA_LINE_LENGTH) + private val excludePackageStatements: Boolean = + valueOrDefault(MaxLineLength.EXCLUDE_PACKAGE_STATEMENTS, true) + private val excludeImportStatements: Boolean = + valueOrDefault(MaxLineLength.EXCLUDE_IMPORT_STATEMENTS, true) + private val excludeCommentStatements: Boolean = + valueOrDefault(MaxLineLength.EXCLUDE_COMMENT_STATEMENTS, false) - fun visit(element: KtFileContent) { - var offset = 0 - val lines = element.content - val file = element.file + fun visit(element: KtFileContent) { + var offset = 0 + val lines = element.content + val file = element.file - for (line in lines) { - offset += line.length - if (!isValidLine(line)) { - val ktElement = findAnnotatedStatementInLine(file, offset, line) - if (ktElement != null) { - report(CodeSmell(issue, Entity.from(ktElement), issue.description)) - } else { - report(CodeSmell(issue, Entity.from(file, offset), issue.description)) - } - } + for (line in lines) { + offset += line.length + if (!isValidLine(line)) { + val ktElement = findAnnotatedStatementInLine(file, offset, line) + if (ktElement != null) { + report(CodeSmell(issue, Entity.from(ktElement), issue.description)) + } else { + report(CodeSmell(issue, Entity.from(file, offset), issue.description)) + } + } - offset += 1 /* '\n' */ - } - } + offset += 1 /* '\n' */ + } + } - private fun isValidLine(line: String): Boolean { - val isUrl = line.lastArgumentMatchesUrl() - return line.length <= maxLineLength || isIgnoredStatement(line) || isUrl - } + private fun isValidLine(line: String): Boolean { + val isUrl = line.lastArgumentMatchesUrl() + return line.length <= maxLineLength || isIgnoredStatement(line) || isUrl + } - private fun isIgnoredStatement(line: String): Boolean { - return containsIgnoredPackageStatement(line) || - containsIgnoredImportStatement(line) || - containsIgnoredCommentStatement(line) - } + private fun isIgnoredStatement(line: String): Boolean { + return containsIgnoredPackageStatement(line) || + containsIgnoredImportStatement(line) || + containsIgnoredCommentStatement(line) + } - private fun containsIgnoredPackageStatement(line: String): Boolean { - if (!excludePackageStatements) return false + private fun containsIgnoredPackageStatement(line: String): Boolean { + if (!excludePackageStatements) return false - return line.trimStart().startsWith("package ") - } + return line.trimStart().startsWith("package ") + } - private fun containsIgnoredImportStatement(line: String): Boolean { - if (!excludeImportStatements) return false + private fun containsIgnoredImportStatement(line: String): Boolean { + if (!excludeImportStatements) return false - return line.trimStart().startsWith("import ") - } + return line.trimStart().startsWith("import ") + } - private fun containsIgnoredCommentStatement(line: String): Boolean { - if (!excludeCommentStatements) return false + private fun containsIgnoredCommentStatement(line: String): Boolean { + if (!excludeCommentStatements) return false - return line.trimStart().startsWith("//") || - line.trimStart().startsWith("/*") || - line.trimStart().startsWith("*") - } + return line.trimStart().startsWith("//") || + line.trimStart().startsWith("/*") || + line.trimStart().startsWith("*") + } - companion object { - const val MAX_LINE_LENGTH = "maxLineLength" - const val DEFAULT_IDEA_LINE_LENGTH = 120 - const val EXCLUDE_PACKAGE_STATEMENTS = "excludePackageStatements" - const val EXCLUDE_IMPORT_STATEMENTS = "excludeImportStatements" - const val EXCLUDE_COMMENT_STATEMENTS = "excludeCommentStatements" - } + companion object { + const val MAX_LINE_LENGTH = "maxLineLength" + const val DEFAULT_IDEA_LINE_LENGTH = 120 + const val EXCLUDE_PACKAGE_STATEMENTS = "excludePackageStatements" + const val EXCLUDE_IMPORT_STATEMENTS = "excludeImportStatements" + const val EXCLUDE_COMMENT_STATEMENTS = "excludeCommentStatements" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/MayBeConst.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/MayBeConst.kt index fee8cd73a..35043d702 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/MayBeConst.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/MayBeConst.kt @@ -39,88 +39,88 @@ import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject */ class MayBeConst(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, - Severity.Style, - "Reports vals that can be const val instead.", - Debt.FIVE_MINS) + override val issue = Issue(javaClass.simpleName, + Severity.Style, + "Reports vals that can be const val instead.", + Debt.FIVE_MINS) - private val binaryTokens = hashSetOf(KtTokens.PLUS, KtTokens.MINUS, KtTokens.MUL, - KtTokens.DIV, KtTokens.PERC) + private val binaryTokens = hashSetOf(KtTokens.PLUS, KtTokens.MINUS, KtTokens.MUL, + KtTokens.DIV, KtTokens.PERC) - private val topLevelConstants = HashSet() - private val companionObjectConstants = HashSet() + private val topLevelConstants = HashSet() + private val companionObjectConstants = HashSet() - override fun visitKtFile(file: KtFile) { - topLevelConstants.clear() - val topLevelProperties = file.declarations - .filterIsInstance() - .filter { it.isTopLevel && it.isConstant() } - .mapNotNull { it.name } - topLevelConstants.addAll(topLevelProperties) - super.visitKtFile(file) - } + override fun visitKtFile(file: KtFile) { + topLevelConstants.clear() + val topLevelProperties = file.declarations + .filterIsInstance() + .filter { it.isTopLevel && it.isConstant() } + .mapNotNull { it.name } + topLevelConstants.addAll(topLevelProperties) + super.visitKtFile(file) + } - override fun visitObjectDeclaration(declaration: KtObjectDeclaration) { - val constProperties = declaration.declarations - .filterIsInstance() - .filter { it.isConstant() } - .mapNotNull { it.name } - companionObjectConstants.addAll(constProperties) - super.visitObjectDeclaration(declaration) - companionObjectConstants.removeAll(constProperties) - } + override fun visitObjectDeclaration(declaration: KtObjectDeclaration) { + val constProperties = declaration.declarations + .filterIsInstance() + .filter { it.isConstant() } + .mapNotNull { it.name } + companionObjectConstants.addAll(constProperties) + super.visitObjectDeclaration(declaration) + companionObjectConstants.removeAll(constProperties) + } - override fun visitProperty(property: KtProperty) { - super.visitProperty(property) + override fun visitProperty(property: KtProperty) { + super.visitProperty(property) - if (property.canBeConst()) { - report(CodeSmell(issue, Entity.from(property), "${property.nameAsSafeName} can be a `const val`.")) - } - } + if (property.canBeConst()) { + report(CodeSmell(issue, Entity.from(property), "${property.nameAsSafeName} can be a `const val`.")) + } + } - private fun KtProperty.canBeConst(): Boolean { - if (cannotBeConstant() || isInObject() || isJvmField()) { - return false - } - return this.initializer?.isConstantExpression() == true - } + private fun KtProperty.canBeConst(): Boolean { + if (cannotBeConstant() || isInObject() || isJvmField()) { + return false + } + return this.initializer?.isConstantExpression() == true + } - private fun KtProperty.isJvmField(): Boolean { - val isJvmField = annotationEntries.any { it.text == "@JvmField" } - return annotationEntries.isNotEmpty() && !isJvmField - } + private fun KtProperty.isJvmField(): Boolean { + val isJvmField = annotationEntries.any { it.text == "@JvmField" } + return annotationEntries.isNotEmpty() && !isJvmField + } - private fun KtProperty.cannotBeConstant(): Boolean { - return isLocal || - isVar || - getter != null || - isConstant() || - isOverride() - } + private fun KtProperty.cannotBeConstant(): Boolean { + return isLocal || + isVar || + getter != null || + isConstant() || + isOverride() + } - private fun KtProperty.isInObject() = - !isTopLevel && containingClassOrObject !is KtObjectDeclaration + private fun KtProperty.isInObject() = + !isTopLevel && containingClassOrObject !is KtObjectDeclaration - private fun KtExpression.isConstantExpression(): Boolean { - return this is KtStringTemplateExpression && !hasInterpolation() || - node.elementType == KtNodeTypes.BOOLEAN_CONSTANT || - node.elementType == KtNodeTypes.INTEGER_CONSTANT || - node.elementType == KtNodeTypes.CHARACTER_CONSTANT || - node.elementType == KtNodeTypes.FLOAT_CONSTANT || - topLevelConstants.contains(text) || - companionObjectConstants.contains(text) || - isBinaryExpression(this) || - isParenthesizedExpression(this) - } + private fun KtExpression.isConstantExpression(): Boolean { + return this is KtStringTemplateExpression && !hasInterpolation() || + node.elementType == KtNodeTypes.BOOLEAN_CONSTANT || + node.elementType == KtNodeTypes.INTEGER_CONSTANT || + node.elementType == KtNodeTypes.CHARACTER_CONSTANT || + node.elementType == KtNodeTypes.FLOAT_CONSTANT || + topLevelConstants.contains(text) || + companionObjectConstants.contains(text) || + isBinaryExpression(this) || + isParenthesizedExpression(this) + } - private fun isParenthesizedExpression(expression: KtExpression) = - (expression as? KtParenthesizedExpression)?.expression?.isConstantExpression() == true + private fun isParenthesizedExpression(expression: KtExpression) = + (expression as? KtParenthesizedExpression)?.expression?.isConstantExpression() == true - private fun isBinaryExpression(expression: KtExpression): Boolean { - val binaryExpression = expression as? KtBinaryExpression ?: return false - return expression.node.elementType == KtNodeTypes.BINARY_EXPRESSION && - binaryTokens.contains(binaryExpression.operationToken) && - binaryExpression.left?.isConstantExpression() == true && - binaryExpression.right?.isConstantExpression() == true - } + private fun isBinaryExpression(expression: KtExpression): Boolean { + val binaryExpression = expression as? KtBinaryExpression ?: return false + return expression.node.elementType == KtNodeTypes.BINARY_EXPRESSION && + binaryTokens.contains(binaryExpression.operationToken) && + binaryExpression.left?.isConstantExpression() == true && + binaryExpression.right?.isConstantExpression() == true + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ModifierOrder.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ModifierOrder.kt index 269f5d94b..2a305faf0 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ModifierOrder.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ModifierOrder.kt @@ -7,6 +7,7 @@ import io.gitlab.arturbosch.detekt.api.Entity import io.gitlab.arturbosch.detekt.api.Issue import io.gitlab.arturbosch.detekt.api.Rule import io.gitlab.arturbosch.detekt.api.Severity +import java.util.Arrays import org.jetbrains.kotlin.com.intellij.psi.PsiWhiteSpace import org.jetbrains.kotlin.lexer.KtTokens.ABSTRACT_KEYWORD import org.jetbrains.kotlin.lexer.KtTokens.ACTUAL_KEYWORD @@ -35,7 +36,6 @@ import org.jetbrains.kotlin.lexer.KtTokens.TAILREC_KEYWORD import org.jetbrains.kotlin.lexer.KtTokens.VARARG_KEYWORD import org.jetbrains.kotlin.psi.KtModifierList import org.jetbrains.kotlin.psi.psiUtil.allChildren -import java.util.Arrays /** * This rule reports cases in the code where modifiers are not in the correct order. The default modifier order is @@ -54,48 +54,48 @@ import java.util.Arrays */ class ModifierOrder(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, - Severity.Style, - "Modifiers are not in the correct order.", - Debt.FIVE_MINS) + override val issue = Issue(javaClass.simpleName, + Severity.Style, + "Modifiers are not in the correct order.", + Debt.FIVE_MINS) - // subset of KtTokens.MODIFIER_KEYWORDS_ARRAY - private val order = arrayOf( - PUBLIC_KEYWORD, PROTECTED_KEYWORD, PRIVATE_KEYWORD, INTERNAL_KEYWORD, - EXPECT_KEYWORD, ACTUAL_KEYWORD, - FINAL_KEYWORD, OPEN_KEYWORD, ABSTRACT_KEYWORD, SEALED_KEYWORD, CONST_KEYWORD, - EXTERNAL_KEYWORD, - OVERRIDE_KEYWORD, - LATEINIT_KEYWORD, - TAILREC_KEYWORD, - VARARG_KEYWORD, - SUSPEND_KEYWORD, - INNER_KEYWORD, - ENUM_KEYWORD, ANNOTATION_KEYWORD, - COMPANION_KEYWORD, - INLINE_KEYWORD, - INFIX_KEYWORD, - OPERATOR_KEYWORD, - DATA_KEYWORD - ) + // subset of KtTokens.MODIFIER_KEYWORDS_ARRAY + private val order = arrayOf( + PUBLIC_KEYWORD, PROTECTED_KEYWORD, PRIVATE_KEYWORD, INTERNAL_KEYWORD, + EXPECT_KEYWORD, ACTUAL_KEYWORD, + FINAL_KEYWORD, OPEN_KEYWORD, ABSTRACT_KEYWORD, SEALED_KEYWORD, CONST_KEYWORD, + EXTERNAL_KEYWORD, + OVERRIDE_KEYWORD, + LATEINIT_KEYWORD, + TAILREC_KEYWORD, + VARARG_KEYWORD, + SUSPEND_KEYWORD, + INNER_KEYWORD, + ENUM_KEYWORD, ANNOTATION_KEYWORD, + COMPANION_KEYWORD, + INLINE_KEYWORD, + INFIX_KEYWORD, + OPERATOR_KEYWORD, + DATA_KEYWORD + ) - override fun visitModifierList(list: KtModifierList) { - super.visitModifierList(list) + override fun visitModifierList(list: KtModifierList) { + super.visitModifierList(list) - val modifiers = list.allChildren - .toList() - .filter { it !is PsiWhiteSpace } - .toTypedArray() + val modifiers = list.allChildren + .toList() + .filter { it !is PsiWhiteSpace } + .toTypedArray() - val sortedModifiers = modifiers.copyOf() - .apply { sortWith(compareBy { order.indexOf(it.node.elementType) }) } + val sortedModifiers = modifiers.copyOf() + .apply { sortWith(compareBy { order.indexOf(it.node.elementType) }) } - if (!Arrays.equals(modifiers, sortedModifiers)) { - val modifierString = sortedModifiers.joinToString(" ") { it.text } + if (!Arrays.equals(modifiers, sortedModifiers)) { + val modifierString = sortedModifiers.joinToString(" ") { it.text } - report(CodeSmell(Issue(javaClass.simpleName, Severity.Style, - "Modifier order should be: $modifierString", Debt(mins = 1)), Entity.from(list), - "Modifier order should be: $modifierString")) - } - } + report(CodeSmell(Issue(javaClass.simpleName, Severity.Style, + "Modifier order should be: $modifierString", Debt(mins = 1)), Entity.from(list), + "Modifier order should be: $modifierString")) + } + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/NestedClassesVisibility.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/NestedClassesVisibility.kt index f29b9ab42..3eeacfb58 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/NestedClassesVisibility.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/NestedClassesVisibility.kt @@ -39,29 +39,29 @@ import org.jetbrains.kotlin.psi.psiUtil.isPublic */ class NestedClassesVisibility(config: Config = Config.empty) : Rule(config) { - override val issue: Issue = Issue("NestedClassesVisibility", Severity.Style, - "Nested types are often used for implementing private functionality " + - "and therefore this should not be public.", - Debt.FIVE_MINS) + override val issue: Issue = Issue("NestedClassesVisibility", Severity.Style, + "Nested types are often used for implementing private functionality " + + "and therefore this should not be public.", + Debt.FIVE_MINS) - override fun visitClass(klass: KtClass) { - if (!klass.isInterface() && klass.isTopLevel() && klass.isInternal()) { - checkDeclarations(klass) - } - } + override fun visitClass(klass: KtClass) { + if (!klass.isInterface() && klass.isTopLevel() && klass.isInternal()) { + checkDeclarations(klass) + } + } - private fun checkDeclarations(klass: KtClass) { - klass.declarations - .filterIsInstance() - .filter { it.isPublic && it.isNoEnum() && it.isNoCompanionObj() } - .forEach { - report(CodeSmell(issue, Entity.from(it), - "Nested types are often used for implementing private functionality. " + - "However the visibility of ${klass.name} makes it visible externally.")) - } - } + private fun checkDeclarations(klass: KtClass) { + klass.declarations + .filterIsInstance() + .filter { it.isPublic && it.isNoEnum() && it.isNoCompanionObj() } + .forEach { + report(CodeSmell(issue, Entity.from(it), + "Nested types are often used for implementing private functionality. " + + "However the visibility of ${klass.name} makes it visible externally.")) + } + } - private fun KtClassOrObject.isNoEnum() = !this.hasModifier(KtTokens.ENUM_KEYWORD) && this !is KtEnumEntry + private fun KtClassOrObject.isNoEnum() = !this.hasModifier(KtTokens.ENUM_KEYWORD) && this !is KtEnumEntry - private fun KtClassOrObject.isNoCompanionObj() = !this.hasModifier(KtTokens.COMPANION_KEYWORD) + private fun KtClassOrObject.isNoCompanionObj() = !this.hasModifier(KtTokens.COMPANION_KEYWORD) } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/NewLineAtEndOfFile.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/NewLineAtEndOfFile.kt index 36bce3ef0..78e372e3e 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/NewLineAtEndOfFile.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/NewLineAtEndOfFile.kt @@ -17,16 +17,16 @@ import org.jetbrains.kotlin.psi.KtFile */ class NewLineAtEndOfFile(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, - Severity.Style, - "Checks whether files end with a line separator.", - Debt.FIVE_MINS) + override val issue = Issue(javaClass.simpleName, + Severity.Style, + "Checks whether files end with a line separator.", + Debt.FIVE_MINS) - override fun visitKtFile(file: KtFile) { - val text = file.text - if (text.isNotEmpty() && text.last() != '\n') { - report(CodeSmell(issue, Entity.from(file, text.length - 1), - "The file ${file.name} is not ending with a new line.")) - } - } + override fun visitKtFile(file: KtFile) { + val text = file.text + if (text.isNotEmpty() && text.last() != '\n') { + report(CodeSmell(issue, Entity.from(file, text.length - 1), + "The file ${file.name} is not ending with a new line.")) + } + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/NoTabs.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/NoTabs.kt index e28e69a9e..891bbff64 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/NoTabs.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/NoTabs.kt @@ -26,34 +26,34 @@ import org.jetbrains.kotlin.psi.KtStringTemplateEntryWithExpression */ class NoTabs(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, - Severity.Style, - "Checks if tabs are used in Kotlin files.", - Debt.FIVE_MINS) + override val issue = Issue(javaClass.simpleName, + Severity.Style, + "Checks if tabs are used in Kotlin files.", + Debt.FIVE_MINS) - fun findTabs(file: KtFile) { - file.collectWhitespaces() - .filter { it.isTab() } - .forEach { report(CodeSmell(issue, Entity.from(it), "Tab character is in use.")) } - } + fun findTabs(file: KtFile) { + file.collectWhitespaces() + .filter { it.isTab() } + .forEach { report(CodeSmell(issue, Entity.from(it), "Tab character is in use.")) } + } - private fun KtFile.collectWhitespaces(): List { - val list = mutableListOf() - this.accept(object : DetektVisitor() { - override fun visitWhiteSpace(space: PsiWhiteSpace?) { - if (space != null) { - list.add(space) - } - super.visitWhiteSpace(space) - } - }) - return list - } + private fun KtFile.collectWhitespaces(): List { + val list = mutableListOf() + this.accept(object : DetektVisitor() { + override fun visitWhiteSpace(space: PsiWhiteSpace?) { + if (space != null) { + list.add(space) + } + super.visitWhiteSpace(space) + } + }) + return list + } - private fun PsiWhiteSpace.isTab(): Boolean { - return (!isPartOfString() || isStringInterpolated()) && text.contains('\t') - } + private fun PsiWhiteSpace.isTab(): Boolean { + return (!isPartOfString() || isStringInterpolated()) && text.contains('\t') + } - private fun PsiWhiteSpace.isStringInterpolated(): Boolean = - this.isPartOf(KtStringTemplateEntryWithExpression::class) + private fun PsiWhiteSpace.isStringInterpolated(): Boolean = + this.isPartOf(KtStringTemplateEntryWithExpression::class) } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/OptionalAbstractKeyword.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/OptionalAbstractKeyword.kt index 5ee3cf3c6..d9ecb748c 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/OptionalAbstractKeyword.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/OptionalAbstractKeyword.kt @@ -37,24 +37,24 @@ import org.jetbrains.kotlin.psi.KtNamedFunction */ class OptionalAbstractKeyword(config: Config = Config.empty) : Rule(config) { - override val issue: Issue = Issue(javaClass.simpleName, Severity.Style, - "Unnecessary abstract modifier in interface", Debt.FIVE_MINS) + override val issue: Issue = Issue(javaClass.simpleName, Severity.Style, + "Unnecessary abstract modifier in interface", Debt.FIVE_MINS) - override fun visitClass(klass: KtClass) { - if (klass.isInterface()) { - handleAbstractKeyword(klass) - val body = klass.body - if (body != null) { - body.properties.forEach { handleAbstractKeyword(it) } - body.children.filterIsInstance().forEach { handleAbstractKeyword(it) } - } - } - super.visitClass(klass) - } + override fun visitClass(klass: KtClass) { + if (klass.isInterface()) { + handleAbstractKeyword(klass) + val body = klass.body + if (body != null) { + body.properties.forEach { handleAbstractKeyword(it) } + body.children.filterIsInstance().forEach { handleAbstractKeyword(it) } + } + } + super.visitClass(klass) + } - internal fun handleAbstractKeyword(dcl: KtDeclaration) { - if (dcl.isAbstract()) { - report(CodeSmell(issue, Entity.from(dcl), "The abstract keyword on this declaration is unnecessary.")) - } - } + internal fun handleAbstractKeyword(dcl: KtDeclaration) { + if (dcl.isAbstract()) { + report(CodeSmell(issue, Entity.from(dcl), "The abstract keyword on this declaration is unnecessary.")) + } + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/OptionalWhenBraces.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/OptionalWhenBraces.kt index 14c330efc..f1a147c3e 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/OptionalWhenBraces.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/OptionalWhenBraces.kt @@ -35,23 +35,23 @@ import org.jetbrains.kotlin.psi.KtWhenExpression */ class OptionalWhenBraces(config: Config = Config.empty) : Rule(config) { - override val issue: Issue = Issue(javaClass.simpleName, - Severity.Style, - "Optional braces in when expression", - Debt.FIVE_MINS) + override val issue: Issue = Issue(javaClass.simpleName, + Severity.Style, + "Optional braces in when expression", + Debt.FIVE_MINS) - override fun visitWhenExpression(expression: KtWhenExpression) { - for (entry in expression.entries) { - val blockExpression = entry.expression as? KtBlockExpression - if (hasOneStatement(blockExpression) && hasOptionalBrace(blockExpression)) { - report(CodeSmell(issue, Entity.from(entry), issue.description)) - } - } - } + override fun visitWhenExpression(expression: KtWhenExpression) { + for (entry in expression.entries) { + val blockExpression = entry.expression as? KtBlockExpression + if (hasOneStatement(blockExpression) && hasOptionalBrace(blockExpression)) { + report(CodeSmell(issue, Entity.from(entry), issue.description)) + } + } + } - private fun hasOneStatement(blockExpression: KtBlockExpression?) = - blockExpression?.statements?.size == 1 && !blockExpression.hasCommentInside() + private fun hasOneStatement(blockExpression: KtBlockExpression?) = + blockExpression?.statements?.size == 1 && !blockExpression.hasCommentInside() - private fun hasOptionalBrace(blockExpression: KtBlockExpression?) = - blockExpression != null && blockExpression.lBrace != null && blockExpression.rBrace != null + private fun hasOptionalBrace(blockExpression: KtBlockExpression?) = + blockExpression != null && blockExpression.lBrace != null && blockExpression.rBrace != null } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ProtectedMemberInFinalClass.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ProtectedMemberInFinalClass.kt index 6c167b39d..f22e3ec25 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ProtectedMemberInFinalClass.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ProtectedMemberInFinalClass.kt @@ -36,37 +36,37 @@ import org.jetbrains.kotlin.psi.psiUtil.isProtected */ class ProtectedMemberInFinalClass(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, Severity.Warning, - "Member with protected visibility in final class is private. Consider using private or internal as modifier.", - Debt.FIVE_MINS) + override val issue = Issue(javaClass.simpleName, Severity.Warning, + "Member with protected visibility in final class is private. Consider using private or internal as modifier.", + Debt.FIVE_MINS) - private val visitor = DeclarationVisitor() + private val visitor = DeclarationVisitor() - /** - * Only classes and companion objects can contain protected members. - */ - override fun visitClass(klass: KtClass) { - if (hasModifiers(klass)) { - klass.primaryConstructor?.accept(visitor) - klass.body?.declarations?.forEach { it.accept(visitor) } - klass.companionObjects.forEach { it.accept(visitor) } - } - super.visitClass(klass) - } + /** + * Only classes and companion objects can contain protected members. + */ + override fun visitClass(klass: KtClass) { + if (hasModifiers(klass)) { + klass.primaryConstructor?.accept(visitor) + klass.body?.declarations?.forEach { it.accept(visitor) } + klass.companionObjects.forEach { it.accept(visitor) } + } + super.visitClass(klass) + } - private fun hasModifiers(klass: KtClass): Boolean { - val isNotAbstract = !klass.isAbstract() - val isFinal = !klass.isOpen() - val isNotSealed = !klass.isSealed() - return isNotAbstract && isFinal && isNotSealed - } + private fun hasModifiers(klass: KtClass): Boolean { + val isNotAbstract = !klass.isAbstract() + val isFinal = !klass.isOpen() + val isNotSealed = !klass.isSealed() + return isNotAbstract && isFinal && isNotSealed + } - internal inner class DeclarationVisitor : DetektVisitor() { + internal inner class DeclarationVisitor : DetektVisitor() { - override fun visitDeclaration(dcl: KtDeclaration) { - if (dcl.isProtected() && !dcl.isOverride()) { - report(CodeSmell(issue, Entity.from(dcl), issue.description)) - } - } - } + override fun visitDeclaration(dcl: KtDeclaration) { + if (dcl.isProtected() && !dcl.isOverride()) { + report(CodeSmell(issue, Entity.from(dcl), issue.description)) + } + } + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/RedundantVisibilityModifierRule.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/RedundantVisibilityModifierRule.kt index af6ecc85e..d25857500 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/RedundantVisibilityModifierRule.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/RedundantVisibilityModifierRule.kt @@ -38,62 +38,62 @@ import org.jetbrains.kotlin.psi.KtProperty * @author Marvin Ramin */ class RedundantVisibilityModifierRule(config: Config = Config.empty) : Rule(config) { - override val issue: Issue = Issue("RedundantVisibilityModifierRule", - Severity.Style, - "Checks for redundant visibility modifiers. " + - "Public is the default visibility for classes. " + - "The public modifier is redundant.", - Debt.FIVE_MINS) + override val issue: Issue = Issue("RedundantVisibilityModifierRule", + Severity.Style, + "Checks for redundant visibility modifiers. " + + "Public is the default visibility for classes. " + + "The public modifier is redundant.", + Debt.FIVE_MINS) - private val classVisitor = ClassVisitor() - private val childrenVisitor = ChildrenVisitor() + private val classVisitor = ClassVisitor() + private val childrenVisitor = ChildrenVisitor() - private fun KtModifierListOwner.isExplicitlyPublicNotOverridden() = isExplicitlyPublic() && !isOverride() + private fun KtModifierListOwner.isExplicitlyPublicNotOverridden() = isExplicitlyPublic() && !isOverride() - private fun KtModifierListOwner.isExplicitlyPublic() = this.hasModifier(KtTokens.PUBLIC_KEYWORD) + private fun KtModifierListOwner.isExplicitlyPublic() = this.hasModifier(KtTokens.PUBLIC_KEYWORD) - override fun visitKtFile(file: KtFile) { - super.visitKtFile(file) - file.declarations.forEach { - it.accept(classVisitor) - it.acceptChildren(childrenVisitor) - } - } + override fun visitKtFile(file: KtFile) { + super.visitKtFile(file) + file.declarations.forEach { + it.accept(classVisitor) + it.acceptChildren(childrenVisitor) + } + } - private inner class ClassVisitor : DetektVisitor() { - override fun visitClass(klass: KtClass) { - super.visitClass(klass) - if (klass.isExplicitlyPublic()) { - report(CodeSmell(issue, - Entity.from(klass), - message = "${klass.name} is explicitly marked as public. " + - "Public is the default visibility for classes. The public modifier is redundant.") - ) - } - } - } + private inner class ClassVisitor : DetektVisitor() { + override fun visitClass(klass: KtClass) { + super.visitClass(klass) + if (klass.isExplicitlyPublic()) { + report(CodeSmell(issue, + Entity.from(klass), + message = "${klass.name} is explicitly marked as public. " + + "Public is the default visibility for classes. The public modifier is redundant.") + ) + } + } + } - private inner class ChildrenVisitor : DetektVisitor() { - override fun visitNamedFunction(function: KtNamedFunction) { - super.visitNamedFunction(function) - if (function.isExplicitlyPublicNotOverridden()) { - report(CodeSmell(issue, - Entity.from(function), - message = "${function.name} is explicitly marked as public. " + - "Functions are public by default so this modifier is redundant.") - ) - } - } + private inner class ChildrenVisitor : DetektVisitor() { + override fun visitNamedFunction(function: KtNamedFunction) { + super.visitNamedFunction(function) + if (function.isExplicitlyPublicNotOverridden()) { + report(CodeSmell(issue, + Entity.from(function), + message = "${function.name} is explicitly marked as public. " + + "Functions are public by default so this modifier is redundant.") + ) + } + } - override fun visitProperty(property: KtProperty) { - super.visitProperty(property) - if (property.isExplicitlyPublicNotOverridden()) { - report(CodeSmell(issue, - Entity.from(property), - message = "${property.name} is explicitly marked as public. " + - "Properties are public by default so this modifier is redundant.") - ) - } - } - } + override fun visitProperty(property: KtProperty) { + super.visitProperty(property) + if (property.isExplicitlyPublicNotOverridden()) { + report(CodeSmell(issue, + Entity.from(property), + message = "${property.name} is explicitly marked as public. " + + "Properties are public by default so this modifier is redundant.") + ) + } + } + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ReturnCount.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ReturnCount.kt index 75a84562e..029963140 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ReturnCount.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ReturnCount.kt @@ -61,66 +61,66 @@ import org.jetbrains.kotlin.psi.KtReturnExpression */ class ReturnCount(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, Severity.Style, - "Restrict the number of return statements in methods.", Debt.TEN_MINS) + override val issue = Issue(javaClass.simpleName, Severity.Style, + "Restrict the number of return statements in methods.", Debt.TEN_MINS) - private val max = valueOrDefault(MAX, 2) - private val excludedFunctions = SplitPattern(valueOrDefault(EXCLUDED_FUNCTIONS, "")) - private val excludeLabeled = valueOrDefault(EXCLUDE_LABELED, false) - private val excludeLambdas = valueOrDefault(EXCLUDE_RETURN_FROM_LAMBDA, true) + private val max = valueOrDefault(MAX, 2) + private val excludedFunctions = SplitPattern(valueOrDefault(EXCLUDED_FUNCTIONS, "")) + private val excludeLabeled = valueOrDefault(EXCLUDE_LABELED, false) + private val excludeLambdas = valueOrDefault(EXCLUDE_RETURN_FROM_LAMBDA, true) - override fun visitNamedFunction(function: KtNamedFunction) { - super.visitNamedFunction(function) + override fun visitNamedFunction(function: KtNamedFunction) { + super.visitNamedFunction(function) - if (!isIgnoredFunction(function)) { - val numberOfReturns = countFunctionReturns(function) + if (!isIgnoredFunction(function)) { + val numberOfReturns = countFunctionReturns(function) - if (numberOfReturns > max) { - report(CodeSmell(issue, Entity.from(function), "Function ${function.name} has " + - "$numberOfReturns return statements which exceeds the limit of $max.")) - } - } - } + if (numberOfReturns > max) { + report(CodeSmell(issue, Entity.from(function), "Function ${function.name} has " + + "$numberOfReturns return statements which exceeds the limit of $max.")) + } + } + } - private fun isIgnoredFunction(function: KtNamedFunction) = excludedFunctions.contains(function.name) + private fun isIgnoredFunction(function: KtNamedFunction) = excludedFunctions.contains(function.name) - private fun countFunctionReturns(function: KtNamedFunction): Int { - var returnsNumber = 0 - function.accept(object : DetektVisitor() { - override fun visitKtElement(element: KtElement) { - if (element is KtReturnExpression) { - if (excludeLabeled && element.labeledExpression != null) { - return - } else if (excludeLambdas && isNamedReturnFromLambda(element)) { - return - } else { - returnsNumber++ - } - } - element.children - .filter { it !is KtNamedFunction } - .forEach { it.accept(this) } - } - }) - return returnsNumber - } + private fun countFunctionReturns(function: KtNamedFunction): Int { + var returnsNumber = 0 + function.accept(object : DetektVisitor() { + override fun visitKtElement(element: KtElement) { + if (element is KtReturnExpression) { + if (excludeLabeled && element.labeledExpression != null) { + return + } else if (excludeLambdas && isNamedReturnFromLambda(element)) { + return + } else { + returnsNumber++ + } + } + element.children + .filter { it !is KtNamedFunction } + .forEach { it.accept(this) } + } + }) + return returnsNumber + } - private fun isNamedReturnFromLambda(expression: KtReturnExpression): Boolean { - val label = expression.labeledExpression - if (label != null) { - return expression.parentsOfTypeUntil() - .map { it.calleeExpression } - .mapNotNull { it as? KtNameReferenceExpression } - .map { it.text } - .any { it in label.text } - } - return false - } + private fun isNamedReturnFromLambda(expression: KtReturnExpression): Boolean { + val label = expression.labeledExpression + if (label != null) { + return expression.parentsOfTypeUntil() + .map { it.calleeExpression } + .mapNotNull { it as? KtNameReferenceExpression } + .map { it.text } + .any { it in label.text } + } + return false + } - companion object { - const val MAX = "max" - const val EXCLUDED_FUNCTIONS = "excludedFunctions" - const val EXCLUDE_LABELED = "excludeLabeled" - const val EXCLUDE_RETURN_FROM_LAMBDA = "excludeReturnFromLambda" - } + companion object { + const val MAX = "max" + const val EXCLUDED_FUNCTIONS = "excludedFunctions" + const val EXCLUDE_LABELED = "excludeLabeled" + const val EXCLUDE_RETURN_FROM_LAMBDA = "excludeReturnFromLambda" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/SafeCast.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/SafeCast.kt index e1b87a99c..f143eb0f8 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/SafeCast.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/SafeCast.kt @@ -38,36 +38,41 @@ import org.jetbrains.kotlin.psi.KtNameReferenceExpression */ class SafeCast(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, Severity.Style, "Safe cast instead of if-else-null", Debt.FIVE_MINS) - private var identifier = "" + override val issue = Issue( + javaClass.simpleName, + Severity.Style, + "Safe cast instead of if-else-null", + Debt.FIVE_MINS + ) + private var identifier = "" - override fun visitIfExpression(expression: KtIfExpression) { - val condition = expression.condition as? KtIsExpression - if (condition != null) { - val leftHandSide = condition.leftHandSide as? KtNameReferenceExpression - if (leftHandSide != null) { - identifier = leftHandSide.text - val thenClause = expression.then - val elseClause = expression.`else` - val result = when (condition.isNegated) { - true -> isIfElseNull(elseClause, thenClause) - false -> isIfElseNull(thenClause, elseClause) - } - if (result) { - addReport(expression) - } - } - } - } + override fun visitIfExpression(expression: KtIfExpression) { + val condition = expression.condition as? KtIsExpression + if (condition != null) { + val leftHandSide = condition.leftHandSide as? KtNameReferenceExpression + if (leftHandSide != null) { + identifier = leftHandSide.text + val thenClause = expression.then + val elseClause = expression.`else` + val result = when (condition.isNegated) { + true -> isIfElseNull(elseClause, thenClause) + false -> isIfElseNull(thenClause, elseClause) + } + if (result) { + addReport(expression) + } + } + } + } - private fun isIfElseNull(thenClause: KtExpression?, elseClause: KtExpression?): Boolean { - val hasIdentifier = thenClause?.asBlockExpression()?.statements?.firstOrNull()?.text == identifier - val elseStatement = elseClause?.asBlockExpression()?.statements?.firstOrNull() - val hasNull = elseStatement is KtConstantExpression && elseStatement.node.elementType == KtNodeTypes.NULL - return hasIdentifier && hasNull - } + private fun isIfElseNull(thenClause: KtExpression?, elseClause: KtExpression?): Boolean { + val hasIdentifier = thenClause?.asBlockExpression()?.statements?.firstOrNull()?.text == identifier + val elseStatement = elseClause?.asBlockExpression()?.statements?.firstOrNull() + val hasNull = elseStatement is KtConstantExpression && elseStatement.node.elementType == KtNodeTypes.NULL + return hasIdentifier && hasNull + } - private fun addReport(expression: KtIfExpression) { - report(CodeSmell(issue, Entity.from(expression), "This cast should be replaced with a safe cast: as?")) - } + private fun addReport(expression: KtIfExpression) { + report(CodeSmell(issue, Entity.from(expression), "This cast should be replaced with a safe cast: as?")) + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/SerialVersionUIDInSerializableClass.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/SerialVersionUIDInSerializableClass.kt index 345141296..dc3ddde87 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/SerialVersionUIDInSerializableClass.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/SerialVersionUIDInSerializableClass.kt @@ -44,50 +44,50 @@ import org.jetbrains.kotlin.psi.KtProperty */ class SerialVersionUIDInSerializableClass(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, Severity.Warning, - "A class which implements the Serializable interface does not define a correct serialVersionUID field. " + - "The serialVersionUID field should be a constant long value inside a companion object.", - Debt.FIVE_MINS) + override val issue = Issue(javaClass.simpleName, Severity.Warning, + "A class which implements the Serializable interface does not define a correct serialVersionUID field. " + + "The serialVersionUID field should be a constant long value inside a companion object.", + Debt.FIVE_MINS) - private val versionUID = "serialVersionUID" + private val versionUID = "serialVersionUID" - override fun visitClass(klass: KtClass) { - if (!klass.isInterface() && isImplementingSerializable(klass)) { - val companionObject = klass.companionObject() - if (companionObject == null || !hasCorrectSerialVersionUUID(companionObject)) { - report(CodeSmell(issue, Entity.from(klass), "The class ${klass.nameAsSafeName} implements" + - " the Serializable interface and should thus define a serialVersionUID.")) - } - } - super.visitClass(klass) - } + override fun visitClass(klass: KtClass) { + if (!klass.isInterface() && isImplementingSerializable(klass)) { + val companionObject = klass.companionObject() + if (companionObject == null || !hasCorrectSerialVersionUUID(companionObject)) { + report(CodeSmell(issue, Entity.from(klass), "The class ${klass.nameAsSafeName} implements" + + " the Serializable interface and should thus define a serialVersionUID.")) + } + } + super.visitClass(klass) + } - override fun visitObjectDeclaration(declaration: KtObjectDeclaration) { - if (!declaration.isCompanion() && - isImplementingSerializable(declaration) && - !hasCorrectSerialVersionUUID(declaration)) { - report(CodeSmell(issue, Entity.from(declaration), "The object ${declaration.nameAsSafeName} " + - "implements the Serializable interface and should thus define a serialVersionUID.")) - } - super.visitObjectDeclaration(declaration) - } + override fun visitObjectDeclaration(declaration: KtObjectDeclaration) { + if (!declaration.isCompanion() && + isImplementingSerializable(declaration) && + !hasCorrectSerialVersionUUID(declaration)) { + report(CodeSmell(issue, Entity.from(declaration), "The object ${declaration.nameAsSafeName} " + + "implements the Serializable interface and should thus define a serialVersionUID.")) + } + super.visitObjectDeclaration(declaration) + } - private fun isImplementingSerializable(classOrObject: KtClassOrObject) = - classOrObject.superTypeListEntries.any { it.text == "Serializable" } + private fun isImplementingSerializable(classOrObject: KtClassOrObject) = + classOrObject.superTypeListEntries.any { it.text == "Serializable" } - private fun hasCorrectSerialVersionUUID(declaration: KtObjectDeclaration): Boolean { - val property = declaration.body?.properties?.firstOrNull { it.name == versionUID } - return property != null && property.isConstant() && isLongProperty(property) - } + private fun hasCorrectSerialVersionUUID(declaration: KtObjectDeclaration): Boolean { + val property = declaration.body?.properties?.firstOrNull { it.name == versionUID } + return property != null && property.isConstant() && isLongProperty(property) + } - private fun isLongProperty(property: KtProperty) = hasLongType(property) || hasLongAssignment(property) + private fun isLongProperty(property: KtProperty) = hasLongType(property) || hasLongAssignment(property) - private fun hasLongType(property: KtProperty) = property.typeReference?.text == "Long" + private fun hasLongType(property: KtProperty) = property.typeReference?.text == "Long" - private fun hasLongAssignment(property: KtProperty): Boolean { - val assignmentText = property.children - .singleOrNull { it is KtConstantExpression || it is KtPrefixExpression }?.text - return assignmentText != null && assignmentText.last() == 'L' && - assignmentText.substring(0, assignmentText.length - 1).toLongOrNull() != null - } + private fun hasLongAssignment(property: KtProperty): Boolean { + val assignmentText = property.children + .singleOrNull { it is KtConstantExpression || it is KtPrefixExpression }?.text + return assignmentText != null && assignmentText.last() == 'L' && + assignmentText.substring(0, assignmentText.length - 1).toLongOrNull() != null + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/SpacingBetweenPackageAndImports.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/SpacingBetweenPackageAndImports.kt index 26227ab90..2e5c95f9e 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/SpacingBetweenPackageAndImports.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/SpacingBetweenPackageAndImports.kt @@ -41,57 +41,57 @@ import org.jetbrains.kotlin.psi.psiUtil.siblings */ class SpacingBetweenPackageAndImports(config: Config = Config.empty) : Rule(config) { - private var containsClassOrObject = false + private var containsClassOrObject = false - override val issue = Issue(javaClass.simpleName, Severity.Style, - "Violation of the package declaration style.", - Debt.FIVE_MINS) + override val issue = Issue(javaClass.simpleName, Severity.Style, + "Violation of the package declaration style.", + Debt.FIVE_MINS) - override fun visitFile(file: PsiFile?) { - file?.accept(object : DetektVisitor() { - override fun visitClassOrObject(classOrObject: KtClassOrObject) { - containsClassOrObject = true - } - }) - super.visitFile(file) - } + override fun visitFile(file: PsiFile?) { + file?.accept(object : DetektVisitor() { + override fun visitClassOrObject(classOrObject: KtClassOrObject) { + containsClassOrObject = true + } + }) + super.visitFile(file) + } - override fun visitImportList(importList: KtImportList) { - if (containsClassOrObject && importList.imports.isNotEmpty()) { - checkPackageDeclaration(importList) - checkKtElementsDeclaration(importList) - } - } + override fun visitImportList(importList: KtImportList) { + if (containsClassOrObject && importList.imports.isNotEmpty()) { + checkPackageDeclaration(importList) + checkKtElementsDeclaration(importList) + } + } - private fun checkPackageDeclaration(importList: KtImportList) { - val prevSibling = importList.prevSibling - if (isPackageDeclaration(prevSibling) || prevSibling is PsiWhiteSpace) { - checkLinebreakAfterElement(prevSibling, "There should be exactly one empty line in between the " + - "package declaration and the list of imports.") - } - } + private fun checkPackageDeclaration(importList: KtImportList) { + val prevSibling = importList.prevSibling + if (isPackageDeclaration(prevSibling) || prevSibling is PsiWhiteSpace) { + checkLinebreakAfterElement(prevSibling, "There should be exactly one empty line in between the " + + "package declaration and the list of imports.") + } + } - private fun isPackageDeclaration(element: PsiElement?) = - element is KtPackageDirective && element.text.isNotEmpty() + private fun isPackageDeclaration(element: PsiElement?) = + element is KtPackageDirective && element.text.isNotEmpty() - private fun checkKtElementsDeclaration(importList: KtImportList) { - val ktElements = importList.siblings(withItself = false).toList().filter { it is KtElement } - val nextSibling = importList.nextSibling - if (ktElements.isNotEmpty() && - (nextSibling is PsiWhiteSpace || nextSibling is KtElement)) { - val name = (ktElements.first() as? KtClassOrObject)?.name ?: "the class or object" + private fun checkKtElementsDeclaration(importList: KtImportList) { + val ktElements = importList.siblings(withItself = false).toList().filter { it is KtElement } + val nextSibling = importList.nextSibling + if (ktElements.isNotEmpty() && + (nextSibling is PsiWhiteSpace || nextSibling is KtElement)) { + val name = (ktElements.first() as? KtClassOrObject)?.name ?: "the class or object" - checkLinebreakAfterElement(nextSibling, "There should be exactly one empty line in between the " + - "list of imports and the declaration of $name.") - } - } + checkLinebreakAfterElement(nextSibling, "There should be exactly one empty line in between the " + + "list of imports and the declaration of $name.") + } + } - private fun checkLinebreakAfterElement(element: PsiElement?, message: String) { - if (element is PsiWhiteSpace || element is KtElement) { - val count = element.text.count { it == '\n' } - if (count != 2) { - report(CodeSmell(issue, Entity.from(element), message)) - } - } - } + private fun checkLinebreakAfterElement(element: PsiElement?, message: String) { + if (element is PsiWhiteSpace || element is KtElement) { + val count = element.text.count { it == '\n' } + if (count != 2) { + report(CodeSmell(issue, Entity.from(element), message)) + } + } + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ThrowsCount.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ThrowsCount.kt index d8d4073e4..44d936e0c 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ThrowsCount.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ThrowsCount.kt @@ -42,24 +42,24 @@ import org.jetbrains.kotlin.psi.KtThrowExpression */ class ThrowsCount(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, Severity.Style, - "Restrict the number of throw statements in methods.", - Debt.TEN_MINS) + override val issue = Issue(javaClass.simpleName, Severity.Style, + "Restrict the number of throw statements in methods.", + Debt.TEN_MINS) - private val max = valueOrDefault(MAX, 2) + private val max = valueOrDefault(MAX, 2) - override fun visitNamedFunction(function: KtNamedFunction) { - super.visitNamedFunction(function) - if (!function.isOverride()) { - val count = function.collectByType().count() - if (count > max) { - report(CodeSmell(issue, Entity.from(function), "Too many throw statements in the function" + - " ${function.nameAsSafeName}. The maximum number of allowed throw statements is $max.")) - } - } - } + override fun visitNamedFunction(function: KtNamedFunction) { + super.visitNamedFunction(function) + if (!function.isOverride()) { + val count = function.collectByType().count() + if (count > max) { + report(CodeSmell(issue, Entity.from(function), "Too many throw statements in the function" + + " ${function.nameAsSafeName}. The maximum number of allowed throw statements is $max.")) + } + } + } - companion object { - const val MAX = "max" - } + companion object { + const val MAX = "max" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/TrailingWhitespace.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/TrailingWhitespace.kt index 6794ee13a..1dd818ac6 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/TrailingWhitespace.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/TrailingWhitespace.kt @@ -16,30 +16,30 @@ import io.gitlab.arturbosch.detekt.api.Severity */ class TrailingWhitespace(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, - Severity.Style, - "Checks which lines end with a whitespace.", - Debt.FIVE_MINS) + override val issue = Issue(javaClass.simpleName, + Severity.Style, + "Checks which lines end with a whitespace.", + Debt.FIVE_MINS) - fun visit(fileContent: KtFileContent) { - var offset = 0 - fileContent.content.forEachIndexed { index, line -> - offset += line.length - if (hasTrailingWhitespace(line)) { - val file = fileContent.file - val ktElement = findAnnotatedStatementInLine(file, offset, line) - if (ktElement != null) { - report(CodeSmell(issue, Entity.from(ktElement), createMessage(index))) - } else { - report(CodeSmell(issue, Entity.from(file, offset), createMessage(index))) - } - } - offset += 1 /* '\n' */ - } - } + fun visit(fileContent: KtFileContent) { + var offset = 0 + fileContent.content.forEachIndexed { index, line -> + offset += line.length + if (hasTrailingWhitespace(line)) { + val file = fileContent.file + val ktElement = findAnnotatedStatementInLine(file, offset, line) + if (ktElement != null) { + report(CodeSmell(issue, Entity.from(ktElement), createMessage(index))) + } else { + report(CodeSmell(issue, Entity.from(file, offset), createMessage(index))) + } + } + offset += 1 /* '\n' */ + } + } - private fun hasTrailingWhitespace(line: String) = - line.isNotEmpty() && (line.last() == ' ' || line.last() == '\t') + private fun hasTrailingWhitespace(line: String) = + line.isNotEmpty() && (line.last() == ' ' || line.last() == '\t') - private fun createMessage(line: Int) = "Line ${line + 1} ends with a whitespace." + private fun createMessage(line: Int) = "Line ${line + 1} ends with a whitespace." } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryAbstractClass.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryAbstractClass.kt index 7cd905f68..fa029bc6b 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryAbstractClass.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryAbstractClass.kt @@ -46,74 +46,74 @@ import org.jetbrains.kotlin.psi.psiUtil.isAbstract */ class UnnecessaryAbstractClass(config: Config = Config.empty) : Rule(config) { - private val noConcreteMember = "An abstract class without a concrete member can be refactored to an interface." - private val noAbstractMember = "An abstract class without an abstract member can be refactored to a concrete class." + private val noConcreteMember = "An abstract class without a concrete member can be refactored to an interface." + private val noAbstractMember = "An abstract class without an abstract member can be refactored to a concrete class." - override val issue = - Issue("UnnecessaryAbstractClass", Severity.Style, - "An abstract class is unnecessary and can be refactored. " + - "An abstract class should have both abstract and concrete properties or functions. " + - noConcreteMember + " " + noAbstractMember, - Debt.FIVE_MINS) + override val issue = + Issue("UnnecessaryAbstractClass", Severity.Style, + "An abstract class is unnecessary and can be refactored. " + + "An abstract class should have both abstract and concrete properties or functions. " + + noConcreteMember + " " + noAbstractMember, + Debt.FIVE_MINS) - private val excludeAnnotatedClasses = SplitPattern(valueOrDefault(EXCLUDE_ANNOTATED_CLASSES, "dagger.Module")) - private lateinit var annotationExcluder: AnnotationExcluder + private val excludeAnnotatedClasses = SplitPattern(valueOrDefault(EXCLUDE_ANNOTATED_CLASSES, "dagger.Module")) + private lateinit var annotationExcluder: AnnotationExcluder - override fun visitKtFile(file: KtFile) { - annotationExcluder = AnnotationExcluder(file, excludeAnnotatedClasses) - super.visitKtFile(file) - } + override fun visitKtFile(file: KtFile) { + annotationExcluder = AnnotationExcluder(file, excludeAnnotatedClasses) + super.visitKtFile(file) + } - override fun visitClass(klass: KtClass) { - if (!klass.isInterface() && klass.isAbstract() && klass.superTypeListEntries.isEmpty()) { - val body = klass.body - if (body != null) { - val namedMembers = body.children.filter { it is KtProperty || it is KtNamedFunction } - val namedClassMembers = NamedClassMembers(klass, namedMembers) - namedClassMembers.detectAbstractAndConcreteType() - } else if (!hasNoConstructorParameter(klass)) { - report(CodeSmell(issue, Entity.from(klass), noAbstractMember), klass) - } - } - super.visitClass(klass) - } + override fun visitClass(klass: KtClass) { + if (!klass.isInterface() && klass.isAbstract() && klass.superTypeListEntries.isEmpty()) { + val body = klass.body + if (body != null) { + val namedMembers = body.children.filter { it is KtProperty || it is KtNamedFunction } + val namedClassMembers = NamedClassMembers(klass, namedMembers) + namedClassMembers.detectAbstractAndConcreteType() + } else if (!hasNoConstructorParameter(klass)) { + report(CodeSmell(issue, Entity.from(klass), noAbstractMember), klass) + } + } + super.visitClass(klass) + } - private fun report(finding: Finding, klass: KtClass) { - if (!annotationExcluder.shouldExclude(klass.annotationEntries)) { - report(finding) - } - } + private fun report(finding: Finding, klass: KtClass) { + if (!annotationExcluder.shouldExclude(klass.annotationEntries)) { + report(finding) + } + } - private fun hasNoConstructorParameter(klass: KtClass): Boolean { - val primaryConstructor = klass.primaryConstructor - return primaryConstructor == null || !primaryConstructor.valueParameters.any() - } + private fun hasNoConstructorParameter(klass: KtClass): Boolean { + val primaryConstructor = klass.primaryConstructor + return primaryConstructor == null || !primaryConstructor.valueParameters.any() + } - private inner class NamedClassMembers(val klass: KtClass, val namedMembers: List) { + private inner class NamedClassMembers(val klass: KtClass, val namedMembers: List) { - fun detectAbstractAndConcreteType() { - val indexOfFirstAbstractMember = indexOfFirstMember(true) - if (indexOfFirstAbstractMember == -1) { - report(CodeSmell(issue, Entity.from(klass), noAbstractMember), klass) - } else if (isAbstractClassWithoutConcreteMembers(indexOfFirstAbstractMember)) { - report(CodeSmell(issue, Entity.from(klass), noConcreteMember), klass) - } - } + fun detectAbstractAndConcreteType() { + val indexOfFirstAbstractMember = indexOfFirstMember(true) + if (indexOfFirstAbstractMember == -1) { + report(CodeSmell(issue, Entity.from(klass), noAbstractMember), klass) + } else if (isAbstractClassWithoutConcreteMembers(indexOfFirstAbstractMember)) { + report(CodeSmell(issue, Entity.from(klass), noConcreteMember), klass) + } + } - private fun indexOfFirstMember(isAbstract: Boolean, members: List = this.namedMembers): Int { - return members.indexOfFirst { - val namedDeclaration = it as? KtNamedDeclaration - namedDeclaration != null && namedDeclaration.isAbstract() == isAbstract - } - } + private fun indexOfFirstMember(isAbstract: Boolean, members: List = this.namedMembers): Int { + return members.indexOfFirst { + val namedDeclaration = it as? KtNamedDeclaration + namedDeclaration != null && namedDeclaration.isAbstract() == isAbstract + } + } - private fun isAbstractClassWithoutConcreteMembers(indexOfFirstAbstractMember: Int) = - indexOfFirstAbstractMember == 0 && hasNoConcreteMemberLeft() && hasNoConstructorParameter(klass) + private fun isAbstractClassWithoutConcreteMembers(indexOfFirstAbstractMember: Int) = + indexOfFirstAbstractMember == 0 && hasNoConcreteMemberLeft() && hasNoConstructorParameter(klass) - private fun hasNoConcreteMemberLeft() = indexOfFirstMember(false, namedMembers.drop(1)) == -1 - } + private fun hasNoConcreteMemberLeft() = indexOfFirstMember(false, namedMembers.drop(1)) == -1 + } - companion object { - const val EXCLUDE_ANNOTATED_CLASSES = "excludeAnnotatedClasses" - } + companion object { + const val EXCLUDE_ANNOTATED_CLASSES = "excludeAnnotatedClasses" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryApply.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryApply.kt index d4ee2199e..b19e4c8c5 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryApply.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryApply.kt @@ -8,13 +8,13 @@ import io.gitlab.arturbosch.detekt.api.Issue import io.gitlab.arturbosch.detekt.api.Rule import io.gitlab.arturbosch.detekt.api.Severity import io.gitlab.arturbosch.detekt.rules.safeAs +import kotlin.contracts.ExperimentalContracts +import kotlin.contracts.contract import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.KtBinaryExpression import org.jetbrains.kotlin.psi.KtBlockExpression import org.jetbrains.kotlin.psi.KtCallExpression import org.jetbrains.kotlin.psi.KtDotQualifiedExpression -import kotlin.contracts.ExperimentalContracts -import kotlin.contracts.contract /** * `apply` expressions are used frequently, but sometimes their usage should be replaced with @@ -36,39 +36,39 @@ import kotlin.contracts.contract */ class UnnecessaryApply(config: Config) : Rule(config) { - override val issue = Issue(javaClass.simpleName, Severity.Style, - "The `apply` usage is unnecessary", Debt.FIVE_MINS) + override val issue = Issue(javaClass.simpleName, Severity.Style, + "The `apply` usage is unnecessary", Debt.FIVE_MINS) - override fun visitCallExpression(expression: KtCallExpression) { - super.visitCallExpression(expression) + override fun visitCallExpression(expression: KtCallExpression) { + super.visitCallExpression(expression) - if (expression.isApplyExpr() && - expression.hasOnlyOneStatement() && - expression.receiverIsUnused()) { - report(CodeSmell( - issue, Entity.from(expression), - "apply expression can be omitted" - )) - } - } + if (expression.isApplyExpr() && + expression.hasOnlyOneStatement() && + expression.receiverIsUnused()) { + report(CodeSmell( + issue, Entity.from(expression), + "apply expression can be omitted" + )) + } + } } private fun KtCallExpression.receiverIsUnused(): Boolean { - if (parent is KtDotQualifiedExpression) { - val scopeOfApplyCall = parent.parent - return scopeOfApplyCall == null || scopeOfApplyCall is KtBlockExpression - } - return false + if (parent is KtDotQualifiedExpression) { + val scopeOfApplyCall = parent.parent + return scopeOfApplyCall == null || scopeOfApplyCall is KtBlockExpression + } + return false } private fun KtCallExpression.hasOnlyOneStatement(): Boolean { - val lambdaBody = firstLambdaArg?.bodyExpression - if (lambdaBody.hasOnlyOneStatement()) { - return lambdaBody.statements[0] - ?.safeAs() - ?.operationToken != KtTokens.EQ - } - return false + val lambdaBody = firstLambdaArg?.bodyExpression + if (lambdaBody.hasOnlyOneStatement()) { + return lambdaBody.statements[0] + ?.safeAs() + ?.operationToken != KtTokens.EQ + } + return false } private const val APPLY_LITERAL = "apply" @@ -76,13 +76,13 @@ private const val APPLY_LITERAL = "apply" private fun KtCallExpression.isApplyExpr() = calleeExpression?.textMatches(APPLY_LITERAL) == true private val KtCallExpression.firstLambdaArg - get() = lambdaArguments.firstOrNull() - ?.getLambdaExpression() + get() = lambdaArguments.firstOrNull() + ?.getLambdaExpression() @UseExperimental(ExperimentalContracts::class) private fun KtBlockExpression?.hasOnlyOneStatement(): Boolean { - contract { - returns(true) implies (this@hasOnlyOneStatement != null) - } - return this?.children?.size == 1 + contract { + returns(true) implies (this@hasOnlyOneStatement != null) + } + return this?.children?.size == 1 } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryInheritance.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryInheritance.kt index 220d5d5e3..52cfe2a71 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryInheritance.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryInheritance.kt @@ -24,19 +24,19 @@ import org.jetbrains.kotlin.psi.KtClassOrObject */ class UnnecessaryInheritance(config: Config = Config.empty) : Rule(config) { - override val issue: Issue = Issue(javaClass.simpleName, Severity.Style, - "The extended super type is unnecessary.", Debt.FIVE_MINS) + override val issue: Issue = Issue(javaClass.simpleName, Severity.Style, + "The extended super type is unnecessary.", Debt.FIVE_MINS) - override fun visitClassOrObject(classOrObject: KtClassOrObject) { - for (superEntry in classOrObject.superTypeListEntries) { - when (superEntry.text) { - "Any()" -> report(classOrObject, "Unnecessary inheritance of 'Any'.") - "Object()" -> report(classOrObject, "Unnecessary inheritance of 'Object'.") - } - } - } + override fun visitClassOrObject(classOrObject: KtClassOrObject) { + for (superEntry in classOrObject.superTypeListEntries) { + when (superEntry.text) { + "Any()" -> report(classOrObject, "Unnecessary inheritance of 'Any'.") + "Object()" -> report(classOrObject, "Unnecessary inheritance of 'Object'.") + } + } + } - private fun report(classOrObject: KtClassOrObject, message: String) { - report(CodeSmell(issue, Entity.from(classOrObject), message)) - } + private fun report(classOrObject: KtClassOrObject, message: String) { + report(CodeSmell(issue, Entity.from(classOrObject), message)) + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryLet.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryLet.kt index d92df7490..1296bf0e4 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryLet.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryLet.kt @@ -42,38 +42,38 @@ import org.jetbrains.kotlin.psi.KtLambdaExpression */ class UnnecessaryLet(config: Config) : Rule(config) { - override val issue = Issue(javaClass.simpleName, Severity.Style, - "The `let` usage is unnecessary", Debt.FIVE_MINS) + override val issue = Issue(javaClass.simpleName, Severity.Style, + "The `let` usage is unnecessary", Debt.FIVE_MINS) - override fun visitCallExpression(expression: KtCallExpression) { - super.visitCallExpression(expression) + override fun visitCallExpression(expression: KtCallExpression) { + super.visitCallExpression(expression) - if (!expression.isLetExpr()) return + if (!expression.isLetExpr()) return - val lambdaExpr = expression.firstLambdaArg - val lambdaParameter = lambdaExpr?.firstParameter - val lambdaBody = lambdaExpr?.bodyExpression + val lambdaExpr = expression.firstLambdaArg + val lambdaParameter = lambdaExpr?.firstParameter + val lambdaBody = lambdaExpr?.bodyExpression - if (lambdaBody.hasOnlyOneStatement()) { - // only dot qualified expressions can be unnecessary - val firstExpr = lambdaBody?.firstChild as? KtDotQualifiedExpression - val exprReceiver = firstExpr?.receiverExpression + if (lambdaBody.hasOnlyOneStatement()) { + // only dot qualified expressions can be unnecessary + val firstExpr = lambdaBody?.firstChild as? KtDotQualifiedExpression + val exprReceiver = firstExpr?.receiverExpression - if (exprReceiver != null) { - val isLetWithImplicitParam = lambdaParameter == null && exprReceiver.textMatches(IT_LITERAL) - val isLetWithExplicitParam = lambdaParameter != null && lambdaParameter.textMatches(exprReceiver) + if (exprReceiver != null) { + val isLetWithImplicitParam = lambdaParameter == null && exprReceiver.textMatches(IT_LITERAL) + val isLetWithExplicitParam = lambdaParameter != null && lambdaParameter.textMatches(exprReceiver) - val hasOneRef = lambdaBody.countVarRefs(lambdaParameter?.text ?: IT_LITERAL) == 1 + val hasOneRef = lambdaBody.countVarRefs(lambdaParameter?.text ?: IT_LITERAL) == 1 - if ((isLetWithExplicitParam || isLetWithImplicitParam) && hasOneRef) { - report(CodeSmell( - issue, Entity.from(expression), - "let expression can be omitted" - )) - } - } - } - } + if ((isLetWithExplicitParam || isLetWithImplicitParam) && hasOneRef) { + report(CodeSmell( + issue, Entity.from(expression), + "let expression can be omitted" + )) + } + } + } + } } private fun KtCallExpression.isLetExpr() = calleeExpression?.textMatches(LET_LITERAL) == true @@ -85,4 +85,4 @@ private val KtLambdaExpression.firstParameter get() = valueParameters.firstOrNul private fun KtBlockExpression?.hasOnlyOneStatement() = this?.children?.size == 1 private fun PsiElement.countVarRefs(varName: String): Int = - children.sumBy { it.countVarRefs(varName) + if (it.textMatches(varName)) 1 else 0 } + children.sumBy { it.countVarRefs(varName) + if (it.textMatches(varName)) 1 else 0 } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryParentheses.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryParentheses.kt index 2e528c6e4..c3ca2c775 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryParentheses.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryParentheses.kt @@ -47,49 +47,49 @@ import org.jetbrains.kotlin.psi.KtValueArgumentList */ class UnnecessaryParentheses(config: Config = Config.empty) : Rule(config) { - override val issue = Issue("UnnecessaryParentheses", Severity.Style, - "Unnecessary parentheses don't add any value to the code and should be removed.", - Debt.FIVE_MINS) + override val issue = Issue("UnnecessaryParentheses", Severity.Style, + "Unnecessary parentheses don't add any value to the code and should be removed.", + Debt.FIVE_MINS) - override fun visitParenthesizedExpression(expression: KtParenthesizedExpression) { - super.visitParenthesizedExpression(expression) + override fun visitParenthesizedExpression(expression: KtParenthesizedExpression) { + super.visitParenthesizedExpression(expression) - if (KtPsiUtil.areParenthesesUseless(expression)) { - val message = "Parentheses in ${expression.text} are unnecessary and can be replaced with: " + - "${KtPsiUtil.deparenthesize(expression)?.text}" - report(CodeSmell(issue, Entity.from(expression), message)) - } - } + if (KtPsiUtil.areParenthesesUseless(expression)) { + val message = "Parentheses in ${expression.text} are unnecessary and can be replaced with: " + + "${KtPsiUtil.deparenthesize(expression)?.text}" + report(CodeSmell(issue, Entity.from(expression), message)) + } + } - override fun visitArgument(argument: KtValueArgument) { - super.visitArgument(argument) - if (argument.children.any { it is KtLambdaExpression } && - isSingleLambdaInArgumentList(argument) && - !isArgumentInFunctionCallWithTwoLambdas(argument)) { - val parent = argument.parent - val message = "Parentheses around the lambda ${parent.text} are unnecessary and can be removed." - report(CodeSmell(issue, Entity.from(parent), message)) - } - } + override fun visitArgument(argument: KtValueArgument) { + super.visitArgument(argument) + if (argument.children.any { it is KtLambdaExpression } && + isSingleLambdaInArgumentList(argument) && + !isArgumentInFunctionCallWithTwoLambdas(argument)) { + val parent = argument.parent + val message = "Parentheses around the lambda ${parent.text} are unnecessary and can be removed." + report(CodeSmell(issue, Entity.from(parent), message)) + } + } - private fun isSingleLambdaInArgumentList(argument: KtValueArgument): Boolean { - val parent = argument.parent - val isOnlyArgument = parent.children.size == 1 - val nodeBeforeArgumentList = parent.parent - val isSuperTypeCallEntry = nodeBeforeArgumentList is KtSuperTypeCallEntry || - nodeBeforeArgumentList is KtConstructorDelegationCall + private fun isSingleLambdaInArgumentList(argument: KtValueArgument): Boolean { + val parent = argument.parent + val isOnlyArgument = parent.children.size == 1 + val nodeBeforeArgumentList = parent.parent + val isSuperTypeCallEntry = nodeBeforeArgumentList is KtSuperTypeCallEntry || + nodeBeforeArgumentList is KtConstructorDelegationCall - return isOnlyArgument && - !isSuperTypeCallEntry && - argument.equalsToken == null - } + return isOnlyArgument && + !isSuperTypeCallEntry && + argument.equalsToken == null + } - private fun isArgumentInFunctionCallWithTwoLambdas(argument: KtValueArgument): Boolean { - val parent = argument.parent - val grandParent = parent.parent + private fun isArgumentInFunctionCallWithTwoLambdas(argument: KtValueArgument): Boolean { + val parent = argument.parent + val grandParent = parent.parent - return parent is KtValueArgumentList && - grandParent.children.size >= 2 && - grandParent.children.last() is KtLambdaArgument - } + return parent is KtValueArgumentList && + grandParent.children.size >= 2 && + grandParent.children.last() is KtLambdaArgument + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UntilInsteadOfRangeTo.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UntilInsteadOfRangeTo.kt index a22bb0e37..9e6cf334d 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UntilInsteadOfRangeTo.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UntilInsteadOfRangeTo.kt @@ -33,28 +33,28 @@ import org.jetbrains.kotlin.psi.KtOperationReferenceExpression */ class UntilInsteadOfRangeTo(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, - Severity.Style, - "'..' call can be replaced with 'until'", - Debt.FIVE_MINS) + override val issue = Issue(javaClass.simpleName, + Severity.Style, + "'..' call can be replaced with 'until'", + Debt.FIVE_MINS) - private val minimumSize = 3 + private val minimumSize = 3 - override fun visitBinaryExpression(expression: KtBinaryExpression) { - if (isUntilApplicable(expression.children)) { - report(CodeSmell(issue, Entity.from(expression), "'..' call can be replaced with 'until'")) - } - super.visitBinaryExpression(expression) - } + override fun visitBinaryExpression(expression: KtBinaryExpression) { + if (isUntilApplicable(expression.children)) { + report(CodeSmell(issue, Entity.from(expression), "'..' call can be replaced with 'until'")) + } + super.visitBinaryExpression(expression) + } - private fun isUntilApplicable(range: Array): Boolean { - if (range.size >= minimumSize && range[1] is KtOperationReferenceExpression && range[1].text == "..") { - val expression = range[2] as? KtBinaryExpression - if (expression?.operationToken == KtTokens.MINUS) { - val rightExpressionValue = expression?.right as? KtConstantExpression - return rightExpressionValue?.text == "1" - } - } - return false - } + private fun isUntilApplicable(range: Array): Boolean { + if (range.size >= minimumSize && range[1] is KtOperationReferenceExpression && range[1].text == "..") { + val expression = range[2] as? KtBinaryExpression + if (expression?.operationToken == KtTokens.MINUS) { + val rightExpressionValue = expression?.right as? KtConstantExpression + return rightExpressionValue?.text == "1" + } + } + return false + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedImports.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedImports.kt index 386da2e26..c1673ab68 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedImports.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedImports.kt @@ -27,92 +27,92 @@ import org.jetbrains.kotlin.psi.KtReferenceExpression */ class UnusedImports(config: Config) : Rule(config) { - override val issue = Issue( - javaClass.simpleName, - Severity.Style, - "Unused Imports are dead code and should be removed.", - Debt.FIVE_MINS) + override val issue = Issue( + javaClass.simpleName, + Severity.Style, + "Unused Imports are dead code and should be removed.", + Debt.FIVE_MINS) - companion object { - private val operatorSet = setOf("unaryPlus", "unaryMinus", "not", "inc", "dec", "plus", "minus", "times", "div", - "mod", "rangeTo", "contains", "get", "set", "invoke", "plusAssign", "minusAssign", "timesAssign", "divAssign", - "modAssign", "equals", "compareTo", "iterator", "getValue", "setValue") + companion object { + private val operatorSet = setOf("unaryPlus", "unaryMinus", "not", "inc", "dec", "plus", "minus", "times", "div", + "mod", "rangeTo", "contains", "get", "set", "invoke", "plusAssign", "minusAssign", "timesAssign", "divAssign", + "modAssign", "equals", "compareTo", "iterator", "getValue", "setValue") - private val kotlinDocReferencesRegExp = Regex("\\[([^]]+)](?!\\[)") - private val kotlinDocSeeReferenceRegExp = Regex("^@see (.+)") - private val whiteSpaceRegex = Regex("\\s+") - } + private val kotlinDocReferencesRegExp = Regex("\\[([^]]+)](?!\\[)") + private val kotlinDocSeeReferenceRegExp = Regex("^@see (.+)") + private val whiteSpaceRegex = Regex("\\s+") + } - override fun visit(root: KtFile) { - with(UnusedImportsVisitor()) { - root.accept(this) - unusedImports().forEach { - report(CodeSmell(issue, Entity.from(it), "The import '${it.importedFqName}' is unused.")) - } - } - super.visit(root) - } + override fun visit(root: KtFile) { + with(UnusedImportsVisitor()) { + root.accept(this) + unusedImports().forEach { + report(CodeSmell(issue, Entity.from(it), "The import '${it.importedFqName}' is unused.")) + } + } + super.visit(root) + } - private class UnusedImportsVisitor : DetektVisitor() { - private var currentPackage: FqName? = null - private var imports: List? = null - private val namedReferences = mutableSetOf() + private class UnusedImportsVisitor : DetektVisitor() { + private var currentPackage: FqName? = null + private var imports: List? = null + private val namedReferences = mutableSetOf() - fun unusedImports(): List { - fun KtImportDirective.isFromSamePackage() = - importedFqName?.parent() == currentPackage && alias == null + fun unusedImports(): List { + fun KtImportDirective.isFromSamePackage() = + importedFqName?.parent() == currentPackage && alias == null - fun KtImportDirective.isNotUsed() = - aliasName !in namedReferences && identifier() !in namedReferences + fun KtImportDirective.isNotUsed() = + aliasName !in namedReferences && identifier() !in namedReferences - return imports?.filter { it.isFromSamePackage() || it.isNotUsed() }.orEmpty() - } + return imports?.filter { it.isFromSamePackage() || it.isNotUsed() }.orEmpty() + } - override fun visitPackageDirective(directive: KtPackageDirective) { - currentPackage = directive.fqName - super.visitPackageDirective(directive) - } + override fun visitPackageDirective(directive: KtPackageDirective) { + currentPackage = directive.fqName + super.visitPackageDirective(directive) + } - override fun visitImportList(importList: KtImportList) { - imports = importList.imports.filter { it.isValidImport } - .filter { it.identifier()?.contains("*")?.not() == true } - .filter { it.identifier() != null } - .filter { !operatorSet.contains(it.identifier()) } - super.visitImportList(importList) - } + override fun visitImportList(importList: KtImportList) { + imports = importList.imports.filter { it.isValidImport } + .filter { it.identifier()?.contains("*")?.not() == true } + .filter { it.identifier() != null } + .filter { !operatorSet.contains(it.identifier()) } + super.visitImportList(importList) + } - override fun visitReferenceExpression(expression: KtReferenceExpression) { - expression - .takeIf { !it.isPartOf(KtImportDirective::class) && !it.isPartOf(KtPackageDirective::class) } - ?.takeIf { it.children.isEmpty() } - ?.run { namedReferences.add(text.trim('`')) } - super.visitReferenceExpression(expression) - } + override fun visitReferenceExpression(expression: KtReferenceExpression) { + expression + .takeIf { !it.isPartOf(KtImportDirective::class) && !it.isPartOf(KtPackageDirective::class) } + ?.takeIf { it.children.isEmpty() } + ?.run { namedReferences.add(text.trim('`')) } + super.visitReferenceExpression(expression) + } - override fun visitDeclaration(dcl: KtDeclaration) { - val kdoc = dcl.docComment?.getDefaultSection() + override fun visitDeclaration(dcl: KtDeclaration) { + val kdoc = dcl.docComment?.getDefaultSection() - kdoc?.children - ?.filter { it is KDocTag } - ?.map { it.text } - ?.forEach { handleKDoc(it) } + kdoc?.children + ?.filter { it is KDocTag } + ?.map { it.text } + ?.forEach { handleKDoc(it) } - kdoc?.getContent()?.let { - handleKDoc(it) - } - super.visitDeclaration(dcl) - } + kdoc?.getContent()?.let { + handleKDoc(it) + } + super.visitDeclaration(dcl) + } - private fun handleKDoc(content: String) { - kotlinDocReferencesRegExp.findAll(content, 0) - .map { it.groupValues[1] } - .forEach { namedReferences.add(it.split(".")[0]) } - kotlinDocSeeReferenceRegExp.find(content)?.let { - val str = it.groupValues[1].split(whiteSpaceRegex)[0] - namedReferences.add(str.split(".")[0]) - } - } - } + private fun handleKDoc(content: String) { + kotlinDocReferencesRegExp.findAll(content, 0) + .map { it.groupValues[1] } + .forEach { namedReferences.add(it.split(".")[0]) } + kotlinDocSeeReferenceRegExp.find(content)?.let { + val str = it.groupValues[1].split(whiteSpaceRegex)[0] + namedReferences.add(str.split(".")[0]) + } + } + } } private fun KtImportDirective.identifier() = this.importPath?.importedName?.identifier diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateClass.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateClass.kt index 1ec200539..e0d56a427 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateClass.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateClass.kt @@ -36,119 +36,119 @@ import org.jetbrains.kotlin.psi.psiUtil.isPrivate */ class UnusedPrivateClass(config: Config = Config.empty) : Rule(config) { - override val defaultRuleIdAliases: Set = setOf("unused") + override val defaultRuleIdAliases: Set = setOf("unused") - override val issue: Issue = Issue("UnusedPrivateClass", - Severity.Maintainability, - "Private class is unused.", - Debt.FIVE_MINS) + override val issue: Issue = Issue("UnusedPrivateClass", + Severity.Maintainability, + "Private class is unused.", + Debt.FIVE_MINS) - override fun visit(root: KtFile) { - super.visit(root) + override fun visit(root: KtFile) { + super.visit(root) - val classVisitor = UnusedClassVisitor() - root.accept(classVisitor) + val classVisitor = UnusedClassVisitor() + root.accept(classVisitor) - classVisitor.getUnusedClasses().forEach { - report(CodeSmell(issue, Entity.from(it), "Private class ${it.nameAsSafeName.identifier} is unused.")) - } - } + classVisitor.getUnusedClasses().forEach { + report(CodeSmell(issue, Entity.from(it), "Private class ${it.nameAsSafeName.identifier} is unused.")) + } + } - @Suppress("Detekt.TooManyFunctions") - private class UnusedClassVisitor : DetektVisitor() { + @Suppress("Detekt.TooManyFunctions") + private class UnusedClassVisitor : DetektVisitor() { - private val privateClasses = mutableSetOf() - private val namedClasses = mutableSetOf() + private val privateClasses = mutableSetOf() + private val namedClasses = mutableSetOf() - fun getUnusedClasses(): List { - return privateClasses.filter { it.nameAsSafeName.identifier !in namedClasses } - } + fun getUnusedClasses(): List { + return privateClasses.filter { it.nameAsSafeName.identifier !in namedClasses } + } - override fun visitClass(klass: KtClass) { - if (klass.isPrivate()) { - privateClasses.add(klass) - } - klass.getSuperTypeList()?.entries - ?.mapNotNull { it.typeReference } - ?.forEach { registerAccess(it) } - super.visitClass(klass) - } + override fun visitClass(klass: KtClass) { + if (klass.isPrivate()) { + privateClasses.add(klass) + } + klass.getSuperTypeList()?.entries + ?.mapNotNull { it.typeReference } + ?.forEach { registerAccess(it) } + super.visitClass(klass) + } - private fun registerAccess(typeReference: KtTypeReference) { - // Try with the actual type of the reference (e.g. Foo, Foo?) - typeReference.orInnerType().run { namedClasses.add(text) } + private fun registerAccess(typeReference: KtTypeReference) { + // Try with the actual type of the reference (e.g. Foo, Foo?) + typeReference.orInnerType().run { namedClasses.add(text) } - // Try with the type with generics (e.g. Foo, Foo?) - (typeReference.typeElement?.orInnerType() as? KtUserType) - ?.referencedName - ?.run { namedClasses.add(this) } + // Try with the type with generics (e.g. Foo, Foo?) + (typeReference.typeElement?.orInnerType() as? KtUserType) + ?.referencedName + ?.run { namedClasses.add(this) } - // Try with the type being a generic argument of other type (e.g. List, List) - typeReference.typeElement?.typeArgumentsAsTypes - ?.asSequence() - ?.filterNotNull() - ?.map { it.orInnerType() } - ?.forEach { - namedClasses.add(it.text) - // Recursively register for nested generic types (e.g. List>) - (it as? KtTypeReference)?.run { registerAccess(it) } - } - } + // Try with the type being a generic argument of other type (e.g. List, List) + typeReference.typeElement?.typeArgumentsAsTypes + ?.asSequence() + ?.filterNotNull() + ?.map { it.orInnerType() } + ?.forEach { + namedClasses.add(it.text) + // Recursively register for nested generic types (e.g. List>) + (it as? KtTypeReference)?.run { registerAccess(it) } + } + } - override fun visitParameter(parameter: KtParameter) { - parameter.typeReference?.run { registerAccess(this) } - super.visitParameter(parameter) - } + override fun visitParameter(parameter: KtParameter) { + parameter.typeReference?.run { registerAccess(this) } + super.visitParameter(parameter) + } - override fun visitNamedFunction(function: KtNamedFunction) { - function.typeReference?.run { registerAccess(this) } - super.visitNamedFunction(function) - } + override fun visitNamedFunction(function: KtNamedFunction) { + function.typeReference?.run { registerAccess(this) } + super.visitNamedFunction(function) + } - override fun visitObjectDeclaration(declaration: KtObjectDeclaration) { - declaration.getSuperTypeList()?.entries?.forEach { - it.typeReference?.run { registerAccess(this) } - } - super.visitObjectDeclaration(declaration) - } + override fun visitObjectDeclaration(declaration: KtObjectDeclaration) { + declaration.getSuperTypeList()?.entries?.forEach { + it.typeReference?.run { registerAccess(this) } + } + super.visitObjectDeclaration(declaration) + } - override fun visitFunctionType(type: KtFunctionType) { - type.returnTypeReference?.run { registerAccess(this) } - super.visitFunctionType(type) - } + override fun visitFunctionType(type: KtFunctionType) { + type.returnTypeReference?.run { registerAccess(this) } + super.visitFunctionType(type) + } - override fun visitProperty(property: KtProperty) { - property.typeReference?.run { registerAccess(this) } - super.visitProperty(property) - } + override fun visitProperty(property: KtProperty) { + property.typeReference?.run { registerAccess(this) } + super.visitProperty(property) + } - override fun visitCallExpression(expression: KtCallExpression) { - expression.calleeExpression?.text?.run { namedClasses.add(this) } - super.visitCallExpression(expression) - } + override fun visitCallExpression(expression: KtCallExpression) { + expression.calleeExpression?.text?.run { namedClasses.add(this) } + super.visitCallExpression(expression) + } - override fun visitDoubleColonExpression(expression: KtDoubleColonExpression) { - checkReceiverForClassUsage(expression.receiverExpression) - super.visitDoubleColonExpression(expression) - } + override fun visitDoubleColonExpression(expression: KtDoubleColonExpression) { + checkReceiverForClassUsage(expression.receiverExpression) + super.visitDoubleColonExpression(expression) + } - private fun checkReceiverForClassUsage(receiver: KtExpression?) { - (receiver as? KtNameReferenceExpression) - ?.text - ?.takeIf { looksLikeAClassName(it) } - ?.let { namedClasses.add(it) } - } + private fun checkReceiverForClassUsage(receiver: KtExpression?) { + (receiver as? KtNameReferenceExpression) + ?.text + ?.takeIf { looksLikeAClassName(it) } + ?.let { namedClasses.add(it) } + } - override fun visitDotQualifiedExpression(expression: KtDotQualifiedExpression) { - checkReceiverForClassUsage(expression.receiverExpression) - super.visitDotQualifiedExpression(expression) - } + override fun visitDotQualifiedExpression(expression: KtDotQualifiedExpression) { + checkReceiverForClassUsage(expression.receiverExpression) + super.visitDotQualifiedExpression(expression) + } - // Without symbol solving it is hard to tell if this is really a class or part of a package. - // We use "first char is uppercase" as a heuristic in conjunction with "KtNameReferenceExpression" - private fun looksLikeAClassName(maybeClassName: String) = - maybeClassName.firstOrNull()?.isUpperCase() == true - } + // Without symbol solving it is hard to tell if this is really a class or part of a package. + // We use "first char is uppercase" as a heuristic in conjunction with "KtNameReferenceExpression" + private fun looksLikeAClassName(maybeClassName: String) = + maybeClassName.firstOrNull()?.isUpperCase() == true + } } /** diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateMember.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateMember.kt index 832462803..9d96fc75f 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateMember.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateMember.kt @@ -47,215 +47,215 @@ import org.jetbrains.kotlin.psi.psiUtil.referenceExpression */ class UnusedPrivateMember(config: Config = Config.empty) : Rule(config) { - companion object { - const val ALLOWED_NAMES_PATTERN = "allowedNames" - } + companion object { + const val ALLOWED_NAMES_PATTERN = "allowedNames" + } - override val defaultRuleIdAliases: Set = setOf("UNUSED_VARIABLE", "UNUSED_PARAMETER", "unused") + override val defaultRuleIdAliases: Set = setOf("UNUSED_VARIABLE", "UNUSED_PARAMETER", "unused") - override val issue: Issue = Issue("UnusedPrivateMember", - Severity.Maintainability, - "Private member is unused.", - Debt.FIVE_MINS) + override val issue: Issue = Issue("UnusedPrivateMember", + Severity.Maintainability, + "Private member is unused.", + Debt.FIVE_MINS) - private val allowedNames by LazyRegex(ALLOWED_NAMES_PATTERN, "(_|ignored|expected|serialVersionUID)") + private val allowedNames by LazyRegex(ALLOWED_NAMES_PATTERN, "(_|ignored|expected|serialVersionUID)") - override fun visit(root: KtFile) { - super.visit(root) - root.acceptUnusedMemberVisitor(UnusedFunctionVisitor(allowedNames)) - root.acceptUnusedMemberVisitor(UnusedParameterVisitor(allowedNames)) - root.acceptUnusedMemberVisitor(UnusedPropertyVisitor(allowedNames)) - } + override fun visit(root: KtFile) { + super.visit(root) + root.acceptUnusedMemberVisitor(UnusedFunctionVisitor(allowedNames)) + root.acceptUnusedMemberVisitor(UnusedParameterVisitor(allowedNames)) + root.acceptUnusedMemberVisitor(UnusedPropertyVisitor(allowedNames)) + } - private fun KtFile.acceptUnusedMemberVisitor(visitor: UnusedMemberVisitor) { - accept(visitor) - visitor.getUnusedReports(issue).forEach { report(it) } - } + private fun KtFile.acceptUnusedMemberVisitor(visitor: UnusedMemberVisitor) { + accept(visitor) + visitor.getUnusedReports(issue).forEach { report(it) } + } } private abstract class UnusedMemberVisitor(protected val allowedNames: Regex) : DetektVisitor() { - abstract fun getUnusedReports(issue: Issue): List + abstract fun getUnusedReports(issue: Issue): List } private class UnusedFunctionVisitor(allowedNames: Regex) : UnusedMemberVisitor(allowedNames) { - private val callExpressions = mutableSetOf() - private val functions = mutableMapOf() + private val callExpressions = mutableSetOf() + private val functions = mutableMapOf() - override fun getUnusedReports(issue: Issue): List { - for (call in callExpressions) { - if (functions.isEmpty()) { - break - } - functions.remove(call) - } - return functions.map { CodeSmell(issue, Entity.from(it.value), "Private function ${it.key} is unused.") } - } + override fun getUnusedReports(issue: Issue): List { + for (call in callExpressions) { + if (functions.isEmpty()) { + break + } + functions.remove(call) + } + return functions.map { CodeSmell(issue, Entity.from(it.value), "Private function ${it.key} is unused.") } + } - override fun visitClassOrObject(classOrObject: KtClassOrObject) { - if (classOrObject.isInterface()) { - return - } - super.visitClassOrObject(classOrObject) - } + override fun visitClassOrObject(classOrObject: KtClassOrObject) { + if (classOrObject.isInterface()) { + return + } + super.visitClassOrObject(classOrObject) + } - override fun visitNamedFunction(function: KtNamedFunction) { - when { - function.isOperator() -> { - // Resolution: we skip overloaded operators due to no symbol resolution #1444 - } - function.isPrivate() -> collectFunction(function) - } + override fun visitNamedFunction(function: KtNamedFunction) { + when { + function.isOperator() -> { + // Resolution: we skip overloaded operators due to no symbol resolution #1444 + } + function.isPrivate() -> collectFunction(function) + } - super.visitNamedFunction(function) - } + super.visitNamedFunction(function) + } - private fun collectFunction(function: KtNamedFunction) { - val name = function.nameAsSafeName.identifier - if (!allowedNames.matches(name)) { - functions[name] = function - } - } + private fun collectFunction(function: KtNamedFunction) { + val name = function.nameAsSafeName.identifier + if (!allowedNames.matches(name)) { + functions[name] = function + } + } - /* + /* * We need to collect all private function declarations and references to these functions * for the whole file as Kotlin allows to access private and internal object declarations * from everywhere in the file. */ - override fun visitReferenceExpression(expression: KtReferenceExpression) { - super.visitReferenceExpression(expression) - when (expression) { - is KtOperationReferenceExpression -> callExpressions.add(expression.getReferencedName()) - is KtNameReferenceExpression -> callExpressions.add(expression.getReferencedName()) - } - } + override fun visitReferenceExpression(expression: KtReferenceExpression) { + super.visitReferenceExpression(expression) + when (expression) { + is KtOperationReferenceExpression -> callExpressions.add(expression.getReferencedName()) + is KtNameReferenceExpression -> callExpressions.add(expression.getReferencedName()) + } + } - override fun visitCallExpression(expression: KtCallExpression) { - super.visitCallExpression(expression) - val calledMethodName = expression.referenceExpression()?.text + override fun visitCallExpression(expression: KtCallExpression) { + super.visitCallExpression(expression) + val calledMethodName = expression.referenceExpression()?.text - if (calledMethodName != null) { - callExpressions.add(calledMethodName) - } - } + if (calledMethodName != null) { + callExpressions.add(calledMethodName) + } + } } private class UnusedParameterVisitor(allowedNames: Regex) : UnusedMemberVisitor(allowedNames) { - private var unusedParameters: MutableMap = mutableMapOf() + private var unusedParameters: MutableMap = mutableMapOf() - override fun getUnusedReports(issue: Issue): List { - return unusedParameters.map { - CodeSmell(issue, Entity.from(it.value), "Function parameter ${it.key} is unused.") - } - } + override fun getUnusedReports(issue: Issue): List { + return unusedParameters.map { + CodeSmell(issue, Entity.from(it.value), "Function parameter ${it.key} is unused.") + } + } - override fun visitClassOrObject(classOrObject: KtClassOrObject) { - if (classOrObject.isInterface()) { - return - } - super.visitClassOrObject(classOrObject) - } + override fun visitClassOrObject(classOrObject: KtClassOrObject) { + if (classOrObject.isInterface()) { + return + } + super.visitClassOrObject(classOrObject) + } - override fun visitNamedFunction(function: KtNamedFunction) { - if (!function.isRelevant()) { - return - } + override fun visitNamedFunction(function: KtNamedFunction) { + if (!function.isRelevant()) { + return + } - collectParameters(function) + collectParameters(function) - super.visitNamedFunction(function) - } + super.visitNamedFunction(function) + } - private fun collectParameters(function: KtNamedFunction) { - function.valueParameterList?.parameters?.forEach { parameter -> - val name = parameter.nameAsSafeName.identifier - if (!allowedNames.matches(name)) { - unusedParameters[name] = parameter - } - } + private fun collectParameters(function: KtNamedFunction) { + function.valueParameterList?.parameters?.forEach { parameter -> + val name = parameter.nameAsSafeName.identifier + if (!allowedNames.matches(name)) { + unusedParameters[name] = parameter + } + } - val localProperties = mutableListOf() - function.accept(object : DetektVisitor() { - override fun visitProperty(property: KtProperty) { - if (property.isLocal) { - val name = property.nameAsSafeName.identifier - localProperties.add(name) - } - super.visitProperty(property) - } + val localProperties = mutableListOf() + function.accept(object : DetektVisitor() { + override fun visitProperty(property: KtProperty) { + if (property.isLocal) { + val name = property.nameAsSafeName.identifier + localProperties.add(name) + } + super.visitProperty(property) + } - override fun visitReferenceExpression(expression: KtReferenceExpression) { - localProperties.add(expression.text) - super.visitReferenceExpression(expression) - } - }) + override fun visitReferenceExpression(expression: KtReferenceExpression) { + localProperties.add(expression.text) + super.visitReferenceExpression(expression) + } + }) - unusedParameters = unusedParameters.filterTo(mutableMapOf()) { it.key !in localProperties } - } + unusedParameters = unusedParameters.filterTo(mutableMapOf()) { it.key !in localProperties } + } - private fun KtNamedFunction.isRelevant() = !isAllowedToHaveUnusedParameters() + private fun KtNamedFunction.isRelevant() = !isAllowedToHaveUnusedParameters() - private fun KtNamedFunction.isAllowedToHaveUnusedParameters() = - isAbstract() || isOpen() || isOverride() || isOperator() || isMainFunction() || isExternal() + private fun KtNamedFunction.isAllowedToHaveUnusedParameters() = + isAbstract() || isOpen() || isOverride() || isOperator() || isMainFunction() || isExternal() } private class UnusedPropertyVisitor(allowedNames: Regex) : UnusedMemberVisitor(allowedNames) { - private val properties = mutableSetOf() - private val nameAccesses = mutableSetOf() + private val properties = mutableSetOf() + private val nameAccesses = mutableSetOf() - override fun getUnusedReports(issue: Issue): List { - return properties - .filter { it.nameAsSafeName.identifier !in nameAccesses } - .map { CodeSmell(issue, Entity.from(it), "Private property ${it.nameAsSafeName.identifier} is unused.") } - } + override fun getUnusedReports(issue: Issue): List { + return properties + .filter { it.nameAsSafeName.identifier !in nameAccesses } + .map { CodeSmell(issue, Entity.from(it), "Private property ${it.nameAsSafeName.identifier} is unused.") } + } - override fun visitParameter(parameter: KtParameter) { - super.visitParameter(parameter) - if (parameter.isLoopParameter) { - val destructuringDeclaration = parameter.destructuringDeclaration - if (destructuringDeclaration != null) { - for (variable in destructuringDeclaration.entries) { - maybeAddUnusedProperty(variable) - } - } else { - maybeAddUnusedProperty(parameter) - } - } - } + override fun visitParameter(parameter: KtParameter) { + super.visitParameter(parameter) + if (parameter.isLoopParameter) { + val destructuringDeclaration = parameter.destructuringDeclaration + if (destructuringDeclaration != null) { + for (variable in destructuringDeclaration.entries) { + maybeAddUnusedProperty(variable) + } + } else { + maybeAddUnusedProperty(parameter) + } + } + } - override fun visitPrimaryConstructor(constructor: KtPrimaryConstructor) { - super.visitPrimaryConstructor(constructor) - constructor.valueParameters - .filter { it.isPrivate() || !it.hasValOrVar() } - .forEach { maybeAddUnusedProperty(it) } - } + override fun visitPrimaryConstructor(constructor: KtPrimaryConstructor) { + super.visitPrimaryConstructor(constructor) + constructor.valueParameters + .filter { it.isPrivate() || !it.hasValOrVar() } + .forEach { maybeAddUnusedProperty(it) } + } - override fun visitSecondaryConstructor(constructor: KtSecondaryConstructor) { - super.visitSecondaryConstructor(constructor) - constructor.valueParameters.forEach { maybeAddUnusedProperty(it) } - } + override fun visitSecondaryConstructor(constructor: KtSecondaryConstructor) { + super.visitSecondaryConstructor(constructor) + constructor.valueParameters.forEach { maybeAddUnusedProperty(it) } + } - private fun maybeAddUnusedProperty(it: KtNamedDeclaration) { - if (!allowedNames.matches(it.nameAsSafeName.identifier)) { - properties.add(it) - } - } + private fun maybeAddUnusedProperty(it: KtNamedDeclaration) { + if (!allowedNames.matches(it.nameAsSafeName.identifier)) { + properties.add(it) + } + } - override fun visitProperty(property: KtProperty) { - if (property.isPrivate() && property.isMemberOrTopLevel() || property.isLocal) { - maybeAddUnusedProperty(property) - } - super.visitProperty(property) - } + override fun visitProperty(property: KtProperty) { + if (property.isPrivate() && property.isMemberOrTopLevel() || property.isLocal) { + maybeAddUnusedProperty(property) + } + super.visitProperty(property) + } - private fun KtProperty.isMemberOrTopLevel() = isMember || isTopLevel + private fun KtProperty.isMemberOrTopLevel() = isMember || isTopLevel - override fun visitReferenceExpression(expression: KtReferenceExpression) { - nameAccesses.add(expression.text) - super.visitReferenceExpression(expression) - } + override fun visitReferenceExpression(expression: KtReferenceExpression) { + nameAccesses.add(expression.text) + super.visitReferenceExpression(expression) + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UseDataClass.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UseDataClass.kt index 080e9f15d..77f2d6193 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UseDataClass.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UseDataClass.kt @@ -49,68 +49,68 @@ import org.jetbrains.kotlin.psi.psiUtil.isPropertyParameter */ class UseDataClass(config: Config = Config.empty) : Rule(config) { - override val issue: Issue = Issue("UseDataClass", - Severity.Style, - "Classes that do nothing but hold data should be replaced with a data class.", - Debt.FIVE_MINS) + override val issue: Issue = Issue("UseDataClass", + Severity.Style, + "Classes that do nothing but hold data should be replaced with a data class.", + Debt.FIVE_MINS) - private val excludeAnnotatedClasses = SplitPattern(valueOrDefault(EXCLUDE_ANNOTATED_CLASSES, "")) - private val defaultFunctionNames = hashSetOf("hashCode", "equals", "toString", "copy") + private val excludeAnnotatedClasses = SplitPattern(valueOrDefault(EXCLUDE_ANNOTATED_CLASSES, "")) + private val defaultFunctionNames = hashSetOf("hashCode", "equals", "toString", "copy") - override fun visit(root: KtFile) { - super.visit(root) - val annotationExcluder = AnnotationExcluder(root, excludeAnnotatedClasses) - root.collectByType().forEach { visitKlass(it, annotationExcluder) } - } + override fun visit(root: KtFile) { + super.visit(root) + val annotationExcluder = AnnotationExcluder(root, excludeAnnotatedClasses) + root.collectByType().forEach { visitKlass(it, annotationExcluder) } + } - private fun visitKlass(klass: KtClass, annotationExcluder: AnnotationExcluder) { - if (isIncorrectClassType(klass) || hasOnlyPrivateConstructors(klass)) { - return - } - if (klass.isClosedForExtension() && klass.doesNotExtendAnything() && - !annotationExcluder.shouldExclude(klass.annotationEntries)) { - val declarations = klass.extractDeclarations() - val properties = declarations.filterIsInstance() - val functions = declarations.filterIsInstance() + private fun visitKlass(klass: KtClass, annotationExcluder: AnnotationExcluder) { + if (isIncorrectClassType(klass) || hasOnlyPrivateConstructors(klass)) { + return + } + if (klass.isClosedForExtension() && klass.doesNotExtendAnything() && + !annotationExcluder.shouldExclude(klass.annotationEntries)) { + val declarations = klass.extractDeclarations() + val properties = declarations.filterIsInstance() + val functions = declarations.filterIsInstance() - val propertyParameters = klass.extractConstructorPropertyParameters() + val propertyParameters = klass.extractConstructorPropertyParameters() - val containsFunctions = functions.none { !defaultFunctionNames.contains(it.name) } - val containsPropertyOrPropertyParameters = properties.isNotEmpty() || propertyParameters.isNotEmpty() + val containsFunctions = functions.none { !defaultFunctionNames.contains(it.name) } + val containsPropertyOrPropertyParameters = properties.isNotEmpty() || propertyParameters.isNotEmpty() - if (containsFunctions && containsPropertyOrPropertyParameters) { - report(CodeSmell(issue, Entity.from(klass), "The class ${klass.nameAsSafeName} defines no" + - "functionality and only holds data. Consider converting it to a data class.")) - } - } - } + if (containsFunctions && containsPropertyOrPropertyParameters) { + report(CodeSmell(issue, Entity.from(klass), "The class ${klass.nameAsSafeName} defines no" + + "functionality and only holds data. Consider converting it to a data class.")) + } + } + } - private fun isIncorrectClassType(klass: KtClass) = - klass.isData() || - klass.isEnum() || - klass.isAnnotation() || - klass.isSealed() || - klass.isInline() + private fun isIncorrectClassType(klass: KtClass) = + klass.isData() || + klass.isEnum() || + klass.isAnnotation() || + klass.isSealed() || + klass.isInline() - private fun hasOnlyPrivateConstructors(klass: KtClass): Boolean { - val primaryConstructor = klass.primaryConstructor - return (primaryConstructor == null || primaryConstructor.isPrivate()) && - klass.secondaryConstructors.all { it.isPrivate() } - } + private fun hasOnlyPrivateConstructors(klass: KtClass): Boolean { + val primaryConstructor = klass.primaryConstructor + return (primaryConstructor == null || primaryConstructor.isPrivate()) && + klass.secondaryConstructors.all { it.isPrivate() } + } - private fun KtClass.doesNotExtendAnything() = superTypeListEntries.isEmpty() + private fun KtClass.doesNotExtendAnything() = superTypeListEntries.isEmpty() - private fun KtClass.isClosedForExtension() = !isAbstract() && !isOpen() + private fun KtClass.isClosedForExtension() = !isAbstract() && !isOpen() - private fun KtClass.extractDeclarations(): List = body?.declarations.orEmpty() + private fun KtClass.extractDeclarations(): List = body?.declarations.orEmpty() - private fun KtClass.extractConstructorPropertyParameters(): List = - getPrimaryConstructorParameterList() - ?.parameters - ?.filter { it.isPropertyParameter() } - .orEmpty() + private fun KtClass.extractConstructorPropertyParameters(): List = + getPrimaryConstructorParameterList() + ?.parameters + ?.filter { it.isPropertyParameter() } + .orEmpty() - companion object { - const val EXCLUDE_ANNOTATED_CLASSES = "excludeAnnotatedClasses" - } + companion object { + const val EXCLUDE_ANNOTATED_CLASSES = "excludeAnnotatedClasses" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UtilityClassWithPublicConstructor.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UtilityClassWithPublicConstructor.kt index 52cf8e153..64598b338 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UtilityClassWithPublicConstructor.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UtilityClassWithPublicConstructor.kt @@ -62,65 +62,65 @@ import org.jetbrains.kotlin.psi.psiUtil.isPublic */ class UtilityClassWithPublicConstructor(config: Config = Config.empty) : Rule(config) { - override val issue: Issue = Issue(javaClass.simpleName, - Severity.Style, - "The class declaration is unnecessary because it only contains utility functions. " + - "An object declaration should be used instead.", - Debt.FIVE_MINS) + override val issue: Issue = Issue(javaClass.simpleName, + Severity.Style, + "The class declaration is unnecessary because it only contains utility functions. " + + "An object declaration should be used instead.", + Debt.FIVE_MINS) - override fun visitClass(klass: KtClass) { - if (!klass.isInterface() && - !klass.superTypeListEntries.any() && - !klass.isAnnotation()) { - val utilityClassConstructor = UtilityClassConstructor(klass) - val declarations = klass.body?.declarations - if (hasOnlyUtilityClassMembers(declarations)) { - if (utilityClassConstructor.hasPublicConstructorWithoutParameters()) { - report(CodeSmell(issue, Entity.from(klass), - "The class ${klass.nameAsSafeName} only contains" + - " utility functions. Consider defining it as an object.")) - } else if (klass.isOpen() && utilityClassConstructor.hasNonPublicConstructorWithoutParameters()) { - report(CodeSmell(issue, Entity.from(klass), - "The utility class ${klass.nameAsSafeName} should be final.")) - } - } - } - super.visitClass(klass) - } + override fun visitClass(klass: KtClass) { + if (!klass.isInterface() && + !klass.superTypeListEntries.any() && + !klass.isAnnotation()) { + val utilityClassConstructor = UtilityClassConstructor(klass) + val declarations = klass.body?.declarations + if (hasOnlyUtilityClassMembers(declarations)) { + if (utilityClassConstructor.hasPublicConstructorWithoutParameters()) { + report(CodeSmell(issue, Entity.from(klass), + "The class ${klass.nameAsSafeName} only contains" + + " utility functions. Consider defining it as an object.")) + } else if (klass.isOpen() && utilityClassConstructor.hasNonPublicConstructorWithoutParameters()) { + report(CodeSmell(issue, Entity.from(klass), + "The utility class ${klass.nameAsSafeName} should be final.")) + } + } + } + super.visitClass(klass) + } - private fun hasOnlyUtilityClassMembers(declarations: List?): Boolean { - if (declarations == null || declarations.isEmpty()) { - return false - } - var containsCompanionObject = false - var isUtilityClassCandidate = true - declarations.forEach { - if (isCompanionObject(it)) { - containsCompanionObject = true - } else if (it !is KtSecondaryConstructor && it !is KtClassInitializer) { - isUtilityClassCandidate = false - } - } - return containsCompanionObject && isUtilityClassCandidate - } + private fun hasOnlyUtilityClassMembers(declarations: List?): Boolean { + if (declarations == null || declarations.isEmpty()) { + return false + } + var containsCompanionObject = false + var isUtilityClassCandidate = true + declarations.forEach { + if (isCompanionObject(it)) { + containsCompanionObject = true + } else if (it !is KtSecondaryConstructor && it !is KtClassInitializer) { + isUtilityClassCandidate = false + } + } + return containsCompanionObject && isUtilityClassCandidate + } - private fun isCompanionObject(declaration: KtDeclaration) = - (declaration as? KtObjectDeclaration)?.isCompanion() == true + private fun isCompanionObject(declaration: KtDeclaration) = + (declaration as? KtObjectDeclaration)?.isCompanion() == true - internal class UtilityClassConstructor(private val klass: KtClass) { + internal class UtilityClassConstructor(private val klass: KtClass) { - internal fun hasPublicConstructorWithoutParameters() = hasConstructorWithoutParameters(true) + internal fun hasPublicConstructorWithoutParameters() = hasConstructorWithoutParameters(true) - internal fun hasNonPublicConstructorWithoutParameters() = hasConstructorWithoutParameters(false) + internal fun hasNonPublicConstructorWithoutParameters() = hasConstructorWithoutParameters(false) - private fun hasConstructorWithoutParameters(publicModifier: Boolean): Boolean { - val primaryConstructor = klass.primaryConstructor - if (primaryConstructor != null) { - return primaryConstructor.isPublic == publicModifier && primaryConstructor.valueParameters.isEmpty() - } - val secondaryConstructors = klass.secondaryConstructors - return secondaryConstructors.isEmpty() || - secondaryConstructors.any { it.isPublic == publicModifier && it.valueParameters.isEmpty() } - } - } + private fun hasConstructorWithoutParameters(publicModifier: Boolean): Boolean { + val primaryConstructor = klass.primaryConstructor + if (primaryConstructor != null) { + return primaryConstructor.isPublic == publicModifier && primaryConstructor.valueParameters.isEmpty() + } + val secondaryConstructors = klass.secondaryConstructors + return secondaryConstructors.isEmpty() || + secondaryConstructors.any { it.isPublic == publicModifier && it.valueParameters.isEmpty() } + } + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/VarCouldBeVal.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/VarCouldBeVal.kt index c5ea2e189..78ed96b33 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/VarCouldBeVal.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/VarCouldBeVal.kt @@ -43,93 +43,93 @@ private val unaryAssignmentOperators = setOf(KtTokens.MINUSMINUS, KtTokens.PLUSP */ class VarCouldBeVal(config: Config = Config.empty) : Rule(config) { - override val defaultRuleIdAliases: Set = setOf("CanBeVal") + override val defaultRuleIdAliases: Set = setOf("CanBeVal") - override val issue: Issue = Issue("VarCouldBeVal", - Severity.Maintainability, - "Var declaration could be val.", - Debt.FIVE_MINS) + override val issue: Issue = Issue("VarCouldBeVal", + Severity.Maintainability, + "Var declaration could be val.", + Debt.FIVE_MINS) - override fun visitNamedFunction(function: KtNamedFunction) { - if (function.isSomehowNested()) { - return - } + override fun visitNamedFunction(function: KtNamedFunction) { + if (function.isSomehowNested()) { + return + } - val assignmentVisitor = AssignmentVisitor() - function.accept(assignmentVisitor) + val assignmentVisitor = AssignmentVisitor() + function.accept(assignmentVisitor) - assignmentVisitor.getNonReAssignedDeclarations().forEach { - report(CodeSmell(issue, Entity.from(it), "Variable '${it.nameAsSafeName.identifier}' could be val.")) - } - super.visitNamedFunction(function) - } + assignmentVisitor.getNonReAssignedDeclarations().forEach { + report(CodeSmell(issue, Entity.from(it), "Variable '${it.nameAsSafeName.identifier}' could be val.")) + } + super.visitNamedFunction(function) + } - private fun KtNamedFunction.isSomehowNested() = - getStrictParentOfType() != null + private fun KtNamedFunction.isSomehowNested() = + getStrictParentOfType() != null - private class AssignmentVisitor : DetektVisitor() { + private class AssignmentVisitor : DetektVisitor() { - private val declarations = mutableSetOf() - // an easy way to find declarations when walking up the contexts of an assignment - private val contextsByDeclarationName = mutableMapOf>() - private val assignments = mutableMapOf>() + private val declarations = mutableSetOf() + // an easy way to find declarations when walking up the contexts of an assignment + private val contextsByDeclarationName = mutableMapOf>() + private val assignments = mutableMapOf>() - fun getNonReAssignedDeclarations(): List { - return declarations.filter { declaration -> - assignments[declaration.nameAsSafeName.identifier] - ?.let { declaration.parent !in it } - ?: true - } - } + fun getNonReAssignedDeclarations(): List { + return declarations.filter { declaration -> + assignments[declaration.nameAsSafeName.identifier] + ?.let { declaration.parent !in it } + ?: true + } + } - override fun visitProperty(property: KtProperty) { - if (property.isVar) { - declarations.add(property) - val identifier = property.nameAsSafeName.identifier - val contextsForName = contextsByDeclarationName.getOrPut(identifier) { mutableSetOf() } - contextsForName.add(property.parent) - } - super.visitProperty(property) - } + override fun visitProperty(property: KtProperty) { + if (property.isVar) { + declarations.add(property) + val identifier = property.nameAsSafeName.identifier + val contextsForName = contextsByDeclarationName.getOrPut(identifier) { mutableSetOf() } + contextsForName.add(property.parent) + } + super.visitProperty(property) + } - override fun visitUnaryExpression(expression: KtUnaryExpression) { - if (expression.operationToken in unaryAssignmentOperators) { - expression.baseExpression?.run { - visitAssignment(text, expression.parent) - } - } - super.visitUnaryExpression(expression) - } + override fun visitUnaryExpression(expression: KtUnaryExpression) { + if (expression.operationToken in unaryAssignmentOperators) { + expression.baseExpression?.run { + visitAssignment(text, expression.parent) + } + } + super.visitUnaryExpression(expression) + } - override fun visitBinaryExpression(expression: KtBinaryExpression) { - if (expression.operationToken in KtTokens.ALL_ASSIGNMENTS) { - val assignedName = extractAssignedName(expression) - if (assignedName != null) { - visitAssignment(assignedName, expression.parent) - } - } - super.visitBinaryExpression(expression) - } + override fun visitBinaryExpression(expression: KtBinaryExpression) { + if (expression.operationToken in KtTokens.ALL_ASSIGNMENTS) { + val assignedName = extractAssignedName(expression) + if (assignedName != null) { + visitAssignment(assignedName, expression.parent) + } + } + super.visitBinaryExpression(expression) + } - private fun extractAssignedName(expression: KtBinaryExpression): String? { - val leftSide = expression.left - if (leftSide is KtDotQualifiedExpression && - leftSide.receiverExpression is KtThisExpression) { - return leftSide.selectorExpression?.text - } - return leftSide?.text - } + private fun extractAssignedName(expression: KtBinaryExpression): String? { + val leftSide = expression.left + if (leftSide is KtDotQualifiedExpression && + leftSide.receiverExpression is KtThisExpression) { + return leftSide.selectorExpression?.text + } + return leftSide?.text + } - private fun visitAssignment(assignedName: String, context: PsiElement) { - val potentialContexts = contextsByDeclarationName[assignedName] - if (potentialContexts != null) { - val actualContextChain = generateSequence(context) { it.parent } - val actualContext = actualContextChain.firstOrNull { it in potentialContexts } - if (actualContext != null) { - val nameAssignments = assignments.getOrPut(assignedName) { mutableSetOf() } - nameAssignments.add(actualContext) - } - } - } - } + private fun visitAssignment(assignedName: String, context: PsiElement) { + val potentialContexts = contextsByDeclarationName[assignedName] + if (potentialContexts != null) { + val actualContextChain = generateSequence(context) { it.parent } + val actualContext = actualContextChain.firstOrNull { it in potentialContexts } + if (actualContext != null) { + val nameAssignments = assignments.getOrPut(assignedName) { mutableSetOf() } + nameAssignments.add(actualContext) + } + } + } + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/WildcardImport.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/WildcardImport.kt index 78f08a5c8..4bd8770b4 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/WildcardImport.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/WildcardImport.kt @@ -48,32 +48,32 @@ import org.jetbrains.kotlin.psi.KtImportDirective */ class WildcardImport(config: Config = Config.empty) : Rule(config) { - override val issue = Issue(javaClass.simpleName, - Severity.Style, - "Wildcard imports should be replaced with imports using fully qualified class names. " + - "Wildcard imports can lead to naming conflicts. " + - "A library update can introduce naming clashes with your classes which " + - "results in compilation errors.", - Debt.FIVE_MINS) + override val issue = Issue(javaClass.simpleName, + Severity.Style, + "Wildcard imports should be replaced with imports using fully qualified class names. " + + "Wildcard imports can lead to naming conflicts. " + + "A library update can introduce naming clashes with your classes which " + + "results in compilation errors.", + Debt.FIVE_MINS) - private val excludedImports = SplitPattern(valueOrDefault(EXCLUDED_IMPORTS, "")) + private val excludedImports = SplitPattern(valueOrDefault(EXCLUDED_IMPORTS, "")) - override fun visitImportDirective(importDirective: KtImportDirective) { - val import = importDirective.importPath?.pathStr - import?.let { - if (!import.contains("*")) { - return - } + override fun visitImportDirective(importDirective: KtImportDirective) { + val import = importDirective.importPath?.pathStr + import?.let { + if (!import.contains("*")) { + return + } - if (excludedImports.contains(import)) { - return - } - report(CodeSmell(issue, Entity.from(importDirective), "$it " + - "is a wildcard import. Replace it with fully qualified imports.")) - } - } + if (excludedImports.contains(import)) { + return + } + report(CodeSmell(issue, Entity.from(importDirective), "$it " + + "is a wildcard import. Replace it with fully qualified imports.")) + } + } - companion object { - const val EXCLUDED_IMPORTS = "excludeImports" - } + companion object { + const val EXCLUDED_IMPORTS = "excludeImports" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/optional/ConditionalPathVisitor.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/optional/ConditionalPathVisitor.kt index f09983391..37e130fb9 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/optional/ConditionalPathVisitor.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/optional/ConditionalPathVisitor.kt @@ -15,49 +15,49 @@ import org.jetbrains.kotlin.psi.KtWhenExpression */ class ConditionalPathVisitor(private val block: (KtReturnExpression) -> Unit) : DetektVisitor() { - override fun visitIfExpression(expression: KtIfExpression) { - if (expression.isLastStatement()) { - expression.then?.checkIfReturnStatement() - expression.`else`?.checkIfReturnStatement() - } - super.visitIfExpression(expression) - } + override fun visitIfExpression(expression: KtIfExpression) { + if (expression.isLastStatement()) { + expression.then?.checkIfReturnStatement() + expression.`else`?.checkIfReturnStatement() + } + super.visitIfExpression(expression) + } - override fun visitTryExpression(expression: KtTryExpression) { - if (expression.isLastStatement()) { - expression.tryBlock.checkIfReturnStatement() - expression.catchClauses.forEach { - it.catchBody?.checkIfReturnStatement() - } - } - super.visitTryExpression(expression) - } + override fun visitTryExpression(expression: KtTryExpression) { + if (expression.isLastStatement()) { + expression.tryBlock.checkIfReturnStatement() + expression.catchClauses.forEach { + it.catchBody?.checkIfReturnStatement() + } + } + super.visitTryExpression(expression) + } - override fun visitWhenExpression(expression: KtWhenExpression) { - if (expression.isLastStatement()) { - expression.entries.forEach { - it.expression?.checkIfReturnStatement() - } - } - super.visitWhenExpression(expression) - } + override fun visitWhenExpression(expression: KtWhenExpression) { + if (expression.isLastStatement()) { + expression.entries.forEach { + it.expression?.checkIfReturnStatement() + } + } + super.visitWhenExpression(expression) + } - private fun KtExpression.isLastStatement(): Boolean { - val parent = parent - parent is KtBlockExpression - return when (parent) { - is KtReturnExpression, is KtProperty -> true - is KtDeclarationWithBody -> parent.bodyExpression == this - is KtBlockExpression -> parent.statements.lastOrNull()?.let { it == this } == true - else -> false - } - } + private fun KtExpression.isLastStatement(): Boolean { + val parent = parent + parent is KtBlockExpression + return when (parent) { + is KtReturnExpression, is KtProperty -> true + is KtDeclarationWithBody -> parent.bodyExpression == this + is KtBlockExpression -> parent.statements.lastOrNull()?.let { it == this } == true + else -> false + } + } - private fun KtExpression.checkIfReturnStatement() { - if (this is KtReturnExpression && this.returnedExpression != null) block(this) - else if (this is KtBlockExpression) { - val last = this.statements.lastOrNull() - if (last is KtReturnExpression && last.returnedExpression != null) block(last) - } - } + private fun KtExpression.checkIfReturnStatement() { + if (this is KtReturnExpression && this.returnedExpression != null) block(this) + else if (this is KtBlockExpression) { + val last = this.statements.lastOrNull() + if (last is KtReturnExpression && last.returnedExpression != null) block(last) + } + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/optional/MandatoryBracesIfStatements.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/optional/MandatoryBracesIfStatements.kt index 2574f9350..020ab56e7 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/optional/MandatoryBracesIfStatements.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/optional/MandatoryBracesIfStatements.kt @@ -31,42 +31,42 @@ import org.jetbrains.kotlin.psi.psiUtil.siblings */ class MandatoryBracesIfStatements(config: Config = Config.empty) : Rule(config) { - override val issue = Issue("MandatoryBracesIfStatements", Severity.Style, - "Multi-line if statement was found that does not have braces. " + - "These should be added to improve readability.", - Debt.FIVE_MINS) + override val issue = Issue("MandatoryBracesIfStatements", Severity.Style, + "Multi-line if statement was found that does not have braces. " + + "These should be added to improve readability.", + Debt.FIVE_MINS) - override fun visitIfExpression(expression: KtIfExpression) { - if (isNotBlockExpression(expression) && hasNewLine(expression)) { - report(CodeSmell(issue, Entity.from(expression), - message = "Multi-line if statement was found that does not have braces. " + - "These should be added to improve readability.")) - } + override fun visitIfExpression(expression: KtIfExpression) { + if (isNotBlockExpression(expression) && hasNewLine(expression)) { + report(CodeSmell(issue, Entity.from(expression), + message = "Multi-line if statement was found that does not have braces. " + + "These should be added to improve readability.")) + } - if (isNotBlockOrIfExpression(expression) && hasNewLine(expression.elseKeyword)) { - report(CodeSmell(issue, Entity.from(expression), - message = "Multi-line else statement was found that does not have braces." + - "These should be added to improve readability")) - } + if (isNotBlockOrIfExpression(expression) && hasNewLine(expression.elseKeyword)) { + report(CodeSmell(issue, Entity.from(expression), + message = "Multi-line else statement was found that does not have braces." + + "These should be added to improve readability")) + } - super.visitIfExpression(expression) - } + super.visitIfExpression(expression) + } - private fun hasNewLine(expression: KtIfExpression): Boolean = - expression.rightParenthesis?.siblings(true, false) - ?.filterIsInstance() - ?.firstOrNull { it.textContains('\n') } != null + private fun hasNewLine(expression: KtIfExpression): Boolean = + expression.rightParenthesis?.siblings(true, false) + ?.filterIsInstance() + ?.firstOrNull { it.textContains('\n') } != null - private fun hasNewLine(element: PsiElement?): Boolean = - element?.siblings(true, false) - ?.filterIsInstance() - ?.firstOrNull { it.textContains('\n') } != null + private fun hasNewLine(element: PsiElement?): Boolean = + element?.siblings(true, false) + ?.filterIsInstance() + ?.firstOrNull { it.textContains('\n') } != null - private fun isNotBlockExpression(expression: KtIfExpression): Boolean = - expression.then !is KtBlockExpression + private fun isNotBlockExpression(expression: KtIfExpression): Boolean = + expression.then !is KtBlockExpression - private fun isNotBlockOrIfExpression(expression: KtIfExpression): Boolean = - expression.`else` != null && - expression.`else` !is KtIfExpression && - expression.`else` !is KtBlockExpression + private fun isNotBlockOrIfExpression(expression: KtIfExpression): Boolean = + expression.`else` != null && + expression.`else` !is KtIfExpression && + expression.`else` !is KtBlockExpression } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/optional/OptionalUnit.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/optional/OptionalUnit.kt index f86e2a819..9d3f0ae5d 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/optional/OptionalUnit.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/optional/OptionalUnit.kt @@ -43,57 +43,57 @@ import org.jetbrains.kotlin.psi.KtNamedFunction */ class OptionalUnit(config: Config = Config.empty) : Rule(config) { - override val issue = Issue( - javaClass.simpleName, - Severity.Style, - "Return type of 'Unit' is unnecessary and can be safely removed.", - Debt.FIVE_MINS) + override val issue = Issue( + javaClass.simpleName, + Severity.Style, + "Return type of 'Unit' is unnecessary and can be safely removed.", + Debt.FIVE_MINS) - override fun visitNamedFunction(function: KtNamedFunction) { - if (function.funKeyword == null) return - if (isInInterface(function)) return - if (function.hasDeclaredReturnType() && function.colon != null) { - checkFunctionWithExplicitReturnType(function) - } else if (!function.isOverride()) { - checkFunctionWithInferredReturnType(function) - } - super.visitNamedFunction(function) - } + override fun visitNamedFunction(function: KtNamedFunction) { + if (function.funKeyword == null) return + if (isInInterface(function)) return + if (function.hasDeclaredReturnType() && function.colon != null) { + checkFunctionWithExplicitReturnType(function) + } else if (!function.isOverride()) { + checkFunctionWithInferredReturnType(function) + } + super.visitNamedFunction(function) + } - override fun visitBlockExpression(expression: KtBlockExpression) { - expression.statements - .filter { it is KtNameReferenceExpression && it.text == UNIT } - .onEach { - report(CodeSmell(issue, Entity.from(expression), - "A single Unit expression is unnecessary and can safely be removed")) - } - super.visitBlockExpression(expression) - } + override fun visitBlockExpression(expression: KtBlockExpression) { + expression.statements + .filter { it is KtNameReferenceExpression && it.text == UNIT } + .onEach { + report(CodeSmell(issue, Entity.from(expression), + "A single Unit expression is unnecessary and can safely be removed")) + } + super.visitBlockExpression(expression) + } - private fun checkFunctionWithExplicitReturnType(function: KtNamedFunction) { - val typeReference = function.typeReference - val typeElementText = typeReference?.typeElement?.text - if (typeElementText == UNIT) { - report(CodeSmell(issue, Entity.from(typeReference), createMessage(function))) - } - } + private fun checkFunctionWithExplicitReturnType(function: KtNamedFunction) { + val typeReference = function.typeReference + val typeElementText = typeReference?.typeElement?.text + if (typeElementText == UNIT) { + report(CodeSmell(issue, Entity.from(typeReference), createMessage(function))) + } + } - private fun checkFunctionWithInferredReturnType(function: KtNamedFunction) { - val referenceExpression = function.bodyExpression as? KtNameReferenceExpression - if (referenceExpression != null && referenceExpression.text == UNIT) { - report(CodeSmell(issue, Entity.from(referenceExpression), createMessage(function))) - } - } + private fun checkFunctionWithInferredReturnType(function: KtNamedFunction) { + val referenceExpression = function.bodyExpression as? KtNameReferenceExpression + if (referenceExpression != null && referenceExpression.text == UNIT) { + report(CodeSmell(issue, Entity.from(referenceExpression), createMessage(function))) + } + } - private fun isInInterface(function: KtNamedFunction): Boolean { - val parent = PsiTreeUtil.getParentOfType(function, KtClass::class.java, true) - return parent is KtClass && parent.isInterface() - } + private fun isInInterface(function: KtNamedFunction): Boolean { + val parent = PsiTreeUtil.getParentOfType(function, KtClass::class.java, true) + return parent is KtClass && parent.isInterface() + } - private fun createMessage(function: KtNamedFunction) = "The function ${function.name} " + - "defines a return type of Unit. This is unnecessary and can safely be removed." + private fun createMessage(function: KtNamedFunction) = "The function ${function.name} " + + "defines a return type of Unit. This is unnecessary and can safely be removed." - companion object { - private const val UNIT = "Unit" - } + companion object { + private const val UNIT = "Unit" + } } diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/optional/PreferToOverPairSyntax.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/optional/PreferToOverPairSyntax.kt index 281d38283..6ed62cb9b 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/optional/PreferToOverPairSyntax.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/optional/PreferToOverPairSyntax.kt @@ -27,25 +27,25 @@ import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElementOrCallableRef * @author jkaan */ class PreferToOverPairSyntax(config: Config = Config.empty) : Rule(config) { - override val issue = Issue("PreferToOverPairSyntax", Severity.Style, - "Pair was created using the Pair constructor, using the to syntax is preferred.", - Debt.FIVE_MINS) + override val issue = Issue("PreferToOverPairSyntax", Severity.Style, + "Pair was created using the Pair constructor, using the to syntax is preferred.", + Debt.FIVE_MINS) - override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) { - val callReference = expression.getQualifiedElementOrCallableRef() - if (expression.getReferencedName() == PAIR_CONSTRUCTOR_REFERENCE_NAME && - callReference is KtCallExpression) { - val (firstArg, secondArg) = callReference.valueArguments.map { it.text } + override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) { + val callReference = expression.getQualifiedElementOrCallableRef() + if (expression.getReferencedName() == PAIR_CONSTRUCTOR_REFERENCE_NAME && + callReference is KtCallExpression) { + val (firstArg, secondArg) = callReference.valueArguments.map { it.text } - report(CodeSmell(issue, Entity.from(expression), - message = "Pair is created by using the pair constructor. " + - "This can replaced by `$firstArg to $secondArg`")) - } + report(CodeSmell(issue, Entity.from(expression), + message = "Pair is created by using the pair constructor. " + + "This can replaced by `$firstArg to $secondArg`")) + } - super.visitSimpleNameExpression(expression) - } + super.visitSimpleNameExpression(expression) + } - companion object { - const val PAIR_CONSTRUCTOR_REFERENCE_NAME = "Pair" - } + companion object { + const val PAIR_CONSTRUCTOR_REFERENCE_NAME = "Pair" + } } diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/Case.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/Case.kt index 3be39ba6f..8ab87b7f6 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/Case.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/Case.kt @@ -10,93 +10,93 @@ import java.nio.file.Paths * @author Artur Bosch */ enum class Case(val file: String) { - CasesFolder("/cases"), - CollapsibleIfsPositive("/cases/CollapsibleIfsPositive.kt"), - CollapsibleIfsNegative("/cases/CollapsibleIfsNegative.kt"), - ComplexMethods("/cases/ComplexMethods.kt"), - ConditionalPath("/cases/ConditionalPath.kt"), - ConstInObjects("/cases/ConstInObjects.kt"), - DataClassContainsFunctionsPositive("/cases/DataClassContainsFunctionsPositive.kt"), - DataClassContainsFunctionsNegative("/cases/DataClassContainsFunctionsNegative.kt"), - Default("/cases/Default.kt"), - Empty("/cases/Empty.kt"), - EmptyKtFile("/cases/EmptyKtFile.kt"), - EmptyIfPositive("/cases/EmptyIfPositive.kt"), - EmptyIfNegative("/cases/EmptyIfNegative.kt"), - EmptyDefaultConstructorNegative("/cases/EmptyDefaultConstructorNegative.kt"), - EmptyDefaultConstructorPositive("/cases/EmptyDefaultConstructorPositive.kt"), - EqualsAlwaysReturnsTrueOrFalsePositive("/cases/EqualsAlwaysReturnsTrueOrFalsePositive.kt"), - EqualsAlwaysReturnsTrueOrFalseNegative("/cases/EqualsAlwaysReturnsTrueOrFalseNegative.kt"), - TooGenericExceptions("/cases/TooGenericExceptions.kt"), - TooGenericExceptionsOptions("/cases/TooGenericExceptionsOptions.kt"), - ExceptionRaisedInMethodsNegative("/cases/ExceptionRaisedInMethodsNegative.kt"), - ExceptionRaisedInMethodsPositive("/cases/ExceptionRaisedInMethodsPositive.kt"), - FinalClassNegative("/cases/ProtectedMemberInFinalClassNegative.kt"), - FinalClassPositive("/cases/ProtectedMemberInFinalClassPositive.kt"), - FunctionReturningConstantPositive("/cases/FunctionReturningConstantPositive.kt"), - FunctionReturningConstantNegative("/cases/FunctionReturningConstantNegative.kt"), - IteratorImplNegative("/cases/IteratorImplNegative.kt"), - IteratorImplPositive("/cases/IteratorImplPositive.kt"), - LabeledExpressionNegative("/cases/LabeledExpressionNegative.kt"), - LabeledExpressionPositive("/cases/LabeledExpressionPositive.kt"), - LoopWithTooManyJumpStatementsNegative("cases/LoopWithTooManyJumpStatementsNegative.kt"), - LoopWithTooManyJumpStatementsPositive("cases/LoopWithTooManyJumpStatementsPositive.kt"), - MayBeConstNegative("cases/MayBeConstNegative.kt"), - MandatoryBracesIfStatementsPositive("cases/MandatoryBracesIfStatementsPositive.kt"), - MandatoryBracesIfStatementsNegative("cases/MandatoryBracesIfStatementsNegative.kt"), - NamingConventions("/cases/NamingConventions.kt"), - NewLineAtEndOfFile("/cases/NewLineAtEndOfFile.kt"), - MaxLineLength("/cases/MaxLineLength.kt"), - MaxLineLengthSuppressed("/cases/MaxLineLengthSuppressed.kt"), - MaxLineLengthWithLongComments("/cases/MaxLineLengthWithLongComments.kt"), - MemberNameEqualsClassNameNegative("/cases/MemberNameEqualsClassNameNegative.kt"), - MemberNameEqualsClassNamePositive("/cases/MemberNameEqualsClassNamePositive.kt"), - MultilineStringLiteralDuplication("/cases/MultilineStringLiteralDuplication.kt"), - OverloadedMethods("/cases/OverloadedMethods.kt"), - ComplexClass("/cases/ComplexClass.kt"), - ComplexInterfaceNegative("/cases/ComplexInterfaceNegative.kt"), - ComplexInterfacePositive("/cases/ComplexInterfacePositive.kt"), - NestedClasses("/cases/NestedClasses.kt"), - NoClasses("/cases/NoClasses.kt"), - LongMethodPositive("/cases/LongMethodPositive.kt"), - LongMethodNegative("/cases/LongMethodNegative.kt"), - UnreachableCode("/cases/UnreachableCode.kt"), - UnnecessaryAbstractClassPositive("/cases/UnnecessaryAbstractClassPositive.kt"), - UnnecessaryAbstractClassNegative("/cases/UnnecessaryAbstractClassNegative.kt"), - UtilityClassesPositive("/cases/UtilityClassesPositive.kt"), - UtilityClassesNegative("/cases/UtilityClassesNegative.kt"), - RethrowCaughtExceptionPositive("/cases/RethrowCaughtExceptionPositive.kt"), - RethrowCaughtExceptionNegative("/cases/RethrowCaughtExceptionNegative.kt"), - SerializablePositive("/cases/SerializablePositive.kt"), - SerializableNegative("/cases/SerializableNegative.kt"), - SuppressedElements("/SuppressedByElementAnnotation.kt"), - SuppressedElementsByFile("/SuppressedElementsByFileAnnotation.kt"), - SuppressedElementsByClass("/SuppressedElementsByClassAnnotation.kt"), - SuppressStringLiteralDuplication("/SuppressStringLiteralDuplication.kt"), - SwallowedExceptionNegative("/cases/SwallowedExceptionNegative.kt"), - SwallowedExceptionPositive("/cases/SwallowedExceptionPositive.kt"), - TooManyFunctions("/cases/TooManyFunctions.kt"), - TooManyFunctionsTopLevel("/cases/TooManyFunctionsTopLevel.kt"), - UseDataClassNegative("/cases/UseDataClassNegative.kt"), - UseDataClassPositive("/cases/UseDataClassPositive.kt"), - UnconditionalJumpStatementInLoopNegative("/cases/UnconditionalJumpStatementInLoopNegative.kt"), - UnconditionalJumpStatementInLoopPositive("/cases/UnconditionalJumpStatementInLoopPositive.kt"), - NestedClassVisibilityPositive("/cases/NestedClassVisibilityPositive.kt"), - NestedClassVisibilityNegative("/cases/NestedClassVisibilityNegative.kt"), - TrailingWhitespaceNegative("/cases/TrailingWhitespaceNegative.kt"), - TrailingWhitespacePositive("/cases/TrailingWhitespacePositive.kt"), - NoTabsNegative("/cases/NoTabsNegative.kt"), - NoTabsPositive("/cases/NoTabsPositive.kt"), - UnusedPrivateMemberPositive("/cases/UnusedPrivateMemberPositive.kt"), - UnusedPrivateMemberNegative("/cases/UnusedPrivateMemberNegative.kt"), - PreferToOverPairSyntaxPositive("/cases/PreferToOverPairSyntaxPositive.kt"), - PreferToOverPairSyntaxNegative("/cases/PreferToOverPairSyntaxNegative.kt"); + CasesFolder("/cases"), + CollapsibleIfsPositive("/cases/CollapsibleIfsPositive.kt"), + CollapsibleIfsNegative("/cases/CollapsibleIfsNegative.kt"), + ComplexMethods("/cases/ComplexMethods.kt"), + ConditionalPath("/cases/ConditionalPath.kt"), + ConstInObjects("/cases/ConstInObjects.kt"), + DataClassContainsFunctionsPositive("/cases/DataClassContainsFunctionsPositive.kt"), + DataClassContainsFunctionsNegative("/cases/DataClassContainsFunctionsNegative.kt"), + Default("/cases/Default.kt"), + Empty("/cases/Empty.kt"), + EmptyKtFile("/cases/EmptyKtFile.kt"), + EmptyIfPositive("/cases/EmptyIfPositive.kt"), + EmptyIfNegative("/cases/EmptyIfNegative.kt"), + EmptyDefaultConstructorNegative("/cases/EmptyDefaultConstructorNegative.kt"), + EmptyDefaultConstructorPositive("/cases/EmptyDefaultConstructorPositive.kt"), + EqualsAlwaysReturnsTrueOrFalsePositive("/cases/EqualsAlwaysReturnsTrueOrFalsePositive.kt"), + EqualsAlwaysReturnsTrueOrFalseNegative("/cases/EqualsAlwaysReturnsTrueOrFalseNegative.kt"), + TooGenericExceptions("/cases/TooGenericExceptions.kt"), + TooGenericExceptionsOptions("/cases/TooGenericExceptionsOptions.kt"), + ExceptionRaisedInMethodsNegative("/cases/ExceptionRaisedInMethodsNegative.kt"), + ExceptionRaisedInMethodsPositive("/cases/ExceptionRaisedInMethodsPositive.kt"), + FinalClassNegative("/cases/ProtectedMemberInFinalClassNegative.kt"), + FinalClassPositive("/cases/ProtectedMemberInFinalClassPositive.kt"), + FunctionReturningConstantPositive("/cases/FunctionReturningConstantPositive.kt"), + FunctionReturningConstantNegative("/cases/FunctionReturningConstantNegative.kt"), + IteratorImplNegative("/cases/IteratorImplNegative.kt"), + IteratorImplPositive("/cases/IteratorImplPositive.kt"), + LabeledExpressionNegative("/cases/LabeledExpressionNegative.kt"), + LabeledExpressionPositive("/cases/LabeledExpressionPositive.kt"), + LoopWithTooManyJumpStatementsNegative("cases/LoopWithTooManyJumpStatementsNegative.kt"), + LoopWithTooManyJumpStatementsPositive("cases/LoopWithTooManyJumpStatementsPositive.kt"), + MayBeConstNegative("cases/MayBeConstNegative.kt"), + MandatoryBracesIfStatementsPositive("cases/MandatoryBracesIfStatementsPositive.kt"), + MandatoryBracesIfStatementsNegative("cases/MandatoryBracesIfStatementsNegative.kt"), + NamingConventions("/cases/NamingConventions.kt"), + NewLineAtEndOfFile("/cases/NewLineAtEndOfFile.kt"), + MaxLineLength("/cases/MaxLineLength.kt"), + MaxLineLengthSuppressed("/cases/MaxLineLengthSuppressed.kt"), + MaxLineLengthWithLongComments("/cases/MaxLineLengthWithLongComments.kt"), + MemberNameEqualsClassNameNegative("/cases/MemberNameEqualsClassNameNegative.kt"), + MemberNameEqualsClassNamePositive("/cases/MemberNameEqualsClassNamePositive.kt"), + MultilineStringLiteralDuplication("/cases/MultilineStringLiteralDuplication.kt"), + OverloadedMethods("/cases/OverloadedMethods.kt"), + ComplexClass("/cases/ComplexClass.kt"), + ComplexInterfaceNegative("/cases/ComplexInterfaceNegative.kt"), + ComplexInterfacePositive("/cases/ComplexInterfacePositive.kt"), + NestedClasses("/cases/NestedClasses.kt"), + NoClasses("/cases/NoClasses.kt"), + LongMethodPositive("/cases/LongMethodPositive.kt"), + LongMethodNegative("/cases/LongMethodNegative.kt"), + UnreachableCode("/cases/UnreachableCode.kt"), + UnnecessaryAbstractClassPositive("/cases/UnnecessaryAbstractClassPositive.kt"), + UnnecessaryAbstractClassNegative("/cases/UnnecessaryAbstractClassNegative.kt"), + UtilityClassesPositive("/cases/UtilityClassesPositive.kt"), + UtilityClassesNegative("/cases/UtilityClassesNegative.kt"), + RethrowCaughtExceptionPositive("/cases/RethrowCaughtExceptionPositive.kt"), + RethrowCaughtExceptionNegative("/cases/RethrowCaughtExceptionNegative.kt"), + SerializablePositive("/cases/SerializablePositive.kt"), + SerializableNegative("/cases/SerializableNegative.kt"), + SuppressedElements("/SuppressedByElementAnnotation.kt"), + SuppressedElementsByFile("/SuppressedElementsByFileAnnotation.kt"), + SuppressedElementsByClass("/SuppressedElementsByClassAnnotation.kt"), + SuppressStringLiteralDuplication("/SuppressStringLiteralDuplication.kt"), + SwallowedExceptionNegative("/cases/SwallowedExceptionNegative.kt"), + SwallowedExceptionPositive("/cases/SwallowedExceptionPositive.kt"), + TooManyFunctions("/cases/TooManyFunctions.kt"), + TooManyFunctionsTopLevel("/cases/TooManyFunctionsTopLevel.kt"), + UseDataClassNegative("/cases/UseDataClassNegative.kt"), + UseDataClassPositive("/cases/UseDataClassPositive.kt"), + UnconditionalJumpStatementInLoopNegative("/cases/UnconditionalJumpStatementInLoopNegative.kt"), + UnconditionalJumpStatementInLoopPositive("/cases/UnconditionalJumpStatementInLoopPositive.kt"), + NestedClassVisibilityPositive("/cases/NestedClassVisibilityPositive.kt"), + NestedClassVisibilityNegative("/cases/NestedClassVisibilityNegative.kt"), + TrailingWhitespaceNegative("/cases/TrailingWhitespaceNegative.kt"), + TrailingWhitespacePositive("/cases/TrailingWhitespacePositive.kt"), + NoTabsNegative("/cases/NoTabsNegative.kt"), + NoTabsPositive("/cases/NoTabsPositive.kt"), + UnusedPrivateMemberPositive("/cases/UnusedPrivateMemberPositive.kt"), + UnusedPrivateMemberNegative("/cases/UnusedPrivateMemberNegative.kt"), + PreferToOverPairSyntaxPositive("/cases/PreferToOverPairSyntaxPositive.kt"), + PreferToOverPairSyntaxNegative("/cases/PreferToOverPairSyntaxNegative.kt"); - fun path(): Path = Paths.get(resource(file)) + fun path(): Path = Paths.get(resource(file)) - fun getKtFileContent(): KtFileContent { - val file = compileForTest(path()) - val lines = file.text.splitToSequence("\n") - return KtFileContent(file, lines) - } + fun getKtFileContent(): KtFileContent { + val file = compileForTest(path()) + val lines = file.text.splitToSequence("\n") + return KtFileContent(file, lines) + } } diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/CommonSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/CommonSpec.kt index e8eb16c2f..f7e1bf70f 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/CommonSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/CommonSpec.kt @@ -13,13 +13,13 @@ import org.jetbrains.spek.subject.SubjectSpek * @author Artur Bosch */ class CommonSpec : SubjectSpek({ - subject { WildcardImport() } - val file = compileForTest(Case.Default.path()) + subject { WildcardImport() } + val file = compileForTest(Case.Default.path()) - describe("running specified rule") { - it("should detect one finding") { - subject.lint(file.text) - assertThat(subject.findings).hasSize(1) - } - } + describe("running specified rule") { + it("should detect one finding") { + subject.lint(file.text) + assertThat(subject.findings).hasSize(1) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/RuleProviderTest.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/RuleProviderTest.kt index 78a64d24b..9c7da292d 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/RuleProviderTest.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/RuleProviderTest.kt @@ -13,109 +13,110 @@ import io.gitlab.arturbosch.detekt.rules.providers.NamingProvider import io.gitlab.arturbosch.detekt.rules.providers.PerformanceProvider import io.gitlab.arturbosch.detekt.rules.providers.PotentialBugProvider import io.gitlab.arturbosch.detekt.rules.providers.StyleGuideProvider +import java.lang.reflect.Modifier import org.assertj.core.api.Assertions.assertThat import org.jetbrains.spek.api.Spek import org.jetbrains.spek.api.dsl.it import org.reflections.Reflections -import java.lang.reflect.Modifier class RuleProviderTest : Spek({ - it("commentSmellProvider") { - RuleProviderAssert( - CommentSmellProvider(), - "io.gitlab.arturbosch.detekt.rules.documentation", - Rule::class.java) - .assert() - } + it("commentSmellProvider") { + RuleProviderAssert( + CommentSmellProvider(), + "io.gitlab.arturbosch.detekt.rules.documentation", + Rule::class.java) + .assert() + } - it("complexityProvider") { - RuleProviderAssert( - ComplexityProvider(), - "io.gitlab.arturbosch.detekt.rules.complexity", - Rule::class.java) - .assert() - } + it("complexityProvider") { + RuleProviderAssert( + ComplexityProvider(), + "io.gitlab.arturbosch.detekt.rules.complexity", + Rule::class.java) + .assert() + } - it("emptyCodeProvider") { - RuleProviderAssert( - EmptyCodeProvider(), - "io.gitlab.arturbosch.detekt.rules.empty", - Rule::class.java) - .assert() - } + it("emptyCodeProvider") { + RuleProviderAssert( + EmptyCodeProvider(), + "io.gitlab.arturbosch.detekt.rules.empty", + Rule::class.java) + .assert() + } - it("exceptionsProvider") { - RuleProviderAssert( - ExceptionsProvider(), - "io.gitlab.arturbosch.detekt.rules.exceptions", - Rule::class.java) - .assert() - } + it("exceptionsProvider") { + RuleProviderAssert( + ExceptionsProvider(), + "io.gitlab.arturbosch.detekt.rules.exceptions", + Rule::class.java) + .assert() + } - it("namingProvider") { - RuleProviderAssert( - NamingProvider(), - "io.gitlab.arturbosch.detekt.rules.naming", - Rule::class.java) - .assert() - } + it("namingProvider") { + RuleProviderAssert( + NamingProvider(), + "io.gitlab.arturbosch.detekt.rules.naming", + Rule::class.java) + .assert() + } - it("performanceProvider") { - RuleProviderAssert( - PerformanceProvider(), - "io.gitlab.arturbosch.detekt.rules.performance", - Rule::class.java) - .assert() - } + it("performanceProvider") { + RuleProviderAssert( + PerformanceProvider(), + "io.gitlab.arturbosch.detekt.rules.performance", + Rule::class.java) + .assert() + } - it("potentialBugProvider") { - RuleProviderAssert( - PotentialBugProvider(), - "io.gitlab.arturbosch.detekt.rules.bugs", - Rule::class.java) - .assert() - } - - it("styleGuideProvider") { - RuleProviderAssert( - StyleGuideProvider(), - "io.gitlab.arturbosch.detekt.rules.style", - Rule::class.java) - .assert() - } + it("potentialBugProvider") { + RuleProviderAssert( + PotentialBugProvider(), + "io.gitlab.arturbosch.detekt.rules.bugs", + Rule::class.java) + .assert() + } + it("styleGuideProvider") { + RuleProviderAssert( + StyleGuideProvider(), + "io.gitlab.arturbosch.detekt.rules.style", + Rule::class.java) + .assert() + } }) -private class RuleProviderAssert(private val provider: RuleSetProvider, - private val packageName: String, - private val clazz: Class) { +private class RuleProviderAssert( + private val provider: RuleSetProvider, + private val packageName: String, + private val clazz: Class +) { - fun assert() { - val rules = getRules(provider) - assertThat(rules).isNotEmpty - val classes = getClasses() - assertThat(classes).isNotEmpty - classes - .map { c -> rules.singleOrNull { it.javaClass.simpleName == c.simpleName } } - .forEach { - if (it == null) { - print(rules.size); println(" rules") - print(classes.size); print(" classes") - } - assertThat(it).isNotNull() - } - } + fun assert() { + val rules = getRules(provider) + assertThat(rules).isNotEmpty + val classes = getClasses() + assertThat(classes).isNotEmpty + classes + .map { c -> rules.singleOrNull { it.javaClass.simpleName == c.simpleName } } + .forEach { + if (it == null) { + print(rules.size); println(" rules") + print(classes.size); print(" classes") + } + assertThat(it).isNotNull() + } + } - private fun getRules(provider: RuleSetProvider): List { - return provider.buildRuleset(Config.empty)!!.rules - .flatMap { (it as? MultiRule)?.rules ?: listOf(it) } - } + private fun getRules(provider: RuleSetProvider): List { + return provider.buildRuleset(Config.empty)!!.rules + .flatMap { (it as? MultiRule)?.rules ?: listOf(it) } + } - private fun getClasses(): List> { - return Reflections(packageName) - .getSubTypesOf(clazz) - .filterNot { "Test" in it.name } - .filter { !Modifier.isAbstract(it.modifiers) && !Modifier.isStatic(it.modifiers) } - } + private fun getClasses(): List> { + return Reflections(packageName) + .getSubTypesOf(clazz) + .filterNot { "Test" in it.name } + .filter { !Modifier.isAbstract(it.modifiers) && !Modifier.isStatic(it.modifiers) } + } } diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/RunRuleSetWithRuleFiltersSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/RunRuleSetWithRuleFiltersSpec.kt index 74d645543..da5a5ad53 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/RunRuleSetWithRuleFiltersSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/RunRuleSetWithRuleFiltersSpec.kt @@ -20,40 +20,40 @@ import org.jetbrains.spek.api.dsl.it */ class RunRuleSetWithRuleFiltersSpec : Spek({ - val emptyFile = compileForTest(Case.Empty.path()) - val defaultFile = compileForTest(Case.Default.path()) + val emptyFile = compileForTest(Case.Empty.path()) + val defaultFile = compileForTest(Case.Default.path()) - describe("RuleSet without MultiRule's") { + describe("RuleSet without MultiRule's") { - val ruleSet = RuleSet("Test", listOf(WildcardImport(), OptionalUnit())) + val ruleSet = RuleSet("Test", listOf(WildcardImport(), OptionalUnit())) - it("filters WildcardImport, runs OptionalUnit") { - val findings = ruleSet.accept(defaultFile, setOf("WildcardImport")) - Assertions.assertThat(findings).allMatch { it.id != "WildcardImport" } - Assertions.assertThat(findings).anySatisfy { it.id != "OptionalUnit" } - } - } + it("filters WildcardImport, runs OptionalUnit") { + val findings = ruleSet.accept(defaultFile, setOf("WildcardImport")) + Assertions.assertThat(findings).allMatch { it.id != "WildcardImport" } + Assertions.assertThat(findings).anySatisfy { it.id != "OptionalUnit" } + } + } - describe("MultiRule test cases") { + describe("MultiRule test cases") { - fun ruleSet() = loadRuleSet() - val ruleSetId = EmptyBlocks::class.java.simpleName + fun ruleSet() = loadRuleSet() + val ruleSetId = EmptyBlocks::class.java.simpleName - it("should filter by RuleSet id") { - assertThat(ruleSet().accept(emptyFile, setOf(ruleSetId))).isEmpty() - } + it("should filter by RuleSet id") { + assertThat(ruleSet().accept(emptyFile, setOf(ruleSetId))).isEmpty() + } - it("should filter EmptyInitBlock rule") { - val ruleIdToFilter = EmptyInitBlock::class.java.simpleName - assertThat(ruleSet().accept(emptyFile, setOf(ruleIdToFilter))).allMatch { it.id != ruleIdToFilter } - } - } + it("should filter EmptyInitBlock rule") { + val ruleIdToFilter = EmptyInitBlock::class.java.simpleName + assertThat(ruleSet().accept(emptyFile, setOf(ruleIdToFilter))).allMatch { it.id != ruleIdToFilter } + } + } - describe("Mix of MultiRule and normal Rule") { + describe("Mix of MultiRule and normal Rule") { - it("should filter all rules") { - val ruleSet = RuleSet("Test", listOf(FileParsingRule(), OptionalUnit())) - assertThat(ruleSet.accept(emptyFile, setOf("MaxLineLength", "NoTabs", "OptionalUnit"))).isEmpty() - } - } + it("should filter all rules") { + val ruleSet = RuleSet("Test", listOf(FileParsingRule(), OptionalUnit())) + assertThat(ruleSet.accept(emptyFile, setOf("MaxLineLength", "NoTabs", "OptionalUnit"))).isEmpty() + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/SuppressingSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/SuppressingSpec.kt index 58b0d007f..b48723b91 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/SuppressingSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/SuppressingSpec.kt @@ -18,46 +18,46 @@ import org.jetbrains.spek.api.dsl.it */ class SuppressingSpec : Spek({ - it("all findings are suppressed on element levels") { - val ktFile = compileForTest(Case.SuppressedElements.path()) - val ruleSet = RuleSet("Test", listOf(LongMethod(), LongParameterList(), ComplexCondition())) - val findings = ruleSet.accept(ktFile) - findings.forEach { - println(it.compact()) - } - assertThat(findings).hasSize(0) - } + it("all findings are suppressed on element levels") { + val ktFile = compileForTest(Case.SuppressedElements.path()) + val ruleSet = RuleSet("Test", listOf(LongMethod(), LongParameterList(), ComplexCondition())) + val findings = ruleSet.accept(ktFile) + findings.forEach { + println(it.compact()) + } + assertThat(findings).hasSize(0) + } - it("all findings are suppressed on file levels") { - val ktFile = compileForTest(Case.SuppressedElementsByFile.path()) - val ruleSet = RuleSet("Test", listOf(LongMethod(), LongParameterList(), ComplexCondition())) - val findings = ruleSet.accept(ktFile) - findings.forEach { - println(it.compact()) - } - assertThat(findings).hasSize(0) - } + it("all findings are suppressed on file levels") { + val ktFile = compileForTest(Case.SuppressedElementsByFile.path()) + val ruleSet = RuleSet("Test", listOf(LongMethod(), LongParameterList(), ComplexCondition())) + val findings = ruleSet.accept(ktFile) + findings.forEach { + println(it.compact()) + } + assertThat(findings).hasSize(0) + } - it("all findings are suppressed on class levels") { - val ktFile = compileForTest(Case.SuppressedElementsByClass.path()) - val ruleSet = RuleSet("Test", listOf(LongMethod(), LongParameterList(), ComplexCondition())) - val findings = ruleSet.accept(ktFile) - findings.forEach { - println(it.compact()) - } - assertThat(findings).hasSize(0) - } + it("all findings are suppressed on class levels") { + val ktFile = compileForTest(Case.SuppressedElementsByClass.path()) + val ruleSet = RuleSet("Test", listOf(LongMethod(), LongParameterList(), ComplexCondition())) + val findings = ruleSet.accept(ktFile) + findings.forEach { + println(it.compact()) + } + assertThat(findings).hasSize(0) + } - it("should suppress TooManyFunctionsRule on class level") { - val findings = TooManyFunctions( - TestConfig(mapOf("thresholdInClass" to "0"))).lint(Case.SuppressedElementsByClass.path()) + it("should suppress TooManyFunctionsRule on class level") { + val findings = TooManyFunctions( + TestConfig(mapOf("thresholdInClass" to "0"))).lint(Case.SuppressedElementsByClass.path()) - assertThat(findings).isEmpty() - } + assertThat(findings).isEmpty() + } - it("should suppress StringLiteralDuplication on class level") { - val findings = StringLiteralDuplication().lint(Case.SuppressStringLiteralDuplication.path()) + it("should suppress StringLiteralDuplication on class level") { + val findings = StringLiteralDuplication().lint(Case.SuppressStringLiteralDuplication.path()) - assertThat(findings).isEmpty() - } + assertThat(findings).isEmpty() + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/DuplicateCaseInWhenExpressionSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/DuplicateCaseInWhenExpressionSpec.kt index 5e2dd86c3..98b711baa 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/DuplicateCaseInWhenExpressionSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/DuplicateCaseInWhenExpressionSpec.kt @@ -11,12 +11,12 @@ import org.jetbrains.spek.subject.SubjectSpek * @author Artur Bosch */ class DuplicateCaseInWhenExpressionSpec : SubjectSpek({ - subject { DuplicateCaseInWhenExpression(Config.empty) } + subject { DuplicateCaseInWhenExpression(Config.empty) } - given("several when expressions") { + given("several when expressions") { - it("reports duplicated label in when") { - val code = """ + it("reports duplicated label in when") { + val code = """ fun f() { when (1) { 1 -> println() @@ -24,18 +24,18 @@ class DuplicateCaseInWhenExpressionSpec : SubjectSpek println() } }""" - assertThat(subject.lint(code)).hasSize(1) - } + assertThat(subject.lint(code)).hasSize(1) + } - it("does not report duplicated label in when") { - val code = """ + it("does not report duplicated label in when") { + val code = """ fun f() { when (1) { 1 -> println() else -> println() } }""" - assertThat(subject.lint(code)).hasSize(0) - } - } + assertThat(subject.lint(code)).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/EqualsAlwaysReturnsTrueOrFalseSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/EqualsAlwaysReturnsTrueOrFalseSpec.kt index 87d1edcbb..49779c6ce 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/EqualsAlwaysReturnsTrueOrFalseSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/EqualsAlwaysReturnsTrueOrFalseSpec.kt @@ -9,16 +9,16 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class EqualsAlwaysReturnsTrueOrFalseSpec : SubjectSpek({ - subject { EqualsAlwaysReturnsTrueOrFalse(Config.empty) } + subject { EqualsAlwaysReturnsTrueOrFalse(Config.empty) } - given("several classes overriding the equals() method") { + given("several classes overriding the equals() method") { - it("reports equals() methods") { - assertThat(subject.lint(Case.EqualsAlwaysReturnsTrueOrFalsePositive.path())).hasSize(6) - } + it("reports equals() methods") { + assertThat(subject.lint(Case.EqualsAlwaysReturnsTrueOrFalsePositive.path())).hasSize(6) + } - it("does not report equals() methods") { - assertThat(subject.lint(Case.EqualsAlwaysReturnsTrueOrFalseNegative.path())).hasSize(0) - } - } + it("does not report equals() methods") { + assertThat(subject.lint(Case.EqualsAlwaysReturnsTrueOrFalseNegative.path())).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/EqualsWithHashCodeExistSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/EqualsWithHashCodeExistSpec.kt index 71a0fc9ca..72426d17e 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/EqualsWithHashCodeExistSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/EqualsWithHashCodeExistSpec.kt @@ -11,55 +11,55 @@ import org.jetbrains.spek.subject.SubjectSpek * @author Artur Bosch */ class EqualsWithHashCodeExistSpec : SubjectSpek({ - subject { EqualsWithHashCodeExist(Config.empty) } + subject { EqualsWithHashCodeExist(Config.empty) } - given("some classes with equals() and hashCode() functions") { + given("some classes with equals() and hashCode() functions") { - it("reports hashCode() without equals() function") { - val code = """ + it("reports hashCode() without equals() function") { + val code = """ class A { override fun hashCode(): Int { return super.hashCode() } }""" - assertThat(subject.lint(code)).hasSize(1) - } + assertThat(subject.lint(code)).hasSize(1) + } - it("reports equals() without hashCode() function") { - val code = """ + it("reports equals() without hashCode() function") { + val code = """ class A { override fun equals(other: Any?): Boolean { return super.equals(other) } }""" - assertThat(subject.lint(code)).hasSize(1) - } + assertThat(subject.lint(code)).hasSize(1) + } - it("does not report equals() with hashCode() function") { - val code = """ + it("does not report equals() with hashCode() function") { + val code = """ class A { override fun equals(other: Any?): Boolean { return super.equals(other) } override fun hashCode(): Int { return super.hashCode() } }""" - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("does not report when using kotlin.Any?") { - val code = """ + it("does not report when using kotlin.Any?") { + val code = """ class A { override fun equals(other: kotlin.Any?): Boolean { return super.equals(other) } override fun hashCode(): Int { return super.hashCode() } }""" - assertThat(subject.lint(code)).isEmpty() - } - } + assertThat(subject.lint(code)).isEmpty() + } + } - given("a data class") { + given("a data class") { - it("does not report equals() or hashcode() violation") { - val code = """ + it("does not report equals() or hashcode() violation") { + val code = """ data class EqualsData(val i: Int) { override fun equals(other: Any?): Boolean { return super.equals(other) } }""" - assertThat(subject.lint(code)).hasSize(0) - } - } + assertThat(subject.lint(code)).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/ExplicitGarbageCollectionCallSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/ExplicitGarbageCollectionCallSpec.kt index c3c3b6453..e6005d0b6 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/ExplicitGarbageCollectionCallSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/ExplicitGarbageCollectionCallSpec.kt @@ -8,18 +8,18 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class ExplicitGarbageCollectionCallSpec : SubjectSpek({ - subject { ExplicitGarbageCollectionCall(Config.empty) } + subject { ExplicitGarbageCollectionCall(Config.empty) } - given("several garbage collector calls") { + given("several garbage collector calls") { - it("reports garbage collector calls") { - val code = """ + it("reports garbage collector calls") { + val code = """ fun f() { System.gc() Runtime.getRuntime().gc() System.runFinalization() }""" - assertThat(subject.lint(code)).hasSize(3) - } - } + assertThat(subject.lint(code)).hasSize(3) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/InvalidRangeSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/InvalidRangeSpec.kt index 7a18885eb..1eb9d0706 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/InvalidRangeSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/InvalidRangeSpec.kt @@ -8,12 +8,12 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class InvalidRangeSpec : SubjectSpek({ - subject { InvalidRange(Config.empty) } + subject { InvalidRange(Config.empty) } - describe("check for loop conditions") { + describe("check for loop conditions") { - it("does not report correct bounds in for loop conditions") { - val code = """ + it("does not report correct bounds in for loop conditions") { + val code = """ fun f() { for (i in 2..2) {} for (i in 2 downTo 2) {} @@ -21,41 +21,41 @@ class InvalidRangeSpec : SubjectSpek({ for (i in 2 until 4 step 2) {} for (i in (1+1)..3) { } }""" - assertThat(subject.lint(code)).hasSize(0) - } + assertThat(subject.lint(code)).hasSize(0) + } - it("reports incorrect bounds in for loop conditions") { - val code = """ + it("reports incorrect bounds in for loop conditions") { + val code = """ fun f() { for (i in 2..1) { } for (i in 1 downTo 2) { } for (i in 2 until 1) { } for (i in 2 until 1 step 2) { } }""" - assertThat(subject.lint(code)).hasSize(4) - } + assertThat(subject.lint(code)).hasSize(4) + } - it("reports nested loops with incorrect bounds in for loop conditions") { - val code = """ + it("reports nested loops with incorrect bounds in for loop conditions") { + val code = """ fun f() { for (i in 2..2) { for (i in 2..1) { } } }""" - assertThat(subject.lint(code)).hasSize(1) - } - } + assertThat(subject.lint(code)).hasSize(1) + } + } - describe("check ranges outside of loops") { + describe("check ranges outside of loops") { - it("reports for '..'") { - val code = "val r = 2..1" - assertThat(subject.lint(code)).hasSize(1) - } + it("reports for '..'") { + val code = "val r = 2..1" + assertThat(subject.lint(code)).hasSize(1) + } - it("does not report binary expressions without an invalid range") { - val code = "val sum = 1 + 2" - assertThat(subject.lint(code)).hasSize(0) - } - } + it("does not report binary expressions without an invalid range") { + val code = "val sum = 1 + 2" + assertThat(subject.lint(code)).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/IteratorHasNextCallsNextMethodSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/IteratorHasNextCallsNextMethodSpec.kt index 3d586ac6a..21c9c9835 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/IteratorHasNextCallsNextMethodSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/IteratorHasNextCallsNextMethodSpec.kt @@ -8,18 +8,18 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class IteratorHasNextCallsNextMethodSpec : SubjectSpek({ - subject { IteratorHasNextCallsNextMethod() } + subject { IteratorHasNextCallsNextMethod() } - given("some iterator classes with a hasNext() method which calls next() method") { + given("some iterator classes with a hasNext() method which calls next() method") { - it("reports wrong iterator implementation") { - val path = Case.IteratorImplPositive.path() - assertThat(subject.lint(path)).hasSize(4) - } + it("reports wrong iterator implementation") { + val path = Case.IteratorImplPositive.path() + assertThat(subject.lint(path)).hasSize(4) + } - it("does not report correct iterator implementations") { - val path = Case.IteratorImplNegative.path() - assertThat(subject.lint(path)).hasSize(0) - } - } + it("does not report correct iterator implementations") { + val path = Case.IteratorImplNegative.path() + assertThat(subject.lint(path)).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/IteratorNotThrowingNoSuchElementExceptionSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/IteratorNotThrowingNoSuchElementExceptionSpec.kt index ea4c2029d..067985c3e 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/IteratorNotThrowingNoSuchElementExceptionSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/IteratorNotThrowingNoSuchElementExceptionSpec.kt @@ -8,18 +8,18 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class IteratorNotThrowingNoSuchElementExceptionSpec : SubjectSpek({ - subject { IteratorNotThrowingNoSuchElementException() } + subject { IteratorNotThrowingNoSuchElementException() } - given("two iterator classes which next() method do not throw a NoSuchElementException") { + given("two iterator classes which next() method do not throw a NoSuchElementException") { - it("reports invalid next() implementations") { - val path = Case.IteratorImplPositive.path() - assertThat(subject.lint(path)).hasSize(4) - } + it("reports invalid next() implementations") { + val path = Case.IteratorImplPositive.path() + assertThat(subject.lint(path)).hasSize(4) + } - it("does not report correct next() implemenations") { - val path = Case.IteratorImplNegative.path() - assertThat(subject.lint(path)).hasSize(0) - } - } + it("does not report correct next() implemenations") { + val path = Case.IteratorImplNegative.path() + assertThat(subject.lint(path)).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/LateinitUsageSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/LateinitUsageSpec.kt index 38e13fca9..f642e9e7e 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/LateinitUsageSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/LateinitUsageSpec.kt @@ -2,17 +2,17 @@ package io.gitlab.arturbosch.detekt.rules.bugs import io.gitlab.arturbosch.detekt.test.TestConfig import io.gitlab.arturbosch.detekt.test.lint +import java.util.regex.PatternSyntaxException import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThatExceptionOfType import org.jetbrains.spek.api.Spek import org.jetbrains.spek.api.dsl.given import org.jetbrains.spek.api.dsl.it -import java.util.regex.PatternSyntaxException class LateinitUsageSpec : Spek({ - given("a kt file with lateinit usages") { - val code = """ + given("a kt file with lateinit usages") { + val code = """ package foo import kotlin.jvm.JvmField @@ -24,61 +24,61 @@ class LateinitUsageSpec : Spek({ } """ - it("should report lateinit usages") { - val findings = LateinitUsage().lint(code) - assertThat(findings).hasSize(2) - } + it("should report lateinit usages") { + val findings = LateinitUsage().lint(code) + assertThat(findings).hasSize(2) + } - it("should not report lateinit properties annotated @JvmField") { - val findings = LateinitUsage(TestConfig(mapOf(LateinitUsage.EXCLUDE_ANNOTATED_PROPERTIES to "JvmField"))).lint(code) - assertThat(findings).isEmpty() - } + it("should not report lateinit properties annotated @JvmField") { + val findings = LateinitUsage(TestConfig(mapOf(LateinitUsage.EXCLUDE_ANNOTATED_PROPERTIES to "JvmField"))).lint(code) + assertThat(findings).isEmpty() + } - it("should not report lateinit properties annotated @JvmField with trailing whitespace") { - val findings = LateinitUsage(TestConfig(mapOf(LateinitUsage.EXCLUDE_ANNOTATED_PROPERTIES to " JvmField "))).lint(code) - assertThat(findings).isEmpty() - } + it("should not report lateinit properties annotated @JvmField with trailing whitespace") { + val findings = LateinitUsage(TestConfig(mapOf(LateinitUsage.EXCLUDE_ANNOTATED_PROPERTIES to " JvmField "))).lint(code) + assertThat(findings).isEmpty() + } - it("should not report lateinit properties matching kotlin.*") { - val findings = LateinitUsage(TestConfig(mapOf(LateinitUsage.EXCLUDE_ANNOTATED_PROPERTIES to "kotlin.*"))).lint(code) - assertThat(findings).isEmpty() - } + it("should not report lateinit properties matching kotlin.*") { + val findings = LateinitUsage(TestConfig(mapOf(LateinitUsage.EXCLUDE_ANNOTATED_PROPERTIES to "kotlin.*"))).lint(code) + assertThat(findings).isEmpty() + } - it("should not report lateinit properties matching kotlin.jvm.") { - val findings = LateinitUsage(TestConfig(mapOf(LateinitUsage.EXCLUDE_ANNOTATED_PROPERTIES to "kotlin.jvm."))).lint(code) - assertThat(findings).isEmpty() - } + it("should not report lateinit properties matching kotlin.jvm.") { + val findings = LateinitUsage(TestConfig(mapOf(LateinitUsage.EXCLUDE_ANNOTATED_PROPERTIES to "kotlin.jvm."))).lint(code) + assertThat(findings).isEmpty() + } - it("should not report lateinit properties matching kotlin.jvm.*") { - val findings = LateinitUsage(TestConfig(mapOf(LateinitUsage.EXCLUDE_ANNOTATED_PROPERTIES to "kotlin.jvm.*"))).lint(code) - assertThat(findings).isEmpty() - } + it("should not report lateinit properties matching kotlin.jvm.*") { + val findings = LateinitUsage(TestConfig(mapOf(LateinitUsage.EXCLUDE_ANNOTATED_PROPERTIES to "kotlin.jvm.*"))).lint(code) + assertThat(findings).isEmpty() + } - it("should not exclude lateinit properties not matching the exclude pattern") { - val findings = LateinitUsage(TestConfig(mapOf(LateinitUsage.EXCLUDE_ANNOTATED_PROPERTIES to "IgnoreThis"))).lint(code) - assertThat(findings).hasSize(2) - } + it("should not exclude lateinit properties not matching the exclude pattern") { + val findings = LateinitUsage(TestConfig(mapOf(LateinitUsage.EXCLUDE_ANNOTATED_PROPERTIES to "IgnoreThis"))).lint(code) + assertThat(findings).hasSize(2) + } - it("should report lateinit properties when ignoreOnClassesPattern does not match") { - val findings = LateinitUsage(TestConfig(mapOf(LateinitUsage.IGNORE_ON_CLASSES_PATTERN to "[\\w]+Test1234"))).lint(code) - assertThat(findings).hasSize(2) - } + it("should report lateinit properties when ignoreOnClassesPattern does not match") { + val findings = LateinitUsage(TestConfig(mapOf(LateinitUsage.IGNORE_ON_CLASSES_PATTERN to "[\\w]+Test1234"))).lint(code) + assertThat(findings).hasSize(2) + } - it("should not report lateinit properties when ignoreOnClassesPattern does match") { - val findings = LateinitUsage(TestConfig(mapOf(LateinitUsage.IGNORE_ON_CLASSES_PATTERN to "[\\w]+Test"))).lint(code) - assertThat(findings).isEmpty() - } + it("should not report lateinit properties when ignoreOnClassesPattern does match") { + val findings = LateinitUsage(TestConfig(mapOf(LateinitUsage.IGNORE_ON_CLASSES_PATTERN to "[\\w]+Test"))).lint(code) + assertThat(findings).isEmpty() + } - it("should fail when enabled with faulty regex pattern") { - assertThatExceptionOfType(PatternSyntaxException::class.java).isThrownBy { - LateinitUsage(TestConfig(mapOf(LateinitUsage.IGNORE_ON_CLASSES_PATTERN to "*Test"))).lint(code) - } - } + it("should fail when enabled with faulty regex pattern") { + assertThatExceptionOfType(PatternSyntaxException::class.java).isThrownBy { + LateinitUsage(TestConfig(mapOf(LateinitUsage.IGNORE_ON_CLASSES_PATTERN to "*Test"))).lint(code) + } + } - it("should not fail when disabled with faulty regex pattern") { - val configValues = mapOf("active" to "false", LateinitUsage.IGNORE_ON_CLASSES_PATTERN to "*Test") - val findings = LateinitUsage(TestConfig(configValues)).lint(code) - assertThat(findings).isEmpty() - } - } + it("should not fail when disabled with faulty regex pattern") { + val configValues = mapOf("active" to "false", LateinitUsage.IGNORE_ON_CLASSES_PATTERN to "*Test") + val findings = LateinitUsage(TestConfig(configValues)).lint(code) + assertThat(findings).isEmpty() + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnconditionalJumpStatementInLoopSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnconditionalJumpStatementInLoopSpec.kt index 415453ace..a2b79caf0 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnconditionalJumpStatementInLoopSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnconditionalJumpStatementInLoopSpec.kt @@ -8,18 +8,18 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class UnconditionalJumpStatementInLoopSpec : SubjectSpek({ - subject { UnconditionalJumpStatementInLoop() } + subject { UnconditionalJumpStatementInLoop() } - given("several jump statements in loops") { + given("several jump statements in loops") { - it("reports unconditional jumps") { - val path = Case.UnconditionalJumpStatementInLoopPositive.path() - assertThat(subject.lint(path)).hasSize(8) - } + it("reports unconditional jumps") { + val path = Case.UnconditionalJumpStatementInLoopPositive.path() + assertThat(subject.lint(path)).hasSize(8) + } - it("does not report conditional jumps") { - val path = Case.UnconditionalJumpStatementInLoopNegative.path() - assertThat(subject.lint(path)).hasSize(0) - } - } + it("does not report conditional jumps") { + val path = Case.UnconditionalJumpStatementInLoopNegative.path() + assertThat(subject.lint(path)).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnreachableCodeSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnreachableCodeSpec.kt index 6f7ee8a3a..63f986129 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnreachableCodeSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnreachableCodeSpec.kt @@ -9,13 +9,13 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class UnreachableCodeSpec : SubjectSpek({ - subject { UnreachableCode(Config.empty) } + subject { UnreachableCode(Config.empty) } - given("several unreachable statements") { + given("several unreachable statements") { - it("reports unreachable code") { - val path = Case.UnreachableCode.path() - assertThat(subject.lint(path)).hasSize(6) - } - } + it("reports unreachable code") { + val path = Case.UnreachableCode.path() + assertThat(subject.lint(path)).hasSize(6) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnsafeCallOnNullableTypeSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnsafeCallOnNullableTypeSpec.kt index 8075c89ad..027e803f2 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnsafeCallOnNullableTypeSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnsafeCallOnNullableTypeSpec.kt @@ -10,32 +10,32 @@ import org.jetbrains.spek.subject.SubjectSpek * @author Ivan Balaksha */ class UnsafeCallOnNullableTypeSpec : SubjectSpek({ - subject { UnsafeCallOnNullableType() } + subject { UnsafeCallOnNullableType() } - describe("check all variants of safe/unsafe calls on nullable types") { + describe("check all variants of safe/unsafe calls on nullable types") { - it("unsafe call on nullable type") { - val code = """ + it("unsafe call on nullable type") { + val code = """ fun test(str: String?) { println(str!!.length) }""" - assertThat(subject.lint(code)).hasSize(1) - } + assertThat(subject.lint(code)).hasSize(1) + } - it("safe call on nullable type") { - val code = """ + it("safe call on nullable type") { + val code = """ fun test(str: String?) { println(str?.length) }""" - assertThat(subject.lint(code)).hasSize(0) - } + assertThat(subject.lint(code)).hasSize(0) + } - it("elvis") { - val code = """ + it("elvis") { + val code = """ fun test(str: String?) { println(str?.length ?: 0) }""" - assertThat(subject.lint(code)).hasSize(0) - } - } + assertThat(subject.lint(code)).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnsafeCastSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnsafeCastSpec.kt index 1183901db..06d3bcdd9 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnsafeCastSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnsafeCastSpec.kt @@ -1,33 +1,33 @@ package io.gitlab.arturbosch.detekt.rules.bugs import io.gitlab.arturbosch.detekt.test.lint +import org.assertj.core.api.Assertions.assertThat import org.jetbrains.spek.api.dsl.describe import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek -import org.assertj.core.api.Assertions.assertThat /** * @author Ivan Balaksha */ class UnsafeCastSpec : SubjectSpek({ - subject { UnsafeCast() } + subject { UnsafeCast() } - describe("check safe and unsafe casts") { + describe("check safe and unsafe casts") { - it("test unsafe cast") { - val code = """ + it("test unsafe cast") { + val code = """ fun test(s: Any) { println(s as Int) }""" - assertThat(subject.lint(code)).hasSize(1) - } + assertThat(subject.lint(code)).hasSize(1) + } - it("test safe cast") { - val code = """ + it("test safe cast") { + val code = """ fun test(s: Any) { println((s as? Int) ?: 0) }""" - assertThat(subject.lint(code)).isEmpty() - } - } + assertThat(subject.lint(code)).isEmpty() + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UselessPostfixExpressionSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UselessPostfixExpressionSpec.kt index 6874b7898..a2e3f35f2 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UselessPostfixExpressionSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UselessPostfixExpressionSpec.kt @@ -7,42 +7,42 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class UselessPostfixExpressionSpec : SubjectSpek({ - subject { UselessPostfixExpression() } + subject { UselessPostfixExpression() } - describe("check several types of postfix increments") { + describe("check several types of postfix increments") { - it("overrides the incremented integer") { - val code = """ + it("overrides the incremented integer") { + val code = """ fun x() { var i = 0 i = i-- // invalid i = 1 + i++ // invalid i = i++ + 1 // invalid }""" - assertThat(subject.lint(code)).hasSize(3) - } + assertThat(subject.lint(code)).hasSize(3) + } - it("does not override the incremented integer") { - val code = """ + it("does not override the incremented integer") { + val code = """ fun f() { var j = 0 j = i++ }""" - assertThat(subject.lint(code)).hasSize(0) - } + assertThat(subject.lint(code)).hasSize(0) + } - it("returns no incremented value") { - val code = """ + it("returns no incremented value") { + val code = """ fun x() { var i = 0 if (i == 0) return 1 + j++ return i++ }""" - assertThat(subject.lint(code)).hasSize(2) - } + assertThat(subject.lint(code)).hasSize(2) + } - it("should not report field increments") { - val code = """ + it("should not report field increments") { + val code = """ class Test { private var runningId: Long = 0 @@ -61,11 +61,11 @@ class UselessPostfixExpressionSpec : SubjectSpek({ } } """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("should detect properties shadowing fields that are incremented") { - val code = """ + it("should detect properties shadowing fields that are incremented") { + val code = """ class Test { private var runningId: Long = 0 @@ -82,14 +82,14 @@ class UselessPostfixExpressionSpec : SubjectSpek({ } } """ - assertThat(subject.lint(code)).hasSize(2) - } - } + assertThat(subject.lint(code)).hasSize(2) + } + } - describe("Only ++ and -- postfix operators should be considered") { + describe("Only ++ and -- postfix operators should be considered") { - it("should not report !! in a return statement") { - val code = """ + it("should not report !! in a return statement") { + val code = """ fun getInstance(): SwiftBrowserIdleTaskHelper { return sInstance!! } @@ -98,11 +98,11 @@ class UselessPostfixExpressionSpec : SubjectSpek({ return shouldNotBeNull!!.field } """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("should not report !! in a standalone expression") { - assertThat(subject.lint("sInstance!!")).isEmpty() - } - } + it("should not report !! in a standalone expression") { + assertThat(subject.lint("sInstance!!")).isEmpty() + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/WrongEqualsTypeParameterSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/WrongEqualsTypeParameterSpec.kt index a506b7c46..91c79c4ab 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/WrongEqualsTypeParameterSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/WrongEqualsTypeParameterSpec.kt @@ -8,36 +8,36 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class WrongEqualsTypeParameterSpec : SubjectSpek({ - subject { WrongEqualsTypeParameter(Config.empty) } + subject { WrongEqualsTypeParameter(Config.empty) } - given("an equals method") { + given("an equals method") { - it("uses Any? as parameter") { - val code = """ + it("uses Any? as parameter") { + val code = """ class A { override fun equals(other: Any?): Boolean { return super.equals(other) } }""" - assertThat(subject.lint(code).size).isEqualTo(0) - } + assertThat(subject.lint(code).size).isEqualTo(0) + } - it("uses String as parameter") { - val code = """ + it("uses String as parameter") { + val code = """ class A { fun equals(other: String): Boolean { return super.equals(other) } }""" - assertThat(subject.lint(code).size).isEqualTo(1) - } + assertThat(subject.lint(code).size).isEqualTo(1) + } - it("uses an interface declaration") { - val code = """ + it("uses an interface declaration") { + val code = """ interface EqualsInterf { fun equals(other: String) }""" - assertThat(subject.lint(code).size).isEqualTo(0) - } - } + assertThat(subject.lint(code).size).isEqualTo(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/ComplexConditionSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/ComplexConditionSpec.kt index ca1a383d7..46a17385e 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/ComplexConditionSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/ComplexConditionSpec.kt @@ -11,9 +11,9 @@ import org.jetbrains.spek.api.dsl.it */ class ComplexConditionSpec : Spek({ - given("some complex conditions") { + given("some complex conditions") { - val code = """ + val code = """ val a = if (5 > 4 && 4 < 6 || (3 < 5 || 2 < 5)) { 42 } else { 24 } fun complexConditions() { @@ -22,8 +22,8 @@ class ComplexConditionSpec : Spek({ } """ - it("reports some complex conditions") { - assertThat(ComplexCondition().lint(code)).hasSize(3) - } - } + it("reports some complex conditions") { + assertThat(ComplexCondition().lint(code)).hasSize(3) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/ComplexInterfaceSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/ComplexInterfaceSpec.kt index 2883af8ff..45cdf478e 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/ComplexInterfaceSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/ComplexInterfaceSpec.kt @@ -10,26 +10,26 @@ import org.jetbrains.spek.subject.SubjectSpek class ComplexInterfaceSpec : SubjectSpek({ - subject { ComplexInterface(threshold = THRESHOLD) } + subject { ComplexInterface(threshold = THRESHOLD) } - given("several interface declarations") { + given("several interface declarations") { - val path = Case.ComplexInterfacePositive.path() + val path = Case.ComplexInterfacePositive.path() - it("reports interfaces which member size exceeds the threshold") { - assertThat(subject.lint(path)).hasSize(2) - } + it("reports interfaces which member size exceeds the threshold") { + assertThat(subject.lint(path)).hasSize(2) + } - it("reports interfaces which member size exceeds the threshold including static declarations") { - val config = TestConfig(mapOf(ComplexInterface.INCLUDE_STATIC_DECLARATIONS to "true")) - val rule = ComplexInterface(config, threshold = THRESHOLD) - assertThat(rule.lint(path)).hasSize(3) - } + it("reports interfaces which member size exceeds the threshold including static declarations") { + val config = TestConfig(mapOf(ComplexInterface.INCLUDE_STATIC_DECLARATIONS to "true")) + val rule = ComplexInterface(config, threshold = THRESHOLD) + assertThat(rule.lint(path)).hasSize(3) + } - it("does not report interfaces which member size is under the threshold") { - assertThat(subject.lint(Case.ComplexInterfaceNegative.path())).hasSize(0) - } - } + it("does not report interfaces which member size is under the threshold") { + assertThat(subject.lint(Case.ComplexInterfaceNegative.path())).hasSize(0) + } + } }) private const val THRESHOLD = 4 diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/ComplexMethodSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/ComplexMethodSpec.kt index fb109a2d9..7e25f3bee 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/ComplexMethodSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/ComplexMethodSpec.kt @@ -15,51 +15,51 @@ import org.jetbrains.spek.api.dsl.it */ class ComplexMethodSpec : Spek({ - given("a complex method") { + given("a complex method") { - it("finds one complex method") { - val subject = ComplexMethod() - subject.lint(Case.ComplexClass.path()) + it("finds one complex method") { + val subject = ComplexMethod() + subject.lint(Case.ComplexClass.path()) - assertThat(subject.findings).hasSourceLocations(SourceLocation(3, 1)) + assertThat(subject.findings).hasSourceLocations(SourceLocation(3, 1)) - assertThat(subject.findings.first()) - .isThresholded() - .withValue(20) - .withThreshold(10) - } - } + assertThat(subject.findings.first()) + .isThresholded() + .withValue(20) + .withThreshold(10) + } + } - given("several complex methods") { + given("several complex methods") { - val path = Case.ComplexMethods.path() + val path = Case.ComplexMethods.path() - it("does not report complex methods with a single when expression") { - val config = TestConfig(mapOf( - ComplexMethod.IGNORE_SIMPLE_WHEN_ENTRIES to "1.0", - ComplexMethod.IGNORE_SINGLE_WHEN_EXPRESSION to "true")) - val subject = ComplexMethod(config, threshold = 4) + it("does not report complex methods with a single when expression") { + val config = TestConfig(mapOf( + ComplexMethod.IGNORE_SIMPLE_WHEN_ENTRIES to "1.0", + ComplexMethod.IGNORE_SINGLE_WHEN_EXPRESSION to "true")) + val subject = ComplexMethod(config, threshold = 4) - assertThat(subject.lint(path)).hasSourceLocations(SourceLocation(42, 1)) - } + assertThat(subject.lint(path)).hasSourceLocations(SourceLocation(42, 1)) + } - it("reports all complex methods") { - val config = TestConfig(mapOf(ComplexMethod.IGNORE_SIMPLE_WHEN_ENTRIES to "1.0")) - val subject = ComplexMethod(config, threshold = 4) + it("reports all complex methods") { + val config = TestConfig(mapOf(ComplexMethod.IGNORE_SIMPLE_WHEN_ENTRIES to "1.0")) + val subject = ComplexMethod(config, threshold = 4) - assertThat(subject.lint(path)).hasSourceLocations( - SourceLocation(5, 1), - SourceLocation(14, 1), - SourceLocation(24, 1), - SourceLocation(34, 1), - SourceLocation(42, 1) - ) - } + assertThat(subject.lint(path)).hasSourceLocations( + SourceLocation(5, 1), + SourceLocation(14, 1), + SourceLocation(24, 1), + SourceLocation(34, 1), + SourceLocation(42, 1) + ) + } - it("does not trip for a reasonable amount of simple when entries when ignoreSimpleWhenEntries is true") { - val config = TestConfig(mapOf(ComplexMethod.IGNORE_SIMPLE_WHEN_ENTRIES to "true")) - val subject = ComplexMethod(config) - val code = """ + it("does not trip for a reasonable amount of simple when entries when ignoreSimpleWhenEntries is true") { + val config = TestConfig(mapOf(ComplexMethod.IGNORE_SIMPLE_WHEN_ENTRIES to "true")) + val subject = ComplexMethod(config) + val code = """ internal fun Map.asBundle(): Bundle { val bundle = Bundle(size) @@ -83,14 +83,14 @@ class ComplexMethodSpec : Spek({ } """.trimIndent() - val findings = subject.lint(code) - assertThat(findings).isEmpty() - } - } + val findings = subject.lint(code) + assertThat(findings).isEmpty() + } + } - given("function containing object literal with many overridden functions") { + given("function containing object literal with many overridden functions") { - val code = """ + val code = """ fun f(): List { return object : List { override val size: Int get() = TODO("not implemented") @@ -138,8 +138,8 @@ class ComplexMethodSpec : Spek({ } """.trimIndent() - it("should not count these overridden functions to base functions complexity") { - assertThat(ComplexMethod().lint(code)).isEmpty() - } - } + it("should not count these overridden functions to base functions complexity") { + assertThat(ComplexMethod().lint(code)).isEmpty() + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LabeledExpressionSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LabeledExpressionSpec.kt index 444771d68..fa1237654 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LabeledExpressionSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LabeledExpressionSpec.kt @@ -14,27 +14,27 @@ import org.jetbrains.spek.subject.SubjectSpek */ class LabeledExpressionSpec : SubjectSpek({ - subject { LabeledExpression() } + subject { LabeledExpression() } - given("several labeled expressions") { + given("several labeled expressions") { - it("reports these labels") { - subject.lint(Case.LabeledExpressionPositive.path()) - assertThat(subject.findings).hasSize(10) - } + it("reports these labels") { + subject.lint(Case.LabeledExpressionPositive.path()) + assertThat(subject.findings).hasSize(10) + } - it("does not report these labels") { - subject.lint(Case.LabeledExpressionNegative.path()) - assertThat(subject.findings).isEmpty() - } + it("does not report these labels") { + subject.lint(Case.LabeledExpressionNegative.path()) + assertThat(subject.findings).isEmpty() + } - it("does not report excluded label") { - val code = """fun f() { + it("does not report excluded label") { + val code = """fun f() { loop@ for (i in 1..5) {} """ - val config = TestConfig(mapOf(LabeledExpression.IGNORED_LABELS to "loop")) - val findings = LabeledExpression(config).lint(code) - assertThat(findings).isEmpty() - } - } + val config = TestConfig(mapOf(LabeledExpression.IGNORED_LABELS to "loop")) + val findings = LabeledExpression(config).lint(code) + assertThat(findings).isEmpty() + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LargeClassSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LargeClassSpec.kt index fc81bfeef..09723b909 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LargeClassSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LargeClassSpec.kt @@ -12,17 +12,17 @@ import org.jetbrains.spek.api.dsl.it */ class LargeClassSpec : Spek({ - describe("nested classes are also considered") { + describe("nested classes are also considered") { - it("should detect only the nested large class which exceeds threshold 70") { - assertThat(LargeClass(threshold = 70).lint(Case.NestedClasses.path())).hasSize(1) - } - } + it("should detect only the nested large class which exceeds threshold 70") { + assertThat(LargeClass(threshold = 70).lint(Case.NestedClasses.path())).hasSize(1) + } + } - describe("files without classes should not be considered") { + describe("files without classes should not be considered") { - it("should not report anything in large files without classes") { - assertThat(LargeClass().lint(Case.NoClasses.path())).isEmpty() - } - } + it("should not report anything in large files without classes") { + assertThat(LargeClass().lint(Case.NoClasses.path())).isEmpty() + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LongMethodSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LongMethodSpec.kt index 30c793630..012e82bc7 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LongMethodSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LongMethodSpec.kt @@ -12,18 +12,18 @@ import org.jetbrains.spek.subject.SubjectSpek */ class LongMethodSpec : SubjectSpek({ - subject { LongMethod(threshold = 5) } + subject { LongMethod(threshold = 5) } - describe("nested functions can be long") { + describe("nested functions can be long") { - it("should find two long methods") { - val path = Case.LongMethodPositive.path() - assertThat(subject.lint(path)).hasSize(2) - } + it("should find two long methods") { + val path = Case.LongMethodPositive.path() + assertThat(subject.lint(path)).hasSize(2) + } - it("should not find too long methods") { - val path = Case.LongMethodNegative.path() - assertThat(subject.lint(path)).isEmpty() - } - } + it("should not find too long methods") { + val path = Case.LongMethodNegative.path() + assertThat(subject.lint(path)).isEmpty() + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LongParameterListSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LongParameterListSpec.kt index 687f171c2..37a22523a 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LongParameterListSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LongParameterListSpec.kt @@ -12,30 +12,30 @@ import org.jetbrains.spek.subject.SubjectSpek */ class LongParameterListSpec : SubjectSpek({ - subject { LongParameterList() } + subject { LongParameterList() } - given("function with parameters") { + given("function with parameters") { - it("reports too long parameter list") { - val code = "fun long(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) {}" - assertThat(subject.lint(code)).hasSize(1) - } + it("reports too long parameter list") { + val code = "fun long(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) {}" + assertThat(subject.lint(code)).hasSize(1) + } - it("does not reports short parameter list") { - val code = "fun long(a: Int, b: Int, c: Int, d: Int, e: Int) {}" - assertThat(subject.lint(code)).isEmpty() - } + it("does not reports short parameter list") { + val code = "fun long(a: Int, b: Int, c: Int, d: Int, e: Int) {}" + assertThat(subject.lint(code)).isEmpty() + } - it("reports too long parameter list event for parameters with defaults") { - val code = "fun long(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int = 1) {}" - assertThat(subject.lint(code)).hasSize(1) - } + it("reports too long parameter list event for parameters with defaults") { + val code = "fun long(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int = 1) {}" + assertThat(subject.lint(code)).hasSize(1) + } - it("does not report long parameter list if parameters with defaults should be ignored") { - val config = TestConfig(mapOf(LongParameterList.IGNORE_DEFAULT_PARAMETERS to "true")) - val rule = LongParameterList(config) - val code = "fun long(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int = 1, g: Int = 2) {}" - assertThat(rule.lint(code)).isEmpty() - } - } + it("does not report long parameter list if parameters with defaults should be ignored") { + val config = TestConfig(mapOf(LongParameterList.IGNORE_DEFAULT_PARAMETERS to "true")) + val rule = LongParameterList(config) + val code = "fun long(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int = 1, g: Int = 2) {}" + assertThat(rule.lint(code)).isEmpty() + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/MethodOverloadingSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/MethodOverloadingSpec.kt index 3aca21099..b00faf8e7 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/MethodOverloadingSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/MethodOverloadingSpec.kt @@ -9,47 +9,47 @@ import org.jetbrains.spek.subject.SubjectSpek class MethodOverloadingSpec : SubjectSpek({ - subject { MethodOverloading(threshold = 3) } + subject { MethodOverloading(threshold = 3) } - given("several overloaded methods") { + given("several overloaded methods") { - val findings = subject.lint(Case.OverloadedMethods.path()) + val findings = subject.lint(Case.OverloadedMethods.path()) - it("reports overloaded methods which exceed the threshold") { - assertThat(findings.size).isEqualTo(3) - } + it("reports overloaded methods which exceed the threshold") { + assertThat(findings.size).isEqualTo(3) + } - it("reports the correct method name") { - val expected = "The method 'overloadedMethod' is overloaded 3 times." - assertThat(findings[0].message).isEqualTo(expected) - } + it("reports the correct method name") { + val expected = "The method 'overloadedMethod' is overloaded 3 times." + assertThat(findings[0].message).isEqualTo(expected) + } - it("does not report overloaded methods which do not exceed the threshold") { - subject.lint(""" + it("does not report overloaded methods which do not exceed the threshold") { + subject.lint(""" class Test { fun x() { } fun x(i: Int) { } }""") - assertThat(subject.findings.size).isZero() - } - } + assertThat(subject.findings.size).isZero() + } + } - given("several overloaded extensions functions") { + given("several overloaded extensions functions") { - it("does not report extension methods with a different receiver") { - subject.lint(""" + it("does not report extension methods with a different receiver") { + subject.lint(""" fun Boolean.foo() {} fun Int.foo() {} fun Long.foo() {}""") - assertThat(subject.findings.size).isZero() - } + assertThat(subject.findings.size).isZero() + } - it("reports extension methods with the same receiver") { - subject.lint(""" + it("reports extension methods with the same receiver") { + subject.lint(""" fun Int.foo() {} fun Int.foo(i: Int) {} fun Int.foo(i: String) {}""") - assertThat(subject.findings.size).isEqualTo(1) - } - } + assertThat(subject.findings.size).isEqualTo(1) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/NestedBlockDepthSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/NestedBlockDepthSpec.kt index 266ebb57b..e1f4542af 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/NestedBlockDepthSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/NestedBlockDepthSpec.kt @@ -13,17 +13,17 @@ import org.jetbrains.spek.subject.SubjectSpek */ class NestedBlockDepthSpec : SubjectSpek({ - subject { NestedBlockDepth(threshold = 4) } + subject { NestedBlockDepth(threshold = 4) } - describe("nested classes are also considered") { - it("should detect only the nested large class") { - subject.lint(Case.NestedClasses.path()) - assertThat(subject.findings.size).isEqualTo(1) - assertThat((subject.findings[0] as ThresholdedCodeSmell).value).isEqualTo(5) - } + describe("nested classes are also considered") { + it("should detect only the nested large class") { + subject.lint(Case.NestedClasses.path()) + assertThat(subject.findings.size).isEqualTo(1) + assertThat((subject.findings[0] as ThresholdedCodeSmell).value).isEqualTo(5) + } - it("should detect too nested block depth") { - val code = """ + it("should detect too nested block depth") { + val code = """ fun f() { if (true) { if (true) { @@ -34,11 +34,11 @@ class NestedBlockDepthSpec : SubjectSpek({ } } }""" - assertThat(subject.lint(code)).hasSize(1) - } + assertThat(subject.lint(code)).hasSize(1) + } - it("should not detect valid nested block depth") { - val code = """ + it("should not detect valid nested block depth") { + val code = """ fun f() { if (true) { if (true) { @@ -47,14 +47,14 @@ class NestedBlockDepthSpec : SubjectSpek({ } } }""" - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("should not count else if as two") { - subject.lint(nestedBlockCode) - assertThat(subject.findings).isEmpty() - } - } + it("should not count else if as two") { + subject.lint(nestedBlockCode) + assertThat(subject.findings).isEmpty() + } + } }) const val nestedBlockCode = """ diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/StringLiteralDuplicationSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/StringLiteralDuplicationSpec.kt index 6eb360ffe..190899803 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/StringLiteralDuplicationSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/StringLiteralDuplicationSpec.kt @@ -3,6 +3,7 @@ package io.gitlab.arturbosch.detekt.rules.complexity import io.gitlab.arturbosch.detekt.rules.Case import io.gitlab.arturbosch.detekt.test.TestConfig import io.gitlab.arturbosch.detekt.test.lint +import java.util.regex.PatternSyntaxException import org.assertj.core.api.Assertions.assertThatExceptionOfType import org.assertj.core.api.Java6Assertions.assertThat import org.jetbrains.spek.api.dsl.describe @@ -10,34 +11,33 @@ import org.jetbrains.spek.api.dsl.given import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek import org.jetbrains.spek.subject.dsl.SubjectProviderDsl -import java.util.regex.PatternSyntaxException class StringLiteralDuplicationSpec : SubjectSpek({ - subject { StringLiteralDuplication() } + subject { StringLiteralDuplication() } - given("many hardcoded strings") { + given("many hardcoded strings") { - it("reports 3 equal hardcoded strings") { - val code = """ + it("reports 3 equal hardcoded strings") { + val code = """ class Duplication { var s1 = "lorem" fun f(s: String = "lorem") { s1.equals("lorem") } }""" - assertCodeFindings(code, 1) - } + assertCodeFindings(code, 1) + } - it("does not report 2 equal hardcoded strings") { - val code = """val str = "lorem" + "lorem" + "ipsum"""" - assertCodeFindings(code, 0) - } - } + it("does not report 2 equal hardcoded strings") { + val code = """val str = "lorem" + "lorem" + "ipsum"""" + assertCodeFindings(code, 0) + } + } - given("strings in annotations") { + given("strings in annotations") { - val code = """ + val code = """ @Suppress("unused") class A @Suppress("unused") @@ -46,93 +46,93 @@ class StringLiteralDuplicationSpec : SubjectSpek({ class C """" - it("does not report strings in annotations") { - assertCodeFindings(code, 0) - } + it("does not report strings in annotations") { + assertCodeFindings(code, 0) + } - it("reports strings in annotations according to config") { - val config = TestConfig(mapOf(StringLiteralDuplication.IGNORE_ANNOTATION to "false")) - assertFindingWithConfig(code, config, 1) - } - } + it("reports strings in annotations according to config") { + val config = TestConfig(mapOf(StringLiteralDuplication.IGNORE_ANNOTATION to "false")) + assertFindingWithConfig(code, config, 1) + } + } - given("strings with less than 5 characters") { + given("strings with less than 5 characters") { - val code = """val str = "amet" + "amet" + "amet"""" + val code = """val str = "amet" + "amet" + "amet"""" - it("does not report strings with 4 characters") { - assertCodeFindings(code, 0) - } + it("does not report strings with 4 characters") { + assertCodeFindings(code, 0) + } - it("reports string with 4 characters") { - val config = TestConfig(mapOf(StringLiteralDuplication.EXCLUDE_SHORT_STRING to "false")) - assertFindingWithConfig(code, config, 1) - } - } + it("reports string with 4 characters") { + val config = TestConfig(mapOf(StringLiteralDuplication.EXCLUDE_SHORT_STRING to "false")) + assertFindingWithConfig(code, config, 1) + } + } - given("strings with values to match for the regex") { + given("strings with values to match for the regex") { - val regexTestingCode = """ + val regexTestingCode = """ val str1 = "lorem" + "lorem" + "lorem" val str2 = "ipsum" + "ipsum" + "ipsum" """ - it("does not report lorem or ipsum according to config in regex") { - val code = """ + it("does not report lorem or ipsum according to config in regex") { + val code = """ val str1 = "lorem" + "lorem" + "lorem" val str2 = "ipsum" + "ipsum" + "ipsum" """ - val config = TestConfig(mapOf(StringLiteralDuplication.IGNORE_STRINGS_REGEX to "(lorem|ipsum)")) - assertFindingWithConfig(code, config, 0) - } + val config = TestConfig(mapOf(StringLiteralDuplication.IGNORE_STRINGS_REGEX to "(lorem|ipsum)")) + assertFindingWithConfig(code, config, 0) + } - it("should not fail with invalid regex when disabled") { - val configValues = mapOf( - "active" to "false", - StringLiteralDuplication.IGNORE_STRINGS_REGEX to "*lorem" - ) - val config = TestConfig(configValues) - assertFindingWithConfig(regexTestingCode, config, 0) - } + it("should not fail with invalid regex when disabled") { + val configValues = mapOf( + "active" to "false", + StringLiteralDuplication.IGNORE_STRINGS_REGEX to "*lorem" + ) + val config = TestConfig(configValues) + assertFindingWithConfig(regexTestingCode, config, 0) + } - it("should fail with invalid regex") { - val config = TestConfig(mapOf(StringLiteralDuplication.IGNORE_STRINGS_REGEX to "*lorem")) - assertThatExceptionOfType(PatternSyntaxException::class.java).isThrownBy { - StringLiteralDuplication(config).lint(regexTestingCode) - } - } - } + it("should fail with invalid regex") { + val config = TestConfig(mapOf(StringLiteralDuplication.IGNORE_STRINGS_REGEX to "*lorem")) + assertThatExceptionOfType(PatternSyntaxException::class.java).isThrownBy { + StringLiteralDuplication(config).lint(regexTestingCode) + } + } + } - describe("saves string literal references") { + describe("saves string literal references") { - it("reports 3 locations for 'lorem'") { - val code = """ + it("reports 3 locations for 'lorem'") { + val code = """ class Duplication { var s1 = "lorem" fun f(s: String = "lorem") { s1.equals("lorem") } }""" - val finding = subject.lint(code)[0] - val locations = finding.references.map { it.location } + finding.entity.location - assertThat(locations).hasSize(3) - } - } + val finding = subject.lint(code)[0] + val locations = finding.references.map { it.location } + finding.entity.location + assertThat(locations).hasSize(3) + } + } - describe("multiline strings with string interpolation") { + describe("multiline strings with string interpolation") { - it("does not report duplicated parts in multiline strings") { - val path = Case.MultilineStringLiteralDuplication.path() - assertThat(subject.lint(path)).hasSize(0) - } - } + it("does not report duplicated parts in multiline strings") { + val path = Case.MultilineStringLiteralDuplication.path() + assertThat(subject.lint(path)).hasSize(0) + } + } }) private fun SubjectProviderDsl.assertCodeFindings(code: String, expected: Int) { - assertThat(subject.lint(code)).hasSize(expected) + assertThat(subject.lint(code)).hasSize(expected) } private fun assertFindingWithConfig(code: String, config: TestConfig, expected: Int) { - val findings = StringLiteralDuplication(config).lint(code) - assertThat(findings).hasSize(expected) + val findings = StringLiteralDuplication(config).lint(code) + assertThat(findings).hasSize(expected) } diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/TooManyFunctionsSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/TooManyFunctionsSpec.kt index 28025dbcf..108871694 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/TooManyFunctionsSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/TooManyFunctionsSpec.kt @@ -13,77 +13,77 @@ import org.jetbrains.spek.api.dsl.it */ class TooManyFunctionsSpec : Spek({ - describe("a simple test") { + describe("a simple test") { - val rule = TooManyFunctions() + val rule = TooManyFunctions() - it("should find one file with too many functions") { - assertThat(rule.lint(Case.TooManyFunctions.path())).hasSize(1) - } + it("should find one file with too many functions") { + assertThat(rule.lint(Case.TooManyFunctions.path())).hasSize(1) + } - it("should find one file with too many top level functions") { - assertThat(rule.lint(Case.TooManyFunctionsTopLevel.path())).hasSize(1) - } - } + it("should find one file with too many top level functions") { + assertThat(rule.lint(Case.TooManyFunctionsTopLevel.path())).hasSize(1) + } + } - describe("different declarations with one function as threshold") { + describe("different declarations with one function as threshold") { - val rule = TooManyFunctions(TestConfig(mapOf( - TooManyFunctions.THRESHOLD_IN_CLASSES to "1", - TooManyFunctions.THRESHOLD_IN_ENUMS to "1", - TooManyFunctions.THRESHOLD_IN_FILES to "1", - TooManyFunctions.THRESHOLD_IN_INTERFACES to "1", - TooManyFunctions.THRESHOLD_IN_OBJECTS to "1" - ))) + val rule = TooManyFunctions(TestConfig(mapOf( + TooManyFunctions.THRESHOLD_IN_CLASSES to "1", + TooManyFunctions.THRESHOLD_IN_ENUMS to "1", + TooManyFunctions.THRESHOLD_IN_FILES to "1", + TooManyFunctions.THRESHOLD_IN_INTERFACES to "1", + TooManyFunctions.THRESHOLD_IN_OBJECTS to "1" + ))) - it("finds one function in class") { - val code = """ + it("finds one function in class") { + val code = """ class A { fun a() = Unit } """ - assertThat(rule.lint(code)).hasSize(1) - } + assertThat(rule.lint(code)).hasSize(1) + } - it("finds one function in object") { - val code = """ + it("finds one function in object") { + val code = """ object O { fun o() = Unit } """ - assertThat(rule.lint(code)).hasSize(1) - } + assertThat(rule.lint(code)).hasSize(1) + } - it("finds one function in interface") { - val code = """ + it("finds one function in interface") { + val code = """ interface I { fun i() } """ - assertThat(rule.lint(code)).hasSize(1) - } + assertThat(rule.lint(code)).hasSize(1) + } - it("finds one function in enum") { - val code = """ + it("finds one function in enum") { + val code = """ enum class E { fun E() } """ - assertThat(rule.lint(code)).hasSize(1) - } + assertThat(rule.lint(code)).hasSize(1) + } - it("finds one function in file") { - val code = "fun f = Unit" + it("finds one function in file") { + val code = "fun f = Unit" - assertThat(rule.lint(code)).hasSize(1) - } + assertThat(rule.lint(code)).hasSize(1) + } - it("finds one function in file ignoring other declarations") { - val code = """ + it("finds one function in file ignoring other declarations") { + val code = """ fun f1 = Unit class C object O @@ -93,11 +93,11 @@ class TooManyFunctionsSpec : Spek({ fun f3 = Unit """ - assertThat(rule.lint(code)).hasSize(1) - } + assertThat(rule.lint(code)).hasSize(1) + } - it("finds one function in nested class") { - val code = """ + it("finds one function in nested class") { + val code = """ class A { class B { class C { @@ -107,12 +107,12 @@ class TooManyFunctionsSpec : Spek({ } """ - assertThat(rule.lint(code)).hasSize(1) - } + assertThat(rule.lint(code)).hasSize(1) + } - describe("different deprecated functions") { + describe("different deprecated functions") { - val code = """ + val code = """ @Deprecated fun f() { } @@ -123,24 +123,24 @@ class TooManyFunctionsSpec : Spek({ } } """ - it("finds all deprecated functions per default") { + it("finds all deprecated functions per default") { - assertThat(rule.lint(code)).hasSize(2) - } + assertThat(rule.lint(code)).hasSize(2) + } - it("finds no deprecated functions") { - val configuredRule = TooManyFunctions(TestConfig(mapOf( - TooManyFunctions.THRESHOLD_IN_CLASSES to "1", - TooManyFunctions.THRESHOLD_IN_FILES to "1", - TooManyFunctions.IGNORE_DEPRECATED to "true" - ))) - assertThat(configuredRule.lint(code)).isEmpty() - } - } + it("finds no deprecated functions") { + val configuredRule = TooManyFunctions(TestConfig(mapOf( + TooManyFunctions.THRESHOLD_IN_CLASSES to "1", + TooManyFunctions.THRESHOLD_IN_FILES to "1", + TooManyFunctions.IGNORE_DEPRECATED to "true" + ))) + assertThat(configuredRule.lint(code)).isEmpty() + } + } - describe("different private functions") { + describe("different private functions") { - val code = """ + val code = """ private fun f() { } @@ -150,37 +150,37 @@ class TooManyFunctionsSpec : Spek({ } """ - it("finds all private functions per default") { - assertThat(rule.lint(code)).hasSize(2) - } + it("finds all private functions per default") { + assertThat(rule.lint(code)).hasSize(2) + } - it("finds no private functions") { - val configuredRule = TooManyFunctions(TestConfig(mapOf( - TooManyFunctions.THRESHOLD_IN_CLASSES to "1", - TooManyFunctions.THRESHOLD_IN_FILES to "1", - TooManyFunctions.IGNORE_PRIVATE to "true" - ))) - assertThat(configuredRule.lint(code)).isEmpty() - } - } + it("finds no private functions") { + val configuredRule = TooManyFunctions(TestConfig(mapOf( + TooManyFunctions.THRESHOLD_IN_CLASSES to "1", + TooManyFunctions.THRESHOLD_IN_FILES to "1", + TooManyFunctions.IGNORE_PRIVATE to "true" + ))) + assertThat(configuredRule.lint(code)).isEmpty() + } + } - describe("false negative when private and deprecated functions are ignored - #1439") { + describe("false negative when private and deprecated functions are ignored - #1439") { - it("should not report when file has no public functions") { - val code = """ + it("should not report when file has no public functions") { + val code = """ private fun a() = Unit private fun b() = Unit @Deprecated private fun c() = Unit """.trimIndent() - val configuredRule = TooManyFunctions(TestConfig(mapOf( - TooManyFunctions.THRESHOLD_IN_CLASSES to "1", - TooManyFunctions.THRESHOLD_IN_FILES to "1", - TooManyFunctions.IGNORE_PRIVATE to "true", - TooManyFunctions.IGNORE_DEPRECATED to "true" - ))) - assertThat(configuredRule.lint(code)).isEmpty() - } - } - } + val configuredRule = TooManyFunctions(TestConfig(mapOf( + TooManyFunctions.THRESHOLD_IN_CLASSES to "1", + TooManyFunctions.THRESHOLD_IN_FILES to "1", + TooManyFunctions.IGNORE_PRIVATE to "true", + TooManyFunctions.IGNORE_DEPRECATED to "true" + ))) + assertThat(configuredRule.lint(code)).isEmpty() + } + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/CommentOverPrivateMethodSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/CommentOverPrivateMethodSpec.kt index 6f51cd5c7..5dd79217a 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/CommentOverPrivateMethodSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/CommentOverPrivateMethodSpec.kt @@ -11,39 +11,39 @@ import org.jetbrains.spek.subject.SubjectSpek * @author schalkms */ class CommentOverPrivateMethodSpec : SubjectSpek({ - subject { CommentOverPrivateFunction() } + subject { CommentOverPrivateFunction() } - given("some methods with comments") { + given("some methods with comments") { - it("reports private method with a comment") { - val code = """ + it("reports private method with a comment") { + val code = """ class Test { /** * asdf */ private fun f() {} }""" - assertThat(subject.compileAndLint(code)).hasSize(1) - } + assertThat(subject.compileAndLint(code)).hasSize(1) + } - it("does not report public method with a comment") { - val code = """ + it("does not report public method with a comment") { + val code = """ /** * asdf */ fun f() {}""" - assertThat(subject.compileAndLint(code)).hasSize(0) - } + assertThat(subject.compileAndLint(code)).hasSize(0) + } - it("does not report public method in a class with a comment") { - val code = """ + it("does not report public method in a class with a comment") { + val code = """ class Test { /** * asdf */ fun f() {} }""" - assertThat(subject.compileAndLint(code)).hasSize(0) - } - } + assertThat(subject.compileAndLint(code)).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/CommentOverPrivatePropertiesSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/CommentOverPrivatePropertiesSpec.kt index 810099341..607f9fc46 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/CommentOverPrivatePropertiesSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/CommentOverPrivatePropertiesSpec.kt @@ -11,48 +11,48 @@ import org.jetbrains.spek.subject.SubjectSpek * @author schalkms */ class CommentOverPrivatePropertiesSpec : SubjectSpek({ - subject { CommentOverPrivateProperty() } + subject { CommentOverPrivateProperty() } - given("some properties with comments") { + given("some properties with comments") { - it("reports private property with a comment") { - val code = """ + it("reports private property with a comment") { + val code = """ /** * asdf */ private val v = 1""" - assertThat(subject.compileAndLint(code)).hasSize(1) - } + assertThat(subject.compileAndLint(code)).hasSize(1) + } - it("does not report public property with a comment") { - val code = """ + it("does not report public property with a comment") { + val code = """ /** * asdf */ val v = 1""" - assertThat(subject.compileAndLint(code)).hasSize(0) - } + assertThat(subject.compileAndLint(code)).hasSize(0) + } - it("reports private property in class with a comment") { - val code = """ + it("reports private property in class with a comment") { + val code = """ class Test { /** * asdf */ private val v = 1 }""" - assertThat(subject.compileAndLint(code)).hasSize(1) - } + assertThat(subject.compileAndLint(code)).hasSize(1) + } - it("does not report public property with a comment") { - val code = """ + it("does not report public property with a comment") { + val code = """ class Test { /** * asdf */ val v = 1 }""" - assertThat(subject.compileAndLint(code)).hasSize(0) - } - } + assertThat(subject.compileAndLint(code)).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/EndOfSentenceFormatSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/EndOfSentenceFormatSpec.kt index 1cc548d75..74748b543 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/EndOfSentenceFormatSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/EndOfSentenceFormatSpec.kt @@ -10,77 +10,77 @@ import org.jetbrains.spek.subject.SubjectSpek * @author schalkms */ class EndOfSentenceFormatSpec : SubjectSpek({ - subject { KDocStyle() } + subject { KDocStyle() } - it("reports invalid KDoc endings on classes") { - val code = """ + it("reports invalid KDoc endings on classes") { + val code = """ /** Some doc */ class Test { } """ - assertThat(subject.compileAndLint(code)).hasSize(1) - } + assertThat(subject.compileAndLint(code)).hasSize(1) + } - it("reports invalid KDoc endings on objects") { - val code = """ + it("reports invalid KDoc endings on objects") { + val code = """ /** Some doc */ object Test { } """ - assertThat(subject.compileAndLint(code)).hasSize(1) - } + assertThat(subject.compileAndLint(code)).hasSize(1) + } - it("reports invalid KDoc endings on properties") { - val code = """ + it("reports invalid KDoc endings on properties") { + val code = """ class Test { /** Some doc */ val test = 3 } """ - assertThat(subject.compileAndLint(code)).hasSize(1) - } + assertThat(subject.compileAndLint(code)).hasSize(1) + } - it("reports invalid KDoc endings on top-level functions") { - val code = """ + it("reports invalid KDoc endings on top-level functions") { + val code = """ /** Some doc */ fun test() = 3 """ - assertThat(subject.compileAndLint(code)).hasSize(1) - } + assertThat(subject.compileAndLint(code)).hasSize(1) + } - it("reports invalid KDoc endings on functions") { - val code = """ + it("reports invalid KDoc endings on functions") { + val code = """ class Test { /** Some doc */ fun test() = 3 } """ - assertThat(subject.compileAndLint(code)).hasSize(1) - } + assertThat(subject.compileAndLint(code)).hasSize(1) + } - it("reports invalid KDoc endings") { - val code = """ + it("reports invalid KDoc endings") { + val code = """ class Test { /** Some doc-- */ fun test() = 3 } """ - assertThat(subject.compileAndLint(code)).hasSize(1) - } + assertThat(subject.compileAndLint(code)).hasSize(1) + } - it("reports invalid KDoc endings in block") { - val code = """ + it("reports invalid KDoc endings in block") { + val code = """ /** * Something off abc@@ */ class Test { } """ - assertThat(subject.compileAndLint(code)).hasSize(1) - } + assertThat(subject.compileAndLint(code)).hasSize(1) + } - it("does not validate first sentence KDoc endings in a multi sentence comment") { - val code = """ + it("does not validate first sentence KDoc endings in a multi sentence comment") { + val code = """ /** * This sentence is correct. * @@ -89,22 +89,22 @@ class EndOfSentenceFormatSpec : SubjectSpek({ class Test { } """ - assertThat(subject.compileAndLint(code)).isEmpty() - } + assertThat(subject.compileAndLint(code)).isEmpty() + } - it("does not report KDoc which doesn't contain any real sentence") { - val code = """ + it("does not report KDoc which doesn't contain any real sentence") { + val code = """ /** * @author Someone */ class Test { } """ - assertThat(subject.compileAndLint(code)).isEmpty() - } + assertThat(subject.compileAndLint(code)).isEmpty() + } - it("does not report KDoc which doesn't contain any real sentence but many tags") { - val code = """ + it("does not report KDoc which doesn't contain any real sentence but many tags") { + val code = """ /** * @configuration this - just an example (default: 150) * @@ -115,11 +115,11 @@ class EndOfSentenceFormatSpec : SubjectSpek({ class Test { } """ - assertThat(subject.compileAndLint(code)).isEmpty() - } + assertThat(subject.compileAndLint(code)).isEmpty() + } - it("does not report KDoc which doesn't contain any real sentence but html tags") { - val code = """ + it("does not report KDoc which doesn't contain any real sentence but html tags") { + val code = """ /** * * @@ -135,44 +135,44 @@ class EndOfSentenceFormatSpec : SubjectSpek({ class Test { } """ - assertThat(subject.compileAndLint(code)).isEmpty() - } + assertThat(subject.compileAndLint(code)).isEmpty() + } - it("does not report KDoc ending with periods") { - val code = """ + it("does not report KDoc ending with periods") { + val code = """ /** * Something correct. */ class Test { } """ - assertThat(subject.compileAndLint(code)).isEmpty() - } + assertThat(subject.compileAndLint(code)).isEmpty() + } - it("does not report KDoc ending with questionmarks") { - val code = """ + it("does not report KDoc ending with questionmarks") { + val code = """ /** * Something correct? */ class Test { } """ - assertThat(subject.compileAndLint(code)).isEmpty() - } + assertThat(subject.compileAndLint(code)).isEmpty() + } - it("does not report KDoc ending with exclamation marks") { - val code = """ + it("does not report KDoc ending with exclamation marks") { + val code = """ /** * Something correct! */ class Test { } """ - assertThat(subject.compileAndLint(code)).isEmpty() - } + assertThat(subject.compileAndLint(code)).isEmpty() + } - it("does not report URLs in comments") { - val code = """ + it("does not report URLs in comments") { + val code = """ /** http://www.google.com */ class Test1 { } @@ -182,6 +182,6 @@ class EndOfSentenceFormatSpec : SubjectSpek({ class Test2 { } """ - assertThat(subject.compileAndLint(code)).isEmpty() - } + assertThat(subject.compileAndLint(code)).isEmpty() + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicClassSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicClassSpec.kt index 376f734c5..eb3824d5b 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicClassSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicClassSpec.kt @@ -11,107 +11,107 @@ import org.jetbrains.spek.subject.SubjectSpek * @author schalkms */ class UndocumentedPublicClassSpec : SubjectSpek({ - subject { UndocumentedPublicClass() } + subject { UndocumentedPublicClass() } - val inner = """ + val inner = """ /** Some doc */ class TestInner { inner class Inner }""" - val innerObject = """ + val innerObject = """ /** Some doc */ class TestInner { object Inner }""" - val innerInterface = """ + val innerInterface = """ /** Some doc */ class TestInner { interface Something }""" - val nested = """ + val nested = """ /** Some doc */ class TestNested { class Nested }""" - val nestedPublic = """ + val nestedPublic = """ /** Some doc */ class TestNested { public class Nested } """ - val nestedPrivate = """ + val nestedPrivate = """ /** Some doc */ class TestNested { private class Nested } """ - val privateClass = "private class TestNested {}" - val internalClass = "internal class TestNested {}" + val privateClass = "private class TestNested {}" + val internalClass = "internal class TestNested {}" - it("should report inner classes by default") { - assertThat(subject.compileAndLint(inner)).hasSize(1) - } + it("should report inner classes by default") { + assertThat(subject.compileAndLint(inner)).hasSize(1) + } - it("should report inner object by default") { - assertThat(subject.compileAndLint(innerObject)).hasSize(1) - } + it("should report inner object by default") { + assertThat(subject.compileAndLint(innerObject)).hasSize(1) + } - it("should report inner interfaces by default") { - assertThat(subject.compileAndLint(innerInterface)).hasSize(1) - } + it("should report inner interfaces by default") { + assertThat(subject.compileAndLint(innerInterface)).hasSize(1) + } - it("should report nested classes by default") { - assertThat(subject.compileAndLint(nested)).hasSize(1) - } + it("should report nested classes by default") { + assertThat(subject.compileAndLint(nested)).hasSize(1) + } - it("should report explicit public nested classes by default") { - assertThat(subject.compileAndLint(nestedPublic)).hasSize(1) - } + it("should report explicit public nested classes by default") { + assertThat(subject.compileAndLint(nestedPublic)).hasSize(1) + } - it("should not report internal classes") { - assertThat(subject.compileAndLint(internalClass)).hasSize(0) - } + it("should not report internal classes") { + assertThat(subject.compileAndLint(internalClass)).hasSize(0) + } - it("should not report private classes") { - assertThat(subject.compileAndLint(privateClass)).hasSize(0) - } + it("should not report private classes") { + assertThat(subject.compileAndLint(privateClass)).hasSize(0) + } - it("should not report nested private classes") { - assertThat(subject.compileAndLint(nestedPrivate)).hasSize(0) - } + it("should not report nested private classes") { + assertThat(subject.compileAndLint(nestedPrivate)).hasSize(0) + } - it("should not report inner classes when turned off") { - val findings = UndocumentedPublicClass(TestConfig(mapOf(UndocumentedPublicClass.SEARCH_IN_INNER_CLASS to "false"))).compileAndLint(inner) - assertThat(findings).isEmpty() - } + it("should not report inner classes when turned off") { + val findings = UndocumentedPublicClass(TestConfig(mapOf(UndocumentedPublicClass.SEARCH_IN_INNER_CLASS to "false"))).compileAndLint(inner) + assertThat(findings).isEmpty() + } - it("should not report inner objects when turned off") { - val findings = UndocumentedPublicClass(TestConfig(mapOf(UndocumentedPublicClass.SEARCH_IN_INNER_OBJECT to "false"))).compileAndLint(innerObject) - assertThat(findings).isEmpty() - } + it("should not report inner objects when turned off") { + val findings = UndocumentedPublicClass(TestConfig(mapOf(UndocumentedPublicClass.SEARCH_IN_INNER_OBJECT to "false"))).compileAndLint(innerObject) + assertThat(findings).isEmpty() + } - it("should not report inner interfaces when turned off") { - val findings = UndocumentedPublicClass(TestConfig(mapOf(UndocumentedPublicClass.SEARCH_IN_INNER_INTERFACE to "false"))).compileAndLint(innerInterface) - assertThat(findings).isEmpty() - } + it("should not report inner interfaces when turned off") { + val findings = UndocumentedPublicClass(TestConfig(mapOf(UndocumentedPublicClass.SEARCH_IN_INNER_INTERFACE to "false"))).compileAndLint(innerInterface) + assertThat(findings).isEmpty() + } - it("should not report nested classes when turned off") { - val findings = UndocumentedPublicClass(TestConfig(mapOf(UndocumentedPublicClass.SEARCH_IN_NESTED_CLASS to "false"))).compileAndLint(nested) - assertThat(findings).isEmpty() - } + it("should not report nested classes when turned off") { + val findings = UndocumentedPublicClass(TestConfig(mapOf(UndocumentedPublicClass.SEARCH_IN_NESTED_CLASS to "false"))).compileAndLint(nested) + assertThat(findings).isEmpty() + } - it("should report missing doc over object declaration") { - assertThat(subject.compileAndLint("object o")).hasSize(1) - } + it("should report missing doc over object declaration") { + assertThat(subject.compileAndLint("object o")).hasSize(1) + } - it("should not report for documented public object") { - val code = """ + it("should not report for documented public object") { + val code = """ /** * Class docs not being recognized. */ @@ -127,11 +127,11 @@ class UndocumentedPublicClassSpec : SubjectSpek({ } """ - assertThat(subject.compileAndLint(code)).isEmpty() - } + assertThat(subject.compileAndLint(code)).isEmpty() + } - it("should not report for anonymous objects") { - val code = """ + it("should not report for anonymous objects") { + val code = """ fun main(args: Array) { val value = object : Iterator { override fun hasNext() = true @@ -140,26 +140,26 @@ class UndocumentedPublicClassSpec : SubjectSpek({ } """ - assertThat(subject.compileAndLint(code)).isEmpty() - } + assertThat(subject.compileAndLint(code)).isEmpty() + } - it("should report for enum classes") { - val code = """ + it("should report for enum classes") { + val code = """ enum class Enum { CONSTANT } """ - assertThat(subject.compileAndLint(code)).hasSize(1) - } + assertThat(subject.compileAndLint(code)).hasSize(1) + } - it("should not report for enum constants") { - val code = """ + it("should not report for enum constants") { + val code = """ /** Some doc */ enum class Enum { CONSTANT } """ - assertThat(subject.compileAndLint(code)).isEmpty() - } + assertThat(subject.compileAndLint(code)).isEmpty() + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicFunctionSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicFunctionSpec.kt index 9f298ada3..e2f6d5624 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicFunctionSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicFunctionSpec.kt @@ -11,19 +11,19 @@ import org.jetbrains.spek.subject.SubjectSpek * @author schalkms */ class UndocumentedPublicFunctionSpec : SubjectSpek({ - subject { UndocumentedPublicFunction() } + subject { UndocumentedPublicFunction() } - given("several functions") { + given("several functions") { - it("reports undocumented public functions") { - val code = """ + it("reports undocumented public functions") { + val code = """ fun noComment1() {} """ - assertThat(subject.compileAndLint(code)).hasSize(1) - } + assertThat(subject.compileAndLint(code)).hasSize(1) + } - it("reports undocumented public functions in companion object") { - val code = """ + it("reports undocumented public functions in companion object") { + val code = """ class Test { companion object { fun noComment1() {} @@ -31,21 +31,21 @@ class UndocumentedPublicFunctionSpec : SubjectSpek({ } } """ - assertThat(subject.compileAndLint(code)).hasSize(2) - } + assertThat(subject.compileAndLint(code)).hasSize(2) + } - it("does not report documented public function") { - val code = """ + it("does not report documented public function") { + val code = """ /** * Comment */ fun commented1() {} """ - assertThat(subject.compileAndLint(code)).isEmpty() - } + assertThat(subject.compileAndLint(code)).isEmpty() + } - it("does not report documented public function in class") { - val code = """ + it("does not report documented public function in class") { + val code = """ class Test { /** * @@ -58,21 +58,21 @@ class UndocumentedPublicFunctionSpec : SubjectSpek({ fun commented2() {} } """ - assertThat(subject.compileAndLint(code)).isEmpty() - } + assertThat(subject.compileAndLint(code)).isEmpty() + } - it("does not report udocumented internal and private function") { - val code = """ + it("does not report udocumented internal and private function") { + val code = """ class Test { internal fun no1(){} private fun no2(){} } """ - assertThat(subject.compileAndLint(code)).isEmpty() - } + assertThat(subject.compileAndLint(code)).isEmpty() + } - it("does not report undocumented nested function") { - val code = """ + it("does not report undocumented nested function") { + val code = """ /** * Comment */ @@ -80,11 +80,11 @@ class UndocumentedPublicFunctionSpec : SubjectSpek({ fun iDontNeedDoc() {} } """ - assertThat(subject.compileAndLint(code)).isEmpty() - } + assertThat(subject.compileAndLint(code)).isEmpty() + } - it("does not report public functions in internal class") { - val code = """ + it("does not report public functions in internal class") { + val code = """ internal class NoComments { fun nope0() {} @@ -94,11 +94,11 @@ class UndocumentedPublicFunctionSpec : SubjectSpek({ private fun nope4() {} } """ - assertThat(subject.compileAndLint(code)).isEmpty() - } + assertThat(subject.compileAndLint(code)).isEmpty() + } - it("does not report public functions in private class") { - val code = """ + it("does not report public functions in private class") { + val code = """ private class NoComments { fun nope0() {} @@ -108,7 +108,7 @@ class UndocumentedPublicFunctionSpec : SubjectSpek({ private fun nope4() {} } """ - assertThat(subject.compileAndLint(code)).isEmpty() - } - } + assertThat(subject.compileAndLint(code)).isEmpty() + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/empty/CommentInsideBlockSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/empty/CommentInsideBlockSpec.kt index d36939e40..766011922 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/empty/CommentInsideBlockSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/empty/CommentInsideBlockSpec.kt @@ -12,20 +12,20 @@ import org.jetbrains.spek.api.dsl.it */ class CommentInsideBlockSpec : Spek({ - class NotConfiguredEmptyRule : EmptyRule(Config.empty) { - override fun visitBlockExpression(expression: KtBlockExpression) = - expression.addFindingIfBlockExprIsEmpty() - } + class NotConfiguredEmptyRule : EmptyRule(Config.empty) { + override fun visitBlockExpression(expression: KtBlockExpression) = + expression.addFindingIfBlockExprIsEmpty() + } - val subject = NotConfiguredEmptyRule() + val subject = NotConfiguredEmptyRule() - it("does not find comment inside an empty block") { - val findings = subject.lint("{/*comment*/}") - assertThat(findings).isEmpty() - } + it("does not find comment inside an empty block") { + val findings = subject.lint("{/*comment*/}") + assertThat(findings).isEmpty() + } - it("finds comments inside block") { - val findings = subject.lint("{}") - assertThat(findings).hasSize(1) - } + it("finds comments inside block") { + val findings = subject.lint("{}") + assertThat(findings).hasSize(1) + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyBlocksMultiRuleSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyBlocksMultiRuleSpec.kt index a3ecf0878..2b99f8048 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyBlocksMultiRuleSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyBlocksMultiRuleSpec.kt @@ -15,31 +15,31 @@ import org.jetbrains.spek.subject.SubjectSpek */ class EmptyBlocksMultiRuleSpec : SubjectSpek({ - subject { EmptyBlocks() } + subject { EmptyBlocks() } - val file = compileForTest(Case.Empty.path()) + val file = compileForTest(Case.Empty.path()) - describe("multi rule with all empty block rules") { + describe("multi rule with all empty block rules") { - it("should report one finding per rule") { - val findings = subject.lint(file) - // -1 because the empty kt file rule doesn't get triggered in the 'Empty' test file - val rulesSize = subject.rules.size - 1 - assertThat(findings).hasSize(rulesSize) - } + it("should report one finding per rule") { + val findings = subject.lint(file) + // -1 because the empty kt file rule doesn't get triggered in the 'Empty' test file + val rulesSize = subject.rules.size - 1 + assertThat(findings).hasSize(rulesSize) + } - it("should not report any as all empty block rules are deactivated") { - val config = yamlConfig("deactivated-empty-blocks.yml") - val ruleSet = EmptyCodeProvider().buildRuleset(config) + it("should not report any as all empty block rules are deactivated") { + val config = yamlConfig("deactivated-empty-blocks.yml") + val ruleSet = EmptyCodeProvider().buildRuleset(config) - val findings = ruleSet?.accept(file) + val findings = ruleSet?.accept(file) - assertThat(findings).hasSize(0) - } + assertThat(findings).hasSize(0) + } - it("reports an empty kt file") { - val findings = subject.lint(Case.EmptyKtFile.path()) - assertThat(findings).hasSize(1) - } - } + it("reports an empty kt file") { + val findings = subject.lint(Case.EmptyKtFile.path()) + assertThat(findings).hasSize(1) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyClassBlockSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyClassBlockSpec.kt index 86d9aea68..f2263f741 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyClassBlockSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyClassBlockSpec.kt @@ -12,26 +12,26 @@ import org.jetbrains.spek.subject.SubjectSpek */ class EmptyClassBlockSpec : SubjectSpek({ - subject { EmptyClassBlock(Config.empty) } + subject { EmptyClassBlock(Config.empty) } - given("a class with an empty body") { + given("a class with an empty body") { - it("flags the empty body") { - val findings = subject.lint("class SomeClass {}") - assertThat(findings).hasSize(1) - } - } + it("flags the empty body") { + val findings = subject.lint("class SomeClass {}") + assertThat(findings).hasSize(1) + } + } - given("an object with an empty body") { + given("an object with an empty body") { - it("flags the object if it is of a non-anonymous class") { - val findings = subject.lint("object SomeObject {}") - assertThat(findings).hasSize(1) - } + it("flags the object if it is of a non-anonymous class") { + val findings = subject.lint("object SomeObject {}") + assertThat(findings).hasSize(1) + } - it("does not flag the object if it is of an anonymous class") { - val findings = subject.lint("object : SomeClass {}") - assertThat(findings).isEmpty() - } - } + it("does not flag the object if it is of an anonymous class") { + val findings = subject.lint("object : SomeClass {}") + assertThat(findings).isEmpty() + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyCodeSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyCodeSpec.kt index 11cc20513..7e1a8049e 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyCodeSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyCodeSpec.kt @@ -6,30 +6,30 @@ import io.gitlab.arturbosch.detekt.rules.Case import io.gitlab.arturbosch.detekt.test.TestConfig import io.gitlab.arturbosch.detekt.test.compileForTest import io.gitlab.arturbosch.detekt.test.lint +import java.util.regex.PatternSyntaxException import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThatExceptionOfType import org.jetbrains.spek.api.Spek import org.jetbrains.spek.api.dsl.it -import java.util.regex.PatternSyntaxException /** * @author Artur Bosch */ class EmptyCodeSpec : Spek({ - val regexTestingCode = """ + val regexTestingCode = """ fun f() { try { } catch (foo: MyException) { } }""" - it("findsEmptyCatch") { - test { EmptyCatchBlock(Config.empty) } - } + it("findsEmptyCatch") { + test { EmptyCatchBlock(Config.empty) } + } - it("findsEmptyNestedCatch") { - val code = """ + it("findsEmptyNestedCatch") { + val code = """ fun f() { try { } catch (ignore: IOException) { @@ -38,105 +38,105 @@ class EmptyCodeSpec : Spek({ } } }""" - assertThat(EmptyCatchBlock(Config.empty).lint(code)).hasSize(1) - } + assertThat(EmptyCatchBlock(Config.empty).lint(code)).hasSize(1) + } - it("doesNotReportIgnoredOrExpectedException") { - val code = """ + it("doesNotReportIgnoredOrExpectedException") { + val code = """ fun f() { try { } catch (ignore: IOException) { } catch (expected: Exception) { } }""" - assertThat(EmptyCatchBlock(Config.empty).lint(code)).isEmpty() - } + assertThat(EmptyCatchBlock(Config.empty).lint(code)).isEmpty() + } - it("doesNotReportEmptyCatchWithConfig") { - val code = """ + it("doesNotReportEmptyCatchWithConfig") { + val code = """ fun f() { try { } catch (foo: MyException) { } }""" - val config = TestConfig(mapOf(EmptyCatchBlock.ALLOWED_EXCEPTION_NAME_REGEX to "foo")) - assertThat(EmptyCatchBlock(config).lint(code)).isEmpty() - } + val config = TestConfig(mapOf(EmptyCatchBlock.ALLOWED_EXCEPTION_NAME_REGEX to "foo")) + assertThat(EmptyCatchBlock(config).lint(code)).isEmpty() + } - it("findsEmptyFinally") { - test { EmptyFinallyBlock(Config.empty) } - } + it("findsEmptyFinally") { + test { EmptyFinallyBlock(Config.empty) } + } - it("findsEmptyIf") { - test { EmptyIfBlock(Config.empty) } - } + it("findsEmptyIf") { + test { EmptyIfBlock(Config.empty) } + } - it("findsEmptyElse") { - test { EmptyElseBlock(Config.empty) } - } + it("findsEmptyElse") { + test { EmptyElseBlock(Config.empty) } + } - it("findsEmptyFor") { - test { EmptyForBlock(Config.empty) } - } + it("findsEmptyFor") { + test { EmptyForBlock(Config.empty) } + } - it("findsEmptyWhile") { - test { EmptyWhileBlock(Config.empty) } - } + it("findsEmptyWhile") { + test { EmptyWhileBlock(Config.empty) } + } - it("findsEmptyDoWhile") { - test { EmptyDoWhileBlock(Config.empty) } - } + it("findsEmptyDoWhile") { + test { EmptyDoWhileBlock(Config.empty) } + } - it("findsEmptyFun") { - test { EmptyFunctionBlock(Config.empty) } - } + it("findsEmptyFun") { + test { EmptyFunctionBlock(Config.empty) } + } - it("findsEmptyClass") { - test { EmptyClassBlock(Config.empty) } - } + it("findsEmptyClass") { + test { EmptyClassBlock(Config.empty) } + } - it("findsEmptyWhen") { - test { EmptyWhenBlock(Config.empty) } - } + it("findsEmptyWhen") { + test { EmptyWhenBlock(Config.empty) } + } - it("findsEmptyInit") { - test { EmptyInitBlock(Config.empty) } - } + it("findsEmptyInit") { + test { EmptyInitBlock(Config.empty) } + } - it("findsOneEmptySecondaryConstructor") { - test { EmptySecondaryConstructor(Config.empty) } - } + it("findsOneEmptySecondaryConstructor") { + test { EmptySecondaryConstructor(Config.empty) } + } - it("findsEmptyDefaultConstructor") { - val rule = EmptyDefaultConstructor(Config.empty) - val text = compileForTest(Case.EmptyDefaultConstructorPositive.path()).text - assertThat(rule.lint(text)).hasSize(2) - } + it("findsEmptyDefaultConstructor") { + val rule = EmptyDefaultConstructor(Config.empty) + val text = compileForTest(Case.EmptyDefaultConstructorPositive.path()).text + assertThat(rule.lint(text)).hasSize(2) + } - it("doesNotFindEmptyDefaultConstructor") { - val rule = EmptyDefaultConstructor(Config.empty) - val text = compileForTest(Case.EmptyDefaultConstructorNegative.path()).text - assertThat(rule.lint(text)).isEmpty() - } + it("doesNotFindEmptyDefaultConstructor") { + val rule = EmptyDefaultConstructor(Config.empty) + val text = compileForTest(Case.EmptyDefaultConstructorNegative.path()).text + assertThat(rule.lint(text)).isEmpty() + } - it("doesNotFailWithInvalidRegexWhenDisabled") { - val configValues = mapOf("active" to "false", - EmptyCatchBlock.ALLOWED_EXCEPTION_NAME_REGEX to "*foo") - val config = TestConfig(configValues) - assertThat(EmptyCatchBlock(config).lint(regexTestingCode)).isEmpty() - } + it("doesNotFailWithInvalidRegexWhenDisabled") { + val configValues = mapOf("active" to "false", + EmptyCatchBlock.ALLOWED_EXCEPTION_NAME_REGEX to "*foo") + val config = TestConfig(configValues) + assertThat(EmptyCatchBlock(config).lint(regexTestingCode)).isEmpty() + } - it("doesFailWithInvalidRegex") { - val configValues = mapOf(EmptyCatchBlock.ALLOWED_EXCEPTION_NAME_REGEX to "*foo") - val config = TestConfig(configValues) - assertThatExceptionOfType(PatternSyntaxException::class.java).isThrownBy { - EmptyCatchBlock(config).lint(regexTestingCode) - } - } + it("doesFailWithInvalidRegex") { + val configValues = mapOf(EmptyCatchBlock.ALLOWED_EXCEPTION_NAME_REGEX to "*foo") + val config = TestConfig(configValues) + assertThatExceptionOfType(PatternSyntaxException::class.java).isThrownBy { + EmptyCatchBlock(config).lint(regexTestingCode) + } + } }) private fun test(block: () -> Rule) { - val rule = block() - rule.lint(compileForTest(Case.Empty.path())) - assertThat(rule.findings).hasSize(1) + val rule = block() + rule.lint(compileForTest(Case.Empty.path())) + assertThat(rule.findings).hasSize(1) } diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyConstructorSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyConstructorSpec.kt index 47d873006..5f1126d1e 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyConstructorSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyConstructorSpec.kt @@ -11,8 +11,8 @@ import org.jetbrains.spek.api.dsl.it */ class EmptyConstructorSpec : Spek({ - it("should not report empty constructors for annotation classes with expect or actual keyword - #1362") { - val code = """ + it("should not report empty constructors for annotation classes with expect or actual keyword - #1362") { + val code = """ expect annotation class NeedsConstructor() actual annotation class NeedsConstructor actual constructor() @@ -20,8 +20,8 @@ class EmptyConstructorSpec : Spek({ fun annotatedFunction() = Unit """.trimIndent() - val findings = EmptyDefaultConstructor(Config.empty).lint(code) + val findings = EmptyDefaultConstructor(Config.empty).lint(code) - assertThat(findings).isEmpty() - } + assertThat(findings).isEmpty() + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyFunctionBlockSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyFunctionBlockSpec.kt index 1f5cda36e..fe0be3867 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyFunctionBlockSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyFunctionBlockSpec.kt @@ -13,32 +13,32 @@ import org.jetbrains.spek.subject.SubjectSpek */ class EmptyFunctionBlockSpec : SubjectSpek({ - subject { EmptyFunctionBlock(Config.empty) } + subject { EmptyFunctionBlock(Config.empty) } - given("some functions") { + given("some functions") { - it("should flag function with protected modifier") { - val code = "protected fun stuff() {}" - assertThat(subject.lint(code)).hasSize(1) - } + it("should flag function with protected modifier") { + val code = "protected fun stuff() {}" + assertThat(subject.lint(code)).hasSize(1) + } - it("should not flag function with open modifier") { - val code = "open fun stuff() {}" - assertThat(subject.lint(code)).isEmpty() - } + it("should not flag function with open modifier") { + val code = "open fun stuff() {}" + assertThat(subject.lint(code)).isEmpty() + } - it("should flag the nested empty function") { - val code = """ + it("should flag the nested empty function") { + val code = """ fun a() { fun b() {} }""" - assertThat(subject.lint(code)).hasSize(1) - } - } + assertThat(subject.lint(code)).hasSize(1) + } + } - given("some overridden functions") { + given("some overridden functions") { - val code = """ + val code = """ fun empty() {} override fun stuff1() {} @@ -51,13 +51,13 @@ class EmptyFunctionBlockSpec : SubjectSpek({ // this is necessary... }""" - it("should flag empty block in overridden function") { - assertThat(subject.lint(code)).hasSize(2) - } + it("should flag empty block in overridden function") { + assertThat(subject.lint(code)).hasSize(2) + } - it("should not flag overridden functions") { - val config = TestConfig(mapOf(EmptyFunctionBlock.IGNORE_OVERRIDDEN_FUNCTIONS to "true")) - assertThat(EmptyFunctionBlock(config).lint(code)).hasSize(1) - } - } + it("should not flag overridden functions") { + val config = TestConfig(mapOf(EmptyFunctionBlock.IGNORE_OVERRIDDEN_FUNCTIONS to "true")) + assertThat(EmptyFunctionBlock(config).lint(code)).hasSize(1) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyIfBlockSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyIfBlockSpec.kt index b7b49582a..d59170bcf 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyIfBlockSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyIfBlockSpec.kt @@ -13,18 +13,18 @@ import org.jetbrains.spek.subject.SubjectSpek */ class EmptyIfBlockSpec : SubjectSpek({ - subject { EmptyIfBlock(Config.empty) } + subject { EmptyIfBlock(Config.empty) } - given("several empty if statements") { + given("several empty if statements") { - it("reports positive cases") { - val path = Case.EmptyIfPositive.path() - assertThat(subject.lint(path)).hasSize(4) - } + it("reports positive cases") { + val path = Case.EmptyIfPositive.path() + assertThat(subject.lint(path)).hasSize(4) + } - it("does not report negative cases") { - val path = Case.EmptyIfNegative.path() - assertThat(subject.lint(path)).hasSize(0) - } - } + it("does not report negative cases") { + val path = Case.EmptyIfNegative.path() + assertThat(subject.lint(path)).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ExceptionRaisedInUnexpectedLocationSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ExceptionRaisedInUnexpectedLocationSpec.kt index 7dff386d7..bf7b11a93 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ExceptionRaisedInUnexpectedLocationSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ExceptionRaisedInUnexpectedLocationSpec.kt @@ -9,34 +9,34 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class ExceptionRaisedInUnexpectedLocationSpec : SubjectSpek({ - subject { - ExceptionRaisedInUnexpectedLocation( - TestConfig(mapOf(ExceptionRaisedInUnexpectedLocation.METHOD_NAMES to "toString,hashCode,equals,finalize")) - ) - } + subject { + ExceptionRaisedInUnexpectedLocation( + TestConfig(mapOf(ExceptionRaisedInUnexpectedLocation.METHOD_NAMES to "toString,hashCode,equals,finalize")) + ) + } - given("methods which throw exceptions") { + given("methods which throw exceptions") { - it("reports methods raising an unexpected exception") { - val path = Case.ExceptionRaisedInMethodsPositive.path() - assertThat(subject.lint(path)).hasSize(5) - } + it("reports methods raising an unexpected exception") { + val path = Case.ExceptionRaisedInMethodsPositive.path() + assertThat(subject.lint(path)).hasSize(5) + } - it("does not report methods raising no exception") { - val path = Case.ExceptionRaisedInMethodsNegative.path() - assertThat(subject.lint(path)).hasSize(0) - } - } + it("does not report methods raising no exception") { + val path = Case.ExceptionRaisedInMethodsNegative.path() + assertThat(subject.lint(path)).hasSize(0) + } + } - given("a configuration with a custom method") { + given("a configuration with a custom method") { - it("reports the configured method") { - val config = TestConfig(mapOf(ExceptionRaisedInUnexpectedLocation.METHOD_NAMES to "toDo,todo2")) - val findings = ExceptionRaisedInUnexpectedLocation(config).lint(""" + it("reports the configured method") { + val config = TestConfig(mapOf(ExceptionRaisedInUnexpectedLocation.METHOD_NAMES to "toDo,todo2")) + val findings = ExceptionRaisedInUnexpectedLocation(config).lint(""" fun toDo() { throw IllegalStateException() }""") - assertThat(findings).hasSize(1) - } - } + assertThat(findings).hasSize(1) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/InstanceOfCheckForExceptionSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/InstanceOfCheckForExceptionSpec.kt index f7713e84e..e78cd4822 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/InstanceOfCheckForExceptionSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/InstanceOfCheckForExceptionSpec.kt @@ -7,12 +7,12 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class InstanceOfCheckForExceptionSpec : SubjectSpek({ - subject { InstanceOfCheckForException() } + subject { InstanceOfCheckForException() } - given("several catch blocks") { + given("several catch blocks") { - it("has is and as checks") { - val code = """ + it("has is and as checks") { + val code = """ fun x() { try { } catch(e: IOException) { @@ -22,11 +22,11 @@ class InstanceOfCheckForExceptionSpec : SubjectSpek } } """ - assertThat(subject.lint(code)).hasSize(2) - } + assertThat(subject.lint(code)).hasSize(2) + } - it("has nested is and as checks") { - val code = """ + it("has nested is and as checks") { + val code = """ fun x() { try { } catch(e: IOException) { @@ -36,11 +36,11 @@ class InstanceOfCheckForExceptionSpec : SubjectSpek } } """ - assertThat(subject.lint(code)).hasSize(2) - } + assertThat(subject.lint(code)).hasSize(2) + } - it("has no instance of check") { - val code = """ + it("has no instance of check") { + val code = """ fun x() { try { } catch(e: IOException) { @@ -51,7 +51,7 @@ class InstanceOfCheckForExceptionSpec : SubjectSpek } } """ - assertThat(subject.lint(code)).hasSize(0) - } - } + assertThat(subject.lint(code)).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/NotImplementedDeclarationSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/NotImplementedDeclarationSpec.kt index 60515a976..a86fa378b 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/NotImplementedDeclarationSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/NotImplementedDeclarationSpec.kt @@ -7,37 +7,37 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class NotImplementedDeclarationSpec : SubjectSpek({ - subject { NotImplementedDeclaration() } + subject { NotImplementedDeclaration() } - given("throwing NotImplementedError declarations") { + given("throwing NotImplementedError declarations") { - it("reports NotImplementedErrors") { - val code = """ + it("reports NotImplementedErrors") { + val code = """ fun f() { if (1 == 1) throw NotImplementedError() throw NotImplementedError() }""" - assertThat(subject.lint(code)).hasSize(2) - } - } + assertThat(subject.lint(code)).hasSize(2) + } + } - given("several TODOs") { + given("several TODOs") { - it("reports TODO method calls") { - val code = """ + it("reports TODO method calls") { + val code = """ fun f() { TODO("not implemented") TODO() }""" - assertThat(subject.lint(code)).hasSize(2) - } + assertThat(subject.lint(code)).hasSize(2) + } - it("does not report TODO comments") { - val code = """ + it("does not report TODO comments") { + val code = """ fun f() { // TODO }""" - assertThat(subject.lint(code)).hasSize(0) - } - } + assertThat(subject.lint(code)).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/PrintStackTraceSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/PrintStackTraceSpec.kt index 3be64a052..1a699c616 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/PrintStackTraceSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/PrintStackTraceSpec.kt @@ -7,23 +7,23 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class PrintStackTraceSpec : SubjectSpek({ - subject { PrintStackTrace() } + subject { PrintStackTrace() } - given("catch clauses with printStacktrace methods") { + given("catch clauses with printStacktrace methods") { - it("prints a stacktrace") { - val code = """ + it("prints a stacktrace") { + val code = """ fun x() { try { } catch (e: Exception) { e.printStackTrace() } }""" - assertThat(subject.lint(code)).hasSize(1) - } + assertThat(subject.lint(code)).hasSize(1) + } - it("does not print a stacktrace") { - val code = """ + it("does not print a stacktrace") { + val code = """ fun x() { try { } catch (e: Exception) { @@ -32,19 +32,19 @@ class PrintStackTraceSpec : SubjectSpek({ printStackTrace() } }""" - assertThat(subject.lint(code)).hasSize(0) - } - } + assertThat(subject.lint(code)).hasSize(0) + } + } - given("a stacktrace printed by a thread") { + given("a stacktrace printed by a thread") { - it("prints one") { - val code = """ + it("prints one") { + val code = """ fun x() { Thread.dumpStack() Foo.dumpStack() }""" - assertThat(subject.lint(code)).hasSize(1) - } - } + assertThat(subject.lint(code)).hasSize(1) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/RethrowCaughtExceptionSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/RethrowCaughtExceptionSpec.kt index df06fcdc9..6ff2e9c02 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/RethrowCaughtExceptionSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/RethrowCaughtExceptionSpec.kt @@ -8,18 +8,18 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class RethrowCaughtExceptionSpec : SubjectSpek({ - subject { RethrowCaughtException() } + subject { RethrowCaughtException() } - given("multiple caught exceptions") { + given("multiple caught exceptions") { - it("reports caught exceptions which are rethrown") { - val path = Case.RethrowCaughtExceptionPositive.path() - assertThat(subject.lint(path)).hasSize(3) - } + it("reports caught exceptions which are rethrown") { + val path = Case.RethrowCaughtExceptionPositive.path() + assertThat(subject.lint(path)).hasSize(3) + } - it("does not report caught exceptions which are encapsulated in another exception or logged") { - val path = Case.RethrowCaughtExceptionNegative.path() - assertThat(subject.lint(path)).hasSize(0) - } - } + it("does not report caught exceptions which are encapsulated in another exception or logged") { + val path = Case.RethrowCaughtExceptionNegative.path() + assertThat(subject.lint(path)).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ReturnFromFinallySpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ReturnFromFinallySpec.kt index 3e31b6d8d..c67d8c177 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ReturnFromFinallySpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ReturnFromFinallySpec.kt @@ -7,10 +7,10 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class ReturnFromFinallySpec : SubjectSpek({ - subject { ReturnFromFinally() } + subject { ReturnFromFinally() } - given("a finally block with a return statement") { - val code = """ + given("a finally block with a return statement") { + val code = """ fun x() { try { } finally { @@ -19,14 +19,14 @@ class ReturnFromFinallySpec : SubjectSpek({ } """ - it("should report") { - val findings = subject.lint(code) - Assertions.assertThat(findings).hasSize(1) - } - } + it("should report") { + val findings = subject.lint(code) + Assertions.assertThat(findings).hasSize(1) + } + } - given("a finally block with no return statement") { - val code = """ + given("a finally block with no return statement") { + val code = """ fun x() { try { } finally { @@ -34,14 +34,14 @@ class ReturnFromFinallySpec : SubjectSpek({ } """ - it("should not report") { - val findings = subject.lint(code) - Assertions.assertThat(findings).hasSize(0) - } - } + it("should not report") { + val findings = subject.lint(code) + Assertions.assertThat(findings).hasSize(0) + } + } - given("a finally block with a nested return statement") { - val code = """ + given("a finally block with a nested return statement") { + val code = """ fun x() { try { } finally { @@ -52,14 +52,14 @@ class ReturnFromFinallySpec : SubjectSpek({ } """ - it("should report") { - val findings = subject.lint(code) - Assertions.assertThat(findings).hasSize(1) - } - } + it("should report") { + val findings = subject.lint(code) + Assertions.assertThat(findings).hasSize(1) + } + } - given("a finally block with a return in an inner function") { - val code = """ + given("a finally block with a return in an inner function") { + val code = """ fun x() { try { } finally { @@ -71,9 +71,9 @@ class ReturnFromFinallySpec : SubjectSpek({ } """ - it("should not report") { - val findings = subject.lint(code) - Assertions.assertThat(findings).hasSize(0) - } - } + it("should not report") { + val findings = subject.lint(code) + Assertions.assertThat(findings).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/SwallowedExceptionSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/SwallowedExceptionSpec.kt index 41a12c1ac..a8c940a65 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/SwallowedExceptionSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/SwallowedExceptionSpec.kt @@ -12,22 +12,22 @@ import org.jetbrains.spek.subject.SubjectSpek * @author schalkms */ class SwallowedExceptionSpec : SubjectSpek({ - subject { SwallowedException() } + subject { SwallowedException() } - given("several catch blocks") { + given("several catch blocks") { - it("reports swallowed exceptions") { - assertThat(subject.lint(Case.SwallowedExceptionPositive.path())).hasSize(5) - } + it("reports swallowed exceptions") { + assertThat(subject.lint(Case.SwallowedExceptionPositive.path())).hasSize(5) + } - it("ignores given exception types in configuration") { - val config = TestConfig(mapOf(SwallowedException.IGNORED_EXCEPTION_TYPES to "IOException")) - val rule = SwallowedException(config) - assertThat(rule.lint(Case.SwallowedExceptionPositive.path())).hasSize(4) - } + it("ignores given exception types in configuration") { + val config = TestConfig(mapOf(SwallowedException.IGNORED_EXCEPTION_TYPES to "IOException")) + val rule = SwallowedException(config) + assertThat(rule.lint(Case.SwallowedExceptionPositive.path())).hasSize(4) + } - it("does not report thrown catch blocks") { - assertThat(subject.lint(Case.SwallowedExceptionNegative.path())).hasSize(0) - } - } + it("does not report thrown catch blocks") { + assertThat(subject.lint(Case.SwallowedExceptionNegative.path())).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ThrowingExceptionFromFinallySpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ThrowingExceptionFromFinallySpec.kt index 2b78d7af6..f0dadc242 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ThrowingExceptionFromFinallySpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ThrowingExceptionFromFinallySpec.kt @@ -7,12 +7,12 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class ThrowingExceptionFromFinallySpec : SubjectSpek({ - subject { ThrowingExceptionFromFinally() } + subject { ThrowingExceptionFromFinally() } - given("some finally blocks") { + given("some finally blocks") { - it("should report a throw expression") { - val code = """ + it("should report a throw expression") { + val code = """ fun x() { try { } finally { @@ -21,29 +21,29 @@ class ThrowingExceptionFromFinallySpec : SubjectSpek({ - subject { ThrowingExceptionInMain() } + subject { ThrowingExceptionInMain() } - given("some main methods") { + given("some main methods") { - it("has a runnable main method which throws an exception") { - val code = "fun main(args: Array) { throw new IOException() }" - assertThat(subject.lint(code)).hasSize(1) - } + it("has a runnable main method which throws an exception") { + val code = "fun main(args: Array) { throw new IOException() }" + assertThat(subject.lint(code)).hasSize(1) + } - it("has wrong main methods") { - val code = """ + it("has wrong main methods") { + val code = """ fun main(args: Array) { } private fun main() { } fun mai() { } fun main(args: String) { }""" - assertThat(subject.lint(code)).hasSize(0) - } - } + assertThat(subject.lint(code)).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ThrowingExceptionsWithoutMessageOrCauseSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ThrowingExceptionsWithoutMessageOrCauseSpec.kt index b360f39aa..ed018b314 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ThrowingExceptionsWithoutMessageOrCauseSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ThrowingExceptionsWithoutMessageOrCauseSpec.kt @@ -8,41 +8,41 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class ThrowingExceptionsWithoutMessageOrCauseSpec : SubjectSpek({ - subject { - ThrowingExceptionsWithoutMessageOrCause( - TestConfig(mapOf(ThrowingExceptionsWithoutMessageOrCause.EXCEPTIONS to "IllegalArgumentException")) - ) - } + subject { + ThrowingExceptionsWithoutMessageOrCause( + TestConfig(mapOf(ThrowingExceptionsWithoutMessageOrCause.EXCEPTIONS to "IllegalArgumentException")) + ) + } - given("several exception calls") { + given("several exception calls") { - val code = """ + val code = """ fun x() { IllegalArgumentException(IllegalArgumentException()) IllegalArgumentException("foo") throw IllegalArgumentException() }""" - it("reports calls to the default constructor") { - assertThat(subject.lint(code)).hasSize(2) - } + it("reports calls to the default constructor") { + assertThat(subject.lint(code)).hasSize(2) + } - it("does not report calls to the default constructor with empty configuration") { - val config = TestConfig(mapOf(ThrowingExceptionsWithoutMessageOrCause.EXCEPTIONS to "")) - val findings = ThrowingExceptionsWithoutMessageOrCause(config).lint(code) - assertThat(findings).hasSize(0) - } - } + it("does not report calls to the default constructor with empty configuration") { + val config = TestConfig(mapOf(ThrowingExceptionsWithoutMessageOrCause.EXCEPTIONS to "")) + val findings = ThrowingExceptionsWithoutMessageOrCause(config).lint(code) + assertThat(findings).hasSize(0) + } + } - given("a test code which asserts an exception") { + given("a test code which asserts an exception") { - it("does not report a call to this exception") { - val code = """ + it("does not report a call to this exception") { + val code = """ fun test() { assertThatIllegalArgumentException().isThrownBy { } } """ - assertThat(subject.lint(code)).isEmpty() - } - } + assertThat(subject.lint(code)).isEmpty() + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ThrowingNewInstanceOfSameExceptionSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ThrowingNewInstanceOfSameExceptionSpec.kt index 9cd55cb9b..f2be4bd4c 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ThrowingNewInstanceOfSameExceptionSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ThrowingNewInstanceOfSameExceptionSpec.kt @@ -7,10 +7,10 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class ThrowingNewInstanceOfSameExceptionSpec : SubjectSpek({ - subject { ThrowingNewInstanceOfSameException() } + subject { ThrowingNewInstanceOfSameException() } - given("a catch block which rethrows a new instance of the caught exception") { - val code = """ + given("a catch block which rethrows a new instance of the caught exception") { + val code = """ fun x() { try { } catch (e: IllegalStateException) { @@ -19,14 +19,14 @@ class ThrowingNewInstanceOfSameExceptionSpec : SubjectSpek({ - subject { MemberNameEqualsClassName(Config.empty) } + subject { MemberNameEqualsClassName(Config.empty) } - given("some classes with methods which don't have the same name") { + given("some classes with methods which don't have the same name") { - it("reports methods which are not named after the class") { - val path = Case.MemberNameEqualsClassNameNegative.path() - assertThat(subject.lint(path)).hasSize(0) - } - } + it("reports methods which are not named after the class") { + val path = Case.MemberNameEqualsClassNameNegative.path() + assertThat(subject.lint(path)).hasSize(0) + } + } - given("some classes with methods which have the same name") { + given("some classes with methods which have the same name") { - val path = Case.MemberNameEqualsClassNamePositive.path() - val findings = subject.lint(path) + val path = Case.MemberNameEqualsClassNamePositive.path() + val findings = subject.lint(path) - it("reports methods which are named after the class") { - assertThat(findings).hasSize(8) - } + it("reports methods which are named after the class") { + assertThat(findings).hasSize(8) + } - it("reports methods which are named after the class object") { - val objectFindings = findings.filter { it.message.contains("object") } - assertThat(objectFindings).hasSize(2) - } + it("reports methods which are named after the class object") { + val objectFindings = findings.filter { it.message.contains("object") } + assertThat(objectFindings).hasSize(2) + } - it("reports methods which are named after the class object including overridden functions") { - val config = TestConfig(mapOf("ignoreOverriddenFunction" to "false")) - val rule = MemberNameEqualsClassName(config) - assertThat(rule.lint(path)).hasSize(9) - } - } + it("reports methods which are named after the class object including overridden functions") { + val config = TestConfig(mapOf("ignoreOverriddenFunction" to "false")) + val rule = MemberNameEqualsClassName(config) + assertThat(rule.lint(path)).hasSize(9) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/NamingConventionCustomPatternTest.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/NamingConventionCustomPatternTest.kt index 9e408c26f..d93f9e654 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/NamingConventionCustomPatternTest.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/NamingConventionCustomPatternTest.kt @@ -2,48 +2,48 @@ package io.gitlab.arturbosch.detekt.rules.naming import io.gitlab.arturbosch.detekt.test.TestConfig import io.gitlab.arturbosch.detekt.test.lint +import java.util.regex.PatternSyntaxException import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThatExceptionOfType import org.jetbrains.spek.api.Spek import org.jetbrains.spek.api.dsl.it -import java.util.regex.PatternSyntaxException class NamingConventionCustomPatternTest : Spek({ - val configCustomRules = - object : TestConfig() { - override fun subConfig(key: String): TestConfig = this + val configCustomRules = + object : TestConfig() { + override fun subConfig(key: String): TestConfig = this - @Suppress("UNCHECKED_CAST") - override fun valueOrDefault(key: String, default: T): T = - when (key) { - FunctionNaming.FUNCTION_PATTERN -> "^`.+`$" as T - ClassNaming.CLASS_PATTERN -> "^aBbD$" as T - VariableNaming.VARIABLE_PATTERN -> "^123var$" as T - TopLevelPropertyNaming.CONSTANT_PATTERN -> "^lowerCaseConst$" as T - EnumNaming.ENUM_PATTERN -> "^(enum1)|(enum2)$" as T - PackageNaming.PACKAGE_PATTERN -> "^(package_1)$" as T - FunctionMaxLength.MAXIMUM_FUNCTION_NAME_LENGTH -> 50 as T - else -> default - } - } - val testConfig = object : TestConfig() { - override fun subConfig(key: String): TestConfig = - when (key) { - FunctionNaming::class.simpleName -> configCustomRules - FunctionMaxLength::class.simpleName -> configCustomRules - ClassNaming::class.simpleName -> configCustomRules - VariableNaming::class.simpleName -> configCustomRules - TopLevelPropertyNaming::class.simpleName -> configCustomRules - EnumNaming::class.simpleName -> configCustomRules - PackageNaming::class.simpleName -> configCustomRules - else -> this - } + @Suppress("UNCHECKED_CAST") + override fun valueOrDefault(key: String, default: T): T = + when (key) { + FunctionNaming.FUNCTION_PATTERN -> "^`.+`$" as T + ClassNaming.CLASS_PATTERN -> "^aBbD$" as T + VariableNaming.VARIABLE_PATTERN -> "^123var$" as T + TopLevelPropertyNaming.CONSTANT_PATTERN -> "^lowerCaseConst$" as T + EnumNaming.ENUM_PATTERN -> "^(enum1)|(enum2)$" as T + PackageNaming.PACKAGE_PATTERN -> "^(package_1)$" as T + FunctionMaxLength.MAXIMUM_FUNCTION_NAME_LENGTH -> 50 as T + else -> default + } + } + val testConfig = object : TestConfig() { + override fun subConfig(key: String): TestConfig = + when (key) { + FunctionNaming::class.simpleName -> configCustomRules + FunctionMaxLength::class.simpleName -> configCustomRules + ClassNaming::class.simpleName -> configCustomRules + VariableNaming::class.simpleName -> configCustomRules + TopLevelPropertyNaming::class.simpleName -> configCustomRules + EnumNaming::class.simpleName -> configCustomRules + PackageNaming::class.simpleName -> configCustomRules + else -> this + } - override fun valueOrDefault(key: String, default: T): T = default - } + override fun valueOrDefault(key: String, default: T): T = default + } - val excludeClassPatternVariableRegexCode = """ + val excludeClassPatternVariableRegexCode = """ class Bar { val MYVar = 3 } @@ -52,7 +52,7 @@ class NamingConventionCustomPatternTest : Spek({ val MYVar = 3 }""" - val excludeClassPatternFunctionRegexCode = """ + val excludeClassPatternFunctionRegexCode = """ class Bar { fun MYFun() {} } @@ -61,9 +61,9 @@ class NamingConventionCustomPatternTest : Spek({ fun MYFun() {} }""" - it("shouldUseCustomNameForMethodAndClass") { - val rule = NamingRules(testConfig) - assertThat(rule.lint(""" + it("shouldUseCustomNameForMethodAndClass") { + val rule = NamingRules(testConfig) + assertThat(rule.lint(""" class aBbD{ fun `name with back ticks`(){ val `123var` = "" @@ -74,37 +74,37 @@ class NamingConventionCustomPatternTest : Spek({ } } """)).isEmpty() - } + } - it("shouldUseCustomNameForConstant") { - val rule = NamingRules(testConfig) - assertThat(rule.lint(""" + it("shouldUseCustomNameForConstant") { + val rule = NamingRules(testConfig) + assertThat(rule.lint(""" class aBbD{ companion object { const val lowerCaseConst = "" } } """)).isEmpty() - } + } - it("shouldUseCustomNameForEnum") { - val rule = NamingRules(testConfig) - assertThat(rule.lint(""" + it("shouldUseCustomNameForEnum") { + val rule = NamingRules(testConfig) + assertThat(rule.lint(""" class aBbD{ enum class aBbD { enum1, enum2 } } """)).isEmpty() - } + } - it("shouldUseCustomNameForPackage") { - val rule = NamingRules(testConfig) - assertThat(rule.lint("package package_1")).isEmpty() - } + it("shouldUseCustomNameForPackage") { + val rule = NamingRules(testConfig) + assertThat(rule.lint("package package_1")).isEmpty() + } - it("shouldExcludeClassesFromVariableNaming") { - val code = """ + it("shouldExcludeClassesFromVariableNaming") { + val code = """ class Bar { val MYVar = 3 } @@ -112,28 +112,28 @@ class NamingConventionCustomPatternTest : Spek({ object Foo { val MYVar = 3 }""" - val config = TestConfig(mapOf(VariableNaming.EXCLUDE_CLASS_PATTERN to "Foo|Bar")) - assertThat(VariableNaming(config).lint(code)).isEmpty() - } + val config = TestConfig(mapOf(VariableNaming.EXCLUDE_CLASS_PATTERN to "Foo|Bar")) + assertThat(VariableNaming(config).lint(code)).isEmpty() + } - it("shouldNotFailWithInvalidRegexWhenDisabledVariableNaming") { - val configValues = mapOf( - "active" to "false", - VariableNaming.EXCLUDE_CLASS_PATTERN to "*Foo" - ) - val config = TestConfig(configValues) - assertThat(VariableNaming(config).lint(excludeClassPatternVariableRegexCode)).isEmpty() - } + it("shouldNotFailWithInvalidRegexWhenDisabledVariableNaming") { + val configValues = mapOf( + "active" to "false", + VariableNaming.EXCLUDE_CLASS_PATTERN to "*Foo" + ) + val config = TestConfig(configValues) + assertThat(VariableNaming(config).lint(excludeClassPatternVariableRegexCode)).isEmpty() + } - it("shouldFailWithInvalidRegexVariableNaming") { - val config = TestConfig(mapOf(VariableNaming.EXCLUDE_CLASS_PATTERN to "*Foo")) - assertThatExceptionOfType(PatternSyntaxException::class.java).isThrownBy { - VariableNaming(config).lint(excludeClassPatternVariableRegexCode) - } - } + it("shouldFailWithInvalidRegexVariableNaming") { + val config = TestConfig(mapOf(VariableNaming.EXCLUDE_CLASS_PATTERN to "*Foo")) + assertThatExceptionOfType(PatternSyntaxException::class.java).isThrownBy { + VariableNaming(config).lint(excludeClassPatternVariableRegexCode) + } + } - it("shouldExcludeClassesFromFunctionNaming") { - val code = """ + it("shouldExcludeClassesFromFunctionNaming") { + val code = """ class Bar { fun MYFun() {} } @@ -141,23 +141,23 @@ class NamingConventionCustomPatternTest : Spek({ object Foo { fun MYFun() {} }""" - val config = TestConfig(mapOf(FunctionNaming.EXCLUDE_CLASS_PATTERN to "Foo|Bar")) - assertThat(FunctionNaming(config).lint(code)).isEmpty() - } + val config = TestConfig(mapOf(FunctionNaming.EXCLUDE_CLASS_PATTERN to "Foo|Bar")) + assertThat(FunctionNaming(config).lint(code)).isEmpty() + } - it("shouldNotFailWithInvalidRegexWhenDisabledFunctionNaming") { - val configRules = mapOf( - "active" to "false", - FunctionNaming.EXCLUDE_CLASS_PATTERN to "*Foo" - ) - val config = TestConfig(configRules) - assertThat(FunctionNaming(config).lint(excludeClassPatternFunctionRegexCode)).isEmpty() - } + it("shouldNotFailWithInvalidRegexWhenDisabledFunctionNaming") { + val configRules = mapOf( + "active" to "false", + FunctionNaming.EXCLUDE_CLASS_PATTERN to "*Foo" + ) + val config = TestConfig(configRules) + assertThat(FunctionNaming(config).lint(excludeClassPatternFunctionRegexCode)).isEmpty() + } - it("shouldFailWithInvalidRegexFunctionNaming") { - val config = TestConfig(mapOf(FunctionNaming.EXCLUDE_CLASS_PATTERN to "*Foo")) - assertThatExceptionOfType(PatternSyntaxException::class.java).isThrownBy { - FunctionNaming(config).lint(excludeClassPatternFunctionRegexCode) - } - } + it("shouldFailWithInvalidRegexFunctionNaming") { + val config = TestConfig(mapOf(FunctionNaming.EXCLUDE_CLASS_PATTERN to "*Foo")) + assertThatExceptionOfType(PatternSyntaxException::class.java).isThrownBy { + FunctionNaming(config).lint(excludeClassPatternFunctionRegexCode) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/NamingConventionLengthSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/NamingConventionLengthSpec.kt index 0db83b7ee..ac28ba486 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/NamingConventionLengthSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/NamingConventionLengthSpec.kt @@ -9,77 +9,77 @@ import org.jetbrains.spek.subject.SubjectSpek class NamingConventionLengthSpec : SubjectSpek({ - subject { NamingRules() } + subject { NamingRules() } - it("should not report underscore variable names") { - val code = "val (_, status) = getResult()" - subject.lint(code) - assertThat(subject.findings).isEmpty() - } + it("should not report underscore variable names") { + val code = "val (_, status) = getResult()" + subject.lint(code) + assertThat(subject.findings).isEmpty() + } - it("should not report a variable with single letter name") { - val code = "private val a = 3" - subject.lint(code) - assertThat(subject.findings).hasSize(0) - } + it("should not report a variable with single letter name") { + val code = "private val a = 3" + subject.lint(code) + assertThat(subject.findings).hasSize(0) + } - describe("VariableMinLength rule with a custom minimum length") { + describe("VariableMinLength rule with a custom minimum length") { - val variableMinLength = VariableMinLength(TestConfig(mapOf(VariableMinLength.MINIMUM_VARIABLE_NAME_LENGTH to "2"))) + val variableMinLength = VariableMinLength(TestConfig(mapOf(VariableMinLength.MINIMUM_VARIABLE_NAME_LENGTH to "2"))) - it("reports a very short variable name") { - val code = "private val a = 3" - assertThat(variableMinLength.lint(code)).hasSize(1) - } + it("reports a very short variable name") { + val code = "private val a = 3" + assertThat(variableMinLength.lint(code)).hasSize(1) + } - it("does not report a variable with only a single underscore") { - val code = """ + it("does not report a variable with only a single underscore") { + val code = """ class C { val prop: (Int) -> Unit = { _ -> Unit } }""" - assertThat(variableMinLength.lint(code)).hasSize(0) - } - } + assertThat(variableMinLength.lint(code)).hasSize(0) + } + } - it("should not report a variable with 64 letters") { - val code = "private val varThatIsExactly64LettersLongWhichYouMightNotWantToBelieveInLolz = 3" - subject.lint(code) - assertThat(subject.findings).hasSize(0) - } + it("should not report a variable with 64 letters") { + val code = "private val varThatIsExactly64LettersLongWhichYouMightNotWantToBelieveInLolz = 3" + subject.lint(code) + assertThat(subject.findings).hasSize(0) + } - it("should report a variable name that is too long") { - val code = "private val thisVariableIsDefinitelyWayTooLongLongerThanEverythingAndShouldBeMuchShorter = 3" - subject.lint(code) - assertThat(subject.findings).hasSize(1) - } + it("should report a variable name that is too long") { + val code = "private val thisVariableIsDefinitelyWayTooLongLongerThanEverythingAndShouldBeMuchShorter = 3" + subject.lint(code) + assertThat(subject.findings).hasSize(1) + } - it("should not report a variable name that is okay") { - val code = "private val thisOneIsCool = 3" - subject.lint(code) - assertThat(subject.findings).isEmpty() - } + it("should not report a variable name that is okay") { + val code = "private val thisOneIsCool = 3" + subject.lint(code) + assertThat(subject.findings).isEmpty() + } - it("should report a function name that is too short") { - val code = "private fun a = 3" - subject.lint(code) - assertThat(subject.findings).hasSize(1) - } + it("should report a function name that is too short") { + val code = "private fun a = 3" + subject.lint(code) + assertThat(subject.findings).hasSize(1) + } - it("should report a function name that is too long") { - val code = "private fun thisFunctionIsDefinitelyWayTooLongAndShouldBeMuchShorter = 3" - subject.lint(code) - assertThat(subject.findings).hasSize(1) - } + it("should report a function name that is too long") { + val code = "private fun thisFunctionIsDefinitelyWayTooLongAndShouldBeMuchShorter = 3" + subject.lint(code) + assertThat(subject.findings).hasSize(1) + } - it("should not report a function name that is okay") { - val code = "private fun three = 3" - subject.lint(code) - assertThat(subject.findings).isEmpty() - } + it("should not report a function name that is okay") { + val code = "private fun three = 3" + subject.lint(code) + assertThat(subject.findings).isEmpty() + } - it("should not report a function name that begins with a backtick, capitals, and spaces") { - val code = "private fun `Hi bye` = 3" - subject.lint(code) - assertThat(subject.findings).isEmpty() - } + it("should not report a function name that begins with a backtick, capitals, and spaces") { + val code = "private fun `Hi bye` = 3" + subject.lint(code) + assertThat(subject.findings).isEmpty() + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/NamingRulesSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/NamingRulesSpec.kt index d45b93f46..c8114e30e 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/NamingRulesSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/NamingRulesSpec.kt @@ -10,14 +10,14 @@ import org.jetbrains.spek.subject.SubjectSpek class NamingRulesSpec : SubjectSpek({ - val fileName = TEST_FILENAME + val fileName = TEST_FILENAME - subject { NamingRules() } + subject { NamingRules() } - describe("properties in classes") { + describe("properties in classes") { - it("should detect all positive cases") { - val code = """ + it("should detect all positive cases") { + val code = """ class C(val CONST_PARAMETER: String, private val PRIVATE_CONST_PARAMETER: Int) { private val _FIELD = 5 val FIELD get() = _field @@ -27,20 +27,20 @@ class NamingRulesSpec : SubjectSpek({ fun doStuff(FUN_PARAMETER: String) {} } """ - assertThat(subject.lint(code)).hasLocationStrings( - "'private val _FIELD = 5' at (2,2) in /$fileName", - "'val FIELD get() = _field' at (3,2) in /$fileName", - "'val camel_Case_Property = 5' at (4,2) in /$fileName", - "'const val MY_CONST = 7' at (5,2) in /$fileName", - "'const val MYCONST = 7' at (6,2) in /$fileName", - "'val CONST_PARAMETER: String' at (1,9) in /$fileName", - "'private val PRIVATE_CONST_PARAMETER: Int' at (1,38) in /$fileName", - "'FUN_PARAMETER: String' at (7,14) in /$fileName" - ) - } + assertThat(subject.lint(code)).hasLocationStrings( + "'private val _FIELD = 5' at (2,2) in /$fileName", + "'val FIELD get() = _field' at (3,2) in /$fileName", + "'val camel_Case_Property = 5' at (4,2) in /$fileName", + "'const val MY_CONST = 7' at (5,2) in /$fileName", + "'const val MYCONST = 7' at (6,2) in /$fileName", + "'val CONST_PARAMETER: String' at (1,9) in /$fileName", + "'private val PRIVATE_CONST_PARAMETER: Int' at (1,38) in /$fileName", + "'FUN_PARAMETER: String' at (7,14) in /$fileName" + ) + } - it("checks all negative cases") { - val code = """ + it("checks all negative cases") { + val code = """ class C(val constParameter: String, private val privateConstParameter: Int) { private val _field = 5 val field get() = _field @@ -56,11 +56,11 @@ class NamingRulesSpec : SubjectSpek({ fun doStuff(funParameter: String) {} } """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("should not flag overridden member properties by default") { - val code = """ + it("should not flag overridden member properties by default") { + val code = """ class C { override val SHOULD_NOT_BE_FLAGGED = "banana" } @@ -68,11 +68,11 @@ class NamingRulesSpec : SubjectSpek({ override val SHOULD_NOT_BE_FLAGGED_2 = "banana" } """ - assertThat(NamingRules().lint(code)).isEmpty() - } + assertThat(NamingRules().lint(code)).isEmpty() + } - it("doesn't ignore overridden member properties if ignoreOverridden is false") { - val code = """ + it("doesn't ignore overridden member properties if ignoreOverridden is false") { + val code = """ class C { override val SHOULD_BE_FLAGGED = "banana" } @@ -80,24 +80,24 @@ class NamingRulesSpec : SubjectSpek({ override val SHOULD_BE_FLAGGED_2 = "banana" } """ - val config = TestConfig(mapOf("ignoreOverridden" to "false")) - assertThat(NamingRules(config).lint(code)).hasLocationStrings( - "'override val SHOULD_BE_FLAGGED = \"banana\"' at (2,2) in /$fileName", - "'override val SHOULD_BE_FLAGGED_2 = \"banana\"' at (5,2) in /$fileName" - ) - } - } + val config = TestConfig(mapOf("ignoreOverridden" to "false")) + assertThat(NamingRules(config).lint(code)).hasLocationStrings( + "'override val SHOULD_BE_FLAGGED = \"banana\"' at (2,2) in /$fileName", + "'override val SHOULD_BE_FLAGGED_2 = \"banana\"' at (5,2) in /$fileName" + ) + } + } - describe("naming like in constants is allowed for destructuring and lambdas") { - it("should not detect any") { - val code = """ + describe("naming like in constants is allowed for destructuring and lambdas") { + it("should not detect any") { + val code = """ data class D(val i: Int, val j: Int) fun doStuff() { val (_, HOLY_GRAIL) = D(5, 4) emptyMap().forEach { _, V -> println(v) } } """ - assertThat(subject.lint(code)).isEmpty() - } - } + assertThat(subject.lint(code)).isEmpty() + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/ObjectPropertyNamingSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/ObjectPropertyNamingSpec.kt index ad677fb59..538581031 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/ObjectPropertyNamingSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/ObjectPropertyNamingSpec.kt @@ -11,202 +11,202 @@ import org.jetbrains.spek.subject.SubjectSpek class ObjectPropertyNamingSpec : SubjectSpek({ - subject { ObjectPropertyNaming() } + subject { ObjectPropertyNaming() } - val fileName = TEST_FILENAME + val fileName = TEST_FILENAME - describe("constants in object declarations") { + describe("constants in object declarations") { - it("should not detect public constants complying to the naming rules") { - val code = compileContentForTest(""" + it("should not detect public constants complying to the naming rules") { + val code = compileContentForTest(""" object O { ${PublicConst.negative} } """) - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("should detect public constants not complying to the naming rules") { - val code = compileContentForTest(""" + it("should detect public constants not complying to the naming rules") { + val code = compileContentForTest(""" object O { ${PublicConst.positive} } """) - assertThat(subject.lint(code)).hasSize(1) - } + assertThat(subject.lint(code)).hasSize(1) + } - it("should not detect private constants complying to the naming rules") { - val code = compileContentForTest(""" + it("should not detect private constants complying to the naming rules") { + val code = compileContentForTest(""" object O { ${PrivateConst.negative} } """) - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("should detect private constants not complying to the naming rules") { - val code = compileContentForTest(""" + it("should detect private constants not complying to the naming rules") { + val code = compileContentForTest(""" object O { ${PrivateConst.positive} } """) - assertThat(subject.lint(code)).hasSize(1) - } + assertThat(subject.lint(code)).hasSize(1) + } - it("should report constants not complying to the naming rules at the right position") { - val code = compileContentForTest(""" + it("should report constants not complying to the naming rules at the right position") { + val code = compileContentForTest(""" object O { ${PublicConst.positive} } """) - assertThat(subject.lint(code)).hasLocationStrings( - "'const val _nAme = \"Artur\"' at (3,6) in /$fileName" - ) - } - } + assertThat(subject.lint(code)).hasLocationStrings( + "'const val _nAme = \"Artur\"' at (3,6) in /$fileName" + ) + } + } - describe("constants in companion object") { + describe("constants in companion object") { - it("should not detect public constants complying to the naming rules") { - val code = compileContentForTest(""" + it("should not detect public constants complying to the naming rules") { + val code = compileContentForTest(""" class C { companion object { ${PublicConst.negative} } } """) - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("should detect public constants not complying to the naming rules") { - val code = compileContentForTest(""" + it("should detect public constants not complying to the naming rules") { + val code = compileContentForTest(""" class C { companion object { ${PublicConst.positive} } } """) - assertThat(subject.lint(code)).hasSize(1) - } + assertThat(subject.lint(code)).hasSize(1) + } - it("should not detect private constants complying to the naming rules") { - val code = compileContentForTest(""" + it("should not detect private constants complying to the naming rules") { + val code = compileContentForTest(""" class C { companion object { ${PrivateConst.negative} } } """) - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("should detect private constants not complying to the naming rules") { - val code = compileContentForTest(""" + it("should detect private constants not complying to the naming rules") { + val code = compileContentForTest(""" class C { companion object { ${PrivateConst.positive} } } """) - assertThat(subject.lint(code)).hasSize(1) - } + assertThat(subject.lint(code)).hasSize(1) + } - it("should report constants not complying to the naming rules at the right position") { - val code = compileContentForTest(""" + it("should report constants not complying to the naming rules at the right position") { + val code = compileContentForTest(""" class C { companion object { ${PublicConst.positive} } } """) - assertThat(subject.lint(code)).hasLocationStrings( - "'const val _nAme = \"Artur\"' at (4,7) in /$fileName" - ) - } - } + assertThat(subject.lint(code)).hasLocationStrings( + "'const val _nAme = \"Artur\"' at (4,7) in /$fileName" + ) + } + } - describe("variables in objects") { + describe("variables in objects") { - it("should not detect public constants complying to the naming rules") { - val code = compileContentForTest(""" + it("should not detect public constants complying to the naming rules") { + val code = compileContentForTest(""" object O { ${PublicVal.negative} } """) - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("should detect public constants not complying to the naming rules") { - val code = compileContentForTest(""" + it("should detect public constants not complying to the naming rules") { + val code = compileContentForTest(""" object O { ${PublicVal.positive} } """) - assertThat(subject.lint(code)).hasSize(1) - } + assertThat(subject.lint(code)).hasSize(1) + } - it("should not detect private constants complying to the naming rules") { - val code = compileContentForTest(""" + it("should not detect private constants complying to the naming rules") { + val code = compileContentForTest(""" object O { ${PrivateVal.negative} } """) - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("should detect private constants not complying to the naming rules") { - val code = compileContentForTest(""" + it("should detect private constants not complying to the naming rules") { + val code = compileContentForTest(""" object O { private val __NAME = "Artur" } """) - assertThat(subject.lint(code)).hasSize(1) - } - } + assertThat(subject.lint(code)).hasSize(1) + } + } - describe("variables and constants in objects with custom config") { + describe("variables and constants in objects with custom config") { - val config = TestConfig(mapOf( - ObjectPropertyNaming.CONSTANT_PATTERN to "_[A-Za-z]*", - ObjectPropertyNaming.PRIVATE_PROPERTY_PATTERN to ".*" - )) - val subject = ObjectPropertyNaming(config) + val config = TestConfig(mapOf( + ObjectPropertyNaming.CONSTANT_PATTERN to "_[A-Za-z]*", + ObjectPropertyNaming.PRIVATE_PROPERTY_PATTERN to ".*" + )) + val subject = ObjectPropertyNaming(config) - it("should not detect constants in object with underscores") { - val code = compileContentForTest(""" + it("should not detect constants in object with underscores") { + val code = compileContentForTest(""" object O { const val _NAME = "Artur" const val _name = "Artur" } """) - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("should not detect private properties in object") { - val code = compileContentForTest(""" + it("should not detect private properties in object") { + val code = compileContentForTest(""" object O { private val __NAME = "Artur" private val _1234 = "Artur" } """) - assertThat(subject.lint(code)).isEmpty() - } - } + assertThat(subject.lint(code)).isEmpty() + } + } }) abstract class NamingSnippet(private val isPrivate: Boolean, private val isConst: Boolean) { - val negative = """ + val negative = """ ${visibility()}${const()}val MY_NAME_8 = "Artur" ${visibility()}${const()}val MYNAME = "Artur" ${visibility()}${const()}val MyNAME = "Artur" ${visibility()}${const()}val name = "Artur" ${visibility()}${const()}val nAme = "Artur" ${visibility()}${const()}val serialVersionUID = 42L""" - val positive = """${visibility()}${const()}val _nAme = "Artur"""" + val positive = """${visibility()}${const()}val _nAme = "Artur"""" - private fun visibility() = if (isPrivate) "private " else "" - private fun const() = if (isConst) "const " else "" + private fun visibility() = if (isPrivate) "private " else "" + private fun const() = if (isConst) "const " else "" } object PrivateConst : NamingSnippet(true, true) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/PackageNamingSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/PackageNamingSpec.kt index 49975b8e9..566a2c7cd 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/PackageNamingSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/PackageNamingSpec.kt @@ -7,19 +7,19 @@ import org.jetbrains.spek.subject.SubjectSpek class PackageNamingSpec : SubjectSpek({ - it("should find a uppercase package name") { - assertThat(NamingRules().lint("package FOO.BAR")).hasSize(1) - } + it("should find a uppercase package name") { + assertThat(NamingRules().lint("package FOO.BAR")).hasSize(1) + } - it("should find a upper camel case package name") { - assertThat(NamingRules().lint("package Foo.Bar")).hasSize(1) - } + it("should find a upper camel case package name") { + assertThat(NamingRules().lint("package Foo.Bar")).hasSize(1) + } - it("should find a camel case package name") { - assertThat(NamingRules().lint("package fOO.bAR")).hasSize(1) - } + it("should find a camel case package name") { + assertThat(NamingRules().lint("package fOO.bAR")).hasSize(1) + } - it("should check an valid package name") { - assertThat(NamingRules().lint("package foo.bar")).isEmpty() - } + it("should check an valid package name") { + assertThat(NamingRules().lint("package foo.bar")).isEmpty() + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/ParameterNamingSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/ParameterNamingSpec.kt index e149bf6f5..01b2ccf81 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/ParameterNamingSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/ParameterNamingSpec.kt @@ -13,10 +13,10 @@ import org.jetbrains.spek.api.dsl.it */ class ParameterNamingSpec : Spek({ - describe("parameters in a constructor of a class") { + describe("parameters in a constructor of a class") { - it("should detect no violations") { - val code = """ + it("should detect no violations") { + val code = """ class C(val param: String, private val privateParam: String) class C { @@ -24,11 +24,11 @@ class ParameterNamingSpec : Spek({ construct(val param: String, private val privateParam: String) {} } """ - assertThat(ConstructorParameterNaming().lint(code)).isEmpty() - } + assertThat(ConstructorParameterNaming().lint(code)).isEmpty() + } - it("should find some violations") { - val code = """ + it("should find some violations") { + val code = """ class C(val PARAM: String, private val PRIVATE_PARAM: String) class C { @@ -36,66 +36,66 @@ class ParameterNamingSpec : Spek({ construct(val PARAM: String, private val PRIVATE_PARAM: String) {} } """ - assertThat(NamingRules().lint(code)).hasSize(5) - } - } + assertThat(NamingRules().lint(code)).hasSize(5) + } + } - describe("parameters in a function of a class") { + describe("parameters in a function of a class") { - it("should detect no violations") { - val code = """ + it("should detect no violations") { + val code = """ class C { fun someStuff(param: String) {} } """ - assertThat(ConstructorParameterNaming().lint(code)).isEmpty() - } + assertThat(ConstructorParameterNaming().lint(code)).isEmpty() + } - it("should not detect violations in overridden function by default") { - val code = """ + it("should not detect violations in overridden function by default") { + val code = """ class C { override fun someStuff(`object`: String) {} } """ - assertThat(FunctionParameterNaming().lint(code)).isEmpty() - } + assertThat(FunctionParameterNaming().lint(code)).isEmpty() + } - it("should detect violations in overridden function if ignoreOverriddenFunctions is false") { - val code = """ + it("should detect violations in overridden function if ignoreOverriddenFunctions is false") { + val code = """ class C { override fun someStuff(`object`: String) {} } """ - val config = TestConfig(mapOf("ignoreOverriddenFunctions" to "false")) - assertThat(FunctionParameterNaming(config).lint(code)).hasSize(1) - } + val config = TestConfig(mapOf("ignoreOverriddenFunctions" to "false")) + assertThat(FunctionParameterNaming(config).lint(code)).hasSize(1) + } - it("should find some violations") { - val code = """ + it("should find some violations") { + val code = """ class C { fun someStuff(PARAM: String) {} } """ - assertThat(NamingRules().lint(code)).hasSize(1) - } - } + assertThat(NamingRules().lint(code)).hasSize(1) + } + } - describe("parameters in a function of an excluded class") { + describe("parameters in a function of an excluded class") { - val config = TestConfig(mapOf("excludeClassPattern" to "Excluded")) + val config = TestConfig(mapOf("excludeClassPattern" to "Excluded")) - it("should not detect function parameter") { - val code = """ + it("should not detect function parameter") { + val code = """ class Excluded { fun f(PARAM: Int) } """ - assertThat(FunctionParameterNaming(config).lint(code)).isEmpty() - } + assertThat(FunctionParameterNaming(config).lint(code)).isEmpty() + } - it("should not detect constructor parameter") { - val code = "class Excluded(val PARAM: Int) {}" - assertThat(ConstructorParameterNaming(config).lint(code)).isEmpty() - } - } + it("should not detect constructor parameter") { + val code = "class Excluded(val PARAM: Int) {}" + assertThat(ConstructorParameterNaming(config).lint(code)).isEmpty() + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/TopLevelPropertyNamingSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/TopLevelPropertyNamingSpec.kt index 2a83a5d61..15b6cfd0c 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/TopLevelPropertyNamingSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/TopLevelPropertyNamingSpec.kt @@ -9,34 +9,34 @@ import org.jetbrains.spek.subject.SubjectSpek class TopLevelPropertyNamingSpec : SubjectSpek({ - subject { TopLevelPropertyNaming() } + subject { TopLevelPropertyNaming() } - describe("constants on top level") { + describe("constants on top level") { - it("should not detect any constants not complying to the naming rules") { - val code = compileContentForTest(""" + it("should not detect any constants not complying to the naming rules") { + val code = compileContentForTest(""" const val MY_NAME_8 = "Artur" const val MYNAME = "Artur" """) - assertThat(subject.lint(code)).hasSize(0) - } + assertThat(subject.lint(code)).hasSize(0) + } - it("should detect five constants not complying to the naming rules") { - val code = compileContentForTest(""" + it("should detect five constants not complying to the naming rules") { + val code = compileContentForTest(""" const val MyNAME = "Artur" const val name = "Artur" const val nAme = "Artur" private const val _nAme = "Artur" const val serialVersionUID = 42L """) - assertThat(subject.lint(code)).hasSize(5) - } - } + assertThat(subject.lint(code)).hasSize(5) + } + } - describe("variables on top level") { + describe("variables on top level") { - it("should not report any") { - val code = compileContentForTest(""" + it("should not report any") { + val code = compileContentForTest(""" val name = "Artur" val nAme8 = "Artur" private val _name = "Artur" @@ -47,21 +47,21 @@ class TopLevelPropertyNamingSpec : SubjectSpek({ private val NAME = "Artur" val s_d_d_1 = listOf("") """) - assertThat(subject.lint(code)).hasSize(0) - } + assertThat(subject.lint(code)).hasSize(0) + } - it("should report non private top level property using underscore") { - val code = compileContentForTest(""" + it("should report non private top level property using underscore") { + val code = compileContentForTest(""" val _nAme = "Artur" """) - assertThat(subject.lint(code)).hasSize(1) - } + assertThat(subject.lint(code)).hasSize(1) + } - it("should report private top level property using two underscores") { - val code = compileContentForTest(""" + it("should report private top level property using two underscores") { + val code = compileContentForTest(""" private val __NAME = "Artur" """) - io.gitlab.arturbosch.detekt.test.assertThat(subject.lint(code)).hasSize(1) - } - } + io.gitlab.arturbosch.detekt.test.assertThat(subject.lint(code)).hasSize(1) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/performance/ArrayPrimitiveSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/performance/ArrayPrimitiveSpec.kt index 4de4c86c6..2036b671a 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/performance/ArrayPrimitiveSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/performance/ArrayPrimitiveSpec.kt @@ -1,7 +1,6 @@ package io.gitlab.arturbosch.detekt.rules.performance import io.gitlab.arturbosch.detekt.test.compileAndLint -import io.gitlab.arturbosch.detekt.test.lint import io.gitlab.arturbosch.detekt.test.compileAndLint import org.assertj.core.api.Assertions.assertThat import org.jetbrains.spek.api.dsl.describe @@ -12,76 +11,76 @@ import org.jetbrains.spek.subject.SubjectSpek * @author elaydis */ class ArrayPrimitiveSpec : SubjectSpek({ - subject { ArrayPrimitive() } + subject { ArrayPrimitive() } - describe("one function parameter") { - it("is an array of primitive type") { - val code = "fun function(array: Array) {}" - assertThat(subject.compileAndLint(code)).hasSize(1) - } + describe("one function parameter") { + it("is an array of primitive type") { + val code = "fun function(array: Array) {}" + assertThat(subject.compileAndLint(code)).hasSize(1) + } - it("is not an array") { - val code = "fun function(i: Int) {}" - assertThat(subject.compileAndLint(code)).isEmpty() - } + it("is not an array") { + val code = "fun function(i: Int) {}" + assertThat(subject.compileAndLint(code)).isEmpty() + } - it("is a specialized array") { - val code = "fun function(array: ByteArray) {}" - assertThat(subject.compileAndLint(code)).isEmpty() - } + it("is a specialized array") { + val code = "fun function(array: ByteArray) {}" + assertThat(subject.compileAndLint(code)).isEmpty() + } - it("is not present") { - val code = "fun function() {}" - assertThat(subject.compileAndLint(code)).isEmpty() - } + it("is not present") { + val code = "fun function() {}" + assertThat(subject.compileAndLint(code)).isEmpty() + } - it("is an array of a non-primitive type") { - val code = "fun function(array: Array) {}" - assertThat(subject.compileAndLint(code)).isEmpty() - } + it("is an array of a non-primitive type") { + val code = "fun function(array: Array) {}" + assertThat(subject.compileAndLint(code)).isEmpty() + } - it("is an array of an array of a primitive type") { - val code = "fun function(array: Array>) {}" - assertThat(subject.compileAndLint(code)).hasSize(1) - } + it("is an array of an array of a primitive type") { + val code = "fun function(array: Array>) {}" + assertThat(subject.compileAndLint(code)).hasSize(1) + } - it("is a dictionary with an array of a primitive type as key") { - val code = "fun function(dict: java.util.Dictionary>) {}" - assertThat(subject.compileAndLint(code)).hasSize(1) - } - } + it("is a dictionary with an array of a primitive type as key") { + val code = "fun function(dict: java.util.Dictionary>) {}" + assertThat(subject.compileAndLint(code)).hasSize(1) + } + } - describe("multiple function parameters") { - it("one is Array and the other is not") { - val code = "fun function(array: Array, array2: IntArray) {}" - assertThat(subject.compileAndLint(code)).hasSize(1) - } + describe("multiple function parameters") { + it("one is Array and the other is not") { + val code = "fun function(array: Array, array2: IntArray) {}" + assertThat(subject.compileAndLint(code)).hasSize(1) + } - it("both are arrays of primitive types") { - val code = "fun function(array: Array, array2: Array) {}" - assertThat(subject.compileAndLint(code)).hasSize(2) - } - } + it("both are arrays of primitive types") { + val code = "fun function(array: Array, array2: Array) {}" + assertThat(subject.compileAndLint(code)).hasSize(2) + } + } - describe("return type") { - it("is Array") { - val code = "fun returningFunction(): Array { return emptyArray() }" - assertThat(subject.compileAndLint(code)).hasSize(1) - } + describe("return type") { + it("is Array") { + val code = "fun returningFunction(): Array { return emptyArray() }" + assertThat(subject.compileAndLint(code)).hasSize(1) + } - it("is not an array") { - val code = "fun returningFunction(): Int { return 1 }" - assertThat(subject.compileAndLint(code)).isEmpty() - } + it("is not an array") { + val code = "fun returningFunction(): Int { return 1 }" + assertThat(subject.compileAndLint(code)).isEmpty() + } - it("is a specialized array") { - val code = "fun returningFunction(): CharArray { return CharArray(0) }" - assertThat(subject.compileAndLint(code)).isEmpty() - } + it("is a specialized array") { + val code = "fun returningFunction(): CharArray { return CharArray(0) }" + assertThat(subject.compileAndLint(code)).isEmpty() + } - it("is not explicitly set") { - val code = "fun returningFunction() {}" - assertThat(subject.compileAndLint(code)).isEmpty() - } - } + it("is not explicitly set") { + val code = "fun returningFunction() {}" + assertThat(subject.compileAndLint(code)).isEmpty() + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/performance/ForEachOnRangeSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/performance/ForEachOnRangeSpec.kt index 2b9beebfc..b35c122d6 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/performance/ForEachOnRangeSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/performance/ForEachOnRangeSpec.kt @@ -8,8 +8,8 @@ import org.jetbrains.spek.api.dsl.it class ForEachOnRangeSpec : Spek({ - given("a kt file with using a forEach on a range") { - val code = """ + given("a kt file with using a forEach on a range") { + val code = """ fun test() { (1..10).forEach { println(it) @@ -26,27 +26,27 @@ class ForEachOnRangeSpec : Spek({ } """ - it("should report the forEach usage") { - val findings = ForEachOnRange().compileAndLint(code) - assertThat(findings).hasSize(4) - } - } + it("should report the forEach usage") { + val findings = ForEachOnRange().compileAndLint(code) + assertThat(findings).hasSize(4) + } + } - given("a kt file with using any other method on a range") { - val code = """ + given("a kt file with using any other method on a range") { + val code = """ fun test() { (1..10).isEmpty() } """ - it("should report not report any issues") { - val findings = ForEachOnRange().compileAndLint(code) - assertThat(findings).isEmpty() - } - } + it("should report not report any issues") { + val findings = ForEachOnRange().compileAndLint(code) + assertThat(findings).isEmpty() + } + } - given("a kt file with using a forEach on a list") { - val code = """ + given("a kt file with using a forEach on a list") { + val code = """ fun test() { listOf(1, 2, 3).forEach { println(it) @@ -54,9 +54,9 @@ class ForEachOnRangeSpec : Spek({ } """ - it("should report not report any issues") { - val findings = ForEachOnRange().compileAndLint(code) - assertThat(findings).isEmpty() - } - } + it("should report not report any issues") { + val findings = ForEachOnRange().compileAndLint(code) + assertThat(findings).isEmpty() + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/performance/SpreadOperatorSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/performance/SpreadOperatorSpec.kt index 808e93812..a66e79841 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/performance/SpreadOperatorSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/performance/SpreadOperatorSpec.kt @@ -11,11 +11,11 @@ import org.jetbrains.spek.subject.SubjectSpek * @author schalkms */ class SpreadOperatorSpec : SubjectSpek({ - subject { SpreadOperator() } + subject { SpreadOperator() } - describe("test vararg cases") { - it("as vararg") { - val code = """ + describe("test vararg cases") { + it("as vararg") { + val code = """ fun test0(strs: Array) { test(*strs) } @@ -23,11 +23,11 @@ class SpreadOperatorSpec : SubjectSpek({ fun test(vararg strs: String) { strs.forEach { println(it) } }""" - assertThat(subject.compileAndLint(code)).hasSize(1) - } + assertThat(subject.compileAndLint(code)).hasSize(1) + } - it("without vararg") { - val code = """ + it("without vararg") { + val code = """ fun test0(strs: Array) { test(strs) } @@ -35,11 +35,11 @@ class SpreadOperatorSpec : SubjectSpek({ fun test(strs: Array) { strs.forEach { println(it) } }""" - assertThat(subject.compileAndLint(code)).isEmpty() - } + assertThat(subject.compileAndLint(code)).isEmpty() + } - it("expression inside params") { - val code = """ + it("expression inside params") { + val code = """ fun test0(strs: Array) { test(2*2) } @@ -47,7 +47,7 @@ class SpreadOperatorSpec : SubjectSpek({ fun test(test : Int) { println(test) }""" - assertThat(subject.compileAndLint(code)).isEmpty() - } - } + assertThat(subject.compileAndLint(code)).isEmpty() + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/performance/UnnecessaryTemporaryInstantiationSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/performance/UnnecessaryTemporaryInstantiationSpec.kt index 7578aa50b..057544db1 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/performance/UnnecessaryTemporaryInstantiationSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/performance/UnnecessaryTemporaryInstantiationSpec.kt @@ -9,15 +9,15 @@ import org.jetbrains.spek.subject.SubjectSpek * @author schalkms */ class UnnecessaryTemporaryInstantiationSpec : SubjectSpek({ - subject { UnnecessaryTemporaryInstantiation() } + subject { UnnecessaryTemporaryInstantiation() } - describe("temporary instantiation for conversion") { - val code = "val i = Integer(1).toString()" - assertThat(subject.compileAndLint(code)).hasSize(1) - } + describe("temporary instantiation for conversion") { + val code = "val i = Integer(1).toString()" + assertThat(subject.compileAndLint(code)).hasSize(1) + } - describe("right conversion without instantiation") { - val code = "val i = Integer.toString(1)" - assertThat(subject.compileAndLint(code)).isEmpty() - } + describe("right conversion without instantiation") { + val code = "val i = Integer.toString(1)" + assertThat(subject.compileAndLint(code)).isEmpty() + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/CollapsibleIfStatementsSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/CollapsibleIfStatementsSpec.kt index 4944d3840..549075a6a 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/CollapsibleIfStatementsSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/CollapsibleIfStatementsSpec.kt @@ -9,18 +9,18 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class CollapsibleIfStatementsSpec : SubjectSpek({ - subject { CollapsibleIfStatements(Config.empty) } + subject { CollapsibleIfStatements(Config.empty) } - given("multiple if statements") { + given("multiple if statements") { - it("reports if statements which can be merged") { - val path = Case.CollapsibleIfsPositive.path() - assertThat(subject.lint(path)).hasSize(2) - } + it("reports if statements which can be merged") { + val path = Case.CollapsibleIfsPositive.path() + assertThat(subject.lint(path)).hasSize(2) + } - it("does not report if statements which can't be merged") { - val path = Case.CollapsibleIfsNegative.path() - assertThat(subject.lint(path)).hasSize(0) - } - } + it("does not report if statements which can't be merged") { + val path = Case.CollapsibleIfsNegative.path() + assertThat(subject.lint(path)).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/DataClassContainsFunctionsSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/DataClassContainsFunctionsSpec.kt index 7dd347ce1..5d246cd49 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/DataClassContainsFunctionsSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/DataClassContainsFunctionsSpec.kt @@ -13,24 +13,24 @@ import org.jetbrains.spek.subject.SubjectSpek */ class DataClassContainsFunctionsSpec : SubjectSpek({ - subject { DataClassContainsFunctions() } + subject { DataClassContainsFunctions() } - given("several data classes") { + given("several data classes") { - val path = Case.DataClassContainsFunctionsPositive.path() + val path = Case.DataClassContainsFunctionsPositive.path() - it("reports valid data class w/o conversion function") { - assertThat(subject.lint(path)).hasSize(3) - } + it("reports valid data class w/o conversion function") { + assertThat(subject.lint(path)).hasSize(3) + } - it("reports valid data class w/ conversion function") { - val config = TestConfig(mapOf(DataClassContainsFunctions.CONVERSION_FUNCTION_PREFIX to "to")) - val rule = DataClassContainsFunctions(config) - assertThat(rule.lint(path)).hasSize(2) - } + it("reports valid data class w/ conversion function") { + val config = TestConfig(mapOf(DataClassContainsFunctions.CONVERSION_FUNCTION_PREFIX to "to")) + val rule = DataClassContainsFunctions(config) + assertThat(rule.lint(path)).hasSize(2) + } - it("does not report data class w/o conversion function") { - assertThat(subject.lint(Case.DataClassContainsFunctionsNegative.path())).hasSize(0) - } - } + it("does not report data class w/o conversion function") { + assertThat(subject.lint(Case.DataClassContainsFunctionsNegative.path())).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/EqualsNullCallSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/EqualsNullCallSpec.kt index 57e699629..20dbc2037 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/EqualsNullCallSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/EqualsNullCallSpec.kt @@ -8,32 +8,32 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class EqualsNullCallSpec : SubjectSpek({ - subject { EqualsNullCall(Config.empty) } + subject { EqualsNullCall(Config.empty) } - given("an equals method with a parameter") { + given("an equals method with a parameter") { - it("with null as parameter") { - val code = """ + it("with null as parameter") { + val code = """ fun x(a: String) { a.equals(null) }""" - Assertions.assertThat(subject.lint(code).size).isEqualTo(1) - } + Assertions.assertThat(subject.lint(code).size).isEqualTo(1) + } - it("with nested equals(null) call as parameter") { - val code = """ + it("with nested equals(null) call as parameter") { + val code = """ fun x(a: String, b: String) { a.equals(b.equals(null)) }""" - Assertions.assertThat(subject.lint(code).size).isEqualTo(1) - } + Assertions.assertThat(subject.lint(code).size).isEqualTo(1) + } - it("with non-nullable parameter") { - val code = """ + it("with non-nullable parameter") { + val code = """ fun x(a: String, b: String) { a.equals(b) }""" - Assertions.assertThat(subject.lint(code).size).isEqualTo(0) - } - } + Assertions.assertThat(subject.lint(code).size).isEqualTo(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/EqualsOnSignatureLineSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/EqualsOnSignatureLineSpec.kt index 85036884a..f113f8213 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/EqualsOnSignatureLineSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/EqualsOnSignatureLineSpec.kt @@ -8,33 +8,33 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class EqualsOnSignatureLineSpec : SubjectSpek({ - subject { EqualsOnSignatureLine(Config.empty) } + subject { EqualsOnSignatureLine(Config.empty) } - given("a function") { + given("a function") { - given("with expression syntax and without a return type") { - it("reports when the equals is on a new line") { - val findings = subject.lint(""" + given("with expression syntax and without a return type") { + it("reports when the equals is on a new line") { + val findings = subject.lint(""" fun foo() = 1 """) - assertThat(findings).hasSize(1) - } + assertThat(findings).hasSize(1) + } - it("succeeds when the equals is on the same line") { - val findings = subject.lint(""" + it("succeeds when the equals is on the same line") { + val findings = subject.lint(""" fun foo() = 1 fun bar() = 2 """) - assertThat(findings).isEmpty() - } - } + assertThat(findings).isEmpty() + } + } - given("with expression syntax and with a return type") { - it("reports when the equals is on a new line") { - val findings = subject.lint(""" + given("with expression syntax and with a return type") { + it("reports when the equals is on a new line") { + val findings = subject.lint(""" fun one(): Int = 1 @@ -48,11 +48,11 @@ class EqualsOnSignatureLineSpec : SubjectSpek({ ): Int = 3 """) - assertThat(findings).hasSize(3) - } + assertThat(findings).hasSize(3) + } - it("succeeds when the equals is on the same line") { - val findings = subject.lint(""" + it("succeeds when the equals is on the same line") { + val findings = subject.lint(""" fun one(): Int = 1 @@ -82,13 +82,13 @@ class EqualsOnSignatureLineSpec : SubjectSpek({ Int = 6 """) - assertThat(findings).isEmpty() - } - } + assertThat(findings).isEmpty() + } + } - given("with expression syntax and with a where clause") { - it("reports when the equals is on a new line") { - val findings = subject.lint(""" + given("with expression syntax and with a where clause") { + it("reports when the equals is on a new line") { + val findings = subject.lint(""" fun one(): Int where V : Number = 1 @@ -103,11 +103,11 @@ class EqualsOnSignatureLineSpec : SubjectSpek({ where V : Number = 3 """) - assertThat(findings).hasSize(3) - } + assertThat(findings).hasSize(3) + } - it("succeeds when the equals is on the same line") { - val findings = subject.lint(""" + it("succeeds when the equals is on the same line") { + val findings = subject.lint(""" fun one(): Int where V : Number = 1 @@ -116,12 +116,12 @@ class EqualsOnSignatureLineSpec : SubjectSpek({ 2 """) - assertThat(findings).isEmpty() - } - } + assertThat(findings).isEmpty() + } + } - it("for non-expression functions") { - val findings = subject.lint(""" + it("for non-expression functions") { + val findings = subject.lint(""" fun foo() { } @@ -135,7 +135,7 @@ class EqualsOnSignatureLineSpec : SubjectSpek({ { } """) - assertThat(findings).isEmpty() - } - } + assertThat(findings).isEmpty() + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ExplicitItLambdaParameterSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ExplicitItLambdaParameterSpec.kt index 2a4e48b45..abc18bc8f 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ExplicitItLambdaParameterSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ExplicitItLambdaParameterSpec.kt @@ -9,53 +9,53 @@ import org.jetbrains.spek.api.dsl.on import org.jetbrains.spek.subject.SubjectSpek class ExplicitItLambdaParameterSpec : SubjectSpek({ - subject { ExplicitItLambdaParameter(Config.empty) } + subject { ExplicitItLambdaParameter(Config.empty) } - given("lambda with single parameter") { - on("single parameter with name `it` declared explicitly") { - it("reports when parameter type is not declared") { - val findings = subject.lint(""" + given("lambda with single parameter") { + on("single parameter with name `it` declared explicitly") { + it("reports when parameter type is not declared") { + val findings = subject.lint(""" fun f() { val digits = 1234.let { it -> listOf(it) } }""") - assertThat(findings).hasSize(1) - } - it("reports when parameter type is declared explicitly") { - val findings = subject.lint(""" + assertThat(findings).hasSize(1) + } + it("reports when parameter type is declared explicitly") { + val findings = subject.lint(""" fun f() { val lambda = { it: Int -> it.toString() } }""") - assertThat(findings).hasSize(1) - } - } - on("no parameter declared explicitly") { - it("does not report implicit `it` parameter usage") { - val findings = subject.lint(""" + assertThat(findings).hasSize(1) + } + } + on("no parameter declared explicitly") { + it("does not report implicit `it` parameter usage") { + val findings = subject.lint(""" fun f() { val lambda = { it.toString() } val digits = 1234.let { lambda(it) }.toList() val flat = listOf(listOf(1), listOf(2)).flatMap { it } }""") - assertThat(findings).isEmpty() - } - } - } - given("some code using lambdas with (slightly) better style guidelines") { - on("multiple parameters one of which with name `it` declared explicitly") { - it("reports when parameter types are not declared") { - val findings = subject.lint(""" + assertThat(findings).isEmpty() + } + } + } + given("some code using lambdas with (slightly) better style guidelines") { + on("multiple parameters one of which with name `it` declared explicitly") { + it("reports when parameter types are not declared") { + val findings = subject.lint(""" fun f() { val flat = listOf(listOf(1), listOf(2)).mapIndexed { index, it -> it + index } }""") - assertThat(findings).hasSize(1) - } - it("reports when parameter types are declared explicitly"){ - val findings = subject.lint(""" + assertThat(findings).hasSize(1) + } + it("reports when parameter types are declared explicitly") { + val findings = subject.lint(""" fun f() { val lambda = { it: Int, that: String -> it.toString() + that } }""") - assertThat(findings).hasSize(1) - } - } - } + assertThat(findings).hasSize(1) + } + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ExpressionBodySyntaxSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ExpressionBodySyntaxSpec.kt index 433667d62..bed924374 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ExpressionBodySyntaxSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ExpressionBodySyntaxSpec.kt @@ -12,30 +12,30 @@ import org.jetbrains.spek.subject.SubjectSpek * @author Artur Bosch */ class ExpressionBodySyntaxSpec : SubjectSpek({ - subject { ExpressionBodySyntax(Config.empty) } + subject { ExpressionBodySyntax(Config.empty) } - given("several return statements") { + given("several return statements") { - it("reports constant return") { - assertThat(subject.lint(""" + it("reports constant return") { + assertThat(subject.lint(""" fun stuff(): Int { return 5 } """ - )).hasSize(1) - } + )).hasSize(1) + } - it("reports return statement with method chain") { - assertThat(subject.lint(""" + it("reports return statement with method chain") { + assertThat(subject.lint(""" fun stuff(): Int { return moreStuff().getStuff().stuffStuff() } """ - )).hasSize(1) - } + )).hasSize(1) + } - it("reports return statements with conditionals") { - assertThat(subject.lint(""" + it("reports return statements with conditionals") { + assertThat(subject.lint(""" fun stuff(): Int { return if (true) return 5 else return 3 } @@ -43,40 +43,40 @@ class ExpressionBodySyntaxSpec : SubjectSpek({ return try { return 5 } catch (e: Exception) { return 3 } } """)).hasSize(2) - } + } - it("does not report multiple if statements") { - assertThat(subject.lint(""" + it("does not report multiple if statements") { + assertThat(subject.lint(""" fun stuff(): Int { if (true) return true return false } """)).isEmpty() - } - } + } + } - given("several return statements with multiline method chain") { + given("several return statements with multiline method chain") { - val code = """ + val code = """ fun stuff(): Int { return moreStuff() .getStuff() .stuffStuff() }""" - it("does not report with the default configuration") { - assertThat(subject.lint(code)).isEmpty() - } + it("does not report with the default configuration") { + assertThat(subject.lint(code)).isEmpty() + } - it("reports with includeLineWrapping = true configuration") { - val config = TestConfig(mapOf(ExpressionBodySyntax.INCLUDE_LINE_WRAPPING to "true")) - assertThat(ExpressionBodySyntax(config).lint(code)).hasSize(1) - } - } + it("reports with includeLineWrapping = true configuration") { + val config = TestConfig(mapOf(ExpressionBodySyntax.INCLUDE_LINE_WRAPPING to "true")) + assertThat(ExpressionBodySyntax(config).lint(code)).hasSize(1) + } + } - given("several return statements with multiline when expression") { + given("several return statements with multiline when expression") { - val code = """ + val code = """ fun stuff(val arg: Int): Int { return when(arg) { 0 -> 0 @@ -84,31 +84,31 @@ class ExpressionBodySyntaxSpec : SubjectSpek({ } }""" - it("does not report with the default configuration") { - assertThat(subject.lint(code)).isEmpty() - } + it("does not report with the default configuration") { + assertThat(subject.lint(code)).isEmpty() + } - it("reports with includeLineWrapping = true configuration") { - val config = TestConfig(mapOf(ExpressionBodySyntax.INCLUDE_LINE_WRAPPING to "true")) - assertThat(ExpressionBodySyntax(config).lint(code)).hasSize(1) - } - } + it("reports with includeLineWrapping = true configuration") { + val config = TestConfig(mapOf(ExpressionBodySyntax.INCLUDE_LINE_WRAPPING to "true")) + assertThat(ExpressionBodySyntax(config).lint(code)).hasSize(1) + } + } - given("several return statements with multiline if expression") { + given("several return statements with multiline if expression") { - val code = """ + val code = """ fun stuff(val arg: Int): Int { return if (arg == 0) 0 else 1 }""" - it("does not report with the default configuration") { - assertThat(subject.lint(code)).isEmpty() - } + it("does not report with the default configuration") { + assertThat(subject.lint(code)).isEmpty() + } - it("reports with includeLineWrapping = true configuration") { - val config = TestConfig(mapOf(ExpressionBodySyntax.INCLUDE_LINE_WRAPPING to "true")) - assertThat(ExpressionBodySyntax(config).lint(code)).hasSize(1) - } - } + it("reports with includeLineWrapping = true configuration") { + val config = TestConfig(mapOf(ExpressionBodySyntax.INCLUDE_LINE_WRAPPING to "true")) + assertThat(ExpressionBodySyntax(config).lint(code)).hasSize(1) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenCommentSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenCommentSpec.kt index 551e52cfc..134d0e3c0 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenCommentSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenCommentSpec.kt @@ -9,74 +9,74 @@ import org.jetbrains.spek.api.dsl.it class ForbiddenCommentSpec : Spek({ - val todoColon = "// TODO: I need to fix this." - val todo = "// TODO I need to fix this." + val todoColon = "// TODO: I need to fix this." + val todo = "// TODO I need to fix this." - val fixmeColon = "// FIXME: I need to fix this." - val fixme = "// FIXME I need to fix this." + val fixmeColon = "// FIXME: I need to fix this." + val fixme = "// FIXME I need to fix this." - val stopShipColon = "// STOPSHIP: I need to fix this." - val stopShip = "// STOPSHIP I need to fix this." + val stopShipColon = "// STOPSHIP: I need to fix this." + val stopShip = "// STOPSHIP I need to fix this." - given("the default values are configured") { + given("the default values are configured") { - it("should report TODO: usages") { - val findings = ForbiddenComment().lint(todoColon) - assertThat(findings).hasSize(1) - } + it("should report TODO: usages") { + val findings = ForbiddenComment().lint(todoColon) + assertThat(findings).hasSize(1) + } - it("should not report TODO usages") { - val findings = ForbiddenComment().lint(todo) - assertThat(findings).hasSize(0) - } + it("should not report TODO usages") { + val findings = ForbiddenComment().lint(todo) + assertThat(findings).hasSize(0) + } - it("should report FIXME: usages") { - val findings = ForbiddenComment().lint(fixmeColon) - assertThat(findings).hasSize(1) - } + it("should report FIXME: usages") { + val findings = ForbiddenComment().lint(fixmeColon) + assertThat(findings).hasSize(1) + } - it("should not report FIXME usages") { - val findings = ForbiddenComment().lint(fixme) - assertThat(findings).hasSize(0) - } + it("should not report FIXME usages") { + val findings = ForbiddenComment().lint(fixme) + assertThat(findings).hasSize(0) + } - it("should report STOPSHIP: usages") { - val findings = ForbiddenComment().lint(stopShipColon) - assertThat(findings).hasSize(1) - } + it("should report STOPSHIP: usages") { + val findings = ForbiddenComment().lint(stopShipColon) + assertThat(findings).hasSize(1) + } - it("should not report STOPSHIP usages") { - val findings = ForbiddenComment().lint(stopShip) - assertThat(findings).hasSize(0) - } - } + it("should not report STOPSHIP usages") { + val findings = ForbiddenComment().lint(stopShip) + assertThat(findings).hasSize(0) + } + } - given("custom default values are configured") { - val banana = "// Banana." + given("custom default values are configured") { + val banana = "// Banana." - it("should not report TODO: usages") { - val findings = ForbiddenComment(TestConfig(mapOf(ForbiddenComment.VALUES to "Banana"))).lint(todoColon) - assertThat(findings).hasSize(0) - } + it("should not report TODO: usages") { + val findings = ForbiddenComment(TestConfig(mapOf(ForbiddenComment.VALUES to "Banana"))).lint(todoColon) + assertThat(findings).hasSize(0) + } - it("should not report FIXME: usages") { - val findings = ForbiddenComment(TestConfig(mapOf(ForbiddenComment.VALUES to "Banana"))).lint(fixmeColon) - assertThat(findings).hasSize(0) - } + it("should not report FIXME: usages") { + val findings = ForbiddenComment(TestConfig(mapOf(ForbiddenComment.VALUES to "Banana"))).lint(fixmeColon) + assertThat(findings).hasSize(0) + } - it("should not report STOPME: usages") { - val findings = ForbiddenComment(TestConfig(mapOf(ForbiddenComment.VALUES to "Banana"))).lint(stopShipColon) - assertThat(findings).hasSize(0) - } + it("should not report STOPME: usages") { + val findings = ForbiddenComment(TestConfig(mapOf(ForbiddenComment.VALUES to "Banana"))).lint(stopShipColon) + assertThat(findings).hasSize(0) + } - it("should report Banana usages") { - val findings = ForbiddenComment(TestConfig(mapOf(ForbiddenComment.VALUES to "Banana"))).lint(banana) - assertThat(findings).hasSize(1) - } + it("should report Banana usages") { + val findings = ForbiddenComment(TestConfig(mapOf(ForbiddenComment.VALUES to "Banana"))).lint(banana) + assertThat(findings).hasSize(1) + } - it("should report Banana usages regardless of case sensitive") { - val findings = ForbiddenComment(TestConfig(mapOf(ForbiddenComment.VALUES to "bAnAnA"))).lint(banana) - assertThat(findings).hasSize(1) - } - } + it("should report Banana usages regardless of case sensitive") { + val findings = ForbiddenComment(TestConfig(mapOf(ForbiddenComment.VALUES to "bAnAnA"))).lint(banana) + assertThat(findings).hasSize(1) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenImportSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenImportSpec.kt index f14595957..da3cbf09d 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenImportSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenImportSpec.kt @@ -8,8 +8,8 @@ import org.jetbrains.spek.api.dsl.given import org.jetbrains.spek.api.dsl.it class ForbiddenImportSpec : Spek({ - given("a file with imports") { - val code = """ + given("a file with imports") { + val code = """ package foo import kotlin.jvm.JvmField @@ -19,44 +19,44 @@ class ForbiddenImportSpec : Spek({ import net.example.R.dimen """ - it("should report nothing by default") { - val findings = ForbiddenImport().lint(code) - assertThat(findings).hasSize(0) - } + it("should report nothing by default") { + val findings = ForbiddenImport().lint(code) + assertThat(findings).hasSize(0) + } - it("should report nothing when imports are blank") { - val findings = ForbiddenImport(TestConfig(mapOf(ForbiddenImport.IMPORTS to " "))).lint(code) - assertThat(findings).hasSize(0) - } + it("should report nothing when imports are blank") { + val findings = ForbiddenImport(TestConfig(mapOf(ForbiddenImport.IMPORTS to " "))).lint(code) + assertThat(findings).hasSize(0) + } - it("should report nothing when imports do not match") { - val findings = ForbiddenImport(TestConfig(mapOf(ForbiddenImport.IMPORTS to "org.*"))).lint(code) - assertThat(findings).hasSize(0) - } + it("should report nothing when imports do not match") { + val findings = ForbiddenImport(TestConfig(mapOf(ForbiddenImport.IMPORTS to "org.*"))).lint(code) + assertThat(findings).hasSize(0) + } - it("should report kotlin.* when imports are kotlin.*") { - val findings = ForbiddenImport(TestConfig(mapOf(ForbiddenImport.IMPORTS to "kotlin.*"))).lint(code) - assertThat(findings).hasSize(2) - } + it("should report kotlin.* when imports are kotlin.*") { + val findings = ForbiddenImport(TestConfig(mapOf(ForbiddenImport.IMPORTS to "kotlin.*"))).lint(code) + assertThat(findings).hasSize(2) + } - it("should report kotlin.SinceKotlin when specified via fully qualified name") { - val findings = ForbiddenImport(TestConfig(mapOf(ForbiddenImport.IMPORTS to "kotlin.SinceKotlin"))).lint(code) - assertThat(findings).hasSize(1) - } + it("should report kotlin.SinceKotlin when specified via fully qualified name") { + val findings = ForbiddenImport(TestConfig(mapOf(ForbiddenImport.IMPORTS to "kotlin.SinceKotlin"))).lint(code) + assertThat(findings).hasSize(1) + } - it("should report kotlin.SinceKotlin and kotlin.jvm.JvmField when specified via fully qualified names") { - val findings = ForbiddenImport(TestConfig(mapOf(ForbiddenImport.IMPORTS to "kotlin.SinceKotlin,kotlin.jvm.JvmField"))).lint(code) - assertThat(findings).hasSize(2) - } + it("should report kotlin.SinceKotlin and kotlin.jvm.JvmField when specified via fully qualified names") { + val findings = ForbiddenImport(TestConfig(mapOf(ForbiddenImport.IMPORTS to "kotlin.SinceKotlin,kotlin.jvm.JvmField"))).lint(code) + assertThat(findings).hasSize(2) + } - it("should report kotlin.SinceKotlin when specified via kotlin.Since*") { - val findings = ForbiddenImport(TestConfig(mapOf(ForbiddenImport.IMPORTS to "kotlin.Since*"))).lint(code) - assertThat(findings).hasSize(1) - } + it("should report kotlin.SinceKotlin when specified via kotlin.Since*") { + val findings = ForbiddenImport(TestConfig(mapOf(ForbiddenImport.IMPORTS to "kotlin.Since*"))).lint(code) + assertThat(findings).hasSize(1) + } - it("should report both com.example.R.string and net.example.R.dimen") { - val findings = ForbiddenImport(TestConfig(mapOf(ForbiddenImport.IMPORTS to "*.R.*"))).lint(code) - assertThat(findings).hasSize(2) - } - } + it("should report both com.example.R.string and net.example.R.dimen") { + val findings = ForbiddenImport(TestConfig(mapOf(ForbiddenImport.IMPORTS to "*.R.*"))).lint(code) + assertThat(findings).hasSize(2) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenVoidSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenVoidSpec.kt index 2f8596243..696470a9a 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenVoidSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenVoidSpec.kt @@ -7,9 +7,9 @@ import org.jetbrains.spek.api.dsl.given import org.jetbrains.spek.api.dsl.it class ForbiddenVoidSpec : Spek({ - given("some Void usage") { - it("should report all Void type usage") { - val code = """ + given("some Void usage") { + it("should report all Void type usage") { + val code = """ lateinit var c: () -> Void fun method(param: Void) { @@ -18,18 +18,18 @@ class ForbiddenVoidSpec : Spek({ } """ - val findings = ForbiddenVoid().lint(code) - assertThat(findings).hasSize(4) - } + val findings = ForbiddenVoid().lint(code) + assertThat(findings).hasSize(4) + } - it("should not report Void class literal") { - val code = """ + it("should not report Void class literal") { + val code = """ val clazz = java.lang.Void::class val klass = Void::class """ - val findings = ForbiddenVoid().lint(code) - assertThat(findings).isEmpty() - } - } + val findings = ForbiddenVoid().lint(code) + assertThat(findings).isEmpty() + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/FunctionOnlyReturningConstantSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/FunctionOnlyReturningConstantSpec.kt index 3eea8f6d9..4a4f5c73a 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/FunctionOnlyReturningConstantSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/FunctionOnlyReturningConstantSpec.kt @@ -9,35 +9,35 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class FunctionOnlyReturningConstantSpec : SubjectSpek({ - subject { FunctionOnlyReturningConstant() } + subject { FunctionOnlyReturningConstant() } - given("some functions which return constants") { + given("some functions which return constants") { - val path = Case.FunctionReturningConstantPositive.path() + val path = Case.FunctionReturningConstantPositive.path() - it("reports functions which return constants") { - assertThat(subject.lint(path)).hasSize(6) - } + it("reports functions which return constants") { + assertThat(subject.lint(path)).hasSize(6) + } - it("reports overridden functions which return constants") { - val config = TestConfig(mapOf("ignoreOverridableFunction" to "false")) - val rule = FunctionOnlyReturningConstant(config) - assertThat(rule.lint(path)).hasSize(9) - } + it("reports overridden functions which return constants") { + val config = TestConfig(mapOf("ignoreOverridableFunction" to "false")) + val rule = FunctionOnlyReturningConstant(config) + assertThat(rule.lint(path)).hasSize(9) + } - it("does not report excluded function which returns a constant") { - val code = "fun f() = 1" - val config = TestConfig(mapOf("excludedFunctions" to "f")) - val rule = FunctionOnlyReturningConstant(config) - assertThat(rule.lint(code)).hasSize(0) - } - } + it("does not report excluded function which returns a constant") { + val code = "fun f() = 1" + val config = TestConfig(mapOf("excludedFunctions" to "f")) + val rule = FunctionOnlyReturningConstant(config) + assertThat(rule.lint(code)).hasSize(0) + } + } - given("some functions which do not return constants") { + given("some functions which do not return constants") { - it("does not report functions which do not return constants") { - val path = Case.FunctionReturningConstantNegative.path() - assertThat(subject.lint(path)).isEmpty() - } - } + it("does not report functions which do not return constants") { + val path = Case.FunctionReturningConstantNegative.path() + assertThat(subject.lint(path)).isEmpty() + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/LoopWithTooManyJumpStatementsSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/LoopWithTooManyJumpStatementsSpec.kt index 564c00332..8ae465db4 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/LoopWithTooManyJumpStatementsSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/LoopWithTooManyJumpStatementsSpec.kt @@ -9,25 +9,25 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class LoopWithTooManyJumpStatementsSpec : SubjectSpek({ - subject { LoopWithTooManyJumpStatements() } + subject { LoopWithTooManyJumpStatements() } - given("loops with multiple break or continue statements") { + given("loops with multiple break or continue statements") { - val path = Case.LoopWithTooManyJumpStatementsPositive.path() + val path = Case.LoopWithTooManyJumpStatementsPositive.path() - it("reports loops with more than 1 break or continue statement") { - assertThat(subject.lint(path)).hasSize(3) - } + it("reports loops with more than 1 break or continue statement") { + assertThat(subject.lint(path)).hasSize(3) + } - it("does not report when max count configuration is set to 2") { - val config = TestConfig(mapOf(LoopWithTooManyJumpStatements.MAX_JUMP_COUNT to "2")) - val findings = LoopWithTooManyJumpStatements(config).lint(path) - assertThat(findings).hasSize(0) - } + it("does not report when max count configuration is set to 2") { + val config = TestConfig(mapOf(LoopWithTooManyJumpStatements.MAX_JUMP_COUNT to "2")) + val findings = LoopWithTooManyJumpStatements(config).lint(path) + assertThat(findings).hasSize(0) + } - it("does not report loop with less than 1 break or continue statement") { - val findings = subject.lint(Case.LoopWithTooManyJumpStatementsNegative.path()) - assertThat(findings).hasSize(0) - } - } + it("does not report loop with less than 1 break or continue statement") { + val findings = subject.lint(Case.LoopWithTooManyJumpStatementsNegative.path()) + assertThat(findings).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MagicNumberSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MagicNumberSpec.kt index 7cf8e9f2a..00043524e 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MagicNumberSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MagicNumberSpec.kt @@ -13,254 +13,254 @@ import org.jetbrains.spek.api.dsl.it class MagicNumberSpec : Spek({ - val fileName = TEST_FILENAME + val fileName = TEST_FILENAME - given("a float of 1") { - val ktFile = compileContentForTest("val myFloat = 1.0f") + given("a float of 1") { + val ktFile = compileContentForTest("val myFloat = 1.0f") - it("should not be reported by default") { - val findings = MagicNumber().lint(ktFile) - assertThat(findings).isEmpty() - } + it("should not be reported by default") { + val findings = MagicNumber().lint(ktFile) + assertThat(findings).isEmpty() + } - it("should be reported when ignoredNumbers is empty") { - val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to ""))).lint(ktFile) - assertThat(findings).hasLocationStrings("'1.0f' at (1,15) in /$fileName") - } - } + it("should be reported when ignoredNumbers is empty") { + val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to ""))).lint(ktFile) + assertThat(findings).hasLocationStrings("'1.0f' at (1,15) in /$fileName") + } + } - given("a const float of 1") { - val ktFile = compileContentForTest("const val MY_FLOAT = 1.0f") + given("a const float of 1") { + val ktFile = compileContentForTest("const val MY_FLOAT = 1.0f") - it("should not be reported by default") { - val findings = MagicNumber().lint(ktFile) - assertThat(findings).isEmpty() - } + it("should not be reported by default") { + val findings = MagicNumber().lint(ktFile) + assertThat(findings).isEmpty() + } - it("should not be reported when ignoredNumbers is empty") { - val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to ""))).lint(ktFile) - assertThat(findings).isEmpty() - } - } + it("should not be reported when ignoredNumbers is empty") { + val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to ""))).lint(ktFile) + assertThat(findings).isEmpty() + } + } - given("an integer of 1") { - val ktFile = compileContentForTest("val myInt = 1") + given("an integer of 1") { + val ktFile = compileContentForTest("val myInt = 1") - it("should not be reported by default") { - val findings = MagicNumber().lint(ktFile) - assertThat(findings).isEmpty() - } + it("should not be reported by default") { + val findings = MagicNumber().lint(ktFile) + assertThat(findings).isEmpty() + } - it("should be reported when ignoredNumbers is empty") { - val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to ""))).lint(ktFile) - assertThat(findings).hasLocationStrings("'1' at (1,13) in /$fileName") - } - } + it("should be reported when ignoredNumbers is empty") { + val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to ""))).lint(ktFile) + assertThat(findings).hasLocationStrings("'1' at (1,13) in /$fileName") + } + } - given("a const integer of 1") { - val ktFile = compileContentForTest("const val MY_INT = 1") + given("a const integer of 1") { + val ktFile = compileContentForTest("const val MY_INT = 1") - it("should not be reported by default") { - val findings = MagicNumber().lint(ktFile) - assertThat(findings).isEmpty() - } + it("should not be reported by default") { + val findings = MagicNumber().lint(ktFile) + assertThat(findings).isEmpty() + } - it("should not be reported when ignoredNumbers is empty") { - val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to ""))).lint(ktFile) - assertThat(findings).isEmpty() - } - } + it("should not be reported when ignoredNumbers is empty") { + val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to ""))).lint(ktFile) + assertThat(findings).isEmpty() + } + } - given("a long of 1") { - val ktFile = compileContentForTest("val myLong = 1L") + given("a long of 1") { + val ktFile = compileContentForTest("val myLong = 1L") - it("should not be reported by default") { - val findings = MagicNumber().lint(ktFile) - assertThat(findings).isEmpty() - } + it("should not be reported by default") { + val findings = MagicNumber().lint(ktFile) + assertThat(findings).isEmpty() + } - it("should be reported when ignoredNumbers is empty") { - val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to ""))).lint(ktFile) - assertThat(findings).hasLocationStrings("'1L' at (1,14) in /$fileName") - } - } + it("should be reported when ignoredNumbers is empty") { + val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to ""))).lint(ktFile) + assertThat(findings).hasLocationStrings("'1L' at (1,14) in /$fileName") + } + } - given("a long of -1") { - val ktFile = compileContentForTest("val myLong = -1L") + given("a long of -1") { + val ktFile = compileContentForTest("val myLong = -1L") - it("should not be reported by default") { - val findings = MagicNumber().lint(ktFile) - assertThat(findings).isEmpty() - } + it("should not be reported by default") { + val findings = MagicNumber().lint(ktFile) + assertThat(findings).isEmpty() + } - it("should be reported when ignoredNumbers is empty") { - val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to ""))).lint(ktFile) - assertThat(findings).hasLocationStrings("'1L' at (1,15) in /$fileName") - } - } + it("should be reported when ignoredNumbers is empty") { + val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to ""))).lint(ktFile) + assertThat(findings).hasLocationStrings("'1L' at (1,15) in /$fileName") + } + } - given("a long of -2") { - val ktFile = compileContentForTest("val myLong = -2L") + given("a long of -2") { + val ktFile = compileContentForTest("val myLong = -2L") - it("should be reported by default") { - val findings = MagicNumber().lint(ktFile) - assertThat(findings).hasLocationStrings("'2L' at (1,15) in /$fileName") - } + it("should be reported by default") { + val findings = MagicNumber().lint(ktFile) + assertThat(findings).hasLocationStrings("'2L' at (1,15) in /$fileName") + } - it("should be ignored when ignoredNumbers contains it verbatim") { - val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to "-2L"))).lint(ktFile) - assertThat(findings).isEmpty() - } + it("should be ignored when ignoredNumbers contains it verbatim") { + val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to "-2L"))).lint(ktFile) + assertThat(findings).isEmpty() + } - it("should be ignored when ignoredNumbers contains it as floating point") { - val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to "-2f"))).lint(ktFile) - assertThat(findings).isEmpty() - } + it("should be ignored when ignoredNumbers contains it as floating point") { + val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to "-2f"))).lint(ktFile) + assertThat(findings).isEmpty() + } - it("should not be ignored when ignoredNumbers contains 2 but not -2") { - val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to "1,2,3,-1,0"))).lint(ktFile) - assertThat(findings).hasLocationStrings("'2L' at (1,15) in /$fileName") - } - } + it("should not be ignored when ignoredNumbers contains 2 but not -2") { + val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to "1,2,3,-1,0"))).lint(ktFile) + assertThat(findings).hasLocationStrings("'2L' at (1,15) in /$fileName") + } + } - given("a const long of 1") { - val ktFile = compileContentForTest("const val MY_LONG = 1L") + given("a const long of 1") { + val ktFile = compileContentForTest("const val MY_LONG = 1L") - it("should not be reported by default") { - val findings = MagicNumber().lint(ktFile) - assertThat(findings).isEmpty() - } + it("should not be reported by default") { + val findings = MagicNumber().lint(ktFile) + assertThat(findings).isEmpty() + } - it("should not be reported when ignoredNumbers is empty") { - val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to ""))).lint(ktFile) - assertThat(findings).isEmpty() - } - } + it("should not be reported when ignoredNumbers is empty") { + val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to ""))).lint(ktFile) + assertThat(findings).isEmpty() + } + } - given("a double of 1") { - val ktFile = compileContentForTest("val myDouble = 1.0") + given("a double of 1") { + val ktFile = compileContentForTest("val myDouble = 1.0") - it("should not be reported by default") { - val findings = MagicNumber().lint(ktFile) - assertThat(findings).isEmpty() - } + it("should not be reported by default") { + val findings = MagicNumber().lint(ktFile) + assertThat(findings).isEmpty() + } - it("should be reported when ignoredNumbers is empty") { - val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to ""))).lint(ktFile) - assertThat(findings).hasLocationStrings("'1.0' at (1,16) in /$fileName") - } - } + it("should be reported when ignoredNumbers is empty") { + val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to ""))).lint(ktFile) + assertThat(findings).hasLocationStrings("'1.0' at (1,16) in /$fileName") + } + } - given("a const double of 1") { - val ktFile = compileContentForTest("const val MY_DOUBLE = 1.0") + given("a const double of 1") { + val ktFile = compileContentForTest("const val MY_DOUBLE = 1.0") - it("should not be reported by default") { - val findings = MagicNumber().lint(ktFile) - assertThat(findings).isEmpty() - } + it("should not be reported by default") { + val findings = MagicNumber().lint(ktFile) + assertThat(findings).isEmpty() + } - it("should not be reported when ignoredNumbers is empty") { - val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to ""))).lint(ktFile) - assertThat(findings).isEmpty() - } - } + it("should not be reported when ignoredNumbers is empty") { + val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to ""))).lint(ktFile) + assertThat(findings).isEmpty() + } + } - given("a hex of 1") { - val ktFile = compileContentForTest("val myHex = 0x1") + given("a hex of 1") { + val ktFile = compileContentForTest("val myHex = 0x1") - it("should not be reported by default") { - val findings = MagicNumber().lint(ktFile) - assertThat(findings).isEmpty() - } + it("should not be reported by default") { + val findings = MagicNumber().lint(ktFile) + assertThat(findings).isEmpty() + } - it("should be reported when ignoredNumbers is empty") { - val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to ""))).lint(ktFile) - assertThat(findings).hasLocationStrings("'0x1' at (1,13) in /$fileName") - } - } + it("should be reported when ignoredNumbers is empty") { + val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to ""))).lint(ktFile) + assertThat(findings).hasLocationStrings("'0x1' at (1,13) in /$fileName") + } + } - given("a const hex of 1") { - val ktFile = compileContentForTest("const val MY_HEX = 0x1") + given("a const hex of 1") { + val ktFile = compileContentForTest("const val MY_HEX = 0x1") - it("should not be reported by default") { - val findings = MagicNumber().lint(ktFile) - assertThat(findings).isEmpty() - } + it("should not be reported by default") { + val findings = MagicNumber().lint(ktFile) + assertThat(findings).isEmpty() + } - it("should not be reported when ignoredNumbers is empty") { - val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to ""))).lint(ktFile) - assertThat(findings).isEmpty() - } - } + it("should not be reported when ignoredNumbers is empty") { + val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to ""))).lint(ktFile) + assertThat(findings).isEmpty() + } + } - given("an integer of 300") { - val ktFile = compileContentForTest("val myInt = 300") + given("an integer of 300") { + val ktFile = compileContentForTest("val myInt = 300") - it("should not be reported when ignoredNumbers contains 300") { - val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to "300"))).lint(ktFile) - assertThat(findings).isEmpty() - } + it("should not be reported when ignoredNumbers contains 300") { + val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to "300"))).lint(ktFile) + assertThat(findings).isEmpty() + } - it("should not be reported when ignoredNumbers contains a floating point 300") { - val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to "300.0"))).lint(ktFile) - assertThat(findings).isEmpty() - } - } + it("should not be reported when ignoredNumbers contains a floating point 300") { + val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to "300.0"))).lint(ktFile) + assertThat(findings).isEmpty() + } + } - given("a binary literal") { - val ktFile = compileContentForTest("val myBinary = 0b01001") + given("a binary literal") { + val ktFile = compileContentForTest("val myBinary = 0b01001") - it("should not be reported") { - val findings = MagicNumber().lint(ktFile) - assertThat(findings).hasSize(1) - } + it("should not be reported") { + val findings = MagicNumber().lint(ktFile) + assertThat(findings).hasSize(1) + } - it("should not be reported when ignoredNumbers contains a binary literal 0b01001") { - val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to "0b01001"))).lint(ktFile) - assertThat(findings).isEmpty() - } - } + it("should not be reported when ignoredNumbers contains a binary literal 0b01001") { + val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to "0b01001"))).lint(ktFile) + assertThat(findings).isEmpty() + } + } - given("an integer literal with underscores") { - val ktFile = compileContentForTest("val myInt = 100_000") + given("an integer literal with underscores") { + val ktFile = compileContentForTest("val myInt = 100_000") - it("should be reported by default") { - val findings = MagicNumber().lint(ktFile) - assertThat(findings).hasLocationStrings("'100_000' at (1,13) in /$fileName") - } + it("should be reported by default") { + val findings = MagicNumber().lint(ktFile) + assertThat(findings).hasLocationStrings("'100_000' at (1,13) in /$fileName") + } - it("should not be reported when ignored verbatim") { - val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to "100_000"))).lint(ktFile) - assertThat(findings).isEmpty() - } + it("should not be reported when ignored verbatim") { + val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to "100_000"))).lint(ktFile) + assertThat(findings).isEmpty() + } - it("should not be reported when ignored with different underscores") { - val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to "10_00_00"))).lint(ktFile) - assertThat(findings).isEmpty() - } + it("should not be reported when ignored with different underscores") { + val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to "10_00_00"))).lint(ktFile) + assertThat(findings).isEmpty() + } - it("should not be reported when ignored without underscores") { - val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to "100000"))).lint(ktFile) - assertThat(findings).isEmpty() - } - } + it("should not be reported when ignored without underscores") { + val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to "100000"))).lint(ktFile) + assertThat(findings).isEmpty() + } + } - given("an if statement with magic numbers") { - val ktFile = compileContentForTest("val myInt = if (5 < 6) 7 else 8") + given("an if statement with magic numbers") { + val ktFile = compileContentForTest("val myInt = if (5 < 6) 7 else 8") - it("should be reported") { - val findings = MagicNumber().lint(ktFile) - assertThat(findings).hasLocationStrings( - "'5' at (1,17) in /$fileName", - "'6' at (1,21) in /$fileName", - "'7' at (1,24) in /$fileName", - "'8' at (1,31) in /$fileName" - ) - } - } + it("should be reported") { + val findings = MagicNumber().lint(ktFile) + assertThat(findings).hasLocationStrings( + "'5' at (1,17) in /$fileName", + "'6' at (1,21) in /$fileName", + "'7' at (1,24) in /$fileName", + "'8' at (1,31) in /$fileName" + ) + } + } - given("a when statement with magic numbers") { - val ktFile = compileContentForTest(""" + given("a when statement with magic numbers") { + val ktFile = compileContentForTest(""" fun test(x: Int) { when (x) { 5 -> return 5 @@ -270,95 +270,95 @@ class MagicNumberSpec : Spek({ } """.trimMargin()) - it("should be reported") { - val findings = MagicNumber().lint(ktFile) - assertThat(findings).hasLocationStrings( - "'5' at (3,6) in /$fileName", - "'5' at (3,18) in /$fileName", - "'4' at (4,6) in /$fileName", - "'4' at (4,18) in /$fileName", - "'3' at (5,6) in /$fileName", - "'3' at (5,18) in /$fileName" - ) - } - } + it("should be reported") { + val findings = MagicNumber().lint(ktFile) + assertThat(findings).hasLocationStrings( + "'5' at (3,6) in /$fileName", + "'5' at (3,18) in /$fileName", + "'4' at (4,6) in /$fileName", + "'4' at (4,18) in /$fileName", + "'3' at (5,6) in /$fileName", + "'3' at (5,18) in /$fileName" + ) + } + } - given("a method containing variables with magic numbers") { - val ktFile = compileContentForTest(""" + given("a method containing variables with magic numbers") { + val ktFile = compileContentForTest(""" fun test(x: Int) { val i = 5 } """.trimMargin()) - it("should be reported") { - val findings = MagicNumber().lint(ktFile) - assertThat(findings).hasLocationStrings("'5' at (2,13) in /$fileName") - } - } + it("should be reported") { + val findings = MagicNumber().lint(ktFile) + assertThat(findings).hasLocationStrings("'5' at (2,13) in /$fileName") + } + } - given("a boolean value") { - val ktFile = compileContentForTest(""" + given("a boolean value") { + val ktFile = compileContentForTest(""" fun test() : Boolean { return true; } """.trimMargin()) - it("should not be reported") { - val findings = MagicNumber().lint(ktFile) - assertThat(findings).isEmpty() - } - } + it("should not be reported") { + val findings = MagicNumber().lint(ktFile) + assertThat(findings).isEmpty() + } + } - given("a non-numeric constant expression") { - val ktFile = compileContentForTest("val surprise = true") + given("a non-numeric constant expression") { + val ktFile = compileContentForTest("val surprise = true") - it("should not be reported") { - val findings = MagicNumber().lint(ktFile) - assertThat(findings).isEmpty() - } - } + it("should not be reported") { + val findings = MagicNumber().lint(ktFile) + assertThat(findings).isEmpty() + } + } - given("a float of 0.5") { - val ktFile = compileContentForTest("val test = 0.5f") + given("a float of 0.5") { + val ktFile = compileContentForTest("val test = 0.5f") - it("should be reported by default") { - val findings = MagicNumber().lint(ktFile) - assertThat(findings).hasLocationStrings("'0.5f' at (1,12) in /$fileName") - } + it("should be reported by default") { + val findings = MagicNumber().lint(ktFile) + assertThat(findings).hasLocationStrings("'0.5f' at (1,12) in /$fileName") + } - it("should not be reported when ignoredNumbers contains it") { - val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to ".5"))).lint(ktFile) - assertThat(findings).isEmpty() - } - } + it("should not be reported when ignoredNumbers contains it") { + val findings = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to ".5"))).lint(ktFile) + assertThat(findings).isEmpty() + } + } - given("a magic number number in a constructor call") { + given("a magic number number in a constructor call") { - it("should report") { - val code = "val file = File(42)" - val findings = MagicNumber().lint(code) - assertThat(findings).hasSize(1) - } - } + it("should report") { + val code = "val file = File(42)" + val findings = MagicNumber().lint(code) + assertThat(findings).hasSize(1) + } + } - given("an invalid ignoredNumber") { + given("an invalid ignoredNumber") { - it("throws a NumberFormatException") { - assertThatExceptionOfType(NumberFormatException::class.java).isThrownBy { - MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to "banana"))) - } - } - } + it("throws a NumberFormatException") { + assertThatExceptionOfType(NumberFormatException::class.java).isThrownBy { + MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to "banana"))) + } + } + } - given("an empty ignoredNumber") { + given("an empty ignoredNumber") { - it("doesn't throw an exception") { - MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to ""))) - } - } + it("doesn't throw an exception") { + MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_NUMBERS to ""))) + } + } - given("ignoring properties") { - val ktFile = compileContentForTest(""" + given("ignoring properties") { + val ktFile = compileContentForTest(""" @Magic(number = 69) class A { val boringNumber = 42 @@ -375,46 +375,46 @@ class MagicNumberSpec : Spek({ } """.trimMargin()) - it("should report all without ignore flags") { - val config = TestConfig( - mapOf( - MagicNumber.IGNORE_PROPERTY_DECLARATION to "false", - MagicNumber.IGNORE_ANNOTATION to "false", - MagicNumber.IGNORE_HASH_CODE to "false", - MagicNumber.IGNORE_CONSTANT_DECLARATION to "false", - MagicNumber.IGNORE_COMPANION_OBJECT_PROPERTY_DECLARATION to "false" - ) - ) + it("should report all without ignore flags") { + val config = TestConfig( + mapOf( + MagicNumber.IGNORE_PROPERTY_DECLARATION to "false", + MagicNumber.IGNORE_ANNOTATION to "false", + MagicNumber.IGNORE_HASH_CODE to "false", + MagicNumber.IGNORE_CONSTANT_DECLARATION to "false", + MagicNumber.IGNORE_COMPANION_OBJECT_PROPERTY_DECLARATION to "false" + ) + ) - val findings = MagicNumber(config).lint(ktFile) - assertThat(findings).hasLocationStrings( - "'69' at (1,20) in /$fileName", - "'42' at (3,24) in /$fileName", - "'93871' at (4,33) in /$fileName", - "'7328672' at (7,23) in /$fileName", - "'43' at (11,35) in /$fileName", - "'93872' at (12,40) in /$fileName" - ) - } + val findings = MagicNumber(config).lint(ktFile) + assertThat(findings).hasLocationStrings( + "'69' at (1,20) in /$fileName", + "'42' at (3,24) in /$fileName", + "'93871' at (4,33) in /$fileName", + "'7328672' at (7,23) in /$fileName", + "'43' at (11,35) in /$fileName", + "'93872' at (12,40) in /$fileName" + ) + } - it("should not report any issues with all ignore flags") { - val config = TestConfig( - mapOf( - MagicNumber.IGNORE_PROPERTY_DECLARATION to "true", - MagicNumber.IGNORE_ANNOTATION to "true", - MagicNumber.IGNORE_HASH_CODE to "true", - MagicNumber.IGNORE_CONSTANT_DECLARATION to "true", - MagicNumber.IGNORE_COMPANION_OBJECT_PROPERTY_DECLARATION to "true" - ) - ) + it("should not report any issues with all ignore flags") { + val config = TestConfig( + mapOf( + MagicNumber.IGNORE_PROPERTY_DECLARATION to "true", + MagicNumber.IGNORE_ANNOTATION to "true", + MagicNumber.IGNORE_HASH_CODE to "true", + MagicNumber.IGNORE_CONSTANT_DECLARATION to "true", + MagicNumber.IGNORE_COMPANION_OBJECT_PROPERTY_DECLARATION to "true" + ) + ) - val findings = MagicNumber(config).lint(ktFile) - assertThat(findings).isEmpty() - } - } + val findings = MagicNumber(config).lint(ktFile) + assertThat(findings).isEmpty() + } + } - given("magic numbers in companion object property assignments") { - val ktFile = compileContentForTest(""" + given("magic numbers in companion object property assignments") { + val ktFile = compileContentForTest(""" class A { companion object { @@ -424,102 +424,102 @@ class MagicNumberSpec : Spek({ } """.trimMargin()) - it("should not report any issues by default") { - val findings = MagicNumber().lint(ktFile) - assertThat(findings).isEmpty() - } + it("should not report any issues by default") { + val findings = MagicNumber().lint(ktFile) + assertThat(findings).isEmpty() + } - it("should not report any issues when ignoring properties but not constants nor companion objects") { - val config = TestConfig( - mapOf( - MagicNumber.IGNORE_PROPERTY_DECLARATION to "true", - MagicNumber.IGNORE_CONSTANT_DECLARATION to "false", - MagicNumber.IGNORE_COMPANION_OBJECT_PROPERTY_DECLARATION to "false" - ) - ) + it("should not report any issues when ignoring properties but not constants nor companion objects") { + val config = TestConfig( + mapOf( + MagicNumber.IGNORE_PROPERTY_DECLARATION to "true", + MagicNumber.IGNORE_CONSTANT_DECLARATION to "false", + MagicNumber.IGNORE_COMPANION_OBJECT_PROPERTY_DECLARATION to "false" + ) + ) - val findings = MagicNumber(config).lint(ktFile) - assertThat(findings).isEmpty() - } + val findings = MagicNumber(config).lint(ktFile) + assertThat(findings).isEmpty() + } - it("should not report any issues when ignoring properties and constants but not companion objects") { - val config = TestConfig( - mapOf( - MagicNumber.IGNORE_PROPERTY_DECLARATION to "true", - MagicNumber.IGNORE_CONSTANT_DECLARATION to "true", - MagicNumber.IGNORE_COMPANION_OBJECT_PROPERTY_DECLARATION to "false" - ) - ) + it("should not report any issues when ignoring properties and constants but not companion objects") { + val config = TestConfig( + mapOf( + MagicNumber.IGNORE_PROPERTY_DECLARATION to "true", + MagicNumber.IGNORE_CONSTANT_DECLARATION to "true", + MagicNumber.IGNORE_COMPANION_OBJECT_PROPERTY_DECLARATION to "false" + ) + ) - val findings = MagicNumber(config).lint(ktFile) - assertThat(findings).isEmpty() - } + val findings = MagicNumber(config).lint(ktFile) + assertThat(findings).isEmpty() + } - it("should not report any issues when ignoring properties, constants and companion objects") { - val config = TestConfig( - mapOf( - MagicNumber.IGNORE_PROPERTY_DECLARATION to "true", - MagicNumber.IGNORE_CONSTANT_DECLARATION to "true", - MagicNumber.IGNORE_COMPANION_OBJECT_PROPERTY_DECLARATION to "true" - ) - ) + it("should not report any issues when ignoring properties, constants and companion objects") { + val config = TestConfig( + mapOf( + MagicNumber.IGNORE_PROPERTY_DECLARATION to "true", + MagicNumber.IGNORE_CONSTANT_DECLARATION to "true", + MagicNumber.IGNORE_COMPANION_OBJECT_PROPERTY_DECLARATION to "true" + ) + ) - val findings = MagicNumber(config).lint(ktFile) - assertThat(findings).isEmpty() - } + val findings = MagicNumber(config).lint(ktFile) + assertThat(findings).isEmpty() + } - it("should not report any issues when ignoring companion objects but not properties and constants") { - val config = TestConfig( - mapOf( - MagicNumber.IGNORE_PROPERTY_DECLARATION to "false", - MagicNumber.IGNORE_CONSTANT_DECLARATION to "false", - MagicNumber.IGNORE_COMPANION_OBJECT_PROPERTY_DECLARATION to "true" - ) - ) + it("should not report any issues when ignoring companion objects but not properties and constants") { + val config = TestConfig( + mapOf( + MagicNumber.IGNORE_PROPERTY_DECLARATION to "false", + MagicNumber.IGNORE_CONSTANT_DECLARATION to "false", + MagicNumber.IGNORE_COMPANION_OBJECT_PROPERTY_DECLARATION to "true" + ) + ) - val findings = MagicNumber(config).lint(ktFile) - assertThat(findings).isEmpty() - } + val findings = MagicNumber(config).lint(ktFile) + assertThat(findings).isEmpty() + } - it("should report property when ignoring constants but not properties and companion objects") { - val config = TestConfig( - mapOf( - MagicNumber.IGNORE_PROPERTY_DECLARATION to "false", - MagicNumber.IGNORE_CONSTANT_DECLARATION to "true", - MagicNumber.IGNORE_COMPANION_OBJECT_PROPERTY_DECLARATION to "false" - ) - ) + it("should report property when ignoring constants but not properties and companion objects") { + val config = TestConfig( + mapOf( + MagicNumber.IGNORE_PROPERTY_DECLARATION to "false", + MagicNumber.IGNORE_CONSTANT_DECLARATION to "true", + MagicNumber.IGNORE_COMPANION_OBJECT_PROPERTY_DECLARATION to "false" + ) + ) - val findings = MagicNumber(config).lint(ktFile) - assertThat(findings).hasLocationStrings("'43' at (4,35) in /$fileName") - } + val findings = MagicNumber(config).lint(ktFile) + assertThat(findings).hasLocationStrings("'43' at (4,35) in /$fileName") + } - it("should report property and constant when not ignoring properties, constants nor companion objects") { - val config = TestConfig( - mapOf( - MagicNumber.IGNORE_PROPERTY_DECLARATION to "false", - MagicNumber.IGNORE_CONSTANT_DECLARATION to "false", - MagicNumber.IGNORE_COMPANION_OBJECT_PROPERTY_DECLARATION to "false" - ) - ) + it("should report property and constant when not ignoring properties, constants nor companion objects") { + val config = TestConfig( + mapOf( + MagicNumber.IGNORE_PROPERTY_DECLARATION to "false", + MagicNumber.IGNORE_CONSTANT_DECLARATION to "false", + MagicNumber.IGNORE_COMPANION_OBJECT_PROPERTY_DECLARATION to "false" + ) + ) - val findings = MagicNumber(config).lint(ktFile) - assertThat(findings).hasLocationStrings("'43' at (4,35) in /$fileName", "'93872' at (5,40) in /$fileName") - } - } + val findings = MagicNumber(config).lint(ktFile) + assertThat(findings).hasLocationStrings("'43' at (4,35) in /$fileName", "'93872' at (5,40) in /$fileName") + } + } - given("a property without number") { - val ktFile = compileContentForTest("private var pair: Pair? = null") + given("a property without number") { + val ktFile = compileContentForTest("private var pair: Pair? = null") - it("should not lead to a crash #276") { - val findings = MagicNumber().lint(ktFile) - assertThat(findings).isEmpty() - } - } + it("should not lead to a crash #276") { + val findings = MagicNumber().lint(ktFile) + assertThat(findings).isEmpty() + } + } - given("ignoring named arguments") { - given("in constructor invocation") { - fun code(numberString: String) = compileContentForTest(""" + given("ignoring named arguments") { + given("in constructor invocation") { + fun code(numberString: String) = compileContentForTest(""" data class Model( val someVal: Int, val other: String = "default" @@ -528,50 +528,50 @@ class MagicNumberSpec : Spek({ var model = Model(someVal = $numberString) """) - it("should not ignore int by default") { - assertThat(MagicNumber().lint(code("53"))).hasSize(1) - } + it("should not ignore int by default") { + assertThat(MagicNumber().lint(code("53"))).hasSize(1) + } - it("should not ignore float by default") { - assertThat(MagicNumber().lint(code("53f"))).hasSize(1) - } + it("should not ignore float by default") { + assertThat(MagicNumber().lint(code("53f"))).hasSize(1) + } - it("should not ignore binary by default") { - assertThat(MagicNumber().lint(code("0b01001"))).hasSize(1) - } + it("should not ignore binary by default") { + assertThat(MagicNumber().lint(code("0b01001"))).hasSize(1) + } - it("should ignore integer with underscores") { - assertThat(MagicNumber().lint(code("101_000"))).hasSize(1) - } + it("should ignore integer with underscores") { + assertThat(MagicNumber().lint(code("101_000"))).hasSize(1) + } - it("should ignore numbers when 'ignoreNamedArgument' is set to true") { - val rule = MagicNumber(TestConfig(mapOf("ignoreNamedArgument" to "true"))) - assertThat(rule.lint(code("53"))).isEmpty() - } + it("should ignore numbers when 'ignoreNamedArgument' is set to true") { + val rule = MagicNumber(TestConfig(mapOf("ignoreNamedArgument" to "true"))) + assertThat(rule.lint(code("53"))).isEmpty() + } - it("should ignore named arguments in inheritance - #992") { - val code = """ + it("should ignore named arguments in inheritance - #992") { + val code = """ abstract class A(n: Int) object B : A(n = 5) """.trimIndent() - val rule = MagicNumber(TestConfig(mapOf("ignoreNamedArgument" to "true"))) - assertThat(rule.lint(code)).isEmpty() - } + val rule = MagicNumber(TestConfig(mapOf("ignoreNamedArgument" to "true"))) + assertThat(rule.lint(code)).isEmpty() + } - it("should ignore named arguments in parameter annotations - #1115") { - val code = - "@JvmStatic fun setCustomDimension(@IntRange(from = 0, to = 19) index: Int, value: String?) {}" - MagicNumber(TestConfig(mapOf("ignoreNamedArgument" to "true"))) - .lint(code) - .assert() - .isEmpty() - } - } + it("should ignore named arguments in parameter annotations - #1115") { + val code = + "@JvmStatic fun setCustomDimension(@IntRange(from = 0, to = 19) index: Int, value: String?) {}" + MagicNumber(TestConfig(mapOf("ignoreNamedArgument" to "true"))) + .lint(code) + .assert() + .isEmpty() + } + } - given("Issue#659 - false-negative reporting on unnamed argument when ignore is true") { + given("Issue#659 - false-negative reporting on unnamed argument when ignore is true") { - fun code(numberString: String) = compileContentForTest(""" + fun code(numberString: String) = compileContentForTest(""" data class Model( val someVal: Int, val other: String = "default" @@ -580,112 +580,112 @@ class MagicNumberSpec : Spek({ var model = Model($numberString) """) - it("should detect the argument") { - val rule = MagicNumber(TestConfig(mapOf("ignoreNamedArgument" to "true"))) - assertThat(rule.lint(code("53"))).hasSize(1) - } - } + it("should detect the argument") { + val rule = MagicNumber(TestConfig(mapOf("ignoreNamedArgument" to "true"))) + assertThat(rule.lint(code("53"))).hasSize(1) + } + } - given("in function invocation") { - fun code(number: Number) = compileContentForTest(""" + given("in function invocation") { + fun code(number: Number) = compileContentForTest(""" fun tested(someVal: Int, other: String = "default") tested(someVal = $number) """) - it("should ignore int by default") { - assertThat(MagicNumber().lint(code(53))).isEmpty() - } + it("should ignore int by default") { + assertThat(MagicNumber().lint(code(53))).isEmpty() + } - it("should ignore float by default") { - assertThat(MagicNumber().lint(code(53f))).isEmpty() - } + it("should ignore float by default") { + assertThat(MagicNumber().lint(code(53f))).isEmpty() + } - it("should ignore binary by default") { - assertThat(MagicNumber().lint(code(0b01001))).isEmpty() - } + it("should ignore binary by default") { + assertThat(MagicNumber().lint(code(0b01001))).isEmpty() + } - it("should ignore integer with underscores") { - assertThat(MagicNumber().lint(code(101_000))).isEmpty() - } - } - given("in enum constructor argument") { - val ktFile = compileContentForTest(""" + it("should ignore integer with underscores") { + assertThat(MagicNumber().lint(code(101_000))).isEmpty() + } + } + given("in enum constructor argument") { + val ktFile = compileContentForTest(""" enum class Bag(id: Int) { SMALL(1), EXTRA_LARGE(5) } """) - it("should be reported by default") { - assertThat(MagicNumber().lint(ktFile)).hasSize(1) - } - it("numbers when 'ignoreEnums' is set to true") { - val rule = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_ENUMS to "true"))) - assertThat(rule.lint(ktFile)).isEmpty() - } - } - given("in enum constructor as named argument") { - val ktFile = compileContentForTest(""" + it("should be reported by default") { + assertThat(MagicNumber().lint(ktFile)).hasSize(1) + } + it("numbers when 'ignoreEnums' is set to true") { + val rule = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_ENUMS to "true"))) + assertThat(rule.lint(ktFile)).isEmpty() + } + } + given("in enum constructor as named argument") { + val ktFile = compileContentForTest(""" enum class Bag(id: Int) { SMALL(id = 1), EXTRA_LARGE(id = 5) } """) - it("should be reported by default") { - assertThat(MagicNumber().lint(ktFile)).hasSize(1) - } - it("numbers when 'ignoreEnums' is set to true") { - val rule = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_ENUMS to "true"))) - assertThat(rule.lint(ktFile)).isEmpty() - } - } - } + it("should be reported by default") { + assertThat(MagicNumber().lint(ktFile)).hasSize(1) + } + it("numbers when 'ignoreEnums' is set to true") { + val rule = MagicNumber(TestConfig(mapOf(MagicNumber.IGNORE_ENUMS to "true"))) + assertThat(rule.lint(ktFile)).isEmpty() + } + } + } - given("functions with and without braces which return values") { + given("functions with and without braces which return values") { - it("does not report functions that always returns a constant value") { - val code = """ + it("does not report functions that always returns a constant value") { + val code = """ fun x() = 9 fun y() { return 9 }""" - assertThat(MagicNumber().lint(code)).isEmpty() - } + assertThat(MagicNumber().lint(code)).isEmpty() + } - it("reports functions that does not return a constant value") { - val code = """ + it("reports functions that does not return a constant value") { + val code = """ fun x() = 9 + 1 fun y(): Int { return 9 + 1 }""" - assertThat(MagicNumber().lint(code)).hasSize(2) - } - } + assertThat(MagicNumber().lint(code)).hasSize(2) + } + } - given("in-class declaration with default parameters") { + given("in-class declaration with default parameters") { - it("reports no finding") { - val code = compileContentForTest("class SomeClassWithDefault(val defaultValue: Int = 10)") - assertThat(MagicNumber().lint(code)).isEmpty() - } + it("reports no finding") { + val code = compileContentForTest("class SomeClassWithDefault(val defaultValue: Int = 10)") + assertThat(MagicNumber().lint(code)).isEmpty() + } - it("reports no finding for an explicit declaration") { - val code = compileContentForTest("class SomeClassWithDefault constructor(val defaultValue: Int = 10)") - assertThat(MagicNumber().lint(code)).isEmpty() - } - } + it("reports no finding for an explicit declaration") { + val code = compileContentForTest("class SomeClassWithDefault constructor(val defaultValue: Int = 10)") + assertThat(MagicNumber().lint(code)).isEmpty() + } + } - given("default parameters in secondary constructor") { + given("default parameters in secondary constructor") { - it("reports no finding") { - val code = compileContentForTest(""" + it("reports no finding") { + val code = compileContentForTest(""" class SomeClassWithDefault { constructor(val defaultValue: Int = 10) { } }""") - assertThat(MagicNumber().lint(code)).isEmpty() - } - } + assertThat(MagicNumber().lint(code)).isEmpty() + } + } - given("default parameters in function") { + given("default parameters in function") { - it("reports no finding") { - val code = compileContentForTest("fun f(p: Int = 100)") - assertThat(MagicNumber().lint(code)).isEmpty() - } - } + it("reports no finding") { + val code = compileContentForTest("fun f(p: Int = 100)") + assertThat(MagicNumber().lint(code)).isEmpty() + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MaxLineLengthSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MaxLineLengthSpec.kt index db75b7694..869b73139 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MaxLineLengthSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MaxLineLengthSpec.kt @@ -11,41 +11,41 @@ import org.jetbrains.spek.api.dsl.it class MaxLineLengthSpec : Spek({ - given("a kt file with some long lines") { - val file = compileForTest(Case.MaxLineLength.path()) - val lines = file.text.splitToSequence("\n") - val fileContent = KtFileContent(file, lines) + given("a kt file with some long lines") { + val file = compileForTest(Case.MaxLineLength.path()) + val lines = file.text.splitToSequence("\n") + val fileContent = KtFileContent(file, lines) - it("should report no errors when maxLineLength is set to 200") { - val rule = MaxLineLength(TestConfig(mapOf("maxLineLength" to "200"))) + it("should report no errors when maxLineLength is set to 200") { + val rule = MaxLineLength(TestConfig(mapOf("maxLineLength" to "200"))) - rule.visit(fileContent) - assertThat(rule.findings).isEmpty() - } + rule.visit(fileContent) + assertThat(rule.findings).isEmpty() + } - it("should report all errors with default maxLineLength") { - val rule = MaxLineLength() + it("should report all errors with default maxLineLength") { + val rule = MaxLineLength() - rule.visit(fileContent) - assertThat(rule.findings).hasSize(3) - } - } + rule.visit(fileContent) + assertThat(rule.findings).hasSize(3) + } + } - given("a kt file with long but suppressed lines") { - val file = compileForTest(Case.MaxLineLengthSuppressed.path()) - val lines = file.text.splitToSequence("\n") - val fileContent = KtFileContent(file, lines) + given("a kt file with long but suppressed lines") { + val file = compileForTest(Case.MaxLineLengthSuppressed.path()) + val lines = file.text.splitToSequence("\n") + val fileContent = KtFileContent(file, lines) - it("should not report as lines are suppressed") { - val rule = MaxLineLength() + it("should not report as lines are suppressed") { + val rule = MaxLineLength() - rule.visit(fileContent) - assertThat(rule.findings).isEmpty() - } - } + rule.visit(fileContent) + assertThat(rule.findings).isEmpty() + } + } - given("a kt file with a long package name and long import statements") { - val code = """ + given("a kt file with a long package name and long import statements") { + val code = """ package anIncrediblyLongAndComplexPackageNameThatProbablyShouldBeMuchShorterButForTheSakeOfTheTestItsNot import anIncrediblyLongAndComplexImportNameThatProbablyShouldBeMuchShorterButForTheSakeOfTheTestItsNot @@ -54,81 +54,81 @@ class MaxLineLengthSpec : Spek({ } """ - val file = compileContentForTest(code) - val lines = file.text.splitToSequence("\n") - val fileContent = KtFileContent(file, lines) + val file = compileContentForTest(code) + val lines = file.text.splitToSequence("\n") + val fileContent = KtFileContent(file, lines) - it("should not report the package statement and import statements by default") { - val rule = MaxLineLength(TestConfig(mapOf( - "maxLineLength" to "60" - ))) + it("should not report the package statement and import statements by default") { + val rule = MaxLineLength(TestConfig(mapOf( + "maxLineLength" to "60" + ))) - rule.visit(fileContent) - assertThat(rule.findings).isEmpty() - } + rule.visit(fileContent) + assertThat(rule.findings).isEmpty() + } - it("should report the package statement and import statements if they're enabled") { - val rule = MaxLineLength(TestConfig(mapOf( - "maxLineLength" to "60", - "excludePackageStatements" to "false", - "excludeImportStatements" to "false" - ))) + it("should report the package statement and import statements if they're enabled") { + val rule = MaxLineLength(TestConfig(mapOf( + "maxLineLength" to "60", + "excludePackageStatements" to "false", + "excludeImportStatements" to "false" + ))) - rule.visit(fileContent) - assertThat(rule.findings).hasSize(2) - } + rule.visit(fileContent) + assertThat(rule.findings).hasSize(2) + } - it("should not report anything if both package and import statements are disabled") { - val rule = MaxLineLength(TestConfig(mapOf( - "maxLineLength" to "60", - "excludePackageStatements" to "true", - "excludeImportStatements" to "true" - ))) + it("should not report anything if both package and import statements are disabled") { + val rule = MaxLineLength(TestConfig(mapOf( + "maxLineLength" to "60", + "excludePackageStatements" to "true", + "excludeImportStatements" to "true" + ))) - rule.visit(fileContent) - assertThat(rule.findings).isEmpty() - } - } + rule.visit(fileContent) + assertThat(rule.findings).isEmpty() + } + } - given("a kt file with a long package name, long import statements, a long line and long comments") { - val file = compileForTest(Case.MaxLineLengthWithLongComments.path()) - val lines = file.text.splitToSequence("\n") - val fileContent = KtFileContent(file, lines) + given("a kt file with a long package name, long import statements, a long line and long comments") { + val file = compileForTest(Case.MaxLineLengthWithLongComments.path()) + val lines = file.text.splitToSequence("\n") + val fileContent = KtFileContent(file, lines) - it("should report the package statement, import statements, line and comments by default") { - val rule = MaxLineLength(TestConfig(mapOf( - "maxLineLength" to "60" - ))) + it("should report the package statement, import statements, line and comments by default") { + val rule = MaxLineLength(TestConfig(mapOf( + "maxLineLength" to "60" + ))) - rule.visit(fileContent) - assertThat(rule.findings).hasSize(8) - } + rule.visit(fileContent) + assertThat(rule.findings).hasSize(8) + } - it("should report the package statement, import statements, line and comments if they're enabled") { - val rule = MaxLineLength(TestConfig(mapOf( - "maxLineLength" to "60", - "excludePackageStatements" to "false", - "excludeImportStatements" to "false", - "excludeCommentStatements" to "false" - ))) + it("should report the package statement, import statements, line and comments if they're enabled") { + val rule = MaxLineLength(TestConfig(mapOf( + "maxLineLength" to "60", + "excludePackageStatements" to "false", + "excludeImportStatements" to "false", + "excludeCommentStatements" to "false" + ))) - rule.visit(fileContent) - assertThat(rule.findings).hasSize(8) - } + rule.visit(fileContent) + assertThat(rule.findings).hasSize(8) + } - it("should not report comments if they're disabled") { - val rule = MaxLineLength(TestConfig(mapOf( - "maxLineLength" to "60", - "excludeCommentStatements" to "true" - ))) + it("should not report comments if they're disabled") { + val rule = MaxLineLength(TestConfig(mapOf( + "maxLineLength" to "60", + "excludeCommentStatements" to "true" + ))) - rule.visit(fileContent) - assertThat(rule.findings).hasSize(5) - } - } + rule.visit(fileContent) + assertThat(rule.findings).hasSize(5) + } + } - given("a kt file with a long package name, long import statements and a long line") { - val code = """ + given("a kt file with a long package name, long import statements and a long line") { + val code = """ package anIncrediblyLongAndComplexPackageNameThatProbablyShouldBeMuchShorterButForTheSakeOfTheTestItsNot import anIncrediblyLongAndComplexImportNameThatProbablyShouldBeMuchShorterButForTheSakeOfTheTestItsNot @@ -138,53 +138,53 @@ class MaxLineLengthSpec : Spek({ } """.trim() - val file = compileContentForTest(code) - val lines = file.text.splitToSequence("\n") - val fileContent = KtFileContent(file, lines) + val file = compileContentForTest(code) + val lines = file.text.splitToSequence("\n") + val fileContent = KtFileContent(file, lines) - it("should only the function line by default") { - val rule = MaxLineLength(TestConfig(mapOf( - "maxLineLength" to "60" - ))) + it("should only the function line by default") { + val rule = MaxLineLength(TestConfig(mapOf( + "maxLineLength" to "60" + ))) - rule.visit(fileContent) - assertThat(rule.findings).hasSize(1) - } + rule.visit(fileContent) + assertThat(rule.findings).hasSize(1) + } - it("should report the package statement, import statements and line if they're not excluded") { - val rule = MaxLineLength(TestConfig(mapOf( - "maxLineLength" to "60", - "excludePackageStatements" to "false", - "excludeImportStatements" to "false" - ))) + it("should report the package statement, import statements and line if they're not excluded") { + val rule = MaxLineLength(TestConfig(mapOf( + "maxLineLength" to "60", + "excludePackageStatements" to "false", + "excludeImportStatements" to "false" + ))) - rule.visit(fileContent) - assertThat(rule.findings).hasSize(3) - } + rule.visit(fileContent) + assertThat(rule.findings).hasSize(3) + } - it("should report only method if both package and import statements are disabled") { - val rule = MaxLineLength(TestConfig(mapOf( - "maxLineLength" to "60", - "excludePackageStatements" to "true", - "excludeImportStatements" to "true" - ))) + it("should report only method if both package and import statements are disabled") { + val rule = MaxLineLength(TestConfig(mapOf( + "maxLineLength" to "60", + "excludePackageStatements" to "true", + "excludeImportStatements" to "true" + ))) - rule.visit(fileContent) - assertThat(rule.findings).hasSize(1) - } + rule.visit(fileContent) + assertThat(rule.findings).hasSize(1) + } - it("should report correct line and column for function with excessive length") { - val rule = MaxLineLength(TestConfig(mapOf( - "maxLineLength" to "60", - "excludePackageStatements" to "true", - "excludeImportStatements" to "true" - ))) + it("should report correct line and column for function with excessive length") { + val rule = MaxLineLength(TestConfig(mapOf( + "maxLineLength" to "60", + "excludePackageStatements" to "true", + "excludeImportStatements" to "true" + ))) - rule.visit(fileContent) - assertThat(rule.findings).hasSize(1) - val findingSource = rule.findings[0].location.source - assertThat(findingSource.line).isEqualTo(6) - assertThat(findingSource.column).isEqualTo(5) - } - } + rule.visit(fileContent) + assertThat(rule.findings).hasSize(1) + val findingSource = rule.findings[0].location.source + assertThat(findingSource.line).isEqualTo(6) + assertThat(findingSource.column).isEqualTo(5) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MayBeConstSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MayBeConstSpec.kt index 9c73978bf..61c970849 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MayBeConstSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MayBeConstSpec.kt @@ -9,39 +9,39 @@ import org.jetbrains.spek.subject.SubjectSpek class MayBeConstSpec : SubjectSpek({ - subject { MayBeConst() } + subject { MayBeConst() } - given("some valid constants") { - it("is a valid constant") { - val code = """const val X = 42""" - subject.lint(code) - assertThat(subject.findings).isEmpty() - } + given("some valid constants") { + it("is a valid constant") { + val code = """const val X = 42""" + subject.lint(code) + assertThat(subject.findings).isEmpty() + } - it("is const vals in object") { - val code = """ + it("is const vals in object") { + val code = """ object Test { const val TEST = "Test" } """ - subject.lint(code) - assertThat(subject.findings).isEmpty() - } + subject.lint(code) + assertThat(subject.findings).isEmpty() + } - it("isconst vals in companion objects") { - val code = """ + it("isconst vals in companion objects") { + val code = """ class Test { companion object { const val B = 1 } } """ - subject.lint(code) - assertThat(subject.findings).isEmpty() - } + subject.lint(code) + assertThat(subject.findings).isEmpty() + } - it("does not report const vals that use other const vals") { - val code = """ + it("does not report const vals that use other const vals") { + val code = """ const val a = 0 class Test { @@ -51,73 +51,73 @@ class MayBeConstSpec : SubjectSpek({ } } """ - subject.lint(code) - assertThat(subject.findings).isEmpty() - } + subject.lint(code) + assertThat(subject.findings).isEmpty() + } - it("does not report none const val candidates") { - val code = """ + it("does not report none const val candidates") { + val code = """ const val a = 0 val p = Pair(a, a + a) val p2 = emptyList().plus(a) """ - subject.lint(code) - assertThat(subject.findings).isEmpty() - } - } + subject.lint(code) + assertThat(subject.findings).isEmpty() + } + } - given("some vals that could be constants") { - it("is a simple val") { - val code = """ + given("some vals that could be constants") { + it("is a simple val") { + val code = """ val x = 1 """ - subject.lint(code) - assertThat(subject.findings).hasSize(1) - } + subject.lint(code) + assertThat(subject.findings).hasSize(1) + } - it("is a simple JvmField val") { - val code = """ + it("is a simple JvmField val") { + val code = """ @JvmField val x = 1 """ - subject.lint(code) - assertThat(subject.findings).hasSize(1) - } + subject.lint(code) + assertThat(subject.findings).hasSize(1) + } - it("is a field in an object") { - val code = """ + it("is a field in an object") { + val code = """ object Test { @JvmField val test = "Test" } """ - subject.lint(code) - assertThat(subject.findings).hasSize(1) - } + subject.lint(code) + assertThat(subject.findings).hasSize(1) + } - it("reports vals in companion objects") { - val code = """ + it("reports vals in companion objects") { + val code = """ class Test { companion object { val b = 1 } } """ - subject.lint(code) - assertThat(subject.findings).hasSize(1) - } - } + subject.lint(code) + assertThat(subject.findings).hasSize(1) + } + } - given("vals that can be constants but detekt doesn't handle yet") { - it("is a constant binary expression") { - val code = """ + given("vals that can be constants but detekt doesn't handle yet") { + it("is a constant binary expression") { + val code = """ const val one = 1 val two = one * 2 """ - subject.lint(code) - assertThat(subject.findings).hasSize(1) - } + subject.lint(code) + assertThat(subject.findings).hasSize(1) + } - it("is a constant binary expression in a companion object") { - val code = """ + it("is a constant binary expression in a companion object") { + val code = """ class Test { companion object { const val one = 1 @@ -125,30 +125,30 @@ class MayBeConstSpec : SubjectSpek({ } } """ - subject.lint(code) - assertThat(subject.findings).hasSize(1) - } + subject.lint(code) + assertThat(subject.findings).hasSize(1) + } - it("is a nested constant binary expression") { - val code = """ + it("is a nested constant binary expression") { + val code = """ const val one = 1 val two = one * 2 + 1 """ - subject.lint(code) - assertThat(subject.findings).hasSize(1) - } + subject.lint(code) + assertThat(subject.findings).hasSize(1) + } - it("is a nested constant parenthesised expression") { - val code = """ + it("is a nested constant parenthesised expression") { + val code = """ const val one = 1 val two = one * (2 + 1) """ - subject.lint(code) - assertThat(subject.findings).hasSize(1) - } + subject.lint(code) + assertThat(subject.findings).hasSize(1) + } - it("reports vals that use other const vals") { - val code = """ + it("reports vals that use other const vals") { + val code = """ const val a = 0 class Test { @@ -158,67 +158,67 @@ class MayBeConstSpec : SubjectSpek({ } } """ - subject.lint(code) - assertThat(subject.findings).hasSize(1) - } + subject.lint(code) + assertThat(subject.findings).hasSize(1) + } - it("reports concatenated string vals") { - val code = """ + it("reports concatenated string vals") { + val code = """ private const val A = "a" private val B = A + "b" """ - subject.lint(code) - assertThat(subject.findings).hasSize(1) - } - } + subject.lint(code) + assertThat(subject.findings).hasSize(1) + } + } - given("vals that cannot be constants") { - it("does not report arrays") { - val code = "val arr = arrayOf(\"a\", \"b\")" - subject.lint(code) - assertThat(subject.findings).isEmpty() - } + given("vals that cannot be constants") { + it("does not report arrays") { + val code = "val arr = arrayOf(\"a\", \"b\")" + subject.lint(code) + assertThat(subject.findings).isEmpty() + } - it("is a var") { - val code = "var test = 1" - subject.lint(code) - assertThat(subject.findings).isEmpty() - } + it("is a var") { + val code = "var test = 1" + subject.lint(code) + assertThat(subject.findings).isEmpty() + } - it("has a getter") { - val code = "val withGetter get() = 42" - subject.lint(code) - assertThat(subject.findings).isEmpty() - } + it("has a getter") { + val code = "val withGetter get() = 42" + subject.lint(code) + assertThat(subject.findings).isEmpty() + } - it("is initialized to null") { - val code = "val test = null" - subject.lint(code) - assertThat(subject.findings).isEmpty() - } + it("is initialized to null") { + val code = "val test = null" + subject.lint(code) + assertThat(subject.findings).isEmpty() + } - it("is a JvmField in a class") { - val code = """ + it("is a JvmField in a class") { + val code = """ class Test { @JvmField val a = 3 } """.trimMargin() - subject.lint(code) - assertThat(subject.findings).isEmpty() - } + subject.lint(code) + assertThat(subject.findings).isEmpty() + } - it("has some annotation") { - val code = """ + it("has some annotation") { + val code = """ annotation class A @A val a = 55 """.trimMargin() - subject.lint(code) - assertThat(subject.findings).isEmpty() - } + subject.lint(code) + assertThat(subject.findings).isEmpty() + } - it("overrides something") { - val code = """ + it("overrides something") { + val code = """ interface Base { val property: Int } @@ -227,28 +227,28 @@ class MayBeConstSpec : SubjectSpek({ override val property = 1 } """.trimMargin() - subject.lint(code) - assertThat(subject.findings).isEmpty() - } + subject.lint(code) + assertThat(subject.findings).isEmpty() + } - it("does not detect just a dollar as interpolation") { - val code = """ val hasDollar = "$" """ - subject.lint(code) - assertThat(subject.findings).hasSize(1) - } + it("does not detect just a dollar as interpolation") { + val code = """ val hasDollar = "$" """ + subject.lint(code) + assertThat(subject.findings).hasSize(1) + } - it("does not report interpolated strings") { - subject.lint(Case.MayBeConstNegative.path()) - assertThat(subject.findings).isEmpty() - } - } + it("does not report interpolated strings") { + subject.lint(Case.MayBeConstNegative.path()) + assertThat(subject.findings).isEmpty() + } + } - given("some const val candidates in nested objects") { + given("some const val candidates in nested objects") { - it("reports the const val candidates") { - val path = Case.ConstInObjects.path() - subject.lint(path) - assertThat(subject.findings).hasSize(3) - } - } + it("reports the const val candidates") { + val path = Case.ConstInObjects.path() + subject.lint(path) + assertThat(subject.findings).hasSize(3) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ModifierOrderSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ModifierOrderSpec.kt index 867b66efa..62b94ad2b 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ModifierOrderSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ModifierOrderSpec.kt @@ -9,88 +9,88 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class ModifierOrderSpec : SubjectSpek({ - subject { ModifierOrder(Config.empty) } + subject { ModifierOrder(Config.empty) } - given("kt classes with modifiers") { - val bad1 = "data internal class Test(val test: String)" - val bad2 = "actual private class Test(val test: String)" - val bad3 = "annotation expect class Test" + given("kt classes with modifiers") { + val bad1 = "data internal class Test(val test: String)" + val bad2 = "actual private class Test(val test: String)" + val bad3 = "annotation expect class Test" - it("should report incorrectly ordered modifiers") { - assertThat(subject.lint(bad1)).hasSize(1) - assertThat(subject.lint(bad2)).hasSize(1) - assertThat(subject.lint(bad3)).hasSize(1) - } + it("should report incorrectly ordered modifiers") { + assertThat(subject.lint(bad1)).hasSize(1) + assertThat(subject.lint(bad2)).hasSize(1) + assertThat(subject.lint(bad3)).hasSize(1) + } - it("does not report correctly ordered modifiers") { - assertThat(subject.lint("internal data class Test")).isEmpty() - assertThat(subject.lint("private actual class Test(val test: String)")).isEmpty() - assertThat(subject.lint("expect annotation class Test")).isEmpty() - } + it("does not report correctly ordered modifiers") { + assertThat(subject.lint("internal data class Test")).isEmpty() + assertThat(subject.lint("private actual class Test(val test: String)")).isEmpty() + assertThat(subject.lint("expect annotation class Test")).isEmpty() + } - it("should not report issues if inactive") { - val rule = ModifierOrder(TestConfig(mapOf("active" to "false"))) - assertThat(rule.lint(bad1)).isEmpty() - assertThat(rule.lint(bad2)).isEmpty() - assertThat(rule.lint(bad3)).isEmpty() - } - } + it("should not report issues if inactive") { + val rule = ModifierOrder(TestConfig(mapOf("active" to "false"))) + assertThat(rule.lint(bad1)).isEmpty() + assertThat(rule.lint(bad2)).isEmpty() + assertThat(rule.lint(bad3)).isEmpty() + } + } - given("a kt parameter with modifiers") { + given("a kt parameter with modifiers") { - it("should report wrongly ordered modifiers") { - val code = "lateinit internal private val test: String" - assertThat(subject.lint(code)).hasSize(1) - } + it("should report wrongly ordered modifiers") { + val code = "lateinit internal private val test: String" + assertThat(subject.lint(code)).hasSize(1) + } - it("should not report correctly ordered modifiers") { - val code = "private internal lateinit val test: String" - assertThat(subject.lint(code)).isEmpty() - } - } + it("should not report correctly ordered modifiers") { + val code = "private internal lateinit val test: String" + assertThat(subject.lint(code)).isEmpty() + } + } - given("an overridden function") { + given("an overridden function") { - it("should report incorrectly ordered modifiers") { - val code = """ + it("should report incorrectly ordered modifiers") { + val code = """ abstract class Test { override open fun test() {} }""" - assertThat(subject.lint(code)).hasSize(1) - } + assertThat(subject.lint(code)).hasSize(1) + } - it("should not report correctly ordered modifiers") { - val code = """ + it("should not report correctly ordered modifiers") { + val code = """ abstract class Test { override fun test() {} }""" - assertThat(subject.lint(code)).isEmpty() - } - } + assertThat(subject.lint(code)).isEmpty() + } + } - given("a tailrec function") { + given("a tailrec function") { - it("should report incorrectly ordered modifiers") { - val code = "tailrec private fun findFixPoint(x: Double = 1.0): Double" - assertThat(subject.lint(code)).hasSize(1) - } + it("should report incorrectly ordered modifiers") { + val code = "tailrec private fun findFixPoint(x: Double = 1.0): Double" + assertThat(subject.lint(code)).hasSize(1) + } - it("should not report correctly ordered modifiers") { - val code = "private tailrec fun findFixPoint(x: Double = 1.0): Double" - assertThat(subject.lint(code)).isEmpty() - } - } + it("should not report correctly ordered modifiers") { + val code = "private tailrec fun findFixPoint(x: Double = 1.0): Double" + assertThat(subject.lint(code)).isEmpty() + } + } - given("a vararg argument") { + given("a vararg argument") { - it("should report incorrectly ordered modifiers") { - val code = "fun foo(vararg private val strings: String) {}" - assertThat(subject.lint(code)).hasSize(1) - } + it("should report incorrectly ordered modifiers") { + val code = "fun foo(vararg private val strings: String) {}" + assertThat(subject.lint(code)).hasSize(1) + } - it("should not report correctly ordered modifiers") { - val code = "fun foo(private vararg val strings: String) {}" - assertThat(subject.lint(code)).isEmpty() - } - } + it("should not report correctly ordered modifiers") { + val code = "fun foo(private vararg val strings: String) {}" + assertThat(subject.lint(code)).isEmpty() + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/NestedClassesVisibilitySpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/NestedClassesVisibilitySpec.kt index 4ac2438cb..5f786efe7 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/NestedClassesVisibilitySpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/NestedClassesVisibilitySpec.kt @@ -8,16 +8,16 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class NestedClassesVisibilitySpec : SubjectSpek({ - subject { NestedClassesVisibility() } + subject { NestedClassesVisibility() } - given("several nested classes") { + given("several nested classes") { - it("reports public nested classes") { - assertThat(subject.lint(Case.NestedClassVisibilityPositive.path())).hasSize(6) - } + it("reports public nested classes") { + assertThat(subject.lint(Case.NestedClassVisibilityPositive.path())).hasSize(6) + } - it("does not report internal and (package) private nested classes") { - assertThat(subject.lint(Case.NestedClassVisibilityNegative.path())).isEmpty() - } - } + it("does not report internal and (package) private nested classes") { + assertThat(subject.lint(Case.NestedClassVisibilityNegative.path())).isEmpty() + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/NewLineAtEndOfFileSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/NewLineAtEndOfFileSpec.kt index 1a3f4748d..73c4bc7f8 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/NewLineAtEndOfFileSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/NewLineAtEndOfFileSpec.kt @@ -8,23 +8,23 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class NewLineAtEndOfFileSpec : SubjectSpek({ - subject { NewLineAtEndOfFile() } + subject { NewLineAtEndOfFile() } - given("a kt file containing new space at end") { - it("should not flag it") { - assertThat(subject.lint(Case.NewLineAtEndOfFile.path())).hasSize(0) - } - } + given("a kt file containing new space at end") { + it("should not flag it") { + assertThat(subject.lint(Case.NewLineAtEndOfFile.path())).hasSize(0) + } + } - given("a kt file not containing new space at end") { - it("should flag it") { - assertThat(subject.lint("class Test")).hasSize(1) - } - } + given("a kt file not containing new space at end") { + it("should flag it") { + assertThat(subject.lint("class Test")).hasSize(1) + } + } - given("an empty kt file") { - it("should not flag it") { - assertThat(subject.lint(Case.EmptyKtFile.path())).hasSize(0) - } - } + given("an empty kt file") { + it("should not flag it") { + assertThat(subject.lint(Case.EmptyKtFile.path())).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/NoTabsSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/NoTabsSpec.kt index 5215f0a3c..e73eb3894 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/NoTabsSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/NoTabsSpec.kt @@ -4,35 +4,35 @@ import io.gitlab.arturbosch.detekt.api.Finding import io.gitlab.arturbosch.detekt.rules.Case import io.gitlab.arturbosch.detekt.test.assertThat import io.gitlab.arturbosch.detekt.test.compileForTest +import java.nio.file.Path import org.jetbrains.spek.api.dsl.given import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek import org.jetbrains.spek.subject.dsl.SubjectProviderDsl -import java.nio.file.Path class NoTabsSpec : SubjectSpek({ - subject { NoTabs() } + subject { NoTabs() } - given("a line that contains a tab") { + given("a line that contains a tab") { - it("should flag it") { - val path = Case.NoTabsPositive.path() - assertThat(lint(path)).hasSize(5) - } - } + it("should flag it") { + val path = Case.NoTabsPositive.path() + assertThat(lint(path)).hasSize(5) + } + } - given("a line that does not contain a tab") { + given("a line that does not contain a tab") { - it("should not flag it") { - val path = Case.NoTabsNegative.path() - assertThat(lint(path)).hasSize(0) - } - } + it("should not flag it") { + val path = Case.NoTabsNegative.path() + assertThat(lint(path)).hasSize(0) + } + } }) private fun SubjectProviderDsl.lint(path: Path): List { - val file = compileForTest(path) - subject.findTabs(file) - return subject.findings + val file = compileForTest(path) + subject.findTabs(file) + return subject.findings } diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/OptionalAbstractKeywordSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/OptionalAbstractKeywordSpec.kt index 8f358f6b5..121fa7595 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/OptionalAbstractKeywordSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/OptionalAbstractKeywordSpec.kt @@ -7,48 +7,48 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class OptionalAbstractKeywordSpec : SubjectSpek({ - subject { OptionalAbstractKeyword() } + subject { OptionalAbstractKeyword() } - describe("some abstract keyword definitions are checked for optionality") { + describe("some abstract keyword definitions are checked for optionality") { - it("does not report abstract keywords on an interface") { - val code = "interface A {}" - assertThat(subject.lint(code)).hasSize(0) - } + it("does not report abstract keywords on an interface") { + val code = "interface A {}" + assertThat(subject.lint(code)).hasSize(0) + } - it("reports abstract interface with abstract property") { - val code = "abstract interface A { abstract var x: Int }" - assertThat(subject.lint(code)).hasSize(2) - } + it("reports abstract interface with abstract property") { + val code = "abstract interface A { abstract var x: Int }" + assertThat(subject.lint(code)).hasSize(2) + } - it("reports abstract interface with abstract function") { - val code = "abstract interface A { abstract fun x() }" - assertThat(subject.lint(code)).hasSize(2) - } + it("reports abstract interface with abstract function") { + val code = "abstract interface A { abstract fun x() }" + assertThat(subject.lint(code)).hasSize(2) + } - it("reports nested abstract interface") { - val code = """ + it("reports nested abstract interface") { + val code = """ class A { abstract interface B { abstract fun x() } }""" - assertThat(subject.lint(code)).hasSize(2) - } + assertThat(subject.lint(code)).hasSize(2) + } - it("does not report an abstract class") { - val code = "abstract class A { abstract fun x() }" - assertThat(subject.lint(code)).hasSize(0) - } + it("does not report an abstract class") { + val code = "abstract class A { abstract fun x() }" + assertThat(subject.lint(code)).hasSize(0) + } - it("does not report a nested abstract class function") { - val code = """@Subcomponent + it("does not report a nested abstract class function") { + val code = """@Subcomponent interface I { abstract class A { abstract fun dependency } }""" - assertThat(subject.lint(code)).hasSize(0) - } - } + assertThat(subject.lint(code)).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/OptionalWhenBracesSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/OptionalWhenBracesSpec.kt index cc098d230..5d8196255 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/OptionalWhenBracesSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/OptionalWhenBracesSpec.kt @@ -7,12 +7,12 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class OptionalWhenBracesSpec : SubjectSpek({ - subject { OptionalWhenBraces() } + subject { OptionalWhenBraces() } - describe("check optional braces in when expression") { + describe("check optional braces in when expression") { - it("has necessary braces") { - val code = """ + it("has necessary braces") { + val code = """ fun x() { when (1) { 1 -> foo @@ -26,18 +26,18 @@ class OptionalWhenBracesSpec : SubjectSpek({ } } }""" - assertThat(subject.lint(code)).hasSize(0) - } + assertThat(subject.lint(code)).hasSize(0) + } - it("has unnecessary braces") { - val code = """ + it("has unnecessary braces") { + val code = """ fun x() { when (1) { 1 -> { foo() } else -> bar() } }""" - assertThat(subject.lint(code)).hasSize(1) - } - } + assertThat(subject.lint(code)).hasSize(1) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ProtectedMemberInFinalClassSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ProtectedMemberInFinalClassSpec.kt index b215fd567..967604bf6 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ProtectedMemberInFinalClassSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ProtectedMemberInFinalClassSpec.kt @@ -9,18 +9,18 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class ProtectedMemberInFinalClassSpec : SubjectSpek({ - subject { ProtectedMemberInFinalClass(Config.empty) } + subject { ProtectedMemberInFinalClass(Config.empty) } - describe("check all variants of protected visibility modifier in final class") { + describe("check all variants of protected visibility modifier in final class") { - it("reports protected visibility") { - val path = Case.FinalClassPositive.path() - assertThat(subject.lint(path)).hasSize(13) - } + it("reports protected visibility") { + val path = Case.FinalClassPositive.path() + assertThat(subject.lint(path)).hasSize(13) + } - it("does not report protected visibility") { - val path = Case.FinalClassNegative.path() - assertThat(subject.lint(path)).hasSize(0) - } - } + it("does not report protected visibility") { + val path = Case.FinalClassNegative.path() + assertThat(subject.lint(path)).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/RedundantVisibilityModifierRuleSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/RedundantVisibilityModifierRuleSpec.kt index eec800748..58e00a750 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/RedundantVisibilityModifierRuleSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/RedundantVisibilityModifierRuleSpec.kt @@ -1,16 +1,16 @@ package io.gitlab.arturbosch.detekt.rules.style +import io.gitlab.arturbosch.detekt.test.assertThat import io.gitlab.arturbosch.detekt.test.lint -import org.assertj.core.api.Assertions.* import org.jetbrains.spek.api.dsl.describe import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class RedundantVisibilityModifierRuleSpec : SubjectSpek({ - subject { RedundantVisibilityModifierRule() } - describe("check all cases") { - it("check overridden function of abstract class w/ public modifier") { - val code = """ + subject { RedundantVisibilityModifierRule() } + describe("check all cases") { + it("check overridden function of abstract class w/ public modifier") { + val code = """ abstract class A { abstract protected fun A() } @@ -19,11 +19,11 @@ class RedundantVisibilityModifierRuleSpec : SubjectSpek return 5 @@ -20,24 +20,24 @@ class ReturnCountSpec : Spek({ } """ - it("should get flagged by default") { - val findings = ReturnCount().lint(code) - assertThat(findings).hasSize(1) - } + it("should get flagged by default") { + val findings = ReturnCount().lint(code) + assertThat(findings).hasSize(1) + } - it("should not get flagged when max value is 3") { - val findings = ReturnCount(TestConfig(mapOf(ReturnCount.MAX to "3"))).lint(code) - assertThat(findings).hasSize(0) - } + it("should not get flagged when max value is 3") { + val findings = ReturnCount(TestConfig(mapOf(ReturnCount.MAX to "3"))).lint(code) + assertThat(findings).hasSize(0) + } - it("should get flagged when max value is 1") { - val findings = ReturnCount(TestConfig(mapOf(ReturnCount.MAX to "1"))).lint(code) - assertThat(findings).hasSize(1) - } - } + it("should get flagged when max value is 1") { + val findings = ReturnCount(TestConfig(mapOf(ReturnCount.MAX to "1"))).lint(code) + assertThat(findings).hasSize(1) + } + } - given("a file with 2 returns") { - val code = """ + given("a file with 2 returns") { + val code = """ fun test(x: Int): Int { when (x) { 5 -> return 5 @@ -46,24 +46,24 @@ class ReturnCountSpec : Spek({ } """ - it("should not get flagged by default") { - val findings = ReturnCount().lint(code) - assertThat(findings).hasSize(0) - } + it("should not get flagged by default") { + val findings = ReturnCount().lint(code) + assertThat(findings).hasSize(0) + } - it("should not get flagged when max value is 2") { - val findings = ReturnCount(TestConfig(mapOf(ReturnCount.MAX to "2"))).lint(code) - assertThat(findings).hasSize(0) - } + it("should not get flagged when max value is 2") { + val findings = ReturnCount(TestConfig(mapOf(ReturnCount.MAX to "2"))).lint(code) + assertThat(findings).hasSize(0) + } - it("should get flagged when max value is 1") { - val findings = ReturnCount(TestConfig(mapOf(ReturnCount.MAX to "1"))).lint(code) - assertThat(findings).hasSize(1) - } - } + it("should get flagged when max value is 1") { + val findings = ReturnCount(TestConfig(mapOf(ReturnCount.MAX to "1"))).lint(code) + assertThat(findings).hasSize(1) + } + } - given("a function is ignored") { - val code = """ + given("a function is ignored") { + val code = """ fun test(x: Int): Int { when (x) { 5 -> return 5 @@ -73,17 +73,17 @@ class ReturnCountSpec : Spek({ } """ - it("should not get flagged") { - val findings = ReturnCount(TestConfig(mapOf( - ReturnCount.MAX to "2", - ReturnCount.EXCLUDED_FUNCTIONS to "test") - )).lint(code) - assertThat(findings).isEmpty() - } - } + it("should not get flagged") { + val findings = ReturnCount(TestConfig(mapOf( + ReturnCount.MAX to "2", + ReturnCount.EXCLUDED_FUNCTIONS to "test") + )).lint(code) + assertThat(findings).isEmpty() + } + } - given("a subset of functions are ignored") { - val code = """ + given("a subset of functions are ignored") { + val code = """ fun test1(x: Int): Int { when (x) { 5 -> return 5 @@ -109,17 +109,17 @@ class ReturnCountSpec : Spek({ } """ - it("should flag none of the ignored functions") { - val findings = ReturnCount(TestConfig(mapOf( - ReturnCount.MAX to "2", - ReturnCount.EXCLUDED_FUNCTIONS to "test1,test2") - )).lint(code) - assertThat(findings).hasSize(1) - } - } + it("should flag none of the ignored functions") { + val findings = ReturnCount(TestConfig(mapOf( + ReturnCount.MAX to "2", + ReturnCount.EXCLUDED_FUNCTIONS to "test1,test2") + )).lint(code) + assertThat(findings).hasSize(1) + } + } - given("a function with inner object") { - val code = """ + given("a function with inner object") { + val code = """ fun test(x: Int): Int { val a = object { fun test2(x: Int): Int { @@ -136,14 +136,14 @@ class ReturnCountSpec : Spek({ } """ - it("should not get flag when returns is in inner object") { - val findings = ReturnCount(TestConfig(mapOf(ReturnCount.MAX to "2"))).lint(code) - assertThat(findings).hasSize(0) - } - } + it("should not get flag when returns is in inner object") { + val findings = ReturnCount(TestConfig(mapOf(ReturnCount.MAX to "2"))).lint(code) + assertThat(findings).hasSize(0) + } + } - given("a function with 2 inner object") { - val code = """ + given("a function with 2 inner object") { + val code = """ fun test(x: Int): Int { val a = object { fun test2(x: Int): Int { @@ -168,14 +168,14 @@ class ReturnCountSpec : Spek({ } """ - it("should not get flag when returns is in inner object") { - val findings = ReturnCount(TestConfig(mapOf(ReturnCount.MAX to "2"))).lint(code) - assertThat(findings).hasSize(0) - } - } + it("should not get flag when returns is in inner object") { + val findings = ReturnCount(TestConfig(mapOf(ReturnCount.MAX to "2"))).lint(code) + assertThat(findings).hasSize(0) + } + } - given("a function with 2 inner object and exceeded max") { - val code = """ + given("a function with 2 inner object and exceeded max") { + val code = """ fun test(x: Int): Int { val a = object { fun test2(x: Int): Int { @@ -202,15 +202,15 @@ class ReturnCountSpec : Spek({ } """ - it("should get flagged when returns is in inner object") { - val findings = ReturnCount(TestConfig(mapOf(ReturnCount.MAX to "2"))).lint(code) - assertThat(findings).hasSize(1) - } - } + it("should get flagged when returns is in inner object") { + val findings = ReturnCount(TestConfig(mapOf(ReturnCount.MAX to "2"))).lint(code) + assertThat(findings).hasSize(1) + } + } - given("function with multiple labeled return statements") { + given("function with multiple labeled return statements") { - val code = """ + val code = """ fun readUsers(name: String): Flowable { return userDao.read(name) .flatMap { @@ -220,24 +220,24 @@ class ReturnCountSpec : Spek({ } """.trimIndent() - it("should not count labeled returns from lambda by default") { - val findings = ReturnCount().lint(code) - assertThat(findings).isEmpty() - } + it("should not count labeled returns from lambda by default") { + val findings = ReturnCount().lint(code) + assertThat(findings).isEmpty() + } - it("should count labeled returns from lambda when activated") { - val findings = ReturnCount( - TestConfig(mapOf("excludeReturnFromLambda" to "false"))).lint(code) - assertThat(findings).hasSize(1) - } + it("should count labeled returns from lambda when activated") { + val findings = ReturnCount( + TestConfig(mapOf("excludeReturnFromLambda" to "false"))).lint(code) + assertThat(findings).hasSize(1) + } - it("should be empty when labeled returns are de-activated") { - val findings = ReturnCount( - TestConfig(mapOf( - "excludeLabeled" to "true", - "excludeReturnFromLambda" to "false" - ))).lint(code) - assertThat(findings).isEmpty() - } - } + it("should be empty when labeled returns are de-activated") { + val findings = ReturnCount( + TestConfig(mapOf( + "excludeLabeled" to "true", + "excludeReturnFromLambda" to "false" + ))).lint(code) + assertThat(findings).isEmpty() + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/SafeCastSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/SafeCastSpec.kt index e8d4cfa30..52d271b95 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/SafeCastSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/SafeCastSpec.kt @@ -7,12 +7,12 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class SafeCastSpec : SubjectSpek({ - subject { SafeCast() } + subject { SafeCast() } - given("some cast expressions") { + given("some cast expressions") { - it("reports negated expression") { - val code = """ + it("reports negated expression") { + val code = """ fun test() { if (element !is KtElement) { null @@ -20,11 +20,11 @@ class SafeCastSpec : SubjectSpek({ element } }""" - assertThat(subject.lint(code)).hasSize(1) - } + assertThat(subject.lint(code)).hasSize(1) + } - it("reports expression") { - val code = """ + it("reports expression") { + val code = """ fun test() { if (element is KtElement) { element @@ -32,11 +32,11 @@ class SafeCastSpec : SubjectSpek({ null } }""" - assertThat(subject.lint(code)).hasSize(1) - } + assertThat(subject.lint(code)).hasSize(1) + } - it("does not report wrong condition") { - val code = """ + it("does not report wrong condition") { + val code = """ fun test() { if (element == other) { element @@ -44,11 +44,11 @@ class SafeCastSpec : SubjectSpek({ null } }""" - assertThat(subject.lint(code)).hasSize(0) - } + assertThat(subject.lint(code)).hasSize(0) + } - it("does not report wrong else clause") { - val code = """ + it("does not report wrong else clause") { + val code = """ fun test() { if (element is KtElement) { element @@ -56,7 +56,7 @@ class SafeCastSpec : SubjectSpek({ KtElement() } }""" - assertThat(subject.lint(code)).hasSize(0) - } - } + assertThat(subject.lint(code)).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/SerialVersionUIDInSerializableClassSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/SerialVersionUIDInSerializableClassSpec.kt index 06c4ba0cc..db8f60ae2 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/SerialVersionUIDInSerializableClassSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/SerialVersionUIDInSerializableClassSpec.kt @@ -9,16 +9,16 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class SerialVersionUIDInSerializableClassSpec : SubjectSpek({ - subject { SerialVersionUIDInSerializableClass(Config.empty) } + subject { SerialVersionUIDInSerializableClass(Config.empty) } - given("several serializable classes") { + given("several serializable classes") { - it("reports serializable classes which do not implement the serialVersionUID correctly") { - assertThat(subject.lint(Case.SerializablePositive.path())).hasSize(5) - } + it("reports serializable classes which do not implement the serialVersionUID correctly") { + assertThat(subject.lint(Case.SerializablePositive.path())).hasSize(5) + } - it("does not report serializable classes which implement the serialVersionUID correctly") { - assertThat(subject.lint(Case.SerializableNegative.path())).hasSize(0) - } - } + it("does not report serializable classes which implement the serialVersionUID correctly") { + assertThat(subject.lint(Case.SerializableNegative.path())).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/SpacingBetweenPackageAndImportsSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/SpacingBetweenPackageAndImportsSpec.kt index 001b0d0f0..2308f9482 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/SpacingBetweenPackageAndImportsSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/SpacingBetweenPackageAndImportsSpec.kt @@ -9,66 +9,66 @@ import org.jetbrains.spek.subject.SubjectSpek import org.jetbrains.spek.subject.dsl.SubjectProviderDsl class SpacingBetweenPackageAndImportsSpec : SubjectSpek({ - subject { SpacingBetweenPackageAndImports(Config.empty) } + subject { SpacingBetweenPackageAndImports(Config.empty) } - given("several package and import declarations") { + given("several package and import declarations") { - it("has no blank lines violation") { - val code = "package test\n\nimport a.b\n\nclass A {}" - assertCodeWithoutViolation(code) - } + it("has no blank lines violation") { + val code = "package test\n\nimport a.b\n\nclass A {}" + assertCodeWithoutViolation(code) + } - it("has a package and import declaration") { - val code = "package test\n\nimport a.b" - assertCodeWithoutViolation(code) - } + it("has a package and import declaration") { + val code = "package test\n\nimport a.b" + assertCodeWithoutViolation(code) + } - it("has no import declaration") { - val code = "package test\n\nclass A {}" - assertCodeWithoutViolation(code) - } + it("has no import declaration") { + val code = "package test\n\nclass A {}" + assertCodeWithoutViolation(code) + } - it("has no package declaration") { - val code = "import a.b\n\nclass A {}" - assertCodeWithoutViolation(code) - } + it("has no package declaration") { + val code = "import a.b\n\nclass A {}" + assertCodeWithoutViolation(code) + } - it("has no package and import declaration") { - val code = "class A {}" - assertCodeWithoutViolation(code) - } + it("has no package and import declaration") { + val code = "class A {}" + assertCodeWithoutViolation(code) + } - it("has a comment declaration") { - val code = "import a.b\n\n// a comment" - assertCodeWithoutViolation(code) - } + it("has a comment declaration") { + val code = "import a.b\n\n// a comment" + assertCodeWithoutViolation(code) + } - it("is an empty kt file") { - assertCodeWithoutViolation("") - } + it("is an empty kt file") { + assertCodeWithoutViolation("") + } - it("has code on new line") { - val code = "package test\nimport a.b\nclass A {}" - assertCodeViolation(code, 2) - } + it("has code on new line") { + val code = "package test\nimport a.b\nclass A {}" + assertCodeViolation(code, 2) + } - it("has code with spaces") { - val code = "package test; import a.b; class A {}" - assertCodeViolation(code, 2) - } + it("has code with spaces") { + val code = "package test; import a.b; class A {}" + assertCodeViolation(code, 2) + } - it("has two many blank lines") { - val code = "package test\n\n\nimport a.b\n\n\nclass A {}" - assertCodeViolation(code, 2) - } + it("has two many blank lines") { + val code = "package test\n\n\nimport a.b\n\n\nclass A {}" + assertCodeViolation(code, 2) + } - it("has package declarations in same line") { - val code = "package test;import a.b;class A {}" - assertCodeViolation(code, 2) - } + it("has package declarations in same line") { + val code = "package test;import a.b;class A {}" + assertCodeViolation(code, 2) + } - it("should be valid") { - val code = """ + it("should be valid") { + val code = """ package com.my.package import android.util.Log @@ -76,25 +76,25 @@ class SpacingBetweenPackageAndImportsSpec : SubjectSpek.assertCodeViolation(code: String, size: Int) { - assertThat(subject.lint(code)).hasSize(size) + assertThat(subject.lint(code)).hasSize(size) } private fun SubjectProviderDsl.assertCodeWithoutViolation(code: String) { - assertThat(subject.lint(code)).hasSize(0) + assertThat(subject.lint(code)).hasSize(0) } diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ThrowsCountSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ThrowsCountSpec.kt index 9c595720a..f975783e9 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ThrowsCountSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ThrowsCountSpec.kt @@ -9,11 +9,11 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class ThrowsCountSpec : SubjectSpek({ - subject { ThrowsCount(Config.empty) } + subject { ThrowsCount(Config.empty) } - given("several methods which throw exceptions") { + given("several methods which throw exceptions") { - val code = """ + val code = """ fun f1(x: Int) { when (x) { 1 -> throw IOException() @@ -38,15 +38,15 @@ class ThrowsCountSpec : SubjectSpek({ } """ - it("reports violation by default") { - val findings = subject.lint(code) - assertThat(findings).hasSize(1) - } + it("reports violation by default") { + val findings = subject.lint(code) + assertThat(findings).hasSize(1) + } - it("does not report for configuration max parameter") { - val config = TestConfig(mapOf(ThrowsCount.MAX to "3")) - val subject = ThrowsCount(config) - assertThat(subject.lint(code)).hasSize(0) - } - } + it("does not report for configuration max parameter") { + val config = TestConfig(mapOf(ThrowsCount.MAX to "3")) + val subject = ThrowsCount(config) + assertThat(subject.lint(code)).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/TrailingWhitespaceSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/TrailingWhitespaceSpec.kt index 36c2a8895..8ecb8ccee 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/TrailingWhitespaceSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/TrailingWhitespaceSpec.kt @@ -9,29 +9,29 @@ import org.jetbrains.spek.api.dsl.it class TrailingWhitespaceSpec : Spek({ - given("a kt file that contains lines that end with a whitespace") { - val rule = TrailingWhitespace() - val file = compileForTest(Case.TrailingWhitespacePositive.path()) - val lines = file.text.splitToSequence("\n") - rule.visit(KtFileContent(file, lines)) + given("a kt file that contains lines that end with a whitespace") { + val rule = TrailingWhitespace() + val file = compileForTest(Case.TrailingWhitespacePositive.path()) + val lines = file.text.splitToSequence("\n") + rule.visit(KtFileContent(file, lines)) - it("should flag it") { - assertThat(rule.findings).hasSize(7) - } + it("should flag it") { + assertThat(rule.findings).hasSize(7) + } - it("should report the correct source location for a comment with trailing whitespace") { - val findingSource = rule.findings[1].location.source - assertThat(findingSource.line).isEqualTo(5) - assertThat(findingSource.column).isEqualTo(1) - } - } + it("should report the correct source location for a comment with trailing whitespace") { + val findingSource = rule.findings[1].location.source + assertThat(findingSource.line).isEqualTo(5) + assertThat(findingSource.column).isEqualTo(1) + } + } - given("a kt file that does not contain lines that end with a whitespace") { + given("a kt file that does not contain lines that end with a whitespace") { - it("should not flag it") { - val rule = TrailingWhitespace() - rule.visit(Case.TrailingWhitespaceNegative.getKtFileContent()) - assertThat(rule.findings).hasSize(0) - } - } + it("should not flag it") { + val rule = TrailingWhitespace() + rule.visit(Case.TrailingWhitespaceNegative.getKtFileContent()) + assertThat(rule.findings).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryAbstractClassSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryAbstractClassSpec.kt index e94671fb2..21e0c9cb7 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryAbstractClassSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryAbstractClassSpec.kt @@ -10,43 +10,43 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class UnnecessaryAbstractClassSpec : SubjectSpek({ - subject { - UnnecessaryAbstractClass(TestConfig(mapOf( - UnnecessaryAbstractClass.EXCLUDE_ANNOTATED_CLASSES to "jdk.nashorn.internal.ir.annotations.Ignore" - ))) - } + subject { + UnnecessaryAbstractClass(TestConfig(mapOf( + UnnecessaryAbstractClass.EXCLUDE_ANNOTATED_CLASSES to "jdk.nashorn.internal.ir.annotations.Ignore" + ))) + } - val noConcreteMemberDescription = "An abstract class without a concrete member can be refactored to an interface." - val noAbstractMemberDescription = "An abstract class without an abstract member can be refactored to a concrete class." + val noConcreteMemberDescription = "An abstract class without a concrete member can be refactored to an interface." + val noAbstractMemberDescription = "An abstract class without an abstract member can be refactored to a concrete class." - given("abstract classes with no abstract members") { + given("abstract classes with no abstract members") { - val path = Case.UnnecessaryAbstractClassPositive.path() - val findings = subject.lint(path) + val path = Case.UnnecessaryAbstractClassPositive.path() + val findings = subject.lint(path) - it("has no abstract member violation") { - assertThat(countViolationsWithDescription(findings, noAbstractMemberDescription)).isEqualTo(5) - } + it("has no abstract member violation") { + assertThat(countViolationsWithDescription(findings, noAbstractMemberDescription)).isEqualTo(5) + } - it("has no concrete member violation") { - assertThat(countViolationsWithDescription(findings, noConcreteMemberDescription)).isEqualTo(1) - } - } + it("has no concrete member violation") { + assertThat(countViolationsWithDescription(findings, noConcreteMemberDescription)).isEqualTo(1) + } + } - given("abstract classes with members") { + given("abstract classes with members") { - val path = Case.UnnecessaryAbstractClassNegative.path() - val findings = subject.lint(path) + val path = Case.UnnecessaryAbstractClassNegative.path() + val findings = subject.lint(path) - it("does not report no abstract member violation") { - assertThat(countViolationsWithDescription(findings, noAbstractMemberDescription)).isEqualTo(0) - } + it("does not report no abstract member violation") { + assertThat(countViolationsWithDescription(findings, noAbstractMemberDescription)).isEqualTo(0) + } - it("does not report no concrete member violation") { - assertThat(countViolationsWithDescription(findings, noConcreteMemberDescription)).isEqualTo(0) - } - } + it("does not report no concrete member violation") { + assertThat(countViolationsWithDescription(findings, noConcreteMemberDescription)).isEqualTo(0) + } + } }) private fun countViolationsWithDescription(findings: List, description: String) = - findings.count { it.message.contains(description) } + findings.count { it.message.contains(description) } diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryApplySpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryApplySpec.kt index 29f5228b3..2ced49b6d 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryApplySpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryApplySpec.kt @@ -9,12 +9,12 @@ import org.jetbrains.spek.subject.SubjectSpek class UnnecessaryApplySpec : SubjectSpek({ - subject { UnnecessaryApply(Config.empty) } + subject { UnnecessaryApply(Config.empty) } - given("unnecessary apply expressions that can be changed to ordinary method call") { + given("unnecessary apply expressions that can be changed to ordinary method call") { - it("reports an apply on non-nullable type") { - assertThat(subject.lint(""" + it("reports an apply on non-nullable type") { + assertThat(subject.lint(""" fun f() { val a : Int = 0 a.apply { @@ -22,10 +22,10 @@ class UnnecessaryApplySpec : SubjectSpek({ } } """)).hasSize(1) - } + } - it("reports a false negative apply on nullable type") { - assertThat(subject.lint(""" + it("reports a false negative apply on nullable type") { + assertThat(subject.lint(""" fun f() { val a : Int? = null // Resolution: we can't say here if plus is on 'this' or just a side effects when a is not null @@ -34,10 +34,10 @@ class UnnecessaryApplySpec : SubjectSpek({ } } """)).isEmpty() - } + } - it("does not report an apply with lambda block") { - assertThat(subject.lint(""" + it("does not report an apply with lambda block") { + assertThat(subject.lint(""" fun f() { val a : Int? = null a.apply({ @@ -45,10 +45,10 @@ class UnnecessaryApplySpec : SubjectSpek({ }) } """)).isEmpty() - } + } - it("does report single statement in apply used as function argument") { - assertThat(subject.lint(""" + it("does report single statement in apply used as function argument") { + assertThat(subject.lint(""" fun b(i : Int?) { } fun f() { @@ -58,10 +58,10 @@ class UnnecessaryApplySpec : SubjectSpek({ }) } """)).isEmpty() - } + } - it("does not report applies with lambda body containing more than one statement") { - assertThat(subject.lint(""" + it("does not report applies with lambda body containing more than one statement") { + assertThat(subject.lint(""" fun b(i : Int?) { } fun f() { @@ -79,40 +79,40 @@ class UnnecessaryApplySpec : SubjectSpek({ plus(2) }) }""")).isEmpty() - } - } + } + } - given("reported false positives - #1305") { + given("reported false positives - #1305") { - it("is used within an assignment expr itself") { - assertThat(subject.lint(""" + it("is used within an assignment expr itself") { + assertThat(subject.lint(""" val content = Intent().apply { putExtra("", 1) } """.trimIndent())).isEmpty() - } + } - it("is used as return type of extension function") { - assertThat(subject.lint(""" + it("is used as return type of extension function") { + assertThat(subject.lint(""" fun setColor(color: Int) = apply { initialColor = color } """.trimIndent())).isEmpty() - } + } - it("should not flag apply when assigning property on this") { - assertThat(subject.lint(""" + it("should not flag apply when assigning property on this") { + assertThat(subject.lint(""" private val requestedInterval by lazy { MutableLiveData().apply { value = UsageFragment.INTERVAL_DAY } } """.trimIndent())).isEmpty() - } + } - it("should not report apply when using it after returning something") { - assertThat(subject.lint(""" + it("should not report apply when using it after returning something") { + assertThat(subject.lint(""" inline class Money(var amount: Int) fun returnMe = (Money(5)).apply { amount = 10 } """.trimIndent())).isEmpty() - } + } - it("should not report apply usage inside safe chained expressions") { - assertThat(subject.lint(""" + it("should not report apply usage inside safe chained expressions") { + assertThat(subject.lint(""" fun test() { val arguments = listOf(1,2,3) ?.map { it * 2 } @@ -120,6 +120,6 @@ class UnnecessaryApplySpec : SubjectSpek({ ?: listOf(0) } """.trimIndent())).isEmpty() - } - } + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryInheritanceSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryInheritanceSpec.kt index e2c4e327d..71c3835ed 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryInheritanceSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryInheritanceSpec.kt @@ -8,20 +8,20 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class UnnecessaryInheritanceSpec : SubjectSpek({ - subject { UnnecessaryInheritance(Config.empty) } + subject { UnnecessaryInheritance(Config.empty) } - describe("check inherit classes") { + describe("check inherit classes") { - it("has unnecessary super type declarations") { - val findings = subject.lint(""" + it("has unnecessary super type declarations") { + val findings = subject.lint(""" class A : Any() class B : Object()""") - assertThat(findings).hasSize(2) - } + assertThat(findings).hasSize(2) + } - it("has no unnecessary super type declarations") { - val findings = subject.lint("class C : An()") - assertThat(findings).hasSize(0) - } - } + it("has no unnecessary super type declarations") { + val findings = subject.lint("class C : An()") + assertThat(findings).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryLetSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryLetSpec.kt index f344e83bd..28fec9e69 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryLetSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryLetSpec.kt @@ -8,11 +8,11 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class UnnecessaryLetSpec : SubjectSpek({ - subject { UnnecessaryLet(Config.empty) } + subject { UnnecessaryLet(Config.empty) } - given("some code using let expressions extensively") { - it("reports unnecessary lets that can be changed to ordinary method call") { - val findings = subject.lint(""" + given("some code using let expressions extensively") { + it("reports unnecessary lets that can be changed to ordinary method call") { + val findings = subject.lint(""" fun f() { val a : Int? = null a.let { it.plus(1) } @@ -21,10 +21,10 @@ class UnnecessaryLetSpec : SubjectSpek({ a?.let { that -> that.plus(1) } a?.let { that -> that.plus(1) }?.let { it.plus(1) } }""") - assertThat(findings).hasSize(6) - } - it("does not report lets used for function calls") { - val findings = subject.lint(""" + assertThat(findings).hasSize(6) + } + it("does not report lets used for function calls") { + val findings = subject.lint(""" fun f() { val a : Int? = null a.let { print(it) } @@ -33,10 +33,10 @@ class UnnecessaryLetSpec : SubjectSpek({ a?.let { that -> 1.plus(that) } a?.let { that -> 1.plus(that) }?.let { print(it) } }""") - assertThat(findings).hasSize(0) - } - it("does not report lets with lambda body containing more than one statement") { - val findings = subject.lint(""" + assertThat(findings).hasSize(0) + } + it("does not report lets with lambda body containing more than one statement") { + val findings = subject.lint(""" fun f() { val a : Int? = null a.let { it.plus(1) @@ -51,16 +51,16 @@ class UnnecessaryLetSpec : SubjectSpek({ ?.let { it.plus(1) it.plus(2) } }""") - assertThat(findings).hasSize(0) - } - it("does not report lets where it is used multiple times") { - val findings = subject.lint(""" + assertThat(findings).hasSize(0) + } + it("does not report lets where it is used multiple times") { + val findings = subject.lint(""" fun f() { val a : Int? = null a?.let { it.plus(it) } a?.let { foo -> foo.plus(foo) } }""") - assertThat(findings).hasSize(0) - } - } + assertThat(findings).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryParenthesesSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryParenthesesSpec.kt index 6f9e6304e..47daf67f2 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryParenthesesSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryParenthesesSpec.kt @@ -8,37 +8,37 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class UnnecessaryParenthesesSpec : SubjectSpek({ - subject { UnnecessaryParentheses(Config.empty) } + subject { UnnecessaryParentheses(Config.empty) } - given("parenthesized expressions") { + given("parenthesized expressions") { - it("with unnecessary parentheses on val assignment") { - val code = "val local = (5)" - assertThat(subject.lint(code)).hasSize(1) - } + it("with unnecessary parentheses on val assignment") { + val code = "val local = (5)" + assertThat(subject.lint(code)).hasSize(1) + } - it("with unnecessary parentheses on val assignment operation") { - val code = "val local = (5 + 3)" - assertThat(subject.lint(code)).hasSize(1) - } + it("with unnecessary parentheses on val assignment operation") { + val code = "val local = (5 + 3)" + assertThat(subject.lint(code)).hasSize(1) + } - it("with unnecessary parentheses on function call") { - val code = "val local = 3.plus((5))" - assertThat(subject.lint(code)).hasSize(1) - } + it("with unnecessary parentheses on function call") { + val code = "val local = 3.plus((5))" + assertThat(subject.lint(code)).hasSize(1) + } - it("unnecessary parentheses in other parentheses") { - val code = """ + it("unnecessary parentheses in other parentheses") { + val code = """ fun x(a: String, b: String) { if ((a equals b)) { println("Test") } }""" - assertThat(subject.lint(code)).hasSize(1) - } + assertThat(subject.lint(code)).hasSize(1) + } - it("reports unnecessary parentheses around lambdas") { - val code = """ + it("reports unnecessary parentheses around lambdas") { + val code = """ fun function (a: (input: String) -> Unit) { a.invoke("TEST") } @@ -47,11 +47,11 @@ class UnnecessaryParenthesesSpec : SubjectSpek({ function({ input -> println(input) }) } """ - assertThat(subject.lint(code)).hasSize(1) - } + assertThat(subject.lint(code)).hasSize(1) + } - it("doesn't report function calls containing lambdas and other parameters") { - val code = """ + it("doesn't report function calls containing lambdas and other parameters") { + val code = """ fun function (integer: Int, a: (input: String) -> Unit) { a.invoke("TEST") } @@ -60,29 +60,29 @@ class UnnecessaryParenthesesSpec : SubjectSpek({ function(1, { input -> println(input) }) } """ - assertThat(subject.lint(code)).hasSize(0) - } + assertThat(subject.lint(code)).hasSize(0) + } - it("does not report unnecessary parentheses when assigning a lambda to a val") { - val code = """ + it("does not report unnecessary parentheses when assigning a lambda to a val") { + val code = """ fun f() { instance.copy(value = { false }) }""" - assertThat(subject.lint(code)).hasSize(0) - } + assertThat(subject.lint(code)).hasSize(0) + } - it("does not report well behaved parentheses") { - val code = """ + it("does not report well behaved parentheses") { + val code = """ fun x(a: String, b: String) { if (a equals b) { println("Test") } }""" - assertThat(subject.lint(code)).hasSize(0) - } + assertThat(subject.lint(code)).hasSize(0) + } - it("does not report well behaved parentheses in super constructors") { - val code = """ + it("does not report well behaved parentheses in super constructors") { + val code = """ class TestSpek : SubjectSpek({ describe("a simple test") { it("should do something") { @@ -90,11 +90,11 @@ class UnnecessaryParenthesesSpec : SubjectSpek({ } }) """ - assertThat(subject.lint(code)).hasSize(0) - } + assertThat(subject.lint(code)).hasSize(0) + } - it("does not report well behaved parentheses in constructors") { - val code = """ + it("does not report well behaved parentheses in constructors") { + val code = """ class TestSpek({ describe("a simple test") { it("should do something") { @@ -102,22 +102,22 @@ class UnnecessaryParenthesesSpec : SubjectSpek({ } }) """ - assertThat(subject.lint(code)).hasSize(0) - } + assertThat(subject.lint(code)).hasSize(0) + } - it("should not report lambdas within super constructor calls") { - val code = """ + it("should not report lambdas within super constructor calls") { + val code = """ class Clazz( private val func: (X, Y) -> Z ) { constructor() : this({ first, second -> true }) } """.trimIndent() - assertThat(subject.lint(code)).hasSize(0) - } + assertThat(subject.lint(code)).hasSize(0) + } - it("should not report call to function with two lambda parameters with one as block body") { - val code = """ + it("should not report call to function with two lambda parameters with one as block body") { + val code = """ class Clazz { fun test(first: (Int) -> Unit, second: (Int) -> Unit) { first(1) @@ -129,11 +129,11 @@ class UnnecessaryParenthesesSpec : SubjectSpek({ } } """.trimIndent() - assertThat(subject.lint(code)).hasSize(0) - } + assertThat(subject.lint(code)).hasSize(0) + } - it("should not report call to function with two lambda parameters") { - val code = """ + it("should not report call to function with two lambda parameters") { + val code = """ class Clazz { fun test(first: (Int) -> Unit, second: (Int) -> Unit) { first(1) @@ -145,11 +145,11 @@ class UnnecessaryParenthesesSpec : SubjectSpek({ } } """.trimIndent() - assertThat(subject.lint(code)).hasSize(0) - } + assertThat(subject.lint(code)).hasSize(0) + } - it("should not report call to function with multiple lambdas as parameters but also other parameters") { - val code = """ + it("should not report call to function with multiple lambdas as parameters but also other parameters") { + val code = """ class Clazz { fun test(text: String, first: () -> Unit, second: () -> Unit) { first() @@ -161,7 +161,7 @@ class UnnecessaryParenthesesSpec : SubjectSpek({ } } """.trimIndent() - assertThat(subject.lint(code)).hasSize(0) - } - } + assertThat(subject.lint(code)).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UntilInsteadOfRangeToSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UntilInsteadOfRangeToSpec.kt index 4835ac56c..1e3280b55 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UntilInsteadOfRangeToSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UntilInsteadOfRangeToSpec.kt @@ -7,56 +7,56 @@ import org.jetbrains.spek.api.dsl.given import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek -class UntilInsteadOfRangeToSpec : SubjectSpek ({ - subject { UntilInsteadOfRangeTo(Config.empty) } +class UntilInsteadOfRangeToSpec : SubjectSpek({ + subject { UntilInsteadOfRangeTo(Config.empty) } - given("several loops") { + given("several loops") { - it("reports for '..'") { - val code = """ + it("reports for '..'") { + val code = """ fun f() { for (i in 0 .. 10 - 1) {} }""" - assertThat(subject.lint(code)).hasSize(1) - } + assertThat(subject.lint(code)).hasSize(1) + } - it("does not report if rangeTo not used") { - val code = """ + it("does not report if rangeTo not used") { + val code = """ fun f() { for (i in 0 until 10 - 1) {} for (i in 10 downTo 2 - 1) {} }""" - assertThat(subject.lint(code)).hasSize(0) - } + assertThat(subject.lint(code)).hasSize(0) + } - it("does not report if upper value isn't a binary expression") { - val code = """ + it("does not report if upper value isn't a binary expression") { + val code = """ fun f() { for (i in 0 .. 10) {} }""" - assertThat(subject.lint(code)).hasSize(0) - } + assertThat(subject.lint(code)).hasSize(0) + } - it("does not report if not minus one") { - val code = """ + it("does not report if not minus one") { + val code = """ fun f() { for (i in 0 .. 10 + 1) {} for (i in 0 .. 10 - 2) {} }""" - assertThat(subject.lint(code)).hasSize(0) - } - } + assertThat(subject.lint(code)).hasSize(0) + } + } - given("several binary expressions") { + given("several binary expressions") { - it("reports for '..'") { - val code = "val r = 0 .. 10 - 1" - assertThat(subject.lint(code)).hasSize(1) - } + it("reports for '..'") { + val code = "val r = 0 .. 10 - 1" + assertThat(subject.lint(code)).hasSize(1) + } - it("does not report binary expressions without a range operator") { - val code = "val sum = 1 + 2" - assertThat(subject.lint(code)).hasSize(0) - } - } + it("does not report binary expressions without a range operator") { + val code = "val sum = 1 + 2" + assertThat(subject.lint(code)).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedImportsSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedImportsSpec.kt index f22105337..92cd1af63 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedImportsSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedImportsSpec.kt @@ -14,12 +14,12 @@ import org.jetbrains.spek.subject.SubjectSpek * @author schalkms */ class UnusedImportsSpec : SubjectSpek({ - subject { UnusedImports(Config.empty) } + subject { UnusedImports(Config.empty) } - given("some import statements") { + given("some import statements") { - it("does not report infix operators") { - assertThat(subject.lint(""" + it("does not report infix operators") { + assertThat(subject.lint(""" import tasks.success fun main() { @@ -27,11 +27,11 @@ class UnusedImportsSpec : SubjectSpek({ } success { } }""" - )).isEmpty() - } + )).isEmpty() + } - it("does not report imports in documentation") { - assertThat(subject.lint(""" + it("does not report imports in documentation") { + assertThat(subject.lint(""" import tasks.success import tasks.failure import tasks.undefined @@ -48,11 +48,11 @@ class UnusedImportsSpec : SubjectSpek({ } } """ - )).isEmpty() - } + )).isEmpty() + } - it("should ignore import for link") { - val lint = subject.lint(""" + it("should ignore import for link") { + val lint = subject.lint(""" import tasks.success import tasks.failure import tasks.undefined @@ -66,29 +66,29 @@ class UnusedImportsSpec : SubjectSpek({ } } """ - ) - with(lint) { - assertThat(this).hasSize(1) - assertThat(this[0].entity.signature).endsWith("import tasks.undefined") - } - } + ) + with(lint) { + assertThat(this).hasSize(1) + assertThat(this[0].entity.signature).endsWith("import tasks.undefined") + } + } - it("reports imports from the current package") { - val lint = subject.lint(""" + it("reports imports from the current package") { + val lint = subject.lint(""" package test import test.SomeClass val a: SomeClass? = null """ - ) - with(lint) { - assertThat(this).hasSize(1) - assertThat(this[0].entity.signature).endsWith("import test.SomeClass") - } - } + ) + with(lint) { + assertThat(this).hasSize(1) + assertThat(this[0].entity.signature).endsWith("import test.SomeClass") + } + } - it("does not report KDoc references with method calls") { - val code = """ + it("does not report KDoc references with method calls") { + val code = """ package com.example import android.text.TextWatcher @@ -101,11 +101,11 @@ class UnusedImportsSpec : SubjectSpek({ TODO() } }""" - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("reports imports with different cases") { - val lint = subject.lint(""" + it("reports imports with different cases") { + val lint = subject.lint(""" import p.a import p.B6 // positive import p.B as B12 // positive @@ -122,17 +122,17 @@ class UnusedImportsSpec : SubjectSpek({ fn(B2.NAME) `when`() }""" - ) - with(lint) { - assertThat(this).hasSize(3) - assertThat(this[0].entity.signature).contains("import p.B6") - assertThat(this[1].entity.signature).contains("import p.B as B12") - assertThat(this[2].entity.signature).contains("import escaped.`foo`") - } - } + ) + with(lint) { + assertThat(this).hasSize(3) + assertThat(this[0].entity.signature).contains("import p.B6") + assertThat(this[1].entity.signature).contains("import p.B as B12") + assertThat(this[2].entity.signature).contains("import escaped.`foo`") + } + } - it("does not report imports in same package when inner") { - val lint = subject.lint(""" + it("does not report imports in same package when inner") { + val lint = subject.lint(""" package test import test.Outer.Inner @@ -140,17 +140,17 @@ class UnusedImportsSpec : SubjectSpek({ class Outer : Something() { class Inner { } }""" - ) - with(lint) { - assertThat(this).isEmpty() - } - } - } + ) + with(lint) { + assertThat(this).isEmpty() + } + } + } - given("some import statements referenced by KDoc @see") { + given("some import statements referenced by KDoc @see") { - it("does not report see annotation linking to class") { - val code = """ + it("does not report see annotation linking to class") { + val code = """ import tasks.success /** @@ -159,11 +159,11 @@ class UnusedImportsSpec : SubjectSpek({ */ fun doSomething()""" - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("does not report see annotation linking to class with description") { - val code = """ + it("does not report see annotation linking to class with description") { + val code = """ import tasks.success /** @@ -172,11 +172,11 @@ class UnusedImportsSpec : SubjectSpek({ */ fun doSomething()""" - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("reports see annotation that does not link to class") { - val code = """ + it("reports see annotation that does not link to class") { + val code = """ import tasks.success /** @@ -185,11 +185,11 @@ class UnusedImportsSpec : SubjectSpek({ */ fun doSomething()""" - assertThat(subject.lint(code)).hasSize(1) - } + assertThat(subject.lint(code)).hasSize(1) + } - it("reports see annotation that links after description") { - val code = """ + it("reports see annotation that links after description") { + val code = """ import tasks.success /** @@ -198,14 +198,14 @@ class UnusedImportsSpec : SubjectSpek({ */ fun doSomething()""" - assertThat(subject.lint(code)).hasSize(1) - } - } + assertThat(subject.lint(code)).hasSize(1) + } + } - given("some import statements with KDoc") { + given("some import statements with KDoc") { - it("does not report imports in KDoc") { - val code = """ + it("does not report imports in KDoc") { + val code = """ import tasks.success // here import tasks.undefined // and here @@ -216,22 +216,22 @@ class UnusedImportsSpec : SubjectSpek({ */ fun doSomething()""" - assertThat(subject.lint(code)).isEmpty() - } - } + assertThat(subject.lint(code)).isEmpty() + } + } - given("imports with aliases") { + given("imports with aliases") { - it("should not report import as unused because the alias is used") { - val code = """ + it("should not report import as unused because the alias is used") { + val code = """ import test.forEach as foreach fun foo() = listOf().iterator().foreach {} """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("should not report used alias even when import is from same package") { - val code = """ + it("should not report used alias even when import is from same package") { + val code = """ package com.example import com.example.foo as myFoo // from same package but with alias, check alias usage @@ -241,7 +241,7 @@ class UnusedImportsSpec : SubjectSpek({ return myFoo() == otherFoo() } """.trimIndent() - assertThat(subject.lint(code)).isEmpty() - } - } + assertThat(subject.lint(code)).isEmpty() + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateClassSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateClassSpec.kt index ed61b1649..76ff3f057 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateClassSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateClassSpec.kt @@ -9,55 +9,55 @@ import org.jetbrains.spek.subject.SubjectSpek class UnusedPrivateClassSpec : SubjectSpek({ - subject { UnusedPrivateClass() } + subject { UnusedPrivateClass() } - given("top level interfaces") { - it("should report them if not used") { - val code = """ + given("top level interfaces") { + it("should report them if not used") { + val code = """ private interface Foo class Bar """ - val lint = subject.lint(code) + val lint = subject.lint(code) - assertThat(lint).hasSize(1) - with(lint[0].entity) { - assertThat(ktElement?.text).isEqualTo("private interface Foo") - } - } + assertThat(lint).hasSize(1) + with(lint[0].entity) { + assertThat(ktElement?.text).isEqualTo("private interface Foo") + } + } - given("top level private classes") { + given("top level private classes") { - it("should report them if not used") { - val code = """ + it("should report them if not used") { + val code = """ private class Foo class Bar """ - val lint = subject.lint(code) + val lint = subject.lint(code) - assertThat(lint).hasSize(1) - with(lint[0].entity) { - assertThat(ktElement?.text).isEqualTo("private class Foo") - } - } + assertThat(lint).hasSize(1) + with(lint[0].entity) { + assertThat(ktElement?.text).isEqualTo("private class Foo") + } + } - it("should not report them if used as parent") { - val code = """ + it("should not report them if used as parent") { + val code = """ private class Foo private class Bar : Foo """ - val lint = subject.lint(code) + val lint = subject.lint(code) - assertThat(lint).hasSize(1) - with(lint[0].entity) { - assertThat(ktElement?.text).isEqualTo("private class Bar : Foo") - } - } + assertThat(lint).hasSize(1) + with(lint[0].entity) { + assertThat(ktElement?.text).isEqualTo("private class Bar : Foo") + } + } - it("should not report them used as generic parent type") { - val code = """ + it("should not report them used as generic parent type") { + val code = """ private class Foo { operator fun invoke(b: Bar): Unit } @@ -67,170 +67,170 @@ class UnusedPrivateClassSpec : SubjectSpek({ } """ - val lint = subject.lint(code) + val lint = subject.lint(code) - assertThat(lint).isEmpty() - } - } + assertThat(lint).isEmpty() + } + } - it("should not report them if used inside a function") { - val code = """ + it("should not report them if used inside a function") { + val code = """ private class Foo fun something() { val foo: Foo = Foo() } """ - val lint = subject.lint(code) + val lint = subject.lint(code) - assertThat(lint).isEmpty() - } + assertThat(lint).isEmpty() + } - it("should not report them if used as function parameter") { - val code = """ + it("should not report them if used as function parameter") { + val code = """ private class Foo fun bar(foo: Foo) = Unit """ - val lint = subject.lint(code) + val lint = subject.lint(code) - assertThat(lint).isEmpty() - } + assertThat(lint).isEmpty() + } - it("should not report them if used as nullable variable type") { - val code = """ + it("should not report them if used as nullable variable type") { + val code = """ private class Foo val a: Foo? = null """ - val lint = subject.lint(code) + val lint = subject.lint(code) - assertThat(lint).isEmpty() - } + assertThat(lint).isEmpty() + } - it("should not report them if used as variable type") { - val code = """ + it("should not report them if used as variable type") { + val code = """ private class Foo lateinit var a: Foo """ - val lint = subject.lint(code) + val lint = subject.lint(code) - assertThat(lint).isEmpty() - } + assertThat(lint).isEmpty() + } - it("should not report them if used as generic type") { - val code = """ + it("should not report them if used as generic type") { + val code = """ private class Foo lateinit var foos: List """ - val lint = subject.lint(code) + val lint = subject.lint(code) - assertThat(lint).isEmpty() - } + assertThat(lint).isEmpty() + } - it("should not report them if used as nested generic type") { - val code = """ + it("should not report them if used as nested generic type") { + val code = """ private class Foo lateinit var foos: List> """ - val lint = subject.lint(code) + val lint = subject.lint(code) - assertThat(lint).isEmpty() - } + assertThat(lint).isEmpty() + } - it("should not report them if used as type with generics") { - val code = """ + it("should not report them if used as type with generics") { + val code = """ private class Foo lateinit var foos: Foo """ - val lint = subject.lint(code) + val lint = subject.lint(code) - assertThat(lint).isEmpty() - } + assertThat(lint).isEmpty() + } - it("should not report them if used as nullable type with generics") { - val code = """ + it("should not report them if used as nullable type with generics") { + val code = """ private class Foo lateinit var foos: Foo? """ - val lint = subject.lint(code) + val lint = subject.lint(code) - assertThat(lint).isEmpty() - } + assertThat(lint).isEmpty() + } - it("should not report them if used as non-argument constructor") { - val code = """ + it("should not report them if used as non-argument constructor") { + val code = """ private class Foo val a = Foo() """ - val lint = subject.lint(code) + val lint = subject.lint(code) - assertThat(lint).isEmpty() - } + assertThat(lint).isEmpty() + } - it("should not report them if used as constructor with arguments") { - val code = """ + it("should not report them if used as constructor with arguments") { + val code = """ private class Foo(val a: String) val a = Foo("test") """ - val lint = subject.lint(code) + val lint = subject.lint(code) - assertThat(lint).isEmpty() - } + assertThat(lint).isEmpty() + } - it("should not report them if used as function return type") { - val code = """ + it("should not report them if used as function return type") { + val code = """ private class Foo(val a: String) fun foo(): Foo? = null """ - val lint = subject.lint(code) + val lint = subject.lint(code) - assertThat(lint).isEmpty() - } + assertThat(lint).isEmpty() + } - it("should not report them if used as lambda declaration parameter") { - val code = """ + it("should not report them if used as lambda declaration parameter") { + val code = """ private class Foo val lambda: ((Foo) -> Unit)? = null """ - val lint = subject.lint(code) + val lint = subject.lint(code) - assertThat(lint).isEmpty() - } + assertThat(lint).isEmpty() + } - it("should not report them if used as lambda declaration return type") { - val code = """ + it("should not report them if used as lambda declaration return type") { + val code = """ private class Foo val lambda: (() -> Foo)? = null """ - val lint = subject.lint(code) + val lint = subject.lint(code) - assertThat(lint).isEmpty() - } + assertThat(lint).isEmpty() + } - it("should not report them if used as lambda declaration generic type") { - val code = """ + it("should not report them if used as lambda declaration generic type") { + val code = """ private class Foo val lambda: (() -> List)? = null """ - val lint = subject.lint(code) + val lint = subject.lint(code) - assertThat(lint).isEmpty() - } + assertThat(lint).isEmpty() + } - it("should not report them if used as inline object type") { - val code = """ + it("should not report them if used as inline object type") { + val code = """ private abstract class Foo { abstract fun bar() } @@ -240,27 +240,27 @@ class UnusedPrivateClassSpec : SubjectSpek({ } """ - val lint = subject.lint(code) + val lint = subject.lint(code) - assertThat(lint).isEmpty() - } - } + assertThat(lint).isEmpty() + } + } - describe("testcase for reported false positives") { + describe("testcase for reported false positives") { - it("does not crash when using wildcasts in generics - #1345") { - val code = """ + it("does not crash when using wildcasts in generics - #1345") { + val code = """ private class Foo fun bar(clazz: KClass<*>) = Unit """.trimIndent() - val findings = UnusedPrivateClass().lint(code) + val findings = UnusedPrivateClass().lint(code) - assertThat(findings).hasSize(1) - } + assertThat(findings).hasSize(1) + } - it("does not report (companion-)object/named-dot references - #1347") { - val code = """ + it("does not report (companion-)object/named-dot references - #1347") { + val code = """ package com.example class Test { @@ -274,13 +274,13 @@ class UnusedPrivateClassSpec : SubjectSpek({ } """.trimIndent() - val findings = UnusedPrivateClass().lint(code) + val findings = UnusedPrivateClass().lint(code) - assertThat(findings).isEmpty() - } + assertThat(findings).isEmpty() + } - it("does not report classes that are used with ::class - #1390") { - val code = """ + it("does not report classes that are used with ::class - #1390") { + val code = """ class UnusedPrivateClassTest { private data class SomeClass(val name: String) @@ -295,9 +295,9 @@ class UnusedPrivateClassSpec : SubjectSpek({ } """.trimIndent() - val findings = UnusedPrivateClass().lint(code) + val findings = UnusedPrivateClass().lint(code) - assertThat(findings).isEmpty() - } - } + assertThat(findings).isEmpty() + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateMemberSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateMemberSpec.kt index ee6121a64..9b9cbdd6a 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateMemberSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateMemberSpec.kt @@ -3,18 +3,18 @@ package io.gitlab.arturbosch.detekt.rules.style import io.gitlab.arturbosch.detekt.rules.Case import io.gitlab.arturbosch.detekt.test.TestConfig import io.gitlab.arturbosch.detekt.test.lint +import java.util.regex.PatternSyntaxException import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThatExceptionOfType import org.jetbrains.spek.api.dsl.given import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek -import java.util.regex.PatternSyntaxException class UnusedPrivateMemberSpec : SubjectSpek({ - subject { UnusedPrivateMember() } + subject { UnusedPrivateMember() } - val regexTestingCode = """ + val regexTestingCode = """ class Test { private val used = "This is used" private val unused = "This is not used" @@ -25,42 +25,42 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } """ - given("cases file with different findings") { + given("cases file with different findings") { - it("positive cases file") { - assertThat(subject.lint(Case.UnusedPrivateMemberPositive.path())).hasSize(13) - } + it("positive cases file") { + assertThat(subject.lint(Case.UnusedPrivateMemberPositive.path())).hasSize(13) + } - it("negative cases file") { - assertThat(subject.lint(Case.UnusedPrivateMemberNegative.path())).isEmpty() - } - } + it("negative cases file") { + assertThat(subject.lint(Case.UnusedPrivateMemberNegative.path())).isEmpty() + } + } - given("interface functions") { + given("interface functions") { - it("should not report parameters in interface functions") { - val code = """ + it("should not report parameters in interface functions") { + val code = """ interface UserPlugin { fun plug(application: Application) fun unplug() } """ - assertThat(subject.lint(code)).isEmpty() - } - } + assertThat(subject.lint(code)).isEmpty() + } + } - given("external functions") { + given("external functions") { - it("should not report parameters in external functions") { - val code = "external fun foo(bar: String)" - assertThat(subject.lint(code)).isEmpty() - } - } + it("should not report parameters in external functions") { + val code = "external fun foo(bar: String)" + assertThat(subject.lint(code)).isEmpty() + } + } - given("overridden functions") { + given("overridden functions") { - it("should not report parameters in not private functions") { - val code = """ + it("should not report parameters in not private functions") { + val code = """ override fun funA() { objectA.resolve(valA, object : MyCallback { override fun onResolveFailed(throwable: Throwable) { @@ -69,14 +69,14 @@ class UnusedPrivateMemberSpec : SubjectSpek({ }) } """ - assertThat(subject.lint(code)).isEmpty() - } - } + assertThat(subject.lint(code)).isEmpty() + } + } - given("classes accessing constants from companion objects") { + given("classes accessing constants from companion objects") { - it("should not report used constants") { - val code = """ + it("should not report used constants") { + val code = """ class A { companion object { private const val MY_CONST = 42 @@ -88,14 +88,14 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } } """ - assertThat(subject.lint(code)).isEmpty() - } - } + assertThat(subject.lint(code)).isEmpty() + } + } - given("several classes with properties") { + given("several classes with properties") { - it("reports an unused member") { - val code = """ + it("reports an unused member") { + val code = """ class Test { private val unused = "This is not used" @@ -104,11 +104,11 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } } """ - assertThat(subject.lint(code)).hasSize(1) - } + assertThat(subject.lint(code)).hasSize(1) + } - it("does not report unused public members") { - val code = """ + it("does not report unused public members") { + val code = """ class Test { val unused = "This is not used" @@ -117,11 +117,11 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } } """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("does not report used members") { - val code = """ + it("does not report used members") { + val code = """ class Test { private val used = "This is used" @@ -130,11 +130,11 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } } """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("does not report used members but reports unused members") { - val code = """ + it("does not report used members but reports unused members") { + val code = """ class Test { private val used = "This is used" private val unused = "This is not used" @@ -144,30 +144,30 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } } """ - assertThat(subject.lint(code)).hasSize(1) - } + assertThat(subject.lint(code)).hasSize(1) + } - it("does not fail when disabled with invalid regex") { - val configRules = mapOf( - "active" to "false", - UnusedPrivateMember.ALLOWED_NAMES_PATTERN to "*foo" - ) - val config = TestConfig(configRules) - assertThat(UnusedPrivateMember(config).lint(regexTestingCode)).isEmpty() - } + it("does not fail when disabled with invalid regex") { + val configRules = mapOf( + "active" to "false", + UnusedPrivateMember.ALLOWED_NAMES_PATTERN to "*foo" + ) + val config = TestConfig(configRules) + assertThat(UnusedPrivateMember(config).lint(regexTestingCode)).isEmpty() + } - it("does fail when enabled with invalid regex") { - val configRules = mapOf(UnusedPrivateMember.ALLOWED_NAMES_PATTERN to "*foo") - val config = TestConfig(configRules) - assertThatExceptionOfType(PatternSyntaxException::class.java) - .isThrownBy { UnusedPrivateMember(config).lint(regexTestingCode) } - } - } + it("does fail when enabled with invalid regex") { + val configRules = mapOf(UnusedPrivateMember.ALLOWED_NAMES_PATTERN to "*foo") + val config = TestConfig(configRules) + assertThatExceptionOfType(PatternSyntaxException::class.java) + .isThrownBy { UnusedPrivateMember(config).lint(regexTestingCode) } + } + } - given("several classes with properties and local properties") { + given("several classes with properties and local properties") { - it("reports an unused member") { - val code = """ + it("reports an unused member") { + val code = """ class Test { private val unused = "This is not used" @@ -177,11 +177,11 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } } """ - assertThat(subject.lint(code)).hasSize(1) - } + assertThat(subject.lint(code)).hasSize(1) + } - it("does not report used members") { - val code = """ + it("does not report used members") { + val code = """ class Test { private val used = "This is used" @@ -191,11 +191,11 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } } """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("reports unused local properties") { - val code = """ + it("reports unused local properties") { + val code = """ class Test { private val used = "This is used" @@ -205,24 +205,24 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } } """ - assertThat(subject.lint(code)).hasSize(1) - } - } + assertThat(subject.lint(code)).hasSize(1) + } + } - given("loop iterators") { + given("loop iterators") { - it("should not depend on evaluation order of functions or properties") { - val code = """ + it("should not depend on evaluation order of functions or properties") { + val code = """ fun RuleSetProvider.provided() = ruleSetId in defaultRuleSetIds val defaultRuleSetIds = listOf("comments", "complexity", "empty-blocks", "exceptions", "potential-bugs", "performance", "style") """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("doesn't report loop properties") { - val code = """ + it("doesn't report loop properties") { + val code = """ class Test { fun use() { for (i in 0 until 10) { @@ -231,11 +231,11 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } } """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("reports unused loop property") { - val code = """ + it("reports unused loop property") { + val code = """ class Test { fun use() { for (i in 0 until 10) { @@ -243,11 +243,11 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } } """ - assertThat(subject.lint(code)).hasSize(1) - } + assertThat(subject.lint(code)).hasSize(1) + } - it("reports unused loop property in indexed array") { - val code = """ + it("reports unused loop property in indexed array") { + val code = """ class Test { fun use() { val array = intArrayOf(1, 2, 3) @@ -257,11 +257,11 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } } """ - assertThat(subject.lint(code)).hasSize(1) - } + assertThat(subject.lint(code)).hasSize(1) + } - it("reports all unused loop properties in indexed array") { - val code = """ + it("reports all unused loop properties in indexed array") { + val code = """ class Test { fun use() { val array = intArrayOf(1, 2, 3) @@ -270,11 +270,11 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } } """ - assertThat(subject.lint(code)).hasSize(2) - } + assertThat(subject.lint(code)).hasSize(2) + } - it("does not report used loop properties in indexed array") { - val code = """ + it("does not report used loop properties in indexed array") { + val code = """ class Test { fun use() { val array = intArrayOf(1, 2, 3) @@ -285,14 +285,14 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } } """ - assertThat(subject.lint(code)).isEmpty() - } - } + assertThat(subject.lint(code)).isEmpty() + } + } - given("properties used to initialize other properties") { + given("properties used to initialize other properties") { - it("does not report properties used by other properties") { - val code = """ + it("does not report properties used by other properties") { + val code = """ class Test { private val used = "This is used" private val text = used @@ -302,11 +302,11 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } } """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("does not report properties used by inner classes") { - val code = """ + it("does not report properties used by inner classes") { + val code = """ class Test { private val unused = "This is not used" @@ -315,13 +315,13 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } } """ - assertThat(subject.lint(code)).isEmpty() - } - } + assertThat(subject.lint(code)).isEmpty() + } + } - given("function parameters") { - it("reports single parameters if they are unused") { - val code = """ + given("function parameters") { + it("reports single parameters if they are unused") { + val code = """ class Test { val value = usedMethod(1) @@ -331,11 +331,11 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } """ - assertThat(subject.lint(code)).hasSize(1) - } + assertThat(subject.lint(code)).hasSize(1) + } - it("does not report single parameters if they used in return statement") { - val code = """ + it("does not report single parameters if they used in return statement") { + val code = """ class Test { val value = usedMethod(1) @@ -345,11 +345,11 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("does not report single parameters if they used in function") { - val code = """ + it("does not report single parameters if they used in function") { + val code = """ class Test { val value = usedMethod(1) @@ -359,11 +359,11 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("reports parameters that are unused in return statement") { - val code = """ + it("reports parameters that are unused in return statement") { + val code = """ class Test { val value = usedMethod(1, 2) @@ -373,11 +373,11 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } """ - assertThat(subject.lint(code)).hasSize(1) - } + assertThat(subject.lint(code)).hasSize(1) + } - it("reports parameters that are unused in function") { - val code = """ + it("reports parameters that are unused in function") { + val code = """ class Test { val value = usedMethod(1, 2) @@ -387,65 +387,65 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } """ - assertThat(subject.lint(code)).hasSize(1) - } - } + assertThat(subject.lint(code)).hasSize(1) + } + } - given("top level function parameters") { - it("reports single parameters if they are unused") { - val code = """ + given("top level function parameters") { + it("reports single parameters if they are unused") { + val code = """ fun function(unusedParameter: Int): Int { return 5 } """ - assertThat(subject.lint(code)).hasSize(1) - } + assertThat(subject.lint(code)).hasSize(1) + } - it("does not report single parameters if they used in return statement") { - val code = """ + it("does not report single parameters if they used in return statement") { + val code = """ fun function(used: Int): Int { return used } """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("does not report single parameters if they used in function") { - val code = """ + it("does not report single parameters if they used in function") { + val code = """ fun function(used: Int) { println(used) } """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("reports parameters that are unused in return statement") { - val code = """ + it("reports parameters that are unused in return statement") { + val code = """ fun function(unusedParameter: Int, usedParameter: Int): Int { return usedParameter } """ - assertThat(subject.lint(code)).hasSize(1) - } + assertThat(subject.lint(code)).hasSize(1) + } - it("reports parameters that are unused in function") { - val code = """ + it("reports parameters that are unused in function") { + val code = """ fun function(unusedParameter: Int, usedParameter: Int) { println(usedParameter) } """ - assertThat(subject.lint(code)).hasSize(1) - } - } + assertThat(subject.lint(code)).hasSize(1) + } + } - given("unused private functions") { - it("does not report used private functions") { - val code = """ + given("unused private functions") { + it("does not report used private functions") { + val code = """ class Test { val value = usedMethod() @@ -455,11 +455,11 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("reports unused private functions") { - val code = """ + it("reports unused private functions") { + val code = """ class Test { private fun unusedFunction(): Int { return 5 @@ -467,14 +467,14 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } """ - assertThat(subject.lint(code)).hasSize(1) - } - } + assertThat(subject.lint(code)).hasSize(1) + } + } - given("private functions only used by unused private functions") { + given("private functions only used by unused private functions") { - it("reports the non called private function") { - val code = """ + it("reports the non called private function") { + val code = """ class Test { private fun unusedFunction(): Int { return someOtherUnusedFunction() @@ -486,147 +486,147 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } """ - assertThat(subject.lint(code)).hasSize(1) - } - } + assertThat(subject.lint(code)).hasSize(1) + } + } - given("unused class declarations which are allowed") { + given("unused class declarations which are allowed") { - it("does not report the unused private property") { - val code = """ + it("does not report the unused private property") { + val code = """ class Test { private val ignored = "" }""" - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("does not report the unused private function and parameter") { - val code = """ + it("does not report the unused private function and parameter") { + val code = """ class Test { private fun ignored(ignored: Int) {} }""" - assertThat(subject.lint(code)).isEmpty() - } - } + assertThat(subject.lint(code)).isEmpty() + } + } - given("nested class declarations") { + given("nested class declarations") { - it("reports unused nested private property") { - val code = """ + it("reports unused nested private property") { + val code = """ class Test { class Inner { private val unused = 1 } }""" - assertThat(subject.lint(code)).hasSize(1) - } + assertThat(subject.lint(code)).hasSize(1) + } - it("does not report used nested private property") { - val code = """ + it("does not report used nested private property") { + val code = """ class Test { class Inner { private val used = 1 fun someFunction() = used } }""" - assertThat(subject.lint(code)).isEmpty() - } - } + assertThat(subject.lint(code)).isEmpty() + } + } - given("parameters in primary constructors") { - it("reports unused private property") { - val code = """ + given("parameters in primary constructors") { + it("reports unused private property") { + val code = """ class Test(private val unused: Any) """ - assertThat(subject.lint(code)).hasSize(1) - } + assertThat(subject.lint(code)).hasSize(1) + } - it("reports unused parameter") { - val code = """ + it("reports unused parameter") { + val code = """ class Test(unused: Any) """ - assertThat(subject.lint(code)).hasSize(1) - } + assertThat(subject.lint(code)).hasSize(1) + } - it("does not report used parameter for calling super") { - val code = """ + it("does not report used parameter for calling super") { + val code = """ class Parent(val ignored: Any) class Test(used: Any) : Parent(used) """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("does not report used parameter in init block") { - val code = """ + it("does not report used parameter in init block") { + val code = """ class Test(used: Any) { init { used.toString() } } """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("does not report used parameter to initialize property") { - val code = """ + it("does not report used parameter to initialize property") { + val code = """ class Test(used: Any) { val usedString = used.toString() } """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("does not report public property") { - val code = """ + it("does not report public property") { + val code = """ class Test(val unused: Any) """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("does not report private property used in init block") { - val code = """ + it("does not report private property used in init block") { + val code = """ class Test(private val used: Any) { init { used.toString() } } """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("does not report private property used in function") { - val code = """ + it("does not report private property used in function") { + val code = """ class Test(private val used: Any) { fun something() { used.toString() } } """ - assertThat(subject.lint(code)).isEmpty() - } - } + assertThat(subject.lint(code)).isEmpty() + } + } - given("error messages") { - it("are specific for function parameters") { - val code = """ + given("error messages") { + it("are specific for function parameters") { + val code = """ fun foo(unused: Int){} """ - val lint = subject.lint(code) + val lint = subject.lint(code) - assertThat(lint.first().message).startsWith("Function parameter") - } + assertThat(lint.first().message).startsWith("Function parameter") + } - it("are specific for local variables") { - val code = """ + it("are specific for local variables") { + val code = """ fun foo(){ val unused = 1 } """ - val lint = subject.lint(code) + val lint = subject.lint(code) - assertThat(lint.first().message).startsWith("Private property") - } + assertThat(lint.first().message).startsWith("Private property") + } - it("are specific for private functions") { - val code = """ + it("are specific for private functions") { + val code = """ class Test { private fun unusedFunction(): Int { return 5 @@ -634,43 +634,43 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } """ - val lint = subject.lint(code) + val lint = subject.lint(code) - assertThat(lint.first().message).startsWith("Private function") - } - } + assertThat(lint.first().message).startsWith("Private function") + } + } - given("suppress unused parameter warning annotations") { - it("does not report annotated parameters") { - val code = """ + given("suppress unused parameter warning annotations") { + it("does not report annotated parameters") { + val code = """ fun foo(@Suppress("UNUSED_PARAMETER") unused: String){} """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("reports parameters without annotation") { - val code = """ + it("reports parameters without annotation") { + val code = """ fun foo(@Suppress("UNUSED_PARAMETER") unused: String, unusedWithoutAnnotation: String){} """ - val lint = subject.lint(code) + val lint = subject.lint(code) - assertThat(lint).hasSize(1) - assertThat(lint[0].entity.name).isEqualTo("unusedWithoutAnnotation") - } + assertThat(lint).hasSize(1) + assertThat(lint[0].entity.name).isEqualTo("unusedWithoutAnnotation") + } - it("does not report parameters in annotated function") { - val code = """ + it("does not report parameters in annotated function") { + val code = """ @Suppress("UNUSED_PARAMETER") fun foo(unused: String, otherUnused: String){} """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("does not report parameters in annotated class") { - val code = """ + it("does not report parameters in annotated class") { + val code = """ @Suppress("UNUSED_PARAMETER") class Test { fun foo(unused: String, otherUnused: String){} @@ -678,22 +678,22 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("does not report parameters in annotated object") { - val code = """ + it("does not report parameters in annotated object") { + val code = """ @Suppress("UNUSED_PARAMETER") object Test { fun foo(unused: String){} } """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("does not report parameters in class with annotated outer class") { - val code = """ + it("does not report parameters in class with annotated outer class") { + val code = """ @Suppress("UNUSED_PARAMETER") class Test { fun foo(unused: String){} @@ -704,11 +704,11 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("does not report parameters in annotated file") { - val code = """ + it("does not report parameters in annotated file") { + val code = """ @file:Suppress("UNUSED_PARAMETER") class Test { @@ -720,35 +720,35 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } """ - assertThat(subject.lint(code)).isEmpty() - } - } + assertThat(subject.lint(code)).isEmpty() + } + } - given("suppress unused property warning annotations") { - it("does not report annotated private constructor properties") { - val code = """ + given("suppress unused property warning annotations") { + it("does not report annotated private constructor properties") { + val code = """ class Test(@Suppress("unused") private val foo: String) {} """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("reports private constructor properties without annotation") { - val code = """ + it("reports private constructor properties without annotation") { + val code = """ class Test( @Suppress("unused") private val foo: String, private val bar: String ) {} """ - val lint = subject.lint(code) + val lint = subject.lint(code) - assertThat(lint).hasSize(1) - assertThat(lint[0].entity.name).isEqualTo("bar") - } + assertThat(lint).hasSize(1) + assertThat(lint[0].entity.name).isEqualTo("bar") + } - it("does not report private constructor properties in annotated class") { - val code = """ + it("does not report private constructor properties in annotated class") { + val code = """ @Suppress("unused") class Test( private val foo: String, @@ -756,11 +756,11 @@ class UnusedPrivateMemberSpec : SubjectSpek({ ) {} """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("does not report private constructor properties in class with annotated outer class") { - val code = """ + it("does not report private constructor properties in class with annotated outer class") { + val code = """ @Suppress("unused") class Test( private val foo: String, @@ -772,11 +772,11 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("does not report private constructor properties in annotated file") { - val code = """ + it("does not report private constructor properties in annotated file") { + val code = """ @file:Suppress("unused") class Test( @@ -789,35 +789,35 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("does not report annotated private properties") { - val code = """ + it("does not report annotated private properties") { + val code = """ class Test { @Suppress("unused") private val foo: String } """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("reports private properties without annotation") { - val code = """ + it("reports private properties without annotation") { + val code = """ class Test { @Suppress("unused") private val foo: String private val bar: String } """ - val lint = subject.lint(code) + val lint = subject.lint(code) - assertThat(lint).hasSize(1) - assertThat(lint[0].entity.name).isEqualTo("bar") - } + assertThat(lint).hasSize(1) + assertThat(lint[0].entity.name).isEqualTo("bar") + } - it("does not report private properties in annotated class") { - val code = """ + it("does not report private properties in annotated class") { + val code = """ @Suppress("unused") class Test { private val foo: String @@ -825,11 +825,11 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("does not report private properties in class with annotated outer class") { - val code = """ + it("does not report private properties in class with annotated outer class") { + val code = """ @Suppress("unused") class Test { private val foo: String @@ -841,11 +841,11 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("does not report private properties in annotated file") { - val code = """ + it("does not report private properties in annotated file") { + val code = """ @file:Suppress("unused") class Test { @@ -858,44 +858,44 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } """ - assertThat(subject.lint(code)).isEmpty() - } - } + assertThat(subject.lint(code)).isEmpty() + } + } - given("suppress unused function warning annotations") { - it("does not report annotated private functions") { - val code = """ + given("suppress unused function warning annotations") { + it("does not report annotated private functions") { + val code = """ @Suppress("unused") private fun foo(): String = "" """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("reports private functions without annotation") { - val code = """ + it("reports private functions without annotation") { + val code = """ private fun foo(): String = "" """ - val lint = subject.lint(code) + val lint = subject.lint(code) - assertThat(lint).hasSize(1) - assertThat(lint[0].entity.name).isEqualTo("foo") - } + assertThat(lint).hasSize(1) + assertThat(lint[0].entity.name).isEqualTo("foo") + } - it("does not report private functions in annotated class") { - val code = """ + it("does not report private functions in annotated class") { + val code = """ @Suppress("unused") class Test { private fun foo(): String = "" } """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("does not report private functions in class with annotated outer class") { - val code = """ + it("does not report private functions in class with annotated outer class") { + val code = """ @Suppress("unused") class Test { private fun foo(): String = "" @@ -907,11 +907,11 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("does not report private functions in annotated file") { - val code = """ + it("does not report private functions in annotated file") { + val code = """ @file:Suppress("unused") class Test { private fun foo(): String = "" @@ -923,14 +923,14 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } """ - assertThat(subject.lint(code)).isEmpty() - } - } + assertThat(subject.lint(code)).isEmpty() + } + } - given("main methods") { + given("main methods") { - it("does not report the args parameter of the main function inside an object") { - val code = """ + it("does not report the args parameter of the main function inside an object") { + val code = """ object O { @JvmStatic @@ -939,23 +939,23 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } } """.trimIndent() - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("does not report the args parameter of the main function as top level function") { - val code = """ + it("does not report the args parameter of the main function as top level function") { + val code = """ fun main(args: Array) { println("b") } """.trimIndent() - assertThat(subject.lint(code)).isEmpty() - } - } + assertThat(subject.lint(code)).isEmpty() + } + } - given("operators") { + given("operators") { - it("does not report used plus operator - #1354") { - val code = """ + it("does not report used plus operator - #1354") { + val code = """ import java.util.Date class Foo { val bla: Date = Date(System.currentTimeMillis()) + 300L @@ -964,7 +964,7 @@ class UnusedPrivateMemberSpec : SubjectSpek({ } } """.trimIndent() - assertThat(subject.lint(code)).isEmpty() - } - } + assertThat(subject.lint(code)).isEmpty() + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UseDataClassSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UseDataClassSpec.kt index 84588252a..52aa55b70 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UseDataClassSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UseDataClassSpec.kt @@ -14,37 +14,36 @@ import org.jetbrains.spek.subject.SubjectSpek */ class UseDataClassSpec : SubjectSpek({ - subject { UseDataClass(Config.empty) } + subject { UseDataClass(Config.empty) } - given("several classes") { + given("several classes") { - it("reports potential data classes") { - assertThat(subject.lint(Case.UseDataClassPositive.path())).hasSize(5) - } + it("reports potential data classes") { + assertThat(subject.lint(Case.UseDataClassPositive.path())).hasSize(5) + } - it("does not report invalid data class candidates") { - assertThat(subject.lint(Case.UseDataClassNegative.path())).isEmpty() - } + it("does not report invalid data class candidates") { + assertThat(subject.lint(Case.UseDataClassNegative.path())).isEmpty() + } - it("does not report inline classes") { - assertThat(subject.lint( - """inline class A(val x: Int)""" - )).isEmpty() + it("does not report inline classes") { + assertThat(subject.lint( + """inline class A(val x: Int)""" + )).isEmpty() + } + } - } - } + given("a class with an annotation which is ignored") { - given("a class with an annotation which is ignored") { - - it("does not report a potential data class") { - val code = """ + it("does not report a potential data class") { + val code = """ import kotlin.SinceKotlin @SinceKotlin("1.0.0") class AnnotatedClass(val i: Int) {} """ - val config = TestConfig(mapOf(UseDataClass.EXCLUDE_ANNOTATED_CLASSES to "kotlin.*")) - assertThat(UseDataClass(config).lint(code)).isEmpty() - } - } + val config = TestConfig(mapOf(UseDataClass.EXCLUDE_ANNOTATED_CLASSES to "kotlin.*")) + assertThat(UseDataClass(config).lint(code)).isEmpty() + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UtilityClassWithPublicConstructorSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UtilityClassWithPublicConstructorSpec.kt index 48cf7f9c9..c52ad5081 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UtilityClassWithPublicConstructorSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UtilityClassWithPublicConstructorSpec.kt @@ -10,34 +10,34 @@ import org.jetbrains.spek.subject.SubjectSpek class UtilityClassWithPublicConstructorSpec : SubjectSpek({ - subject { UtilityClassWithPublicConstructor(Config.empty) } + subject { UtilityClassWithPublicConstructor(Config.empty) } - given("several UtilityClassWithPublicConstructor rule violations") { + given("several UtilityClassWithPublicConstructor rule violations") { - val findings = subject.lint(Case.UtilityClassesPositive.path()) + val findings = subject.lint(Case.UtilityClassesPositive.path()) - it("reports utility classes with a public constructor") { - assertThat(findings).hasSize(6) - } + it("reports utility classes with a public constructor") { + assertThat(findings).hasSize(6) + } - it("reports utility classes which are marked as open") { - val count = findings.count { it.message.contains("The utility class OpenUtilityClass should be final.") } - assertThat(count).isEqualTo(1) - } - } + it("reports utility classes which are marked as open") { + val count = findings.count { it.message.contains("The utility class OpenUtilityClass should be final.") } + assertThat(count).isEqualTo(1) + } + } - given("several classes which adhere to the UtilityClassWithPublicConstructor rule") { + given("several classes which adhere to the UtilityClassWithPublicConstructor rule") { - it("does not report given classes") { - val findings = subject.lint(Case.UtilityClassesNegative.path()) - assertThat(findings).isEmpty() - } - } + it("does not report given classes") { + val findings = subject.lint(Case.UtilityClassesNegative.path()) + assertThat(findings).isEmpty() + } + } - given("annotations class") { + given("annotations class") { - it("should not get triggered for utility class") { - val code = """ + it("should not get triggered for utility class") { + val code = """ @Retention(AnnotationRetention.SOURCE) @StringDef( Gender.MALE, @@ -50,7 +50,7 @@ class UtilityClassWithPublicConstructorSpec : SubjectSpek({ - subject { VarCouldBeVal() } + subject { VarCouldBeVal() } - given("local declarations in functions") { + given("local declarations in functions") { - it("does not report variables that are re-assigned") { - val code = """ + it("does not report variables that are re-assigned") { + val code = """ fun test() { var a = 1 a = 2 } """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("does not report variables that are re-assigned with assignment operator") { - val code = """ + it("does not report variables that are re-assigned with assignment operator") { + val code = """ fun test() { var a = 1 a += 2 } """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("does not report variables that are re-assigned with assignment operator") { - val code = """ + it("does not report variables that are re-assigned with assignment operator") { + val code = """ fun test() { var a = 1 a += 2 } """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("does not report variables that are re-assigned with postfix operators") { - val code = """ + it("does not report variables that are re-assigned with postfix operators") { + val code = """ fun test() { var a = 1 a++ } """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("does not report variables that are re-assigned with infix operators") { - val code = """ + it("does not report variables that are re-assigned with infix operators") { + val code = """ fun test() { var a = 1 --a } """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("does not report variables that are re-assigned inside scope functions") { - val code = """ + it("does not report variables that are re-assigned inside scope functions") { + val code = """ fun test() { var a = 1 a.also { @@ -71,41 +71,41 @@ class VarCouldBeValSpec : SubjectSpek({ } } """ - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("reports variables that are not re-assigned, but used in expressions") { - val code = """ + it("reports variables that are not re-assigned, but used in expressions") { + val code = """ fun test() { var a = 1 val b = a + 2 } """ - val lint = subject.lint(code) + val lint = subject.lint(code) - assertThat(lint).hasSize(1) - with(lint[0]) { - assertThat(entity.name).isEqualTo("a") - } - } + assertThat(lint).hasSize(1) + with(lint[0]) { + assertThat(entity.name).isEqualTo("a") + } + } - it("reports variables that are not re-assigned, but used in function calls") { - val code = """ + it("reports variables that are not re-assigned, but used in function calls") { + val code = """ fun test() { var a = 1 something(a) } """ - val lint = subject.lint(code) + val lint = subject.lint(code) - assertThat(lint).hasSize(1) - with(lint[0]) { - assertThat(entity.name).isEqualTo("a") - } - } + assertThat(lint).hasSize(1) + with(lint[0]) { + assertThat(entity.name).isEqualTo("a") + } + } - it("reports variables that are not re-assigned, but shadowed by one that is") { - val code = """ + it("reports variables that are not re-assigned, but shadowed by one that is") { + val code = """ fun test() { var shadowed = 1 fun nestedFunction() { @@ -114,19 +114,19 @@ class VarCouldBeValSpec : SubjectSpek({ } } """ - val lint = subject.lint(code) + val lint = subject.lint(code) - assertThat(lint).hasSize(1) - with(lint[0].entity) { - assertThat(ktElement?.text).isEqualTo("var shadowed = 1") - } - } - } + assertThat(lint).hasSize(1) + with(lint[0].entity) { + assertThat(ktElement?.text).isEqualTo("var shadowed = 1") + } + } + } - given("this-prefixed properties - #1257") { + given("this-prefixed properties - #1257") { - it("finds unused field and local") { - val code = """ + it("finds unused field and local") { + val code = """ fun createObject() = object { private var myVar: String? = null fun assign(value: String?) { @@ -134,11 +134,11 @@ class VarCouldBeValSpec : SubjectSpek({ } } """.trimIndent() - assertThat(subject.lint(code)).hasSize(2) - } + assertThat(subject.lint(code)).hasSize(2) + } - it("should not report this-prefixed property") { - val code = """ + it("should not report this-prefixed property") { + val code = """ fun createObject() = object { private var myVar: String? = null fun assign(value: String?) { @@ -146,11 +146,11 @@ class VarCouldBeValSpec : SubjectSpek({ } } """.trimIndent() - assertThat(subject.lint(code)).isEmpty() - } + assertThat(subject.lint(code)).isEmpty() + } - it("should report unused local variable") { - val code = """ + it("should report unused local variable") { + val code = """ fun createObject() = object { private var myVar: String? = null fun assign(value: String?) { @@ -159,11 +159,11 @@ class VarCouldBeValSpec : SubjectSpek({ } } """.trimIndent() - with(subject.lint(code)[0]) { - // we accept wrong entity reporting here due to no symbol solving - // false reporting with shadowed vars vs false positives - assertThat(entity.ktElement?.text).isEqualTo("private var myVar: String? = null") - } - } - } + with(subject.lint(code)[0]) { + // we accept wrong entity reporting here due to no symbol solving + // false reporting with shadowed vars vs false positives + assertThat(entity.ktElement?.text).isEqualTo("private var myVar: String? = null") + } + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/WildcardImportSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/WildcardImportSpec.kt index 12a0183cc..cad6d5156 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/WildcardImportSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/WildcardImportSpec.kt @@ -10,8 +10,8 @@ import org.jetbrains.spek.api.dsl.it class WildcardImportSpec : Spek({ - given("a kt file with wildcard imports") { - val code = """ + given("a kt file with wildcard imports") { + val code = """ package test import io.gitlab.arturbosch.detekt.* @@ -21,46 +21,46 @@ class WildcardImportSpec : Spek({ } """ - val file = compileContentForTest(code).text + val file = compileContentForTest(code).text - it("should not report anything when the rule is turned off") { - val rule = WildcardImport(TestConfig(mapOf("active" to "false"))) + it("should not report anything when the rule is turned off") { + val rule = WildcardImport(TestConfig(mapOf("active" to "false"))) - val findings = rule.lint(file) - assertThat(findings).isEmpty() - } + val findings = rule.lint(file) + assertThat(findings).isEmpty() + } - it("should report all wildcard imports") { - val rule = WildcardImport() + it("should report all wildcard imports") { + val rule = WildcardImport() - val findings = rule.lint(file) - assertThat(findings).hasSize(2) - } + val findings = rule.lint(file) + assertThat(findings).hasSize(2) + } - it("should not report excluded wildcard imports") { - val rule = WildcardImport(TestConfig(mapOf("excludeImports" to "test.test.*"))) + it("should not report excluded wildcard imports") { + val rule = WildcardImport(TestConfig(mapOf("excludeImports" to "test.test.*"))) - val findings = rule.lint(file) - assertThat(findings).hasSize(1) - } + val findings = rule.lint(file) + assertThat(findings).hasSize(1) + } - it("should not report excluded wildcard imports when multiple are excluded") { - val rule = WildcardImport(TestConfig(mapOf("excludeImports" to "test.test.*, io.gitlab.arturbosch.detekt"))) + it("should not report excluded wildcard imports when multiple are excluded") { + val rule = WildcardImport(TestConfig(mapOf("excludeImports" to "test.test.*, io.gitlab.arturbosch.detekt"))) - val findings = rule.lint(file) - assertThat(findings).isEmpty() - } + val findings = rule.lint(file) + assertThat(findings).isEmpty() + } - it("ignores excludes that are not matching") { - val rule = WildcardImport(TestConfig(mapOf("excludeImports" to "other.test.*"))) + it("ignores excludes that are not matching") { + val rule = WildcardImport(TestConfig(mapOf("excludeImports" to "other.test.*"))) - val findings = rule.lint(file) - assertThat(findings).hasSize(2) - } - } + val findings = rule.lint(file) + assertThat(findings).hasSize(2) + } + } - given("a kt file with no wildcard imports") { - val code = """ + given("a kt file with no wildcard imports") { + val code = """ package test import test.Test @@ -69,9 +69,9 @@ class WildcardImportSpec : Spek({ } """ - it("should not report any issues") { - val findings = WildcardImport().lint(code) - assertThat(findings).isEmpty() - } - } + it("should not report any issues") { + val findings = WildcardImport().lint(code) + assertThat(findings).isEmpty() + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/optional/ConditionalPathVisitorTest.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/optional/ConditionalPathVisitorTest.kt index 1944dbcf5..34a93eb7f 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/optional/ConditionalPathVisitorTest.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/optional/ConditionalPathVisitorTest.kt @@ -11,17 +11,17 @@ import org.jetbrains.spek.api.dsl.it */ class ConditionalPathVisitorTest : Spek({ - it("pathCount") { - var counter = 0 + it("pathCount") { + var counter = 0 - val visitor = ConditionalPathVisitor { - counter++ - } + val visitor = ConditionalPathVisitor { + counter++ + } - val ktFile = compileForTest(Case.ConditionalPath.path()) + val ktFile = compileForTest(Case.ConditionalPath.path()) - ktFile.accept(visitor) + ktFile.accept(visitor) - assertThat(counter).isEqualTo(5) - } + assertThat(counter).isEqualTo(5) + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/optional/MandatoryBracesIfStatementsSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/optional/MandatoryBracesIfStatementsSpec.kt index 11bbad556..2ec56b0a4 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/optional/MandatoryBracesIfStatementsSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/optional/MandatoryBracesIfStatementsSpec.kt @@ -9,18 +9,18 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class MandatoryBracesIfStatementsSpec : SubjectSpek({ - subject { MandatoryBracesIfStatements(Config.empty) } + subject { MandatoryBracesIfStatements(Config.empty) } - given("if statements") { + given("if statements") { - it("reports multi-line if statements should have braces") { - val path = Case.MandatoryBracesIfStatementsPositive.path() - assertThat(subject.lint(path)).hasSize(7) - } + it("reports multi-line if statements should have braces") { + val path = Case.MandatoryBracesIfStatementsPositive.path() + assertThat(subject.lint(path)).hasSize(7) + } - it("reports non multi-line if statements should have braces") { - val path = Case.MandatoryBracesIfStatementsNegative.path() - assertThat(subject.lint(path)).hasSize(0) - } - } + it("reports non multi-line if statements should have braces") { + val path = Case.MandatoryBracesIfStatementsNegative.path() + assertThat(subject.lint(path)).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/optional/OptionalUnitSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/optional/OptionalUnitSpec.kt index f666000c8..65d1754b1 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/optional/OptionalUnitSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/optional/OptionalUnitSpec.kt @@ -11,11 +11,11 @@ import org.jetbrains.spek.subject.SubjectSpek * @author Artur Bosch */ class OptionalUnitSpec : SubjectSpek({ - subject { OptionalUnit(Config.empty) } + subject { OptionalUnit(Config.empty) } - given("several functions which return Unit") { + given("several functions which return Unit") { - val code = """ + val code = """ fun returnsUnit1(): Unit { fun returnsUnitNested(): Unit { return Unit @@ -25,32 +25,32 @@ class OptionalUnitSpec : SubjectSpek({ fun returnsUnit2() = Unit """ - val findings = subject.lint(code) + val findings = subject.lint(code) - it("should report functions returning Unit") { - assertThat(findings).hasSize(3) - } + it("should report functions returning Unit") { + assertThat(findings).hasSize(3) + } - it("should report the correct violation message") { - findings.forEach { - assertThat(it.message).endsWith( - " defines a return type of Unit. This is unnecessary and can safely be removed.") - } - } - } + it("should report the correct violation message") { + findings.forEach { + assertThat(it.message).endsWith( + " defines a return type of Unit. This is unnecessary and can safely be removed.") + } + } + } - given("an overridden function which returns Unit") { + given("an overridden function which returns Unit") { - it("should not report Unit return type in overridden function") { - val code = "override fun returnsUnit2() = Unit" - val findings = subject.lint(code) - assertThat(findings).isEmpty() - } - } + it("should not report Unit return type in overridden function") { + val code = "override fun returnsUnit2() = Unit" + val findings = subject.lint(code) + assertThat(findings).isEmpty() + } + } - given("several lone Unit statements") { + given("several lone Unit statements") { - val code = """ + val code = """ fun returnsNothing() { Unit val i: (Int) -> Unit = { _ -> Unit } @@ -65,23 +65,23 @@ class OptionalUnitSpec : SubjectSpek({ } } """ - val findings = subject.lint(code) + val findings = subject.lint(code) - it("should report lone Unit statement") { - assertThat(findings).hasSize(4) - } + it("should report lone Unit statement") { + assertThat(findings).hasSize(4) + } - it("should report the correct violation message") { - findings.forEach { - assertThat(it.message).isEqualTo("A single Unit expression is unnecessary and can safely be removed") - } - } - } + it("should report the correct violation message") { + findings.forEach { + assertThat(it.message).isEqualTo("A single Unit expression is unnecessary and can safely be removed") + } + } + } - given("several Unit references") { + given("several Unit references") { - it("should not report Unit reference") { - val findings = subject.lint(""" + it("should not report Unit reference") { + val findings = subject.lint(""" fun returnsNothing(u: Unit, us: () -> String) { val u1 = u is Unit val u2: Unit = Unit @@ -90,19 +90,19 @@ class OptionalUnitSpec : SubjectSpek({ val i: (Int) -> Unit = { _ -> } } """) - assertThat(findings).isEmpty() - } - } + assertThat(findings).isEmpty() + } + } - given("a default interface implementation") { - it("should not report Unit as part of default interface implementations") { - val code = """ + given("a default interface implementation") { + it("should not report Unit as part of default interface implementations") { + val code = """ interface Foo { fun onMapClicked(point: Point?) = Unit } """ - val findings = subject.lint(code) - assertThat(findings).isEmpty() - } - } + val findings = subject.lint(code) + assertThat(findings).isEmpty() + } + } }) diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/optional/PreferToOverPairSyntaxSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/optional/PreferToOverPairSyntaxSpec.kt index d46e3d78a..01335446d 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/optional/PreferToOverPairSyntaxSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/optional/PreferToOverPairSyntaxSpec.kt @@ -9,18 +9,18 @@ import org.jetbrains.spek.api.dsl.it import org.jetbrains.spek.subject.SubjectSpek class PreferToOverPairSyntaxSpec : SubjectSpek({ - subject { PreferToOverPairSyntax(Config.empty) } + subject { PreferToOverPairSyntax(Config.empty) } - given("pair objects") { + given("pair objects") { - it("reports if pair is created using pair constructor") { - val path = Case.PreferToOverPairSyntaxPositive.path() - Assertions.assertThat(subject.lint(path)).hasSize(5) - } + it("reports if pair is created using pair constructor") { + val path = Case.PreferToOverPairSyntaxPositive.path() + Assertions.assertThat(subject.lint(path)).hasSize(5) + } - it("does not report if it is created using the to syntax ") { - val path = Case.PreferToOverPairSyntaxNegative.path() - Assertions.assertThat(subject.lint(path)).hasSize(0) - } - } + it("does not report if it is created using the to syntax ") { + val path = Case.PreferToOverPairSyntaxNegative.path() + Assertions.assertThat(subject.lint(path)).hasSize(0) + } + } }) diff --git a/detekt-rules/src/test/resources/SuppressStringLiteralDuplication.kt b/detekt-rules/src/test/resources/SuppressStringLiteralDuplication.kt index 80a362449..50397d75b 100644 --- a/detekt-rules/src/test/resources/SuppressStringLiteralDuplication.kt +++ b/detekt-rules/src/test/resources/SuppressStringLiteralDuplication.kt @@ -2,8 +2,8 @@ @Suppress("StringLiteralDuplication") class Duplication { - var s1 = "lorem" - fun f(s: String = "lorem") { - s1 == "lorem" - } + var s1 = "lorem" + fun f(s: String = "lorem") { + s1 == "lorem" + } } diff --git a/detekt-rules/src/test/resources/SuppressedByElementAnnotation.kt b/detekt-rules/src/test/resources/SuppressedByElementAnnotation.kt index b6b7c23d3..c6d944781 100644 --- a/detekt-rules/src/test/resources/SuppressedByElementAnnotation.kt +++ b/detekt-rules/src/test/resources/SuppressedByElementAnnotation.kt @@ -6,48 +6,48 @@ @SuppressWarnings("LongParameterList") fun lpl(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) = (a + b + c + d + e + f).apply { - assert(false) { "FAILED TEST" } + assert(false) { "FAILED TEST" } } @SuppressWarnings("ComplexCondition") class SuppressedElements { - @SuppressWarnings("LongParameterList") - fun lpl(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) = (a + b + c + d + e + f).apply { - assert(false) { "FAILED TEST" } - } + @SuppressWarnings("LongParameterList") + fun lpl(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) = (a + b + c + d + e + f).apply { + assert(false) { "FAILED TEST" } + } - @SuppressWarnings("ComplexCondition") - fun cc() { - if (this is SuppressedElements && this !is Any && this is Nothing && this is SuppressedElements) { - assert(false) { "FAIL" } - } - } + @SuppressWarnings("ComplexCondition") + fun cc() { + if (this is SuppressedElements && this !is Any && this is Nothing && this is SuppressedElements) { + assert(false) { "FAIL" } + } + } - @SuppressWarnings("LongMethod") - fun lm() { - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - assert(false) { "FAILED TEST" } - } + @SuppressWarnings("LongMethod") + fun lm() { + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + assert(false) { "FAILED TEST" } + } } diff --git a/detekt-rules/src/test/resources/SuppressedElementsByClassAnnotation.kt b/detekt-rules/src/test/resources/SuppressedElementsByClassAnnotation.kt index 1c79500a5..bf60efc31 100644 --- a/detekt-rules/src/test/resources/SuppressedElementsByClassAnnotation.kt +++ b/detekt-rules/src/test/resources/SuppressedElementsByClassAnnotation.kt @@ -4,39 +4,39 @@ @Suppress("unused", "LongMethod", "LongParameterList", "ComplexCondition", "TooManyFunctions") class SuppressedElements3 { - fun lpl(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) = (a + b + c + d + e + f).apply { - assert(false) { "FAILED TEST" } - } + fun lpl(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) = (a + b + c + d + e + f).apply { + assert(false) { "FAILED TEST" } + } - fun cc() { - if (this is SuppressedElements3 && this !is Any && this is Nothing && this is SuppressedElements3) { - assert(false) { "FAIL" } - } - } + fun cc() { + if (this is SuppressedElements3 && this !is Any && this is Nothing && this is SuppressedElements3) { + assert(false) { "FAIL" } + } + } - fun lm() { - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - assert(false) { "FAILED TEST" } - } + fun lm() { + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + assert(false) { "FAILED TEST" } + } } diff --git a/detekt-rules/src/test/resources/SuppressedElementsByFileAnnotation.kt b/detekt-rules/src/test/resources/SuppressedElementsByFileAnnotation.kt index 57385ab85..e68ca9278 100644 --- a/detekt-rules/src/test/resources/SuppressedElementsByFileAnnotation.kt +++ b/detekt-rules/src/test/resources/SuppressedElementsByFileAnnotation.kt @@ -5,44 +5,44 @@ */ fun lpl2(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) = (a + b + c + d + e + f).apply { - assert(false) { "FAILED TEST" } + assert(false) { "FAILED TEST" } } class SuppressedElements2 { - fun lpl(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) = (a + b + c + d + e + f).apply { - assert(false) { "FAILED TEST" } - } + fun lpl(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) = (a + b + c + d + e + f).apply { + assert(false) { "FAILED TEST" } + } - fun cc() { - if (this is SuppressedElements2 && this !is Any && this is Nothing && this is SuppressedElements2) { - assert(false) { "FAIL" } - } - } + fun cc() { + if (this is SuppressedElements2 && this !is Any && this is Nothing && this is SuppressedElements2) { + assert(false) { "FAIL" } + } + } - fun lm() { - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - lpl(1, 2, 3, 4, 5, 6) - assert(false) { "FAILED TEST" } - } + fun lm() { + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + lpl(1, 2, 3, 4, 5, 6) + assert(false) { "FAILED TEST" } + } } diff --git a/detekt-rules/src/test/resources/cases/CollapsibleIfsNegative.kt b/detekt-rules/src/test/resources/cases/CollapsibleIfsNegative.kt index e22eef035..ee9d1869f 100644 --- a/detekt-rules/src/test/resources/cases/CollapsibleIfsNegative.kt +++ b/detekt-rules/src/test/resources/cases/CollapsibleIfsNegative.kt @@ -3,33 +3,40 @@ package cases @Suppress("unused", "ConstantConditionIf", "SimplifyBooleanWithConstants", "RedundantSemicolon") fun collapsibleIfsNegative() { - if (true) {} - else if (1 == 1) { - if (true) {} - } + if (true) { + } else if (1 == 1) { + if (true) { + } + } - if (true) { - if (1 == 1) {} - } else {} + if (true) { + if (1 == 1) { + } + } else { + } - if (true) { - if (1 == 1) {} - } else if (false) {} - else {} + if (true) { + if (1 == 1) { + } + } else if (false) { + } else { + } - if (true) { - if (1 == 1) ; - println() - } + if (true) { + if (1 == 1); + println() + } - if (true) { - if (1 == 1) { - } else {} - } + if (true) { + if (1 == 1) { + } else { + } + } - if (true) { - if (1 == 1) { - } else if (2 == 2) {} - } + if (true) { + if (1 == 1) { + } else if (2 == 2) { + } + } } diff --git a/detekt-rules/src/test/resources/cases/CollapsibleIfsPositive.kt b/detekt-rules/src/test/resources/cases/CollapsibleIfsPositive.kt index 7d66f053e..7e2440573 100644 --- a/detekt-rules/src/test/resources/cases/CollapsibleIfsPositive.kt +++ b/detekt-rules/src/test/resources/cases/CollapsibleIfsPositive.kt @@ -3,15 +3,17 @@ package cases @Suppress("unused", "ConstantConditionIf", "SimplifyBooleanWithConstants") fun collapsibleIfsPositive() { - if (true) { // reports 1 - if statements could be merged - if (1 == 1) {} - // a comment - } + if (true) { // reports 1 - if statements could be merged + if (1 == 1) { + } + // a comment + } - if (true) { - if (1 == 1) { // reports 1 - if statements could be merged - if (2 == 2) {} - } - println() - } + if (true) { + if (1 == 1) { // reports 1 - if statements could be merged + if (2 == 2) { + } + } + println() + } } diff --git a/detekt-rules/src/test/resources/cases/ComplexClass.kt b/detekt-rules/src/test/resources/cases/ComplexClass.kt index 26520c663..3ad9ca9de 100644 --- a/detekt-rules/src/test/resources/cases/ComplexClass.kt +++ b/detekt-rules/src/test/resources/cases/ComplexClass.kt @@ -5,45 +5,45 @@ package cases */ @Suppress("unused", "ConstantConditionIf") fun complex() { //20 - try {//5 - while (true) { - if (true) { - when ("string") { - "" -> println() - else -> println() - } - } - } - } catch (ex: Exception) { //1 + 5 - try { - println() - } catch (ex: Exception) { - while (true) { - if (false) { - println() - } else { - println() - } - } - } - } finally { // 6 - try { - println() - } catch (ex: Exception) { - while (true) { - if (false) { - println() - } else { - println() - } - } - } - } - (1..10).forEach { - //1 - println() - } - for (i in 1..10) { //1 - println() - } + try {//5 + while (true) { + if (true) { + when ("string") { + "" -> println() + else -> println() + } + } + } + } catch (ex: Exception) { //1 + 5 + try { + println() + } catch (ex: Exception) { + while (true) { + if (false) { + println() + } else { + println() + } + } + } + } finally { // 6 + try { + println() + } catch (ex: Exception) { + while (true) { + if (false) { + println() + } else { + println() + } + } + } + } + (1..10).forEach { + //1 + println() + } + for (i in 1..10) { //1 + println() + } } diff --git a/detekt-rules/src/test/resources/cases/ComplexInterfaceNegative.kt b/detekt-rules/src/test/resources/cases/ComplexInterfaceNegative.kt index fc5be6b7a..9f85af801 100644 --- a/detekt-rules/src/test/resources/cases/ComplexInterfaceNegative.kt +++ b/detekt-rules/src/test/resources/cases/ComplexInterfaceNegative.kt @@ -3,21 +3,22 @@ package cases interface InterfaceOk1 { - fun f1() - fun fImpl() { - val x = 0 // should not report - } - val i1: Int - // a comment shouldn't be detected + fun f1() + fun fImpl() { + val x = 0 // should not report + } + + val i1: Int + // a comment shouldn't be detected } interface InterfaceOk2 { - fun f1() + fun f1() - companion object { - fun sf() = 0 - const val c = 0 - } + companion object { + fun sf() = 0 + const val c = 0 + } } interface EmptyInterface diff --git a/detekt-rules/src/test/resources/cases/ComplexInterfacePositive.kt b/detekt-rules/src/test/resources/cases/ComplexInterfacePositive.kt index be74b5bf7..d4e1092be 100644 --- a/detekt-rules/src/test/resources/cases/ComplexInterfacePositive.kt +++ b/detekt-rules/src/test/resources/cases/ComplexInterfacePositive.kt @@ -4,30 +4,30 @@ package cases // reports 1 - too many members interface TooLargeInterface { - fun f1() - fun f2() - val i1: Int - fun fImpl() { } + fun f1() + fun f2() + val i1: Int + fun fImpl() {} } // reports 1 - too many members class ClassWithNestedInterface { - interface TooLargeNestedInterface { - fun f1() - fun f2() - val i1: Int - fun fImpl() { } - } + interface TooLargeNestedInterface { + fun f1() + fun f2() + val i1: Int + fun fImpl() {} + } } // reports 1 - too many members interface TooLargeInterfaceWithStaticDeclarations { - fun f1() + fun f1() - companion object { - fun sf() = 0 - const val c = 0 - val si = 0 - } + companion object { + fun sf() = 0 + const val c = 0 + val si = 0 + } } diff --git a/detekt-rules/src/test/resources/cases/ComplexMethods.kt b/detekt-rules/src/test/resources/cases/ComplexMethods.kt index ca9f5b4b8..db1d5314b 100644 --- a/detekt-rules/src/test/resources/cases/ComplexMethods.kt +++ b/detekt-rules/src/test/resources/cases/ComplexMethods.kt @@ -4,48 +4,49 @@ package cases // reports 1 - only if ignoreSingleWhenExpression = false fun complexMethodWithSingleWhen1(i: Int) = - when (i) { - 1 -> print("one") - 2 -> print("two") - 3 -> print("three") - else -> print(i) - } + when (i) { + 1 -> print("one") + 2 -> print("two") + 3 -> print("three") + else -> print(i) + } // reports 1 - only if ignoreSingleWhenExpression = false fun complexMethodWithSingleWhen2(i: Int) { - when (i) { - 1 -> print("one") - 2 -> print("two") - 3 -> print("three") - else -> print(i) - } + when (i) { + 1 -> print("one") + 2 -> print("two") + 3 -> print("three") + else -> print(i) + } } // reports 1 - only if ignoreSingleWhenExpression = false fun complexMethodWithSingleWhen3(i: Int): String { - return when (i) { - 1 -> "one" - 2 -> "two" - 3 -> "three" - else -> "" - } + return when (i) { + 1 -> "one" + 2 -> "two" + 3 -> "three" + else -> "" + } } // reports 1 - only if ignoreSingleWhenExpression = false fun complexMethodWithSingleWhen4(i: Int) = when (i) { - 1 -> "one" - 2 -> "two" - 3 -> "three" - else -> "" + 1 -> "one" + 2 -> "two" + 3 -> "three" + else -> "" } // reports 1 fun complexMethodWith2Statements(i: Int) { - when (i) { - 1 -> print("one") - 2 -> print("two") - 3 -> print("three") - else -> print(i) - } - if (i == 1) { } + when (i) { + 1 -> print("one") + 2 -> print("two") + 3 -> print("three") + else -> print(i) + } + if (i == 1) { + } } diff --git a/detekt-rules/src/test/resources/cases/ConditionalPath.kt b/detekt-rules/src/test/resources/cases/ConditionalPath.kt index ad39c4bd0..ec81eb9b3 100644 --- a/detekt-rules/src/test/resources/cases/ConditionalPath.kt +++ b/detekt-rules/src/test/resources/cases/ConditionalPath.kt @@ -3,58 +3,58 @@ package cases fun conditionalFunction1(): Int { // gets counted by ConditionalPathVisitor - return try { - return if (true) { - if (false) return -1 - return 5 - } else { - 5 - return try { - "5".toInt() - } catch (e: IllegalArgumentException) { - 5 - } catch (e: RuntimeException) { - 3 - return 5 - } - } - } catch (e: Exception) { - when(5) { - 5 -> return 1 - 2 -> return 1 - else -> 5 - } - return 7 - } + return try { + return if (true) { + if (false) return -1 + return 5 + } else { + 5 + return try { + "5".toInt() + } catch (e: IllegalArgumentException) { + 5 + } catch (e: RuntimeException) { + 3 + return 5 + } + } + } catch (e: Exception) { + when (5) { + 5 -> return 1 + 2 -> return 1 + else -> 5 + } + return 7 + } } fun conditionalFunction2(): Int = try { - if (true) { - if (false) -1 - 5 - } else { - 5 - try { - "5".toInt() - } catch (e: IllegalArgumentException) { - 5 - } catch (e: RuntimeException) { - 3 - 5 - } - } + if (true) { + if (false) -1 + 5 + } else { + 5 + try { + "5".toInt() + } catch (e: IllegalArgumentException) { + 5 + } catch (e: RuntimeException) { + 3 + 5 + } + } } catch (e: Exception) { - when(5) { - 5 -> 1 - 2 -> 1 - else -> 5 - } - 7 + when (5) { + 5 -> 1 + 2 -> 1 + else -> 5 + } + 7 } fun conditionalForWhenStatement(i: Int): Int { - return when (i) { - 1 -> 1 - else -> 2 - } + return when (i) { + 1 -> 1 + else -> 2 + } } diff --git a/detekt-rules/src/test/resources/cases/ConstInObjects.kt b/detekt-rules/src/test/resources/cases/ConstInObjects.kt index 3824627a2..d68fed6ec 100644 --- a/detekt-rules/src/test/resources/cases/ConstInObjects.kt +++ b/detekt-rules/src/test/resources/cases/ConstInObjects.kt @@ -3,18 +3,18 @@ package cases @Suppress("unused") object Root { - const val ROOT_CONST = 1 + const val ROOT_CONST = 1 - object A1 { - val ACONST = ROOT_CONST + 1 // reports 1 - const val ACONST_1 = 1 + object A1 { + val ACONST = ROOT_CONST + 1 // reports 1 + const val ACONST_1 = 1 - object B1 { - val BCONST = ACONST_1 + 1 // reports 1 - } - } + object B1 { + val BCONST = ACONST_1 + 1 // reports 1 + } + } - object A2 { - val ACONST = ROOT_CONST + 1 // reports 1 - } + object A2 { + val ACONST = ROOT_CONST + 1 // reports 1 + } } diff --git a/detekt-rules/src/test/resources/cases/DataClassContainsFunctionsNegative.kt b/detekt-rules/src/test/resources/cases/DataClassContainsFunctionsNegative.kt index 540229ec2..72a593750 100644 --- a/detekt-rules/src/test/resources/cases/DataClassContainsFunctionsNegative.kt +++ b/detekt-rules/src/test/resources/cases/DataClassContainsFunctionsNegative.kt @@ -6,21 +6,21 @@ data class ValidDataClass(val i: Int) data class DataClassWithOverriddenMethods(val i: Int) { - override fun hashCode(): Int { - return super.hashCode() - } + override fun hashCode(): Int { + return super.hashCode() + } - override fun equals(other: Any?): Boolean { - return super.equals(other) - } + override fun equals(other: Any?): Boolean { + return super.equals(other) + } - override fun toString(): String { - return super.toString() - } + override fun toString(): String { + return super.toString() + } } class ClassWithRegularFunctions { - fun f1() {} - fun f2() {} + fun f1() {} + fun f2() {} } diff --git a/detekt-rules/src/test/resources/cases/DataClassContainsFunctionsPositive.kt b/detekt-rules/src/test/resources/cases/DataClassContainsFunctionsPositive.kt index 9ca34f98a..f3d4a9469 100644 --- a/detekt-rules/src/test/resources/cases/DataClassContainsFunctionsPositive.kt +++ b/detekt-rules/src/test/resources/cases/DataClassContainsFunctionsPositive.kt @@ -5,11 +5,11 @@ package cases // reports 2 - for each defined function in the data class data class DataClassWithFunctions(val i: Int) { - fun f1() {} - fun f2() {} + fun f1() {} + fun f2() {} - // reports 1 - for each defined conversion function in the data class - data class NestedDataClassWithConversionFunction(val i : Int) { - fun toDataClassWithOverriddenMethods() = DataClassWithOverriddenMethods(i) - } + // reports 1 - for each defined conversion function in the data class + data class NestedDataClassWithConversionFunction(val i: Int) { + fun toDataClassWithOverriddenMethods() = DataClassWithOverriddenMethods(i) + } } diff --git a/detekt-rules/src/test/resources/cases/Default.kt b/detekt-rules/src/test/resources/cases/Default.kt index d0052f720..4acf227be 100644 --- a/detekt-rules/src/test/resources/cases/Default.kt +++ b/detekt-rules/src/test/resources/cases/Default.kt @@ -8,6 +8,6 @@ import java.util.* @Suppress("unused") class Default { - // declares unnecessary return of type "Unit" - fun f(): Unit {} + // declares unnecessary return of type "Unit" + fun f(): Unit {} } diff --git a/detekt-rules/src/test/resources/cases/Empty.kt b/detekt-rules/src/test/resources/cases/Empty.kt index e05bb565c..f09afbc29 100644 --- a/detekt-rules/src/test/resources/cases/Empty.kt +++ b/detekt-rules/src/test/resources/cases/Empty.kt @@ -7,58 +7,58 @@ package cases */ class Empty : Runnable { - init { + init { - } + } - constructor() { + constructor() { - } + } - override fun run() { + override fun run() { - } + } - fun emptyMethod() { + fun emptyMethod() { - } + } - fun stuff() { - try { + fun stuff() { + try { - } catch (e: Exception) { + } catch (e: Exception) { - } catch (e: Exception) { - //no-op - } catch (e: Exception) { - println() - } catch (ignored: Exception) { + } catch (e: Exception) { + //no-op + } catch (e: Exception) { + println() + } catch (ignored: Exception) { - } catch (expected: Exception) { + } catch (expected: Exception) { - } catch (_: Exception) { + } catch (_: Exception) { - } finally { + } finally { - } - if (true) { + } + if (true) { - } else { + } else { - } - when (true) { + } + when (true) { - } - for (i in 1..10) { + } + for (i in 1..10) { - } - while (true) { + } + while (true) { - } - do { + } + do { - } while (true) - } + } while (true) + } } class EmptyClass() {} diff --git a/detekt-rules/src/test/resources/cases/EmptyDefaultConstructorNegative.kt b/detekt-rules/src/test/resources/cases/EmptyDefaultConstructorNegative.kt index ca0176859..80538ac14 100644 --- a/detekt-rules/src/test/resources/cases/EmptyDefaultConstructorNegative.kt +++ b/detekt-rules/src/test/resources/cases/EmptyDefaultConstructorNegative.kt @@ -10,5 +10,5 @@ class PrivatePrimaryConstructor private constructor() class EmptyConstructorIsCalled() { - constructor(i: Int) : this() + constructor(i: Int) : this() } diff --git a/detekt-rules/src/test/resources/cases/EmptyIfNegative.kt b/detekt-rules/src/test/resources/cases/EmptyIfNegative.kt index b56212ad4..16450ad69 100644 --- a/detekt-rules/src/test/resources/cases/EmptyIfNegative.kt +++ b/detekt-rules/src/test/resources/cases/EmptyIfNegative.kt @@ -3,30 +3,30 @@ package cases @Suppress("unused") class EmptyIfNegative { - private var i = 0 + private var i = 0 - // normal if with braces - fun negative1() { - if (i == 0) { - i++ - } - } + // normal if with braces + fun negative1() { + if (i == 0) { + i++ + } + } - // normal if without braces - fun negative2() { - if (i == 0) i++ - } + // normal if without braces + fun negative2() { + if (i == 0) i++ + } - // if then with semicolon but nonempty else body - fun negative3() { - if (i == 0) ; - else i++ - } + // if then with semicolon but nonempty else body + fun negative3() { + if (i == 0) ; + else i++ + } - // multiple if thens with semicolon but nonempty else body - fun negative4() { - if (i == 0) ; - else if (i == 1) ; - else i++ - } + // multiple if thens with semicolon but nonempty else body + fun negative4() { + if (i == 0) ; + else if (i == 1) ; + else i++ + } } diff --git a/detekt-rules/src/test/resources/cases/EmptyIfPositive.kt b/detekt-rules/src/test/resources/cases/EmptyIfPositive.kt index 1a69b053e..221cad72b 100644 --- a/detekt-rules/src/test/resources/cases/EmptyIfPositive.kt +++ b/detekt-rules/src/test/resources/cases/EmptyIfPositive.kt @@ -3,30 +3,30 @@ package cases @Suppress("unused") class EmptyIfPositive { - private var i = 0 + private var i = 0 - // reports 1 - fun trailingSemicolon1() { - if (i == 0) ; - i++ - } + // reports 1 + fun trailingSemicolon1() { + if (i == 0); + i++ + } - // reports 1 - fun trailingSemicolon2() { - if (i == 0); - i++ - } + // reports 1 + fun trailingSemicolon2() { + if (i == 0); + i++ + } - // reports 1 - fun semicolonOnNewLine() { - if (i == 0) - ; - i++ - } + // reports 1 + fun semicolonOnNewLine() { + if (i == 0) + ; + i++ + } - // reports 1 - fun semicolonAndBraces() { - if (i == 0) ; { - } - } + // reports 1 + fun semicolonAndBraces() { + if (i == 0); { + } + } } diff --git a/detekt-rules/src/test/resources/cases/EqualsAlwaysReturnsTrueOrFalseNegative.kt b/detekt-rules/src/test/resources/cases/EqualsAlwaysReturnsTrueOrFalseNegative.kt index 18b392e3a..e6614aa37 100644 --- a/detekt-rules/src/test/resources/cases/EqualsAlwaysReturnsTrueOrFalseNegative.kt +++ b/detekt-rules/src/test/resources/cases/EqualsAlwaysReturnsTrueOrFalseNegative.kt @@ -4,35 +4,35 @@ package cases class EqualsReturnsTrueOrFalse { - override fun equals(other: Any?): Boolean { - if (other is Int) { - return true - } - return false - } + override fun equals(other: Any?): Boolean { + if (other is Int) { + return true + } + return false + } } class CorrectEquals { - override fun equals(other: Any?): Boolean { - return this.toString() == other.toString() - } + override fun equals(other: Any?): Boolean { + return this.toString() == other.toString() + } } fun equals(other: Any?): Boolean { - return false + return false } class NotOverridingEquals { - fun equal(other: Any?): Boolean { - return true - } + fun equal(other: Any?): Boolean { + return true + } } class WrongEqualsParameterList { - fun equals(other: Any, i: Int): Boolean { - return true - } + fun equals(other: Any, i: Int): Boolean { + return true + } } diff --git a/detekt-rules/src/test/resources/cases/EqualsAlwaysReturnsTrueOrFalsePositive.kt b/detekt-rules/src/test/resources/cases/EqualsAlwaysReturnsTrueOrFalsePositive.kt index bd667ec27..87ce8d150 100644 --- a/detekt-rules/src/test/resources/cases/EqualsAlwaysReturnsTrueOrFalsePositive.kt +++ b/detekt-rules/src/test/resources/cases/EqualsAlwaysReturnsTrueOrFalsePositive.kt @@ -5,45 +5,45 @@ package cases // reports 1 for every equals method class EqualsReturnsTrue { - override fun equals(other: Any?): Boolean { - return true - } + override fun equals(other: Any?): Boolean { + return true + } } class EqualsReturnsFalse { - override fun equals(other: Any?): Boolean { - return false - } + override fun equals(other: Any?): Boolean { + return false + } } class EqualsReturnsFalseWithUnreachableReturnStatement { - override fun equals(other: Any?): Boolean { - return false - return true - } + override fun equals(other: Any?): Boolean { + return false + return true + } } class EqualsReturnsFalseWithUnreachableCode { - override fun equals(other: Any?): Boolean { - return false - val i = 0 - } + override fun equals(other: Any?): Boolean { + return false + val i = 0 + } } class EqualsReturnsConstantExpression { - override fun equals(other: Any?) = false + override fun equals(other: Any?) = false } class EqualsWithTwoReturnExpressions { - override fun equals(other: Any?): Boolean { - if (other is Int) { - return true - } - return true - } + override fun equals(other: Any?): Boolean { + if (other is Int) { + return true + } + return true + } } diff --git a/detekt-rules/src/test/resources/cases/ExceptionRaisedInMethodsNegative.kt b/detekt-rules/src/test/resources/cases/ExceptionRaisedInMethodsNegative.kt index aefc48c14..58051583b 100644 --- a/detekt-rules/src/test/resources/cases/ExceptionRaisedInMethodsNegative.kt +++ b/detekt-rules/src/test/resources/cases/ExceptionRaisedInMethodsNegative.kt @@ -4,32 +4,32 @@ package cases open class NoExceptionRaisedInMethods { - init { - throw IllegalStateException() - } + init { + throw IllegalStateException() + } - override fun toString(): String { - return super.toString() - } + override fun toString(): String { + return super.toString() + } - override fun hashCode(): Int { - return super.hashCode() - } + override fun hashCode(): Int { + return super.hashCode() + } - override fun equals(other: Any?): Boolean { - return super.equals(other) - } + override fun equals(other: Any?): Boolean { + return super.equals(other) + } - companion object { - init { - throw IllegalStateException() - } - } + companion object { + init { + throw IllegalStateException() + } + } - fun doSomeEqualsComparison() { - throw IllegalStateException() - } + fun doSomeEqualsComparison() { + throw IllegalStateException() + } - protected fun finalize() { - } + protected fun finalize() { + } } diff --git a/detekt-rules/src/test/resources/cases/ExceptionRaisedInMethodsPositive.kt b/detekt-rules/src/test/resources/cases/ExceptionRaisedInMethodsPositive.kt index fe5a9a89a..26e89b8ea 100644 --- a/detekt-rules/src/test/resources/cases/ExceptionRaisedInMethodsPositive.kt +++ b/detekt-rules/src/test/resources/cases/ExceptionRaisedInMethodsPositive.kt @@ -4,33 +4,33 @@ package cases open class ExceptionRaisedInMethods { - // reports 1 - method should not throw an exception - override fun toString(): String { - throw IllegalStateException() - } + // reports 1 - method should not throw an exception + override fun toString(): String { + throw IllegalStateException() + } - // reports 1 - method should not throw an exception - override fun hashCode(): Int { - throw IllegalStateException() - } + // reports 1 - method should not throw an exception + override fun hashCode(): Int { + throw IllegalStateException() + } - // reports 1 - method should not throw an exception - override fun equals(other: Any?): Boolean { - throw IllegalStateException() - } + // reports 1 - method should not throw an exception + override fun equals(other: Any?): Boolean { + throw IllegalStateException() + } - // reports 1 - method should not throw an exception - protected fun finalize() { - if (true) { - throw IllegalStateException() - } - } + // reports 1 - method should not throw an exception + protected fun finalize() { + if (true) { + throw IllegalStateException() + } + } } object ExceptionRaisedInMethodsObject { - // reports 1 - method should not throw an exception - override fun equals(other: Any?): Boolean { - throw IllegalStateException() - } + // reports 1 - method should not throw an exception + override fun equals(other: Any?): Boolean { + throw IllegalStateException() + } } diff --git a/detekt-rules/src/test/resources/cases/FunctionReturningConstantNegative.kt b/detekt-rules/src/test/resources/cases/FunctionReturningConstantNegative.kt index 226bfae13..6dc323780 100644 --- a/detekt-rules/src/test/resources/cases/FunctionReturningConstantNegative.kt +++ b/detekt-rules/src/test/resources/cases/FunctionReturningConstantNegative.kt @@ -5,7 +5,7 @@ package cases fun functionNotReturningConstant1() = 1 + 1 fun functionNotReturningConstant2(): Int { - return 1 + 1 + return 1 + 1 } fun functionNotReturningConstantString1(str: String) = "str: $str" diff --git a/detekt-rules/src/test/resources/cases/FunctionReturningConstantPositive.kt b/detekt-rules/src/test/resources/cases/FunctionReturningConstantPositive.kt index 3c008306e..241b17dd3 100644 --- a/detekt-rules/src/test/resources/cases/FunctionReturningConstantPositive.kt +++ b/detekt-rules/src/test/resources/cases/FunctionReturningConstantPositive.kt @@ -11,22 +11,22 @@ fun functionReturningConstantEscapedString(str: String) = "str: \$str" // report fun functionReturningConstantChar() = '1' // reports 1 fun functionReturningConstantInt(): Int { // reports 1 - return 1 + return 1 } @Suppress("EqualsOrHashCode") open class FunctionReturningConstant { - open fun f() = 1 // reports 1 - override fun hashCode() = 1 // reports 1 + open fun f() = 1 // reports 1 + override fun hashCode() = 1 // reports 1 } interface InterfaceFunctionReturningConstant { - fun interfaceFunctionWithImplementation() = 1 // reports 1 + fun interfaceFunctionWithImplementation() = 1 // reports 1 - class NestedClassFunctionReturningConstant { + class NestedClassFunctionReturningConstant { - fun interfaceFunctionWithImplementation() = 1 // reports 1 - } + fun interfaceFunctionWithImplementation() = 1 // reports 1 + } } diff --git a/detekt-rules/src/test/resources/cases/IteratorImplNegative.kt b/detekt-rules/src/test/resources/cases/IteratorImplNegative.kt index 7a182cfbb..4958d88a1 100644 --- a/detekt-rules/src/test/resources/cases/IteratorImplNegative.kt +++ b/detekt-rules/src/test/resources/cases/IteratorImplNegative.kt @@ -6,18 +6,18 @@ import java.util.NoSuchElementException class IteratorImplOk : Iterator { - override fun hasNext(): Boolean { - return true - } + override fun hasNext(): Boolean { + return true + } - override fun next(): String { - if (!hasNext()) throw NoSuchElementException() - return "" - } + override fun next(): String { + if (!hasNext()) throw NoSuchElementException() + return "" + } - // next method overload should not be reported - private fun next(i: Int) { - } + // next method overload should not be reported + private fun next(i: Int) { + } } class NoIteratorImpl diff --git a/detekt-rules/src/test/resources/cases/IteratorImplPositive.kt b/detekt-rules/src/test/resources/cases/IteratorImplPositive.kt index 1b8e7ad88..517301c58 100644 --- a/detekt-rules/src/test/resources/cases/IteratorImplPositive.kt +++ b/detekt-rules/src/test/resources/cases/IteratorImplPositive.kt @@ -5,56 +5,56 @@ package cases // reports IteratorNotThrowingNoSuchElementException, IteratorHasNextCallsNextMethod class IteratorImpl2 : Iterator { - override fun hasNext(): Boolean { - next() - return true - } + override fun hasNext(): Boolean { + next() + return true + } - override fun next(): String { - return "" - } + override fun next(): String { + return "" + } } class IteratorImplContainer { - // reports IteratorNotThrowingNoSuchElementException, IteratorHasNextCallsNextMethod - object IteratorImplNegative3 : Iterator { + // reports IteratorNotThrowingNoSuchElementException, IteratorHasNextCallsNextMethod + object IteratorImplNegative3 : Iterator { - override fun hasNext(): Boolean { - next() - return true - } + override fun hasNext(): Boolean { + next() + return true + } - override fun next(): String { - throw IllegalStateException() - } - } + override fun next(): String { + throw IllegalStateException() + } + } } // reports IteratorNotThrowingNoSuchElementException, IteratorHasNextCallsNextMethod interface InterfaceIterator : Iterator { - override fun hasNext(): Boolean { - next() - return true - } + override fun hasNext(): Boolean { + next() + return true + } - override fun next(): String { - return "" - } + override fun next(): String { + return "" + } } // reports IteratorNotThrowingNoSuchElementException, IteratorHasNextCallsNextMethod abstract class AbstractIterator : Iterator { - override fun hasNext(): Boolean { - if (true) { - next() - } - return true - } + override fun hasNext(): Boolean { + if (true) { + next() + } + return true + } - override fun next(): String { - return "" - } + override fun next(): String { + return "" + } } diff --git a/detekt-rules/src/test/resources/cases/LabeledExpressionNegative.kt b/detekt-rules/src/test/resources/cases/LabeledExpressionNegative.kt index 102f702de..da44c9d08 100644 --- a/detekt-rules/src/test/resources/cases/LabeledExpressionNegative.kt +++ b/detekt-rules/src/test/resources/cases/LabeledExpressionNegative.kt @@ -3,31 +3,31 @@ package cases @Suppress("unused", "UNUSED_VARIABLE") class LabeledOuterNegative { - inner class Inner { + inner class Inner { - fun foo() { - print(this@LabeledOuterNegative) - } + fun foo() { + print(this@LabeledOuterNegative) + } - inner class InnerInner { - val a = 0 + inner class InnerInner { + val a = 0 - fun foo() { - print(this@LabeledOuterNegative) - print(this@Inner) - } + fun foo() { + print(this@LabeledOuterNegative) + print(this@Inner) + } - fun Int.extensionMethod() { - print(this@Inner) - print(this@InnerInner) - } - } - } + fun Int.extensionMethod() { + print(this@Inner) + print(this@InnerInner) + } + } + } - class Nested { + class Nested { - fun Int.extensionMethod() { - print(this@Nested) - } - } + fun Int.extensionMethod() { + print(this@Nested) + } + } } diff --git a/detekt-rules/src/test/resources/cases/LabeledExpressionPositive.kt b/detekt-rules/src/test/resources/cases/LabeledExpressionPositive.kt index 54684ab29..255a49ce6 100644 --- a/detekt-rules/src/test/resources/cases/LabeledExpressionPositive.kt +++ b/detekt-rules/src/test/resources/cases/LabeledExpressionPositive.kt @@ -3,50 +3,50 @@ package cases fun breakWithLabel() { // reports 2 - for each @label - loop@ for (i in 1..100) { - for (j in 1..100) { - if (j == 5) break@loop - } - } + loop@ for (i in 1..100) { + for (j in 1..100) { + if (j == 5) break@loop + } + } } fun continueWithLabel() { // reports 2 - for each @label - loop@ for (i in 1..100) { - for (j in 1..100) { - if (j == 5) continue@loop - } - } + loop@ for (i in 1..100) { + for (j in 1..100) { + if (j == 5) continue@loop + } + } } fun implicitReturnWithLabel(range: IntRange) { // reports 1 - range.forEach { - if (it == 5) return@forEach - println(it) - } + range.forEach { + if (it == 5) return@forEach + println(it) + } } fun returnWithLabel(range: IntRange) { // reports 2 - for each @label - range.forEach label@ { - if (it == 5) return@label - println(it) - } + range.forEach label@{ + if (it == 5) return@label + println(it) + } } class LabeledOuterPositive { - inner class Inner1 { + inner class Inner1 { - fun referenceItself() { - val foo = this@Inner1 // reports 1 - inner class referencing itself - } + fun referenceItself() { + val foo = this@Inner1 // reports 1 - inner class referencing itself + } - fun labelShadowing() { - // reports 1 - new label with the same as the outer class - emptyList().forEach LabeledOuterPositive@ { - // reports 1 - references forEach label and not outer class - if (it == 5) return@LabeledOuterPositive - println(it) - } - } - } + fun labelShadowing() { + // reports 1 - new label with the same as the outer class + emptyList().forEach LabeledOuterPositive@{ + // reports 1 - references forEach label and not outer class + if (it == 5) return@LabeledOuterPositive + println(it) + } + } + } } diff --git a/detekt-rules/src/test/resources/cases/LongMethodNegative.kt b/detekt-rules/src/test/resources/cases/LongMethodNegative.kt index deac45e04..478e8f5a1 100644 --- a/detekt-rules/src/test/resources/cases/LongMethodNegative.kt +++ b/detekt-rules/src/test/resources/cases/LongMethodNegative.kt @@ -4,11 +4,11 @@ package cases class LongMethodNegative { - fun methodOk() { // 3 lines - println() - fun localMethodOk() { // 4 lines - println() - println() - } - } + fun methodOk() { // 3 lines + println() + fun localMethodOk() { // 4 lines + println() + println() + } + } } diff --git a/detekt-rules/src/test/resources/cases/LongMethodPositive.kt b/detekt-rules/src/test/resources/cases/LongMethodPositive.kt index 21843a1fa..ce02b2d53 100644 --- a/detekt-rules/src/test/resources/cases/LongMethodPositive.kt +++ b/detekt-rules/src/test/resources/cases/LongMethodPositive.kt @@ -6,15 +6,15 @@ package cases @Suppress("unused") class LongMethodPositive { - fun longMethod() { // 5 lines - println() - println() - println() + fun longMethod() { // 5 lines + println() + println() + println() - fun nestedLongMethod() { // 5 lines - println() - println() - println() - } - } + fun nestedLongMethod() { // 5 lines + println() + println() + println() + } + } } diff --git a/detekt-rules/src/test/resources/cases/LoopWithTooManyJumpStatementsNegative.kt b/detekt-rules/src/test/resources/cases/LoopWithTooManyJumpStatementsNegative.kt index 07e4b8897..6dff44e92 100644 --- a/detekt-rules/src/test/resources/cases/LoopWithTooManyJumpStatementsNegative.kt +++ b/detekt-rules/src/test/resources/cases/LoopWithTooManyJumpStatementsNegative.kt @@ -3,17 +3,17 @@ package cases fun onlyOneJump() { - for (i in 1..2) { - if (i > 1) break - } + for (i in 1..2) { + if (i > 1) break + } } fun jumpsInNestedLoops() { - for (i in 1..2) { - if (i > 1) break - // jump statements of the inner loop must not be counted in the outer loop - while (i > 1) { - if (i > 1) continue - } - } + for (i in 1..2) { + if (i > 1) break + // jump statements of the inner loop must not be counted in the outer loop + while (i > 1) { + if (i > 1) continue + } + } } diff --git a/detekt-rules/src/test/resources/cases/LoopWithTooManyJumpStatementsPositive.kt b/detekt-rules/src/test/resources/cases/LoopWithTooManyJumpStatementsPositive.kt index c4a18d703..740f7a6d1 100644 --- a/detekt-rules/src/test/resources/cases/LoopWithTooManyJumpStatementsPositive.kt +++ b/detekt-rules/src/test/resources/cases/LoopWithTooManyJumpStatementsPositive.kt @@ -2,24 +2,24 @@ package cases @Suppress("unused", "ConstantConditionIf") fun tooManyJumpStatements() { - val i = 0 + val i = 0 - // reports 1 - too many jump statements - for (j in 1..2) { - if (i > 1) { - break - } else { - continue - } - } + // reports 1 - too many jump statements + for (j in 1..2) { + if (i > 1) { + break + } else { + continue + } + } - // reports 1 - too many jump statements - while (i < 2) { - if (i > 1) break else continue - } + // reports 1 - too many jump statements + while (i < 2) { + if (i > 1) break else continue + } - // reports 1 - too many jump statements - do { - if (i > 1) break else continue - } while (i < 2) + // reports 1 - too many jump statements + do { + if (i > 1) break else continue + } while (i < 2) } diff --git a/detekt-rules/src/test/resources/cases/MandatoryBracesIfStatementsNegative.kt b/detekt-rules/src/test/resources/cases/MandatoryBracesIfStatementsNegative.kt index 0d9b38e5b..51731d75b 100644 --- a/detekt-rules/src/test/resources/cases/MandatoryBracesIfStatementsNegative.kt +++ b/detekt-rules/src/test/resources/cases/MandatoryBracesIfStatementsNegative.kt @@ -2,20 +2,21 @@ package cases @Suppress("unused", "ConstantConditionIf") fun mandatoryBracesIfStatementNegative() { - if (true) { - println() - } + if (true) { + println() + } - if (true) - { - println() - } + if (true) { + println() + } - if (true) println() + if (true) println() - if (true) { println() } + if (true) { + println() + } - if (true) println() else println() + if (true) println() else println() - if (true) println() else if (false) println() else println() + if (true) println() else if (false) println() else println() } diff --git a/detekt-rules/src/test/resources/cases/MandatoryBracesIfStatementsPositive.kt b/detekt-rules/src/test/resources/cases/MandatoryBracesIfStatementsPositive.kt index f3115fc0e..beacd7de5 100644 --- a/detekt-rules/src/test/resources/cases/MandatoryBracesIfStatementsPositive.kt +++ b/detekt-rules/src/test/resources/cases/MandatoryBracesIfStatementsPositive.kt @@ -2,23 +2,23 @@ package cases @Suppress("unused", "ConstantConditionIf", "CascadeIf") fun mandatoryBracesIfStatementPositive() { - if (true) - println() + if (true) + println() - if (true) - println() - else - println() + if (true) + println() + else + println() - if (true) - println() - else if (false) - println() - else - println() + if (true) + println() + else if (false) + println() + else + println() - if (true) { - println() - } else - println() + if (true) { + println() + } else + println() } diff --git a/detekt-rules/src/test/resources/cases/MaxLineLength.kt b/detekt-rules/src/test/resources/cases/MaxLineLength.kt index 827f8a754..f73656fd9 100644 --- a/detekt-rules/src/test/resources/cases/MaxLineLength.kt +++ b/detekt-rules/src/test/resources/cases/MaxLineLength.kt @@ -2,31 +2,31 @@ package cases @Suppress("unused") class MaxLineLength { - companion object { - val LOREM_IPSUM = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua." - } + companion object { + val LOREM_IPSUM = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua." + } - val loremIpsumField = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua." + val loremIpsumField = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua." - fun main() { - val thisIsAVeryLongValName = "This is a very, very long String that will break the MaxLineLength" + fun main() { + val thisIsAVeryLongValName = "This is a very, very long String that will break the MaxLineLength" - if (thisIsAVeryLongValName.length > "This is not quite as long of a String".length) { - println("It's indeed a very long String") - } + if (thisIsAVeryLongValName.length > "This is not quite as long of a String".length) { + println("It's indeed a very long String") + } - val hello = anIncrediblyLongAndComplexMethodNameThatProbablyShouldBeMuchShorterButForTheSakeOfTheTestItsNot() - val loremIpsum = getLoremIpsum() + val hello = anIncrediblyLongAndComplexMethodNameThatProbablyShouldBeMuchShorterButForTheSakeOfTheTestItsNot() + val loremIpsum = getLoremIpsum() - println(hello) - println(loremIpsum) + println(hello) + println(loremIpsum) - } + } - // https://longurlmaker.com/go?id=z4Is.gd8c11rangy50farawayRedirx1drawn%2Bout60c3protractedTinyLinkstringylingeringfar%2BreachinglMyURLSHurl86018lengthy7frunningoutstretched1111ilengthy2xSimURLSmallr800xSimURL361juEasyURLSimURL0022faraway1095xhighfar%2Boff1618sustained0Shima8961toutstretchedexpanded0stretch611220drawn%2BoutdwkTightURL8kDoioplongish10Xil14b101ShredURLTraceURLbptoweringB6512TinyURL6towering0rGetShorty004bm5301URLprotracted0prolonged61MooURLy1948jspread%2Bout428u0t3stretchingfarawaylasting11ShredURLc2bDigBigexpandedX.se90a20TinyURL26WapURLr1cprolongedkelongatedc1f2c01loftylengthycontinuede7WapURLgGetShorty2NutshellURLcontinued6a2lastingr5protracted1expandeddistantspread%2BoutURl.iersustainedNotLongSHurl3w2SimURL011xSnipURL02GetShorty2prolonged0f02f60blingeringIs.gd301URLTinyLinktowering3d200t01osustained2WapURL90ShortURL11spread%2Boute02URLPieFly2toweringDwarfurl70elongated9s070SnipURL6Is.gd7spread%2Boutc0hy210vtcnf43Redirxb9148n1lingering6PiURL16URLcutaspread%2BoutYATUCoutstretchede70lUlimita1e610ShortenURL1lnk.inenduringUlimit0U760l8m72011793v7020TightURLelongatedYATUCt6UrlTeaetc91e5kspun%2Bout010d1e1b1Dwarfurl6Shortlinksb0sustained0enlarged6great1187e5e690URLCutter1spun%2Bout10drawn%2Bouttall4EasyURLDecentURLenduringd1eTraceURL5yGetShortyTinyLinkfar%2Boff1prolonged4cc0stretcheddeepprotracted3f001elongate9018ystretchinglastingi7TinyURL7expanded910continuedremotef8sustainedz175lingeringcbloftyprolonged10079running0UlimitB6515Shrinkr00LiteURL1loftyoutstretchedclnk.in3farawayg5runningTinyLinkspread%2Bout1stringy11c036greatfarawaystretchingefar%2Boff31spread%2Bout4kDoiopMooURL53m19Beam.tolastingShredURL1s25ShimBeam.to8nstretchtowering80StartURLShortURL4lengthened018Is.gdNotLongzWapURLNutshellURLe2spun%2Bout119elongated7elongated5outstretchedh8k1stringyloftyShredURL84running06308d071Minilien3wg3UrlTealoftystretchedwCanURLfar%2Boff7atf104083towering820ganglingw35m1a063LiteURLt081NanoRef361lnk.in0deep0Shrinkr6e80far%2Boff9170Redirxy6btspread%2Boutsustained10UlimitShortlinks2toweringGetShorty3ShrinkrDecentURLsustaineddbg1nfShortURL331a001enlargedB65RedirxelongatedMinilien809UrlT - fun anIncrediblyLongAndComplexMethodNameThatProbablyShouldBeMuchShorterButForTheSakeOfTheTestItsNot(): String { - return "Hello" - } + // https://longurlmaker.com/go?id=z4Is.gd8c11rangy50farawayRedirx1drawn%2Bout60c3protractedTinyLinkstringylingeringfar%2BreachinglMyURLSHurl86018lengthy7frunningoutstretched1111ilengthy2xSimURLSmallr800xSimURL361juEasyURLSimURL0022faraway1095xhighfar%2Boff1618sustained0Shima8961toutstretchedexpanded0stretch611220drawn%2BoutdwkTightURL8kDoioplongish10Xil14b101ShredURLTraceURLbptoweringB6512TinyURL6towering0rGetShorty004bm5301URLprotracted0prolonged61MooURLy1948jspread%2Bout428u0t3stretchingfarawaylasting11ShredURLc2bDigBigexpandedX.se90a20TinyURL26WapURLr1cprolongedkelongatedc1f2c01loftylengthycontinuede7WapURLgGetShorty2NutshellURLcontinued6a2lastingr5protracted1expandeddistantspread%2BoutURl.iersustainedNotLongSHurl3w2SimURL011xSnipURL02GetShorty2prolonged0f02f60blingeringIs.gd301URLTinyLinktowering3d200t01osustained2WapURL90ShortURL11spread%2Boute02URLPieFly2toweringDwarfurl70elongated9s070SnipURL6Is.gd7spread%2Boutc0hy210vtcnf43Redirxb9148n1lingering6PiURL16URLcutaspread%2BoutYATUCoutstretchede70lUlimita1e610ShortenURL1lnk.inenduringUlimit0U760l8m72011793v7020TightURLelongatedYATUCt6UrlTeaetc91e5kspun%2Bout010d1e1b1Dwarfurl6Shortlinksb0sustained0enlarged6great1187e5e690URLCutter1spun%2Bout10drawn%2Bouttall4EasyURLDecentURLenduringd1eTraceURL5yGetShortyTinyLinkfar%2Boff1prolonged4cc0stretcheddeepprotracted3f001elongate9018ystretchinglastingi7TinyURL7expanded910continuedremotef8sustainedz175lingeringcbloftyprolonged10079running0UlimitB6515Shrinkr00LiteURL1loftyoutstretchedclnk.in3farawayg5runningTinyLinkspread%2Bout1stringy11c036greatfarawaystretchingefar%2Boff31spread%2Bout4kDoiopMooURL53m19Beam.tolastingShredURL1s25ShimBeam.to8nstretchtowering80StartURLShortURL4lengthened018Is.gdNotLongzWapURLNutshellURLe2spun%2Bout119elongated7elongated5outstretchedh8k1stringyloftyShredURL84running06308d071Minilien3wg3UrlTealoftystretchedwCanURLfar%2Boff7atf104083towering820ganglingw35m1a063LiteURLt081NanoRef361lnk.in0deep0Shrinkr6e80far%2Boff9170Redirxy6btspread%2Boutsustained10UlimitShortlinks2toweringGetShorty3ShrinkrDecentURLsustaineddbg1nfShortURL331a001enlargedB65RedirxelongatedMinilien809UrlT + fun anIncrediblyLongAndComplexMethodNameThatProbablyShouldBeMuchShorterButForTheSakeOfTheTestItsNot(): String { + return "Hello" + } - fun getLoremIpsum() = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua." + fun getLoremIpsum() = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua." } diff --git a/detekt-rules/src/test/resources/cases/MaxLineLengthSuppressed.kt b/detekt-rules/src/test/resources/cases/MaxLineLengthSuppressed.kt index 8d109638b..34244cb9e 100644 --- a/detekt-rules/src/test/resources/cases/MaxLineLengthSuppressed.kt +++ b/detekt-rules/src/test/resources/cases/MaxLineLengthSuppressed.kt @@ -2,36 +2,36 @@ package cases @Suppress("unused") class MaxLineLengthSuppressed { - companion object { - @Suppress("MaxLineLength") - val LOREM_IPSUM = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua." - } + companion object { + @Suppress("MaxLineLength") + val LOREM_IPSUM = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua." + } - @Suppress("MaxLineLength") - val loremIpsumField = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua." + @Suppress("MaxLineLength") + val loremIpsumField = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua." - fun main() { - val thisIsAVeryLongValName = "This is a very, very long String that will break the MaxLineLength" + fun main() { + val thisIsAVeryLongValName = "This is a very, very long String that will break the MaxLineLength" - if (thisIsAVeryLongValName.length > "This is not quite as long of a String".length) { - println("It's indeed a very long String") - } + if (thisIsAVeryLongValName.length > "This is not quite as long of a String".length) { + println("It's indeed a very long String") + } - @Suppress("MaxLineLength") - val hello = anIncrediblyLongAndComplexMethodNameThatProbablyShouldBeMuchShorterButForTheSakeOfTheTestItsNot() - val loremIpsum = getLoremIpsum() + @Suppress("MaxLineLength") + val hello = anIncrediblyLongAndComplexMethodNameThatProbablyShouldBeMuchShorterButForTheSakeOfTheTestItsNot() + val loremIpsum = getLoremIpsum() - println(hello) - println(loremIpsum) + println(hello) + println(loremIpsum) - } + } - fun anIncrediblyLongAndComplexMethodNameThatProbablyShouldBeMuchShorterButForTheSakeOfTheTestItsNot(): String { - return "Hello" - } + fun anIncrediblyLongAndComplexMethodNameThatProbablyShouldBeMuchShorterButForTheSakeOfTheTestItsNot(): String { + return "Hello" + } - @Suppress("MaxLineLength") - fun getLoremIpsum() = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua." + @Suppress("MaxLineLength") + fun getLoremIpsum() = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua." } @Suppress("MaxLineLength") diff --git a/detekt-rules/src/test/resources/cases/MaxLineLengthWithLongComments.kt b/detekt-rules/src/test/resources/cases/MaxLineLengthWithLongComments.kt index 62e48ce60..1271d6ae5 100644 --- a/detekt-rules/src/test/resources/cases/MaxLineLengthWithLongComments.kt +++ b/detekt-rules/src/test/resources/cases/MaxLineLengthWithLongComments.kt @@ -2,29 +2,30 @@ package cases @Suppress("unused") class MaxLineLengthWithLongComments { - // Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. - /* Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. */ + // Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. + /* Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. */ - /* - * Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. - */ - companion object { - val LOREM_IPSUM = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua." - } + /* + * Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. + */ + companion object { + val LOREM_IPSUM = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua." + } - val loremIpsumField = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua." + val loremIpsumField = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua." - fun main() { - val thisIsAVeryLongValName = "This is a very, very long String that will break the MaxLineLength" + fun main() { + val thisIsAVeryLongValName = "This is a very, very long String that will break the MaxLineLength" - if (thisIsAVeryLongValName.length > "This is not quite as long of a String".length) { - println("It's indeed a very long String") - } + if (thisIsAVeryLongValName.length > "This is not quite as long of a String".length) { + println("It's indeed a very long String") + } - val loremIpsum = getLoremIpsum() + val loremIpsum = getLoremIpsum() - println(loremIpsum) + println(loremIpsum) - } - fun getLoremIpsum() = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua." + } + + fun getLoremIpsum() = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua." } diff --git a/detekt-rules/src/test/resources/cases/MayBeConstNegative.kt b/detekt-rules/src/test/resources/cases/MayBeConstNegative.kt index 222bb92dd..2748303b8 100644 --- a/detekt-rules/src/test/resources/cases/MayBeConstNegative.kt +++ b/detekt-rules/src/test/resources/cases/MayBeConstNegative.kt @@ -5,16 +5,16 @@ package cases * @author Artur Bosch */ class MyClass { - companion object { - val const = "${MyClass::class.java.name}.EXTRA_DETAILS" - private val A = "asdf=${AnotherClass.staticVariable}" - } + companion object { + val const = "${MyClass::class.java.name}.EXTRA_DETAILS" + private val A = "asdf=${AnotherClass.staticVariable}" + } } class AnotherClass { - companion object { - const val staticVariable = "" - } + companion object { + const val staticVariable = "" + } } var test_var = "test" diff --git a/detekt-rules/src/test/resources/cases/MemberNameEqualsClassNameNegative.kt b/detekt-rules/src/test/resources/cases/MemberNameEqualsClassNameNegative.kt index d8f874e84..f1b838af4 100644 --- a/detekt-rules/src/test/resources/cases/MemberNameEqualsClassNameNegative.kt +++ b/detekt-rules/src/test/resources/cases/MemberNameEqualsClassNameNegative.kt @@ -4,51 +4,51 @@ package cases class MethodNameNotEqualsClassName { - val prop = 0 + val prop = 0 - // should not report a nested function with the same name as the class - fun nestedFunction() { - fun MethodNameNotEqualsClassName() {} - } + // should not report a nested function with the same name as the class + fun nestedFunction() { + fun MethodNameNotEqualsClassName() {} + } - class NestedNameEqualsTopClassName { + class NestedNameEqualsTopClassName { - // should not report function with same name in nested class - fun MethodNameNotEqualsClassName() {} - } + // should not report function with same name in nested class + fun MethodNameNotEqualsClassName() {} + } } class StaticMethodNameEqualsObjectName { - companion object A { - fun A() {} - } + companion object A { + fun A() {} + } } // factory method can have the same name as the class class FactoryClass1 { - companion object { - fun factoryClass1(): FactoryClass1 { - return FactoryClass1() - } - } + companion object { + fun factoryClass1(): FactoryClass1 { + return FactoryClass1() + } + } } // factory method can have the same name as the class class FactoryClass2 { - companion object { - fun factoryClass2() = FactoryClass2() - } + companion object { + fun factoryClass2() = FactoryClass2() + } } abstract class BaseClassForMethodNameEqualsClassName { - abstract fun AbstractMethodNameEqualsClassName() + abstract fun AbstractMethodNameEqualsClassName() } interface MethodNameEqualsInterfaceName { - fun MethodNameEqualsInterfaceName() {} + fun MethodNameEqualsInterfaceName() {} } diff --git a/detekt-rules/src/test/resources/cases/MemberNameEqualsClassNamePositive.kt b/detekt-rules/src/test/resources/cases/MemberNameEqualsClassNamePositive.kt index 307542b28..c359467d9 100644 --- a/detekt-rules/src/test/resources/cases/MemberNameEqualsClassNamePositive.kt +++ b/detekt-rules/src/test/resources/cases/MemberNameEqualsClassNamePositive.kt @@ -4,57 +4,57 @@ package cases class MethodNameEqualsClassName { - fun methodNameEqualsClassName() {} // reports 1 + fun methodNameEqualsClassName() {} // reports 1 } object MethodNameEqualsObjectName { - fun MethodNameEqualsObjectName() {} // reports 1 + fun MethodNameEqualsObjectName() {} // reports 1 } class PropertyNameEqualsClassName { - val propertyNameEqualsClassName = 0 // reports 1 + val propertyNameEqualsClassName = 0 // reports 1 } object PropertyNameEqualsObjectName { - val propertyNameEqualsObjectName = 0 // reports 1 + val propertyNameEqualsObjectName = 0 // reports 1 } class StaticMethodNameEqualsClassName { - companion object { - fun StaticMethodNameEqualsClassName() {} // reports 1 - } + companion object { + fun StaticMethodNameEqualsClassName() {} // reports 1 + } } class MethodNameContainer { - class MethodNameEqualsNestedClassName { + class MethodNameEqualsNestedClassName { - fun MethodNameEqualsNestedClassName() {} // reports 1 - } + fun MethodNameEqualsNestedClassName() {} // reports 1 + } } class WrongFactoryClass1 { - companion object { - fun wrongFactoryClass1() {} // reports 1 - no return type - } + companion object { + fun wrongFactoryClass1() {} // reports 1 - no return type + } } class WrongFactoryClass2 { - companion object { - fun wrongFactoryClass2(): Int { // reports 1 - wrong return type - return 0 - } - } + companion object { + fun wrongFactoryClass2(): Int { // reports 1 - wrong return type + return 0 + } + } } class AbstractMethodNameEqualsClassName : BaseClassForMethodNameEqualsClassName() { - // reports 1 - if overridden functions are not ignored - override fun AbstractMethodNameEqualsClassName() {} + // reports 1 - if overridden functions are not ignored + override fun AbstractMethodNameEqualsClassName() {} } diff --git a/detekt-rules/src/test/resources/cases/NestedClassVisibilityNegative.kt b/detekt-rules/src/test/resources/cases/NestedClassVisibilityNegative.kt index 9cc772a4d..e3f4bf52b 100644 --- a/detekt-rules/src/test/resources/cases/NestedClassVisibilityNegative.kt +++ b/detekt-rules/src/test/resources/cases/NestedClassVisibilityNegative.kt @@ -4,22 +4,22 @@ package cases internal class NestedClassVisibilityNegative { - // enums with public visibility are excluded - enum class NestedEnum { One, Two } + // enums with public visibility are excluded + enum class NestedEnum { One, Two } - private interface PrivateTest - internal interface InternalTest + private interface PrivateTest + internal interface InternalTest - // should not detect companion object - companion object C + // should not detect companion object + companion object C } private class PrivateClassWithNestedElements { - class Inner + class Inner } internal interface IgnoreNestedClassInInterface { - class Nested + class Nested } diff --git a/detekt-rules/src/test/resources/cases/NestedClassVisibilityPositive.kt b/detekt-rules/src/test/resources/cases/NestedClassVisibilityPositive.kt index b14ed6d7d..9f6387a3a 100644 --- a/detekt-rules/src/test/resources/cases/NestedClassVisibilityPositive.kt +++ b/detekt-rules/src/test/resources/cases/NestedClassVisibilityPositive.kt @@ -4,27 +4,29 @@ package cases internal class NestedClassesVisibilityPositive { - // reports 1 - public visibility - public class NestedPublicClass1 - // reports 1 - public visibility - class NestedPublicClass2 - // reports 1 - public visibility - interface NestedPublicInterface + // reports 1 - public visibility + public class NestedPublicClass1 - // reports 1 - public visibility - object A + // reports 1 - public visibility + class NestedPublicClass2 - // reports 1 - public visibility - public class NestedClassWithNestedCLass { + // reports 1 - public visibility + interface NestedPublicInterface - // classes with a nesting depth higher than 1 are excluded - public class NestedClass - } + // reports 1 - public visibility + object A + + // reports 1 - public visibility + public class NestedClassWithNestedCLass { + + // classes with a nesting depth higher than 1 are excluded + public class NestedClass + } } internal enum class NestedEnumsVisibility { - A; + A; - class Inner // reports 1 - public visibility inside enum class + class Inner // reports 1 - public visibility inside enum class } diff --git a/detekt-rules/src/test/resources/cases/NestedClasses.kt b/detekt-rules/src/test/resources/cases/NestedClasses.kt index 2c32aa8ef..9805b8ca6 100644 --- a/detekt-rules/src/test/resources/cases/NestedClasses.kt +++ b/detekt-rules/src/test/resources/cases/NestedClasses.kt @@ -8,103 +8,103 @@ package cases @Suppress("unused") class NestedClasses { - private val i = 0 + private val i = 0 - class InnerClass { + class InnerClass { - class NestedInnerClass { + class NestedInnerClass { - fun nestedLongMethod() { - if (true) { - if (true) { - if (true) { - 5.run { - this.let { - listOf(1, 2, 3).map { it * 2 } - .groupBy(Int::toString, Int::toString) - } - } - } - } - } + fun nestedLongMethod() { + if (true) { + if (true) { + if (true) { + 5.run { + this.let { + listOf(1, 2, 3).map { it * 2 } + .groupBy(Int::toString, Int::toString) + } + } + } + } + } - try { - for (i in 1..5) { - when (i) { - 1 -> print(1) - } - } - } finally { + try { + for (i in 1..5) { + when (i) { + 1 -> print(1) + } + } + } finally { - } + } - fun nestedLocalMethod() { - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - println() - } - nestedLocalMethod() - } - } - } + fun nestedLocalMethod() { + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + println() + } + nestedLocalMethod() + } + } + } } @Suppress("unused") -/** - * Top level members must be skipped for LargeClass rule - */ + /** + * Top level members must be skipped for LargeClass rule + */ val aTopLevelPropertyOfNestedClasses = 0 diff --git a/detekt-rules/src/test/resources/cases/NoClasses.kt b/detekt-rules/src/test/resources/cases/NoClasses.kt index db7d43b9b..b2620c07a 100644 --- a/detekt-rules/src/test/resources/cases/NoClasses.kt +++ b/detekt-rules/src/test/resources/cases/NoClasses.kt @@ -6,59 +6,59 @@ package cases const val test = 1 fun test() { - println(test) - println(test) - println(test) - println(test) - println(test) - println(test) - println(test) - println(test) - println(test) - println(test) - println(test) - println(test) - println(test) - println(test) - println(test) - println(test) - println(test) - println(test) - println(1) - println(1) - for (i in 0..500) { - println(i) - longMethod() - } + println(test) + println(test) + println(test) + println(test) + println(test) + println(test) + println(test) + println(test) + println(test) + println(test) + println(test) + println(test) + println(test) + println(test) + println(test) + println(test) + println(test) + println(test) + println(1) + println(1) + for (i in 0..500) { + println(i) + longMethod() + } } fun longMethod() { - if (true) { - if (true) { - if (true) { - 5.run { - this.let { - listOf(1, 2, 3).map { it * 2 } - .groupBy(Int::toString, Int::toString) - } - } - } - } - } + if (true) { + if (true) { + if (true) { + 5.run { + this.let { + listOf(1, 2, 3).map { it * 2 } + .groupBy(Int::toString, Int::toString) + } + } + } + } + } - try { - for (i in 1..5) { - when (i) { - 1 -> print(1) - } - } - } finally { + try { + for (i in 1..5) { + when (i) { + 1 -> print(1) + } + } + } finally { - } + } } @Suppress("unused") -/** - * Top level members must be skipped for LargeClass rule - */ + /** + * Top level members must be skipped for LargeClass rule + */ val aTopLevelProperty = 0 diff --git a/detekt-rules/src/test/resources/cases/NoTabsNegative.kt b/detekt-rules/src/test/resources/cases/NoTabsNegative.kt index ba3f3ca00..79e0dc2f4 100644 --- a/detekt-rules/src/test/resources/cases/NoTabsNegative.kt +++ b/detekt-rules/src/test/resources/cases/NoTabsNegative.kt @@ -2,10 +2,10 @@ package cases class NoTabsNegative { - fun methodOk() { - println("A message") - } + fun methodOk() { + println("A message") + } - val str = "A \t tab " - val multiStr = """A \t tab """ + val str = "A \t tab " + val multiStr = """A \t tab """ } diff --git a/detekt-rules/src/test/resources/cases/OverloadedMethods.kt b/detekt-rules/src/test/resources/cases/OverloadedMethods.kt index e46a4564d..24c43631d 100644 --- a/detekt-rules/src/test/resources/cases/OverloadedMethods.kt +++ b/detekt-rules/src/test/resources/cases/OverloadedMethods.kt @@ -4,21 +4,24 @@ package cases class OverloadedMethods { - // reports 1 - x() method overload count exceeds threshold - fun x() {} - fun x(i: Int) {} - fun x(i: Int, j: Int) {} + // reports 1 - x() method overload count exceeds threshold + fun x() {} - private class InnerClass { + fun x(i: Int) {} + fun x(i: Int, j: Int) {} - // reports 1 - x() method overload count exceeds threshold - fun x() {} - fun x(i: Int) {} - fun x(i: Int, j: Int) {} - } + private class InnerClass { + + // reports 1 - x() method overload count exceeds threshold + fun x() {} + + fun x(i: Int) {} + fun x(i: Int, j: Int) {} + } } // reports 1 - overloadedMethod() method overload count exceeds threshold fun overloadedMethod() {} + fun overloadedMethod(i: Int) {} fun overloadedMethod(i: Int, j: Int) {} diff --git a/detekt-rules/src/test/resources/cases/PreferToOverPairSyntaxNegative.kt b/detekt-rules/src/test/resources/cases/PreferToOverPairSyntaxNegative.kt index da21ce02e..c938e87f8 100644 --- a/detekt-rules/src/test/resources/cases/PreferToOverPairSyntaxNegative.kt +++ b/detekt-rules/src/test/resources/cases/PreferToOverPairSyntaxNegative.kt @@ -2,5 +2,5 @@ package cases @Suppress("unused", "UNUSED_VARIABLE") fun preferToOverPairSyntaxNegative() { - val pair = 1 to 2 + val pair = 1 to 2 } diff --git a/detekt-rules/src/test/resources/cases/PreferToOverPairSyntaxPositive.kt b/detekt-rules/src/test/resources/cases/PreferToOverPairSyntaxPositive.kt index b97e0ff1d..4efb946d5 100644 --- a/detekt-rules/src/test/resources/cases/PreferToOverPairSyntaxPositive.kt +++ b/detekt-rules/src/test/resources/cases/PreferToOverPairSyntaxPositive.kt @@ -2,9 +2,9 @@ package cases @Suppress("unused", "UNUSED_VARIABLE") fun preferToOverPairSyntaxPositive() { - val pair1 = Pair(1, 2) + val pair1 = Pair(1, 2) - val pair2: Pair = Pair(1, 2) + val pair2: Pair = Pair(1, 2) - val pair3 = Pair(Pair(1, 2), Pair(3, 4)) + val pair3 = Pair(Pair(1, 2), Pair(3, 4)) } diff --git a/detekt-rules/src/test/resources/cases/ProtectedMemberInFinalClassNegative.kt b/detekt-rules/src/test/resources/cases/ProtectedMemberInFinalClassNegative.kt index 44afc3ba6..92fd85eeb 100644 --- a/detekt-rules/src/test/resources/cases/ProtectedMemberInFinalClassNegative.kt +++ b/detekt-rules/src/test/resources/cases/ProtectedMemberInFinalClassNegative.kt @@ -4,27 +4,27 @@ package cases class NoProtectedMembersInFinalClass : BaseClass() { - private val i = 0 + private val i = 0 - // should not report protected = private visibility - protected override val abstractProp = 0 + // should not report protected = private visibility + protected override val abstractProp = 0 - // should not report protected = private visibility - protected override fun abstractFunction() { - } + // should not report protected = private visibility + protected override fun abstractFunction() { + } } abstract class BaseClass { - protected abstract val abstractProp: Int - protected abstract fun abstractFunction() + protected abstract val abstractProp: Int + protected abstract fun abstractFunction() - protected object InnerObject + protected object InnerObject } sealed class SealedClass { - protected fun a() {} + protected fun a() {} } diff --git a/detekt-rules/src/test/resources/cases/ProtectedMemberInFinalClassPositive.kt b/detekt-rules/src/test/resources/cases/ProtectedMemberInFinalClassPositive.kt index 0ad5c1f0b..9dd29d553 100644 --- a/detekt-rules/src/test/resources/cases/ProtectedMemberInFinalClassPositive.kt +++ b/detekt-rules/src/test/resources/cases/ProtectedMemberInFinalClassPositive.kt @@ -4,45 +4,45 @@ package cases class ProtectedMemberInFinalClassPositive { - protected var i1 = 0 // reports 1 + protected var i1 = 0 // reports 1 - protected constructor(i1: Int) : super() { // reports 1 - this.i1 = i1 - } + protected constructor(i1: Int) : super() { // reports 1 + this.i1 = i1 + } - protected fun function() {} // reports 1 + protected fun function() {} // reports 1 - protected inner class InnerClass1 { // reports 1 - protected val i = 0 // reports 1 - } + protected inner class InnerClass1 { // reports 1 + protected val i = 0 // reports 1 + } - inner class InnerClass2 { - protected val i = 0 // reports 1 - } + inner class InnerClass2 { + protected val i = 0 // reports 1 + } - protected object InnerObject // reports 1 + protected object InnerObject // reports 1 - protected companion object { // reports 1 - protected class A { // reports 1 - protected var x = 0 // reports 1 - } - } + protected companion object { // reports 1 + protected class A { // reports 1 + protected var x = 0 // reports 1 + } + } } abstract class ClassWithAbstractCompanionMembers { - protected companion object { - protected class A { - protected var x = 0 // reports 1 - } - } + protected companion object { + protected class A { + protected var x = 0 // reports 1 + } + } } open class OpenClass { - inner class InnerClass { - protected val i = 0 // reports 1 - } + inner class InnerClass { + protected val i = 0 // reports 1 + } } class FinalClassWithProtectedConstructor protected constructor() // reports 1 diff --git a/detekt-rules/src/test/resources/cases/RethrowCaughtExceptionNegative.kt b/detekt-rules/src/test/resources/cases/RethrowCaughtExceptionNegative.kt index aa4c38383..cb71e90a7 100644 --- a/detekt-rules/src/test/resources/cases/RethrowCaughtExceptionNegative.kt +++ b/detekt-rules/src/test/resources/cases/RethrowCaughtExceptionNegative.kt @@ -2,31 +2,31 @@ package cases @Suppress("unused") fun rethrowCaughtExceptionNegative() { - try { - } catch (e: IllegalStateException) { - throw IllegalArgumentException(e) // e encapsulated in a new exception is allowed - } - try { - } catch (e: IllegalStateException) { - throw IllegalArgumentException("msg", e) - } - try { - } catch (e: IllegalStateException) { - print(e) // logging an exception is allowed - } - try { - } catch (e: IllegalStateException) { - print(e) // logging an exception is allowed - throw e - } - try { - } catch (e: IllegalStateException) { - print("log") // taking specific action before throwing the exception - throw e - } - try { - } catch (e: IllegalStateException) { - print(e.message) // taking specific action before throwing the exception - throw e - } + try { + } catch (e: IllegalStateException) { + throw IllegalArgumentException(e) // e encapsulated in a new exception is allowed + } + try { + } catch (e: IllegalStateException) { + throw IllegalArgumentException("msg", e) + } + try { + } catch (e: IllegalStateException) { + print(e) // logging an exception is allowed + } + try { + } catch (e: IllegalStateException) { + print(e) // logging an exception is allowed + throw e + } + try { + } catch (e: IllegalStateException) { + print("log") // taking specific action before throwing the exception + throw e + } + try { + } catch (e: IllegalStateException) { + print(e.message) // taking specific action before throwing the exception + throw e + } } diff --git a/detekt-rules/src/test/resources/cases/RethrowCaughtExceptionPositive.kt b/detekt-rules/src/test/resources/cases/RethrowCaughtExceptionPositive.kt index 06d008ec3..2bc6ccf4d 100644 --- a/detekt-rules/src/test/resources/cases/RethrowCaughtExceptionPositive.kt +++ b/detekt-rules/src/test/resources/cases/RethrowCaughtExceptionPositive.kt @@ -2,20 +2,20 @@ package cases @Suppress("unused", "UNREACHABLE_CODE", "UNUSED_EXPRESSION") fun rethrowCaughtExceptionPositive() { - try { - } catch (e: IllegalStateException) { - throw e // reports 1 - the same exception is rethrown - } - try { - } catch (e: IllegalStateException) { - throw e // reports 1 - dead code after the same exception is rethrown - print("log") - } - try { - } catch (e: IllegalStateException) { - try { - } catch (f: IllegalStateException) { - throw f // reports 1 - dead code after the same exception is rethrown - } - } + try { + } catch (e: IllegalStateException) { + throw e // reports 1 - the same exception is rethrown + } + try { + } catch (e: IllegalStateException) { + throw e // reports 1 - dead code after the same exception is rethrown + print("log") + } + try { + } catch (e: IllegalStateException) { + try { + } catch (f: IllegalStateException) { + throw f // reports 1 - dead code after the same exception is rethrown + } + } } diff --git a/detekt-rules/src/test/resources/cases/SerializableNegative.kt b/detekt-rules/src/test/resources/cases/SerializableNegative.kt index fef634e5b..0afeddb69 100644 --- a/detekt-rules/src/test/resources/cases/SerializableNegative.kt +++ b/detekt-rules/src/test/resources/cases/SerializableNegative.kt @@ -5,21 +5,21 @@ package cases import java.io.Serializable class CorrectSerializable1 : Serializable { - companion object { - const val serialVersionUID = 1L - } + companion object { + const val serialVersionUID = 1L + } } class CorrectSerializable2 : Serializable { - companion object { - const val serialVersionUID: Long = 1 - } + companion object { + const val serialVersionUID: Long = 1 + } } class CorrectSerializable3 : Serializable { - companion object { - const val serialVersionUID = -1L - } + companion object { + const val serialVersionUID = -1L + } } class NoSerializableClass diff --git a/detekt-rules/src/test/resources/cases/SerializablePositive.kt b/detekt-rules/src/test/resources/cases/SerializablePositive.kt index dc933c5a1..076c992bf 100644 --- a/detekt-rules/src/test/resources/cases/SerializablePositive.kt +++ b/detekt-rules/src/test/resources/cases/SerializablePositive.kt @@ -5,25 +5,25 @@ package cases import java.io.Serializable class IncorrectSerialVersionUID1 : Serializable { - companion object { - const val serialVersionUID = 1 // reports 1 - wrong datatype - } + companion object { + const val serialVersionUID = 1 // reports 1 - wrong datatype + } } class IncorrectSerialVersionUID2 : Serializable { - companion object { - const val serialVersionUUID = 1L // reports 1 - wrong naming - } + companion object { + const val serialVersionUUID = 1L // reports 1 - wrong naming + } - object NestedIncorrectSerialVersionUID : Serializable { - val serialVersionUUID = 1L // reports 1 - missing const modifier - } + object NestedIncorrectSerialVersionUID : Serializable { + val serialVersionUUID = 1L // reports 1 - missing const modifier + } } class IncorrectSerialVersionUID3 : Serializable { - companion object { - const val serialVersionUID: Int = 1 // reports 1 - wrong datatype - } + companion object { + const val serialVersionUID: Int = 1 // reports 1 - wrong datatype + } } class NoSerialVersionUID : Serializable // reports 1 - no serialVersionUID at all diff --git a/detekt-rules/src/test/resources/cases/SwallowedExceptionNegative.kt b/detekt-rules/src/test/resources/cases/SwallowedExceptionNegative.kt index 6b01c8303..e833cb3fc 100644 --- a/detekt-rules/src/test/resources/cases/SwallowedExceptionNegative.kt +++ b/detekt-rules/src/test/resources/cases/SwallowedExceptionNegative.kt @@ -3,21 +3,21 @@ package cases import java.io.IOException fun noSwallowedException() { - try { - } catch(e: Exception) { - throw IOException(e.message, e) - } catch(e: Exception) { - throw IOException(e) - } catch (e: Exception) { - throw Exception(e) - } + try { + } catch (e: Exception) { + throw IOException(e.message, e) + } catch (e: Exception) { + throw IOException(e) + } catch (e: Exception) { + throw Exception(e) + } } fun usedException() { - try { - } catch (e: Exception) { - print(e) - } catch(e: Exception) { - print(e.message) - } + try { + } catch (e: Exception) { + print(e) + } catch (e: Exception) { + print(e.message) + } } diff --git a/detekt-rules/src/test/resources/cases/SwallowedExceptionPositive.kt b/detekt-rules/src/test/resources/cases/SwallowedExceptionPositive.kt index 3a7aac571..be3359560 100644 --- a/detekt-rules/src/test/resources/cases/SwallowedExceptionPositive.kt +++ b/detekt-rules/src/test/resources/cases/SwallowedExceptionPositive.kt @@ -3,21 +3,21 @@ package cases import java.io.IOException fun swallowedExceptions() { - try { - } catch(e: Exception) { - throw IOException(e.message) // violation - } catch(e: Exception) { - throw Exception(IOException(e.toString())) // violation - } catch(e: Exception) { - throw IOException(e.message) // violation - } catch(e: Exception) { - throw IOException() // violation - } + try { + } catch (e: Exception) { + throw IOException(e.message) // violation + } catch (e: Exception) { + throw Exception(IOException(e.toString())) // violation + } catch (e: Exception) { + throw IOException(e.message) // violation + } catch (e: Exception) { + throw IOException() // violation + } } fun unusedException() { - try { - } catch (e: IOException) { - println() // violation - } + try { + } catch (e: IOException) { + println() // violation + } } diff --git a/detekt-rules/src/test/resources/cases/TooGenericExceptions.kt b/detekt-rules/src/test/resources/cases/TooGenericExceptions.kt index 0e1af8c1b..53a5fd220 100644 --- a/detekt-rules/src/test/resources/cases/TooGenericExceptions.kt +++ b/detekt-rules/src/test/resources/cases/TooGenericExceptions.kt @@ -6,23 +6,23 @@ package cases */ class TooGenericExceptions { - fun main() { - try { - throw Throwable() - } catch (e: ArrayIndexOutOfBoundsException) { - throw Error() - } catch (e: Error) { - throw Exception() - } catch (e: Exception) { - } catch (e: IllegalMonitorStateException) { - } catch (e: IndexOutOfBoundsException) { - throw RuntimeException() - } catch (e: Throwable) { - } catch (e: RuntimeException) { - throw NullPointerException() - } catch (e: NullPointerException) { + fun main() { + try { + throw Throwable() + } catch (e: ArrayIndexOutOfBoundsException) { + throw Error() + } catch (e: Error) { + throw Exception() + } catch (e: Exception) { + } catch (e: IllegalMonitorStateException) { + } catch (e: IndexOutOfBoundsException) { + throw RuntimeException() + } catch (e: Throwable) { + } catch (e: RuntimeException) { + throw NullPointerException() + } catch (e: NullPointerException) { - } - } + } + } } diff --git a/detekt-rules/src/test/resources/cases/TooGenericExceptionsOptions.kt b/detekt-rules/src/test/resources/cases/TooGenericExceptionsOptions.kt index 132e7bcbc..b42849dbc 100644 --- a/detekt-rules/src/test/resources/cases/TooGenericExceptionsOptions.kt +++ b/detekt-rules/src/test/resources/cases/TooGenericExceptionsOptions.kt @@ -4,13 +4,13 @@ package cases class TooGenericExceptionsOptions { - fun f() { - try { - throw Throwable() - } catch (myIgnore: MyTooGenericException) { - throw Error() - } - } + fun f() { + try { + throw Throwable() + } catch (myIgnore: MyTooGenericException) { + throw Error() + } + } } class MyTooGenericException : RuntimeException() diff --git a/detekt-rules/src/test/resources/cases/TooManyFunctions.kt b/detekt-rules/src/test/resources/cases/TooManyFunctions.kt index 5eeded1dd..4b5bc3656 100644 --- a/detekt-rules/src/test/resources/cases/TooManyFunctions.kt +++ b/detekt-rules/src/test/resources/cases/TooManyFunctions.kt @@ -3,67 +3,67 @@ package cases @Suppress("unused") class TooManyFunctions { - fun f1() { - println() - } + fun f1() { + println() + } - fun f2() { - println() - } + fun f2() { + println() + } - fun f3() { - println() - } + fun f3() { + println() + } - fun f4() { - println() - } + fun f4() { + println() + } - fun f5() { - println() - } + fun f5() { + println() + } - fun f6() { - println() - } + fun f6() { + println() + } - fun f7() { - println() - } + fun f7() { + println() + } - fun f8() { - println() - } + fun f8() { + println() + } - fun f9() { - println() - } + fun f9() { + println() + } - fun f10() { - println() - } + fun f10() { + println() + } - fun f11() { - println() - } + fun f11() { + println() + } - fun f12() { - println() - } + fun f12() { + println() + } - fun f13() { - println() - } + fun f13() { + println() + } - fun f14() { - println() - } + fun f14() { + println() + } - fun f15() { - println() - } + fun f15() { + println() + } - fun f16() { - println() - } + fun f16() { + println() + } } diff --git a/detekt-rules/src/test/resources/cases/TrailingWhitespaceNegative.kt b/detekt-rules/src/test/resources/cases/TrailingWhitespaceNegative.kt index a9ce067fc..3e69dbcc8 100644 --- a/detekt-rules/src/test/resources/cases/TrailingWhitespaceNegative.kt +++ b/detekt-rules/src/test/resources/cases/TrailingWhitespaceNegative.kt @@ -3,7 +3,7 @@ package cases @Suppress("unused") class TrailingWhitespaceNegative { - fun myFunction() { - println("A message") - } + fun myFunction() { + println("A message") + } } diff --git a/detekt-rules/src/test/resources/cases/UnconditionalJumpStatementInLoopNegative.kt b/detekt-rules/src/test/resources/cases/UnconditionalJumpStatementInLoopNegative.kt index dc7bf3a35..f5332e4c0 100644 --- a/detekt-rules/src/test/resources/cases/UnconditionalJumpStatementInLoopNegative.kt +++ b/detekt-rules/src/test/resources/cases/UnconditionalJumpStatementInLoopNegative.kt @@ -3,19 +3,19 @@ package cases fun jumpStatementNestedOk() { - for (i in 1..2) { - try { - break - } finally { - } - } + for (i in 1..2) { + try { + break + } finally { + } + } } fun jumpStatementInIf() { - for (i in 1..2) { - if (i > 1) { - break - } - if (i > 1) println() else break - } + for (i in 1..2) { + if (i > 1) { + break + } + if (i > 1) println() else break + } } diff --git a/detekt-rules/src/test/resources/cases/UnconditionalJumpStatementInLoopPositive.kt b/detekt-rules/src/test/resources/cases/UnconditionalJumpStatementInLoopPositive.kt index d0ce9af80..ca155b212 100644 --- a/detekt-rules/src/test/resources/cases/UnconditionalJumpStatementInLoopPositive.kt +++ b/detekt-rules/src/test/resources/cases/UnconditionalJumpStatementInLoopPositive.kt @@ -3,30 +3,30 @@ package cases fun unconditionalJumpStatementsInLoop() { // reports 5 - 1 for every jump statement - for (i in 1..2) break - for (i in 1..2) continue - for (i in 1..2) return - while (true) break - do { - break - } while (true) + for (i in 1..2) break + for (i in 1..2) continue + for (i in 1..2) return + while (true) break + do { + break + } while (true) } fun unconditionalJumpStatementsInLoop2() { - for (i in 1..2) { - break // reports 1 - dead code - print("") - } - for (i in 1..2) { - print("") - break // reports 1 - } + for (i in 1..2) { + break // reports 1 - dead code + print("") + } + for (i in 1..2) { + print("") + break // reports 1 + } } fun unconditionalJumpStatementInNestedLoop() { // reports 1 - for (i in 1..2) { - for (j in 1..2) { - break - } - } + for (i in 1..2) { + for (j in 1..2) { + break + } + } } diff --git a/detekt-rules/src/test/resources/cases/UnnecessaryAbstractClassNegative.kt b/detekt-rules/src/test/resources/cases/UnnecessaryAbstractClassNegative.kt index 203e854d4..dbd96122c 100644 --- a/detekt-rules/src/test/resources/cases/UnnecessaryAbstractClassNegative.kt +++ b/detekt-rules/src/test/resources/cases/UnnecessaryAbstractClassNegative.kt @@ -6,24 +6,26 @@ import jdk.nashorn.internal.ir.annotations.Ignore abstract class AbstractClassOk { - abstract val i: Int - fun f() { } + abstract val i: Int + fun f() {} } abstract class AbstractClassWithPrimaryConstructorConcretePropertyOk(val i: Int) { - abstract fun f() + abstract fun f() } // empty abstract classes should not be reported by this rule abstract class EmptyAbstractClass1 + abstract class EmptyAbstractClass2() // This test case should be removed when type resolution is available - see issue #727 abstract class AbstractClassDerivedFrom : EmptyAbstractClass1() { - fun f() {} + fun f() {} } -@Ignore abstract class AbstractClassWithModuleAnnotation { - abstract fun binds(foo: Integer): Number +@Ignore +abstract class AbstractClassWithModuleAnnotation { + abstract fun binds(foo: Integer): Number } diff --git a/detekt-rules/src/test/resources/cases/UnnecessaryAbstractClassPositive.kt b/detekt-rules/src/test/resources/cases/UnnecessaryAbstractClassPositive.kt index 4e6892dba..4f7656b49 100644 --- a/detekt-rules/src/test/resources/cases/UnnecessaryAbstractClassPositive.kt +++ b/detekt-rules/src/test/resources/cases/UnnecessaryAbstractClassPositive.kt @@ -4,28 +4,28 @@ package cases abstract class OnlyAbstractMembersInAbstractClass { // violation: no concrete members - abstract val i: Int - abstract fun f() + abstract val i: Int + abstract fun f() } abstract class OnlyConcreteMembersInAbstractClass { // violation: no abstract members - val i: Int = 0 - fun f() { } + val i: Int = 0 + fun f() {} } class ConcreteClass { - abstract class NestedAbstractClass { // violation: no abstract members - fun f() { } - } + abstract class NestedAbstractClass { // violation: no abstract members + fun f() {} + } } interface AbstractInterface { - abstract class NestedAbstractClass { // violation: no abstract members - fun f() { } - } + abstract class NestedAbstractClass { // violation: no abstract members + fun f() {} + } } abstract class OnlyConcreteMembersInAbstractClassWithPrimaryCtor1(val i: Int) {} // violation: no abstract members diff --git a/detekt-rules/src/test/resources/cases/UnreachableCode.kt b/detekt-rules/src/test/resources/cases/UnreachableCode.kt index d604788cb..10898c5a2 100644 --- a/detekt-rules/src/test/resources/cases/UnreachableCode.kt +++ b/detekt-rules/src/test/resources/cases/UnreachableCode.kt @@ -3,54 +3,54 @@ package cases @Suppress("unused", "UNREACHABLE_CODE") class UnreachableCode { - fun return1(p: Int) { - if (p == 0) { - return - println() // report 1 - unreachable code - } - } + fun return1(p: Int) { + if (p == 0) { + return + println() // report 1 - unreachable code + } + } - fun return2(p: String) : Boolean { - p.let { - return it.length < 3 - println() // report 1 - unreachable code - } - return false - } + fun return2(p: String): Boolean { + p.let { + return it.length < 3 + println() // report 1 - unreachable code + } + return false + } - fun returnLabel1(ints: List): List { - return ints.map f@{ - if (it == 0) { - return@f 0 - println() // report 1 - unreachable code - } - return@f 1 - } - } + fun returnLabel1(ints: List): List { + return ints.map f@{ + if (it == 0) { + return@f 0 + println() // report 1 - unreachable code + } + return@f 1 + } + } - fun returnLabel2(ints: List) { - ints.forEach { - if (it == 0) return@forEach - println() - } - } + fun returnLabel2(ints: List) { + ints.forEach { + if (it == 0) return@forEach + println() + } + } - fun throw1(p: Int): Int { - if (p == 0) { - throw IllegalArgumentException() - println() // report 1 - unreachable code - } - throw IllegalArgumentException() - } + fun throw1(p: Int): Int { + if (p == 0) { + throw IllegalArgumentException() + println() // report 1 - unreachable code + } + throw IllegalArgumentException() + } - fun breakAndContinue() { - for (i in 1..2) { - break - println() // report 1 - unreachable code - } - for (i in 1..2) { - continue - println() // report 1 - unreachable code - } - } + fun breakAndContinue() { + for (i in 1..2) { + break + println() // report 1 - unreachable code + } + for (i in 1..2) { + continue + println() // report 1 - unreachable code + } + } } diff --git a/detekt-rules/src/test/resources/cases/UnusedPrivateMemberNegative.kt b/detekt-rules/src/test/resources/cases/UnusedPrivateMemberNegative.kt index e04e4c138..9d4adb777 100644 --- a/detekt-rules/src/test/resources/cases/UnusedPrivateMemberNegative.kt +++ b/detekt-rules/src/test/resources/cases/UnusedPrivateMemberNegative.kt @@ -5,106 +5,108 @@ package cases import kotlin.reflect.KProperty object O { // public - const val NUMBER = 5 // public + const val NUMBER = 5 // public } private object PO { // private, but constants may be used - const val TEXT = "text" + const val TEXT = "text" } class C { - val myNumber = 5 + val myNumber = 5 - fun publicFunction(usedParam: String) { - println(usedParam) - println(PC.THE_CONST) - println("Hello " ext "World" ext "!") - println(::doubleColonObjectReferenced) - println(this::doubleColonThisReferenced) - } + fun publicFunction(usedParam: String) { + println(usedParam) + println(PC.THE_CONST) + println("Hello " ext "World" ext "!") + println(::doubleColonObjectReferenced) + println(this::doubleColonThisReferenced) + } - fun usesAllowedNames() { - for ((index, _) in mapOf(0 to 0, 1 to 1, 2 to 2)) { // unused but allowed name - println(index) - } - try { - } catch (_: OutOfMemoryError) { // unused but allowed name - } - } + fun usesAllowedNames() { + for ((index, _) in mapOf(0 to 0, 1 to 1, 2 to 2)) { // unused but allowed name + println(index) + } + try { + } catch (_: OutOfMemoryError) { // unused but allowed name + } + } - private fun doubleColonThisReferenced() {} + private fun doubleColonThisReferenced() {} - companion object { - private infix fun String.ext(other: String): String { - return this + other - } - private fun doubleColonObjectReferenced() {} - } + companion object { + private infix fun String.ext(other: String): String { + return this + other + } + + private fun doubleColonObjectReferenced() {} + } } private class PC { // used private class - companion object { - internal const val THE_CONST = "" // used private const - object OO { - const val BLA = 4 - } - } + companion object { + internal const val THE_CONST = "" // used private const + + object OO { + const val BLA = 4 + } + } } internal fun libraryFunction() = run { - val o: Function1 = object : Function1 { - override fun invoke(p1: Any): Any { // unused but overridden param - throw UnsupportedOperationException("not implemented") - } - } - println(o("${PC.Companion.OO.BLA.toString() + ""}")) + val o: Function1 = object : Function1 { + override fun invoke(p1: Any): Any { // unused but overridden param + throw UnsupportedOperationException("not implemented") + } + } + println(o("${PC.Companion.OO.BLA.toString() + ""}")) } internal class IC // unused but internal val stuff = object : Iterator { - var mutatable: String? = null + var mutatable: String? = null - private fun preCall() { - mutatable = "done" - } + private fun preCall() { + mutatable = "done" + } - override fun next(): String? { - preCall() - return mutatable - } + override fun next(): String? { + preCall() + return mutatable + } - override fun hasNext(): Boolean = true + override fun hasNext(): Boolean = true } fun main(args: Array) { - println(stuff.next()) - calledFromMain() + println(stuff.next()) + calledFromMain() } -private fun calledFromMain() { } +private fun calledFromMain() {} abstract class Parent { - abstract fun abstractFun(arg: Any) - open fun openFun(arg: Any): Int = 0 + abstract fun abstractFun(arg: Any) + open fun openFun(arg: Any): Int = 0 } class Child : Parent() { - override fun abstractFun(arg: Any) { - println(arg) - } + override fun abstractFun(arg: Any) { + println(arg) + } - override fun openFun(arg: Any): Int { - println(arg) - return 1 - } + override fun openFun(arg: Any): Int { + println(arg) + return 1 + } } class SingleAssign { - // ignore unused operator function parameters - operator fun getValue(thisRef: Any?, property: KProperty<*>): kotlin.String { - return "" - } + // ignore unused operator function parameters + operator fun getValue(thisRef: Any?, property: KProperty<*>): kotlin.String { + return "" + } } diff --git a/detekt-rules/src/test/resources/cases/UnusedPrivateMemberPositive.kt b/detekt-rules/src/test/resources/cases/UnusedPrivateMemberPositive.kt index 8505e7e3b..1d4d38bff 100644 --- a/detekt-rules/src/test/resources/cases/UnusedPrivateMemberPositive.kt +++ b/detekt-rules/src/test/resources/cases/UnusedPrivateMemberPositive.kt @@ -2,24 +2,24 @@ // reports 1 violation for every unused* element class UnusedPrivateMemberPositive { - private val unusedField = 5 - val publicField = 2 - private val clashingName = 4 - private fun unusedFunction(unusedParam: Int) { - val unusedLocal = 5 - } + private val unusedField = 5 + val publicField = 2 + private val clashingName = 4 + private fun unusedFunction(unusedParam: Int) { + val unusedLocal = 5 + } } object UnusedPrivateMemberPositiveObject { - private const val unusedObjectConst = 2 - private val unusedField = 5 - private val clashingName = 5 - val useForClashingName = clashingName - private val unusedObjectField = 4 + private const val unusedObjectConst = 2 + private val unusedField = 5 + private val clashingName = 5 + val useForClashingName = clashingName + private val unusedObjectField = 4 - object Foo { - private val unusedNestedVal = 1 - } + object Foo { + private val unusedNestedVal = 1 + } } private fun unusedTopLevelFunction() = 5 @@ -29,15 +29,16 @@ private const val unusedTopLevelConst = 1 private val unusedTopLevelVal = usedTopLevelVal private class ClassWithSecondaryConstructor { - constructor(used: Any, unused: Any) { - used.toString() - } - // this is actually unused, but clashes with the other constructor - constructor(used: Any) + constructor(used: Any, unused: Any) { + used.toString() + } + + // this is actually unused, but clashes with the other constructor + constructor(used: Any) } fun main(args: Array) { - println("") + println("") } -private fun unusedAndNotCalledFromMain() { } // unused +private fun unusedAndNotCalledFromMain() {} // unused diff --git a/detekt-rules/src/test/resources/cases/UseDataClassNegative.kt b/detekt-rules/src/test/resources/cases/UseDataClassNegative.kt index 3ee673492..99846c126 100644 --- a/detekt-rules/src/test/resources/cases/UseDataClassNegative.kt +++ b/detekt-rules/src/test/resources/cases/UseDataClassNegative.kt @@ -4,38 +4,38 @@ package cases class NoDataClassCandidate(val i: Int) { - val i2: Int = 0 + val i2: Int = 0 - fun f() { - println() - } + fun f() { + println() + } - object Obj + object Obj } class NoDataClassCandidateWithAdditionalMethod(val i: Int) { - fun f1() { - println() - } + fun f1() { + println() + } } class NoDataClassCandidateWithOnlyPrivateCtor1 private constructor(val i: Int) class NoDataClassCandidateWithOnlyPrivateCtor2 { - @Suppress("ConvertSecondaryConstructorToPrimary") - private constructor(i: Int) + @Suppress("ConvertSecondaryConstructorToPrimary") + private constructor(i: Int) } sealed class NoDataClassBecauseItsSealed { - data class Success(val any: Any) : NoDataClassBecauseItsSealed() - data class Error(val error: Throwable) : NoDataClassBecauseItsSealed() + data class Success(val any: Any) : NoDataClassBecauseItsSealed() + data class Error(val error: Throwable) : NoDataClassBecauseItsSealed() } enum class EnumNoDataClass(val i: Int) { - FIRST(1), SECOND(2); + FIRST(1), SECOND(2); } annotation class AnnotationNoDataClass(val i: Int) diff --git a/detekt-rules/src/test/resources/cases/UseDataClassPositive.kt b/detekt-rules/src/test/resources/cases/UseDataClassPositive.kt index d882c0328..81f2a7f1e 100644 --- a/detekt-rules/src/test/resources/cases/UseDataClassPositive.kt +++ b/detekt-rules/src/test/resources/cases/UseDataClassPositive.kt @@ -6,30 +6,30 @@ class DataClassCandidate1(val i: Int) // reports 1 class DataClassCandidateWithProperties(val i: Int) { // reports 1 - val i2: Int = 0 + val i2: Int = 0 } class DataClassCandidate2(val s: String) { // reports 1 - also has a public constructor - private constructor(i: Int) : this(i.toString()) + private constructor(i: Int) : this(i.toString()) } class DataClassCandidate3 private constructor(val s: String) { // reports 1 - also has a public constructor - constructor(i: Int) : this(i.toString()) + constructor(i: Int) : this(i.toString()) } class DataClassCandidateWithOverriddenMethods(val i: Int) { // reports 1 - override fun equals(other: Any?): Boolean { - return super.equals(other) - } + override fun equals(other: Any?): Boolean { + return super.equals(other) + } - override fun hashCode(): Int { - return super.hashCode() - } + override fun hashCode(): Int { + return super.hashCode() + } - override fun toString(): String { - return super.toString() - } + override fun toString(): String { + return super.toString() + } } diff --git a/detekt-rules/src/test/resources/cases/UtilityClassesNegative.kt b/detekt-rules/src/test/resources/cases/UtilityClassesNegative.kt index f7b5261f1..c80d87ee4 100644 --- a/detekt-rules/src/test/resources/cases/UtilityClassesNegative.kt +++ b/detekt-rules/src/test/resources/cases/UtilityClassesNegative.kt @@ -4,106 +4,106 @@ package cases class UtilityClassWithPrimaryPrivateConstructorOk private constructor() { - companion object { - val C = 0 - } + companion object { + val C = 0 + } } class UtilityClassWithPrimaryInternalConstructorOk internal constructor() { - companion object { - val C = 0 - } + companion object { + val C = 0 + } } class UtilityClassWithSecondaryConstructorOk { - private constructor() + private constructor() - companion object { - val C = 0 - } + companion object { + val C = 0 + } } class NoUtilityClassBecauseOfInterface : InterfaceWithCompanionObject { - constructor() + constructor() - companion object { - val C = 0 - } + companion object { + val C = 0 + } } -open class UtilityClassesNegativeParent(val i : Int) +open class UtilityClassesNegativeParent(val i: Int) class NoUtilityClassBecauseOfInheritance : UtilityClassesNegativeParent { - constructor(i: Int) : super(i) + constructor(i: Int) : super(i) - companion object { - val C = 0 - } + companion object { + val C = 0 + } } class NoUtilityClasses { - private val i = 0 + private val i = 0 - class EmptyClass1 { } - class EmptyClass2 + class EmptyClass1 {} + class EmptyClass2 - class ClassWithSecondaryConstructor { - constructor() - } + class ClassWithSecondaryConstructor { + constructor() + } - class ClassWithInstanceFunc { + class ClassWithInstanceFunc { - fun f() {} + fun f() {} - companion object { - val C = 0 - } - } + companion object { + val C = 0 + } + } - class ClassWithPrimaryConstructorParameter1(val i: Int) { + class ClassWithPrimaryConstructorParameter1(val i: Int) { - companion object { - val C = 0 - } - } + companion object { + val C = 0 + } + } - class ClassWithPrimaryConstructorParameter2 constructor(val i: Int) { + class ClassWithPrimaryConstructorParameter2 constructor(val i: Int) { - companion object { - val C = 0 - } - } + companion object { + val C = 0 + } + } - class ClassWithSecondaryConstructorParameter { + class ClassWithSecondaryConstructorParameter { - constructor(i: Int) + constructor(i: Int) - companion object { - val C = 0 - } - } + companion object { + val C = 0 + } + } - companion object { - val C = 0 - } + companion object { + val C = 0 + } } interface InterfaceWithCompanionObject { - companion object { - val C = 0 - } + companion object { + val C = 0 + } } interface SomeInterface class SomeImplementation : SomeInterface class NotUtilityClass : SomeInterface by SomeImplementation() { - // Issue#682 - Class with delegate is no utility class - companion object { - val C = 0 - } + // Issue#682 - Class with delegate is no utility class + companion object { + val C = 0 + } } diff --git a/detekt-rules/src/test/resources/cases/UtilityClassesPositive.kt b/detekt-rules/src/test/resources/cases/UtilityClassesPositive.kt index 3e30a7511..54589d4c3 100644 --- a/detekt-rules/src/test/resources/cases/UtilityClassesPositive.kt +++ b/detekt-rules/src/test/resources/cases/UtilityClassesPositive.kt @@ -4,44 +4,44 @@ package cases class UtilityClassWithDefaultConstructor { // violation - companion object { - val C = 0 - } + companion object { + val C = 0 + } } class UtilityClassWithPrimaryConstructor1 constructor() { // violation - companion object { - val C = 0 - } + companion object { + val C = 0 + } } class UtilityClassWithPrimaryConstructor2() { // violation - companion object { - val C = 0 - } + companion object { + val C = 0 + } } class UtilityClassWithSecondaryConstructor { // violation - constructor() + constructor() - companion object { - val C = 0 - } + companion object { + val C = 0 + } } class UtilityClassWithEmptyCompanionObj { // violation - companion object + companion object } open class OpenUtilityClass { // violation - utility class should be final - internal constructor() + internal constructor() - companion object { - val C = 0 - } + companion object { + val C = 0 + } } diff --git a/detekt-sample-extensions/build.gradle.kts b/detekt-sample-extensions/build.gradle.kts index 284b121a6..ca39204cc 100644 --- a/detekt-sample-extensions/build.gradle.kts +++ b/detekt-sample-extensions/build.gradle.kts @@ -4,14 +4,14 @@ val junitPlatformVersion: String by project val spekVersion: String by project dependencies { - implementation("io.gitlab.arturbosch.detekt:detekt-api:$usedDetektVersion") - implementation(kotlin("compiler-embeddable")) + implementation("io.gitlab.arturbosch.detekt:detekt-api:$usedDetektVersion") + implementation(kotlin("compiler-embeddable")) - testImplementation("io.gitlab.arturbosch.detekt:detekt-test:$usedDetektVersion") - testImplementation("org.assertj:assertj-core:$assertjVersion") - testImplementation("org.jetbrains.spek:spek-api:$spekVersion") - testImplementation("org.jetbrains.spek:spek-subject-extension:$spekVersion") + testImplementation("io.gitlab.arturbosch.detekt:detekt-test:$usedDetektVersion") + testImplementation("org.assertj:assertj-core:$assertjVersion") + testImplementation("org.jetbrains.spek:spek-api:$spekVersion") + testImplementation("org.jetbrains.spek:spek-subject-extension:$spekVersion") - testRuntimeOnly("org.junit.platform:junit-platform-launcher:$junitPlatformVersion") - testRuntimeOnly("org.jetbrains.spek:spek-junit-platform-engine:$spekVersion") + testRuntimeOnly("org.junit.platform:junit-platform-launcher:$junitPlatformVersion") + testRuntimeOnly("org.jetbrains.spek:spek-junit-platform-engine:$spekVersion") } diff --git a/detekt-sample-extensions/src/main/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/SampleProvider.kt b/detekt-sample-extensions/src/main/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/SampleProvider.kt index 678d37241..7b7d58a7a 100644 --- a/detekt-sample-extensions/src/main/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/SampleProvider.kt +++ b/detekt-sample-extensions/src/main/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/SampleProvider.kt @@ -11,12 +11,12 @@ import io.gitlab.arturbosch.detekt.sample.extensions.rules.TooManyFunctionsTwo */ class SampleProvider : RuleSetProvider { - override val ruleSetId: String = "sample" + override val ruleSetId: String = "sample" - override fun instance(config: Config): RuleSet { - return RuleSet(ruleSetId, listOf( - TooManyFunctions(), - TooManyFunctionsTwo(config) - )) - } + override fun instance(config: Config): RuleSet { + return RuleSet(ruleSetId, listOf( + TooManyFunctions(), + TooManyFunctionsTwo(config) + )) + } } diff --git a/detekt-sample-extensions/src/main/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/processors/NumberOfLoopsProcessor.kt b/detekt-sample-extensions/src/main/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/processors/NumberOfLoopsProcessor.kt index 72648d68d..b38c07946 100644 --- a/detekt-sample-extensions/src/main/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/processors/NumberOfLoopsProcessor.kt +++ b/detekt-sample-extensions/src/main/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/processors/NumberOfLoopsProcessor.kt @@ -11,22 +11,22 @@ import org.jetbrains.kotlin.psi.KtLoopExpression */ class NumberOfLoopsProcessor : FileProcessListener { - override fun onProcess(file: KtFile) { - val visitor = LoopVisitor() - file.accept(visitor) - file.putUserData(numberOfLoopsKey, visitor.numberOfLoops) - } + override fun onProcess(file: KtFile) { + val visitor = LoopVisitor() + file.accept(visitor) + file.putUserData(numberOfLoopsKey, visitor.numberOfLoops) + } - companion object { - val numberOfLoopsKey = Key("number of loops") - } + companion object { + val numberOfLoopsKey = Key("number of loops") + } - class LoopVisitor : DetektVisitor() { + class LoopVisitor : DetektVisitor() { - internal var numberOfLoops = 0 - override fun visitLoopExpression(loopExpression: KtLoopExpression) { - super.visitLoopExpression(loopExpression) - numberOfLoops++ - } - } + internal var numberOfLoops = 0 + override fun visitLoopExpression(loopExpression: KtLoopExpression) { + super.visitLoopExpression(loopExpression) + numberOfLoops++ + } + } } diff --git a/detekt-sample-extensions/src/main/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/processors/QualifiedNameProcessor.kt b/detekt-sample-extensions/src/main/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/processors/QualifiedNameProcessor.kt index a33dbb1aa..83f7b9563 100644 --- a/detekt-sample-extensions/src/main/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/processors/QualifiedNameProcessor.kt +++ b/detekt-sample-extensions/src/main/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/processors/QualifiedNameProcessor.kt @@ -12,28 +12,28 @@ import org.jetbrains.kotlin.psi.KtFile */ class QualifiedNameProcessor : FileProcessListener { - override fun onProcess(file: KtFile) { - val packageName = file.packageFqName.asString() - val nameVisitor = ClassNameVisitor() - file.accept(nameVisitor) - val fqNames = nameVisitor.names.mapTo(HashSet()) { "$packageName.$it" } - file.putUserData(fqNamesKey, fqNames) - } + override fun onProcess(file: KtFile) { + val packageName = file.packageFqName.asString() + val nameVisitor = ClassNameVisitor() + file.accept(nameVisitor) + val fqNames = nameVisitor.names.mapTo(HashSet()) { "$packageName.$it" } + file.putUserData(fqNamesKey, fqNames) + } - override fun onFinish(files: List, result: Detektion) { - val fqNames = files.mapNotNull { it.getUserData(fqNamesKey) } - .flatMapTo(HashSet()) { it } - result.addData(fqNamesKey, fqNames) - } + override fun onFinish(files: List, result: Detektion) { + val fqNames = files.mapNotNull { it.getUserData(fqNamesKey) } + .flatMapTo(HashSet()) { it } + result.addData(fqNamesKey, fqNames) + } - class ClassNameVisitor : DetektVisitor() { + class ClassNameVisitor : DetektVisitor() { - val names = mutableSetOf() + val names = mutableSetOf() - override fun visitClassOrObject(classOrObject: KtClassOrObject) { - names.add(classOrObject.nameAsSafeName.asString()) - } - } + override fun visitClassOrObject(classOrObject: KtClassOrObject) { + names.add(classOrObject.nameAsSafeName.asString()) + } + } } val fqNamesKey: Key> = Key.create>("FQNames") diff --git a/detekt-sample-extensions/src/main/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/reports/QualifiedNamesConsoleReport.kt b/detekt-sample-extensions/src/main/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/reports/QualifiedNamesConsoleReport.kt index 012ab1a66..12615c913 100644 --- a/detekt-sample-extensions/src/main/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/reports/QualifiedNamesConsoleReport.kt +++ b/detekt-sample-extensions/src/main/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/reports/QualifiedNamesConsoleReport.kt @@ -8,7 +8,7 @@ import io.gitlab.arturbosch.detekt.api.Detektion */ class QualifiedNamesConsoleReport : ConsoleReport() { - override fun render(detektion: Detektion): String? { - return qualifiedNamesReport(detektion) - } + override fun render(detektion: Detektion): String? { + return qualifiedNamesReport(detektion) + } } diff --git a/detekt-sample-extensions/src/main/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/reports/QualifiedNamesOutputReport.kt b/detekt-sample-extensions/src/main/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/reports/QualifiedNamesOutputReport.kt index ee3acceaf..89b5d02dc 100644 --- a/detekt-sample-extensions/src/main/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/reports/QualifiedNamesOutputReport.kt +++ b/detekt-sample-extensions/src/main/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/reports/QualifiedNamesOutputReport.kt @@ -9,10 +9,10 @@ import io.gitlab.arturbosch.detekt.api.OutputReport */ class QualifiedNamesOutputReport : OutputReport() { - var fileName: String = "fqNames" - override val ending: String = "txt" + var fileName: String = "fqNames" + override val ending: String = "txt" - override fun render(detektion: Detektion): String? { - return qualifiedNamesReport(detektion) - } + override fun render(detektion: Detektion): String? { + return qualifiedNamesReport(detektion) + } } diff --git a/detekt-sample-extensions/src/main/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/reports/Reports.kt b/detekt-sample-extensions/src/main/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/reports/Reports.kt index 784093e68..d1a48933c 100644 --- a/detekt-sample-extensions/src/main/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/reports/Reports.kt +++ b/detekt-sample-extensions/src/main/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/reports/Reports.kt @@ -5,17 +5,17 @@ import org.jetbrains.kotlin.com.intellij.openapi.util.Key @Suppress("UNCHECKED_CAST", "DEPRECATION") fun qualifiedNamesReport(detektion: Detektion): String? { - // referencing the original key 'fqNamesKey' does not retrieve the stored values - // using the deprecated method seems to work for unknown reasons - val key = Key.findKeyByName("FQNames") as Key> - val fqNames = detektion.getData(key) - println("fqNames: " + fqNames) - if (fqNames == null || fqNames.isEmpty()) return null + // referencing the original key 'fqNamesKey' does not retrieve the stored values + // using the deprecated method seems to work for unknown reasons + val key = Key.findKeyByName("FQNames") as Key> + val fqNames = detektion.getData(key) + println("fqNames: " + fqNames) + if (fqNames == null || fqNames.isEmpty()) return null - return with(StringBuilder()) { - fqNames.forEach { - append(it + "\n") - } - toString() - } + return with(StringBuilder()) { + fqNames.forEach { + append(it + "\n") + } + toString() + } } diff --git a/detekt-sample-extensions/src/main/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/rules/TooManyFunctions.kt b/detekt-sample-extensions/src/main/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/rules/TooManyFunctions.kt index 35dcf5acc..d1a2ecbc6 100644 --- a/detekt-sample-extensions/src/main/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/rules/TooManyFunctions.kt +++ b/detekt-sample-extensions/src/main/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/rules/TooManyFunctions.kt @@ -17,25 +17,25 @@ import org.jetbrains.kotlin.psi.KtNamedFunction */ class TooManyFunctions : Rule() { - override val issue = Issue(javaClass.simpleName, - Severity.CodeSmell, - "This rule reports a file with an excessive function count.", - Debt.TWENTY_MINS) + override val issue = Issue(javaClass.simpleName, + Severity.CodeSmell, + "This rule reports a file with an excessive function count.", + Debt.TWENTY_MINS) - private var amount: Int = 0 + private var amount: Int = 0 - override fun visitFile(file: PsiFile) { - super.visitFile(file) - if (amount > THRESHOLD) { - report(CodeSmell(issue, Entity.from(file), - message = "The file ${file.name} has $amount function declarations. " + - "Threshold is specified with $THRESHOLD.")) - } - } + override fun visitFile(file: PsiFile) { + super.visitFile(file) + if (amount > THRESHOLD) { + report(CodeSmell(issue, Entity.from(file), + message = "The file ${file.name} has $amount function declarations. " + + "Threshold is specified with $THRESHOLD.")) + } + } - override fun visitNamedFunction(function: KtNamedFunction) { - amount++ - } + override fun visitNamedFunction(function: KtNamedFunction) { + amount++ + } } const val THRESHOLD = 10 diff --git a/detekt-sample-extensions/src/main/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/rules/TooManyFunctionsTwo.kt b/detekt-sample-extensions/src/main/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/rules/TooManyFunctionsTwo.kt index 8ee1d2ef7..ebbe11337 100644 --- a/detekt-sample-extensions/src/main/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/rules/TooManyFunctionsTwo.kt +++ b/detekt-sample-extensions/src/main/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/rules/TooManyFunctionsTwo.kt @@ -23,27 +23,27 @@ import org.jetbrains.kotlin.psi.KtNamedFunction */ class TooManyFunctionsTwo(config: Config) : ThresholdRule(config, THRESHOLD) { - override val issue = Issue(javaClass.simpleName, - Severity.Maintainability, - "Too many functions can make the maintainability of a file more costly", - Debt(hours = 1)) + override val issue = Issue(javaClass.simpleName, + Severity.Maintainability, + "Too many functions can make the maintainability of a file more costly", + Debt(hours = 1)) - private var amount: Int = 0 + private var amount: Int = 0 - override fun visitFile(file: PsiFile) { - super.visitFile(file) - if (amount > threshold) { - report(ThresholdedCodeSmell(issue, - entity = Entity.from(file), - metric = Metric(type = "SIZE", value = amount, threshold = THRESHOLD), - message = "The file ${file.name} has $amount function declarations. " + - "Threshold is specified with $THRESHOLD.", - references = emptyList()) - ) - } - } + override fun visitFile(file: PsiFile) { + super.visitFile(file) + if (amount > threshold) { + report(ThresholdedCodeSmell(issue, + entity = Entity.from(file), + metric = Metric(type = "SIZE", value = amount, threshold = THRESHOLD), + message = "The file ${file.name} has $amount function declarations. " + + "Threshold is specified with $THRESHOLD.", + references = emptyList()) + ) + } + } - override fun visitNamedFunction(function: KtNamedFunction) { - amount++ - } + override fun visitNamedFunction(function: KtNamedFunction) { + amount++ + } } diff --git a/detekt-sample-extensions/src/test/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/TooManyFunctionsSpec.kt b/detekt-sample-extensions/src/test/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/TooManyFunctionsSpec.kt index 33bab9fdf..d14becad5 100644 --- a/detekt-sample-extensions/src/test/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/TooManyFunctionsSpec.kt +++ b/detekt-sample-extensions/src/test/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/TooManyFunctionsSpec.kt @@ -12,19 +12,19 @@ import org.jetbrains.spek.subject.SubjectSpek */ class TooManyFunctionsSpec : SubjectSpek({ - subject { TooManyFunctions() } + subject { TooManyFunctions() } - describe("a simple test") { + describe("a simple test") { - it("should find one file with too many functions") { - val findings = subject.lint(code) - assertThat(findings).hasSize(1) - } - } + it("should find one file with too many functions") { + val findings = subject.lint(code) + assertThat(findings).hasSize(1) + } + } }) const val code: String = - """ + """ class TooManyFunctions : Rule("TooManyFunctions") { override fun visitUserType(type: KtUserType) { diff --git a/detekt-sample-extensions/src/test/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/processors/NumberOfLoopsProcessorSpec.kt b/detekt-sample-extensions/src/test/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/processors/NumberOfLoopsProcessorSpec.kt index a669ee61c..61e376846 100644 --- a/detekt-sample-extensions/src/test/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/processors/NumberOfLoopsProcessorSpec.kt +++ b/detekt-sample-extensions/src/test/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/processors/NumberOfLoopsProcessorSpec.kt @@ -11,8 +11,8 @@ import org.jetbrains.spek.api.dsl.it */ class NumberOfLoopsProcessorSpec : Spek({ - it("should expect two loops") { - val code = """ + it("should expect two loops") { + val code = """ fun main() { for (i in 0..10) { while (i < 5) { @@ -22,10 +22,10 @@ class NumberOfLoopsProcessorSpec : Spek({ } """ - val ktFile = compileContentForTest(code) - ktFile.accept(DetektVisitor()) - NumberOfLoopsProcessor().onProcess(ktFile) + val ktFile = compileContentForTest(code) + ktFile.accept(DetektVisitor()) + NumberOfLoopsProcessor().onProcess(ktFile) - assertThat(ktFile.getUserData(NumberOfLoopsProcessor.numberOfLoopsKey)).isEqualTo(2) - } + assertThat(ktFile.getUserData(NumberOfLoopsProcessor.numberOfLoopsKey)).isEqualTo(2) + } }) diff --git a/detekt-sample-extensions/src/test/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/processors/QualifiedNameProcessorTest.kt b/detekt-sample-extensions/src/test/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/processors/QualifiedNameProcessorTest.kt index d52a46f16..d719c8267 100644 --- a/detekt-sample-extensions/src/test/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/processors/QualifiedNameProcessorTest.kt +++ b/detekt-sample-extensions/src/test/kotlin/io/gitlab/arturbosch/detekt/sample/extensions/processors/QualifiedNameProcessorTest.kt @@ -16,40 +16,40 @@ import org.jetbrains.spek.api.dsl.it */ class QualifiedNameProcessorTest : Spek({ - it("fqNamesOfTestFiles") { - val ktFile = compileContentForTest(code) - val processor = QualifiedNameProcessor() - processor.onProcess(ktFile) - processor.onFinish(listOf(ktFile), result) + it("fqNamesOfTestFiles") { + val ktFile = compileContentForTest(code) + val processor = QualifiedNameProcessor() + processor.onProcess(ktFile) + processor.onFinish(listOf(ktFile), result) - val data = result.getData(fqNamesKey) - Assertions.assertThat(data).contains( - "io.gitlab.arturbosch.detekt.sample.Foo", - "io.gitlab.arturbosch.detekt.sample.Bar", - "io.gitlab.arturbosch.detekt.sample.Bla") - } + val data = result.getData(fqNamesKey) + Assertions.assertThat(data).contains( + "io.gitlab.arturbosch.detekt.sample.Foo", + "io.gitlab.arturbosch.detekt.sample.Bar", + "io.gitlab.arturbosch.detekt.sample.Bla") + } }) private val result = object : Detektion { - override val findings: Map> = mapOf() - override val notifications: Collection = listOf() - override val metrics: Collection = listOf() + override val findings: Map> = mapOf() + override val notifications: Collection = listOf() + override val metrics: Collection = listOf() - private var userData = KeyFMap.EMPTY_MAP - override fun getData(key: Key): V? = userData.get(key) + private var userData = KeyFMap.EMPTY_MAP + override fun getData(key: Key): V? = userData.get(key) - override fun addData(key: Key, value: V) { - userData = userData.plus(key, value) - } + override fun addData(key: Key, value: V) { + userData = userData.plus(key, value) + } - override fun add(notification: Notification) { - throw UnsupportedOperationException("not implemented") - } + override fun add(notification: Notification) { + throw UnsupportedOperationException("not implemented") + } - override fun add(projectMetric: ProjectMetric) { - throw UnsupportedOperationException("not implemented") - } + override fun add(projectMetric: ProjectMetric) { + throw UnsupportedOperationException("not implemented") + } } const val code = """ diff --git a/detekt-test/build.gradle.kts b/detekt-test/build.gradle.kts index 02911317d..ec063ec9a 100644 --- a/detekt-test/build.gradle.kts +++ b/detekt-test/build.gradle.kts @@ -1,10 +1,10 @@ val assertjVersion: String by project dependencies { - implementation(kotlin("script-runtime")) - implementation(kotlin("compiler-embeddable")) - implementation(kotlin("script-util")) + implementation(kotlin("script-runtime")) + implementation(kotlin("compiler-embeddable")) + implementation(kotlin("script-util")) - implementation(project(":detekt-core")) - implementation("org.assertj:assertj-core:$assertjVersion") + implementation(project(":detekt-core")) + implementation("org.assertj:assertj-core:$assertjVersion") } 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 34fea5bec..dbbbf2ed5 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 @@ -13,43 +13,43 @@ fun assertThat(finding: Finding) = FindingAssert(finding) fun List.assert() = FindingsAssert(this) class FindingsAssert(actual: List) : - AbstractListAssert, - Finding, FindingAssert>(actual, FindingsAssert::class.java) { + AbstractListAssert, + Finding, FindingAssert>(actual, FindingsAssert::class.java) { - override fun newAbstractIterableAssert(iterable: MutableIterable): FindingsAssert { - throw UnsupportedOperationException("not implemented") - } + override fun newAbstractIterableAssert(iterable: MutableIterable): FindingsAssert { + throw UnsupportedOperationException("not implemented") + } - override fun toAssert(value: Finding?, description: String?): FindingAssert = - FindingAssert(value).`as`(description) + override fun toAssert(value: Finding?, description: String?): FindingAssert = + FindingAssert(value).`as`(description) - fun hasLocationStrings(vararg expected: String, trimIndent: Boolean = false) { - isNotNull - val locationStrings = actual.asSequence().map { it.locationAsString }.sorted() - if (trimIndent) { - areEqual(locationStrings.map { it.trimIndent() }.toList(), expected.map { it.trimIndent() }.sorted()) - } else { - areEqual(locationStrings.toList(), expected.toList().sorted()) - } - } + fun hasLocationStrings(vararg expected: String, trimIndent: Boolean = false) { + isNotNull + val locationStrings = actual.asSequence().map { it.locationAsString }.sorted() + if (trimIndent) { + areEqual(locationStrings.map { it.trimIndent() }.toList(), expected.map { it.trimIndent() }.sorted()) + } else { + areEqual(locationStrings.toList(), expected.toList().sorted()) + } + } - fun hasSourceLocations(vararg expected: SourceLocation) { - isNotNull + fun hasSourceLocations(vararg expected: SourceLocation) { + isNotNull - val actualSources = actual.asSequence() - .map { it.location.source } - .sortedWith(compareBy({ it.line }, { it.column })) + val actualSources = actual.asSequence() + .map { it.location.source } + .sortedWith(compareBy({ it.line }, { it.column })) - val expectedSources = expected.asSequence() - .sortedWith(compareBy({ it.line }, { it.column })) + val expectedSources = expected.asSequence() + .sortedWith(compareBy({ it.line }, { it.column })) - areEqual(actualSources.toList(), expectedSources.toList()) - } + areEqual(actualSources.toList(), expectedSources.toList()) + } - private fun areEqual(actual: List, expected: List) { - Objects.instance() - .assertEqual(writableAssertionInfo, actual, expected) - } + private fun areEqual(actual: List, expected: List) { + Objects.instance() + .assertEqual(writableAssertionInfo, actual, expected) + } } class FindingAssert(val actual: Finding?) : AbstractAssert(actual, FindingAssert::class.java) diff --git a/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/KotlinScriptEngine.kt b/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/KotlinScriptEngine.kt index 002f5c915..257e254d7 100644 --- a/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/KotlinScriptEngine.kt +++ b/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/KotlinScriptEngine.kt @@ -1,9 +1,9 @@ package io.gitlab.arturbosch.detekt.test -import org.jetbrains.kotlin.cli.common.environment.setIdeaIoUseFallback -import org.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmLocalScriptEngine import javax.script.ScriptEngineManager import javax.script.ScriptException +import org.jetbrains.kotlin.cli.common.environment.setIdeaIoUseFallback +import org.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmLocalScriptEngine /** * The object to create the Kotlin script engine for code compilation. @@ -12,34 +12,34 @@ import javax.script.ScriptException */ object KotlinScriptEngine { - private lateinit var engine: KotlinJsr223JvmLocalScriptEngine + private lateinit var engine: KotlinJsr223JvmLocalScriptEngine - init { - createEngine() - } + init { + createEngine() + } - /** - * Compiles a given code string with the Jsr223 script engine. - * If a compilation error occurs the script engine is recovered. - * - * @param code The String to compile - * @throws ScriptException - */ - fun compile(code: String) { - try { - engine.compile(code) - } catch (e: ScriptException) { - createEngine() // recover - throw KotlinScriptException(e) - } - } + /** + * Compiles a given code string with the Jsr223 script engine. + * If a compilation error occurs the script engine is recovered. + * + * @param code The String to compile + * @throws ScriptException + */ + fun compile(code: String) { + try { + engine.compile(code) + } catch (e: ScriptException) { + createEngine() // recover + throw KotlinScriptException(e) + } + } - private fun createEngine() { - setIdeaIoUseFallback() // To avoid error on Windows + private fun createEngine() { + setIdeaIoUseFallback() // To avoid error on Windows - val scriptEngineManager = ScriptEngineManager() - val localEngine = scriptEngineManager.getEngineByExtension("kts") as? KotlinJsr223JvmLocalScriptEngine - requireNotNull(localEngine) { "Kotlin script engine not supported" } - engine = localEngine - } + val scriptEngineManager = ScriptEngineManager() + val localEngine = scriptEngineManager.getEngineByExtension("kts") as? KotlinJsr223JvmLocalScriptEngine + requireNotNull(localEngine) { "Kotlin script engine not supported" } + engine = localEngine + } } diff --git a/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/KtTestCompiler.kt b/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/KtTestCompiler.kt index f5af85655..163192e3d 100644 --- a/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/KtTestCompiler.kt +++ b/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/KtTestCompiler.kt @@ -1,11 +1,11 @@ package io.gitlab.arturbosch.detekt.test import io.gitlab.arturbosch.detekt.core.KtCompiler +import java.nio.file.Path +import java.nio.file.Paths import org.jetbrains.kotlin.com.intellij.openapi.util.text.StringUtilRt import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.psi.KtFile -import java.nio.file.Path -import java.nio.file.Paths /** * Test compiler extends kt compiler and adds ability to compile from text content. @@ -14,17 +14,17 @@ import java.nio.file.Paths */ object KtTestCompiler : KtCompiler() { - private val root = Paths.get(resource("/")) + private val root = Paths.get(resource("/")) - fun compile(path: Path) = compile(root, path) + fun compile(path: Path) = compile(root, path) - fun compileFromContent(content: String): KtFile { - val psiFile = psiFileFactory.createFileFromText( - TEST_FILENAME, - KotlinLanguage.INSTANCE, - StringUtilRt.convertLineSeparators(content)) - return psiFile as? KtFile ?: throw IllegalStateException("kotlin file expected") - } + fun compileFromContent(content: String): KtFile { + val psiFile = psiFileFactory.createFileFromText( + TEST_FILENAME, + KotlinLanguage.INSTANCE, + StringUtilRt.convertLineSeparators(content)) + return psiFile as? KtFile ?: throw IllegalStateException("kotlin file expected") + } } const val TEST_FILENAME = "Test.kt" diff --git a/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/Resources.kt b/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/Resources.kt index 40b706d99..72605bf85 100644 --- a/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/Resources.kt +++ b/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/Resources.kt @@ -6,10 +6,10 @@ import java.net.URI internal object Resources fun resource(name: String): URI { - val explicitName = if (name.startsWith("/")) name else "/$name" - val resource = Resources::class.java.getResource(explicitName) - requireNotNull(resource) { "Make sure the resource '$name' exists!" } - return resource.toURI() + val explicitName = if (name.startsWith("/")) name else "/$name" + val resource = Resources::class.java.getResource(explicitName) + requireNotNull(resource) { "Make sure the resource '$name' exists!" } + return resource.toURI() } fun yamlConfig(name: String) = YamlConfig.loadResource(resource(name).toURL()) diff --git a/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/RuleExtensions.kt b/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/RuleExtensions.kt index 429ddc4f7..e59884ec1 100644 --- a/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/RuleExtensions.kt +++ b/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/RuleExtensions.kt @@ -4,43 +4,43 @@ import io.gitlab.arturbosch.detekt.api.BaseRule import io.gitlab.arturbosch.detekt.api.Finding import io.gitlab.arturbosch.detekt.api.Rule import io.gitlab.arturbosch.detekt.test.KotlinScriptEngine.compile +import java.nio.file.Path import org.intellij.lang.annotations.Language import org.jetbrains.kotlin.psi.KtFile -import java.nio.file.Path fun BaseRule.compileAndLint(@Language("kotlin") content: String): List { - compile(content) - return lint(content) + compile(content) + return lint(content) } fun BaseRule.lint(content: String): List { - val ktFile = KtTestCompiler.compileFromContent(content.trimIndent()) - return findingsAfterVisit(ktFile) + val ktFile = KtTestCompiler.compileFromContent(content.trimIndent()) + return findingsAfterVisit(ktFile) } fun BaseRule.lint(path: Path): List { - val ktFile = KtTestCompiler.compile(path) - return findingsAfterVisit(ktFile) + val ktFile = KtTestCompiler.compile(path) + return findingsAfterVisit(ktFile) } fun BaseRule.lint(ktFile: KtFile) = findingsAfterVisit(ktFile) private fun BaseRule.findingsAfterVisit(ktFile: KtFile): List { - this.visitFile(ktFile) - return this.findings + this.visitFile(ktFile) + return this.findings } fun Rule.format(content: String): String { - val ktFile = KtTestCompiler.compileFromContent(content.trimIndent()) - return contentAfterVisit(ktFile) + val ktFile = KtTestCompiler.compileFromContent(content.trimIndent()) + return contentAfterVisit(ktFile) } fun Rule.format(path: Path): String { - val ktFile = KtTestCompiler.compile(path) - return contentAfterVisit(ktFile) + val ktFile = KtTestCompiler.compile(path) + return contentAfterVisit(ktFile) } private fun Rule.contentAfterVisit(ktFile: KtFile): String { - this.visit(ktFile) - return ktFile.text + this.visit(ktFile) + return ktFile.text } diff --git a/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/RuleSetExtensions.kt b/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/RuleSetExtensions.kt index bf3eb74c8..46841912f 100644 --- a/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/RuleSetExtensions.kt +++ b/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/RuleSetExtensions.kt @@ -7,5 +7,5 @@ import io.gitlab.arturbosch.detekt.api.RuleSetProvider * Creates a RuleSet instance of given RuleSetProvider. */ inline fun loadRuleSet(config: Config = Config.empty) = - (T::class.java.constructors[0].newInstance() as? T)?.buildRuleset(config) - ?: throw IllegalStateException("Could not load RuleSet for '${T::class.java}'") + (T::class.java.constructors[0].newInstance() as? T)?.buildRuleset(config) + ?: throw IllegalStateException("Could not load RuleSet for '${T::class.java}'") diff --git a/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/TestConfig.kt b/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/TestConfig.kt index ac87bfebb..15bc66f5d 100644 --- a/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/TestConfig.kt +++ b/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/TestConfig.kt @@ -8,37 +8,37 @@ import io.gitlab.arturbosch.detekt.api.BaseConfig @Suppress("UNCHECKED_CAST") open class TestConfig(private val values: Map = mutableMapOf()) : BaseConfig() { - override fun subConfig(key: String) = this + override fun subConfig(key: String) = this - override fun valueOrDefault(key: String, default: T) = when (key) { - "active" -> getActiveValue(default) as T - else -> valueOrDefaultInternal(values[key], default) as T - } + override fun valueOrDefault(key: String, default: T) = when (key) { + "active" -> getActiveValue(default) as T + else -> valueOrDefaultInternal(values[key], default) as T + } - private fun getActiveValue(default: T): Any { - val active = values["active"] - return if (active != null) valueOrDefaultInternal(active, default) else true - } + private fun getActiveValue(default: T): Any { + val active = values["active"] + return if (active != null) valueOrDefaultInternal(active, default) else true + } - override fun valueOrNull(key: String): T? = when (key) { - "active" -> (values["active"] ?: true) as T? - else -> values[key] as? T - } + override fun valueOrNull(key: String): T? = when (key) { + "active" -> (values["active"] ?: true) as T? + else -> values[key] as? T + } - override fun tryParseBasedOnDefault(result: String, defaultResult: Any): Any = when (defaultResult) { - is List<*> -> parseList(result) - is Set<*> -> parseList(result).toSet() - else -> super.tryParseBasedOnDefault(result, defaultResult) - } + override fun tryParseBasedOnDefault(result: String, defaultResult: Any): Any = when (defaultResult) { + is List<*> -> parseList(result) + is Set<*> -> parseList(result).toSet() + else -> super.tryParseBasedOnDefault(result, defaultResult) + } - protected fun parseList(result: String): List { - if (result.startsWith('[') && result.endsWith(']')) { - val str = result.substring(1, result.length - 1) - return str.splitToSequence(',') - .map { it.trim() } - .filter { it.isNotEmpty() } - .toList() - } - throw ClassCastException() - } + protected fun parseList(result: String): List { + if (result.startsWith('[') && result.endsWith(']')) { + val str = result.substring(1, result.length - 1) + return str.splitToSequence(',') + .map { it.trim() } + .filter { it.isNotEmpty() } + .toList() + } + throw ClassCastException() + } } diff --git a/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/ThresholdedCodeSmellAssert.kt b/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/ThresholdedCodeSmellAssert.kt index 1977ed230..e58e9afec 100644 --- a/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/ThresholdedCodeSmellAssert.kt +++ b/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/ThresholdedCodeSmellAssert.kt @@ -8,34 +8,34 @@ fun assertThat(thresholdedCodeSmell: ThresholdedCodeSmell) = ThresholdedCodeSmel @Suppress("UnsafeCast") // False positive, see issue #1137 fun FindingAssert.isThresholded(): ThresholdedCodeSmellAssert { - isNotNull - assert(actual is ThresholdedCodeSmell) { "The finding '$actual' is not a ThresholdedCodeSmell" } - return ThresholdedCodeSmellAssert(actual as ThresholdedCodeSmell?) + isNotNull + assert(actual is ThresholdedCodeSmell) { "The finding '$actual' is not a ThresholdedCodeSmell" } + return ThresholdedCodeSmellAssert(actual as ThresholdedCodeSmell?) } class ThresholdedCodeSmellAssert(actual: ThresholdedCodeSmell?) : - AbstractAssert( - actual, ThresholdedCodeSmellAssert::class.java) { + AbstractAssert( + actual, ThresholdedCodeSmellAssert::class.java) { - fun withValue(expected: Int) = hasValue(expected).let { this } + fun withValue(expected: Int) = hasValue(expected).let { this } - private val objects = Objects.instance() + private val objects = Objects.instance() - @Suppress("UnsafeCast") // False positive, see issue #1137 - fun hasValue(expected: Int) { - isNotNull + @Suppress("UnsafeCast") // False positive, see issue #1137 + fun hasValue(expected: Int) { + isNotNull - val smell = actual as ThresholdedCodeSmell - objects.assertEqual(writableAssertionInfo, smell.value, expected) - } + val smell = actual as ThresholdedCodeSmell + objects.assertEqual(writableAssertionInfo, smell.value, expected) + } - fun withThreshold(expected: Int) = hasThreshold(expected).let { this } + fun withThreshold(expected: Int) = hasThreshold(expected).let { this } - @Suppress("UnsafeCast") // False positive, see issue #1137 - fun hasThreshold(expected: Int) { - isNotNull + @Suppress("UnsafeCast") // False positive, see issue #1137 + fun hasThreshold(expected: Int) { + isNotNull - val smell = actual as ThresholdedCodeSmell - objects.assertEqual(writableAssertionInfo, smell.threshold, expected) - } + val smell = actual as ThresholdedCodeSmell + objects.assertEqual(writableAssertionInfo, smell.threshold, expected) + } } diff --git a/detekt-watcher/build.gradle.kts b/detekt-watcher/build.gradle.kts index 6f1448ae4..13b002084 100644 --- a/detekt-watcher/build.gradle.kts +++ b/detekt-watcher/build.gradle.kts @@ -1,7 +1,7 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar application { - mainClassName = "io.gitlab.arturbosch.detekt.watcher.MainKt" + mainClassName = "io.gitlab.arturbosch.detekt.watcher.MainKt" } configurations.testImplementation.extendsFrom(configurations["kotlinTest"]) @@ -12,16 +12,16 @@ val spekVersion: String by project val kshVersion: String by project dependencies { - implementation("com.beust:jcommander:$jcommanderVersion") - implementation("io.gitlab.arturbosch:ksh:$kshVersion") - implementation(kotlin("compiler-embeddable")) - implementation(project(":detekt-cli")) - implementation(project(":detekt-core")) - testImplementation(project(":detekt-test")) - testRuntimeOnly("org.junit.platform:junit-platform-launcher:$junitPlatformVersion") - testRuntimeOnly("org.jetbrains.spek:spek-junit-platform-engine:$spekVersion") + implementation("com.beust:jcommander:$jcommanderVersion") + implementation("io.gitlab.arturbosch:ksh:$kshVersion") + implementation(kotlin("compiler-embeddable")) + implementation(project(":detekt-cli")) + implementation(project(":detekt-core")) + testImplementation(project(":detekt-test")) + testRuntimeOnly("org.junit.platform:junit-platform-launcher:$junitPlatformVersion") + testRuntimeOnly("org.jetbrains.spek:spek-junit-platform-engine:$spekVersion") } tasks.withType { - mergeServiceFiles() + mergeServiceFiles() } diff --git a/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/Main.kt b/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/Main.kt index 244e7010c..15600d730 100644 --- a/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/Main.kt +++ b/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/Main.kt @@ -15,9 +15,9 @@ import java.nio.file.Paths * @author Artur Bosch */ fun main(args: Array) { - Injekt.addSingletonFactory { DetektHome(Paths.get(System.getProperty(USER_HOME), HOME_DIR)) } - Injekt.addSingletonFactory { DetektPrompt() } - Injekt.addSingletonFactory { State() } - Injekt.addSingletonFactory { DetektService() } - bootstrap(args) + Injekt.addSingletonFactory { DetektHome(Paths.get(System.getProperty(USER_HOME), HOME_DIR)) } + Injekt.addSingletonFactory { DetektPrompt() } + Injekt.addSingletonFactory { State() } + Injekt.addSingletonFactory { DetektService() } + bootstrap(args) } diff --git a/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/commands/Analyze.kt b/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/commands/Analyze.kt index 535a79f90..7b79d035b 100644 --- a/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/commands/Analyze.kt +++ b/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/commands/Analyze.kt @@ -13,22 +13,22 @@ import io.gitlab.arturbosch.kutils.get * @author Artur Bosch */ class Analyze( - private val state: State = Injekt.get(), - private val detekt: DetektService = Injekt.get() + private val state: State = Injekt.get(), + private val detekt: DetektService = Injekt.get() ) : ShellClass { - @ShellMethod(help = "Runs an analysis on specified project.") - fun main( - @ShellOption( - value = ["", "--subpath"], - help = "If a sub path inside the project should be analyzed.", - defaultValue = ShellOptions.NULL_DEFAULT - ) subPath: String? - ) { - if (subPath == null) { - detekt.run(state.project()) - } else { - detekt.run(state.resolveSubPath(subPath)) - } - } + @ShellMethod(help = "Runs an analysis on specified project.") + fun main( + @ShellOption( + value = ["", "--subpath"], + help = "If a sub path inside the project should be analyzed.", + defaultValue = ShellOptions.NULL_DEFAULT + ) subPath: String? + ) { + if (subPath == null) { + detekt.run(state.project()) + } else { + detekt.run(state.resolveSubPath(subPath)) + } + } } diff --git a/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/commands/Project.kt b/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/commands/Project.kt index f3b6e6c11..292e91605 100644 --- a/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/commands/Project.kt +++ b/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/commands/Project.kt @@ -13,24 +13,24 @@ import io.gitlab.arturbosch.kutils.get * @author Artur Bosch */ class Project( - private val state: State = Injekt.get() + private val state: State = Injekt.get() ) : ShellClass { - override val commandId: String = "project" + override val commandId: String = "project" - @ShellMethod(help = "Allows to set project to analyze and config to use for detekt.") - fun main( - @ShellOption( - value = ["", "--path"], - help = "Path to project. Must be a directory.", - defaultValue = ShellOptions.NULL_DEFAULT - ) path: String?, - @ShellOption( - value = ["-c", "--config"], - help = "Config to use for detekt analysis.", - defaultValue = ShellOptions.NULL_DEFAULT - ) config: String? - ) { - state.use(Parameters(path, config)) - } + @ShellMethod(help = "Allows to set project to analyze and config to use for detekt.") + fun main( + @ShellOption( + value = ["", "--path"], + help = "Path to project. Must be a directory.", + defaultValue = ShellOptions.NULL_DEFAULT + ) path: String?, + @ShellOption( + value = ["-c", "--config"], + help = "Config to use for detekt analysis.", + defaultValue = ShellOptions.NULL_DEFAULT + ) config: String? + ) { + state.use(Parameters(path, config)) + } } diff --git a/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/commands/Watch.kt b/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/commands/Watch.kt index f9f410ddc..c9c0e3188 100644 --- a/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/commands/Watch.kt +++ b/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/commands/Watch.kt @@ -19,55 +19,55 @@ import kotlin.concurrent.thread * @author Artur Bosch */ class Watch( - private val state: State = Injekt.get(), - private val detekt: DetektService = Injekt.get(), - home: DetektHome = Injekt.get() + private val state: State = Injekt.get(), + private val detekt: DetektService = Injekt.get(), + home: DetektHome = Injekt.get() ) : ShellClass { - private val id = AtomicInteger(0) - private var watcher: Thread? = null - private val timeout = home.property(WATCHER_CHANGE_TIMEOUT)?.toLongOrNull() ?: 5L + private val id = AtomicInteger(0) + private var watcher: Thread? = null + private val timeout = home.property(WATCHER_CHANGE_TIMEOUT)?.toLongOrNull() ?: 5L - @ShellMethod(help = "Starts watching project, specified by 'project' command.") - fun main() { - start() - } + @ShellMethod(help = "Starts watching project, specified by 'project' command.") + fun main() { + start() + } - @ShellMethod(help = "Starts watching project, specified by 'project' command.") - fun start() { - check(watcher == null) { "Already a watcher in progress." } - state.shouldWatch = true - watcher = thread( - start = true, - isDaemon = true, - name = "detekt-watcher#${id.getAndIncrement()}", - block = startWatching()) - } + @ShellMethod(help = "Starts watching project, specified by 'project' command.") + fun start() { + check(watcher == null) { "Already a watcher in progress." } + state.shouldWatch = true + watcher = thread( + start = true, + isDaemon = true, + name = "detekt-watcher#${id.getAndIncrement()}", + block = startWatching()) + } - @ShellMethod(help = "Stops watching project.") - fun stop() { - check(watcher != null) { "No watcher is currently running." } - state.shouldWatch = false - watcher = null - } + @ShellMethod(help = "Stops watching project.") + fun stop() { + check(watcher != null) { "No watcher is currently running." } + state.shouldWatch = false + watcher = null + } - private fun startWatching() = { - val watchService = state.newWatcher() - while (state.shouldWatch) { - val watchKey = watchService.poll(timeout, TimeUnit.SECONDS) - if (watchKey != null) { + private fun startWatching() = { + val watchService = state.newWatcher() + while (state.shouldWatch) { + val watchKey = watchService.poll(timeout, TimeUnit.SECONDS) + if (watchKey != null) { - val events = watchKey.pollEvents() - .mapNotNull { event -> - (event.context() as? Path)?.let { PathEvent(it, event.kind()) } - } - val watchedPath = watchKey.watchable() as? Path - ?: throw IllegalStateException("Project path expected.") - val watchedDir = WatchedDir(watchKey.isValid, watchedPath, events) + val events = watchKey.pollEvents() + .mapNotNull { event -> + (event.context() as? Path)?.let { PathEvent(it, event.kind()) } + } + val watchedPath = watchKey.watchable() as? Path + ?: throw IllegalStateException("Project path expected.") + val watchedDir = WatchedDir(watchKey.isValid, watchedPath, events) - detekt.check(watchedDir) - watchKey.reset() - } - } - } + detekt.check(watchedDir) + watchKey.reset() + } + } + } } diff --git a/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/config/DetektHome.kt b/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/config/DetektHome.kt index 87bbd0b50..75114fb60 100644 --- a/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/config/DetektHome.kt +++ b/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/config/DetektHome.kt @@ -8,10 +8,10 @@ import java.nio.file.Path */ class DetektHome(home: Path) : ApplicationHomeFolder(home) { - internal val configFile: Path = resolveFile(CONFIG_FILE, shouldCreate = true) - internal val historyFile: String = System.getProperty(USER_HOME) + HISTORY_FILE + internal val configFile: Path = resolveFile(CONFIG_FILE, shouldCreate = true) + internal val historyFile: String = System.getProperty(USER_HOME) + HISTORY_FILE - init { - addPropertiesFromFile(configFile) - } + init { + addPropertiesFromFile(configFile) + } } diff --git a/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/config/DetektPrompt.kt b/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/config/DetektPrompt.kt index 36ed807a5..41c769d36 100644 --- a/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/config/DetektPrompt.kt +++ b/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/config/DetektPrompt.kt @@ -7,10 +7,10 @@ import io.gitlab.arturbosch.kutils.get * @author Artur Bosch */ class DetektPrompt( - config: DetektHome = Injekt.get() + config: DetektHome = Injekt.get() ) : Prompt { - override val applicationName: String = APP_NAME - override val historyFile: String = config.historyFile - override fun message(): String = "$APP_NAME> " + override val applicationName: String = APP_NAME + override val historyFile: String = config.historyFile + override fun message(): String = "$APP_NAME> " } diff --git a/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/service/DetektService.kt b/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/service/DetektService.kt index ab6babe61..245bae733 100644 --- a/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/service/DetektService.kt +++ b/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/service/DetektService.kt @@ -18,63 +18,63 @@ import java.nio.file.Path * @author Artur Bosch */ class DetektService( - private val state: State = Injekt.get(), - home: DetektHome = Injekt.get() + private val state: State = Injekt.get(), + home: DetektHome = Injekt.get() ) { - private val compiler by lazy { KtCompiler() } - private val reporter = FindingsReport() + private val compiler by lazy { KtCompiler() } + private val reporter = FindingsReport() - private val printChangesNotification = home.property(WATCHER_CHANGE_NOTIFICATION) - ?.toBoolean() ?: true + private val printChangesNotification = home.property(WATCHER_CHANGE_NOTIFICATION) + ?.toBoolean() ?: true - fun run(subPath: Path) { - val settings = state.settings() - val ktFiles = when { - subPath.isFile() -> listOf(compiler.compile(subPath, subPath)) - subPath.isDirectory() -> with(settings) { - KtTreeCompiler(compiler, pathFilters, parallelCompilation, debug = true) - .compile(subPath) - } - else -> emptyList() - } + fun run(subPath: Path) { + val settings = state.settings() + val ktFiles = when { + subPath.isFile() -> listOf(compiler.compile(subPath, subPath)) + subPath.isDirectory() -> with(settings) { + KtTreeCompiler(compiler, pathFilters, parallelCompilation, debug = true) + .compile(subPath) + } + else -> emptyList() + } - val detektor = DetektFacade.create( - settings, RuleSetLocator(settings).load(), emptyList() - ) + val detektor = DetektFacade.create( + settings, RuleSetLocator(settings).load(), emptyList() + ) - val result = detektor.run(state.project(), ktFiles) - reporter.render(result)?.let { println(it) } - } + val result = detektor.run(state.project(), ktFiles) + reporter.render(result)?.let { println(it) } + } - fun check(dir: WatchedDir) { - val settings = state.settings() - val detektor = DetektFacade.create( - settings, RuleSetLocator(settings).load(), emptyList() - ) + fun check(dir: WatchedDir) { + val settings = state.settings() + val detektor = DetektFacade.create( + settings, RuleSetLocator(settings).load(), emptyList() + ) - val watchedDir = dir.dir - val paths = dir.events - .asSequence() - .filter { it.kind.name() != "ENTRY_DELETE" } - .filter { it.path.toString().endsWith(".kt") } - .map { watchedDir.resolve(it.path) } - .distinct() - .toList() + val watchedDir = dir.dir + val paths = dir.events + .asSequence() + .filter { it.kind.name() != "ENTRY_DELETE" } + .filter { it.path.toString().endsWith(".kt") } + .map { watchedDir.resolve(it.path) } + .distinct() + .toList() - val ktFiles = paths - .map { compiler.compile(watchedDir, it) } + val ktFiles = paths + .map { compiler.compile(watchedDir, it) } - if (ktFiles.isNotEmpty()) { - if (printChangesNotification) { - paths.forEach { println("Change detected for $it") } - } - detektor.run(watchedDir, ktFiles) - .findings - .values - .asSequence() - .flatMap { it.asSequence() } - .forEach { println(it.compact()) } - } - } + if (ktFiles.isNotEmpty()) { + if (printChangesNotification) { + paths.forEach { println("Change detected for $it") } + } + detektor.run(watchedDir, ktFiles) + .findings + .values + .asSequence() + .flatMap { it.asSequence() } + .forEach { println(it.compact()) } + } + } } diff --git a/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/service/DirectoryRegisteringVisitor.kt b/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/service/DirectoryRegisteringVisitor.kt index 10c35946b..bb4e19188 100644 --- a/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/service/DirectoryRegisteringVisitor.kt +++ b/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/service/DirectoryRegisteringVisitor.kt @@ -12,11 +12,11 @@ import java.nio.file.attribute.BasicFileAttributes * @author Artur Bosch */ class DirectoryRegisteringVisitor( - private val watchService: WatchService + private val watchService: WatchService ) : SimpleFileVisitor() { - override fun preVisitDirectory(dir: Path, attrs: BasicFileAttributes): FileVisitResult { - dir.register(watchService, ENTRY_CREATE, ENTRY_MODIFY) - return FileVisitResult.CONTINUE - } + override fun preVisitDirectory(dir: Path, attrs: BasicFileAttributes): FileVisitResult { + dir.register(watchService, ENTRY_CREATE, ENTRY_MODIFY) + return FileVisitResult.CONTINUE + } } diff --git a/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/service/Models.kt b/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/service/Models.kt index 0a15e0226..cfcac8aaa 100644 --- a/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/service/Models.kt +++ b/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/service/Models.kt @@ -6,8 +6,10 @@ import java.nio.file.WatchEvent /** * @author Artur Bosch */ -data class WatchedDir(val valid: Boolean, - val dir: Path, - val events: List) +data class WatchedDir( + val valid: Boolean, + val dir: Path, + val events: List +) data class PathEvent(val path: Path, val kind: WatchEvent.Kind<*>) diff --git a/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/state/Parameters.kt b/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/state/Parameters.kt index 41b1293ea..3763a4099 100644 --- a/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/state/Parameters.kt +++ b/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/state/Parameters.kt @@ -11,18 +11,18 @@ import java.nio.file.Paths * @author Artur Bosch */ class Parameters( - private val input: String? = null, - private var config: String? = null + private val input: String? = null, + private var config: String? = null ) { - fun extractWatchDirectory(): Path { - return input?.let { - ExistingPathConverter().convert(it) - } ?: Paths.get(".") - } + fun extractWatchDirectory(): Path { + return input?.let { + ExistingPathConverter().convert(it) + } ?: Paths.get(".") + } - fun extractConfig(): Config? = - config?.let { - CliArgs().apply { this.config = this@Parameters.config }.loadConfiguration() - } + fun extractConfig(): Config? = + config?.let { + CliArgs().apply { this.config = this@Parameters.config }.loadConfiguration() + } } diff --git a/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/state/State.kt b/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/state/State.kt index 023b87315..9369dd21e 100644 --- a/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/state/State.kt +++ b/detekt-watcher/src/main/kotlin/io/gitlab/arturbosch/detekt/watcher/state/State.kt @@ -21,46 +21,46 @@ import java.nio.file.WatchService * @author Artur Bosch */ class State( - home: DetektHome = Injekt.get() + home: DetektHome = Injekt.get() ) { - var shouldWatch: Boolean = false + var shouldWatch: Boolean = false - private var project: Path? = null + private var project: Path? = null - private var config: Config = - home.property(DETEKT_YAML_CONFIG_PATHS)?.let { - CliArgs().apply { config = it }.loadConfiguration() - } ?: Config.empty + private var config: Config = + home.property(DETEKT_YAML_CONFIG_PATHS)?.let { + CliArgs().apply { config = it }.loadConfiguration() + } ?: Config.empty - fun project(): Path = project - ?: throw IllegalStateException("Please specify a root path with the 'project' command first.") + fun project(): Path = project + ?: throw IllegalStateException("Please specify a root path with the 'project' command first.") - fun isValid() = project != null + fun isValid() = project != null - fun use(parameters: Parameters) { - if (shouldWatch) { - shouldWatch = false - println("Stopping ongoing watcher for ${project()}") - } - project = parameters.extractWatchDirectory() - config = parameters.extractConfig() ?: config - } + fun use(parameters: Parameters) { + if (shouldWatch) { + shouldWatch = false + println("Stopping ongoing watcher for ${project()}") + } + project = parameters.extractWatchDirectory() + config = parameters.extractConfig() ?: config + } - fun resolveSubPath(sub: String): Path = project().resolve(sub) + fun resolveSubPath(sub: String): Path = project().resolve(sub) - fun settings() = ProcessingSettings( - project(), - config, - listOf(PathFilter(".*/resources/.*"), - PathFilter(".*/build/.*")) - ) + fun settings() = ProcessingSettings( + project(), + config, + listOf(PathFilter(".*/resources/.*"), + PathFilter(".*/build/.*")) + ) - fun newWatcher(): WatchService { - check(project != null && project?.exists().isTrue()) - val watchService = FileSystems.getDefault().newWatchService() - Files.walkFileTree(project, DirectoryRegisteringVisitor(watchService)) - println("Starting detekt watch service for $project") - return watchService - } + fun newWatcher(): WatchService { + check(project != null && project?.exists().isTrue()) + val watchService = FileSystems.getDefault().newWatchService() + Files.walkFileTree(project, DirectoryRegisteringVisitor(watchService)) + println("Starting detekt watch service for $project") + return watchService + } } diff --git a/detekt-watcher/src/test/kotlin/io/gitlab/arturbosch/detekt/watcher/DetektServiceSpec.kt b/detekt-watcher/src/test/kotlin/io/gitlab/arturbosch/detekt/watcher/DetektServiceSpec.kt index b29649f35..aa38d2156 100644 --- a/detekt-watcher/src/test/kotlin/io/gitlab/arturbosch/detekt/watcher/DetektServiceSpec.kt +++ b/detekt-watcher/src/test/kotlin/io/gitlab/arturbosch/detekt/watcher/DetektServiceSpec.kt @@ -7,46 +7,46 @@ import io.gitlab.arturbosch.detekt.watcher.service.PathEvent import io.gitlab.arturbosch.detekt.watcher.service.WatchedDir import io.gitlab.arturbosch.detekt.watcher.state.Parameters import io.gitlab.arturbosch.detekt.watcher.state.State -import org.assertj.core.api.Assertions.assertThat -import org.jetbrains.spek.api.Spek -import org.jetbrains.spek.api.dsl.describe -import org.jetbrains.spek.api.dsl.it import java.io.ByteArrayOutputStream import java.io.PrintStream import java.lang.UnsupportedOperationException import java.nio.file.Files import java.nio.file.Paths import java.nio.file.WatchEvent.Kind +import org.assertj.core.api.Assertions.assertThat +import org.jetbrains.spek.api.Spek +import org.jetbrains.spek.api.dsl.describe +import org.jetbrains.spek.api.dsl.it class DetektServiceSpec : Spek({ - val tmpDir = Files.createTempDirectory("detekt-watcher") - val content = ByteArrayOutputStream() + val tmpDir = Files.createTempDirectory("detekt-watcher") + val content = ByteArrayOutputStream() - beforeEachTest { - content.reset() - System.setOut(PrintStream(content)) - } + beforeEachTest { + content.reset() + System.setOut(PrintStream(content)) + } - afterEachTest { - System.setOut(System.out) - } + afterEachTest { + System.setOut(System.out) + } - describe("tests the watch service") { + describe("tests the watch service") { - it("detects a change in a file") { - val path = Paths.get(resource("Default.kt")) - val home = DetektHome(tmpDir) - val state = State(home) - state.use(Parameters(tmpDir.toString())) - val service = DetektService(state, home) - val mock = object : Kind { - override fun type(): Class = throw UnsupportedOperationException() - override fun name(): String = "" - } - val dir = WatchedDir(true, path, listOf(PathEvent(path, mock))) - service.check(dir) - assertThat(content.toString()).contains("Change detected for") - } - } + it("detects a change in a file") { + val path = Paths.get(resource("Default.kt")) + val home = DetektHome(tmpDir) + val state = State(home) + state.use(Parameters(tmpDir.toString())) + val service = DetektService(state, home) + val mock = object : Kind { + override fun type(): Class = throw UnsupportedOperationException() + override fun name(): String = "" + } + val dir = WatchedDir(true, path, listOf(PathEvent(path, mock))) + service.check(dir) + assertThat(content.toString()).contains("Change detected for") + } + } }) diff --git a/reports/baseline.xml b/reports/baseline.xml index 5ae704124..f0c9fba75 100644 --- a/reports/baseline.xml +++ b/reports/baseline.xml @@ -1,10 +1,21 @@ - - LargeClass:MagicNumberSpec.kt$MagicNumberSpec : Spek + LargeClass:UnusedPrivateMemberSpec.kt$UnusedPrivateMemberSpec : SubjectSpek - TooManyFunctions:LargeClass.kt$LargeClass : ThresholdRule - TooManyFunctions:UnusedPrivateMember.kt$UnusedPrivateMember : Rule + MaxLineLength:BaselineFacade.kt$BaselineFacade$val blackFiltered = whiteFiltered.filterNot { finding -> listings.second.ids.contains(finding.baselineId) } + MaxLineLength:ComplexityReportGenerator.kt$ComplexityReportGenerator.Factory$fun create(detektion: Detektion): ComplexityReportGenerator + MaxLineLength:Config.kt$io.gitlab.arturbosch.detekt.api.Config.kt + MaxLineLength:ConstructorParameterNaming.kt$io.gitlab.arturbosch.detekt.rules.naming.ConstructorParameterNaming.kt + MaxLineLength:Detektor.kt$io.gitlab.arturbosch.detekt.core.Detektor.kt + MaxLineLength:ForbiddenImport.kt$io.gitlab.arturbosch.detekt.rules.style.ForbiddenImport.kt + MaxLineLength:IteratorNotThrowingNoSuchElementException.kt$io.gitlab.arturbosch.detekt.rules.bugs.IteratorNotThrowingNoSuchElementException.kt + MaxLineLength:ProtectedMemberInFinalClass.kt$io.gitlab.arturbosch.detekt.rules.style.ProtectedMemberInFinalClass.kt + MaxLineLength:SwallowedException.kt$SwallowedException$val parameterNameReferences = throwExpr.thrownExpression?.collectByType<KtNameReferenceExpression>()?.filter { it.text == parameterName } + MaxLineLength:ThrowingExceptionInMain.kt$io.gitlab.arturbosch.detekt.rules.exceptions.ThrowingExceptionInMain.kt + MaxLineLength:TooGenericExceptionThrown.kt$TooGenericExceptionThrown$private val exceptions: Set<String> = valueOrDefault(THROWN_EXCEPTIONS_PROPERTY, thrownExceptionDefaults).toHashSet() + MaxLineLength:UnusedImports.kt$io.gitlab.arturbosch.detekt.rules.style.UnusedImports.kt + MaxLineLength:UnusedPrivateMember.kt$io.gitlab.arturbosch.detekt.rules.style.UnusedPrivateMember.kt + NewLineAtEndOfFile:PluginVersion.kt$io.gitlab.arturbosch.detekt.PluginVersion.kt \ No newline at end of file diff --git a/reports/failfast.yml b/reports/failfast.yml index 9fbe9ee69..82ea4b4c5 100644 --- a/reports/failfast.yml +++ b/reports/failfast.yml @@ -59,21 +59,9 @@ formatting: active: true android: false autoCorrect: true - Indentation: - active: false - autoCorrect: true - indentSize: 4 - continuationIndentSize: 4 - ParameterListWrapping: - active: false - autoCorrect: true - indentSize: 4 - ImportOrdering: - active: false - autoCorrect: true NoItParamInMultilineLambda: active: false - NoWildcardImports: + MaximumLineLength: active: false naming: diff --git a/reports/format.yml b/reports/format.yml new file mode 100644 index 000000000..23a46cbfa --- /dev/null +++ b/reports/format.yml @@ -0,0 +1,9 @@ +formatting: + active: true + android: false + autoCorrect: true + # reports false positive for calls named 'it' in Spek + NoItParamInMultilineLambda: + active: false + MaximumLineLength: + active: false diff --git a/scripts/compare_releases.kts b/scripts/compare_releases.kts index 26d588037..85f0490b2 100644 --- a/scripts/compare_releases.kts +++ b/scripts/compare_releases.kts @@ -11,7 +11,7 @@ val analysisPath = Paths.get(arguments[2]).toAbsolutePath().normalize() check(Files.exists(analysisPath)) { "analysis path '$analysisPath' does not exist" } val configPath = Paths.get(".", "scripts/compare_releases_config.yml") - .toAbsolutePath().normalize() + .toAbsolutePath().normalize() check(Files.exists(configPath)) { "config at '$configPath' must exist" } // the diff tool is expected to exist and accept two files @@ -19,11 +19,11 @@ check(Files.exists(configPath)) { "config at '$configPath' must exist" } val diffTool = if (arguments.size == 4) arguments[3] else "diff" fun findJar(root: Path, version: String): Path { - val pattern = Pattern.compile("detekt-cli-$version-all.jar").asPredicate() - return Files.walk(root) - .filter { pattern.test(it.fileName.toString()) } - .findFirst() - .orElseThrow { IllegalArgumentException("no jar with version $version found") } + val pattern = Pattern.compile("detekt-cli-$version-all.jar").asPredicate() + return Files.walk(root) + .filter { pattern.test(it.fileName.toString()) } + .findFirst() + .orElseThrow { IllegalArgumentException("no jar with version $version found") } } val rootForJars = Paths.get(".", "detekt-cli/build/libs") @@ -36,51 +36,51 @@ val jar2 = findJar(rootForJars, version2).toAbsolutePath().normalize() println("Comparing: \n$jar1\n$jar2") fun javaExec(jar: Path, output: Path) { - val command = listOf( - "java", - "-jar", - jar.toString(), - "--input", - analysisPath.toString(), - "--config", - configPath.toString(), - "--filters", - ".*/resources/.*,.*/build/.*,.*/out/.*,.*/test/.*", - "--report", - "txt:$output" - ) - println("Executing ${command.joinToString(" ")}") - ProcessBuilder(command) - .inheritIO() - .start() - .waitFor() + val command = listOf( + "java", + "-jar", + jar.toString(), + "--input", + analysisPath.toString(), + "--config", + configPath.toString(), + "--filters", + ".*/resources/.*,.*/build/.*,.*/out/.*,.*/test/.*", + "--report", + "txt:$output" + ) + println("Executing ${command.joinToString(" ")}") + ProcessBuilder(command) + .inheritIO() + .start() + .waitFor() } val diff1 = Files.createTempFile("detekt", "compare") val diff2 = Files.createTempFile("detekt", "compare") fun executeDetekt() { - javaExec(jar1, diff1) - javaExec(jar2, diff2) - println("Detekt txt results are saved at:\n$diff1\n$diff2") + javaExec(jar1, diff1) + javaExec(jar2, diff2) + println("Detekt txt results are saved at:\n$diff1\n$diff2") } executeDetekt() fun performDiff() { - val command = listOf("diff", diff1.toString(), diff2.toString()) - val diffResult = Files.createTempFile("detekt", "diff").toFile() - ProcessBuilder(command) - .redirectOutput(diffResult) - .start() - .waitFor() - val diff = diffResult.readText().trim() - if (diff.isNotEmpty()) { - println(diff) - println("There were differences beween results.") - } else { - println("No differences between results.") - } + val command = listOf("diff", diff1.toString(), diff2.toString()) + val diffResult = Files.createTempFile("detekt", "diff").toFile() + ProcessBuilder(command) + .redirectOutput(diffResult) + .start() + .waitFor() + val diff = diffResult.readText().trim() + if (diff.isNotEmpty()) { + println(diff) + println("There were differences beween results.") + } else { + println("No differences between results.") + } } performDiff() diff --git a/settings.gradle.kts b/settings.gradle.kts index f080af75d..fc0e47bcc 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,12 +1,12 @@ rootProject.name = "detekt" include("detekt-api", - "detekt-core", - "detekt-rules", - "detekt-cli", - "detekt-test", - "detekt-sample-extensions", - "detekt-generator", - "detekt-watcher", - "detekt-formatting") + "detekt-core", + "detekt-rules", + "detekt-cli", + "detekt-test", + "detekt-sample-extensions", + "detekt-generator", + "detekt-watcher", + "detekt-formatting") includeBuild("detekt-gradle-plugin")