K2: drop unnecessary attributes when inferring declaration types

Related to KT-62578
This commit is contained in:
Mikhail Glukhikh
2023-10-17 13:44:40 +02:00
committed by Space Team
parent 90eaf5f70f
commit cebb6747e3
5 changed files with 29 additions and 13 deletions
@@ -1,6 +1,6 @@
FILE: test.kt
public final fun foo(tag: R|XmlTag|, name: R|kotlin/String|): R|kotlin/collections/List<XmlTag>| {
lval result: R|kotlin/collections/List<@NoInfer XmlTag>| = R|<local>/tag|.R|/PsiElement.children|.R|kotlin/collections/filterIsInstance|<R|XmlTag|>().R|kotlin/collections/filter|<R|@NoInfer XmlTag|>(<L> = filter@fun <anonymous>(it: R|@NoInfer XmlTag|): R|kotlin/Boolean| <inline=Inline, kind=UNKNOWN> {
lval result: R|kotlin/collections/List<XmlTag>| = R|<local>/tag|.R|/PsiElement.children|.R|kotlin/collections/filterIsInstance|<R|XmlTag|>().R|kotlin/collections/filter|<R|@NoInfer XmlTag|>(<L> = filter@fun <anonymous>(it: R|@NoInfer XmlTag|): R|kotlin/Boolean| <inline=Inline, kind=UNKNOWN> {
^ ==(R|<local>/it|.R|/XmlTag.localName|, R|<local>/name|)
}
)
@@ -19,13 +19,13 @@ FILE: withInInitializer.kt
public final val data: R|First| = R|/First.First|(Int(42))
public get(): R|First|
public final val test: R|kotlin/collections/List<@NoInfer kotlin/Int>| = R|kotlin/with|<R|First|, R|kotlin/collections/List<@NoInfer kotlin/Int>|>(this@R|/Second|.R|/Second.data|, <L> = with@fun R|First|.<anonymous>(): R|kotlin/collections/List<@NoInfer kotlin/Int>| <inline=Inline, kind=EXACTLY_ONCE> {
public final val test: R|kotlin/collections/List<kotlin/Int>| = R|kotlin/with|<R|First|, R|kotlin/collections/List<@NoInfer kotlin/Int>|>(this@R|/Second|.R|/Second.data|, <L> = with@fun R|First|.<anonymous>(): R|kotlin/collections/List<@NoInfer kotlin/Int>| <inline=Inline, kind=EXACTLY_ONCE> {
^ this@R|/Second|.R|/Second.list|.R|kotlin/collections/filterIsInstance|<R|kotlin/Int|>().R|kotlin/collections/filter|<R|@NoInfer kotlin/Int|>(<L> = filter@fun <anonymous>(it: R|@NoInfer kotlin/Int|): R|kotlin/Boolean| <inline=Inline, kind=UNKNOWN> {
^ ==(R|<local>/it|, this@R|special/anonymous|.R|/First.member|)
}
)
}
)
public get(): R|kotlin/collections/List<@NoInfer kotlin/Int>|
public get(): R|kotlin/collections/List<kotlin/Int>|
}
@@ -125,6 +125,11 @@ class ConeAttributes private constructor(attributes: List<ConeAttribute<*>>) : A
})
}
fun filterNecessaryToKeep(): ConeAttributes {
return if (all { it.keepInInferredDeclarationType }) this
else create(filter { it.keepInInferredDeclarationType })
}
private inline fun perform(other: ConeAttributes, op: ConeAttribute<*>.(ConeAttribute<*>?) -> ConeAttribute<*>?): ConeAttributes {
if (this.isEmpty() && other.isEmpty()) return this
val attributes = mutableListOf<ConeAttribute<*>>()
@@ -30,10 +30,21 @@ fun FirTypeRef.approximateDeclarationType(
}
val preparedType = if (isLocal) baseType else baseType.substituteAlternativesInPublicType(session)
val approximatedType = session.typeApproximator.approximateToSuperType(preparedType, configuration) ?: preparedType
var approximatedType = session.typeApproximator.approximateToSuperType(preparedType, configuration) ?: preparedType
if (approximatedType.contains { type -> type.attributes.any { !it.keepInInferredDeclarationType } }) {
approximatedType = UnnecessaryAttributesRemover(session).substituteOrSelf(approximatedType)
}
return this.withReplacedConeType(approximatedType).applyIf(stripEnhancedNullability) { withoutEnhancedNullability() }
}
private class UnnecessaryAttributesRemover(session: FirSession) : AbstractConeSubstitutor(session.typeContext) {
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
val filteredAttributes = type.attributes.filterNecessaryToKeep()
return if (filteredAttributes === type.attributes) null
else type.withAttributes(filteredAttributes)
}
}
private fun ConeKotlinType.substituteAlternativesInPublicType(session: FirSession): ConeKotlinType {
val substitutor = object : AbstractConeSubstitutor(session.typeContext) {
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
@@ -434,12 +434,12 @@ FILE: metaSerializable.kt
lval reconstructed: R|Project2| = Q|kotlinx/serialization/json/Json|.R|kotlinx/serialization/json/Json.decodeFromString|<R|Project2|>(Q|Project2|.R|/Project2.Companion.serializer|(), R|<local>/string|)
R|kotlin/test/assertEquals|<R|kotlin/String|>(String(name), R|<local>/reconstructed|.R|/Project2.name|)
R|kotlin/test/assertEquals|<R|kotlin/String|>(String(lang), R|<local>/reconstructed|.R|/Project2.language|)
lval info: R|@NoInfer MySerializableWithInfo| = Q|Project2|.R|/Project2.Companion.serializer|().R|SubstitutionOverride<kotlinx/serialization/KSerializer.descriptor: R|kotlinx/serialization/descriptors/SerialDescriptor|>|.R|kotlinx/serialization/descriptors/SerialDescriptor.annotations|.R|kotlin/collections/filterIsInstance|<R|MySerializableWithInfo|>().R|kotlin/collections/first|<R|@NoInfer MySerializableWithInfo|>()
lval info: R|MySerializableWithInfo| = Q|Project2|.R|/Project2.Companion.serializer|().R|SubstitutionOverride<kotlinx/serialization/KSerializer.descriptor: R|kotlinx/serialization/descriptors/SerialDescriptor|>|.R|kotlinx/serialization/descriptors/SerialDescriptor.annotations|.R|kotlin/collections/filterIsInstance|<R|MySerializableWithInfo|>().R|kotlin/collections/first|<R|@NoInfer MySerializableWithInfo|>()
R|kotlin/test/assertEquals|<R|kotlin/Int|>(Int(123), R|<local>/info|.R|/MySerializableWithInfo.value|)
R|kotlin/test/assertEquals|<R|kotlin/reflect/KClass<out kotlin/Any>|>(<getClass>(Q|kotlin/String|), R|<local>/info|.R|/MySerializableWithInfo.kclass|)
}
public final fun testMetaSerializableOnProperty(): R|kotlin/Unit| {
lval info: R|@NoInfer MySerializableWithInfo| = Q|Wrapper|.R|/Wrapper.Companion.serializer|().R|SubstitutionOverride<kotlinx/serialization/KSerializer.descriptor: R|kotlinx/serialization/descriptors/SerialDescriptor|>|.R|kotlinx/serialization/descriptors/SerialDescriptor.getElementAnnotations|(Int(0)).R|kotlin/collections/filterIsInstance|<R|MySerializableWithInfo|>().R|kotlin/collections/first|<R|@NoInfer MySerializableWithInfo|>()
lval info: R|MySerializableWithInfo| = Q|Wrapper|.R|/Wrapper.Companion.serializer|().R|SubstitutionOverride<kotlinx/serialization/KSerializer.descriptor: R|kotlinx/serialization/descriptors/SerialDescriptor|>|.R|kotlinx/serialization/descriptors/SerialDescriptor.getElementAnnotations|(Int(0)).R|kotlin/collections/filterIsInstance|<R|MySerializableWithInfo|>().R|kotlin/collections/first|<R|@NoInfer MySerializableWithInfo|>()
R|kotlin/test/assertEquals|<R|kotlin/Int|>(Int(234), R|<local>/info|.R|/MySerializableWithInfo.value|)
R|kotlin/test/assertEquals|<R|kotlin/reflect/KClass<out kotlin/Any>|>(<getClass>(Q|kotlin/Int|), R|<local>/info|.R|/MySerializableWithInfo.kclass|)
}
@@ -449,7 +449,7 @@ FILE: metaSerializable.kt
lval reconstructed: R|Project3| = Q|kotlinx/serialization/json/Json|.R|kotlinx/serialization/json/Json.decodeFromString|<R|Project3|>(Q|Project3|.R|/Project3.Companion.serializer|(), R|<local>/string|)
R|kotlin/test/assertEquals|<R|kotlin/String|>(String(name), R|<local>/reconstructed|.R|/Project3.name|)
R|kotlin/test/assertEquals|<R|kotlin/String|>(String(lang), R|<local>/reconstructed|.R|/Project3.language|)
lval info: R|@NoInfer MySerializableWithInfo| = Q|Project3|.R|/Project3.Companion.serializer|().R|SubstitutionOverride<kotlinx/serialization/KSerializer.descriptor: R|kotlinx/serialization/descriptors/SerialDescriptor|>|.R|kotlinx/serialization/descriptors/SerialDescriptor.annotations|.R|kotlin/collections/filterIsInstance|<R|MySerializableWithInfo|>().R|kotlin/collections/first|<R|@NoInfer MySerializableWithInfo|>()
lval info: R|MySerializableWithInfo| = Q|Project3|.R|/Project3.Companion.serializer|().R|SubstitutionOverride<kotlinx/serialization/KSerializer.descriptor: R|kotlinx/serialization/descriptors/SerialDescriptor|>|.R|kotlinx/serialization/descriptors/SerialDescriptor.annotations|.R|kotlin/collections/filterIsInstance|<R|MySerializableWithInfo|>().R|kotlin/collections/first|<R|@NoInfer MySerializableWithInfo|>()
R|kotlin/test/assertEquals|<R|kotlin/Int|>(Int(123), R|<local>/info|.R|/MySerializableWithInfo.value|)
R|kotlin/test/assertEquals|<R|kotlin/reflect/KClass<out kotlin/Any>|>(<getClass>(Q|kotlin/String|), R|<local>/info|.R|/MySerializableWithInfo.kclass|)
}
@@ -465,8 +465,8 @@ FILE: metaSerializable.kt
lval serializerB: R|kotlinx/serialization/KSerializer<TestSealed.B>| = Q|TestSealed.B|.R|/TestSealed.B.Companion.serializer|()
R|kotlin/test/assertNotNull|<R|kotlinx/serialization/KSerializer<TestSealed.A>|>(R|<local>/serializerA|)
R|kotlin/test/assertNotNull|<R|kotlinx/serialization/KSerializer<TestSealed.B>|>(R|<local>/serializerB|)
lval infoA: R|@NoInfer MySerializableWithInfo| = R|<local>/serializerA|.R|SubstitutionOverride<kotlinx/serialization/KSerializer.descriptor: R|kotlinx/serialization/descriptors/SerialDescriptor|>|.R|kotlinx/serialization/descriptors/SerialDescriptor.annotations|.R|kotlin/collections/filterIsInstance|<R|MySerializableWithInfo|>().R|kotlin/collections/first|<R|@NoInfer MySerializableWithInfo|>()
lval infoB: R|@NoInfer MySerializableWithInfo| = R|<local>/serializerB|.R|SubstitutionOverride<kotlinx/serialization/KSerializer.descriptor: R|kotlinx/serialization/descriptors/SerialDescriptor|>|.R|kotlinx/serialization/descriptors/SerialDescriptor.annotations|.R|kotlin/collections/filterIsInstance|<R|MySerializableWithInfo|>().R|kotlin/collections/first|<R|@NoInfer MySerializableWithInfo|>()
lval infoA: R|MySerializableWithInfo| = R|<local>/serializerA|.R|SubstitutionOverride<kotlinx/serialization/KSerializer.descriptor: R|kotlinx/serialization/descriptors/SerialDescriptor|>|.R|kotlinx/serialization/descriptors/SerialDescriptor.annotations|.R|kotlin/collections/filterIsInstance|<R|MySerializableWithInfo|>().R|kotlin/collections/first|<R|@NoInfer MySerializableWithInfo|>()
lval infoB: R|MySerializableWithInfo| = R|<local>/serializerB|.R|SubstitutionOverride<kotlinx/serialization/KSerializer.descriptor: R|kotlinx/serialization/descriptors/SerialDescriptor|>|.R|kotlinx/serialization/descriptors/SerialDescriptor.annotations|.R|kotlin/collections/filterIsInstance|<R|MySerializableWithInfo|>().R|kotlin/collections/first|<R|@NoInfer MySerializableWithInfo|>()
R|kotlin/test/assertEquals|<R|kotlin/Int|>(Int(123), R|<local>/infoA|.R|/MySerializableWithInfo.value|)
R|kotlin/test/assertEquals|<R|kotlin/reflect/KClass<out kotlin/Any>|>(<getClass>(Q|kotlin/String|), R|<local>/infoA|.R|/MySerializableWithInfo.kclass|)
R|kotlin/test/assertEquals|<R|kotlin/Int|>(Int(123), R|<local>/infoB|.R|/MySerializableWithInfo.value|)
@@ -477,8 +477,8 @@ FILE: metaSerializable.kt
lval serializerB: R|kotlinx/serialization/KSerializer<TestAbstract.B>| = Q|TestAbstract.B|.R|/TestAbstract.B.Companion.serializer|()
R|kotlin/test/assertNotNull|<R|kotlinx/serialization/KSerializer<TestAbstract.A>|>(R|<local>/serializerA|)
R|kotlin/test/assertNotNull|<R|kotlinx/serialization/KSerializer<TestAbstract.B>|>(R|<local>/serializerB|)
lval infoA: R|@NoInfer MySerializableWithInfo| = R|<local>/serializerA|.R|SubstitutionOverride<kotlinx/serialization/KSerializer.descriptor: R|kotlinx/serialization/descriptors/SerialDescriptor|>|.R|kotlinx/serialization/descriptors/SerialDescriptor.annotations|.R|kotlin/collections/filterIsInstance|<R|MySerializableWithInfo|>().R|kotlin/collections/first|<R|@NoInfer MySerializableWithInfo|>()
lval infoB: R|@NoInfer MySerializableWithInfo| = R|<local>/serializerB|.R|SubstitutionOverride<kotlinx/serialization/KSerializer.descriptor: R|kotlinx/serialization/descriptors/SerialDescriptor|>|.R|kotlinx/serialization/descriptors/SerialDescriptor.annotations|.R|kotlin/collections/filterIsInstance|<R|MySerializableWithInfo|>().R|kotlin/collections/first|<R|@NoInfer MySerializableWithInfo|>()
lval infoA: R|MySerializableWithInfo| = R|<local>/serializerA|.R|SubstitutionOverride<kotlinx/serialization/KSerializer.descriptor: R|kotlinx/serialization/descriptors/SerialDescriptor|>|.R|kotlinx/serialization/descriptors/SerialDescriptor.annotations|.R|kotlin/collections/filterIsInstance|<R|MySerializableWithInfo|>().R|kotlin/collections/first|<R|@NoInfer MySerializableWithInfo|>()
lval infoB: R|MySerializableWithInfo| = R|<local>/serializerB|.R|SubstitutionOverride<kotlinx/serialization/KSerializer.descriptor: R|kotlinx/serialization/descriptors/SerialDescriptor|>|.R|kotlinx/serialization/descriptors/SerialDescriptor.annotations|.R|kotlin/collections/filterIsInstance|<R|MySerializableWithInfo|>().R|kotlin/collections/first|<R|@NoInfer MySerializableWithInfo|>()
R|kotlin/test/assertEquals|<R|kotlin/Int|>(Int(123), R|<local>/infoA|.R|/MySerializableWithInfo.value|)
R|kotlin/test/assertEquals|<R|kotlin/reflect/KClass<out kotlin/Any>|>(<getClass>(Q|kotlin/String|), R|<local>/infoA|.R|/MySerializableWithInfo.kclass|)
R|kotlin/test/assertEquals|<R|kotlin/Int|>(Int(123), R|<local>/infoB|.R|/MySerializableWithInfo.value|)
@@ -487,14 +487,14 @@ FILE: metaSerializable.kt
public final fun testEnum(): R|kotlin/Unit| {
lval serializer: R|kotlinx/serialization/KSerializer<TestEnum>| = Q|TestEnum|.R|/TestEnum.Companion.serializer|()
R|kotlin/test/assertNotNull|<R|kotlinx/serialization/KSerializer<TestEnum>|>(R|<local>/serializer|)
lval info: R|@NoInfer MySerializableWithInfo| = R|<local>/serializer|.R|SubstitutionOverride<kotlinx/serialization/KSerializer.descriptor: R|kotlinx/serialization/descriptors/SerialDescriptor|>|.R|kotlinx/serialization/descriptors/SerialDescriptor.annotations|.R|kotlin/collections/filterIsInstance|<R|MySerializableWithInfo|>().R|kotlin/collections/first|<R|@NoInfer MySerializableWithInfo|>()
lval info: R|MySerializableWithInfo| = R|<local>/serializer|.R|SubstitutionOverride<kotlinx/serialization/KSerializer.descriptor: R|kotlinx/serialization/descriptors/SerialDescriptor|>|.R|kotlinx/serialization/descriptors/SerialDescriptor.annotations|.R|kotlin/collections/filterIsInstance|<R|MySerializableWithInfo|>().R|kotlin/collections/first|<R|@NoInfer MySerializableWithInfo|>()
R|kotlin/test/assertEquals|<R|kotlin/Int|>(Int(123), R|<local>/info|.R|/MySerializableWithInfo.value|)
R|kotlin/test/assertEquals|<R|kotlin/reflect/KClass<out kotlin/Any>|>(<getClass>(Q|kotlin/String|), R|<local>/info|.R|/MySerializableWithInfo.kclass|)
}
public final fun testObject(): R|kotlin/Unit| {
lval serializer: R|kotlinx/serialization/KSerializer<TestObject>| = Q|TestObject|.R|/TestObject.serializer|()
R|kotlin/test/assertNotNull|<R|kotlinx/serialization/KSerializer<TestObject>|>(R|<local>/serializer|)
lval info: R|@NoInfer MySerializableWithInfo| = R|<local>/serializer|.R|SubstitutionOverride<kotlinx/serialization/KSerializer.descriptor: R|kotlinx/serialization/descriptors/SerialDescriptor|>|.R|kotlinx/serialization/descriptors/SerialDescriptor.annotations|.R|kotlin/collections/filterIsInstance|<R|MySerializableWithInfo|>().R|kotlin/collections/first|<R|@NoInfer MySerializableWithInfo|>()
lval info: R|MySerializableWithInfo| = R|<local>/serializer|.R|SubstitutionOverride<kotlinx/serialization/KSerializer.descriptor: R|kotlinx/serialization/descriptors/SerialDescriptor|>|.R|kotlinx/serialization/descriptors/SerialDescriptor.annotations|.R|kotlin/collections/filterIsInstance|<R|MySerializableWithInfo|>().R|kotlin/collections/first|<R|@NoInfer MySerializableWithInfo|>()
R|kotlin/test/assertEquals|<R|kotlin/Int|>(Int(123), R|<local>/info|.R|/MySerializableWithInfo.value|)
R|kotlin/test/assertEquals|<R|kotlin/reflect/KClass<out kotlin/Any>|>(<getClass>(Q|kotlin/String|), R|<local>/info|.R|/MySerializableWithInfo.kclass|)
}