Skip to content

Commit 324f3d9

Browse files
Merge pull request #254 from AxonFramework/fix/235-popup-exception
Move to built-in gutter renderer to prevent exception
2 parents fc06e94 + 926b703 commit 324f3d9

25 files changed

+161
-270
lines changed

gradle.properties

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@
1919

2020
pluginGroup=io.axoniq.ide.intellij
2121
pluginName=Axon Framework
22-
pluginVersion=0.8.2
23-
axonVersion=4.7.0
22+
pluginVersion=0.8.3
23+
axonVersion=4.9.0
2424

2525
# See https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
2626
# for insight into build numbers and IntelliJ Platform versions.
27-
pluginSinceBuild = 231
27+
pluginSinceBuild = 232
2828
pluginUntilBuild = 232.*
2929

3030
# IntelliJ Platform Properties -> https://github.com/JetBrains/gradle-intellij-plugin#intellij-platform-properties

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class ClassReferenceHierarcyItem(
3131
private val field: PsiField?,
3232
override val element: PsiElement = field ?: clazz,
3333
val depth: Int
34-
) : PsiElementWrapper {
34+
) : PsiElementWrapper, PsiElement by element {
3535

3636
override fun getIcon(): Icon {
3737
return AxonIcons.Axon

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import javax.swing.Icon
3030
* @see Handler
3131
* @see MessageCreator
3232
*/
33-
interface PsiElementWrapper {
33+
interface PsiElementWrapper : PsiElement{
3434
val element: PsiElement
3535

3636

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

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

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

Lines changed: 0 additions & 80 deletions
This file was deleted.
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright (c) (2010-2023). Axon Framework
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.axonframework.intellij.ide.plugin.markers
18+
19+
import com.intellij.codeInsight.navigation.impl.PsiTargetPresentationRenderer
20+
import com.intellij.psi.PsiElement
21+
import org.axonframework.intellij.ide.plugin.api.PsiElementWrapper
22+
import javax.swing.Icon
23+
24+
class AxonNavigationTargetRenderer private constructor() : PsiTargetPresentationRenderer<PsiElement>() {
25+
26+
override fun getContainerText(element: PsiElement): String? {
27+
if (element is PsiElementWrapper) {
28+
return element.renderContainerText()
29+
}
30+
return super.getContainerText(element)
31+
}
32+
33+
override fun getElementText(element: PsiElement): String {
34+
if (element is PsiElementWrapper) {
35+
return element.renderText()
36+
}
37+
return super.getElementText(element)
38+
}
39+
40+
override fun getIcon(element: PsiElement): Icon? {
41+
if (element is PsiElementWrapper) {
42+
return element.getIcon()
43+
}
44+
return super.getIcon(element)
45+
}
46+
47+
companion object {
48+
val INSTANCE = AxonNavigationTargetRenderer()
49+
}
50+
}

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

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

1919
import com.intellij.codeInsight.daemon.LineMarkerInfo
2020
import com.intellij.codeInsight.daemon.LineMarkerProvider
21+
import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder
2122
import com.intellij.openapi.util.NotNullLazyValue
2223
import com.intellij.psi.PsiElement
2324
import com.intellij.psi.PsiField
2425
import org.axonframework.intellij.ide.plugin.AxonIcons
2526
import org.axonframework.intellij.ide.plugin.api.ClassReferenceHierarcyItem
2627
import org.axonframework.intellij.ide.plugin.api.Entity
27-
import org.axonframework.intellij.ide.plugin.markers.handlers.ValidatingLazyValue
2828
import org.axonframework.intellij.ide.plugin.util.aggregateResolver
2929
import org.axonframework.intellij.ide.plugin.util.creatorResolver
3030
import org.axonframework.intellij.ide.plugin.util.handlerResolver
@@ -47,29 +47,27 @@ class ClassLineMarkerProvider : LineMarkerProvider {
4747
if (!uElement.isAggregate()) {
4848
val handlers = element.handlerResolver().findHandlersForType(qualifiedName)
4949
if (handlers.isNotEmpty()) {
50-
return AxonNavigationGutterIconRenderer(
51-
icon = AxonIcons.Axon,
52-
popupTitle = "Axon References To This Class",
53-
tooltipText = "Navigate to message handlers and creations",
54-
emptyText = "No references were found",
55-
elements = NotNullLazyValue.createValue {
50+
return NavigationGutterIconBuilder.create(AxonIcons.Axon)
51+
.setPopupTitle("Axon References To This Class")
52+
.setTooltipText("Navigate to message handlers and creations")
53+
.setEmptyPopupText("No references were found")
54+
.setTargets(NotNullLazyValue.lazy {
5655
val publishers = element.creatorResolver().getCreatorsForPayload(qualifiedName)
5756
handlers + publishers
58-
}).createLineMarkerInfo(element)
57+
})
58+
.createLineMarkerInfo(element)
5959
}
6060
}
6161

6262
val owner = element.aggregateResolver().getTopEntityOfEntityWithName(qualifiedName) ?: return null
6363
val items = createHierarchy(owner, null, 0)
6464
if (items.isNotEmpty()) {
65-
return AxonNavigationGutterIconRenderer(
66-
icon = AxonIcons.Axon,
67-
popupTitle = "Related Models",
68-
tooltipText = "Navigate to entities in the same command model hierarchy",
69-
emptyText = "No related entities were found",
70-
elements = ValidatingLazyValue(element) {
71-
items
72-
}).createLineMarkerInfo(element)
65+
return NavigationGutterIconBuilder.create(AxonIcons.Axon)
66+
.setPopupTitle("Related Models")
67+
.setTooltipText("Navigate to entities in the same command model hierarchy")
68+
.setEmptyPopupText("No related entities were found")
69+
.setTargets(NotNullLazyValue.lazy { items })
70+
.createLineMarkerInfo(element)
7371
}
7472

7573
return null

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ abstract class AbstractHandlerLineMarkerProvider : LineMarkerProvider {
5050
// Do nothing, IntelliJ does not even want us to log it
5151
return null
5252
}
53-
// We don't want to do anything on errors here. As is shown by Sentry exception catching, the process is error-=prone
53+
// We don't want to do anything on errors here. As is shown by Sentry exception catching, the process is error-prone
5454
// mostly due to Kotlin plugin internals. We don't want to pester the user with it.
5555
// Generally, the issue will resolve itself on the next line marker pass anyway.
5656
logger<AbstractHandlerLineMarkerProvider>().error("Got an exception while analyzing line markers in class {}", e, this::class.java.name)

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

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@
1717
package org.axonframework.intellij.ide.plugin.markers.handlers
1818

1919
import com.intellij.codeInsight.daemon.LineMarkerInfo
20+
import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder
21+
import com.intellij.openapi.util.NotNullLazyValue
2022
import com.intellij.psi.PsiElement
2123
import org.axonframework.intellij.ide.plugin.AxonIcons
2224
import org.axonframework.intellij.ide.plugin.api.MessageHandlerType
2325
import org.axonframework.intellij.ide.plugin.api.MessageType
24-
import org.axonframework.intellij.ide.plugin.markers.AxonNavigationGutterIconRenderer
26+
import org.axonframework.intellij.ide.plugin.markers.AxonNavigationTargetRenderer
2527
import org.axonframework.intellij.ide.plugin.resolving.handlers.types.CommandHandlerInterceptor
2628
import org.axonframework.intellij.ide.plugin.util.creatorResolver
2729
import org.axonframework.intellij.ide.plugin.util.handlerResolver
@@ -43,16 +45,17 @@ class CommandHandlerMethodLineMarkerProvider : AbstractHandlerLineMarkerProvider
4345
.filterIsInstance<CommandHandlerInterceptor>()
4446

4547
val icon = if (interceptingElements.isNotEmpty()) AxonIcons.HandlerIntercepted else AxonIcons.Handler
46-
return AxonNavigationGutterIconRenderer(
47-
icon = icon,
48-
popupTitle = "Payload Creators",
49-
tooltipText = "Navigate to creators of $payload",
50-
emptyText = "No creators of this message payload were found",
51-
elements = ValidatingLazyValue(element) {
52-
val creatingElements = element.creatorResolver().getCreatorsForPayload(payload)
48+
return NavigationGutterIconBuilder.create(icon)
49+
.setTargets(NotNullLazyValue.lazy {
50+
val creatingElements = element.creatorResolver()
51+
.getCreatorsForPayload(payload)
5352
.distinctBy { it.parentHandler }
5453
interceptingElements + creatingElements
5554
})
55+
.setTargetRenderer { AxonNavigationTargetRenderer.INSTANCE }
56+
.setPopupTitle("Payload Creators")
57+
.setTooltipText("Navigate to creators of $payload")
58+
.setEmptyPopupText("No creators of this message payload were found")
5659
.createLineMarkerInfo(element)
5760
}
5861
}

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

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@
1717
package org.axonframework.intellij.ide.plugin.markers.handlers
1818

1919
import com.intellij.codeInsight.daemon.LineMarkerInfo
20+
import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder
21+
import com.intellij.openapi.util.NotNullLazyValue
2022
import com.intellij.psi.PsiElement
2123
import org.axonframework.intellij.ide.plugin.AxonIcons
2224
import org.axonframework.intellij.ide.plugin.api.MessageHandlerType
2325
import org.axonframework.intellij.ide.plugin.api.MessageType
24-
import org.axonframework.intellij.ide.plugin.markers.AxonNavigationGutterIconRenderer
26+
import org.axonframework.intellij.ide.plugin.markers.AxonNavigationTargetRenderer
2527
import org.axonframework.intellij.ide.plugin.resolving.handlers.types.CommandHandler
2628
import org.axonframework.intellij.ide.plugin.util.aggregateResolver
2729
import org.axonframework.intellij.ide.plugin.util.handlerResolver
@@ -48,12 +50,8 @@ class CommandInterceptorLineMarkerProvider : AbstractHandlerLineMarkerProvider()
4850
// An interceptor without payload is fine, default to Object to match all
4951
val actualPayload = payload ?: "java.lang.Object"
5052

51-
return AxonNavigationGutterIconRenderer(
52-
icon = AxonIcons.Interceptor,
53-
popupTitle = "Commands Intercepted",
54-
tooltipText = "Navigate to command handlers that are intercepted",
55-
emptyText = "No intercepted command handlers were found",
56-
elements = ValidatingLazyValue(element) {
53+
return NavigationGutterIconBuilder.create(AxonIcons.Interceptor)
54+
.setTargets(NotNullLazyValue.lazy {
5755
val members = element.aggregateResolver().getEntityAndAllChildrenRecursively(className)
5856
element.handlerResolver().findHandlersForType(actualPayload, MessageType.COMMAND)
5957
.filterIsInstance<CommandHandler>()
@@ -62,6 +60,10 @@ class CommandInterceptorLineMarkerProvider : AbstractHandlerLineMarkerProvider()
6260
members.any { member -> member.name == name }
6361
}
6462
})
65-
.createLineMarkerInfo(element)
63+
.setTargetRenderer { AxonNavigationTargetRenderer.INSTANCE }
64+
.setPopupTitle("Commands Intercepted")
65+
.setTooltipText("Navigate to command handlers that are intercepted")
66+
.setEmptyPopupText("No intercepted command handlers were found")
67+
.createLineMarkerInfo(element, )
6668
}
6769
}

0 commit comments

Comments
 (0)