From a7653f9a745179c152a8410ee6a6ba9d453d6ba3 Mon Sep 17 00:00:00 2001 From: Izabela Zawadzka Date: Thu, 11 Apr 2019 14:27:21 +0200 Subject: Create custom rule to report public modifiers in impl Change-Id: I383ca27a835943bd2dc2508425264ad7f64c7725 Signed-off-by: Izabela Zawadzka Issue-ID: DCAEGEN2-1430 --- .../veshv/analysis/PublicModifiersInImpl.kt | 72 ++++++++++++ .../veshv/analysis/VesHvRuleSetProvider.kt | 5 +- .../src/main/resources/onap-detekt-config.yml | 2 + .../veshv/analysis/PublicModifiersInImplTest.kt | 122 +++++++++++++++++++++ 4 files changed, 199 insertions(+), 2 deletions(-) create mode 100644 build/hv-collector-analysis/src/main/kotlin/org/onap/dcae/collectors/veshv/analysis/PublicModifiersInImpl.kt create mode 100644 build/hv-collector-analysis/src/test/kotlin/org/onap/dcae/collectors/veshv/analysis/PublicModifiersInImplTest.kt diff --git a/build/hv-collector-analysis/src/main/kotlin/org/onap/dcae/collectors/veshv/analysis/PublicModifiersInImpl.kt b/build/hv-collector-analysis/src/main/kotlin/org/onap/dcae/collectors/veshv/analysis/PublicModifiersInImpl.kt new file mode 100644 index 00000000..027cadea --- /dev/null +++ b/build/hv-collector-analysis/src/main/kotlin/org/onap/dcae/collectors/veshv/analysis/PublicModifiersInImpl.kt @@ -0,0 +1,72 @@ +/* + * ============LICENSE_START======================================================= + * dcaegen2-collectors-veshv + * ================================================================================ + * Copyright (C) 2019 NOKIA + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ +package org.onap.dcae.collectors.veshv.analysis + +import io.gitlab.arturbosch.detekt.api.* +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.isPublic + +class PublicModifiersInImpl(config: Config = Config.empty) : Rule(config) { + override val issue: Issue = Issue(javaClass.simpleName, Severity.Maintainability, + ISSUE_DESCRIPTION, Debt(mins=10)) + + override fun visitKtFile(file: KtFile) { + super.visitKtFile(file) + + if(file.packageFqName.toString().contains("impl")) { + ImplVisitor.also { + file.accept(it) + if(it.publicDeclarations.isNotEmpty()){ + for(entity in it.publicDeclarations) + report(CodeSmell(issue, entity, REPORT_MESSAGE)) + it.publicDeclarations.clear() + } + } + } + } + + companion object { + private val REPORT_MESSAGE = """ + Implementation package members cannot have public declarations. + Please, add `internal` modifier for this element to disallow usage outside of module + """.trimIndent() + private const val ISSUE_DESCRIPTION = "Reports public modifiers inside '*.impl' package." + } +} + +private object ImplVisitor: DetektVisitor(){ + var publicDeclarations = mutableListOf() + + override fun visitClassOrObject(classOrObject: KtClassOrObject) { + if(classOrObject.isTopLevel() && classOrObject.isPublic){ + publicDeclarations.add(Entity.from(classOrObject)) + } + } + + override fun visitNamedFunction(function: KtNamedFunction) { + if(function.isTopLevel && function.isPublic){ + publicDeclarations.add(Entity.from(function)) + } + } + + override fun visitProperty(property: KtProperty) { + if(property.isTopLevel && property.isPublic) publicDeclarations.add(Entity.from(property)) + } +} \ No newline at end of file diff --git a/build/hv-collector-analysis/src/main/kotlin/org/onap/dcae/collectors/veshv/analysis/VesHvRuleSetProvider.kt b/build/hv-collector-analysis/src/main/kotlin/org/onap/dcae/collectors/veshv/analysis/VesHvRuleSetProvider.kt index eec933dc..eb906ad5 100644 --- a/build/hv-collector-analysis/src/main/kotlin/org/onap/dcae/collectors/veshv/analysis/VesHvRuleSetProvider.kt +++ b/build/hv-collector-analysis/src/main/kotlin/org/onap/dcae/collectors/veshv/analysis/VesHvRuleSetProvider.kt @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * dcaegen2-collectors-veshv * ================================================================================ - * Copyright (C) 2018 NOKIA + * Copyright (C) 2018-2019 NOKIA * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,6 +31,7 @@ class VesHvRuleSetProvider : RuleSetProvider { override val ruleSetId: String get() = "HvVesCustomRules" - override fun instance(config: Config) = RuleSet(ruleSetId, listOf(SuboptimalLoggerUsage(config))) + override fun instance(config: Config) = RuleSet(ruleSetId, + listOf(SuboptimalLoggerUsage(config), PublicModifiersInImpl(config))) } diff --git a/build/hv-collector-analysis/src/main/resources/onap-detekt-config.yml b/build/hv-collector-analysis/src/main/resources/onap-detekt-config.yml index f8d8b1ee..b45f6b64 100644 --- a/build/hv-collector-analysis/src/main/resources/onap-detekt-config.yml +++ b/build/hv-collector-analysis/src/main/resources/onap-detekt-config.yml @@ -479,3 +479,5 @@ HvVesCustomRules: active: true SuboptimalLoggerUsage: active: false + PublicModifiersInImpl: + active: false diff --git a/build/hv-collector-analysis/src/test/kotlin/org/onap/dcae/collectors/veshv/analysis/PublicModifiersInImplTest.kt b/build/hv-collector-analysis/src/test/kotlin/org/onap/dcae/collectors/veshv/analysis/PublicModifiersInImplTest.kt new file mode 100644 index 00000000..b3de1a2e --- /dev/null +++ b/build/hv-collector-analysis/src/test/kotlin/org/onap/dcae/collectors/veshv/analysis/PublicModifiersInImplTest.kt @@ -0,0 +1,122 @@ +/* + * ============LICENSE_START======================================================= + * dcaegen2-collectors-veshv + * ================================================================================ + * Copyright (C) 2019 NOKIA + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.dcae.collectors.veshv.analysis + +import io.gitlab.arturbosch.detekt.test.assertThat +import io.gitlab.arturbosch.detekt.test.lint +import org.jetbrains.spek.api.Spek +import org.jetbrains.spek.api.dsl.describe +import org.jetbrains.spek.api.dsl.it + +internal class PublicModifiersInImplTest: Spek({ + fun checkPassingCase(code: String, cut: PublicModifiersInImpl = PublicModifiersInImpl()) { + describe(code) { + val findings = cut.lint(code) + + it("should pass") { + assertThat(findings).isEmpty() + } + } + } + + fun checkFailingCase(code: String, cut: PublicModifiersInImpl = PublicModifiersInImpl()) { + describe(code) { + val findings = cut.lint(code) + + it("should fail") { + assertThat(findings).isNotEmpty + } + } + } + + describe("passing cases") { + checkPassingCase(ExemplaryCode.publicModifiersOutsideImplPackage) + checkPassingCase(ExemplaryCode.internalTopLevelModifiersInsideImplPackage) + checkPassingCase(ExemplaryCode.privateTopLevelModifiersInsideImplPackage) + checkPassingCase(ExemplaryCode.protectedTopLevelModifiersInsideImplPackage) + } + + describe("failing cases") { + checkFailingCase(ExemplaryCode.publicTopLevelModifiersInsideImplPackage) + } +}) + +private object ExemplaryCode { + val publicModifiersOutsideImplPackage = """ + package a.b.c + + class SampleClass { + + } + + object SampleObject { + + } + """.trimIndent() + + val internalTopLevelModifiersInsideImplPackage = """ + package a.impl.b + + internal fun sampleFunction() = true + + internal val sampleProperty = true + + internal class SampleClass { + fun someFunction() = true + } + """.trimIndent() + + val privateTopLevelModifiersInsideImplPackage = """ + package a.impl.b + + private fun sampleFunction() = true + + private val sampleProperty = true + + private class SampleClass { + fun someFunction() = true + } + """.trimIndent() + + val protectedTopLevelModifiersInsideImplPackage = """ + package a.impl.b + + protected fun sampleFunction() = true + + protected val sampleProperty = true + + protected class SampleClass { + fun someFunction() = true + } + """.trimIndent() + + val publicTopLevelModifiersInsideImplPackage = """ + package a.impl.b + + fun sampleFunction() = true + + val sampleProperty = true + + class SampleClass { + private fun someFunction() = true + } + """.trimIndent() +} \ No newline at end of file -- cgit 1.2.3-korg