-
Notifications
You must be signed in to change notification settings - Fork 401
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merged branch idea243.release into idea243.x
- Loading branch information
Showing
40 changed files
with
977 additions
and
204 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
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
1 change: 1 addition & 0 deletions
1
...nversion/testdata/sbt_projects_for_paste/autoCreatePluginSbtFile/project/build.properties
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 @@ | ||
sbt.version=1.10.3 |
8 changes: 8 additions & 0 deletions
8
...ata/sbt_projects_for_paste/autoCreatePluginSbtFileWithAlreadyExistingPluginsSbt/build.sbt
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,8 @@ | ||
ThisBuild / version := "0.1.0-SNAPSHOT" | ||
|
||
ThisBuild / scalaVersion := "3.3.4" | ||
|
||
lazy val root = (project in file(".")) | ||
.settings( | ||
name := "root" | ||
) |
1 change: 1 addition & 0 deletions
1
...s_for_paste/autoCreatePluginSbtFileWithAlreadyExistingPluginsSbt/project/build.properties
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 @@ | ||
sbt.version=1.10.3 |
Empty file.
Empty file.
Empty file.
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
61 changes: 61 additions & 0 deletions
61
...ecompiler/src/org/jetbrains/plugins/scala/decompileToJava/ShowDecompiledTastyAction.scala
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,61 @@ | ||
package org.jetbrains.plugins.scala.decompileToJava | ||
|
||
import com.intellij.ide.util.PsiNavigationSupport | ||
import com.intellij.openapi.actionSystem.{ActionUpdateThread, AnAction, AnActionEvent, CommonDataKeys} | ||
import com.intellij.openapi.fileTypes.FileTypeRegistry | ||
import com.intellij.openapi.vfs.VirtualFile | ||
import com.intellij.psi.util.{PsiTreeUtil, PsiUtilBase} | ||
import com.intellij.psi.{PsiClass, PsiClassOwner, PsiElement} | ||
import org.jetbrains.plugins.scala.tasty.TastyFileType | ||
|
||
/** | ||
* The action shows the decompiled version of .tasty files in a format of readable Scala code | ||
* | ||
* This class was copied from [[org.jetbrains.java.decompiler.ShowDecompiledClassAction]] | ||
* with the exception that it handles .tasty files instead of .class files | ||
* | ||
* @see [[ShowDecompiledClassAsJavaAction]] | ||
* @see [[org.jetbrains.java.decompiler.ShowDecompiledClassAction]] | ||
*/ | ||
class ShowDecompiledTastyAction extends AnAction(ScalaJavaDecompilerBundle.message("show.decompiled.tasty")) { | ||
|
||
override def getActionUpdateThread: ActionUpdateThread = ActionUpdateThread.BGT | ||
|
||
override def update(e: AnActionEvent): Unit = { | ||
val psiElement = getPsiElement(e) | ||
val visible = psiElement.exists(_.getContainingFile.isInstanceOf[PsiClassOwner]) | ||
val enabled = visible && getOriginalFile(psiElement.orNull) != null | ||
e.getPresentation.setVisible(visible) | ||
e.getPresentation.setEnabled(enabled) | ||
} | ||
|
||
override def actionPerformed(e: AnActionEvent): Unit = { | ||
val project = e.getProject | ||
if (project == null) return | ||
|
||
val file = getOriginalFile(getPsiElement(e).orNull) | ||
if (file == null) return | ||
|
||
PsiNavigationSupport.getInstance().createNavigatable(project, file, -1).navigate(true) | ||
} | ||
|
||
private def getPsiElement(e: AnActionEvent): Option[PsiElement] = { | ||
val project = e.getProject | ||
if (project == null) return None | ||
|
||
val editor = e.getData(CommonDataKeys.EDITOR) | ||
if (editor != null) { | ||
val file = Option(PsiUtilBase.getPsiFileInEditor(editor, project)) | ||
file.flatMap(file => Option(file.findElementAt(editor.getCaretModel.getOffset))) | ||
} | ||
else { | ||
Option(e.getData(CommonDataKeys.PSI_ELEMENT)) | ||
} | ||
} | ||
|
||
private def getOriginalFile(psiElement: PsiElement): VirtualFile = { | ||
val psiClass = PsiTreeUtil.getParentOfType(psiElement, classOf[PsiClass], false) | ||
val file = Option(psiClass).flatMap(cls => Option(cls.getOriginalElement.getContainingFile.getVirtualFile)) | ||
file.filter(FileTypeRegistry.getInstance.isFileOfType(_, TastyFileType)).orNull | ||
} | ||
} |
122 changes: 122 additions & 0 deletions
122
...iler/test/org/jetbrains/plugins/scala/decompileToJava/ShowDecompiledTastyActionTest.scala
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,122 @@ | ||
package org.jetbrains.plugins.scala.decompileToJava | ||
|
||
import com.intellij.ide.util.PsiNavigationSupport | ||
import com.intellij.openapi.actionSystem.impl.SimpleDataContext | ||
import com.intellij.openapi.actionSystem.{ActionUiKind, AnAction, AnActionEvent, CommonDataKeys, DataContext, Presentation} | ||
import com.intellij.openapi.fileEditor.FileEditorManager | ||
import com.intellij.openapi.project.Project | ||
import com.intellij.psi.search.{FileTypeIndex, GlobalSearchScope} | ||
import com.intellij.psi.{PsiFile, PsiManager} | ||
import junit.framework.TestCase.assertEquals | ||
import org.jetbrains.plugins.scala.base.ScalaLightCodeInsightFixtureTestCase | ||
import org.jetbrains.plugins.scala.extensions.invokeAndWait | ||
import org.jetbrains.plugins.scala.lang.psi.api.ScalaFile | ||
import org.jetbrains.plugins.scala.{ScalaFileType, ScalaVersion} | ||
import org.junit.Assert.{assertFalse, assertNotNull, assertTrue} | ||
|
||
import scala.jdk.CollectionConverters.CollectionHasAsScala | ||
|
||
class ShowDecompiledTastyActionTest extends ScalaLightCodeInsightFixtureTestCase { | ||
|
||
override protected def supportedIn(version: ScalaVersion): Boolean = version.isScala3 | ||
|
||
private val ActionId = "Scala.DecompileTasty" | ||
|
||
private def getAction: AnAction = { | ||
val actionManager = com.intellij.openapi.actionSystem.ActionManager.getInstance() | ||
val registeredAction = actionManager.getAction(ActionId) | ||
assertNotNull(s"Action '$ActionId' should be registered in the ActionManager", registeredAction) | ||
registeredAction | ||
} | ||
|
||
def testActionAvailableForScala3LibraryFile(): Unit = { | ||
val action = getAction | ||
val actionPresentation = openFileEditorAndUpdateAction(getProject, action, "CanEqual.scala") | ||
assertTrue( | ||
s"Action '$ActionId' should be available in the given context", | ||
actionPresentation.isEnabledAndVisible | ||
) | ||
|
||
val event = createActionEvent(getProject, action) | ||
action.actionPerformed(event) | ||
|
||
val editor = FileEditorManager.getInstance(getProject).getSelectedTextEditor | ||
assertEquals("Opened file name", "CanEqual.tasty", editor.getVirtualFile.getName) | ||
} | ||
|
||
def testActionNotAvailableForOtherFiles(): Unit = { | ||
val actionPresentation = openFileEditorAndUpdateAction(getProject, getAction, "Option.scala") | ||
assertFalse( | ||
s"Action '$ActionId' should not be enabled in the given context", | ||
actionPresentation.isEnabled | ||
) | ||
assertTrue( | ||
s"Action '$ActionId' should be visible in the given context", | ||
actionPresentation.isVisible | ||
) | ||
} | ||
|
||
private def openFileEditorAndUpdateAction(project: Project, action: AnAction, scala2SourceFile: String): Presentation = { | ||
findFileAndOpenEditor(project, scala2SourceFile) | ||
updateActionWithCurrentlySelectedClass(project, action) | ||
} | ||
|
||
private def updateActionWithCurrentlySelectedClass(project: Project, action: AnAction): Presentation = { | ||
val event = createActionEvent(project, action) | ||
action.update(event) | ||
event.getPresentation | ||
} | ||
|
||
private def createActionEvent(project: Project, action: AnAction) = { | ||
val editor = FileEditorManager.getInstance(project).getSelectedTextEditor | ||
assertNotNull("There should be a selected editor", editor) | ||
|
||
val psiFile = PsiManager.getInstance(project).findFile(editor.getVirtualFile) | ||
.ensuring(_ != null, "PsiFile could not be retrieved from the editor's virtual file") | ||
.asInstanceOf[ScalaFile] | ||
|
||
val firstDefinitionInFile = psiFile.members.head | ||
|
||
val dataContext: DataContext = SimpleDataContext.builder() | ||
.add(CommonDataKeys.PSI_ELEMENT, firstDefinitionInFile) | ||
.add(CommonDataKeys.PROJECT, project) | ||
.build() | ||
|
||
val event = AnActionEvent.createEvent(action, dataContext, null, "dummy place", ActionUiKind.TOOLBAR, null) | ||
event | ||
} | ||
|
||
private def findFileAndOpenEditor(project: Project, Scala3LibrarySourceFile: String): Unit = { | ||
val scala3PsiFile = findFile(project, Scala3LibrarySourceFile) | ||
openFileInEditor(project, scala3PsiFile) | ||
assertSelectedEditorFileName(project, Scala3LibrarySourceFile) | ||
} | ||
|
||
private def assertSelectedEditorFileName(project: Project, ScalaLibrarySourceFile: String): Unit = { | ||
val editor = FileEditorManager.getInstance(project).getSelectedTextEditor | ||
assertNotNull("There should be an open editor", editor) | ||
assertEquals(ScalaLibrarySourceFile, editor.getVirtualFile.getName) | ||
} | ||
|
||
private def openFileInEditor(project: Project, psiFile: PsiFile): Unit = { | ||
// Open CanEqual.scala file | ||
invokeAndWait { | ||
PsiNavigationSupport.getInstance | ||
.createNavigatable(project, psiFile.getVirtualFile, psiFile.getTextOffset) | ||
.navigate(true) | ||
} | ||
} | ||
|
||
private def closeAllOpenEditors(project: Project): Unit = { | ||
FileEditorManager.getInstance(project).getSelectedEditors.foreach { fileEditor => | ||
FileEditorManager.getInstance(project).closeFile(fileEditor.getFile) | ||
} | ||
} | ||
|
||
private def findFile(project: Project, ScalaLibrarySourceFile: String) = { | ||
FileTypeIndex.getFiles(ScalaFileType.INSTANCE, GlobalSearchScope.everythingScope(project)).asScala | ||
.find(_.getName == ScalaLibrarySourceFile) | ||
.map(vf => PsiManager.getInstance(project).findFile(vf)) | ||
.getOrElse(throw new RuntimeException(s"File '$ScalaLibrarySourceFile' not found in the library scope")) | ||
} | ||
} |
Oops, something went wrong.