diff --git a/CHANGELOG.md b/CHANGELOG.md index d765f074..84a1ee75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ - Plugin is now compatible with IDEA 2024.3 (IDEA 243.*) with minimum version of 2024.2 - Fix various deprecation warnings - Fix various javadoc issues +- Fix class hierarchy not being taken into account for handler and creator resolving. +- Remove wrong implementation of interceptor support, to possibly be re-implemented in a future release in a better form. ## [0.8.7] - Plugin is now compatible with IDEA 2024.2 (IDEA 242.*) diff --git a/src/main/kotlin/org/axonframework/intellij/ide/plugin/api/MessageHandlerType.kt b/src/main/kotlin/org/axonframework/intellij/ide/plugin/api/MessageHandlerType.kt index 649a8e76..5562baa1 100644 --- a/src/main/kotlin/org/axonframework/intellij/ide/plugin/api/MessageHandlerType.kt +++ b/src/main/kotlin/org/axonframework/intellij/ide/plugin/api/MessageHandlerType.kt @@ -32,7 +32,6 @@ enum class MessageHandlerType( EVENT_SOURCING(AxonAnnotation.EVENT_SOURCING_HANDLER, MessageType.EVENT), QUERY(AxonAnnotation.QUERY_HANDLER, MessageType.QUERY), DEADLINE(AxonAnnotation.DEADLINE_HANDLER, MessageType.DEADLINE), - COMMAND_INTERCEPTOR(AxonAnnotation.COMMAND_HANDLER_INTERCEPTOR, MessageType.COMMAND), SAGA(AxonAnnotation.SAGA_EVENT_HANDLER, MessageType.EVENT), ; diff --git a/src/main/kotlin/org/axonframework/intellij/ide/plugin/markers/handlers/CommandHandlerMethodLineMarkerProvider.kt b/src/main/kotlin/org/axonframework/intellij/ide/plugin/markers/handlers/CommandHandlerMethodLineMarkerProvider.kt deleted file mode 100644 index a3068b70..00000000 --- a/src/main/kotlin/org/axonframework/intellij/ide/plugin/markers/handlers/CommandHandlerMethodLineMarkerProvider.kt +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) (2010-2022). Axon Framework - * - * 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. - */ - -package org.axonframework.intellij.ide.plugin.markers.handlers - -import com.intellij.codeInsight.daemon.LineMarkerInfo -import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder -import com.intellij.openapi.util.NotNullLazyValue -import com.intellij.psi.PsiElement -import org.axonframework.intellij.ide.plugin.AxonIcons -import org.axonframework.intellij.ide.plugin.api.MessageHandlerType -import org.axonframework.intellij.ide.plugin.api.MessageType -import org.axonframework.intellij.ide.plugin.markers.AxonNavigationTargetRenderer -import org.axonframework.intellij.ide.plugin.resolving.handlers.types.CommandHandlerInterceptor -import org.axonframework.intellij.ide.plugin.util.creatorResolver -import org.axonframework.intellij.ide.plugin.util.handlerResolver - -/** - * Provides a gutter icon on command handlers, switching to an intercepted icon if necessary - */ -class CommandHandlerMethodLineMarkerProvider : AbstractHandlerLineMarkerProvider() { - override fun createLineMarker( - element: PsiElement, - handlerType: MessageHandlerType, - payload: String?, - ): LineMarkerInfo<*>? { - if (handlerType != MessageHandlerType.COMMAND || payload == null) { - return null - } - - val interceptingElements = element.handlerResolver().findHandlersForType(payload, MessageType.COMMAND, true) - .filterIsInstance() - - val icon = if (interceptingElements.isNotEmpty()) AxonIcons.HandlerIntercepted else AxonIcons.Handler - return NavigationGutterIconBuilder.create(icon) - .setTargets(NotNullLazyValue.lazy { - val creatingElements = element.creatorResolver() - .getCreatorsForPayload(payload) - .distinctBy { it.parentHandler } - interceptingElements + creatingElements - }) - .setTargetRenderer { AxonNavigationTargetRenderer.INSTANCE } - .setPopupTitle("Payload Creators") - .setTooltipText("Navigate to creators of $payload") - .setEmptyPopupText("No creators of this message payload were found") - .createLineMarkerInfo(element) - } -} diff --git a/src/main/kotlin/org/axonframework/intellij/ide/plugin/markers/handlers/CommandInterceptorLineMarkerProvider.kt b/src/main/kotlin/org/axonframework/intellij/ide/plugin/markers/handlers/CommandInterceptorLineMarkerProvider.kt deleted file mode 100644 index 815344c4..00000000 --- a/src/main/kotlin/org/axonframework/intellij/ide/plugin/markers/handlers/CommandInterceptorLineMarkerProvider.kt +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) (2010-2022). Axon Framework - * - * 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. - */ - -package org.axonframework.intellij.ide.plugin.markers.handlers - -import com.intellij.codeInsight.daemon.LineMarkerInfo -import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder -import com.intellij.openapi.util.NotNullLazyValue -import com.intellij.psi.PsiElement -import org.axonframework.intellij.ide.plugin.AxonIcons -import org.axonframework.intellij.ide.plugin.api.MessageHandlerType -import org.axonframework.intellij.ide.plugin.api.MessageType -import org.axonframework.intellij.ide.plugin.markers.AxonNavigationTargetRenderer -import org.axonframework.intellij.ide.plugin.resolving.handlers.types.CommandHandler -import org.axonframework.intellij.ide.plugin.util.aggregateResolver -import org.axonframework.intellij.ide.plugin.util.handlerResolver -import org.jetbrains.uast.getContainingUClass -import org.jetbrains.uast.toUElement - -/** - * Creates an interceptor icon in the gutter, containing all handler methods that are intercepted by this - * interceptor. Includes aggregate members, using the `AggregateStructureResolver` - * - * @see org.axonframework.intellij.ide.plugin.resolving.AggregateStructureResolver - */ -class CommandInterceptorLineMarkerProvider : AbstractHandlerLineMarkerProvider() { - - override fun createLineMarker( - element: PsiElement, - handlerType: MessageHandlerType, - payload: String?, - ): LineMarkerInfo<*>? { - if (handlerType != MessageHandlerType.COMMAND_INTERCEPTOR) { - return null - } - val className = element.toUElement()?.getContainingUClass()?.qualifiedName ?: return null - // An interceptor without payload is fine, default to Object to match all - val actualPayload = payload ?: "java.lang.Object" - - return NavigationGutterIconBuilder.create(AxonIcons.Interceptor) - .setTargets(NotNullLazyValue.lazy { - val members = element.aggregateResolver().getEntityAndAllChildrenRecursively(className) - element.handlerResolver().findHandlersForType(actualPayload, MessageType.COMMAND) - .filterIsInstance() - .filter { - val name = it.element.toUElement()?.getContainingUClass()?.qualifiedName - members.any { member -> member.name == name } - } - }) - .setTargetRenderer { AxonNavigationTargetRenderer.INSTANCE } - .setPopupTitle("Commands Intercepted") - .setTooltipText("Navigate to command handlers that are intercepted") - .setEmptyPopupText("No intercepted command handlers were found") - .createLineMarkerInfo(element, ) - } -} diff --git a/src/main/kotlin/org/axonframework/intellij/ide/plugin/markers/handlers/CommonHandlerMethodLineMarkerProvider.kt b/src/main/kotlin/org/axonframework/intellij/ide/plugin/markers/handlers/CommonHandlerMethodLineMarkerProvider.kt index 6a7e3a11..6dc2a995 100644 --- a/src/main/kotlin/org/axonframework/intellij/ide/plugin/markers/handlers/CommonHandlerMethodLineMarkerProvider.kt +++ b/src/main/kotlin/org/axonframework/intellij/ide/plugin/markers/handlers/CommonHandlerMethodLineMarkerProvider.kt @@ -29,7 +29,7 @@ import org.axonframework.intellij.ide.plugin.util.creatorResolver * Provides a gutter icon on all generic handler methods */ class CommonHandlerMethodLineMarkerProvider : AbstractHandlerLineMarkerProvider() { - private val blacklistedTypes = listOf(MessageHandlerType.DEADLINE, MessageHandlerType.COMMAND, MessageHandlerType.COMMAND_INTERCEPTOR) + private val blacklistedTypes = listOf(MessageHandlerType.DEADLINE) override fun createLineMarker( element: PsiElement, handlerType: MessageHandlerType, diff --git a/src/main/kotlin/org/axonframework/intellij/ide/plugin/markers/publishers/PublishMethodLineMarkerProvider.kt b/src/main/kotlin/org/axonframework/intellij/ide/plugin/markers/publishers/PublishMethodLineMarkerProvider.kt index 04721437..13ca58b5 100644 --- a/src/main/kotlin/org/axonframework/intellij/ide/plugin/markers/publishers/PublishMethodLineMarkerProvider.kt +++ b/src/main/kotlin/org/axonframework/intellij/ide/plugin/markers/publishers/PublishMethodLineMarkerProvider.kt @@ -18,8 +18,6 @@ package org.axonframework.intellij.ide.plugin.markers.publishers import com.intellij.codeInsight.daemon.LineMarkerInfo import com.intellij.codeInsight.daemon.LineMarkerProvider -import com.intellij.codeInsight.daemon.RelatedItemLineMarkerInfo -import com.intellij.codeInsight.daemon.RelatedItemLineMarkerProvider import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder import com.intellij.ide.highlighter.JavaFileType import com.intellij.psi.PsiElement @@ -29,7 +27,6 @@ import org.axonframework.intellij.ide.plugin.AxonIcons import org.axonframework.intellij.ide.plugin.api.MessageHandlerType import org.axonframework.intellij.ide.plugin.markers.AxonNavigationTargetRenderer import org.axonframework.intellij.ide.plugin.resolving.MessageHandlerResolver -import org.axonframework.intellij.ide.plugin.resolving.handlers.types.CommandHandlerInterceptor import org.axonframework.intellij.ide.plugin.resolving.handlers.types.DeadlineHandler import org.axonframework.intellij.ide.plugin.util.containingClassFqn import org.axonframework.intellij.ide.plugin.util.handlerResolver @@ -66,11 +63,9 @@ class PublishMethodLineMarkerProvider : LineMarkerProvider { else -> null } ?: return null - val allHandlers = element.handlerResolver().findHandlersForType(payload) + val handlers = element.handlerResolver().findHandlersForType(payload) // Hide DeadlineHandlers here. These are handled by a more specific LineMarkerProvider .filter { it !is DeadlineHandler } - val isCommand = allHandlers.all { it.handlerType == MessageHandlerType.COMMAND } - val handlers = allHandlers.filter { it !is CommandHandlerInterceptor || isCommand } // Only show interceptors when is a command if (handlers.isEmpty()) { return null } diff --git a/src/main/kotlin/org/axonframework/intellij/ide/plugin/resolving/MessageCreationResolver.kt b/src/main/kotlin/org/axonframework/intellij/ide/plugin/resolving/MessageCreationResolver.kt index 80b6d6fc..f37b1698 100644 --- a/src/main/kotlin/org/axonframework/intellij/ide/plugin/resolving/MessageCreationResolver.kt +++ b/src/main/kotlin/org/axonframework/intellij/ide/plugin/resolving/MessageCreationResolver.kt @@ -18,11 +18,11 @@ package org.axonframework.intellij.ide.plugin.resolving import com.intellij.openapi.project.Project import com.intellij.psi.PsiElement +import com.intellij.psi.search.searches.ClassInheritorsSearch import com.intellij.psi.search.searches.MethodReferencesSearch import com.intellij.psi.util.CachedValue import org.axonframework.intellij.ide.plugin.api.MessageCreator import org.axonframework.intellij.ide.plugin.resolving.creators.DefaultMessageCreator -import org.axonframework.intellij.ide.plugin.util.areAssignable import org.axonframework.intellij.ide.plugin.util.axonScope import org.axonframework.intellij.ide.plugin.util.createCachedValue import org.axonframework.intellij.ide.plugin.util.findParentHandlers @@ -38,7 +38,6 @@ import java.util.concurrent.ConcurrentHashMap * the PSI is modified (code is edited) or is collected by the garbage collector. */ class MessageCreationResolver(private val project: Project) { - private val handlerResolver = project.handlerResolver() private val psiFacade = project.javaFacade() private val constructorsByPayloadCache = ConcurrentHashMap>>() @@ -59,25 +58,19 @@ class MessageCreationResolver(private val project: Project) { } private fun findByPayload(payload: String): List { - val matchingHandlers = handlerResolver.findAllHandlers() - .map { it.payload } - .filter { areAssignable(project, payload, it) } - val classesForQualifiedName = listOf(payload).plus(matchingHandlers) - .distinct() - return resolveCreatorsForFqns(classesForQualifiedName) - } + val classes = psiFacade.findClass(payload, project.axonScope())?.let { clazz -> + listOf(clazz) + ClassInheritorsSearch.search(clazz, project.axonScope(), true) + } ?: return emptyList() - private fun resolveCreatorsForFqns(fqns: List): List { - return fqns.flatMap { typeFqn -> - psiFacade.findClasses(typeFqn, project.axonScope()).flatMap { clazz -> + return classes + .flatMap { clazz -> // Account for constructors and builder methods (builder(), toBuilder(), etc) val methods = clazz.constructors + clazz.methods.filter { it.name.contains("build", ignoreCase = true) } methods .flatMap { MethodReferencesSearch.search(it, project.axonScope(), true) } - .flatMap { ref -> createCreators(typeFqn, ref.element) } + .flatMap { ref -> createCreators(clazz.qualifiedName!!, ref.element) } .distinct() } - } } private fun createCreators(payload: String, element: PsiElement): List { diff --git a/src/main/kotlin/org/axonframework/intellij/ide/plugin/resolving/MessageHandlerResolver.kt b/src/main/kotlin/org/axonframework/intellij/ide/plugin/resolving/MessageHandlerResolver.kt index abdc392d..998e7938 100644 --- a/src/main/kotlin/org/axonframework/intellij/ide/plugin/resolving/MessageHandlerResolver.kt +++ b/src/main/kotlin/org/axonframework/intellij/ide/plugin/resolving/MessageHandlerResolver.kt @@ -17,19 +17,22 @@ package org.axonframework.intellij.ide.plugin.resolving import com.intellij.openapi.project.Project +import com.intellij.psi.JavaPsiFacade +import com.intellij.psi.PsiClass import com.intellij.psi.PsiElement +import com.intellij.psi.search.searches.ClassInheritorsSearch import org.axonframework.intellij.ide.plugin.api.Handler import org.axonframework.intellij.ide.plugin.api.MessageType import org.axonframework.intellij.ide.plugin.resolving.handlers.searchers.AggregateConstructorSearcher -import org.axonframework.intellij.ide.plugin.resolving.handlers.searchers.CommandHandlerInterceptorSearcher import org.axonframework.intellij.ide.plugin.resolving.handlers.searchers.CommandHandlerSearcher import org.axonframework.intellij.ide.plugin.resolving.handlers.searchers.DeadlineHandlerSearcher import org.axonframework.intellij.ide.plugin.resolving.handlers.searchers.EventHandlerSearcher import org.axonframework.intellij.ide.plugin.resolving.handlers.searchers.EventSourcingHandlerSearcher import org.axonframework.intellij.ide.plugin.resolving.handlers.searchers.QueryHandlerSearcher import org.axonframework.intellij.ide.plugin.resolving.handlers.searchers.SagaEventHandlerSearcher -import org.axonframework.intellij.ide.plugin.util.areAssignable +import org.axonframework.intellij.ide.plugin.util.axonScope import org.axonframework.intellij.ide.plugin.util.createCachedValue +import org.axonframework.intellij.ide.plugin.util.findCompleteSupers /** * Searches the codebase for Message handlers based on the annotations defined in MessageHandlerType. @@ -41,7 +44,6 @@ import org.axonframework.intellij.ide.plugin.util.createCachedValue */ class MessageHandlerResolver(private val project: Project) { private val searchers = listOf( - CommandHandlerInterceptorSearcher(), CommandHandlerSearcher(), EventHandlerSearcher(), EventSourcingHandlerSearcher(), @@ -61,20 +63,29 @@ class MessageHandlerResolver(private val project: Project) { fun findHandlersForType( qualifiedName: String, messageType: MessageType? = null, - reverseAssign: Boolean = false ): List { + val baseClass = JavaPsiFacade.getInstance(project).findClasses(qualifiedName, project.axonScope()).firstOrNull() + ?: return emptyList() + + val additionalSupersOrImplementors = searchRelatedClasses(baseClass) + val completeList = listOf(qualifiedName) + additionalSupersOrImplementors return handlerCache.value .filter { messageType == null || it.handlerType.messageType == messageType } - .filter { - if (reverseAssign) areAssignable(project, qualifiedName, it.payload) else areAssignable( - project, - it.payload, - qualifiedName - ) - } + .filter { completeList.contains(it.payload) } .filter { it.element.isValid } } + private fun searchRelatedClasses(baseClass: PsiClass): List { + val implementors = ClassInheritorsSearch.search(baseClass, project.axonScope(), true) + .mapNotNull { it.qualifiedName } + .distinct() + + // The supers call only returns one level at a time. We need to do this recursively + return implementors + baseClass.findCompleteSupers() + .mapNotNull { it.qualifiedName } + .distinct() + } + fun findAllHandlers(): List = handlerCache.value fun findHandlerByElement(psiElement: PsiElement): Handler? { diff --git a/src/main/kotlin/org/axonframework/intellij/ide/plugin/resolving/handlers/searchers/CommandHandlerInterceptorSearcher.kt b/src/main/kotlin/org/axonframework/intellij/ide/plugin/resolving/handlers/searchers/CommandHandlerInterceptorSearcher.kt deleted file mode 100644 index 464086b0..00000000 --- a/src/main/kotlin/org/axonframework/intellij/ide/plugin/resolving/handlers/searchers/CommandHandlerInterceptorSearcher.kt +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2022. Axon Framework - * - * 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. - */ - -package org.axonframework.intellij.ide.plugin.resolving.handlers.searchers - -import com.intellij.psi.PsiClass -import com.intellij.psi.PsiMethod -import org.axonframework.intellij.ide.plugin.api.Handler -import org.axonframework.intellij.ide.plugin.api.MessageHandlerType -import org.axonframework.intellij.ide.plugin.resolving.handlers.types.CommandHandlerInterceptor -import org.axonframework.intellij.ide.plugin.util.containingClassFqn -import org.axonframework.intellij.ide.plugin.util.isAggregate -import org.axonframework.intellij.ide.plugin.util.resolvePayloadType -import org.axonframework.intellij.ide.plugin.util.toQualifiedName - -/** - * Searches for any command interceptors. Currently, limited to Aggregates only. - * - * @see org.axonframework.intellij.ide.plugin.resolving.handlers.types.CommandHandlerInterceptor - */ -class CommandHandlerInterceptorSearcher : AbstractHandlerSearcher(MessageHandlerType.COMMAND_INTERCEPTOR) { - override fun createMessageHandler(method: PsiMethod, annotation: PsiClass?): Handler? { - if (!method.containingClass.isAggregate()) { - return null - } - val payloadType = method.resolvePayloadType()?.toQualifiedName() ?: "java.lang.Object" - return CommandHandlerInterceptor(method, payloadType, method.containingClassFqn()) - } -} diff --git a/src/main/kotlin/org/axonframework/intellij/ide/plugin/resolving/handlers/types/CommandHandlerInterceptor.kt b/src/main/kotlin/org/axonframework/intellij/ide/plugin/resolving/handlers/types/CommandHandlerInterceptor.kt deleted file mode 100644 index 45d5ea0e..00000000 --- a/src/main/kotlin/org/axonframework/intellij/ide/plugin/resolving/handlers/types/CommandHandlerInterceptor.kt +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2022. Axon Framework - * - * 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. - */ - -package org.axonframework.intellij.ide.plugin.resolving.handlers.types - -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiMethod -import org.axonframework.intellij.ide.plugin.AxonIcons -import org.axonframework.intellij.ide.plugin.api.Handler -import org.axonframework.intellij.ide.plugin.api.MessageHandlerType -import org.axonframework.intellij.ide.plugin.util.toShortName -import javax.swing.Icon - -/** - * Represents a method that is able to intercept a command. - * - * @param componentName The fully qualified name of the class intercepting the command - * @see org.axonframework.intellij.ide.plugin.resolving.handlers.searchers.CommandHandlerInterceptorSearcher - */ -data class CommandHandlerInterceptor( - override val element: PsiMethod, - override val payload: String, - val componentName: String, -) : Handler, PsiElement by element { - override val handlerType: MessageHandlerType = MessageHandlerType.COMMAND_INTERCEPTOR - - override fun renderText(): String { - return "Command Interceptor of ${componentName.toShortName()}" - } - - override fun renderContainerText(): String { - return element.name - } - - override fun getIcon(): Icon { - return AxonIcons.Interceptor - } -} diff --git a/src/main/kotlin/org/axonframework/intellij/ide/plugin/util/PSiProcessingUtils.kt b/src/main/kotlin/org/axonframework/intellij/ide/plugin/util/PSiProcessingUtils.kt index e8549b1d..3c737926 100644 --- a/src/main/kotlin/org/axonframework/intellij/ide/plugin/util/PSiProcessingUtils.kt +++ b/src/main/kotlin/org/axonframework/intellij/ide/plugin/util/PSiProcessingUtils.kt @@ -184,6 +184,12 @@ fun PsiElement.findParentHandlers(depth: Int = 0): List { return references.flatMap { it.element.findParentHandlers(depth + 1) } } + + +fun PsiClass.findCompleteSupers(): List { + return this.supers.flatMap { it.findCompleteSupers() } + this +} + fun String.toGetterRepresentation(): String { return "get${this.capitalize()}" } diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index ab8d5bb9..adbcba73 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -34,24 +34,16 @@ implementationClass="org.axonframework.intellij.ide.plugin.markers.publishers.PublishMethodLineMarkerProvider"/> - - - - () - Assertions.assertThat(handlers).anyMatch { - it.payload == "test.MyCommand" && it.componentName == "test.MyAggregate" && it.element.name == "intercept" - } - } - - fun `test does not resolve command handler interceptor outside of aggregates`() { - addFile( - "MyAggregate.kt", """ - data class MyCommand(@TargetAggregateIdentifier id: String) - - class MyNonAggregate { - @CommandHandlerInterceptor - fun intercept(command: MyCommand) { - - } - } - """.trimIndent() - ) - val handlers = project.handlerResolver().findAllHandlers() - .filterIsInstance() - Assertions.assertThat(handlers).isEmpty() - } -} diff --git a/src/test/kotlin/org/axonframework/intellij/ide/plugin/markers/handlers/CommandHandlerMethodLineMarkerProviderTest.kt b/src/test/kotlin/org/axonframework/intellij/ide/plugin/markers/handlers/CommandHandlerMethodLineMarkerProviderTest.kt deleted file mode 100644 index d6a4d6ef..00000000 --- a/src/test/kotlin/org/axonframework/intellij/ide/plugin/markers/handlers/CommandHandlerMethodLineMarkerProviderTest.kt +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (c) 2022. Axon Framework - * - * 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. - */ - -package org.axonframework.intellij.ide.plugin.markers.handlers - -import org.assertj.core.api.Assertions.assertThat -import org.axonframework.intellij.ide.plugin.AbstractAxonFixtureTestCase -import org.axonframework.intellij.ide.plugin.AxonIcons - -class CommandHandlerMethodLineMarkerProviderTest : AbstractAxonFixtureTestCase() { - override fun setUp() { - super.setUp() - addFile( - "MyCommand.kt", """ - data class MyCommand(val id: String) - """.trimIndent() - ) - } - - - fun `test marks command handler on function even when there are no producers in kotlin`() { - addFile( - "MyAggregate.kt", """ - @AggregateRoot - class MyAggregate { - @CommandHandler - fun handle(command: MyCommand) { - } - } - """.trimIndent(), open = true - ) - - assertThat(hasLineMarker(CommandHandlerMethodLineMarkerProvider::class.java)).isTrue - assertThat(getLineMarkerOptions(CommandHandlerMethodLineMarkerProvider::class.java)).isEmpty() - } - - fun `test marks command handler on constructor even when there are no producers in kotlin`() { - addFile( - "MyAggregate.kt", """ - @AggregateRoot - class MyAggregate { - @CommandHandler - constructor(command: MyCommand) { - } - } - """.trimIndent(), open = true - ) - - assertThat(hasLineMarker(CommandHandlerMethodLineMarkerProvider::class.java)).isTrue - assertThat(getLineMarkerOptions(CommandHandlerMethodLineMarkerProvider::class.java)).isEmpty() - } - - fun `test marks command handler on function even when there are no producers in java`() { - addFile( - "MyAggregate.java", """ - @AggregateRoot - class MyAggregate { - @CommandHandler - public void handle(MyCommand command) { - } - } - """.trimIndent(), open = true - ) - - assertThat(hasLineMarker(CommandHandlerMethodLineMarkerProvider::class.java)).isTrue - assertThat(getLineMarkerOptions(CommandHandlerMethodLineMarkerProvider::class.java)).isEmpty() - } - - fun `test marks command handler on constructor even when there are no producers in java`() { - addFile( - "MyAggregate.java", """ - @AggregateRoot - class MyAggregate { - @CommandHandler - public MyAggregate(MyCommand command) { - } - } - """.trimIndent(), open = true - ) - - assertThat(hasLineMarker(CommandHandlerMethodLineMarkerProvider::class.java)).isTrue - assertThat(getLineMarkerOptions(CommandHandlerMethodLineMarkerProvider::class.java)).isEmpty() - } - - fun `test marks command handler as intercepted when command interceptor matches`() { - addFile( - "MyAggregate.java", """ - @AggregateRoot - class MyAggregate { - @CommandHandler - public MyAggregate(MyCommand command) { - } - - @CommandHandlerInterceptor - fun intercept() {} - } - """.trimIndent(), open = true - ) - - assertThat(hasLineMarker(CommandHandlerMethodLineMarkerProvider::class.java)).isTrue - assertThat(getLineMarkerOptions(CommandHandlerMethodLineMarkerProvider::class.java)).containsExactly( - OptionSummary("Command Interceptor of MyAggregate", "intercept", AxonIcons.Interceptor) - ) - } - - fun `test shows command created by saga in command handler marker in kotlin`() { - addFile( - "MyAggregate.kt", """ - data class MySagaTriggeringEvent(val id: String) - - @Saga - class MySaga { - @SagaEventHandler - fun handleSagaEvent(event: MySagaTriggeringEvent) { - MyCommand(event.id) - } - } - - @AggregateRoot - class MyAggregate { - @CommandHandler - fun handle(command: MyCommand) { - } - } - """.trimIndent(), open = true - ) - - assertThat(hasLineMarker(CommandHandlerMethodLineMarkerProvider::class.java)).isTrue - assertThat(getLineMarkerOptions(CommandHandlerMethodLineMarkerProvider::class.java)).containsExactly( - OptionSummary("Saga: test", null, AxonIcons.Publisher) - ) - } - - fun `test shows command created by saga in command handler marker in java`() { - addFile( - "MySagaTriggeringEvent.kt", """ - data class MySagaTriggeringEvent(val id: String) - """.trimIndent() - ) - addFile( - "MySaga.java", """ - @Saga - class MySaga { - @SagaEventHandler - public void handleSagaEvent(MySagaTriggeringEvent event) { - new MyCommand(event.id); - } - } - - """.trimIndent() - ) - addFile( - "MyAggregate.java", """ - @AggregateRoot - class MyAggregate { - @CommandHandler - public void handle(MyCommand command) { - } - } - """.trimIndent(), open = true - ) - - assertThat(hasLineMarker(CommandHandlerMethodLineMarkerProvider::class.java)).isTrue - assertThat(getLineMarkerOptions(CommandHandlerMethodLineMarkerProvider::class.java)).containsExactly( - OptionSummary("Saga: test", null, AxonIcons.Publisher) - ) - } -} diff --git a/src/test/kotlin/org/axonframework/intellij/ide/plugin/markers/handlers/CommandInterceptorLineMarkerProviderTest.kt b/src/test/kotlin/org/axonframework/intellij/ide/plugin/markers/handlers/CommandInterceptorLineMarkerProviderTest.kt deleted file mode 100644 index 57453268..00000000 --- a/src/test/kotlin/org/axonframework/intellij/ide/plugin/markers/handlers/CommandInterceptorLineMarkerProviderTest.kt +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (c) 2022. Axon Framework - * - * 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. - */ - -package org.axonframework.intellij.ide.plugin.markers.handlers - -import org.assertj.core.api.Assertions.assertThat -import org.axonframework.intellij.ide.plugin.AbstractAxonFixtureTestCase -import org.axonframework.intellij.ide.plugin.AxonIcons - -class CommandInterceptorLineMarkerProviderTest : AbstractAxonFixtureTestCase() { - fun `test shows marker without options on interceptor with no intercepted handlers`() { - addFile( - "MyAggregate.kt", """ - class MyCommand - - @AggregateRoot - class MyAggregate { - - @CommandHandlerInterceptor - fun intercept(command: MyCommand) { - } - } - """.trimIndent(), open = true - ) - assertThat(hasLineMarker(CommandInterceptorLineMarkerProvider::class.java)).isTrue - assertThat(getLineMarkerOptions(CommandInterceptorLineMarkerProvider::class.java)).isEmpty() - } - - fun `test shows intercepted command on interceptor in same class`() { - addFile( - "MyAggregate.kt", """ - class MyCommand - - @AggregateRoot - class MyAggregate { - - @CommandHandlerInterceptor - fun intercept(command: MyCommand) { - } - - @CommandHandler - fun handle(command: MyCommand) { - } - } - """.trimIndent(), open = true - ) - assertThat(hasLineMarker(CommandInterceptorLineMarkerProvider::class.java)).isTrue - assertThat(getLineMarkerOptions(CommandInterceptorLineMarkerProvider::class.java)).containsExactly( - OptionSummary("MyCommand", "MyAggregate", AxonIcons.Handler) - ) - } - - fun `test shows intercepted command when is interface of payload`() { - addFile( - "MyAggregate.kt", """ - interface MyCommandInterface - class MyCommand : MyCommandInterface - - @AggregateRoot - class MyAggregate { - - @CommandHandlerInterceptor - fun intercept(commandInterface: MyCommandInterface) { - } - - @CommandHandler - fun handle(command: MyCommand) { - } - } - """.trimIndent(), open = true - ) - assertThat(hasLineMarker(CommandInterceptorLineMarkerProvider::class.java)).isTrue - assertThat(getLineMarkerOptions(CommandInterceptorLineMarkerProvider::class.java)).containsExactly( - OptionSummary("MyCommand", "MyAggregate", AxonIcons.Handler) - ) - } - - fun `test shows intercepted command on interceptor`() { - addFile( - "MyAggregate.kt", """ - interface MyCommandInterface - class MyCommand : MyCommandInterface - - @AggregateRoot - class MyAggregate { - - @CommandHandlerInterceptor - fun intercept() { - } - - @CommandHandler - fun handle(command: MyCommand) { - } - } - """.trimIndent(), open = true - ) - assertThat(hasLineMarker(CommandInterceptorLineMarkerProvider::class.java)).isTrue - assertThat(getLineMarkerOptions(CommandInterceptorLineMarkerProvider::class.java)).containsExactly( - OptionSummary("MyCommand", "MyAggregate", AxonIcons.Handler) - ) - } - - fun `test shows intercepted entity command handler on parent aggregate command interceptor`() { - addFile( - "MyAggregate.kt", """ - class MyCommand - - class MyEntity { - - @CommandHandler - fun handle(command: MyCommand) { - } - } - - - @AggregateRoot - class MyAggregate { - @AggregateMember - private lateinit var entity: MyEntity - - @CommandHandlerInterceptor - fun intercept() { - } - } - """.trimIndent(), open = true - ) - assertThat(hasLineMarker(CommandInterceptorLineMarkerProvider::class.java)).isTrue - assertThat(getLineMarkerOptions(CommandInterceptorLineMarkerProvider::class.java)).containsExactly( - OptionSummary("MyCommand", "MyEntity", AxonIcons.Handler) - ) - } -}