@@ -36,6 +36,7 @@ import com.demonwav.mcdev.util.constantStringValue
3636import com.demonwav.mcdev.util.descriptor
3737import com.demonwav.mcdev.util.findAnnotation
3838import com.demonwav.mcdev.util.findContainingClass
39+ import com.demonwav.mcdev.util.findContainingModifierList
3940import com.demonwav.mcdev.util.findField
4041import com.demonwav.mcdev.util.findMethods
4142import com.demonwav.mcdev.util.findQualifiedClass
@@ -45,6 +46,7 @@ import com.demonwav.mcdev.util.mapToArray
4546import com.demonwav.mcdev.util.resolveClass
4647import com.demonwav.mcdev.util.resolveType
4748import com.demonwav.mcdev.util.resolveTypeArray
49+ import com.intellij.openapi.editor.Editor
4850import com.intellij.openapi.extensions.ExtensionPointName
4951import com.intellij.openapi.project.Project
5052import com.intellij.openapi.util.RecursionManager
@@ -55,10 +57,14 @@ import com.intellij.psi.PsiCallExpression
5557import com.intellij.psi.PsiClass
5658import com.intellij.psi.PsiElement
5759import com.intellij.psi.PsiField
60+ import com.intellij.psi.PsiLiteral
5861import com.intellij.psi.PsiMember
5962import com.intellij.psi.PsiMethod
63+ import com.intellij.psi.PsiModifierList
6064import com.intellij.psi.PsiNameValuePair
6165import com.intellij.psi.PsiTypes
66+ import com.intellij.psi.codeStyle.CodeStyleManager
67+ import com.intellij.psi.codeStyle.JavaCodeStyleManager
6268import com.intellij.psi.search.GlobalSearchScope
6369import com.intellij.psi.search.searches.AnnotatedMembersSearch
6470import com.intellij.psi.search.searches.MethodReferencesSearch
@@ -418,7 +424,7 @@ private fun findNamespace(
418424
419425private val DYNAMIC_SELECTOR_PATTERN = " (?i)^@([a-z]+(:[a-z]+)?)(\\ ((.*)\\ ))?$" .toRegex()
420426
421- abstract class DynamicSelectorParser (id : String , vararg aliases : String ) : MixinSelectorParser {
427+ abstract class DynamicSelectorParser (val id : String , vararg aliases : String ) : MixinSelectorParser {
422428 val validIds = aliases.toSet() + id
423429
424430 final override fun parse (value : String , context : PsiElement ): MixinSelector ? {
@@ -431,6 +437,9 @@ abstract class DynamicSelectorParser(id: String, vararg aliases: String) : Mixin
431437 }
432438
433439 abstract fun parseDynamic (args : String , context : PsiElement ): MixinSelector ?
440+
441+ open fun onCompleted (editor : Editor , reference : PsiLiteral ) {
442+ }
434443}
435444
436445// @Desc
@@ -546,6 +555,32 @@ class DescSelectorParser : DynamicSelectorParser("Desc", "mixin:Desc") {
546555 }
547556 }
548557
558+ override fun onCompleted (editor : Editor , reference : PsiLiteral ) {
559+ val modifierList = reference.findContainingModifierList() ? : return
560+ if (modifierList.hasAnnotation(DESC )) {
561+ return
562+ }
563+
564+ val project = reference.project
565+
566+ val descAnnotation = modifierList.addAfter(
567+ JavaPsiFacade .getElementFactory(project)
568+ .createAnnotationFromText(" @${DESC } (\"\" )" , reference),
569+ null
570+ )
571+
572+ // add imports and reformat
573+ JavaCodeStyleManager .getInstance(project).shortenClassReferences(descAnnotation)
574+ JavaCodeStyleManager .getInstance(project).optimizeImports(modifierList.containingFile)
575+ val formattedModifierList = CodeStyleManager .getInstance(project).reformat(modifierList) as PsiModifierList
576+
577+ // move the caret to @Desc("<caret>")
578+ val formattedDescAnnotation = formattedModifierList.findAnnotation(DESC )
579+ ? : return
580+ val descLiteral = formattedDescAnnotation.findDeclaredAttributeValue(null ) ? : return
581+ editor.caretModel.moveToOffset(descLiteral.textRange.startOffset + 1 )
582+ }
583+
549584 object Util {
550585 fun descSelectorFromAnnotation (descAnnotation : PsiAnnotation ): DescSelector ? {
551586 val explicitOwner = descAnnotation.findAttributeValue(" owner" )
0 commit comments