diff --git a/test2code/src/main/kotlin/com/epam/drill/agent/test2code/Test2Code.kt b/test2code/src/main/kotlin/com/epam/drill/agent/test2code/Test2Code.kt index 8adcf4fa..fca9400b 100644 --- a/test2code/src/main/kotlin/com/epam/drill/agent/test2code/Test2Code.kt +++ b/test2code/src/main/kotlin/com/epam/drill/agent/test2code/Test2Code.kt @@ -148,16 +148,33 @@ class Test2Code( return } var classCount = 0 - var methodCount = 0 + var totalMethodsCount = 0 + var filteredMethodsCount = 0 + + val excludeMethodsByAnnotationPackage = + configuration.parameters[Test2CodeParameterDefinitions.EXCLUDE_METHODS_BY_ANNOTATION_PACKAGE] as List + val hasAnnotationsExclusions = excludeMethodsByAnnotationPackage.isNotEmpty() + scanClasses { classes -> classes .also { classCount += it.size } - .flatMap { parseAstClass(it.entityName(), it.bytes()) } - .also { methodCount += it.size } - .chunked(configuration.parameters[Test2CodeParameterDefinitions.METHODS_SEND_PAGE_SIZE]) + .asSequence() + .flatMap { parseAstClass(it.entityName(), it.bytes()).asSequence() } + .onEach { totalMethodsCount++ } + .filter { method -> + !hasAnnotationsExclusions || + method.annotations?.keys?.none { key -> + excludeMethodsByAnnotationPackage.any { key.contains(it) } + } ?: false + } + .onEach { filteredMethodsCount++ } + .chunkedLazy(configuration.parameters[Test2CodeParameterDefinitions.METHODS_SEND_PAGE_SIZE]) .forEach(::sendClassMetadata) } - logger.info { "Scanned $classCount classes with $methodCount methods" } + logger.info { """Scanned $classCount classes with $filteredMethodsCount methods + | total methods: ${totalMethodsCount + filteredMethodsCount}; + | methods excluded by annotations: ${totalMethodsCount - filteredMethodsCount} + | packages for annotations-based exclusion are specified in ${Test2CodeParameterDefinitions.EXCLUDE_METHODS_BY_ANNOTATION_PACKAGE.name} parameter """.trimMargin() } } private val classMetadataDestination = AgentMessageDestination("PUT", "methods") @@ -174,5 +191,16 @@ class Test2Code( logger.debug { "sendClassMetadata: Sending methods: $message" } sender.send(classMetadataDestination, message, ClassMetadata.serializer()) } +} +private fun Sequence.chunkedLazy(size: Int): Sequence> = sequence { + val buffer = mutableListOf() + for (item in this@chunkedLazy) { + buffer += item + if (buffer.size == size) { + yield(buffer.toList()) + buffer.clear() + } + } + if (buffer.isNotEmpty()) yield(buffer.toList()) } diff --git a/test2code/src/main/kotlin/com/epam/drill/agent/test2code/configuration/Test2CodeParameterDefinitions.kt b/test2code/src/main/kotlin/com/epam/drill/agent/test2code/configuration/Test2CodeParameterDefinitions.kt index fdc5547c..10625a34 100644 --- a/test2code/src/main/kotlin/com/epam/drill/agent/test2code/configuration/Test2CodeParameterDefinitions.kt +++ b/test2code/src/main/kotlin/com/epam/drill/agent/test2code/configuration/Test2CodeParameterDefinitions.kt @@ -21,6 +21,7 @@ import com.epam.drill.agent.common.configuration.AgentParameterDefinitionCollect import com.epam.drill.agent.common.configuration.BaseAgentParameterDefinition import com.epam.drill.agent.common.configuration.ValidationType import com.epam.drill.agent.configuration.isNotBlank +import com.epam.drill.agent.configuration.isValidPackage import com.epam.drill.agent.configuration.minDuration object Test2CodeParameterDefinitions : AgentParameterDefinitionCollection() { @@ -68,5 +69,23 @@ object Test2CodeParameterDefinitions : AgentParameterDefinitionCollection() { description = "Enable/disable application classes scanning", defaultValue = true ).register() + val EXCLUDE_METHODS_BY_ANNOTATION_PACKAGE = AgentParameterDefinition.forList( + name = "excludeMethodsByAnnotationPackage", + description = """ + Excludes methods with annotations from the specified packages from code scanning process. + Matches exact packages and descendants. + + Package names must be delimited with / (forward slash) and separated by ; + + Example: exclude methods autogenerated by SLF4J and Lombok + org/slf4j;lombok + """.trimIndent(), + defaultValue = emptyList(), + parser = { it.split(";") }, + validation = ValidationType.SOFT, + itemValidator = { + isValidPackage() + } + ).register() }