'val' in 'when': IEEE754 equality
This commit is contained in:
@@ -10,9 +10,9 @@ import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
|||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.psi.KtExpression
|
import org.jetbrains.kotlin.psi.KtExpression
|
||||||
|
import org.jetbrains.kotlin.psi.KtProperty
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfoBefore
|
import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfoBefore
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactoryImpl
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactoryImpl
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
@@ -28,20 +28,26 @@ fun calcProperTypeForIeee754ArithmeticIfNeeded(
|
|||||||
typeMapper: KotlinTypeMapper
|
typeMapper: KotlinTypeMapper
|
||||||
): TypeAndNullability? {
|
): TypeAndNullability? {
|
||||||
if (inferredPrimitiveType == null) return null
|
if (inferredPrimitiveType == null) return null
|
||||||
val ktType = expression.kotlinType(bindingContext) ?: return null
|
val ktType = expression.getKotlinTypeForComparison(bindingContext) ?: return null
|
||||||
val isNullable = TypeUtils.isNullableType(ktType)
|
val isNullable = TypeUtils.isNullableType(ktType)
|
||||||
val asmType = typeMapper.mapType(inferredPrimitiveType)
|
val asmType = typeMapper.mapType(inferredPrimitiveType)
|
||||||
if (!AsmUtil.isPrimitive(asmType)) return null
|
if (!AsmUtil.isPrimitive(asmType)) return null
|
||||||
return TypeAndNullability(asmType, isNullable)
|
return TypeAndNullability(asmType, isNullable)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun KtExpression.getKotlinTypeForComparison(bindingContext: BindingContext): KotlinType? =
|
||||||
|
when {
|
||||||
|
this is KtProperty -> bindingContext[BindingContext.VARIABLE, this]?.type
|
||||||
|
else -> kotlinType(bindingContext)
|
||||||
|
}
|
||||||
|
|
||||||
fun legacyCalcTypeForIeee754ArithmeticIfNeeded(
|
fun legacyCalcTypeForIeee754ArithmeticIfNeeded(
|
||||||
expression: KtExpression?,
|
expression: KtExpression?,
|
||||||
bindingContext: BindingContext,
|
bindingContext: BindingContext,
|
||||||
descriptor: DeclarationDescriptor,
|
descriptor: DeclarationDescriptor,
|
||||||
languageVersionSettings: LanguageVersionSettings
|
languageVersionSettings: LanguageVersionSettings
|
||||||
): TypeAndNullability? {
|
): TypeAndNullability? {
|
||||||
val ktType = expression.kotlinType(bindingContext) ?: return null
|
val ktType = expression?.getKotlinTypeForComparison(bindingContext) ?: return null
|
||||||
|
|
||||||
if (KotlinBuiltIns.isDoubleOrNullableDouble(ktType)) {
|
if (KotlinBuiltIns.isDoubleOrNullableDouble(ktType)) {
|
||||||
return TypeAndNullability(
|
return TypeAndNullability(
|
||||||
@@ -59,7 +65,7 @@ fun legacyCalcTypeForIeee754ArithmeticIfNeeded(
|
|||||||
|
|
||||||
// NB. Using DataFlowValueFactoryImpl is a hack, but it is ok for 'legacy'
|
// NB. Using DataFlowValueFactoryImpl is a hack, but it is ok for 'legacy'
|
||||||
val dataFlow = DataFlowValueFactoryImpl().createDataFlowValue(
|
val dataFlow = DataFlowValueFactoryImpl().createDataFlowValue(
|
||||||
expression!!,
|
expression,
|
||||||
ktType,
|
ktType,
|
||||||
bindingContext,
|
bindingContext,
|
||||||
descriptor
|
descriptor
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
// !LANGUAGE: +VariableDeclarationInWhenSubject
|
||||||
|
// IGNORE_BACKEND: JS
|
||||||
|
|
||||||
|
val dz = -0.0
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
when (val y = dz) {
|
||||||
|
0.0 -> {}
|
||||||
|
else -> throw AssertionError()
|
||||||
|
}
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
// !LANGUAGE: +VariableDeclarationInWhenSubject +ProperIeee754Comparisons
|
||||||
|
// IGNORE_BACKEND: JS
|
||||||
|
|
||||||
|
val az: Any = -0.0
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
when (val y = az) {
|
||||||
|
!is Double -> throw AssertionError()
|
||||||
|
0.0 -> {}
|
||||||
|
else -> throw AssertionError()
|
||||||
|
}
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
Generated
+10
@@ -21673,6 +21673,16 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/equalityWithSubjectVariable.kt");
|
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/equalityWithSubjectVariable.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ieee754Equality.kt")
|
||||||
|
public void testIeee754Equality() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/ieee754Equality.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ieee754EqualityWithSmartCast.kt")
|
||||||
|
public void testIeee754EqualityWithSmartCast() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/ieee754EqualityWithSmartCast.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("isCheckOnSubjectVariable.kt")
|
@TestMetadata("isCheckOnSubjectVariable.kt")
|
||||||
public void testIsCheckOnSubjectVariable() throws Exception {
|
public void testIsCheckOnSubjectVariable() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/isCheckOnSubjectVariable.kt");
|
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/isCheckOnSubjectVariable.kt");
|
||||||
|
|||||||
+10
@@ -21673,6 +21673,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/equalityWithSubjectVariable.kt");
|
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/equalityWithSubjectVariable.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ieee754Equality.kt")
|
||||||
|
public void testIeee754Equality() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/ieee754Equality.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ieee754EqualityWithSmartCast.kt")
|
||||||
|
public void testIeee754EqualityWithSmartCast() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/ieee754EqualityWithSmartCast.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("isCheckOnSubjectVariable.kt")
|
@TestMetadata("isCheckOnSubjectVariable.kt")
|
||||||
public void testIsCheckOnSubjectVariable() throws Exception {
|
public void testIsCheckOnSubjectVariable() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/isCheckOnSubjectVariable.kt");
|
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/isCheckOnSubjectVariable.kt");
|
||||||
|
|||||||
+10
@@ -21673,6 +21673,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/equalityWithSubjectVariable.kt");
|
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/equalityWithSubjectVariable.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ieee754Equality.kt")
|
||||||
|
public void testIeee754Equality() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/ieee754Equality.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ieee754EqualityWithSmartCast.kt")
|
||||||
|
public void testIeee754EqualityWithSmartCast() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/ieee754EqualityWithSmartCast.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("isCheckOnSubjectVariable.kt")
|
@TestMetadata("isCheckOnSubjectVariable.kt")
|
||||||
public void testIsCheckOnSubjectVariable() throws Exception {
|
public void testIsCheckOnSubjectVariable() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/isCheckOnSubjectVariable.kt");
|
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/isCheckOnSubjectVariable.kt");
|
||||||
|
|||||||
+10
@@ -19566,6 +19566,16 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/equalityWithSubjectVariable.kt");
|
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/equalityWithSubjectVariable.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ieee754Equality.kt")
|
||||||
|
public void testIeee754Equality() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/ieee754Equality.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ieee754EqualityWithSmartCast.kt")
|
||||||
|
public void testIeee754EqualityWithSmartCast() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/ieee754EqualityWithSmartCast.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("isCheckOnSubjectVariable.kt")
|
@TestMetadata("isCheckOnSubjectVariable.kt")
|
||||||
public void testIsCheckOnSubjectVariable() throws Exception {
|
public void testIsCheckOnSubjectVariable() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/isCheckOnSubjectVariable.kt");
|
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/isCheckOnSubjectVariable.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user