Create first draft of AbstractStrictEqualityTypeChecker
This commit is contained in:
committed by
Simon Ogorodnik
parent
f7702d3e43
commit
be79aeafa7
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.types
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.types.model.KotlinTypeIM
|
||||||
|
import org.jetbrains.kotlin.types.model.SimpleTypeIM
|
||||||
|
import org.jetbrains.kotlin.types.model.TypeSystemContext
|
||||||
|
|
||||||
|
object AbstractStrictEqualityTypeChecker {
|
||||||
|
fun strictEqualTypes(context: TypeSystemContext, a: KotlinTypeIM, b: KotlinTypeIM) = context.strictEqualTypesInternal(a, b)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Note that:
|
||||||
|
* - `String!` != `String`
|
||||||
|
* - `A<String!>` != `A<String>`
|
||||||
|
* - `A<in Nothing>` != `A<out Any?>`
|
||||||
|
* - `A<*>` != `A<out Any?>`
|
||||||
|
*
|
||||||
|
* Also different error types are not equal even if errorTypeEqualToAnything is true
|
||||||
|
*/
|
||||||
|
private fun TypeSystemContext.strictEqualTypesInternal(a: KotlinTypeIM, b: KotlinTypeIM): Boolean {
|
||||||
|
if (a === b) return true
|
||||||
|
|
||||||
|
val simpleA = a.asSimpleType()
|
||||||
|
val simpleB = b.asSimpleType()
|
||||||
|
if (simpleA != null && simpleB != null) return strictEqualSimpleTypes(simpleA, simpleB)
|
||||||
|
|
||||||
|
val flexibleA = a.asFlexibleType()
|
||||||
|
val flexibleB = b.asFlexibleType()
|
||||||
|
if (flexibleA != null && flexibleB != null) {
|
||||||
|
return strictEqualSimpleTypes(flexibleA.lowerBound(), flexibleB.lowerBound()) &&
|
||||||
|
strictEqualSimpleTypes(flexibleA.upperBound(), flexibleB.upperBound())
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun TypeSystemContext.strictEqualSimpleTypes(a: SimpleTypeIM, b: SimpleTypeIM): Boolean {
|
||||||
|
if (a.isMarkedNullable() != b.isMarkedNullable()
|
||||||
|
|| (a.asDefinitelyNotNullType() == null) != (b.asDefinitelyNotNullType() == null)
|
||||||
|
|| !isEqualTypeConstructors(a.typeConstructor(), b.typeConstructor())
|
||||||
|
|| a.argumentsCount() != b.argumentsCount()
|
||||||
|
) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (a.arguments === b.arguments) return true
|
||||||
|
|
||||||
|
for (i in 0 until a.argumentsCount()) {
|
||||||
|
val aArg = a.getArgument(i)
|
||||||
|
val bArg = b.getArgument(i)
|
||||||
|
if (aArg.isStarProjection() != bArg.isStarProjection()) return false
|
||||||
|
|
||||||
|
// both non-star
|
||||||
|
if (!aArg.isStarProjection()) {
|
||||||
|
if (aArg.getVariance() != bArg.getVariance()) return false
|
||||||
|
if (!strictEqualTypesInternal(aArg.getType(), bArg.getType())) return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.types
|
||||||
|
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.types.model
|
||||||
|
|
||||||
|
interface KotlinTypeIM
|
||||||
|
interface TypeArgumentIM
|
||||||
|
interface TypeConstructorIM
|
||||||
|
interface TypeParameterIM
|
||||||
|
|
||||||
|
interface SimpleTypeIM : KotlinTypeIM
|
||||||
|
interface CapturedTypeIM : SimpleTypeIM
|
||||||
|
interface DefinitelyNotNullTypeIM : SimpleTypeIM
|
||||||
|
|
||||||
|
interface FlexibleTypeIM : KotlinTypeIM
|
||||||
|
interface DynamicTypeIM : FlexibleTypeIM
|
||||||
|
interface RawTypeIM : FlexibleTypeIM
|
||||||
|
|
||||||
|
|
||||||
|
enum class TypeVariance {
|
||||||
|
IN,
|
||||||
|
OUT,
|
||||||
|
INV
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TypeSystemContext {
|
||||||
|
fun KotlinTypeIM.asSimpleType(): SimpleTypeIM?
|
||||||
|
fun KotlinTypeIM.asFlexibleType(): FlexibleTypeIM?
|
||||||
|
|
||||||
|
fun FlexibleTypeIM.asDynamicType(): DynamicTypeIM?
|
||||||
|
fun FlexibleTypeIM.asRawType(): RawTypeIM?
|
||||||
|
|
||||||
|
fun FlexibleTypeIM.upperBound(): SimpleTypeIM
|
||||||
|
fun FlexibleTypeIM.lowerBound(): SimpleTypeIM
|
||||||
|
|
||||||
|
fun SimpleTypeIM.asCapturedType(): CapturedTypeIM?
|
||||||
|
fun SimpleTypeIM.asDefinitelyNotNullType(): DefinitelyNotNullTypeIM?
|
||||||
|
fun SimpleTypeIM.isMarkedNullable(): Boolean
|
||||||
|
fun SimpleTypeIM.typeConstructor(): TypeConstructorIM
|
||||||
|
|
||||||
|
fun SimpleTypeIM.argumentsCount(): Int
|
||||||
|
fun SimpleTypeIM.getArgument(index: Int): TypeArgumentIM
|
||||||
|
|
||||||
|
fun TypeArgumentIM.isStarProjection(): Boolean
|
||||||
|
fun TypeArgumentIM.getVariance(): TypeVariance
|
||||||
|
fun TypeArgumentIM.getType(): KotlinTypeIM
|
||||||
|
|
||||||
|
fun TypeConstructorIM.isErrorTypeConstructor(): Boolean
|
||||||
|
fun TypeConstructorIM.parametersCount(): Int
|
||||||
|
fun TypeConstructorIM.getParameter(index: Int): TypeParameterIM
|
||||||
|
fun TypeConstructorIM.supertypesCount(): Int
|
||||||
|
fun TypeConstructorIM.getSupertype(index: Int): KotlinTypeIM
|
||||||
|
|
||||||
|
fun TypeParameterIM.getVariance(): TypeVariance
|
||||||
|
fun TypeParameterIM.upperBoundCount(): Int
|
||||||
|
fun TypeParameterIM.getUpperBound(index: Int): KotlinTypeIM
|
||||||
|
fun TypeParameterIM.getTypeConstructor(): TypeConstructorIM
|
||||||
|
|
||||||
|
fun isEqualTypeConstructors(c1: TypeConstructorIM, c2: TypeConstructorIM): Boolean
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user