Skip to content

Commit 90ea068

Browse files
Merge pull request #290 from AxonFramework/fix/take-hierarchy-into-account
Take class hierarchy into account when resolving
2 parents bf15afa + 0425dbc commit 90ea068

15 files changed

+39
-654
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
- Plugin is now compatible with IDEA 2024.3 (IDEA 243.*) with minimum version of 2024.2
88
- Fix various deprecation warnings
99
- Fix various javadoc issues
10+
- Fix class hierarchy not being taken into account for handler and creator resolving.
11+
- Remove wrong implementation of interceptor support, to possibly be re-implemented in a future release in a better form.
1012

1113
## [0.8.7]
1214
- Plugin is now compatible with IDEA 2024.2 (IDEA 242.*)

src/main/kotlin/org/axonframework/intellij/ide/plugin/api/MessageHandlerType.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ enum class MessageHandlerType(
3232
EVENT_SOURCING(AxonAnnotation.EVENT_SOURCING_HANDLER, MessageType.EVENT),
3333
QUERY(AxonAnnotation.QUERY_HANDLER, MessageType.QUERY),
3434
DEADLINE(AxonAnnotation.DEADLINE_HANDLER, MessageType.DEADLINE),
35-
COMMAND_INTERCEPTOR(AxonAnnotation.COMMAND_HANDLER_INTERCEPTOR, MessageType.COMMAND),
3635
SAGA(AxonAnnotation.SAGA_EVENT_HANDLER, MessageType.EVENT),
3736
;
3837

src/main/kotlin/org/axonframework/intellij/ide/plugin/markers/handlers/CommandHandlerMethodLineMarkerProvider.kt

Lines changed: 0 additions & 61 deletions
This file was deleted.

src/main/kotlin/org/axonframework/intellij/ide/plugin/markers/handlers/CommandInterceptorLineMarkerProvider.kt

Lines changed: 0 additions & 69 deletions
This file was deleted.

src/main/kotlin/org/axonframework/intellij/ide/plugin/markers/handlers/CommonHandlerMethodLineMarkerProvider.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import org.axonframework.intellij.ide.plugin.util.creatorResolver
2929
* Provides a gutter icon on all generic handler methods
3030
*/
3131
class CommonHandlerMethodLineMarkerProvider : AbstractHandlerLineMarkerProvider() {
32-
private val blacklistedTypes = listOf(MessageHandlerType.DEADLINE, MessageHandlerType.COMMAND, MessageHandlerType.COMMAND_INTERCEPTOR)
32+
private val blacklistedTypes = listOf(MessageHandlerType.DEADLINE)
3333
override fun createLineMarker(
3434
element: PsiElement,
3535
handlerType: MessageHandlerType,

src/main/kotlin/org/axonframework/intellij/ide/plugin/markers/publishers/PublishMethodLineMarkerProvider.kt

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ package org.axonframework.intellij.ide.plugin.markers.publishers
1818

1919
import com.intellij.codeInsight.daemon.LineMarkerInfo
2020
import com.intellij.codeInsight.daemon.LineMarkerProvider
21-
import com.intellij.codeInsight.daemon.RelatedItemLineMarkerInfo
22-
import com.intellij.codeInsight.daemon.RelatedItemLineMarkerProvider
2321
import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder
2422
import com.intellij.ide.highlighter.JavaFileType
2523
import com.intellij.psi.PsiElement
@@ -29,7 +27,6 @@ import org.axonframework.intellij.ide.plugin.AxonIcons
2927
import org.axonframework.intellij.ide.plugin.api.MessageHandlerType
3028
import org.axonframework.intellij.ide.plugin.markers.AxonNavigationTargetRenderer
3129
import org.axonframework.intellij.ide.plugin.resolving.MessageHandlerResolver
32-
import org.axonframework.intellij.ide.plugin.resolving.handlers.types.CommandHandlerInterceptor
3330
import org.axonframework.intellij.ide.plugin.resolving.handlers.types.DeadlineHandler
3431
import org.axonframework.intellij.ide.plugin.util.containingClassFqn
3532
import org.axonframework.intellij.ide.plugin.util.handlerResolver
@@ -66,11 +63,9 @@ class PublishMethodLineMarkerProvider : LineMarkerProvider {
6663
else -> null
6764
} ?: return null
6865

69-
val allHandlers = element.handlerResolver().findHandlersForType(payload)
66+
val handlers = element.handlerResolver().findHandlersForType(payload)
7067
// Hide DeadlineHandlers here. These are handled by a more specific LineMarkerProvider
7168
.filter { it !is DeadlineHandler }
72-
val isCommand = allHandlers.all { it.handlerType == MessageHandlerType.COMMAND }
73-
val handlers = allHandlers.filter { it !is CommandHandlerInterceptor || isCommand } // Only show interceptors when is a command
7469
if (handlers.isEmpty()) {
7570
return null
7671
}

src/main/kotlin/org/axonframework/intellij/ide/plugin/resolving/MessageCreationResolver.kt

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ package org.axonframework.intellij.ide.plugin.resolving
1818

1919
import com.intellij.openapi.project.Project
2020
import com.intellij.psi.PsiElement
21+
import com.intellij.psi.search.searches.ClassInheritorsSearch
2122
import com.intellij.psi.search.searches.MethodReferencesSearch
2223
import com.intellij.psi.util.CachedValue
2324
import org.axonframework.intellij.ide.plugin.api.MessageCreator
2425
import org.axonframework.intellij.ide.plugin.resolving.creators.DefaultMessageCreator
25-
import org.axonframework.intellij.ide.plugin.util.areAssignable
2626
import org.axonframework.intellij.ide.plugin.util.axonScope
2727
import org.axonframework.intellij.ide.plugin.util.createCachedValue
2828
import org.axonframework.intellij.ide.plugin.util.findParentHandlers
@@ -38,7 +38,6 @@ import java.util.concurrent.ConcurrentHashMap
3838
* the PSI is modified (code is edited) or is collected by the garbage collector.
3939
*/
4040
class MessageCreationResolver(private val project: Project) {
41-
private val handlerResolver = project.handlerResolver()
4241
private val psiFacade = project.javaFacade()
4342
private val constructorsByPayloadCache = ConcurrentHashMap<String, CachedValue<List<MessageCreator>>>()
4443

@@ -59,25 +58,19 @@ class MessageCreationResolver(private val project: Project) {
5958
}
6059

6160
private fun findByPayload(payload: String): List<MessageCreator> {
62-
val matchingHandlers = handlerResolver.findAllHandlers()
63-
.map { it.payload }
64-
.filter { areAssignable(project, payload, it) }
65-
val classesForQualifiedName = listOf(payload).plus(matchingHandlers)
66-
.distinct()
67-
return resolveCreatorsForFqns(classesForQualifiedName)
68-
}
61+
val classes = psiFacade.findClass(payload, project.axonScope())?.let { clazz ->
62+
listOf(clazz) + ClassInheritorsSearch.search(clazz, project.axonScope(), true)
63+
} ?: return emptyList()
6964

70-
private fun resolveCreatorsForFqns(fqns: List<String>): List<MessageCreator> {
71-
return fqns.flatMap { typeFqn ->
72-
psiFacade.findClasses(typeFqn, project.axonScope()).flatMap { clazz ->
65+
return classes
66+
.flatMap { clazz ->
7367
// Account for constructors and builder methods (builder(), toBuilder(), etc)
7468
val methods = clazz.constructors + clazz.methods.filter { it.name.contains("build", ignoreCase = true) }
7569
methods
7670
.flatMap { MethodReferencesSearch.search(it, project.axonScope(), true) }
77-
.flatMap { ref -> createCreators(typeFqn, ref.element) }
71+
.flatMap { ref -> createCreators(clazz.qualifiedName!!, ref.element) }
7872
.distinct()
7973
}
80-
}
8174
}
8275

8376
private fun createCreators(payload: String, element: PsiElement): List<MessageCreator> {

src/main/kotlin/org/axonframework/intellij/ide/plugin/resolving/MessageHandlerResolver.kt

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,22 @@
1717
package org.axonframework.intellij.ide.plugin.resolving
1818

1919
import com.intellij.openapi.project.Project
20+
import com.intellij.psi.JavaPsiFacade
21+
import com.intellij.psi.PsiClass
2022
import com.intellij.psi.PsiElement
23+
import com.intellij.psi.search.searches.ClassInheritorsSearch
2124
import org.axonframework.intellij.ide.plugin.api.Handler
2225
import org.axonframework.intellij.ide.plugin.api.MessageType
2326
import org.axonframework.intellij.ide.plugin.resolving.handlers.searchers.AggregateConstructorSearcher
24-
import org.axonframework.intellij.ide.plugin.resolving.handlers.searchers.CommandHandlerInterceptorSearcher
2527
import org.axonframework.intellij.ide.plugin.resolving.handlers.searchers.CommandHandlerSearcher
2628
import org.axonframework.intellij.ide.plugin.resolving.handlers.searchers.DeadlineHandlerSearcher
2729
import org.axonframework.intellij.ide.plugin.resolving.handlers.searchers.EventHandlerSearcher
2830
import org.axonframework.intellij.ide.plugin.resolving.handlers.searchers.EventSourcingHandlerSearcher
2931
import org.axonframework.intellij.ide.plugin.resolving.handlers.searchers.QueryHandlerSearcher
3032
import org.axonframework.intellij.ide.plugin.resolving.handlers.searchers.SagaEventHandlerSearcher
31-
import org.axonframework.intellij.ide.plugin.util.areAssignable
33+
import org.axonframework.intellij.ide.plugin.util.axonScope
3234
import org.axonframework.intellij.ide.plugin.util.createCachedValue
35+
import org.axonframework.intellij.ide.plugin.util.findCompleteSupers
3336

3437
/**
3538
* 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
4144
*/
4245
class MessageHandlerResolver(private val project: Project) {
4346
private val searchers = listOf(
44-
CommandHandlerInterceptorSearcher(),
4547
CommandHandlerSearcher(),
4648
EventHandlerSearcher(),
4749
EventSourcingHandlerSearcher(),
@@ -61,20 +63,29 @@ class MessageHandlerResolver(private val project: Project) {
6163
fun findHandlersForType(
6264
qualifiedName: String,
6365
messageType: MessageType? = null,
64-
reverseAssign: Boolean = false
6566
): List<Handler> {
67+
val baseClass = JavaPsiFacade.getInstance(project).findClasses(qualifiedName, project.axonScope()).firstOrNull()
68+
?: return emptyList()
69+
70+
val additionalSupersOrImplementors = searchRelatedClasses(baseClass)
71+
val completeList = listOf(qualifiedName) + additionalSupersOrImplementors
6672
return handlerCache.value
6773
.filter { messageType == null || it.handlerType.messageType == messageType }
68-
.filter {
69-
if (reverseAssign) areAssignable(project, qualifiedName, it.payload) else areAssignable(
70-
project,
71-
it.payload,
72-
qualifiedName
73-
)
74-
}
74+
.filter { completeList.contains(it.payload) }
7575
.filter { it.element.isValid }
7676
}
7777

78+
private fun searchRelatedClasses(baseClass: PsiClass): List<String> {
79+
val implementors = ClassInheritorsSearch.search(baseClass, project.axonScope(), true)
80+
.mapNotNull { it.qualifiedName }
81+
.distinct()
82+
83+
// The supers call only returns one level at a time. We need to do this recursively
84+
return implementors + baseClass.findCompleteSupers()
85+
.mapNotNull { it.qualifiedName }
86+
.distinct()
87+
}
88+
7889
fun findAllHandlers(): List<Handler> = handlerCache.value
7990

8091
fun findHandlerByElement(psiElement: PsiElement): Handler? {

src/main/kotlin/org/axonframework/intellij/ide/plugin/resolving/handlers/searchers/CommandHandlerInterceptorSearcher.kt

Lines changed: 0 additions & 42 deletions
This file was deleted.

0 commit comments

Comments
 (0)