Use background task for Kotlin decompiler (KT-23981)
#KT-23981 Fixed
This commit is contained in:
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.idea.actions.canBeDecompiledToJava
|
||||
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import java.io.File
|
||||
import java.util.jar.Manifest
|
||||
@@ -36,11 +37,14 @@ import java.util.jar.Manifest
|
||||
class KotlinDecompilerServiceImpl : KotlinDecompilerService {
|
||||
override fun decompile(file: KtFile): String? {
|
||||
try {
|
||||
val bytecodeMap = when {
|
||||
file.canBeDecompiledToJava() -> bytecodeMapForExistingClassfile(file.virtualFile)
|
||||
!file.isCompiled -> bytecodeMapForSourceFile(file)
|
||||
else -> return null
|
||||
}
|
||||
val bytecodeMap: Map<File, () -> ByteArray> = runReadAction {
|
||||
when {
|
||||
file.canBeDecompiledToJava() -> bytecodeMapForExistingClassfile(file.virtualFile)
|
||||
!file.isCompiled -> bytecodeMapForSourceFile(file)
|
||||
else -> null
|
||||
}
|
||||
} ?: return null
|
||||
|
||||
val resultSaver = KotlinResultSaver()
|
||||
val options = hashMapOf<String, Any>(
|
||||
IFernflowerPreferences.REMOVE_BRIDGE to "0"
|
||||
|
||||
@@ -5,7 +5,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.internal
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.fileEditor.OpenFileDescriptor
|
||||
import com.intellij.openapi.progress.ProgressIndicator
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.progress.Task
|
||||
import com.intellij.openapi.ui.Messages
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.vfs.VfsUtil
|
||||
@@ -16,25 +20,38 @@ import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
fun showDecompiledCode(sourceFile: KtFile) {
|
||||
val decompilerService = KotlinDecompilerService.getInstance() ?: return
|
||||
val decompiledCode = try {
|
||||
decompilerService.decompile(sourceFile)
|
||||
} catch (e: DecompileFailedException) {
|
||||
null
|
||||
}
|
||||
ProgressManager.getInstance().run(KotlinBytecodeDecompilerTask(sourceFile))
|
||||
}
|
||||
|
||||
if (decompiledCode == null) {
|
||||
Messages.showErrorDialog("Cannot decompile ${sourceFile.name}", "Decompiler error")
|
||||
return
|
||||
}
|
||||
class KotlinBytecodeDecompilerTask(val file: KtFile) : Task.Backgroundable(file.project, "Decompile kotlin bytecode") {
|
||||
override fun run(indicator: ProgressIndicator) {
|
||||
val decompilerService = KotlinDecompilerService.getInstance() ?: return
|
||||
|
||||
runWriteAction {
|
||||
val root = getOrCreateDummyRoot()
|
||||
val decompiledFileName = FileUtil.getNameWithoutExtension(sourceFile.name) + ".decompiled.java"
|
||||
val result = DummyFileSystem.getInstance().createChildFile(null, root, decompiledFileName)
|
||||
VfsUtil.saveText(result, decompiledCode)
|
||||
indicator.text = "Decompiling ${file.name}"
|
||||
|
||||
OpenFileDescriptor(sourceFile.project, result).navigate(true)
|
||||
val decompiledText = try {
|
||||
decompilerService.decompile(file)
|
||||
} catch (e: DecompileFailedException) {
|
||||
null
|
||||
}
|
||||
|
||||
ApplicationManager.getApplication().invokeLater {
|
||||
runWriteAction {
|
||||
if (!file.isValid || file.project.isDisposed) return@runWriteAction
|
||||
|
||||
if (decompiledText == null) {
|
||||
Messages.showErrorDialog("Cannot decompile ${file.name}", "Decompiler error")
|
||||
return@runWriteAction
|
||||
}
|
||||
|
||||
val root = getOrCreateDummyRoot()
|
||||
val decompiledFileName = FileUtil.getNameWithoutExtension(file.name) + ".decompiled.java"
|
||||
val result = DummyFileSystem.getInstance().createChildFile(null, root, decompiledFileName)
|
||||
VfsUtil.saveText(result, decompiledText)
|
||||
|
||||
OpenFileDescriptor(file.project, result).navigate(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user