Get rid of Guava in DelegatingDataFlowInfo (except Multimap things)
This commit is contained in:
+26
-25
@@ -16,7 +16,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.calls.smartcasts
|
package org.jetbrains.kotlin.resolve.calls.smartcasts
|
||||||
|
|
||||||
import com.google.common.collect.*
|
import com.google.common.collect.SetMultimap
|
||||||
|
import com.google.common.collect.LinkedHashMultimap
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
@@ -31,7 +32,7 @@ import java.util.*
|
|||||||
|
|
||||||
internal class DelegatingDataFlowInfo private constructor(
|
internal class DelegatingDataFlowInfo private constructor(
|
||||||
private val parent: DataFlowInfo?,
|
private val parent: DataFlowInfo?,
|
||||||
private val nullabilityInfo: ImmutableMap<DataFlowValue, Nullability>,
|
private val nullabilityInfo: Map<DataFlowValue, Nullability>,
|
||||||
// Also immutable
|
// Also immutable
|
||||||
private val typeInfo: SetMultimap<DataFlowValue, KotlinType>,
|
private val typeInfo: SetMultimap<DataFlowValue, KotlinType>,
|
||||||
/**
|
/**
|
||||||
@@ -41,11 +42,11 @@ internal class DelegatingDataFlowInfo private constructor(
|
|||||||
private val valueWithGivenTypeInfo: DataFlowValue?
|
private val valueWithGivenTypeInfo: DataFlowValue?
|
||||||
) : DataFlowInfo {
|
) : DataFlowInfo {
|
||||||
|
|
||||||
constructor(): this(null, ImmutableMap.of(), newTypeInfo(), null)
|
constructor(): this(null, emptyMap(), newTypeInfo(), null)
|
||||||
|
|
||||||
override val completeNullabilityInfo: Map<DataFlowValue, Nullability>
|
override val completeNullabilityInfo: Map<DataFlowValue, Nullability>
|
||||||
get() {
|
get() {
|
||||||
val result = Maps.newHashMap<DataFlowValue, Nullability>()
|
val result = hashMapOf<DataFlowValue, Nullability>()
|
||||||
var info: DelegatingDataFlowInfo? = this
|
var info: DelegatingDataFlowInfo? = this
|
||||||
while (info != null) {
|
while (info != null) {
|
||||||
for ((key, value) in info.nullabilityInfo) {
|
for ((key, value) in info.nullabilityInfo) {
|
||||||
@@ -145,13 +146,13 @@ internal class DelegatingDataFlowInfo private constructor(
|
|||||||
* @param value
|
* @param value
|
||||||
*/
|
*/
|
||||||
override fun clearValueInfo(value: DataFlowValue, languageVersionSettings: LanguageVersionSettings): DataFlowInfo {
|
override fun clearValueInfo(value: DataFlowValue, languageVersionSettings: LanguageVersionSettings): DataFlowInfo {
|
||||||
val builder = Maps.newHashMap<DataFlowValue, Nullability>()
|
val builder = hashMapOf<DataFlowValue, Nullability>()
|
||||||
putNullability(builder, value, value.immanentNullability, languageVersionSettings)
|
putNullability(builder, value, value.immanentNullability, languageVersionSettings)
|
||||||
return create(this, ImmutableMap.copyOf(builder), EMPTY_TYPE_INFO, value)
|
return create(this, builder.toMap(), EMPTY_TYPE_INFO, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun assign(a: DataFlowValue, b: DataFlowValue, languageVersionSettings: LanguageVersionSettings): DataFlowInfo {
|
override fun assign(a: DataFlowValue, b: DataFlowValue, languageVersionSettings: LanguageVersionSettings): DataFlowInfo {
|
||||||
val nullability = Maps.newHashMap<DataFlowValue, Nullability>()
|
val nullability = hashMapOf<DataFlowValue, Nullability>()
|
||||||
val nullabilityOfB = getStableNullability(b)
|
val nullabilityOfB = getStableNullability(b)
|
||||||
putNullability(nullability, a, nullabilityOfB, languageVersionSettings, affectReceiver = false)
|
putNullability(nullability, a, nullabilityOfB, languageVersionSettings, affectReceiver = false)
|
||||||
|
|
||||||
@@ -166,13 +167,13 @@ internal class DelegatingDataFlowInfo private constructor(
|
|||||||
}
|
}
|
||||||
newTypeInfo.putAll(a, typesForB)
|
newTypeInfo.putAll(a, typesForB)
|
||||||
|
|
||||||
return create(this, ImmutableMap.copyOf(nullability), if (newTypeInfo.isEmpty) EMPTY_TYPE_INFO else newTypeInfo, a)
|
return create(this, nullability.toMap(), if (newTypeInfo.isEmpty) EMPTY_TYPE_INFO else newTypeInfo, a)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun equate(
|
override fun equate(
|
||||||
a: DataFlowValue, b: DataFlowValue, identityEquals: Boolean, languageVersionSettings: LanguageVersionSettings
|
a: DataFlowValue, b: DataFlowValue, identityEquals: Boolean, languageVersionSettings: LanguageVersionSettings
|
||||||
): DataFlowInfo {
|
): DataFlowInfo {
|
||||||
val builder = Maps.newHashMap<DataFlowValue, Nullability>()
|
val builder = hashMapOf<DataFlowValue, Nullability>()
|
||||||
val nullabilityOfA = getStableNullability(a)
|
val nullabilityOfA = getStableNullability(a)
|
||||||
val nullabilityOfB = getStableNullability(b)
|
val nullabilityOfB = getStableNullability(b)
|
||||||
|
|
||||||
@@ -200,7 +201,7 @@ internal class DelegatingDataFlowInfo private constructor(
|
|||||||
this
|
this
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
create(this, ImmutableMap.copyOf(builder), if (newTypeInfo.isEmpty) EMPTY_TYPE_INFO else newTypeInfo)
|
create(this, builder.toMap(), if (newTypeInfo.isEmpty) EMPTY_TYPE_INFO else newTypeInfo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,13 +226,13 @@ internal class DelegatingDataFlowInfo private constructor(
|
|||||||
override fun disequate(
|
override fun disequate(
|
||||||
a: DataFlowValue, b: DataFlowValue, languageVersionSettings: LanguageVersionSettings
|
a: DataFlowValue, b: DataFlowValue, languageVersionSettings: LanguageVersionSettings
|
||||||
): DataFlowInfo {
|
): DataFlowInfo {
|
||||||
val builder = Maps.newHashMap<DataFlowValue, Nullability>()
|
val builder = hashMapOf<DataFlowValue, Nullability>()
|
||||||
val nullabilityOfA = getStableNullability(a)
|
val nullabilityOfA = getStableNullability(a)
|
||||||
val nullabilityOfB = getStableNullability(b)
|
val nullabilityOfB = getStableNullability(b)
|
||||||
|
|
||||||
val changed = putNullability(builder, a, nullabilityOfA.refine(nullabilityOfB.invert()), languageVersionSettings) or
|
val changed = putNullability(builder, a, nullabilityOfA.refine(nullabilityOfB.invert()), languageVersionSettings) or
|
||||||
putNullability(builder, b, nullabilityOfB.refine(nullabilityOfA.invert()), languageVersionSettings)
|
putNullability(builder, b, nullabilityOfB.refine(nullabilityOfA.invert()), languageVersionSettings)
|
||||||
return if (changed) create(this, ImmutableMap.copyOf(builder), EMPTY_TYPE_INFO) else this
|
return if (changed) create(this, builder.toMap(), EMPTY_TYPE_INFO) else this
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun establishSubtyping(
|
override fun establishSubtyping(
|
||||||
@@ -242,11 +243,11 @@ internal class DelegatingDataFlowInfo private constructor(
|
|||||||
if (!value.type.isFlexible() && value.type.isSubtypeOf(type)) return this
|
if (!value.type.isFlexible() && value.type.isSubtypeOf(type)) return this
|
||||||
val newTypeInfo = newTypeInfo()
|
val newTypeInfo = newTypeInfo()
|
||||||
newTypeInfo.put(value, type)
|
newTypeInfo.put(value, type)
|
||||||
val builder = Maps.newHashMap<DataFlowValue, Nullability>()
|
val builder = hashMapOf<DataFlowValue, Nullability>()
|
||||||
if (!type.isMarkedNullable) {
|
if (!type.isMarkedNullable) {
|
||||||
putNullability(builder, value, NOT_NULL, languageVersionSettings)
|
putNullability(builder, value, NOT_NULL, languageVersionSettings)
|
||||||
}
|
}
|
||||||
val newNullabilityInfo = if (type.isMarkedNullable) EMPTY_NULLABILITY_INFO else ImmutableMap.copyOf(builder)
|
val newNullabilityInfo = if (type.isMarkedNullable) emptyMap() else builder.toMap()
|
||||||
return create(this, newNullabilityInfo, newTypeInfo)
|
return create(this, newNullabilityInfo, newTypeInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,7 +258,7 @@ internal class DelegatingDataFlowInfo private constructor(
|
|||||||
|
|
||||||
assert(other is DelegatingDataFlowInfo) { "Unknown DataFlowInfo type: " + other }
|
assert(other is DelegatingDataFlowInfo) { "Unknown DataFlowInfo type: " + other }
|
||||||
|
|
||||||
val nullabilityMapBuilder = Maps.newHashMap<DataFlowValue, Nullability>()
|
val nullabilityMapBuilder = hashMapOf<DataFlowValue, Nullability>()
|
||||||
for ((key, otherFlags) in other.completeNullabilityInfo) {
|
for ((key, otherFlags) in other.completeNullabilityInfo) {
|
||||||
val thisFlags = getCollectedNullability(key)
|
val thisFlags = getCollectedNullability(key)
|
||||||
val flags = thisFlags.and(otherFlags)
|
val flags = thisFlags.and(otherFlags)
|
||||||
@@ -272,16 +273,16 @@ internal class DelegatingDataFlowInfo private constructor(
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
return create(this, ImmutableMap.copyOf(nullabilityMapBuilder), otherTypeInfo)
|
return create(this, nullabilityMapBuilder.toMap(), otherTypeInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Set<KotlinType>.containsNothing() = any { KotlinBuiltIns.isNothing(it) }
|
private fun Set<KotlinType>.containsNothing() = any { KotlinBuiltIns.isNothing(it) }
|
||||||
|
|
||||||
private fun Set<KotlinType>.intersect(other: Set<KotlinType>) =
|
private fun Set<KotlinType>.intersectConsideringNothing(other: Set<KotlinType>) =
|
||||||
when {
|
when {
|
||||||
other.containsNothing() -> this
|
other.containsNothing() -> this
|
||||||
this.containsNothing() -> other
|
this.containsNothing() -> other
|
||||||
else -> Sets.intersection(this, other)
|
else -> this.intersect(other)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun or(other: DataFlowInfo): DataFlowInfo {
|
override fun or(other: DataFlowInfo): DataFlowInfo {
|
||||||
@@ -291,7 +292,7 @@ internal class DelegatingDataFlowInfo private constructor(
|
|||||||
|
|
||||||
assert(other is DelegatingDataFlowInfo) { "Unknown DataFlowInfo type: " + other }
|
assert(other is DelegatingDataFlowInfo) { "Unknown DataFlowInfo type: " + other }
|
||||||
|
|
||||||
val nullabilityMapBuilder = Maps.newHashMap<DataFlowValue, Nullability>()
|
val nullabilityMapBuilder = hashMapOf<DataFlowValue, Nullability>()
|
||||||
for ((key, otherFlags) in other.completeNullabilityInfo) {
|
for ((key, otherFlags) in other.completeNullabilityInfo) {
|
||||||
val thisFlags = getCollectedNullability(key)
|
val thisFlags = getCollectedNullability(key)
|
||||||
nullabilityMapBuilder.put(key, thisFlags.or(otherFlags))
|
nullabilityMapBuilder.put(key, thisFlags.or(otherFlags))
|
||||||
@@ -301,17 +302,17 @@ internal class DelegatingDataFlowInfo private constructor(
|
|||||||
val otherTypeInfo = other.completeTypeInfo
|
val otherTypeInfo = other.completeTypeInfo
|
||||||
val newTypeInfo = newTypeInfo()
|
val newTypeInfo = newTypeInfo()
|
||||||
|
|
||||||
for (key in Sets.intersection(myTypeInfo.keySet(), otherTypeInfo.keySet())) {
|
for (key in myTypeInfo.keySet()) {
|
||||||
newTypeInfo.putAll(key, myTypeInfo[key].intersect(otherTypeInfo[key]))
|
if (key in otherTypeInfo.keySet()) {
|
||||||
|
newTypeInfo.putAll(key, myTypeInfo[key].intersectConsideringNothing(otherTypeInfo[key]))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return create(null, nullabilityMapBuilder.toMap(), newTypeInfo)
|
||||||
return create(null, ImmutableMap.copyOf(nullabilityMapBuilder), newTypeInfo)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString() = if (typeInfo.isEmpty && nullabilityInfo.isEmpty()) "EMPTY" else "Non-trivial DataFlowInfo"
|
override fun toString() = if (typeInfo.isEmpty && nullabilityInfo.isEmpty()) "EMPTY" else "Non-trivial DataFlowInfo"
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val EMPTY_NULLABILITY_INFO = ImmutableMap.of<DataFlowValue, Nullability>()
|
|
||||||
private val EMPTY_TYPE_INFO = newTypeInfo()
|
private val EMPTY_TYPE_INFO = newTypeInfo()
|
||||||
|
|
||||||
private fun containsAll(first: SetMultimap<DataFlowValue, KotlinType>, second: SetMultimap<DataFlowValue, KotlinType>) =
|
private fun containsAll(first: SetMultimap<DataFlowValue, KotlinType>, second: SetMultimap<DataFlowValue, KotlinType>) =
|
||||||
@@ -320,7 +321,7 @@ internal class DelegatingDataFlowInfo private constructor(
|
|||||||
fun newTypeInfo(): SetMultimap<DataFlowValue, KotlinType> = LinkedHashMultimap.create<DataFlowValue, KotlinType>()
|
fun newTypeInfo(): SetMultimap<DataFlowValue, KotlinType> = LinkedHashMultimap.create<DataFlowValue, KotlinType>()
|
||||||
|
|
||||||
private fun create(parent: DataFlowInfo?,
|
private fun create(parent: DataFlowInfo?,
|
||||||
nullabilityInfo: ImmutableMap<DataFlowValue, Nullability>,
|
nullabilityInfo: Map<DataFlowValue, Nullability>,
|
||||||
// NB: typeInfo must be mutable here!
|
// NB: typeInfo must be mutable here!
|
||||||
typeInfo: SetMultimap<DataFlowValue, KotlinType>,
|
typeInfo: SetMultimap<DataFlowValue, KotlinType>,
|
||||||
valueWithGivenTypeInfo: DataFlowValue? = null
|
valueWithGivenTypeInfo: DataFlowValue? = null
|
||||||
|
|||||||
Reference in New Issue
Block a user