Java nullability checker: take type arguments' types from resolution atom if possible, instead of from resolved call directly
^KT-47833 Fixed
This commit is contained in:
committed by
teamcityserver
parent
93f9d9dacd
commit
7567597be6
+10
-1
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
|
|||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.Nullability
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.Nullability
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.tower.NewResolvedCallImpl
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||||
@@ -135,10 +136,18 @@ class JavaNullabilityChecker(val upperBoundChecker: UpperBoundChecker) : Additio
|
|||||||
?: return
|
?: return
|
||||||
val resolvedCall = c.trace.bindingContext[BindingContext.RESOLVED_CALL, call] ?: return
|
val resolvedCall = c.trace.bindingContext[BindingContext.RESOLVED_CALL, call] ?: return
|
||||||
|
|
||||||
for ((typeParameter, typeArgument) in resolvedCall.typeArguments) {
|
val typeArguments = if (resolvedCall is NewResolvedCallImpl<*>) {
|
||||||
|
resolvedCall.resolvedCallAtom.typeArgumentMappingByOriginal
|
||||||
|
} else {
|
||||||
|
resolvedCall.typeArguments.entries
|
||||||
|
}
|
||||||
|
|
||||||
|
for ((typeParameter, typeArgument) in typeArguments) {
|
||||||
// continue if we don't have explicit type arguments
|
// continue if we don't have explicit type arguments
|
||||||
val typeReference = call.typeArguments.getOrNull(typeParameter.index)?.typeReference ?: continue
|
val typeReference = call.typeArguments.getOrNull(typeParameter.index)?.typeReference ?: continue
|
||||||
|
|
||||||
|
if (typeArgument == null) continue
|
||||||
|
|
||||||
upperBoundChecker.checkBounds(
|
upperBoundChecker.checkBounds(
|
||||||
typeReference, typeArgument, typeParameter, TypeSubstitutor.create(typeArgument), c.trace, withOnlyCheckForWarning = true
|
typeReference, typeArgument, typeParameter, TypeSubstitutor.create(typeArgument), c.trace, withOnlyCheckForWarning = true
|
||||||
)
|
)
|
||||||
|
|||||||
+9
-1
@@ -19,16 +19,22 @@ package org.jetbrains.kotlin.resolve.calls.components
|
|||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
class TypeArgumentsToParametersMapper {
|
class TypeArgumentsToParametersMapper {
|
||||||
|
|
||||||
sealed class TypeArgumentsMapping(val diagnostics: List<KotlinCallDiagnostic>) {
|
sealed class TypeArgumentsMapping(val diagnostics: List<KotlinCallDiagnostic>) :
|
||||||
|
Iterable<Map.Entry<TypeParameterDescriptor, KotlinType?>> {
|
||||||
|
|
||||||
abstract fun getTypeArgument(typeParameterDescriptor: TypeParameterDescriptor): TypeArgument
|
abstract fun getTypeArgument(typeParameterDescriptor: TypeParameterDescriptor): TypeArgument
|
||||||
|
|
||||||
object NoExplicitArguments : TypeArgumentsMapping(emptyList()) {
|
object NoExplicitArguments : TypeArgumentsMapping(emptyList()) {
|
||||||
|
private val emptyIterator = mapOf<Nothing, Nothing>().iterator()
|
||||||
|
|
||||||
override fun getTypeArgument(typeParameterDescriptor: TypeParameterDescriptor): TypeArgument =
|
override fun getTypeArgument(typeParameterDescriptor: TypeParameterDescriptor): TypeArgument =
|
||||||
TypeArgumentPlaceholder
|
TypeArgumentPlaceholder
|
||||||
|
|
||||||
|
override fun iterator() = emptyIterator
|
||||||
}
|
}
|
||||||
|
|
||||||
class TypeArgumentsMappingImpl(
|
class TypeArgumentsMappingImpl(
|
||||||
@@ -37,6 +43,8 @@ class TypeArgumentsToParametersMapper {
|
|||||||
) : TypeArgumentsMapping(diagnostics) {
|
) : TypeArgumentsMapping(diagnostics) {
|
||||||
override fun getTypeArgument(typeParameterDescriptor: TypeParameterDescriptor): TypeArgument =
|
override fun getTypeArgument(typeParameterDescriptor: TypeParameterDescriptor): TypeArgument =
|
||||||
typeParameterToArgumentMap[typeParameterDescriptor] ?: TypeArgumentPlaceholder
|
typeParameterToArgumentMap[typeParameterDescriptor] ?: TypeArgumentPlaceholder
|
||||||
|
|
||||||
|
override fun iterator() = typeParameterToArgumentMap.mapValues { (it.value as? SimpleTypeArgument)?.type }.iterator()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
// FILE: main.kt
|
||||||
|
sealed class ClientBootResult
|
||||||
|
|
||||||
|
object ClientBootSuccess : ClientBootResult()
|
||||||
|
|
||||||
|
fun example(): Single<out ClientBootResult> {
|
||||||
|
return Single.just(true).map<ClientBootResult> { ClientBootSuccess }
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: Single.java
|
||||||
|
import io.reactivex.rxjava3.annotations.NonNull;
|
||||||
|
|
||||||
|
public class Single<@NonNull T> {
|
||||||
|
@NonNull
|
||||||
|
public static <@NonNull T> Single<T> just(T item) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
@NonNull
|
||||||
|
public final <@NonNull R> Single<R> map(@NonNull Function<? super T, ? extends R> mapper) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: Function.java
|
||||||
|
import io.reactivex.rxjava3.annotations.NonNull;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface Function<@NonNull T, @NonNull R> {
|
||||||
|
R apply(T t) throws Throwable;
|
||||||
|
}
|
||||||
+6
@@ -86,6 +86,12 @@ public class ForeignAnnotationsCompiledJavaTestGenerated extends AbstractForeign
|
|||||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/kt47920.kt");
|
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/kt47920.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("kt47833.kt")
|
||||||
|
public void testKt47833() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/kt47833.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("lombokSimple.kt")
|
@TestMetadata("lombokSimple.kt")
|
||||||
public void testLombokSimple() throws Exception {
|
public void testLombokSimple() throws Exception {
|
||||||
|
|||||||
+6
@@ -86,6 +86,12 @@ public class ForeignAnnotationsCompiledJavaWithPsiClassReadingTestGenerated exte
|
|||||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/kt47920.kt");
|
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/kt47920.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("kt47833.kt")
|
||||||
|
public void testKt47833() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/kt47833.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("lombokSimple.kt")
|
@TestMetadata("lombokSimple.kt")
|
||||||
public void testLombokSimple() throws Exception {
|
public void testLombokSimple() throws Exception {
|
||||||
|
|||||||
+6
@@ -86,6 +86,12 @@ public class ForeignAnnotationsSourceJavaTestGenerated extends AbstractForeignAn
|
|||||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/kt47920.kt");
|
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/kt47920.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("kt47833.kt")
|
||||||
|
public void testKt47833() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/kt47833.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("lombokSimple.kt")
|
@TestMetadata("lombokSimple.kt")
|
||||||
public void testLombokSimple() throws Exception {
|
public void testLombokSimple() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user