[FIR] Fix determining nullability of arguments during enhancement

This commit is contained in:
Dmitriy Novozhilov
2021-03-09 12:45:31 +03:00
parent 65ea4e184a
commit 932eed2c14
7 changed files with 79 additions and 3 deletions
@@ -601,6 +601,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/tryInLambda.kt");
}
@TestMetadata("typeMismatchOnExpectedJavaMap.kt")
public void testTypeMismatchOnExpectedJavaMap() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/typeMismatchOnExpectedJavaMap.kt");
}
@TestMetadata("untouchedReturnInIf.kt")
public void testUntouchedReturnInIf() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/untouchedReturnInIf.kt");
@@ -0,0 +1,4 @@
FILE: main.kt
public final fun <T> test(executor: R|BuildActionExecuter<T>|, modelType: R|java/lang/Class<T>|, env: R|kotlin/collections/Map<kotlin/String, kotlin/String>|): R|kotlin/Unit| {
lval model: R|ft<BuildActionExecuter<ft<T, T?>!>, BuildActionExecuter<ft<T, T?>!>?>!| = R|<local>/executor|.R|SubstitutionOverride</BuildActionExecuter.setEnvironmentVariables: R|ft<BuildActionExecuter<ft<T, T?>!>, BuildActionExecuter<ft<T, T?>!>?>!|>|(R|<local>/env|)
}
@@ -0,0 +1,26 @@
// FULL_JDK
// FILE: LongRunningOperation.java
import java.util.Map;
import org.jetbrains.annotations.Nullable;
public interface LongRunningOperation {
LongRunningOperation setEnvironmentVariables(@Nullable Map<String, String> envVariables);
}
// FILE: ConfigurableLauncher.java
import java.util.Map;
public interface ConfigurableLauncher<T extends ConfigurableLauncher<T>> extends LongRunningOperation {
@Override
T setEnvironmentVariables(Map<String, String> envVariables);
}
// FILE: BuildActionExecuter.java
public interface BuildActionExecuter<T> extends ConfigurableLauncher<BuildActionExecuter<T>> {}
// FILE: main.kt
fun <T> test(executor: BuildActionExecuter<T>, modelType: Class<T>, env: Map<String, String>) {
val model = executor.setEnvironmentVariables(env)
}
@@ -707,6 +707,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/tryInLambda.kt");
}
@Test
@TestMetadata("typeMismatchOnExpectedJavaMap.kt")
public void testTypeMismatchOnExpectedJavaMap() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/typeMismatchOnExpectedJavaMap.kt");
}
@Test
@TestMetadata("untouchedReturnInIf.kt")
public void testUntouchedReturnInIf() throws Exception {
@@ -711,6 +711,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/tryInLambda.kt");
}
@Test
@TestMetadata("typeMismatchOnExpectedJavaMap.kt")
public void testTypeMismatchOnExpectedJavaMap() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/typeMismatchOnExpectedJavaMap.kt");
}
@Test
@TestMetadata("untouchedReturnInIf.kt")
public void testUntouchedReturnInIf() throws Exception {
@@ -248,7 +248,7 @@ internal class EnhancementSignatureParts(
val superQualifiers = fromSupertypes.map { it.extractQualifiers(session) }
val mutabilityFromSupertypes = superQualifiers.mapNotNull { it.mutability }.toSet()
val nullabilityFromSupertypes = superQualifiers.mapNotNull { it.nullability }.toSet()
val nullabilityFromSupertypesWithWarning = fromOverridden
val nullabilityFromSupertypesWithWarning = fromSupertypes
.mapNotNull { it.extractQualifiers(session).nullability }
.toSet()
@@ -28,6 +28,8 @@ import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
import org.jetbrains.kotlin.fir.types.builder.buildStarProjection
import org.jetbrains.kotlin.fir.types.builder.buildTypeProjectionWithVariance
import org.jetbrains.kotlin.fir.types.jvm.FirJavaTypeRef
import org.jetbrains.kotlin.load.java.JavaDefaultQualifiers
import org.jetbrains.kotlin.load.java.structure.JavaClassifierType
@@ -38,6 +40,7 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.AbstractStrictEqualityTypeChecker
import org.jetbrains.kotlin.types.ConstantValueKind
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.utils.extractRadix
internal class IndexedJavaTypeQualifiers(private val data: Array<JavaTypeQualifiers>) {
@@ -253,8 +256,34 @@ internal data class TypeAndDefaultQualifiers(
val defaultQualifiers: JavaDefaultQualifiers?
)
internal fun FirTypeRef.typeArguments(): List<FirTypeProjection> =
(this as? FirUserTypeRef)?.qualifier?.lastOrNull()?.typeArgumentList?.typeArguments.orEmpty()
internal fun FirTypeRef.typeArguments(): List<FirTypeProjection> = when (this) {
is FirUserTypeRef -> qualifier.lastOrNull()?.typeArgumentList?.typeArguments.orEmpty()
is FirResolvedTypeRef -> type.typeArguments.map {
when (it) {
is ConeStarProjection -> buildStarProjection {}
else -> {
val kind = it.kind
val type = when (it) {
is ConeKotlinTypeProjection -> it.type
is ConeKotlinType -> it
else -> error("Should not be here")
}
buildTypeProjectionWithVariance {
variance = when (kind) {
ProjectionKind.IN -> Variance.IN_VARIANCE
ProjectionKind.OUT -> Variance.OUT_VARIANCE
ProjectionKind.INVARIANT -> Variance.INVARIANT
else -> error("Should not be here")
}
typeRef = buildResolvedTypeRef {
this.type = type
}
}
}
}
}
else -> emptyList()
}
internal fun JavaType.typeArguments(): List<JavaType?> = (this as? JavaClassifierType)?.typeArguments.orEmpty()