mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-02-04 23:39:07 +07:00
IDEA-337454 ExtensionPointImpl - prefer JDK immutable list instead of kotlinx immutable collections (better implemented)
GitOrigin-RevId: 5c83e0c7e87ee02e0c06a7a48f838f59f28ce5ca
This commit is contained in:
committed by
intellij-monorepo-bot
parent
836668198c
commit
a653f3cd1f
@@ -23,7 +23,7 @@ class ContainerDescriptor {
|
||||
@JvmField var extensionPoints: PersistentList<ExtensionPointDescriptor> = persistentListOf()
|
||||
|
||||
@Transient var distinctExtensionPointCount: Int = -1
|
||||
@Transient @JvmField var extensions: Map<String, PersistentList<ExtensionDescriptor>> = Java11Shim.INSTANCE.emptyMap()
|
||||
@Transient @JvmField var extensions: Map<String, PersistentList<ExtensionDescriptor>> = Java11Shim.INSTANCE.mapOf()
|
||||
|
||||
fun addService(serviceDescriptor: ServiceDescriptor) {
|
||||
if (_services == null) {
|
||||
|
||||
@@ -15,7 +15,10 @@ import com.intellij.openapi.progress.ProcessCanceledException
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.util.Java11Shim
|
||||
import com.intellij.util.ThreeState
|
||||
import kotlinx.collections.immutable.*
|
||||
import kotlinx.collections.immutable.PersistentList
|
||||
import kotlinx.collections.immutable.mutate
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import org.jetbrains.annotations.NonNls
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
@@ -193,8 +196,10 @@ sealed class ExtensionPointImpl<T : Any>(@JvmField val name: String,
|
||||
}
|
||||
else {
|
||||
message += " (adapter=$adapter)"
|
||||
throw componentManager.createError(message, null, adapter.pluginDescriptor.pluginId,
|
||||
persistentHashMapOf("threadDump" to ThreadDumper.dumpThreadsToString()))
|
||||
throw componentManager.createError(/* message = */ message,
|
||||
/* error = */ null,
|
||||
/* pluginId = */ adapter.pluginDescriptor.pluginId,
|
||||
/* attachments = */ Java11Shim.INSTANCE.mapOf("threadDump", ThreadDumper.dumpThreadsToString()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -347,15 +352,15 @@ sealed class ExtensionPointImpl<T : Any>(@JvmField val name: String,
|
||||
listeners = listeners,
|
||||
result = null,
|
||||
duplicates = null,
|
||||
extensionClassForCheck = extensionClass, adapters = adapters) ?: return Java11Shim.INSTANCE.listOf()
|
||||
extensionClassForCheck = extensionClass,
|
||||
adapters = adapters) ?: return Java11Shim.INSTANCE.listOf()
|
||||
return Java11Shim.INSTANCE.listOf(extension)
|
||||
}
|
||||
|
||||
val duplicates = if (this is BeanExtensionPoint<*>) null else Collections.newSetFromMap<T>(IdentityHashMap(totalSize))
|
||||
val listeners = listeners
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val result = java.lang.reflect.Array.newInstance(extensionClass, totalSize) as Array<T>
|
||||
val result = arrayOfNulls<Any>(totalSize)
|
||||
var index = 0
|
||||
for (adapter in adapters) {
|
||||
val extension = processAdapter(adapter = adapter,
|
||||
@@ -368,22 +373,13 @@ sealed class ExtensionPointImpl<T : Any>(@JvmField val name: String,
|
||||
result[index++] = extension
|
||||
}
|
||||
}
|
||||
|
||||
// do not count ProcessCanceledException as a valid action to measure (later special category can be introduced if needed)
|
||||
if (result.size == index) {
|
||||
return Java11Shim.INSTANCE.listOf(result)
|
||||
}
|
||||
else {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val newResult = java.lang.reflect.Array.newInstance(extensionClass, index) as Array<T>
|
||||
System.arraycopy(result, 0, newResult, 0, index)
|
||||
return Java11Shim.INSTANCE.listOf(newResult)
|
||||
}
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return Java11Shim.INSTANCE.listOf(result, index) as List<T>
|
||||
}
|
||||
|
||||
private fun processAdapter(adapter: ExtensionComponentAdapter,
|
||||
listeners: List<ExtensionPointListener<T>>?,
|
||||
result: Array<T>?,
|
||||
result: Array<*>?,
|
||||
duplicates: MutableSet<T>?,
|
||||
extensionClassForCheck: Class<T>,
|
||||
adapters: List<ExtensionComponentAdapter>): T? {
|
||||
|
||||
@@ -25,10 +25,10 @@ internal class InterfaceExtensionPoint<T : Any>(
|
||||
|
||||
if (hasAttributes) {
|
||||
val customAttributes = if (descriptor.hasExtraAttributes) {
|
||||
descriptor.element?.attributes ?: Java11Shim.INSTANCE.emptyMap()
|
||||
descriptor.element?.attributes ?: Java11Shim.INSTANCE.mapOf()
|
||||
}
|
||||
else {
|
||||
Java11Shim.INSTANCE.emptyMap()
|
||||
Java11Shim.INSTANCE.mapOf()
|
||||
}
|
||||
return AdapterWithCustomAttributes(implementationClassName = implementationClassName,
|
||||
pluginDescriptor = pluginDescriptor,
|
||||
|
||||
@@ -44,7 +44,7 @@ public abstract class ContributorsBasedGotoByModel implements ChooseByNameModelE
|
||||
private final List<ChooseByNameContributor> myContributors;
|
||||
|
||||
protected ContributorsBasedGotoByModel(@NotNull Project project, ChooseByNameContributor @NotNull [] contributors) {
|
||||
this(project, Java11Shim.INSTANCE.listOf(contributors));
|
||||
this(project, List.of(contributors));
|
||||
}
|
||||
|
||||
protected ContributorsBasedGotoByModel(@NotNull Project project, @NotNull List<ChooseByNameContributor> contributors) {
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.platform.ide.bootstrap
|
||||
|
||||
import com.intellij.concurrency.ConcurrentCollectionFactory
|
||||
import com.intellij.util.Java11Shim
|
||||
import com.intellij.util.containers.ConcurrentLongObjectMap
|
||||
import org.jetbrains.annotations.VisibleForTesting
|
||||
|
||||
@VisibleForTesting
|
||||
@Suppress("ReplaceJavaStaticMethodWithKotlinAnalog")
|
||||
class Java11ShimImpl : Java11Shim() {
|
||||
override fun <K : Any, V> copyOf(map: Map<K, V>): Map<K, V> = java.util.Map.copyOf(map)
|
||||
|
||||
override fun <K : Any, V> mapOf(k: K, v: V): Map<K, V> = java.util.Map.of(k, v)
|
||||
|
||||
override fun <E> copyOf(collection: Collection<E>): Set<E> = java.util.Set.copyOf(collection)
|
||||
|
||||
override fun <K : Any, V> mapOf(): Map<K, V> = java.util.Map.of()
|
||||
|
||||
override fun <K : Any, V> mapOf(k: K, v: V, k2: K, v2: V): Map<K, V> = java.util.Map.of(k, v, k2, v2)
|
||||
|
||||
override fun <V : Any> createConcurrentLongObjectMap(): ConcurrentLongObjectMap<V> {
|
||||
return ConcurrentCollectionFactory.createConcurrentLongObjectMap()
|
||||
}
|
||||
|
||||
override fun <E> listOf(): List<E> = java.util.List.of()
|
||||
|
||||
override fun <E> listOf(element: E): List<E> = java.util.List.of(element)
|
||||
|
||||
override fun <E> listOf(e1: E, e2: E): List<E> = java.util.List.of(e1, e2)
|
||||
|
||||
override fun <E> listOf(array: Array<E>, size: Int): List<E> {
|
||||
return when (size) {
|
||||
1 -> java.util.List.of(array[0])
|
||||
2 -> java.util.List.of(array[0], array[1])
|
||||
3 -> java.util.List.of(array[0], array[1], array[2])
|
||||
4 -> java.util.List.of(array[0], array[1], array[2], array[3])
|
||||
5 -> java.util.List.of(array[0], array[1], array[2], array[3], array[4])
|
||||
6 -> java.util.List.of(array[0], array[1], array[2], array[3], array[4], array[5])
|
||||
7 -> java.util.List.of(array[0], array[1], array[2], array[3], array[4], array[5], array[6])
|
||||
8 -> java.util.List.of(array[0], array[1], array[2], array[3], array[4], array[5], array[6], array[7])
|
||||
9 -> java.util.List.of(array[0], array[1], array[2], array[3], array[4], array[5], array[6], array[7], array[8])
|
||||
10 -> java.util.List.of(array[0], array[1], array[2], array[3], array[4], array[5], array[6], array[7], array[8], array[9])
|
||||
11 -> java.util.List.of(array[0], array[1], array[2], array[3], array[4], array[5], array[6], array[7], array[8], array[9], array[10])
|
||||
12 -> java.util.List.of(array[0], array[1], array[2], array[3], array[4], array[5], array[6], array[7], array[8], array[9], array[10],
|
||||
array[11])
|
||||
else -> {
|
||||
if (array.size == size) {
|
||||
java.util.List.of(*array)
|
||||
}
|
||||
else {
|
||||
val newResult = arrayOfNulls<Any>(size)
|
||||
System.arraycopy(array, 0, newResult, 0, size)
|
||||
@Suppress("UNCHECKED_CAST", "KotlinConstantConditions")
|
||||
return java.util.List.of(*newResult) as List<E>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,6 @@ package com.intellij.platform.ide.bootstrap
|
||||
|
||||
import com.intellij.BundleBase
|
||||
import com.intellij.accessibility.enableScreenReaderSupportIfNecessary
|
||||
import com.intellij.concurrency.ConcurrentCollectionFactory
|
||||
import com.intellij.diagnostic.*
|
||||
import com.intellij.ide.*
|
||||
import com.intellij.ide.bootstrap.*
|
||||
@@ -35,7 +34,6 @@ import com.intellij.ui.mac.screenmenu.Menu
|
||||
import com.intellij.ui.scale.JBUIScale
|
||||
import com.intellij.ui.svg.SvgCacheManager
|
||||
import com.intellij.util.*
|
||||
import com.intellij.util.containers.ConcurrentLongObjectMap
|
||||
import com.intellij.util.containers.SLRUMap
|
||||
import com.intellij.util.io.*
|
||||
import com.intellij.util.lang.ZipFilePool
|
||||
@@ -44,7 +42,6 @@ import io.opentelemetry.sdk.OpenTelemetrySdkBuilder
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.debug.internal.DebugProbesImpl
|
||||
import org.jetbrains.annotations.ApiStatus.Internal
|
||||
import org.jetbrains.annotations.VisibleForTesting
|
||||
import java.awt.Toolkit
|
||||
import java.lang.invoke.MethodHandles
|
||||
import java.lang.invoke.MethodType
|
||||
@@ -725,24 +722,3 @@ interface AppStarter {
|
||||
fun importFinished(newConfigDir: Path) {}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@Suppress("ReplaceJavaStaticMethodWithKotlinAnalog")
|
||||
class Java11ShimImpl : Java11Shim() {
|
||||
override fun <K : Any, V> copyOf(map: Map<K, V>) = java.util.Map.copyOf(map)
|
||||
|
||||
override fun <K : Any, V> mapOf(k: K, v: V): Map<K, V> = java.util.Map.of(k, v)
|
||||
|
||||
override fun <E> copyOf(collection: Collection<E>): Set<E> = java.util.Set.copyOf(collection)
|
||||
|
||||
override fun <K : Any, V> emptyMap(): Map<K, V> = java.util.Map.of()
|
||||
|
||||
override fun <V : Any> createConcurrentLongObjectMap(): ConcurrentLongObjectMap<V> {
|
||||
return ConcurrentCollectionFactory.createConcurrentLongObjectMap()
|
||||
}
|
||||
|
||||
override fun <E> listOf(): List<E> = java.util.List.of()
|
||||
|
||||
override fun <E> listOf(element: E): List<E> = java.util.List.of(element)
|
||||
|
||||
override fun <E> listOf(array: Array<E>): List<E> = java.util.List.of(*array)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@file:Suppress("ReplacePutWithAssignment", "ReplaceJavaStaticMethodWithKotlinAnalog")
|
||||
|
||||
package com.intellij.util
|
||||
|
||||
import com.intellij.util.containers.ConcurrentLongObjectMap
|
||||
@@ -15,19 +17,28 @@ abstract class Java11Shim {
|
||||
|
||||
override fun <K : Any, V> mapOf(k: K, v: V): Map<K, V> = Collections.singletonMap(k, v)
|
||||
|
||||
override fun <K : Any, V> mapOf(k: K, v: V, k2: K, v2: V): Map<K, V> {
|
||||
val map = HashMap<K, V>(2)
|
||||
map.put(k, v)
|
||||
map.put(k2, v2)
|
||||
return map
|
||||
}
|
||||
|
||||
override fun <E> copyOf(collection: Collection<E>): Set<E> = Collections.unmodifiableSet(HashSet(collection))
|
||||
|
||||
override fun <V : Any> createConcurrentLongObjectMap(): ConcurrentLongObjectMap<V> {
|
||||
return ConcurrentLongObjectHashMap()
|
||||
}
|
||||
|
||||
override fun <K : Any, V> emptyMap(): Map<K, V> = Collections.emptyMap()
|
||||
override fun <K : Any, V> mapOf(): Map<K, V> = Collections.emptyMap()
|
||||
|
||||
override fun <E> listOf(): List<E> = Collections.emptyList()
|
||||
|
||||
override fun <E> listOf(element: E): List<E> = Collections.singletonList(element)
|
||||
|
||||
override fun <E> listOf(array: Array<E>) = array.asList()
|
||||
override fun <E> listOf(e1: E, e2: E): List<E> = Arrays.asList(e1, e2)
|
||||
|
||||
override fun <E> listOf(array: Array<E>, size: Int) = if (array.size == size) array.asList() else array.asList().subList(0, size)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +46,9 @@ abstract class Java11Shim {
|
||||
|
||||
abstract fun <K : Any, V> mapOf(k: K, v: V): Map<K, V>
|
||||
|
||||
abstract fun <K : Any, V> emptyMap(): Map<K, V>
|
||||
abstract fun <K : Any, V> mapOf(k: K, v: V, k2: K, v2: V): Map<K, V>
|
||||
|
||||
abstract fun <K : Any, V> mapOf(): Map<K, V>
|
||||
|
||||
abstract fun <E> copyOf(collection: Collection<E>): Set<E>
|
||||
|
||||
@@ -43,7 +56,9 @@ abstract class Java11Shim {
|
||||
|
||||
abstract fun <E> listOf(element: E): List<E>
|
||||
|
||||
abstract fun <E> listOf(array: Array<E>): List<E>
|
||||
abstract fun <E> listOf(e1: E, e2: E): List<E>
|
||||
|
||||
abstract fun <E> listOf(array: Array<E>, size: Int): List<E>
|
||||
|
||||
abstract fun <V : Any> createConcurrentLongObjectMap(): ConcurrentLongObjectMap<V>
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@file:Suppress("ReplacePutWithAssignment")
|
||||
|
||||
package com.intellij.util.containers
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.util.Java11Shim
|
||||
import com.intellij.util.SmartList
|
||||
import com.intellij.util.lang.CompoundRuntimeException
|
||||
import org.jetbrains.annotations.ApiStatus.Experimental
|
||||
@@ -18,6 +21,62 @@ fun <K, V> MutableMap<K, MutableList<V>>.remove(key: K, value: V) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not use it for a concurrent map (doesn't make sense).
|
||||
*/
|
||||
@Internal
|
||||
@Experimental
|
||||
fun <K : Any, V> Map<K, V>.without(key: K): Map<K, V> {
|
||||
if (!containsKey(key)) {
|
||||
return this
|
||||
}
|
||||
else if (size == 1) {
|
||||
return Java11Shim.INSTANCE.mapOf()
|
||||
}
|
||||
else {
|
||||
val result = HashMap<K, V>(size, 0.5f)
|
||||
result.putAll(this)
|
||||
result.remove(key)
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not use it for a concurrent map (doesn't make sense).
|
||||
*/
|
||||
@Internal
|
||||
@Experimental
|
||||
fun <K : Any, V> Map<K, V>.with(key: K, value: V): Map<K, V> {
|
||||
val size = size
|
||||
if (size == 0) {
|
||||
return Java11Shim.INSTANCE.mapOf(key, value)
|
||||
}
|
||||
|
||||
// do not use a java-immutable map, same as ours UnmodifiableHashMap and fastutil it uses open addressing hashing
|
||||
// - https://stackoverflow.com/a/16303438
|
||||
val result = HashMap<K, V>(size + 1, 0.5f)
|
||||
result.putAll(this)
|
||||
result.put(key, value)
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not use it for a concurrent map (doesn't make sense).
|
||||
*/
|
||||
@Internal
|
||||
@Experimental
|
||||
fun <K : Any, V> Map<K, V>.withAll(otherMap: Map<K, V>): Map<K, V> {
|
||||
val totalSize = size + otherMap.size
|
||||
if (totalSize == 0) {
|
||||
return Java11Shim.INSTANCE.mapOf()
|
||||
}
|
||||
|
||||
val result = HashMap<K, V>(totalSize, 0.5f)
|
||||
result.putAll(this)
|
||||
result.putAll(otherMap)
|
||||
return result
|
||||
}
|
||||
|
||||
fun <K, V> MutableMap<K, MutableList<V>>.putValue(key: K, value: V) {
|
||||
val list = get(key)
|
||||
if (list == null) {
|
||||
|
||||
Reference in New Issue
Block a user