[FIR] Implement util Multimap classes
This commit is contained in:
+1
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.resolve.calls.ImplicitDispatchReceiverValue
|
|||||||
import org.jetbrains.kotlin.fir.resolve.calls.ImplicitReceiverValue
|
import org.jetbrains.kotlin.fir.resolve.calls.ImplicitReceiverValue
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
|
import org.jetbrains.kotlin.fir.util.PersistentSetMultimap
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
class PersistentImplicitReceiverStack private constructor(
|
class PersistentImplicitReceiverStack private constructor(
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.fir.declarations.FirProperty
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirVariable
|
import org.jetbrains.kotlin.fir.declarations.FirVariable
|
||||||
import org.jetbrains.kotlin.fir.resolve.PersistentMultimap
|
import org.jetbrains.kotlin.fir.util.PersistentMultimap
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
|
import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.fir.util
|
||||||
|
|
||||||
|
class ChainedIterator<T>(delegates: Collection<Iterator<T>>) : Iterator<T> {
|
||||||
|
private var metaIterator = delegates.iterator()
|
||||||
|
private var currentIterator: Iterator<T>? = null
|
||||||
|
|
||||||
|
private fun promote() {
|
||||||
|
if (currentIterator?.hasNext() == true) return
|
||||||
|
while (metaIterator.hasNext()) {
|
||||||
|
currentIterator = metaIterator.next()
|
||||||
|
if (currentIterator!!.hasNext()) return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hasNext(): Boolean {
|
||||||
|
promote()
|
||||||
|
return currentIterator?.hasNext() == true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun next(): T {
|
||||||
|
promote()
|
||||||
|
return currentIterator?.next() ?: throw NoSuchElementException()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.fir.util
|
||||||
|
|
||||||
|
interface Multimap<K, out V, out C : Collection<V>> {
|
||||||
|
operator fun get(key: K): C
|
||||||
|
operator fun contains(key: K): Boolean
|
||||||
|
val keys: Set<K>
|
||||||
|
val values: Collection<V>
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MutableMultimap<K, V, C : Collection<V>> : Multimap<K, V, C> {
|
||||||
|
fun put(key: K, value: V)
|
||||||
|
fun putAll(key: K, values: Collection<V>) {
|
||||||
|
values.forEach { put(key, it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun remove(key: K, value: V)
|
||||||
|
fun removeKey(key: K)
|
||||||
|
|
||||||
|
fun clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class BaseMultimap<K, V, C : Collection<V>, MC : MutableCollection<V>> : MutableMultimap<K, V, C> {
|
||||||
|
private val map: MutableMap<K, MC> = mutableMapOf()
|
||||||
|
protected abstract fun createContainer(): MC
|
||||||
|
protected abstract fun createEmptyContainer(): C
|
||||||
|
|
||||||
|
override fun get(key: K): C {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return map[key] as C? ?: createEmptyContainer()
|
||||||
|
}
|
||||||
|
|
||||||
|
override operator fun contains(key: K): Boolean {
|
||||||
|
return key in map
|
||||||
|
}
|
||||||
|
|
||||||
|
override val keys: Set<K>
|
||||||
|
get() = map.keys
|
||||||
|
|
||||||
|
override val values: Collection<V>
|
||||||
|
get() = object : AbstractCollection<V>() {
|
||||||
|
override val size: Int
|
||||||
|
get() = map.values.sumBy { it.size }
|
||||||
|
|
||||||
|
override fun iterator(): Iterator<V> {
|
||||||
|
return ChainedIterator(map.values.map { it.iterator() })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun put(key: K, value: V) {
|
||||||
|
val container = map.getOrPut(key) { createContainer() }
|
||||||
|
container.add(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun remove(key: K, value: V) {
|
||||||
|
val collection = map[key] ?: return
|
||||||
|
collection.remove(value)
|
||||||
|
if (collection.isEmpty()) {
|
||||||
|
map.remove(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun removeKey(key: K) {
|
||||||
|
map.remove(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun clear() {
|
||||||
|
map.clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SetMultimap<K, V> : BaseMultimap<K, V, Set<V>, MutableSet<V>>() {
|
||||||
|
override fun createContainer(): MutableSet<V> {
|
||||||
|
return mutableSetOf()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createEmptyContainer(): Set<V> {
|
||||||
|
return emptySet()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ListMultimap<K, V> : BaseMultimap<K, V, List<V>, MutableList<V>>() {
|
||||||
|
override fun createContainer(): MutableList<V> {
|
||||||
|
return mutableListOf()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createEmptyContainer(): List<V> {
|
||||||
|
return emptyList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <K, V> setMultimapOf(): SetMultimap<K, V> = SetMultimap()
|
||||||
|
fun <K, V> listMultimapOf(): ListMultimap<K, V> = ListMultimap()
|
||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.fir.resolve
|
package org.jetbrains.kotlin.fir.util
|
||||||
|
|
||||||
import kotlinx.collections.immutable.*
|
import kotlinx.collections.immutable.*
|
||||||
|
|
||||||
Reference in New Issue
Block a user