Support @EnhancedNullability in psi2ir
This commit is contained in:
+5
@@ -1670,6 +1670,11 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest {
|
|||||||
runTest("compiler/testData/ir/irText/types/asOnPlatformType.kt");
|
runTest("compiler/testData/ir/irText/types/asOnPlatformType.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("enhancedNullability.kt")
|
||||||
|
public void testEnhancedNullability() throws Exception {
|
||||||
|
runTest("compiler/testData/ir/irText/types/enhancedNullability.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.kt")
|
@TestMetadata("explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.kt")
|
||||||
public void testExplicitEqualsAndCompareToCallsOnPlatformTypeReceiver() throws Exception {
|
public void testExplicitEqualsAndCompareToCallsOnPlatformTypeReceiver() throws Exception {
|
||||||
runTest("compiler/testData/ir/irText/types/explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.kt");
|
runTest("compiler/testData/ir/irText/types/explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.kt");
|
||||||
|
|||||||
+24
@@ -10,14 +10,17 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.FilteredAnnotations
|
||||||
import org.jetbrains.kotlin.ir.builders.declarations.buildClass
|
import org.jetbrains.kotlin.ir.builders.declarations.buildClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||||
|
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
|
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
||||||
import org.jetbrains.kotlin.load.java.sam.SamAdapterDescriptor
|
import org.jetbrains.kotlin.load.java.sam.SamAdapterDescriptor
|
||||||
import org.jetbrains.kotlin.load.java.sam.SamConstructorDescriptor
|
import org.jetbrains.kotlin.load.java.sam.SamConstructorDescriptor
|
||||||
import org.jetbrains.kotlin.load.java.sam.SingleAbstractMethodUtils
|
import org.jetbrains.kotlin.load.java.sam.SingleAbstractMethodUtils
|
||||||
|
import org.jetbrains.kotlin.load.java.typeEnhancement.hasEnhancedNullability
|
||||||
import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource
|
import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource
|
||||||
import org.jetbrains.kotlin.psi2ir.generators.GeneratorExtensions
|
import org.jetbrains.kotlin.psi2ir.generators.GeneratorExtensions
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||||
@@ -27,6 +30,7 @@ import org.jetbrains.kotlin.synthetic.SamAdapterExtensionFunctionDescriptor
|
|||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.replaceAnnotations
|
||||||
|
|
||||||
class JvmGeneratorExtensions(private val generateFacades: Boolean = true) : GeneratorExtensions() {
|
class JvmGeneratorExtensions(private val generateFacades: Boolean = true) : GeneratorExtensions() {
|
||||||
val classNameOverride = mutableMapOf<IrClass, JvmClassName>()
|
val classNameOverride = mutableMapOf<IrClass, JvmClassName>()
|
||||||
@@ -88,4 +92,24 @@ class JvmGeneratorExtensions(private val generateFacades: Boolean = true) : Gene
|
|||||||
|
|
||||||
override fun isPropertyWithPlatformField(descriptor: PropertyDescriptor): Boolean =
|
override fun isPropertyWithPlatformField(descriptor: PropertyDescriptor): Boolean =
|
||||||
descriptor.hasJvmFieldAnnotation()
|
descriptor.hasJvmFieldAnnotation()
|
||||||
|
|
||||||
|
override val enhancedNullability: EnhancedNullability
|
||||||
|
get() = JvmEnhancedNullability
|
||||||
|
|
||||||
|
open class JvmEnhancedNullability : EnhancedNullability() {
|
||||||
|
override fun hasEnhancedNullability(kotlinType: KotlinType): Boolean =
|
||||||
|
kotlinType.hasEnhancedNullability()
|
||||||
|
|
||||||
|
override fun stripEnhancedNullability(kotlinType: KotlinType): KotlinType =
|
||||||
|
if (kotlinType.hasEnhancedNullability())
|
||||||
|
kotlinType.replaceAnnotations(
|
||||||
|
FilteredAnnotations(kotlinType.annotations, true) {
|
||||||
|
it != JvmAnnotationNames.ENHANCED_NULLABILITY_ANNOTATION
|
||||||
|
}
|
||||||
|
)
|
||||||
|
else
|
||||||
|
kotlinType
|
||||||
|
|
||||||
|
companion object Instance : JvmEnhancedNullability()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+12
@@ -30,4 +30,16 @@ open class GeneratorExtensions : StubGeneratorExtensions() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
open fun computeFieldVisibility(descriptor: PropertyDescriptor): Visibility? = null
|
open fun computeFieldVisibility(descriptor: PropertyDescriptor): Visibility? = null
|
||||||
|
|
||||||
|
open val enhancedNullability: EnhancedNullability
|
||||||
|
get() = EnhancedNullability
|
||||||
|
|
||||||
|
open class EnhancedNullability {
|
||||||
|
open fun hasEnhancedNullability(kotlinType: KotlinType): Boolean = false
|
||||||
|
|
||||||
|
open fun stripEnhancedNullability(kotlinType: KotlinType): KotlinType = kotlinType
|
||||||
|
|
||||||
|
companion object Instance : EnhancedNullability()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-5
@@ -50,7 +50,7 @@ fun insertImplicitCasts(element: IrElement, context: GeneratorContext) {
|
|||||||
context.irBuiltIns,
|
context.irBuiltIns,
|
||||||
context.typeTranslator,
|
context.typeTranslator,
|
||||||
context.callToSubstitutedDescriptorMap,
|
context.callToSubstitutedDescriptorMap,
|
||||||
context.extensions.samConversion
|
context.extensions
|
||||||
),
|
),
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
@@ -61,7 +61,7 @@ open class InsertImplicitCasts(
|
|||||||
private val irBuiltIns: IrBuiltIns,
|
private val irBuiltIns: IrBuiltIns,
|
||||||
private val typeTranslator: TypeTranslator,
|
private val typeTranslator: TypeTranslator,
|
||||||
private val callToSubstitutedDescriptorMap: Map<IrMemberAccessExpression, CallableDescriptor>,
|
private val callToSubstitutedDescriptorMap: Map<IrMemberAccessExpression, CallableDescriptor>,
|
||||||
private val samConversion: GeneratorExtensions.SamConversion
|
private val generatorExtensions: GeneratorExtensions
|
||||||
) : IrElementTransformerVoid() {
|
) : IrElementTransformerVoid() {
|
||||||
|
|
||||||
private fun KotlinType.toIrType() = typeTranslator.translateType(this)
|
private fun KotlinType.toIrType() = typeTranslator.translateType(this)
|
||||||
@@ -191,10 +191,13 @@ open class InsertImplicitCasts(
|
|||||||
finallyExpression = finallyExpression?.coerceToUnit()
|
finallyExpression = finallyExpression?.coerceToUnit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun KotlinType.getSubstitutedFunctionTypeForSamType() =
|
||||||
|
generatorExtensions.samConversion.getSubstitutedFunctionTypeForSamType(this)
|
||||||
|
|
||||||
override fun visitTypeOperator(expression: IrTypeOperatorCall): IrExpression =
|
override fun visitTypeOperator(expression: IrTypeOperatorCall): IrExpression =
|
||||||
when (expression.operator) {
|
when (expression.operator) {
|
||||||
IrTypeOperator.SAM_CONVERSION -> expression.transformPostfix {
|
IrTypeOperator.SAM_CONVERSION -> expression.transformPostfix {
|
||||||
argument = argument.cast(samConversion.getSubstitutedFunctionTypeForSamType(typeOperand.originalKotlinType!!))
|
argument = argument.cast(typeOperand.originalKotlinType!!.getSubstitutedFunctionTypeForSamType())
|
||||||
}
|
}
|
||||||
|
|
||||||
IrTypeOperator.IMPLICIT_CAST -> {
|
IrTypeOperator.IMPLICIT_CAST -> {
|
||||||
@@ -251,7 +254,8 @@ open class InsertImplicitCasts(
|
|||||||
else
|
else
|
||||||
implicitCast(expectedType, IrTypeOperator.IMPLICIT_DYNAMIC_CAST)
|
implicitCast(expectedType, IrTypeOperator.IMPLICIT_DYNAMIC_CAST)
|
||||||
|
|
||||||
valueType.isNullabilityFlexible() && valueType.containsNull() && !expectedType.containsNull() ->
|
(valueType.isNullabilityFlexible() && valueType.containsNull() || valueType.hasEnhancedNullability()) &&
|
||||||
|
!expectedType.containsNull() ->
|
||||||
implicitNonNull(valueType, expectedType)
|
implicitNonNull(valueType, expectedType)
|
||||||
|
|
||||||
KotlinTypeChecker.DEFAULT.isSubtypeOf(valueType, expectedType.makeNullable()) ->
|
KotlinTypeChecker.DEFAULT.isSubtypeOf(valueType, expectedType.makeNullable()) ->
|
||||||
@@ -267,8 +271,12 @@ open class InsertImplicitCasts(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun KotlinType.hasEnhancedNullability() =
|
||||||
|
generatorExtensions.enhancedNullability.hasEnhancedNullability(this)
|
||||||
|
|
||||||
private fun IrExpression.implicitNonNull(valueType: KotlinType, expectedType: KotlinType): IrExpression {
|
private fun IrExpression.implicitNonNull(valueType: KotlinType, expectedType: KotlinType): IrExpression {
|
||||||
val nonNullValueType = valueType.upperIfFlexible().makeNotNullable()
|
val nonNullFlexibleType = valueType.upperIfFlexible().makeNotNullable()
|
||||||
|
val nonNullValueType = generatorExtensions.enhancedNullability.stripEnhancedNullability(nonNullFlexibleType)
|
||||||
return implicitCast(nonNullValueType, IrTypeOperator.IMPLICIT_NOTNULL).cast(expectedType)
|
return implicitCast(nonNullValueType, IrTypeOperator.IMPLICIT_NOTNULL).cast(expectedType)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
-1
@@ -1,7 +1,6 @@
|
|||||||
// !API_VERSION: LATEST
|
// !API_VERSION: LATEST
|
||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
// IGNORE_BACKEND_FIR: JVM_IR
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// FILE: A.java
|
// FILE: A.java
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
FILE fqName:<root> fileName:/enhancedNullability.kt
|
||||||
|
FUN name:use visibility:public modality:FINAL <> (s:kotlin.String) returnType:kotlin.Unit
|
||||||
|
VALUE_PARAMETER name:s index:0 type:kotlin.String
|
||||||
|
BLOCK_BODY
|
||||||
|
FUN name:testUse visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||||
|
BLOCK_BODY
|
||||||
|
CALL 'public final fun use (s: kotlin.String): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||||
|
s: CALL 'public open fun s (): kotlin.String [operator] declared in <root>.J' type=kotlin.String origin=null
|
||||||
|
FUN name:testLocalVal visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||||
|
BLOCK_BODY
|
||||||
|
VAR name:local type:kotlin.String [val]
|
||||||
|
CALL 'public open fun s (): kotlin.String [operator] declared in <root>.J' type=kotlin.String origin=null
|
||||||
|
FUN name:testReturnValue visibility:public modality:FINAL <> () returnType:kotlin.String
|
||||||
|
BLOCK_BODY
|
||||||
|
RETURN type=kotlin.Nothing from='public final fun testReturnValue (): kotlin.String declared in <root>'
|
||||||
|
CALL 'public open fun s (): kotlin.String [operator] declared in <root>.J' type=kotlin.String origin=null
|
||||||
|
PROPERTY name:testGlobalVal visibility:public modality:FINAL [val]
|
||||||
|
FIELD PROPERTY_BACKING_FIELD name:testGlobalVal type:kotlin.String visibility:private [final,static]
|
||||||
|
EXPRESSION_BODY
|
||||||
|
CALL 'public open fun s (): kotlin.String [operator] declared in <root>.J' type=kotlin.String origin=null
|
||||||
|
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-testGlobalVal> visibility:public modality:FINAL <> () returnType:kotlin.String
|
||||||
|
correspondingProperty: PROPERTY name:testGlobalVal visibility:public modality:FINAL [val]
|
||||||
|
BLOCK_BODY
|
||||||
|
RETURN type=kotlin.Nothing from='public final fun <get-testGlobalVal> (): kotlin.String declared in <root>'
|
||||||
|
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:testGlobalVal type:kotlin.String visibility:private [final,static]' type=kotlin.String origin=null
|
||||||
|
PROPERTY name:testGlobalValGetter visibility:public modality:FINAL [val]
|
||||||
|
FUN name:<get-testGlobalValGetter> visibility:public modality:FINAL <> () returnType:kotlin.String
|
||||||
|
correspondingProperty: PROPERTY name:testGlobalValGetter visibility:public modality:FINAL [val]
|
||||||
|
BLOCK_BODY
|
||||||
|
RETURN type=kotlin.Nothing from='public final fun <get-testGlobalValGetter> (): kotlin.String declared in <root>'
|
||||||
|
CALL 'public open fun s (): kotlin.String [operator] declared in <root>.J' type=kotlin.String origin=null
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
// FILE: enhancedNullability.kt
|
||||||
|
fun use(s: String) {}
|
||||||
|
|
||||||
|
fun testUse() {
|
||||||
|
use(J.s())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testLocalVal() {
|
||||||
|
val local = J.s()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testReturnValue() = J.s()
|
||||||
|
|
||||||
|
val testGlobalVal = J.s()
|
||||||
|
|
||||||
|
val testGlobalValGetter get() = J.s()
|
||||||
|
|
||||||
|
// FILE: J.java
|
||||||
|
import org.jetbrains.annotations.*
|
||||||
|
|
||||||
|
public class J {
|
||||||
|
public static @NotNull String s() { return null; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
FILE fqName:<root> fileName:/enhancedNullability.kt
|
||||||
|
FUN name:use visibility:public modality:FINAL <> (s:kotlin.String) returnType:kotlin.Unit
|
||||||
|
VALUE_PARAMETER name:s index:0 type:kotlin.String
|
||||||
|
BLOCK_BODY
|
||||||
|
FUN name:testUse visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||||
|
BLOCK_BODY
|
||||||
|
CALL 'public final fun use (s: kotlin.String): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||||
|
s: TYPE_OP type=kotlin.String origin=IMPLICIT_NOTNULL typeOperand=kotlin.String
|
||||||
|
CALL 'public open fun s (): kotlin.String declared in <root>.J' type=kotlin.String origin=null
|
||||||
|
FUN name:testLocalVal visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||||
|
BLOCK_BODY
|
||||||
|
VAR name:local type:kotlin.String [val]
|
||||||
|
TYPE_OP type=kotlin.String origin=IMPLICIT_NOTNULL typeOperand=kotlin.String
|
||||||
|
CALL 'public open fun s (): kotlin.String declared in <root>.J' type=kotlin.String origin=null
|
||||||
|
FUN name:testReturnValue visibility:public modality:FINAL <> () returnType:kotlin.String
|
||||||
|
BLOCK_BODY
|
||||||
|
RETURN type=kotlin.Nothing from='public final fun testReturnValue (): kotlin.String declared in <root>'
|
||||||
|
TYPE_OP type=kotlin.String origin=IMPLICIT_NOTNULL typeOperand=kotlin.String
|
||||||
|
CALL 'public open fun s (): kotlin.String declared in <root>.J' type=kotlin.String origin=null
|
||||||
|
PROPERTY name:testGlobalVal visibility:public modality:FINAL [val]
|
||||||
|
FIELD PROPERTY_BACKING_FIELD name:testGlobalVal type:kotlin.String visibility:private [final,static]
|
||||||
|
EXPRESSION_BODY
|
||||||
|
TYPE_OP type=kotlin.String origin=IMPLICIT_NOTNULL typeOperand=kotlin.String
|
||||||
|
CALL 'public open fun s (): kotlin.String declared in <root>.J' type=kotlin.String origin=null
|
||||||
|
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-testGlobalVal> visibility:public modality:FINAL <> () returnType:kotlin.String
|
||||||
|
correspondingProperty: PROPERTY name:testGlobalVal visibility:public modality:FINAL [val]
|
||||||
|
BLOCK_BODY
|
||||||
|
RETURN type=kotlin.Nothing from='public final fun <get-testGlobalVal> (): kotlin.String declared in <root>'
|
||||||
|
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:testGlobalVal type:kotlin.String visibility:private [final,static]' type=kotlin.String origin=null
|
||||||
|
PROPERTY name:testGlobalValGetter visibility:public modality:FINAL [val]
|
||||||
|
FUN name:<get-testGlobalValGetter> visibility:public modality:FINAL <> () returnType:kotlin.String
|
||||||
|
correspondingProperty: PROPERTY name:testGlobalValGetter visibility:public modality:FINAL [val]
|
||||||
|
BLOCK_BODY
|
||||||
|
RETURN type=kotlin.Nothing from='public final fun <get-testGlobalValGetter> (): kotlin.String declared in <root>'
|
||||||
|
TYPE_OP type=kotlin.String origin=IMPLICIT_NOTNULL typeOperand=kotlin.String
|
||||||
|
CALL 'public open fun s (): kotlin.String declared in <root>.J' type=kotlin.String origin=null
|
||||||
@@ -1670,6 +1670,11 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
|
|||||||
runTest("compiler/testData/ir/irText/types/asOnPlatformType.kt");
|
runTest("compiler/testData/ir/irText/types/asOnPlatformType.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("enhancedNullability.kt")
|
||||||
|
public void testEnhancedNullability() throws Exception {
|
||||||
|
runTest("compiler/testData/ir/irText/types/enhancedNullability.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.kt")
|
@TestMetadata("explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.kt")
|
||||||
public void testExplicitEqualsAndCompareToCallsOnPlatformTypeReceiver() throws Exception {
|
public void testExplicitEqualsAndCompareToCallsOnPlatformTypeReceiver() throws Exception {
|
||||||
runTest("compiler/testData/ir/irText/types/explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.kt");
|
runTest("compiler/testData/ir/irText/types/explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user