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.config.languageVersionSettings
|
||||||
import org.jetbrains.kotlin.idea.actions.canBeDecompiledToJava
|
import org.jetbrains.kotlin.idea.actions.canBeDecompiledToJava
|
||||||
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.jar.Manifest
|
import java.util.jar.Manifest
|
||||||
@@ -36,11 +37,14 @@ import java.util.jar.Manifest
|
|||||||
class KotlinDecompilerServiceImpl : KotlinDecompilerService {
|
class KotlinDecompilerServiceImpl : KotlinDecompilerService {
|
||||||
override fun decompile(file: KtFile): String? {
|
override fun decompile(file: KtFile): String? {
|
||||||
try {
|
try {
|
||||||
val bytecodeMap = when {
|
val bytecodeMap: Map<File, () -> ByteArray> = runReadAction {
|
||||||
file.canBeDecompiledToJava() -> bytecodeMapForExistingClassfile(file.virtualFile)
|
when {
|
||||||
!file.isCompiled -> bytecodeMapForSourceFile(file)
|
file.canBeDecompiledToJava() -> bytecodeMapForExistingClassfile(file.virtualFile)
|
||||||
else -> return null
|
!file.isCompiled -> bytecodeMapForSourceFile(file)
|
||||||
}
|
else -> null
|
||||||
|
}
|
||||||
|
} ?: return null
|
||||||
|
|
||||||
val resultSaver = KotlinResultSaver()
|
val resultSaver = KotlinResultSaver()
|
||||||
val options = hashMapOf<String, Any>(
|
val options = hashMapOf<String, Any>(
|
||||||
IFernflowerPreferences.REMOVE_BRIDGE to "0"
|
IFernflowerPreferences.REMOVE_BRIDGE to "0"
|
||||||
|
|||||||
@@ -5,7 +5,11 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.internal
|
package org.jetbrains.kotlin.idea.internal
|
||||||
|
|
||||||
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
import com.intellij.openapi.fileEditor.OpenFileDescriptor
|
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.ui.Messages
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
import com.intellij.openapi.vfs.VfsUtil
|
import com.intellij.openapi.vfs.VfsUtil
|
||||||
@@ -16,25 +20,38 @@ import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
|||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
|
||||||
fun showDecompiledCode(sourceFile: KtFile) {
|
fun showDecompiledCode(sourceFile: KtFile) {
|
||||||
val decompilerService = KotlinDecompilerService.getInstance() ?: return
|
ProgressManager.getInstance().run(KotlinBytecodeDecompilerTask(sourceFile))
|
||||||
val decompiledCode = try {
|
}
|
||||||
decompilerService.decompile(sourceFile)
|
|
||||||
} catch (e: DecompileFailedException) {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
if (decompiledCode == null) {
|
class KotlinBytecodeDecompilerTask(val file: KtFile) : Task.Backgroundable(file.project, "Decompile kotlin bytecode") {
|
||||||
Messages.showErrorDialog("Cannot decompile ${sourceFile.name}", "Decompiler error")
|
override fun run(indicator: ProgressIndicator) {
|
||||||
return
|
val decompilerService = KotlinDecompilerService.getInstance() ?: return
|
||||||
}
|
|
||||||
|
|
||||||
runWriteAction {
|
indicator.text = "Decompiling ${file.name}"
|
||||||
val root = getOrCreateDummyRoot()
|
|
||||||
val decompiledFileName = FileUtil.getNameWithoutExtension(sourceFile.name) + ".decompiled.java"
|
|
||||||
val result = DummyFileSystem.getInstance().createChildFile(null, root, decompiledFileName)
|
|
||||||
VfsUtil.saveText(result, decompiledCode)
|
|
||||||
|
|
||||||
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