diff --git a/semantic/src/main/kotlin/tools/samt/semantic/SemanticModelPreProcessor.kt b/semantic/src/main/kotlin/tools/samt/semantic/SemanticModelPreProcessor.kt index 2c9db0a7..97cd8364 100644 --- a/semantic/src/main/kotlin/tools/samt/semantic/SemanticModelPreProcessor.kt +++ b/semantic/src/main/kotlin/tools/samt/semantic/SemanticModelPreProcessor.kt @@ -41,8 +41,29 @@ internal class SemanticModelPreProcessor(private val controller: DiagnosticContr } } + private fun reportFileSeparation(file: FileNode) { + val statements = file.statements + if (statements.size < 10) { + return + } + for (provider in statements.filterIsInstance()) { + controller.getOrCreateContext(provider.location.source).warn { + message("Provider declaration should be in its own file") + highlight("provider declaration", provider.location, highlightBeginningOnly = true) + } + } + for (consumer in statements.filterIsInstance()) { + controller.getOrCreateContext(consumer.location.source).warn { + message("Consumer declaration should be in its own file") + highlight("consumer declaration", consumer.location, highlightBeginningOnly = true) + } + } + } + fun fillPackage(samtPackage: Package, files: List) { for (file in files) { + reportFileSeparation(file) + var parentPackage = samtPackage for (component in file.packageDeclaration.name.components) { var subPackage = parentPackage.subPackages.find { it.name == component.name } diff --git a/semantic/src/test/kotlin/tools/samt/semantic/SemanticModelTest.kt b/semantic/src/test/kotlin/tools/samt/semantic/SemanticModelTest.kt index 9a0b2156..7686c458 100644 --- a/semantic/src/test/kotlin/tools/samt/semantic/SemanticModelTest.kt +++ b/semantic/src/test/kotlin/tools/samt/semantic/SemanticModelTest.kt @@ -1244,6 +1244,74 @@ class SemanticModelTest { } } + @Nested + inner class FileSeparation { + @Test + fun `provider in file with other types is warning`() { + val source = """ + package separation + + record A {} + record B {} + record C {} + record D {} + record E {} + record F {} + record G {} + record H {} + record I {} + + service TestService {} + + provide TestProvider { + implements TestService + + transport http + } + """.trimIndent() + parseAndCheck( + source to listOf("Warning: Provider declaration should be in its own file") + ) + } + + @Test + fun `consumer in file with other types is warning`() { + val source = """ + package separation + + record A {} + record B {} + record C {} + record D {} + record E {} + record F {} + record G {} + record H {} + record I {} + + service TestService {} + + consume TestProvider { + uses TestService + } + """.trimIndent() + val providerSource = """ + package separation + + provide TestProvider { + implements TestService + + transport http + } + """.trimIndent() + + parseAndCheck( + source to listOf("Warning: Consumer declaration should be in its own file"), + providerSource to emptyList() + ) + } + } + private fun parseAndCheck( vararg sourceAndExpectedMessages: Pair>, ): SemanticModel {