2020
2121package com.demonwav.mcdev.platform.fabric.reference
2222
23+ import com.demonwav.mcdev.platform.fabric.util.FabricConstants
24+ import com.demonwav.mcdev.util.fullQualifiedName
2325import com.demonwav.mcdev.util.manipulator
2426import com.demonwav.mcdev.util.reference.InspectionReference
27+ import com.intellij.codeInsight.completion.JavaLookupElementBuilder
2528import com.intellij.json.psi.JsonStringLiteral
2629import com.intellij.openapi.util.TextRange
2730import com.intellij.psi.JavaPsiFacade
2831import com.intellij.psi.PsiClass
32+ import com.intellij.psi.PsiClassType
2933import com.intellij.psi.PsiElement
3034import com.intellij.psi.PsiElementResolveResult
3135import com.intellij.psi.PsiField
@@ -36,6 +40,8 @@ import com.intellij.psi.PsiReference
3640import com.intellij.psi.PsiReferenceBase
3741import com.intellij.psi.PsiReferenceProvider
3842import com.intellij.psi.ResolveResult
43+ import com.intellij.psi.search.searches.ClassInheritorsSearch
44+ import com.intellij.util.ArrayUtil
3945import com.intellij.util.IncorrectOperationException
4046import com.intellij.util.ProcessingContext
4147
@@ -130,7 +136,34 @@ object EntryPointReference : PsiReferenceProvider() {
130136
131137 fun isEntryPointReference (reference : PsiReference ) = reference is Reference
132138
133- private class Reference (
139+ fun isValidEntrypointClass (element : PsiClass ): Boolean {
140+ val psiFacade = JavaPsiFacade .getInstance(element.project)
141+ var inheritsEntrypointInterface = false
142+ for (entrypoint in FabricConstants .ENTRYPOINTS ) {
143+ val entrypointClass = psiFacade.findClass(entrypoint, element.resolveScope)
144+ ? : continue
145+ if (element.isInheritor(entrypointClass, true )) {
146+ inheritsEntrypointInterface = true
147+ break
148+ }
149+ }
150+ return inheritsEntrypointInterface
151+ }
152+
153+ fun isValidEntrypointField (field : PsiField ): Boolean {
154+ if (! field.hasModifierProperty(PsiModifier .PUBLIC ) || ! field.hasModifierProperty(PsiModifier .STATIC )) {
155+ return false
156+ }
157+
158+ val fieldTypeClass = (field.type as ? PsiClassType )?.resolve()
159+ return fieldTypeClass != null && isValidEntrypointClass(fieldTypeClass)
160+ }
161+
162+ fun isValidEntrypointMethod (method : PsiMethod ): Boolean {
163+ return method.hasModifierProperty(PsiModifier .PUBLIC ) && ! method.hasParameters()
164+ }
165+
166+ class Reference (
134167 element : JsonStringLiteral ,
135168 range : TextRange ,
136169 private val innerClassDepth : Int ,
@@ -186,5 +219,39 @@ object EntryPointReference : PsiReferenceProvider() {
186219 return manipulator.handleContentChange(element, classRange, targetClass.qualifiedName)
187220 }
188221 }
222+
223+ override fun getVariants (): Array <Any > {
224+ val manipulator = element.manipulator
225+ ? : return ArrayUtil .EMPTY_OBJECT_ARRAY
226+
227+ val range = manipulator.getRangeInElement(element)
228+ val text = element.text.substring(range.startOffset, range.endOffset)
229+ val parts = text.split(" ::" , limit = 2 )
230+
231+ val variants = mutableListOf<Any >()
232+ if (! isMemberReference) {
233+ val psiFacade = JavaPsiFacade .getInstance(element.project)
234+ for (entrypoint in FabricConstants .ENTRYPOINTS ) {
235+ val entrypointClass = psiFacade.findClass(entrypoint, element.resolveScope)
236+ ? : continue
237+ ClassInheritorsSearch .search(entrypointClass, true )
238+ .mapNotNullTo(variants) {
239+ val shortName = it.name ? : return @mapNotNullTo null
240+ val fqName = it.fullQualifiedName ? : return @mapNotNullTo null
241+ JavaLookupElementBuilder .forClass(it, fqName, true ).withPresentableText(shortName)
242+ }
243+ }
244+ } else if (parts.size >= 2 ) {
245+ val psiFacade = JavaPsiFacade .getInstance(element.project)
246+ val className = parts[0 ].replace(' $' , ' .' )
247+ val clazz = psiFacade.findClass(className, element.resolveScope)
248+ if (clazz != null ) {
249+ clazz.fields.filterTo(variants, ::isValidEntrypointField)
250+ clazz.methods.filterTo(variants, ::isValidEntrypointMethod)
251+ }
252+ }
253+
254+ return variants.toTypedArray()
255+ }
189256 }
190257}
0 commit comments