FIR: Create DefinitelyNotNull only for annotated types
This commit is contained in:
+8
-3
@@ -15,12 +15,14 @@ import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
|
||||
import org.jetbrains.kotlin.fir.java.toConeKotlinTypeWithNullability
|
||||
import org.jetbrains.kotlin.fir.java.toFirJavaTypeRef
|
||||
import org.jetbrains.kotlin.fir.java.toNotNullConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.jvm.FirJavaTypeRef
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.jvm.FirJavaTypeRef
|
||||
import org.jetbrains.kotlin.load.java.AnnotationTypeQualifierResolver
|
||||
import org.jetbrains.kotlin.load.java.MUTABLE_ANNOTATIONS
|
||||
import org.jetbrains.kotlin.load.java.READ_ONLY_ANNOTATIONS
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaClassifierType
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaWildcardType
|
||||
import org.jetbrains.kotlin.load.java.typeEnhancement.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
@@ -133,7 +135,7 @@ internal class EnhancementSignatureParts(
|
||||
mapping.isMutable(upper.toFqNameUnsafe()) -> MutabilityQualifier.MUTABLE
|
||||
else -> null
|
||||
},
|
||||
isNotNullTypeParameter = false //TODO: unwrap() is NotNullTypeParameter
|
||||
isNotNullTypeParameter = lower is ConeDefinitelyNotNullType
|
||||
)
|
||||
}
|
||||
|
||||
@@ -212,11 +214,14 @@ internal class EnhancementSignatureParts(
|
||||
MutabilityQualifier.MUTABLE
|
||||
)
|
||||
),
|
||||
isNotNullTypeParameter = nullabilityInfo?.qualifier == NullabilityQualifier.NOT_NULL && true, /* TODO: isTypeParameter()*/
|
||||
isNotNullTypeParameter = nullabilityInfo?.qualifier == NullabilityQualifier.NOT_NULL && this.isTypeParameterBasedType(),
|
||||
isNullabilityQualifierForWarning = nullabilityInfo?.isForWarningOnly == true
|
||||
)
|
||||
}
|
||||
|
||||
private fun FirTypeRef?.isTypeParameterBasedType() =
|
||||
((this as? FirJavaTypeRef)?.type as? JavaClassifierType)?.classifier is JavaTypeParameter
|
||||
|
||||
private fun FirTypeRef?.computeQualifiersForOverride(
|
||||
session: FirSession,
|
||||
fromSupertypes: Collection<FirTypeRef>,
|
||||
|
||||
@@ -18,7 +18,6 @@ import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass
|
||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaField
|
||||
import org.jetbrains.kotlin.fir.java.toConeProjection
|
||||
import org.jetbrains.kotlin.fir.java.toNotNullConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.jvm.FirJavaTypeRef
|
||||
import org.jetbrains.kotlin.fir.references.impl.FirResolvedNamedReferenceImpl
|
||||
import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
@@ -32,6 +31,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.typeContext
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
|
||||
import org.jetbrains.kotlin.fir.types.jvm.FirJavaTypeRef
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.DEFAULT_NULL_FQ_NAME
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.DEFAULT_VALUE_FQ_NAME
|
||||
import org.jetbrains.kotlin.load.java.descriptors.AnnotationDefaultValue
|
||||
@@ -87,7 +87,9 @@ private fun JavaType?.enhancePossiblyFlexible(
|
||||
|
||||
when {
|
||||
type.isRaw -> ConeRawType(lowerResult, upperResult)
|
||||
else -> coneFlexibleOrSimpleType(session, lowerResult, upperResult)
|
||||
else -> coneFlexibleOrSimpleType(
|
||||
session, lowerResult, upperResult, isNotNullTypeParameter = qualifiers(index).isNotNullTypeParameter
|
||||
)
|
||||
}
|
||||
}
|
||||
is JavaArrayType -> {
|
||||
@@ -122,11 +124,12 @@ private fun JavaType?.subtreeSize(): Int {
|
||||
private fun coneFlexibleOrSimpleType(
|
||||
session: FirSession,
|
||||
lowerBound: ConeLookupTagBasedType,
|
||||
upperBound: ConeLookupTagBasedType
|
||||
upperBound: ConeLookupTagBasedType,
|
||||
isNotNullTypeParameter: Boolean
|
||||
): ConeKotlinType {
|
||||
if (AbstractStrictEqualityTypeChecker.strictEqualTypes(session.typeContext, lowerBound, upperBound)) {
|
||||
val lookupTag = lowerBound.lookupTag
|
||||
if (lookupTag is ConeTypeParameterLookupTag && !lowerBound.isMarkedNullable) {
|
||||
if (isNotNullTypeParameter && lookupTag is ConeTypeParameterLookupTag && !lowerBound.isMarkedNullable) {
|
||||
// TODO: we need enhancement for type parameter bounds for this code to work properly
|
||||
// At this moment, this condition is always true
|
||||
if (lookupTag.typeParameterSymbol.fir.bounds.any {
|
||||
|
||||
@@ -14,7 +14,7 @@ FILE: hashTableWithForEach.kt
|
||||
when () {
|
||||
R|/DEBUG| -> {
|
||||
^ Q|java/util/Collections|.R|java/util/Collections.unmodifiableSet|<R|kotlin/collections/MutableMap.MutableEntry<K, V>|>(R|kotlin/collections/mutableSetOf|<R|kotlin/collections/MutableMap.MutableEntry<K, V>|>().R|kotlin/apply|<R|kotlin/collections/MutableSet<kotlin/collections/MutableMap.MutableEntry<K, V>>|>(<L> = apply@fun R|kotlin/collections/MutableSet<kotlin/collections/MutableMap.MutableEntry<K, V>>|.<anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
|
||||
this@R|/SomeHashTable|.R|FakeOverride</SomeHashTable.forEach: R|kotlin/Unit|>|(<L> = forEach@fun <anonymous>(key: R|K!|, value: R|V!|): R|kotlin/Unit| {
|
||||
this@R|/SomeHashTable|.R|FakeOverride</SomeHashTable.forEach: R|kotlin/Unit|>|(<L> = forEach@fun <anonymous>(key: R|K|, value: R|V|): R|kotlin/Unit| {
|
||||
this@R|kotlin/collections/MutableSet|.R|FakeOverride<kotlin/collections/MutableSet.add: R|kotlin/Boolean|>|(R|/SomeHashTable.Entry.Entry|<R|K|, R|V|>(R|<local>/key|, R|<local>/value|))
|
||||
}
|
||||
)
|
||||
|
||||
@@ -2,11 +2,11 @@ FILE: test.kt
|
||||
public abstract interface UseIterable : R|MyIterable<kotlin/String>| {
|
||||
public open fun test(): R|kotlin/Unit| {
|
||||
lval it: R|kotlin/collections/MutableIterator<kotlin/String>| = this@R|kotlin/collections/MutableIterable|.R|FakeOverride<kotlin/collections/MutableIterable.iterator: R|kotlin/collections/MutableIterator<kotlin/String>|>|()
|
||||
lval split: R|java/util/Spliterator<kotlin/String!>| = this@R|java/lang/Iterable|.R|FakeOverride<java/lang/Iterable.spliterator: R|java/util/Spliterator<kotlin/String!>|>|()
|
||||
lval split: R|java/util/Spliterator<kotlin/String>| = this@R|java/lang/Iterable|.R|FakeOverride<java/lang/Iterable.spliterator: R|java/util/Spliterator<kotlin/String>|>|()
|
||||
}
|
||||
|
||||
}
|
||||
public final fun test(some: R|kotlin/collections/Iterable<kotlin/String>|): R|kotlin/Unit| {
|
||||
lval it: R|kotlin/collections/Iterator<kotlin/String>| = R|<local>/some|.R|FakeOverride<kotlin/collections/Iterable.iterator: R|kotlin/collections/Iterator<kotlin/String>|>|()
|
||||
lval split: R|java/util/Spliterator<kotlin/String!>| = R|<local>/some|.R|FakeOverride<java/lang/Iterable.spliterator: R|java/util/Spliterator<kotlin/String!>|>|()
|
||||
lval split: R|java/util/Spliterator<kotlin/String>| = R|<local>/some|.R|FakeOverride<java/lang/Iterable.spliterator: R|java/util/Spliterator<kotlin/String>|>|()
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ FILE: test.kt
|
||||
)
|
||||
lval otherResult: R|kotlin/String| = R|<local>/map|.R|FakeOverride<kotlin/collections/Map.getOrDefault: R|kotlin/String|>|(String(key), String(value))
|
||||
lval anotherResult: <ERROR TYPE REF: Unresolved name: replace> = R|<local>/map|.<Unresolved name: replace>#(String(key), String(value))
|
||||
R|<local>/map|.R|FakeOverride<java/util/Map.forEach: R|kotlin/Unit|>|(<L> = forEach@fun <anonymous>(key: R|kotlin/String!|, value: R|kotlin/String!|): R|kotlin/Unit| {
|
||||
R|<local>/map|.R|FakeOverride<java/util/Map.forEach: R|kotlin/Unit|>|(<L> = forEach@fun <anonymous>(key: R|kotlin/String|, value: R|kotlin/String|): R|kotlin/Unit| {
|
||||
R|kotlin/io/println|(<strcat>(R|<local>/key|.R|kotlin/Any.toString|(), String(: ), R|<local>/value|.R|kotlin/Any.toString|()))
|
||||
R|<local>/key|.R|kotlin/String.length|
|
||||
R|<local>/value|.R|kotlin/String.length|
|
||||
@@ -28,7 +28,7 @@ FILE: test.kt
|
||||
)
|
||||
lval otherResult: R|kotlin/String| = R|<local>/map|.R|FakeOverride<kotlin/collections/Map.getOrDefault: R|kotlin/String|>|(String(key), String(value))
|
||||
lval anotherResult: <ERROR TYPE REF: Unresolved name: replace> = R|<local>/map|.<Unresolved name: replace>#(String(key), String(value))
|
||||
R|<local>/map|.R|FakeOverride<java/util/Map.forEach: R|kotlin/Unit|>|(<L> = forEach@fun <anonymous>(key: R|kotlin/String!|, value: R|kotlin/String!|): R|kotlin/Unit| {
|
||||
R|<local>/map|.R|FakeOverride<java/util/Map.forEach: R|kotlin/Unit|>|(<L> = forEach@fun <anonymous>(key: R|kotlin/String|, value: R|kotlin/String|): R|kotlin/Unit| {
|
||||
R|kotlin/io/println|(<strcat>(R|<local>/key|.R|kotlin/Any.toString|(), String(: ), R|<local>/value|.R|kotlin/Any.toString|()))
|
||||
R|<local>/key|.R|kotlin/String.length|
|
||||
R|<local>/value|.R|kotlin/String.length|
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
FILE: test.kt
|
||||
public final fun <D : R|kotlin/Any|> R|Call<D>|.testForEach(): R|kotlin/Unit| {
|
||||
this@R|/Call|.R|/Call.arguments|.R|FakeOverride<java/util/Map.forEach: R|kotlin/Unit|>|(<L> = forEach@fun <anonymous>(key: R|kotlin/String!|, value: R|kotlin/String!|): R|kotlin/Unit| {
|
||||
this@R|/Call|.R|/Call.arguments|.R|FakeOverride<java/util/Map.forEach: R|kotlin/Unit|>|(<L> = forEach@fun <anonymous>(key: R|ft<kotlin/String, kotlin/String?>!|, value: R|ft<kotlin/String, kotlin/String?>!|): R|kotlin/Unit| {
|
||||
R|<local>/key|.R|kotlin/String.length|
|
||||
R|<local>/value|.R|kotlin/String.length|
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import java.util.AbstractSet
|
||||
|
||||
class SmartSet<T> : AbstractSet<T>() {
|
||||
override var size: Int = 0
|
||||
override fun iterator(): MutableIterator<T> = TODO()
|
||||
override fun add(element: T): Boolean = true
|
||||
override fun clear() {}
|
||||
override fun contains(element: T): Boolean = false
|
||||
}
|
||||
|
||||
fun foo(x: Any) {
|
||||
val s = SmartSet<Any>()
|
||||
s.add(x)
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
FILE: smartSet.kt
|
||||
public final class SmartSet<T> : R|java/util/AbstractSet<T>| {
|
||||
public constructor<T>(): R|SmartSet<T>| {
|
||||
super<R|java/util/AbstractSet<T>|>()
|
||||
}
|
||||
|
||||
public final override var size: R|kotlin/Int| = Int(0)
|
||||
public get(): R|kotlin/Int|
|
||||
public set(value: R|kotlin/Int|): R|kotlin/Unit|
|
||||
|
||||
public final override fun iterator(): R|kotlin/collections/MutableIterator<T>| {
|
||||
^iterator R|kotlin/TODO|()
|
||||
}
|
||||
|
||||
public final override fun add(element: R|T|): R|kotlin/Boolean| {
|
||||
^add Boolean(true)
|
||||
}
|
||||
|
||||
public final override fun clear(): R|kotlin/Unit| {
|
||||
}
|
||||
|
||||
public final override fun contains(element: R|T|): R|kotlin/Boolean| {
|
||||
^contains Boolean(false)
|
||||
}
|
||||
|
||||
}
|
||||
public final fun foo(x: R|kotlin/Any|): R|kotlin/Unit| {
|
||||
lval s: R|SmartSet<kotlin/Any>| = R|/SmartSet.SmartSet|<R|kotlin/Any|>()
|
||||
R|<local>/s|.R|FakeOverride</SmartSet.add: R|kotlin/Boolean|>|(R|<local>/x|)
|
||||
}
|
||||
@@ -10,7 +10,7 @@ FILE: typeAliasWithForEach.kt
|
||||
public final typealias Arguments = R|kotlin/collections/Map<kotlin/String, ArgsInfo>|
|
||||
public final fun R|Arguments|.deepCopy(): R|Arguments| {
|
||||
lval result: R|java/util/HashMap<kotlin/String, ArgsInfo>| = R|java/util/HashMap.HashMap|<R|kotlin/String|, R|ArgsInfo|>()
|
||||
this@R|/deepCopy|.R|FakeOverride<java/util/Map.forEach: R|kotlin/Unit|>|(<L> = forEach@fun <anonymous>(key: R|kotlin/String!|, value: R|ArgsInfo!|): R|kotlin/Unit| {
|
||||
this@R|/deepCopy|.R|FakeOverride<java/util/Map.forEach: R|kotlin/Unit|>|(<L> = forEach@fun <anonymous>(key: R|kotlin/String|, value: R|ArgsInfo|): R|kotlin/Unit| {
|
||||
R|<local>/result|.R|kotlin/collections/set|<R|kotlin/String|, R|ArgsInfo|>(R|<local>/key|, R|/ArgsInfoImpl.ArgsInfoImpl|(R|<local>/value|))
|
||||
}
|
||||
)
|
||||
|
||||
Generated
+5
@@ -534,6 +534,11 @@ public class FirDiagnosticsWithStdlibTestGenerated extends AbstractFirDiagnostic
|
||||
runTest("compiler/fir/resolve/testData/resolve/stdlib/j+k/RawType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("smartSet.kt")
|
||||
public void testSmartSet() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/stdlib/j+k/smartSet.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("StaticClassConstructorFromBaseClass.kt")
|
||||
public void testStaticClassConstructorFromBaseClass() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/stdlib/j+k/StaticClassConstructorFromBaseClass.kt");
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
public abstract interface SubclassOfMapEntry<K, V> : R|kotlin/collections/MutableMap.MutableEntry<K, V>| {
|
||||
public abstract operator fun setValue(value: R|V!|): R|V!|
|
||||
public abstract operator fun setValue(value: R|V|): R|V|
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user