提交 3950dec4 编写于 作者: S Simon Ogorodnik 提交者: Mikhail Glukhikh

Implement TypeSystemContext for FIR #KT-29968 Fixed

Use this context in FirClassUseSiteScope for type comparison
上级 85cd4f3c
......@@ -6,10 +6,13 @@
package org.jetbrains.kotlin.fir.symbols
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
import org.jetbrains.kotlin.types.model.TypeParameterMarker
interface ConeSymbol
interface ConeSymbol : TypeConstructorMarker
interface ConeClassifierSymbol : ConeSymbol {
interface ConeClassifierSymbol : ConeSymbol, TypeParameterMarker {
fun toLookupTag(): ConeClassifierLookupTag
}
......@@ -17,7 +20,7 @@ interface ConeTypeParameterSymbol : ConeClassifierSymbol, ConeTypeParameterLooku
override fun toLookupTag(): ConeTypeParameterLookupTag = this
}
interface ConeClassLikeSymbol : ConeClassifierSymbol {
interface ConeClassLikeSymbol : ConeClassifierSymbol, TypeConstructorMarker {
val classId: ClassId
override fun toLookupTag(): ConeClassLikeLookupTag
......
......@@ -6,8 +6,9 @@
package org.jetbrains.kotlin.fir.types
import org.jetbrains.kotlin.fir.symbols.*
import org.jetbrains.kotlin.types.model.*
sealed class ConeKotlinTypeProjection {
sealed class ConeKotlinTypeProjection : TypeArgumentMarker {
abstract val kind: ProjectionKind
companion object {
......@@ -19,7 +20,7 @@ enum class ProjectionKind {
STAR, IN, OUT, INVARIANT
}
object StarProjection : ConeKotlinTypeProjection() {
object ConeStarProjection : ConeKotlinTypeProjection() {
override val kind: ProjectionKind
get() = ProjectionKind.STAR
}
......@@ -52,7 +53,7 @@ enum class ConeNullability(val suffix: String) {
// We assume type IS an invariant type projection to prevent additional wrapper here
// (more exactly, invariant type projection contains type)
sealed class ConeKotlinType : ConeKotlinTypeProjection(), ConeTypedProjection {
sealed class ConeKotlinType : ConeKotlinTypeProjection(), ConeTypedProjection, KotlinTypeMarker, TypeArgumentListMarker {
override val kind: ProjectionKind
get() = ProjectionKind.INVARIANT
......@@ -91,14 +92,16 @@ class ConeClassErrorType(val reason: String) : ConeClassLikeType() {
}
}
sealed class ConeLookupTagBasedType : ConeKotlinType() {
sealed class ConeLookupTagBasedType : ConeKotlinType(), SimpleTypeMarker {
abstract val lookupTag: ConeClassifierLookupTag
}
abstract class ConeClassLikeType : ConeLookupTagBasedType() {
sealed class ConeClassLikeType : ConeLookupTagBasedType() {
abstract override val lookupTag: ConeClassLikeLookupTag
}
abstract class ConeClassType : ConeClassLikeType()
abstract class ConeAbbreviatedType : ConeClassLikeType() {
abstract val abbreviationLookupTag: ConeClassLikeLookupTag
......@@ -118,7 +121,7 @@ abstract class ConeFunctionType : ConeClassLikeType() {
abstract val returnType: ConeKotlinType
}
class ConeFlexibleType(val lowerBound: ConeKotlinType, val upperBound: ConeKotlinType) : ConeKotlinType() {
class ConeFlexibleType(val lowerBound: ConeLookupTagBasedType, val upperBound: ConeLookupTagBasedType) : ConeKotlinType(), FlexibleTypeMarker {
override val typeArguments: Array<out ConeKotlinTypeProjection>
get() = emptyArray()
......
......@@ -11,15 +11,15 @@ import org.jetbrains.kotlin.fir.types.*
open class ConeClassTypeImpl(
override val lookupTag: ConeClassLikeLookupTag,
override val typeArguments: Array<ConeKotlinTypeProjection>,
override val typeArguments: Array<out ConeKotlinTypeProjection>,
isNullable: Boolean
) : ConeClassLikeType() {
) : ConeClassType() {
override val nullability: ConeNullability = ConeNullability.create(isNullable)
}
class ConeAbbreviatedTypeImpl(
override val abbreviationLookupTag: ConeClassLikeLookupTag,
override val typeArguments: Array<ConeKotlinTypeProjection>,
override val typeArguments: Array<out ConeKotlinTypeProjection>,
override val directExpansion: ConeClassLikeType,
isNullable: Boolean
) : ConeAbbreviatedType() {
......
......@@ -136,7 +136,7 @@ class JavaSymbolProvider(
}
}
private fun flexibleType(create: (isNullable: Boolean) -> ConeKotlinType): ConeFlexibleType {
private fun flexibleType(create: (isNullable: Boolean) -> ConeLookupTagBasedType): ConeFlexibleType {
return ConeFlexibleType(create(false), create(true))
}
......
......@@ -121,7 +121,7 @@ class FirTypeDeserializer(
private fun typeArgument(typeArgumentProto: ProtoBuf.Type.Argument): ConeKotlinTypeProjection {
if (typeArgumentProto.projection == ProtoBuf.Type.Argument.Projection.STAR) {
return StarProjection
return ConeStarProjection
}
val variance = ProtoEnumFlags.variance(typeArgumentProto.projection)
......
......@@ -6,12 +6,10 @@
package org.jetbrains.kotlin.fir.resolve
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.ConeClassifierSymbol
import org.jetbrains.kotlin.fir.declarations.expandedConeType
import org.jetbrains.kotlin.fir.symbols.ConeClassSymbol
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterSymbol
import org.jetbrains.kotlin.fir.symbols.*
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeAbbreviatedTypeImpl
import org.jetbrains.kotlin.fir.types.impl.ConeClassTypeImpl
......@@ -33,6 +31,14 @@ inline fun <K, V, VA : V> MutableMap<K, V>.getOrPut(key: K, defaultValue: (K) ->
fun ConeClassLikeLookupTag.toSymbol(useSiteSession: FirSession): ConeClassifierSymbol? =
useSiteSession.getService(FirSymbolProvider::class).getSymbolByLookupTag(this)
fun ConeClassifierLookupTag.toSymbol(useSiteSession: FirSession): ConeClassifierSymbol? =
when (this) {
is ConeClassLikeLookupTag -> toSymbol(useSiteSession)
is FirTypeParameterSymbol -> this.symbol
else -> error("sealed")
}
fun ConeClassifierSymbol.constructType(typeArguments: Array<ConeKotlinTypeProjection>, isNullable: Boolean): ConeKotlinType {
return when (this) {
is ConeTypeParameterSymbol -> {
......@@ -66,7 +72,7 @@ fun ConeKotlinType.toTypeProjection(variance: Variance): ConeKotlinTypeProjectio
private fun List<FirQualifierPart>.toTypeProjections(): Array<ConeKotlinTypeProjection> = flatMap {
it.typeArguments.map { typeArgument ->
when (typeArgument) {
is FirStarProjection -> StarProjection
is FirStarProjection -> ConeStarProjection
is FirTypeProjectionWithVariance -> {
val type = (typeArgument.typeRef as FirResolvedTypeRef).type
type.toTypeProjection(typeArgument.variance)
......
......@@ -31,7 +31,7 @@ class FirClassSubstitutionScope(
private fun wrapProjection(old: ConeKotlinTypeProjection, newType: ConeKotlinType): ConeKotlinTypeProjection {
return when (old) {
is StarProjection -> old
is ConeStarProjection -> old
is ConeKotlinTypeProjectionIn -> ConeKotlinTypeProjectionIn(newType)
is ConeKotlinTypeProjectionOut -> ConeKotlinTypeProjectionOut(newType)
is ConeKotlinType -> newType
......
......@@ -20,9 +20,11 @@ import org.jetbrains.kotlin.fir.symbols.ConeCallableSymbol
import org.jetbrains.kotlin.fir.symbols.ConeFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.ConePropertySymbol
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.ConeTypeContext
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.AbstractStrictEqualityTypeChecker
import org.jetbrains.kotlin.utils.addToStdlib.cast
class FirClassUseSiteScope(
......@@ -34,22 +36,16 @@ class FirClassUseSiteScope(
//base symbol as key
val overrides = mutableMapOf<ConeCallableSymbol, ConeCallableSymbol?>()
@Suppress("UNUSED_PARAMETER")
private fun isSubtypeOf(subType: ConeKotlinType, superType: ConeKotlinType): Boolean {
// TODO: introduce normal sub-typing
return true
}
private fun isSubtypeOf(subType: FirTypeRef, superType: FirTypeRef) =
isSubtypeOf(subType.cast<FirResolvedTypeRef>().type, superType.cast<FirResolvedTypeRef>().type)
@Suppress("UNUSED_PARAMETER")
private fun isEqualTypes(a: ConeKotlinType, b: ConeKotlinType): Boolean {
// TODO: introduce normal type comparison
return true
val context = object : ConeTypeContext {
override val session: FirSession
get() = session
}
private fun isEqualTypes(a: FirTypeRef, b: FirTypeRef) = isEqualTypes(a.cast<FirResolvedTypeRef>().type, b.cast<FirResolvedTypeRef>().type)
private fun isEqualTypes(a: ConeKotlinType, b: ConeKotlinType) = AbstractStrictEqualityTypeChecker.strictEqualTypes(context, a, b)
private fun isEqualTypes(a: FirTypeRef, b: FirTypeRef) =
isEqualTypes(a.cast<FirResolvedTypeRef>().type, b.cast<FirResolvedTypeRef>().type)
private fun isOverriddenFunCheck(member: FirNamedFunction, self: FirNamedFunction): Boolean {
return member.valueParameters.size == self.valueParameters.size &&
......@@ -82,7 +78,6 @@ class FirClassUseSiteScope(
val member = (it as AbstractFirBasedSymbol<*>).fir as FirCallableMember
member.isOverride && self.modality != Modality.FINAL
&& sameReceivers(member.receiverTypeRef, self.receiverTypeRef)
&& isSubtypeOf(member.returnTypeRef, self.returnTypeRef)
&& similarFunctionsOrBothProperties(member, self)
} // TODO: two or more overrides for one fun?
overrides[this] = overriding
......
/*
* 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.fir.types
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.expandedConeType
import org.jetbrains.kotlin.fir.declarations.superConeTypes
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.service
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.ConeClassSymbol
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.impl.ConeAbbreviatedTypeImpl
import org.jetbrains.kotlin.fir.types.impl.ConeClassTypeImpl
import org.jetbrains.kotlin.fir.types.impl.ConeFunctionTypeImpl
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
import org.jetbrains.kotlin.types.checker.convertVariance
import org.jetbrains.kotlin.types.model.*
class ErrorTypeConstructor(reason: String) : TypeConstructorMarker
interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext {
val session: FirSession
override fun KotlinTypeMarker.asSimpleType(): SimpleTypeMarker? {
assert(this is ConeKotlinType)
return this as? ConeLookupTagBasedType
}
override fun KotlinTypeMarker.asFlexibleType(): FlexibleTypeMarker? {
assert(this is ConeKotlinType)
return this as? ConeFlexibleType
}
override fun KotlinTypeMarker.isError(): Boolean {
assert(this is ConeKotlinType)
return this is ConeClassErrorType || this is ConeKotlinErrorType || this.typeConstructor() is ErrorTypeConstructor
}
override fun FlexibleTypeMarker.asDynamicType(): DynamicTypeMarker? {
assert(this is ConeKotlinType)
return null // TODO
}
override fun FlexibleTypeMarker.asRawType(): RawTypeMarker? {
assert(this is ConeKotlinType)
return null // TODO
}
override fun FlexibleTypeMarker.upperBound(): SimpleTypeMarker {
require(this is ConeFlexibleType)
return this.upperBound
}
override fun FlexibleTypeMarker.lowerBound(): SimpleTypeMarker {
require(this is ConeFlexibleType)
return this.lowerBound
}
override fun SimpleTypeMarker.asCapturedType(): CapturedTypeMarker? {
require(this is ConeLookupTagBasedType)
return null // TODO
}
override fun SimpleTypeMarker.asDefinitelyNotNullType(): DefinitelyNotNullTypeMarker? {
require(this is ConeLookupTagBasedType)
return null // TODO
}
override fun SimpleTypeMarker.isMarkedNullable(): Boolean {
require(this is ConeLookupTagBasedType)
return this.nullability.isNullable
}
override fun SimpleTypeMarker.withNullability(nullable: Boolean): SimpleTypeMarker {
require(this is ConeLookupTagBasedType)
if (nullability.isNullable == nullable) return this
return when (this) {
is ConeTypeParameterType -> ConeTypeParameterTypeImpl(lookupTag, nullable)
is ConeClassErrorType -> this
is ConeClassType -> ConeClassTypeImpl(lookupTag, typeArguments, nullable)
is ConeAbbreviatedType -> ConeAbbreviatedTypeImpl(
lookupTag,
typeArguments,
directExpansion,
nullable
)
is ConeFunctionType -> ConeFunctionTypeImpl(
receiverType,
parameterTypes,
returnType,
lookupTag,
nullable
)
}
}
override fun SimpleTypeMarker.typeConstructor(): TypeConstructorMarker {
require(this is ConeLookupTagBasedType)
return this.lookupTag.toSymbol(session) ?: ErrorTypeConstructor("Unresolved: ${this.lookupTag}")
}
override fun SimpleTypeMarker.argumentsCount(): Int {
require(this is ConeLookupTagBasedType)
return this.typeArguments.size
}
override fun SimpleTypeMarker.getArgument(index: Int): TypeArgumentMarker {
require(this is ConeLookupTagBasedType)
return this.typeArguments[index]
}
override fun KotlinTypeMarker.asTypeArgument(): TypeArgumentMarker {
require(this is ConeKotlinType)
return this
}
override fun CapturedTypeMarker.lowerType(): KotlinTypeMarker? {
require(this is ConeKotlinType)
return null // TODO
}
override fun TypeArgumentMarker.isStarProjection(): Boolean {
require(this is ConeKotlinTypeProjection)
return this is ConeStarProjection
}
override fun TypeArgumentMarker.getVariance(): TypeVariance {
require(this is ConeKotlinTypeProjection)
return when (this.kind) {
ProjectionKind.STAR -> error("Nekorrektno (c) Stas")
ProjectionKind.IN -> TypeVariance.IN
ProjectionKind.OUT -> TypeVariance.OUT
ProjectionKind.INVARIANT -> TypeVariance.INV
}
}
override fun TypeArgumentMarker.getType(): KotlinTypeMarker {
require(this is ConeKotlinTypeProjection)
require(this is ConeTypedProjection) { "No type for StarProjection" }
return this.type
}
override fun TypeConstructorMarker.parametersCount(): Int {
require(this is ConeSymbol)
return when (this) {
is ConeTypeParameterSymbol -> 0
is FirClassSymbol -> fir.typeParameters.size
is FirTypeAliasSymbol -> fir.typeParameters.size
else -> error("?!:10")
}
}
override fun TypeConstructorMarker.getParameter(index: Int): TypeParameterMarker {
require(this is ConeSymbol)
return when (this) {
is ConeTypeParameterSymbol -> error("?!:11")
is FirClassSymbol -> fir.typeParameters[index].symbol
is FirTypeAliasSymbol -> fir.typeParameters[index].symbol
else -> error("?!:12")
}
}
override fun TypeConstructorMarker.supertypes(): Collection<KotlinTypeMarker> {
require(this is ConeSymbol)
return when (this) {
is ConeTypeParameterSymbol -> emptyList()
is FirClassSymbol -> fir.superConeTypes
is FirTypeAliasSymbol -> listOfNotNull(fir.expandedConeType)
else -> error("?!:13")
}
}
override fun TypeConstructorMarker.isIntersection(): Boolean {
return false // TODO
}
override fun TypeConstructorMarker.isClassTypeConstructor(): Boolean {
assert(this is ConeSymbol)
return this is FirClassSymbol
}
override fun TypeParameterMarker.getVariance(): TypeVariance {
require(this is FirTypeParameterSymbol)
return this.fir.variance.convertVariance()
}
override fun TypeParameterMarker.upperBoundCount(): Int {
require(this is FirTypeParameterSymbol)
return this.fir.bounds.size
}
override fun TypeParameterMarker.getUpperBound(index: Int): KotlinTypeMarker {
require(this is FirTypeParameterSymbol)
return this.fir.bounds[index].coneTypeUnsafe()
}
override fun TypeParameterMarker.getTypeConstructor(): TypeConstructorMarker {
require(this is FirTypeParameterSymbol)
return this
}
override fun isEqualTypeConstructors(c1: TypeConstructorMarker, c2: TypeConstructorMarker): Boolean {
assert(c1 is ConeSymbol)
assert(c2 is ConeSymbol)
return c1 == c2
}
override fun TypeConstructorMarker.isDenotable(): Boolean {
return true // TODO
}
override fun TypeConstructorMarker.isCommonFinalClassConstructor(): Boolean {
require(this is ConeSymbol)
val classSymbol = this as? ConeClassSymbol ?: return false
val fir = (classSymbol as FirClassSymbol).fir
return fir.modality == Modality.FINAL &&
fir.classKind != ClassKind.ENUM_ENTRY &&
fir.classKind != ClassKind.ANNOTATION_CLASS
}
override fun captureFromArguments(type: SimpleTypeMarker, status: CaptureStatus): SimpleTypeMarker? {
TODO("not implemented")
}
override fun SimpleTypeMarker.asArgumentList(): TypeArgumentListMarker {
require(this is ConeKotlinType)
return this
}
override fun identicalArguments(a: SimpleTypeMarker, b: SimpleTypeMarker): Boolean {
require(a is ConeLookupTagBasedType)
require(b is ConeLookupTagBasedType)
return a.typeArguments === b.typeArguments
}
override fun TypeConstructorMarker.isAnyConstructor(): Boolean {
assert(this is ConeSymbol)
return this is ConeClassLikeSymbol && classId.asString() == "kotlin/Any"
}
override fun TypeConstructorMarker.isNothingConstructor(): Boolean {
return this is ConeClassLikeSymbol && classId.asString() == "kotlin/Nothing"
}
override fun KotlinTypeMarker.isNotNullNothing(): Boolean {
require(this is ConeKotlinType)
return typeConstructor().isNothingConstructor() && !this.nullability.isNullable
}
override fun SimpleTypeMarker.isSingleClassifierType(): Boolean {
TODO("not implemented")
}
}
\ No newline at end of file
......@@ -3,15 +3,18 @@
open class A {
open fun foo(): A = this
open fun bar(): A = this
open fun buz(p: A): A = this
}
class B : A() {
override fun foo(): B = this
fun bar(): B = this // Ambiguity, no override here
override fun buz(p: B): B = this //No override as B <!:> A
fun test() {
foo()
bar()
buz()
}
}
......@@ -10,6 +10,10 @@ FILE: simple.kt
return@@@bar this#
}
public open function buz(p: R|A|): R|A| {
return@@@buz this#
}
}
public final class B : R|A| {
public constructor(): super<R|A|>()
......@@ -22,9 +26,14 @@ FILE: simple.kt
return@@@bar this#
}
public final override function buz(p: R|B|): R|B| {
return@@@buz this#
}
public final function test(): R|kotlin/Unit| {
R|/B.foo|()
<Ambiguity: bar, [/B.bar, /A.bar]>#()
<Ambiguity: buz, [/B.buz, /A.buz]>#()
}
}
......@@ -629,7 +629,7 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
if (typeArguments.isNotEmpty()) {
sb.append(typeArguments.joinToString(prefix = "<", postfix = ">") {
when (it) {
StarProjection -> "*"
ConeStarProjection -> "*"
is ConeKotlinTypeProjectionIn -> "in ${it.type.asString()}"
is ConeKotlinTypeProjectionOut -> "out ${it.type.asString()}"
is ConeKotlinType -> it.asString()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册