-
Notifications
You must be signed in to change notification settings - Fork 186
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add dialog to automatically add mcdev annotations library if not present
- Loading branch information
1 parent
95e914a
commit 2d660a2
Showing
13 changed files
with
433 additions
and
63 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
90 changes: 90 additions & 0 deletions
90
src/main/kotlin/sideonly/MakeInferredMcdevAnnotationExplicit.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
/* | ||
* Minecraft Dev for IntelliJ | ||
* | ||
* https://minecraftdev.org | ||
* | ||
* Copyright (c) 2020 minecraft-dev | ||
* | ||
* MIT License | ||
*/ | ||
|
||
package com.demonwav.mcdev.sideonly | ||
|
||
import com.demonwav.mcdev.util.findModule | ||
import com.intellij.codeInsight.FileModificationService | ||
import com.intellij.codeInsight.intention.impl.BaseIntentionAction | ||
import com.intellij.lang.java.JavaLanguage | ||
import com.intellij.openapi.command.WriteCommandAction | ||
import com.intellij.openapi.editor.Editor | ||
import com.intellij.openapi.project.DumbService | ||
import com.intellij.openapi.project.Project | ||
import com.intellij.psi.JavaPsiFacade | ||
import com.intellij.psi.PsiCompiledElement | ||
import com.intellij.psi.PsiFile | ||
import com.intellij.psi.PsiModifierListOwner | ||
import com.intellij.psi.codeStyle.JavaCodeStyleManager | ||
import com.intellij.psi.util.PsiUtilCore | ||
|
||
class MakeInferredMcdevAnnotationExplicit : BaseIntentionAction() { | ||
override fun getFamilyName() = "Make Inferred MinecraftDev Annotations Explicit" | ||
|
||
override fun getText() = "Make Inferred MinecraftDev Annotations Explicit" | ||
|
||
override fun isAvailable(project: Project, editor: Editor, file: PsiFile): Boolean { | ||
val leaf = file.findElementAt(editor.caretModel.offset) ?: return false | ||
val owner = leaf.parent as? PsiModifierListOwner | ||
return isAvailable(file, owner) | ||
} | ||
|
||
fun isAvailable(file: PsiFile, owner: PsiModifierListOwner?): Boolean { | ||
if (owner != null && | ||
owner.language.isKindOf(JavaLanguage.INSTANCE) && | ||
isWritable(owner) && | ||
file.findModule() != null | ||
) { | ||
val annotation = SideOnlyUtil.getInferredAnnotationOnly(owner, SideHardness.HARD) | ||
?: SideOnlyUtil.getInferredAnnotationOnly(owner, SideHardness.SOFT) | ||
if (annotation != null) { | ||
text = "Insert '@CheckEnv(Env.${annotation.side})'" | ||
return true | ||
} | ||
} | ||
return false | ||
} | ||
|
||
private fun isWritable(owner: PsiModifierListOwner): Boolean { | ||
if (owner is PsiCompiledElement) return false | ||
val vFile = PsiUtilCore.getVirtualFile(owner) | ||
return vFile != null && vFile.isInLocalFileSystem | ||
} | ||
|
||
override fun invoke(project: Project, editor: Editor, file: PsiFile) { | ||
val leaf = file.findElementAt(editor.caretModel.offset) ?: return | ||
val owner = leaf.parent as? PsiModifierListOwner ?: return | ||
makeAnnotationExplicit(project, file, owner) | ||
} | ||
|
||
fun makeAnnotationExplicit(project: Project, file: PsiFile, owner: PsiModifierListOwner) { | ||
val modifierList = owner.modifierList ?: return | ||
val module = file.findModule() ?: return | ||
if (!SideOnlyUtil.ensureMcdevDependencyPresent(project, module, familyName, file.resolveScope)) { | ||
return | ||
} | ||
if (!FileModificationService.getInstance().preparePsiElementForWrite(owner)) return | ||
val facade = JavaPsiFacade.getInstance(project) | ||
val inferredSide = SideOnlyUtil.getInferredAnnotationOnly(owner, SideHardness.HARD) | ||
?: SideOnlyUtil.getInferredAnnotationOnly(owner, SideHardness.SOFT) ?: return | ||
val inferred = facade.elementFactory.createAnnotationFromText( | ||
"@${SideOnlyUtil.MCDEV_SIDEONLY_ANNOTATION}(${SideOnlyUtil.MCDEV_SIDE}.${inferredSide.side})", | ||
owner | ||
) | ||
WriteCommandAction.runWriteCommandAction(project) { | ||
DumbService.getInstance(project).withAlternativeResolveEnabled { | ||
JavaCodeStyleManager.getInstance(project) | ||
.shortenClassReferences(modifierList.addAfter(inferred, null)) | ||
} | ||
} | ||
} | ||
|
||
override fun startInWriteAction() = false | ||
} |
42 changes: 0 additions & 42 deletions
42
src/main/kotlin/sideonly/SideOnlyInferredAnnotationProvider.kt
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
/* | ||
* Minecraft Dev for IntelliJ | ||
* | ||
* https://minecraftdev.org | ||
* | ||
* Copyright (c) 2020 minecraft-dev | ||
* | ||
* MIT License | ||
*/ | ||
|
||
package com.demonwav.mcdev.sideonly | ||
|
||
import com.demonwav.mcdev.MinecraftSettings | ||
import com.intellij.codeInsight.daemon.LineMarkerInfo | ||
import com.intellij.codeInsight.daemon.LineMarkerProvider | ||
import com.intellij.icons.AllIcons | ||
import com.intellij.ide.actions.ApplyIntentionAction | ||
import com.intellij.openapi.actionSystem.DefaultActionGroup | ||
import com.intellij.openapi.actionSystem.impl.SimpleDataContext | ||
import com.intellij.openapi.editor.Editor | ||
import com.intellij.openapi.editor.markup.GutterIconRenderer | ||
import com.intellij.openapi.fileEditor.FileEditorManager | ||
import com.intellij.openapi.project.Project | ||
import com.intellij.openapi.ui.popup.JBPopup | ||
import com.intellij.openapi.ui.popup.JBPopupFactory | ||
import com.intellij.psi.PsiDocumentManager | ||
import com.intellij.psi.PsiElement | ||
import com.intellij.psi.PsiFile | ||
import com.intellij.psi.PsiIdentifier | ||
import com.intellij.psi.PsiModifierListOwner | ||
import com.intellij.psi.util.PsiUtilCore | ||
import com.intellij.ui.awt.RelativePoint | ||
import java.awt.event.MouseEvent | ||
|
||
class SideOnlyLineMarkerProvider : LineMarkerProvider { | ||
override fun getLineMarkerInfo(element: PsiElement): LineMarkerInfo<*>? { | ||
if (!MinecraftSettings.instance.isShowSideOnlyGutterIcons) { | ||
return null | ||
} | ||
if (element !is PsiIdentifier) { | ||
return null | ||
} | ||
val listOwner = element.parent as? PsiModifierListOwner ?: return null | ||
val implicitHard = SideOnlyUtil.getInferredAnnotationOnly(listOwner, SideHardness.HARD) | ||
val implicitSoft = SideOnlyUtil.getInferredAnnotationOnly(listOwner, SideHardness.SOFT) | ||
val implicitAnnotation = implicitHard ?: implicitSoft ?: return null | ||
|
||
var message = "Implicit " | ||
message += if (implicitHard == null) { | ||
"soft" | ||
} else { | ||
"hard" | ||
} | ||
message += "-sided annotation available: " + implicitAnnotation.reason | ||
return LineMarkerInfo( | ||
element, | ||
element.textRange, | ||
AllIcons.Gutter.ExtAnnotation, | ||
{ message }, | ||
this::navigate, | ||
GutterIconRenderer.Alignment.RIGHT | ||
) | ||
} | ||
|
||
private fun navigate(event: MouseEvent, element: PsiElement) { | ||
val listOwner = element.parent | ||
val containingFile = listOwner.containingFile | ||
val virtualFile = PsiUtilCore.getVirtualFile(listOwner) | ||
|
||
if (virtualFile != null && containingFile != null) { | ||
val project = listOwner.project | ||
val editor = FileEditorManager.getInstance(project).selectedTextEditor | ||
if (editor != null) { | ||
editor.caretModel.moveToOffset(element.textOffset) | ||
val file = PsiDocumentManager.getInstance(project).getPsiFile(editor.document) | ||
if (file != null && virtualFile == file.virtualFile) { | ||
val popup = createActionGroupPopup(containingFile, project, editor) | ||
popup?.show(RelativePoint(event)) | ||
} | ||
} | ||
} | ||
} | ||
|
||
private fun createActionGroupPopup(file: PsiFile, project: Project, editor: Editor): JBPopup? { | ||
val intention = MakeInferredMcdevAnnotationExplicit() | ||
val action = ApplyIntentionAction(intention, intention.text, editor, file) | ||
val group = DefaultActionGroup(action) | ||
val context = SimpleDataContext.getProjectContext(null) | ||
return JBPopupFactory.getInstance() | ||
.createActionGroupPopup(null, group, context, JBPopupFactory.ActionSelectionAid.SPEEDSEARCH, true) | ||
} | ||
} |
Oops, something went wrong.