mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-16 14:23:28 +07:00
IDEA-338011 cleanup
GitOrigin-RevId: d2c47516160c4496a66f17b50a40e3532ab3a0fa
This commit is contained in:
committed by
intellij-monorepo-bot
parent
c0150a09ca
commit
378e147165
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.java.decompiler
|
||||
|
||||
import com.intellij.application.options.CodeStyle
|
||||
@@ -39,81 +39,55 @@ import java.util.concurrent.Callable
|
||||
import java.util.concurrent.Future
|
||||
import java.util.jar.Manifest
|
||||
|
||||
const val IDEA_DECOMPILER_BANNER: String = "//\n// Source code recreated from a .class file by IntelliJ IDEA\n// (powered by FernFlower decompiler)\n//\n\n"
|
||||
|
||||
class IdeaDecompiler : ClassFileDecompilers.Light() {
|
||||
companion object {
|
||||
const val BANNER: String = "//\n// Source code recreated from a .class file by IntelliJ IDEA\n// (powered by FernFlower decompiler)\n//\n\n"
|
||||
|
||||
private const val LEGAL_NOTICE_KEY = "decompiler.legal.notice.accepted"
|
||||
|
||||
private const val POSTPONE_EXIT_CODE = DialogWrapper.CANCEL_EXIT_CODE
|
||||
private const val DECLINE_EXIT_CODE = DialogWrapper.NEXT_USER_EXIT_CODE
|
||||
|
||||
private val TASK_KEY: Key<Future<CharSequence>> = Key.create("java.decompiler.optimistic.task")
|
||||
|
||||
private fun getOptions(): Map<String, Any> {
|
||||
val options = CodeStyle.getDefaultSettings().getIndentOptions(JavaFileType.INSTANCE)
|
||||
val indent = StringUtil.repeat(" ", options.INDENT_SIZE)
|
||||
return mapOf(
|
||||
IFernflowerPreferences.HIDE_DEFAULT_CONSTRUCTOR to "0",
|
||||
IFernflowerPreferences.DECOMPILE_GENERIC_SIGNATURES to "1",
|
||||
IFernflowerPreferences.REMOVE_SYNTHETIC to "1",
|
||||
IFernflowerPreferences.REMOVE_BRIDGE to "1",
|
||||
IFernflowerPreferences.NEW_LINE_SEPARATOR to "1",
|
||||
IFernflowerPreferences.BANNER to BANNER,
|
||||
IFernflowerPreferences.MAX_PROCESSING_METHOD to 60,
|
||||
IFernflowerPreferences.INDENT_STRING to indent,
|
||||
IFernflowerPreferences.IGNORE_INVALID_BYTECODE to "1",
|
||||
IFernflowerPreferences.VERIFY_ANONYMOUS_CLASSES to "1",
|
||||
//IFernflowerPreferences.UNIT_TEST_MODE to if (ApplicationManager.getApplication().isUnitTestMode) "1" else "0"
|
||||
)
|
||||
}
|
||||
|
||||
private fun canWork(): Boolean =
|
||||
ApplicationManager.getApplication().isUnitTestMode || PropertiesComponent.getInstance().isValueSet(LEGAL_NOTICE_KEY)
|
||||
}
|
||||
|
||||
class LegalBurden : FileEditorManagerListener.Before {
|
||||
private var myShowNotice = !canWork()
|
||||
private var showNotice = !canWork()
|
||||
|
||||
override fun beforeFileOpened(source: FileEditorManager, file: VirtualFile) {
|
||||
if (myShowNotice && file.fileType === JavaClassFileType.INSTANCE) {
|
||||
val decompiler = ClassFileDecompilers.getInstance().find(file, ClassFileDecompilers.Light::class.java)
|
||||
if (decompiler is IdeaDecompiler) {
|
||||
TASK_KEY.set(file, ApplicationManager.getApplication().executeOnPooledThread(Callable { decompiler.decompile(file) }))
|
||||
if (!showNotice || file.fileType !== JavaClassFileType.INSTANCE) {
|
||||
return
|
||||
}
|
||||
|
||||
val title = IdeaDecompilerBundle.message("legal.notice.title", StringUtil.last(file.path, 40, true))
|
||||
val message = IdeaDecompilerBundle.message("legal.notice.text")
|
||||
val result = LegalNoticeDialog.build(title, message)
|
||||
.withCancelText(IdeaDecompilerBundle.message("legal.notice.action.postpone"))
|
||||
.withCustomAction(IdeaDecompilerBundle.message("legal.notice.action.reject"), DECLINE_EXIT_CODE)
|
||||
.show()
|
||||
when (result) {
|
||||
DialogWrapper.OK_EXIT_CODE -> {
|
||||
myShowNotice = false
|
||||
PropertiesComponent.getInstance().setValue(LEGAL_NOTICE_KEY, true)
|
||||
ApplicationManager.getApplication().invokeLater { FileContentUtilCore.reparseFiles(file) }
|
||||
}
|
||||
val decompiler = ClassFileDecompilers.getInstance().find(file, ClassFileDecompilers.Light::class.java)
|
||||
if (decompiler !is IdeaDecompiler) {
|
||||
return
|
||||
}
|
||||
|
||||
DECLINE_EXIT_CODE -> {
|
||||
myShowNotice = false
|
||||
TASK_KEY.set(file, null)
|
||||
TASK_KEY.set(file, ApplicationManager.getApplication().executeOnPooledThread(Callable { decompiler.decompile(file) }))
|
||||
|
||||
val id = PluginId.getId("org.jetbrains.java.decompiler")
|
||||
PluginManagerCore.disablePlugin(id)
|
||||
val title = IdeaDecompilerBundle.message("legal.notice.title", StringUtil.last(file.path, 40, true))
|
||||
val message = IdeaDecompilerBundle.message("legal.notice.text")
|
||||
val result = LegalNoticeDialog.build(title, message)
|
||||
.withCancelText(IdeaDecompilerBundle.message("legal.notice.action.postpone"))
|
||||
.withCustomAction(IdeaDecompilerBundle.message("legal.notice.action.reject"), DECLINE_EXIT_CODE)
|
||||
.show()
|
||||
when (result) {
|
||||
DialogWrapper.OK_EXIT_CODE -> {
|
||||
showNotice = false
|
||||
PropertiesComponent.getInstance().setValue(LEGAL_NOTICE_KEY, true)
|
||||
ApplicationManager.getApplication().invokeLater { FileContentUtilCore.reparseFiles(file) }
|
||||
}
|
||||
|
||||
val plugin = PluginManagerCore.getPlugin(id)
|
||||
if (plugin is IdeaPluginDescriptorImpl && DynamicPlugins.allowLoadUnloadWithoutRestart(plugin)) {
|
||||
ApplicationManager.getApplication().invokeLater {
|
||||
DynamicPlugins.unloadPlugin(plugin, DynamicPlugins.UnloadPluginOptions(save = false))
|
||||
}
|
||||
}
|
||||
}
|
||||
DECLINE_EXIT_CODE -> {
|
||||
showNotice = false
|
||||
TASK_KEY.set(file, null)
|
||||
|
||||
POSTPONE_EXIT_CODE -> {
|
||||
TASK_KEY.set(file, null)
|
||||
val id = PluginId.getId("org.jetbrains.java.decompiler")
|
||||
PluginManagerCore.disablePlugin(id)
|
||||
|
||||
val plugin = PluginManagerCore.getPlugin(id)
|
||||
if (plugin is IdeaPluginDescriptorImpl && DynamicPlugins.allowLoadUnloadWithoutRestart(plugin)) {
|
||||
ApplicationManager.getApplication().invokeLater {
|
||||
DynamicPlugins.unloadPlugin(plugin, DynamicPlugins.UnloadPluginOptions(save = false))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
POSTPONE_EXIT_CODE -> {
|
||||
TASK_KEY.set(file, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -174,12 +148,12 @@ class IdeaDecompiler : ClassFileDecompilers.Light() {
|
||||
throw e
|
||||
}
|
||||
|
||||
val mapping = saver.myMapping
|
||||
val mapping = saver.mapping
|
||||
if (mapping != null) {
|
||||
file.putUserData(LineNumbersMapping.LINE_NUMBERS_MAPPING_KEY, LineNumbersMapping.ArrayBasedMapping(mapping))
|
||||
}
|
||||
|
||||
return saver.myResult
|
||||
return saver.result
|
||||
}
|
||||
catch (e: ProcessCanceledException) {
|
||||
throw e
|
||||
@@ -204,13 +178,13 @@ class IdeaDecompiler : ClassFileDecompilers.Light() {
|
||||
}
|
||||
|
||||
private class MyResultSaver : IResultSaver {
|
||||
var myResult = ""
|
||||
var myMapping: IntArray? = null
|
||||
var result = ""
|
||||
var mapping: IntArray? = null
|
||||
|
||||
override fun saveClassFile(path: String, qualifiedName: String, entryName: String, content: String, mapping: IntArray?) {
|
||||
if (myResult.isEmpty()) {
|
||||
myResult = content
|
||||
myMapping = mapping
|
||||
if (result.isEmpty()) {
|
||||
result = content
|
||||
this.mapping = mapping
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,3 +209,32 @@ class IdeaDecompiler : ClassFileDecompilers.Light() {
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
private const val LEGAL_NOTICE_KEY = "decompiler.legal.notice.accepted"
|
||||
|
||||
private const val POSTPONE_EXIT_CODE = DialogWrapper.CANCEL_EXIT_CODE
|
||||
private const val DECLINE_EXIT_CODE = DialogWrapper.NEXT_USER_EXIT_CODE
|
||||
|
||||
private val TASK_KEY: Key<Future<CharSequence>> = Key.create("java.decompiler.optimistic.task")
|
||||
|
||||
private fun getOptions(): Map<String, Any> {
|
||||
val options = CodeStyle.getDefaultSettings().getIndentOptions(JavaFileType.INSTANCE)
|
||||
val indent = " ".repeat(options.INDENT_SIZE)
|
||||
return mapOf(
|
||||
IFernflowerPreferences.HIDE_DEFAULT_CONSTRUCTOR to "0",
|
||||
IFernflowerPreferences.DECOMPILE_GENERIC_SIGNATURES to "1",
|
||||
IFernflowerPreferences.REMOVE_SYNTHETIC to "1",
|
||||
IFernflowerPreferences.REMOVE_BRIDGE to "1",
|
||||
IFernflowerPreferences.NEW_LINE_SEPARATOR to "1",
|
||||
IFernflowerPreferences.BANNER to IDEA_DECOMPILER_BANNER,
|
||||
IFernflowerPreferences.MAX_PROCESSING_METHOD to 60,
|
||||
IFernflowerPreferences.INDENT_STRING to indent,
|
||||
IFernflowerPreferences.IGNORE_INVALID_BYTECODE to "1",
|
||||
IFernflowerPreferences.VERIFY_ANONYMOUS_CLASSES to "1",
|
||||
//IFernflowerPreferences.UNIT_TEST_MODE to if (ApplicationManager.getApplication().isUnitTestMode) "1" else "0"
|
||||
)
|
||||
}
|
||||
|
||||
private fun canWork(): Boolean {
|
||||
return ApplicationManager.getApplication().isUnitTestMode || PropertiesComponent.getInstance().isValueSet(LEGAL_NOTICE_KEY)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.java.decompiler
|
||||
|
||||
import com.intellij.JavaTestUtil
|
||||
@@ -55,7 +55,7 @@ class IdeaDecompilerTest : LightJavaCodeInsightFixtureTestCase() {
|
||||
fun testSimple() {
|
||||
val file = getTestFile("${IdeaTestUtil.getMockJdk18Path().path}/jre/lib/rt.jar!/java/lang/String.class")
|
||||
val decompiled = IdeaDecompiler().getText(file).toString()
|
||||
assertTrue(decompiled, decompiled.startsWith("${IdeaDecompiler.BANNER}package java.lang;\n"))
|
||||
assertTrue(decompiled, decompiled.startsWith("${IDEA_DECOMPILER_BANNER}package java.lang;\n"))
|
||||
assertTrue(decompiled, decompiled.contains("public final class String"))
|
||||
assertTrue(decompiled, decompiled.contains("@deprecated"))
|
||||
assertTrue(decompiled, decompiled.contains("private static class CaseInsensitiveComparator"))
|
||||
@@ -222,7 +222,7 @@ class IdeaDecompilerTest : LightJavaCodeInsightFixtureTestCase() {
|
||||
}
|
||||
|
||||
val decompiled = psiFile.mirror.text
|
||||
assertTrue(file.path, decompiled.startsWith(IdeaDecompiler.BANNER) || file.name.endsWith("-info.class"))
|
||||
assertTrue(file.path, decompiled.startsWith(IDEA_DECOMPILER_BANNER) || file.name.endsWith("-info.class"))
|
||||
|
||||
// check that no mapped line number is on an empty line
|
||||
val prefix = "// "
|
||||
|
||||
Reference in New Issue
Block a user