Skip to content

Commit 3192ec3

Browse files
authored
Convert Sponge Getter support to UAST (#795)
1 parent d6796fa commit 3192ec3

12 files changed

+314
-503
lines changed

src/main/kotlin/insight/InsightUtil.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,13 @@ import org.jetbrains.uast.UClass
1818
import org.jetbrains.uast.UElement
1919
import org.jetbrains.uast.UMethod
2020
import org.jetbrains.uast.UParameter
21+
import org.jetbrains.uast.getParentOfType
2122
import org.jetbrains.uast.toUElementOfType
2223

2324
val UElement.uastEventListener: Pair<UClass, UMethod>?
2425
get() {
2526
// The PsiIdentifier is going to be a method of course!
26-
val method = this.uastParent as? UMethod ?: return null
27+
val method = this.getParentOfType<UMethod>() ?: return null
2728
if (method.javaPsi.hasModifierProperty(PsiModifier.ABSTRACT)) {
2829
// I don't think any implementation allows for abstract method listeners.
2930
return null

src/main/kotlin/insight/ListenerLineMarkerProvider.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,13 @@ class ListenerLineMarkerProvider : LineMarkerProviderDescriptor() {
4545
return null
4646
}
4747

48-
val listener = element.toUElementOfType<UIdentifier>()?.uastEventListener ?: return null
48+
val identifier = element.toUElementOfType<UIdentifier>()
49+
if (identifier?.uastParent !is UMethod) {
50+
// We only target the method name
51+
return null
52+
}
53+
54+
val listener = identifier.uastEventListener ?: return null
4955
// By this point, we can guarantee that the action of "go to declaration" will work
5056
// since the PsiClass can be resolved, meaning the event listener is listening to
5157
// a valid event.

src/main/kotlin/platform/sponge/completion/SpongeCompletionConfidence.kt

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

src/main/kotlin/platform/sponge/completion/SpongeGetterFilterCompletionContributor.kt

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

src/main/kotlin/platform/sponge/inspection/SpongeInvalidGetterTargetInspection.kt

Lines changed: 25 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -13,90 +13,43 @@ package com.demonwav.mcdev.platform.sponge.inspection
1313
import com.demonwav.mcdev.platform.sponge.util.SpongeConstants
1414
import com.demonwav.mcdev.platform.sponge.util.isValidSpongeListener
1515
import com.demonwav.mcdev.platform.sponge.util.resolveSpongeGetterTarget
16-
import com.intellij.codeInsight.AutoPopupController
16+
import com.intellij.codeInspection.AbstractBaseUastLocalInspectionTool
17+
import com.intellij.codeInspection.InspectionManager
1718
import com.intellij.codeInspection.ProblemDescriptor
18-
import com.intellij.openapi.project.Project
19-
import com.intellij.psi.JavaPsiFacade
20-
import com.intellij.psi.PsiAnnotation
21-
import com.intellij.psi.PsiMethod
22-
import com.intellij.psi.util.PsiEditorUtil
23-
import com.intellij.structuralsearch.plugin.util.SmartPsiPointer
24-
import com.siyeh.ig.BaseInspection
25-
import com.siyeh.ig.BaseInspectionVisitor
26-
import com.siyeh.ig.InspectionGadgetsFix
19+
import com.intellij.codeInspection.ProblemHighlightType
20+
import org.jetbrains.uast.UMethod
2721

28-
class SpongeInvalidGetterTargetInspection : BaseInspection() {
22+
class SpongeInvalidGetterTargetInspection : AbstractBaseUastLocalInspectionTool() {
2923

3024
override fun getDisplayName() = "@Getter targeted method does not exist"
3125

32-
override fun buildErrorString(vararg infos: Any?) = staticDescription
33-
3426
override fun getStaticDescription() =
3527
"@Getter must target a method accessible from the event class of this listener"
3628

37-
override fun buildVisitor(): BaseInspectionVisitor {
38-
return object : BaseInspectionVisitor() {
39-
override fun visitMethod(method: PsiMethod) {
40-
if (method.parameters.size < 2 || !method.isValidSpongeListener()) {
41-
return
42-
}
43-
44-
for (i in 1 until method.parameters.size) {
45-
val parameter = method.parameters[i]
46-
val getterAnnotation =
47-
parameter.getAnnotation(SpongeConstants.GETTER_ANNOTATION) as? PsiAnnotation ?: continue
48-
49-
val getterTarget = getterAnnotation.resolveSpongeGetterTarget()
50-
if (getterTarget == null) {
51-
val attribute = getterAnnotation.findAttributeValue("value")
52-
if (attribute == null) {
53-
registerError(getterAnnotation, getterAnnotation)
54-
} else {
55-
registerError(attribute)
56-
}
57-
continue
58-
}
59-
}
60-
}
61-
}
62-
}
63-
64-
override fun buildFix(vararg infos: Any?): InspectionGadgetsFix? {
65-
if (infos.isEmpty()) {
66-
return null
67-
}
68-
69-
val annotation = infos[0] as PsiAnnotation
70-
if (!annotation.isWritable) {
29+
override fun checkMethod(
30+
method: UMethod,
31+
manager: InspectionManager,
32+
isOnTheFly: Boolean
33+
): Array<ProblemDescriptor>? {
34+
if (!method.isValidSpongeListener()) {
7135
return null
7236
}
7337

74-
return QuickFix(annotation, "Add target method")
75-
}
76-
77-
class QuickFix(annotation: PsiAnnotation, private val name: String) : InspectionGadgetsFix() {
78-
79-
private val pointer = SmartPsiPointer(annotation)
80-
81-
override fun doFix(project: Project, descriptor: ProblemDescriptor?) {
82-
doFix(project, pointer.element as PsiAnnotation)
83-
}
84-
85-
override fun getFamilyName() = name
86-
87-
override fun getName() = name
88-
89-
companion object {
90-
91-
fun doFix(project: Project, annotation: PsiAnnotation) {
92-
val value = JavaPsiFacade.getElementFactory(project).createExpressionFromText("\"\"", annotation)
93-
val newValue = annotation.setDeclaredAttributeValue(null, value)
94-
val editor = PsiEditorUtil.Service.getInstance().findEditorByPsiElement(annotation) ?: return
95-
editor.caretModel.removeSecondaryCarets()
96-
editor.selectionModel.removeSelection()
97-
editor.caretModel.moveToOffset(newValue.textOffset + 1)
98-
AutoPopupController.getInstance(project).scheduleAutoPopup(editor)
38+
val problems = mutableListOf<ProblemDescriptor>()
39+
for (parameter in method.uastParameters.drop(1)) {
40+
val getter = parameter.findAnnotation(SpongeConstants.GETTER_ANNOTATION) ?: continue
41+
if (getter.resolveSpongeGetterTarget() == null) {
42+
getter.findAttributeValue("value")?.sourcePsi?.let { problemAnchor ->
43+
problems += manager.createProblemDescriptor(
44+
problemAnchor,
45+
this.staticDescription,
46+
isOnTheFly,
47+
null,
48+
ProblemHighlightType.GENERIC_ERROR_OR_WARNING
49+
)
50+
}
9951
}
10052
}
53+
return problems.toTypedArray()
10154
}
10255
}

0 commit comments

Comments
 (0)