[JS IR BE] Make tests work

This commit is contained in:
Roman Artemev
2019-04-16 18:57:18 +03:00
committed by Dmitry Petrov
parent 760806a1ac
commit 6a82ffdc5e
5 changed files with 30 additions and 17 deletions
@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.psi2ir.generators.GeneratorExtensions
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.isDynamic import org.jetbrains.kotlin.types.isDynamic
import org.jetbrains.kotlin.types.isNullabilityFlexible import org.jetbrains.kotlin.types.isNullabilityFlexible
import org.jetbrains.kotlin.types.typeUtil.isUnit
fun insertImplicitCasts(element: IrElement, context: GeneratorContext) { fun insertImplicitCasts(element: IrElement, context: GeneratorContext) {
element.transformChildren( element.transformChildren(
@@ -279,15 +280,14 @@ open class InsertImplicitCasts(
val valueType = this.type val valueType = this.type
val valueKotlinType = valueType.originalKotlinType!! val valueKotlinType = valueType.originalKotlinType!!
val expectedKotlinType = expectedType.originalKotlinType!!
return when { return when {
expectedType.isUnit() -> { expectedType.isUnit() -> {
expectedType.originalKotlinType?.let { require(it.isUnit()) }
coerceToUnit() coerceToUnit()
} }
valueType is IrDynamicType && expectedType !is IrDynamicType -> { valueType is IrDynamicType && expectedType !is IrDynamicType -> {
require(valueKotlinType.isDynamic() && !expectedKotlinType.isDynamic())
if (expectedType.isNullableAny()) { if (expectedType.isNullableAny()) {
this this
} else { } else {
@@ -339,8 +339,7 @@ open class InsertImplicitCasts(
} }
protected open fun IrExpression.coerceToUnit(): IrExpression { protected open fun IrExpression.coerceToUnit(): IrExpression {
val valueType = getKotlinType(this) return coerceToUnitIfNeeded(type, irBuiltIns)
return coerceToUnitIfNeeded(valueType, irBuiltIns)
} }
protected fun getKotlinType(irExpression: IrExpression) = protected fun getKotlinType(irExpression: IrExpression) =
@@ -27,10 +27,12 @@ class IrTypeSubstitutor(
if (substitution.isEmpty()) return type if (substitution.isEmpty()) return type
return type.typeParameterConstructor()?.let { return type.typeParameterConstructor()?.let {
// check whether it's T or T?
val isNullable = type.isMarkedNullable()
val typeArgument = substitution.getValue(it) val typeArgument = substitution.getValue(it)
when (typeArgument) { when (typeArgument) {
is IrStarProjection -> irBuiltIns.anyNType is IrStarProjection -> if (isNullable) irBuiltIns.anyNType else irBuiltIns.anyType
is IrTypeProjection -> typeArgument.type is IrTypeProjection -> with(typeArgument.type) { if (isNullable) makeNullable() else makeNotNull() }
else -> error("unknown type argument") else -> error("unknown type argument")
} }
} ?: substituteType(type) } ?: substituteType(type)
@@ -61,7 +63,7 @@ class IrTypeSubstitutor(
if (classifier is IrTypeParameterSymbol) { if (classifier is IrTypeParameterSymbol) {
val newArgument = substitution.getValue(classifier) val newArgument = substitution.getValue(classifier)
return if (newArgument is IrTypeProjection) { return if (newArgument is IrTypeProjection) {
makeTypeProjection(newArgument.type, TypeSubstitutor.combine(typeArgument.variance, newArgument.variance)) makeTypeProjection(newArgument.type, typeArgument.variance)
} else newArgument } else newArgument
} }
} }
@@ -330,21 +330,23 @@ interface IrTypeSystemContext : TypeSystemInferenceExtensionContext {
makeTypeIntersection(types as List<IrType>) makeTypeIntersection(types as List<IrType>)
} }
fun extractTypeParameters(klass: IrTypeParametersContainer): List<IrTypeParameter> { fun extractTypeParameters(klass: IrDeclarationParent): List<IrTypeParameter> {
val result = mutableListOf<IrTypeParameter>() val result = mutableListOf<IrTypeParameter>()
var current: IrTypeParametersContainer? = klass var current: IrDeclarationParent? = klass
while (current != null) { while (current != null) {
result += current.typeParameters // result += current.typeParameters
(current as? IrTypeParametersContainer)?.let { result += it.typeParameters }
current = current =
when (current) { when (current) {
is IrField -> current.parent
is IrClass -> when { is IrClass -> when {
current.isInner -> current.parent as IrClass current.isInner -> current.parent as IrClass
current.visibility == Visibilities.LOCAL -> current.parent as? IrTypeParametersContainer current.visibility == Visibilities.LOCAL -> current.parent
else -> null else -> null
} }
is IrConstructor -> current.parent as IrClass is IrConstructor -> current.parent as IrClass
is IrFunction -> if (current.visibility == Visibilities.LOCAL || current.dispatchReceiverParameter != null) { is IrFunction -> if (current.visibility == Visibilities.LOCAL || current.dispatchReceiverParameter != null) {
current.parent as? IrTypeParametersContainer current.parent
} else null } else null
else -> null else -> null
} }
@@ -102,5 +102,5 @@ fun makeTypeProjection(type: IrType, variance: Variance): IrTypeProjection =
fun makeTypeIntersection(types: List<IrType>): IrType = fun makeTypeIntersection(types: List<IrType>): IrType =
with(types.map { makeTypeProjection(it, Variance.INVARIANT).type }.distinct()) { with(types.map { makeTypeProjection(it, Variance.INVARIANT).type }.distinct()) {
if (size == 1) return single() if (size == 1) return single()
else first { !(it.isAny() || it.isNullableAny()) } else firstOrNull { !(it.isAny() || it.isNullableAny()) } ?: first { it.isAny() }
} }
@@ -15,10 +15,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl
import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.types.IrSimpleType import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.types.classifierOrFail
import org.jetbrains.kotlin.ir.types.isAny
import org.jetbrains.kotlin.ir.types.toKotlinType
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.name.SpecialNames
@@ -162,6 +159,19 @@ fun IrExpression.coerceToUnitIfNeeded(valueType: KotlinType, irBuiltIns: IrBuilt
) )
} }
fun IrExpression.coerceToUnitIfNeeded(valueType: IrType, irBuiltIns: IrBuiltIns): IrExpression {
return if (valueType.isSubtypeOf(irBuiltIns.unitType, irBuiltIns))
this
else
IrTypeOperatorCallImpl(
startOffset, endOffset,
irBuiltIns.unitType,
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT,
irBuiltIns.unitType, irBuiltIns.unitType.classifierOrFail,
this
)
}
fun IrMemberAccessExpression.usesDefaultArguments(): Boolean = fun IrMemberAccessExpression.usesDefaultArguments(): Boolean =
this.descriptor.valueParameters.any { this.getValueArgument(it) == null } this.descriptor.valueParameters.any { this.getValueArgument(it) == null }