Do not resolve services in static initializers in IDEKotlinBinaryClassCache, KT-33973
This commit is contained in:
+11
-2
@@ -18,6 +18,8 @@ package org.jetbrains.kotlin.idea.core.formatter;
|
|||||||
|
|
||||||
import com.intellij.application.options.CodeStyle;
|
import com.intellij.application.options.CodeStyle;
|
||||||
import com.intellij.openapi.application.ApplicationManager;
|
import com.intellij.openapi.application.ApplicationManager;
|
||||||
|
import com.intellij.openapi.components.Service;
|
||||||
|
import com.intellij.openapi.components.ServiceManager;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.openapi.util.InvalidDataException;
|
import com.intellij.openapi.util.InvalidDataException;
|
||||||
import com.intellij.openapi.util.WriteExternalException;
|
import com.intellij.openapi.util.WriteExternalException;
|
||||||
@@ -33,8 +35,6 @@ import org.jetbrains.kotlin.idea.util.ReflectionUtil;
|
|||||||
import static com.intellij.util.ReflectionUtil.copyFields;
|
import static com.intellij.util.ReflectionUtil.copyFields;
|
||||||
|
|
||||||
public class KotlinCodeStyleSettings extends CustomCodeStyleSettings {
|
public class KotlinCodeStyleSettings extends CustomCodeStyleSettings {
|
||||||
public static final KotlinCodeStyleSettings DEFAULT = new KotlinCodeStyleSettings(new CodeStyleSettings());
|
|
||||||
|
|
||||||
public final PackageEntryTable PACKAGES_TO_USE_STAR_IMPORTS = new PackageEntryTable();
|
public final PackageEntryTable PACKAGES_TO_USE_STAR_IMPORTS = new PackageEntryTable();
|
||||||
public boolean SPACE_AROUND_RANGE = false;
|
public boolean SPACE_AROUND_RANGE = false;
|
||||||
public boolean SPACE_BEFORE_TYPE_COLON = false;
|
public boolean SPACE_BEFORE_TYPE_COLON = false;
|
||||||
@@ -180,4 +180,13 @@ public class KotlinCodeStyleSettings extends CustomCodeStyleSettings {
|
|||||||
copyFrom(settingsAgainstPreviousDefaults);
|
copyFrom(settingsAgainstPreviousDefaults);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static KotlinCodeStyleSettings defaultSettings() {
|
||||||
|
return ServiceManager.getService(KotlinCodeStyleSettingsHolder.class).defaultSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Service
|
||||||
|
private static final class KotlinCodeStyleSettingsHolder {
|
||||||
|
private final KotlinCodeStyleSettings defaultSettings = new KotlinCodeStyleSettings(new CodeStyleSettings());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,4 +16,4 @@ fun ASTBlock.requireNode() = node ?: error("ASTBlock.getNode() returned null")
|
|||||||
/**
|
/**
|
||||||
* Can be removed with all usages after moving master to 1.3 with new default code style settings.
|
* Can be removed with all usages after moving master to 1.3 with new default code style settings.
|
||||||
*/
|
*/
|
||||||
val isDefaultOfficialCodeStyle by lazy { !KotlinCodeStyleSettings.DEFAULT.CONTINUATION_INDENT_FOR_CHAINED_CALLS }
|
val isDefaultOfficialCodeStyle by lazy { !KotlinCodeStyleSettings.defaultSettings().CONTINUATION_INDENT_FOR_CHAINED_CALLS }
|
||||||
+8
-1
@@ -17,7 +17,9 @@
|
|||||||
package org.jetbrains.kotlin.idea.caches
|
package org.jetbrains.kotlin.idea.caches
|
||||||
|
|
||||||
import com.intellij.ide.highlighter.JavaClassFileType
|
import com.intellij.ide.highlighter.JavaClassFileType
|
||||||
|
import com.intellij.openapi.components.Service
|
||||||
import com.intellij.openapi.components.ServiceManager
|
import com.intellij.openapi.components.ServiceManager
|
||||||
|
import com.intellij.openapi.components.service
|
||||||
import com.intellij.openapi.util.Key
|
import com.intellij.openapi.util.Key
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.openapi.vfs.VirtualFileWithId
|
import com.intellij.openapi.vfs.VirtualFileWithId
|
||||||
@@ -28,7 +30,8 @@ import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
|||||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion
|
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
|
||||||
object IDEKotlinBinaryClassCache {
|
@Service
|
||||||
|
class IDEKotlinBinaryClassCache {
|
||||||
class KotlinBinaryClassHeaderData(
|
class KotlinBinaryClassHeaderData(
|
||||||
val classId: ClassId,
|
val classId: ClassId,
|
||||||
val kind: KotlinClassHeader.Kind,
|
val kind: KotlinClassHeader.Kind,
|
||||||
@@ -132,4 +135,8 @@ object IDEKotlinBinaryClassCache {
|
|||||||
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun getInstance(): IDEKotlinBinaryClassCache = service()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-4
@@ -41,9 +41,10 @@ val KEY = Key.create<IsKotlinBinary>(KOTLIN_COMPILED_FILE_ATTRIBUTE)
|
|||||||
* Checks if this file is a compiled Kotlin class file ABI-compatible with the current plugin
|
* Checks if this file is a compiled Kotlin class file ABI-compatible with the current plugin
|
||||||
*/
|
*/
|
||||||
fun isKotlinWithCompatibleAbiVersion(file: VirtualFile): Boolean {
|
fun isKotlinWithCompatibleAbiVersion(file: VirtualFile): Boolean {
|
||||||
if (!IDEKotlinBinaryClassCache.isKotlinJvmCompiledFile(file)) return false
|
val ideKotlinBinaryClassCache = IDEKotlinBinaryClassCache.getInstance()
|
||||||
|
if (!ideKotlinBinaryClassCache.isKotlinJvmCompiledFile(file)) return false
|
||||||
|
|
||||||
val kotlinClass = IDEKotlinBinaryClassCache.getKotlinBinaryClassHeaderData(file)
|
val kotlinClass = ideKotlinBinaryClassCache.getKotlinBinaryClassHeaderData(file)
|
||||||
return kotlinClass != null && kotlinClass.metadataVersion.isCompatible()
|
return kotlinClass != null && kotlinClass.metadataVersion.isCompatible()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,7 +58,9 @@ fun isKotlinInternalCompiledFile(file: VirtualFile, fileContent: ByteArray? = nu
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IDEKotlinBinaryClassCache.isKotlinJvmCompiledFile(file, fileContent)) {
|
val ideKotlinBinaryClassCache = IDEKotlinBinaryClassCache.getInstance()
|
||||||
|
|
||||||
|
if (!ideKotlinBinaryClassCache.isKotlinJvmCompiledFile(file, fileContent)) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,7 +83,7 @@ fun isKotlinInternalCompiledFile(file: VirtualFile, fileContent: ByteArray? = nu
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
val header = IDEKotlinBinaryClassCache.getKotlinBinaryClassHeaderData(file, fileContent) ?: return false
|
val header = ideKotlinBinaryClassCache.getKotlinBinaryClassHeaderData(file, fileContent) ?: return false
|
||||||
if (header.classId.isLocal) return true
|
if (header.classId.isLocal) return true
|
||||||
|
|
||||||
return header.kind == KotlinClassHeader.Kind.SYNTHETIC_CLASS ||
|
return header.kind == KotlinClassHeader.Kind.SYNTHETIC_CLASS ||
|
||||||
|
|||||||
+4
-3
@@ -43,8 +43,9 @@ import org.jetbrains.kotlin.serialization.deserialization.descriptors.Deserializ
|
|||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
|
|
||||||
fun DeserializerForClassfileDecompiler(classFile: VirtualFile): DeserializerForClassfileDecompiler {
|
fun DeserializerForClassfileDecompiler(classFile: VirtualFile): DeserializerForClassfileDecompiler {
|
||||||
val kotlinClassHeaderInfo = IDEKotlinBinaryClassCache.getKotlinBinaryClassHeaderData(classFile)
|
val kotlinClassHeaderInfo =
|
||||||
?: error("Decompiled data factory shouldn't be called on an unsupported file: " + classFile)
|
IDEKotlinBinaryClassCache.getInstance().getKotlinBinaryClassHeaderData(classFile)
|
||||||
|
?: error("Decompiled data factory shouldn't be called on an unsupported file: $classFile")
|
||||||
val packageFqName = kotlinClassHeaderInfo.classId.packageFqName
|
val packageFqName = kotlinClassHeaderInfo.classId.packageFqName
|
||||||
return DeserializerForClassfileDecompiler(classFile.parent!!, packageFqName)
|
return DeserializerForClassfileDecompiler(classFile.parent!!, packageFqName)
|
||||||
}
|
}
|
||||||
@@ -119,7 +120,7 @@ class DirectoryBasedClassFinder(
|
|||||||
val targetName = classId.relativeClassName.pathSegments().joinToString("$", postfix = ".class")
|
val targetName = classId.relativeClassName.pathSegments().joinToString("$", postfix = ".class")
|
||||||
val virtualFile = packageDirectory.findChild(targetName)
|
val virtualFile = packageDirectory.findChild(targetName)
|
||||||
if (virtualFile != null && isKotlinWithCompatibleAbiVersion(virtualFile)) {
|
if (virtualFile != null && isKotlinWithCompatibleAbiVersion(virtualFile)) {
|
||||||
return IDEKotlinBinaryClassCache.getKotlinBinaryClass(virtualFile)?.let(::KotlinClass)
|
return IDEKotlinBinaryClassCache.getInstance().getKotlinBinaryClass(virtualFile)?.let(::KotlinClass)
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-3
@@ -40,7 +40,7 @@ import org.jetbrains.kotlin.types.isFlexible
|
|||||||
class KotlinClassFileDecompiler : ClassFileDecompilers.Full() {
|
class KotlinClassFileDecompiler : ClassFileDecompilers.Full() {
|
||||||
private val stubBuilder = KotlinClsStubBuilder()
|
private val stubBuilder = KotlinClsStubBuilder()
|
||||||
|
|
||||||
override fun accepts(file: VirtualFile) = IDEKotlinBinaryClassCache.isKotlinJvmCompiledFile(file)
|
override fun accepts(file: VirtualFile) = IDEKotlinBinaryClassCache.getInstance().isKotlinJvmCompiledFile(file)
|
||||||
|
|
||||||
override fun getStubBuilder() = stubBuilder
|
override fun getStubBuilder() = stubBuilder
|
||||||
|
|
||||||
@@ -67,8 +67,9 @@ fun buildDecompiledTextForClassFile(
|
|||||||
classFile: VirtualFile,
|
classFile: VirtualFile,
|
||||||
resolver: ResolverForDecompiler = DeserializerForClassfileDecompiler(classFile)
|
resolver: ResolverForDecompiler = DeserializerForClassfileDecompiler(classFile)
|
||||||
): DecompiledText {
|
): DecompiledText {
|
||||||
val classHeader = IDEKotlinBinaryClassCache.getKotlinBinaryClassHeaderData(classFile)
|
val classHeader =
|
||||||
?: error("Decompiled data factory shouldn't be called on an unsupported file: " + classFile)
|
IDEKotlinBinaryClassCache.getInstance().getKotlinBinaryClassHeaderData(classFile)
|
||||||
|
?: error("Decompiled data factory shouldn't be called on an unsupported file: $classFile")
|
||||||
|
|
||||||
val classId = classHeader.classId
|
val classId = classHeader.classId
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -59,7 +59,8 @@ open class KotlinClsStubBuilder : ClsStubBuilder() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun doBuildFileStub(file: VirtualFile, fileContent: ByteArray): PsiFileStub<KtFile>? {
|
private fun doBuildFileStub(file: VirtualFile, fileContent: ByteArray): PsiFileStub<KtFile>? {
|
||||||
val kotlinClass = IDEKotlinBinaryClassCache.getKotlinBinaryClass(file, fileContent) ?: error("Can't find binary class for Kotlin file: $file")
|
val kotlinClass = IDEKotlinBinaryClassCache.getInstance().getKotlinBinaryClass(file, fileContent)
|
||||||
|
?: error("Can't find binary class for Kotlin file: $file")
|
||||||
val header = kotlinClass.classHeader
|
val header = kotlinClass.classHeader
|
||||||
val classId = kotlinClass.classId
|
val classId = kotlinClass.classId
|
||||||
val packageFqName = header.packageName?.let { FqName(it) } ?: classId.packageFqName
|
val packageFqName = header.packageName?.let { FqName(it) } ?: classId.packageFqName
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ object KotlinClassFileIndex : KotlinFileIndexBase<KotlinClassFileIndex>(KotlinCl
|
|||||||
private val VERSION = 3
|
private val VERSION = 3
|
||||||
|
|
||||||
private val INDEXER = indexer { fileContent ->
|
private val INDEXER = indexer { fileContent ->
|
||||||
val headerInfo = IDEKotlinBinaryClassCache.getKotlinBinaryClassHeaderData(fileContent.file, fileContent.content)
|
val headerInfo = IDEKotlinBinaryClassCache.getInstance().getKotlinBinaryClassHeaderData(fileContent.file, fileContent.content)
|
||||||
if (headerInfo != null && headerInfo.metadataVersion.isCompatible()) headerInfo.classId.asSingleFqName() else null
|
if (headerInfo != null && headerInfo.metadataVersion.isCompatible()) headerInfo.classId.asSingleFqName() else null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,9 +70,9 @@ class ImportSettingsPanel(private val commonSettings: CodeStyleSettings) : JPane
|
|||||||
private val starImportPackageTable = ImportLayoutPanel.createTableForPackageEntries(starImportPackageEntryTable, dummyImportLayoutPanel)
|
private val starImportPackageTable = ImportLayoutPanel.createTableForPackageEntries(starImportPackageEntryTable, dummyImportLayoutPanel)
|
||||||
|
|
||||||
private val nameCountToUseStarImportSelector = NameCountToUseStarImportSelector(
|
private val nameCountToUseStarImportSelector = NameCountToUseStarImportSelector(
|
||||||
"Top-level Symbols", KotlinCodeStyleSettings.DEFAULT.NAME_COUNT_TO_USE_STAR_IMPORT)
|
"Top-level Symbols", KotlinCodeStyleSettings.defaultSettings().NAME_COUNT_TO_USE_STAR_IMPORT)
|
||||||
private val nameCountToUseStarImportForMembersSelector = NameCountToUseStarImportSelector(
|
private val nameCountToUseStarImportForMembersSelector = NameCountToUseStarImportSelector(
|
||||||
"Java Statics and Enum Members", KotlinCodeStyleSettings.DEFAULT.NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS)
|
"Java Statics and Enum Members", KotlinCodeStyleSettings.defaultSettings().NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
layout = BorderLayout()
|
layout = BorderLayout()
|
||||||
|
|||||||
@@ -42,14 +42,18 @@ class KotlinFormatterUsageCollector {
|
|||||||
private val KOTLIN_DEFAULT_COMMON = KotlinLanguageCodeStyleSettingsProvider().defaultCommonSettings
|
private val KOTLIN_DEFAULT_COMMON = KotlinLanguageCodeStyleSettingsProvider().defaultCommonSettings
|
||||||
.also { KotlinStyleGuideCodeStyle.applyToCommonSettings(it) }
|
.also { KotlinStyleGuideCodeStyle.applyToCommonSettings(it) }
|
||||||
|
|
||||||
private val KOTLIN_DEFAULT_CUSTOM = KotlinCodeStyleSettings.DEFAULT.cloneSettings()
|
private val KOTLIN_DEFAULT_CUSTOM by lazy {
|
||||||
.also { KotlinStyleGuideCodeStyle.applyToKotlinCustomSettings(it) }
|
KotlinCodeStyleSettings.defaultSettings().cloneSettings()
|
||||||
|
.also { KotlinStyleGuideCodeStyle.applyToKotlinCustomSettings(it) }
|
||||||
|
}
|
||||||
|
|
||||||
private val KOTLIN_OBSOLETE_DEFAULT_COMMON = KotlinLanguageCodeStyleSettingsProvider().defaultCommonSettings
|
private val KOTLIN_OBSOLETE_DEFAULT_COMMON = KotlinLanguageCodeStyleSettingsProvider().defaultCommonSettings
|
||||||
.also { KotlinObsoleteCodeStyle.applyToCommonSettings(it) }
|
.also { KotlinObsoleteCodeStyle.applyToCommonSettings(it) }
|
||||||
|
|
||||||
private val KOTLIN_OBSOLETE_DEFAULT_CUSTOM = KotlinCodeStyleSettings.DEFAULT.cloneSettings()
|
private val KOTLIN_OBSOLETE_DEFAULT_CUSTOM by lazy {
|
||||||
.also { KotlinObsoleteCodeStyle.applyToKotlinCustomSettings(it) }
|
KotlinCodeStyleSettings.defaultSettings().cloneSettings()
|
||||||
|
.also { KotlinObsoleteCodeStyle.applyToKotlinCustomSettings(it) }
|
||||||
|
}
|
||||||
|
|
||||||
fun getKotlinFormatterKind(project: Project): KotlinFormatterKind {
|
fun getKotlinFormatterKind(project: Project): KotlinFormatterKind {
|
||||||
val isProject = CodeStyleSettingsManager.getInstance(project).USE_PER_PROJECT_SETTINGS
|
val isProject = CodeStyleSettingsManager.getInstance(project).USE_PER_PROJECT_SETTINGS
|
||||||
@@ -60,11 +64,11 @@ class KotlinFormatterUsageCollector {
|
|||||||
val kotlinCustomSettings = settings.kotlinCustomSettings
|
val kotlinCustomSettings = settings.kotlinCustomSettings
|
||||||
|
|
||||||
val isDefaultKotlinCommonSettings = kotlinCommonSettings == KotlinLanguageCodeStyleSettingsProvider().defaultCommonSettings
|
val isDefaultKotlinCommonSettings = kotlinCommonSettings == KotlinLanguageCodeStyleSettingsProvider().defaultCommonSettings
|
||||||
val isDefaultKotlinCustomSettings = kotlinCustomSettings == KotlinCodeStyleSettings.DEFAULT
|
val isDefaultKotlinCustomSettings = kotlinCustomSettings == KotlinCodeStyleSettings.defaultSettings()
|
||||||
|
|
||||||
if (isDefaultKotlinCommonSettings && isDefaultKotlinCustomSettings) {
|
if (isDefaultKotlinCommonSettings && isDefaultKotlinCustomSettings) {
|
||||||
return if (isDefaultOfficialCodeStyle) {
|
return if (isDefaultOfficialCodeStyle) {
|
||||||
paired(IDEA_OFFICIAL_DEFAULT, isProject)
|
paired(KotlinFormatterKind.IDEA_OFFICIAL_DEFAULT, isProject)
|
||||||
} else {
|
} else {
|
||||||
paired(IDEA_DEFAULT, isProject)
|
paired(IDEA_DEFAULT, isProject)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -16,7 +16,7 @@ import org.junit.Assert
|
|||||||
|
|
||||||
abstract class AbstractInternalCompiledClassesTest : KotlinLightCodeInsightFixtureTestCase() {
|
abstract class AbstractInternalCompiledClassesTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||||
private fun isFileWithHeader(predicate: (IDEKotlinBinaryClassCache.KotlinBinaryClassHeaderData, ClassId) -> Boolean) : VirtualFile.() -> Boolean = {
|
private fun isFileWithHeader(predicate: (IDEKotlinBinaryClassCache.KotlinBinaryClassHeaderData, ClassId) -> Boolean) : VirtualFile.() -> Boolean = {
|
||||||
val info = IDEKotlinBinaryClassCache.getKotlinBinaryClassHeaderData(this)
|
val info = IDEKotlinBinaryClassCache.getInstance().getKotlinBinaryClassHeaderData(this)
|
||||||
info != null && predicate(info, info.classId)
|
info != null && predicate(info, info.classId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -63,7 +63,7 @@ class BuiltInDecompilerConsistencyTest : KotlinLightCodeInsightFixtureTestCase()
|
|||||||
for (className in classFiles) {
|
for (className in classFiles) {
|
||||||
val classFile = dir.findChild(className + "." + JavaClassFileType.INSTANCE.defaultExtension)!!
|
val classFile = dir.findChild(className + "." + JavaClassFileType.INSTANCE.defaultExtension)!!
|
||||||
val fileContent = FileContentImpl.createByFile(classFile)
|
val fileContent = FileContentImpl.createByFile(classFile)
|
||||||
if (IDEKotlinBinaryClassCache.getKotlinBinaryClassHeaderData(fileContent.file) == null) continue
|
if (IDEKotlinBinaryClassCache.getInstance().getKotlinBinaryClassHeaderData(fileContent.file) == null) continue
|
||||||
val fileStub = classFileDecompiler.stubBuilder.buildFileStub(fileContent) ?: continue
|
val fileStub = classFileDecompiler.stubBuilder.buildFileStub(fileContent) ?: continue
|
||||||
val classStub = fileStub.findChildStubByType(KtClassElementType.getStubType(false)) ?: continue
|
val classStub = fileStub.findChildStubByType(KtClassElementType.getStubType(false)) ?: continue
|
||||||
val classFqName = classStub.getFqName()!!
|
val classFqName = classStub.getFqName()!!
|
||||||
|
|||||||
Reference in New Issue
Block a user