Integrate nullability into cone types, add & use FIR flexible type
FIR fake overrides are rendered now more precisely to test this process
This commit is contained in:
@@ -40,6 +40,18 @@ class ConeKotlinTypeProjectionOut(override val type: ConeKotlinType) : ConeKotli
|
|||||||
get() = ProjectionKind.OUT
|
get() = ProjectionKind.OUT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class ConeNullability(val suffix: String) {
|
||||||
|
NULLABLE("?"),
|
||||||
|
UNKNOWN("!"),
|
||||||
|
NOT_NULL("");
|
||||||
|
|
||||||
|
val isNullable: Boolean get() = this != NOT_NULL
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun create(isNullable: Boolean) = if (isNullable) NULLABLE else NOT_NULL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// We assume type IS an invariant type projection to prevent additional wrapper here
|
// We assume type IS an invariant type projection to prevent additional wrapper here
|
||||||
// (more exactly, invariant type projection contains type)
|
// (more exactly, invariant type projection contains type)
|
||||||
sealed class ConeKotlinType : ConeKotlinTypeProjection(), ConeTypedProjection {
|
sealed class ConeKotlinType : ConeKotlinTypeProjection(), ConeTypedProjection {
|
||||||
@@ -50,12 +62,17 @@ sealed class ConeKotlinType : ConeKotlinTypeProjection(), ConeTypedProjection {
|
|||||||
|
|
||||||
override val type: ConeKotlinType
|
override val type: ConeKotlinType
|
||||||
get() = this
|
get() = this
|
||||||
|
|
||||||
|
abstract val nullability: ConeNullability
|
||||||
}
|
}
|
||||||
|
|
||||||
class ConeKotlinErrorType(val reason: String) : ConeKotlinType() {
|
class ConeKotlinErrorType(val reason: String) : ConeKotlinType() {
|
||||||
override val typeArguments: Array<out ConeKotlinTypeProjection>
|
override val typeArguments: Array<out ConeKotlinTypeProjection>
|
||||||
get() = EMPTY_ARRAY
|
get() = EMPTY_ARRAY
|
||||||
|
|
||||||
|
override val nullability: ConeNullability
|
||||||
|
get() = ConeNullability.UNKNOWN
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "<ERROR TYPE: $reason>"
|
return "<ERROR TYPE: $reason>"
|
||||||
}
|
}
|
||||||
@@ -68,6 +85,9 @@ class ConeClassErrorType(val reason: String) : ConeClassLikeType() {
|
|||||||
override val typeArguments: Array<out ConeKotlinTypeProjection>
|
override val typeArguments: Array<out ConeKotlinTypeProjection>
|
||||||
get() = EMPTY_ARRAY
|
get() = EMPTY_ARRAY
|
||||||
|
|
||||||
|
override val nullability: ConeNullability
|
||||||
|
get() = ConeNullability.UNKNOWN
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "<ERROR CLASS: $reason>"
|
return "<ERROR CLASS: $reason>"
|
||||||
}
|
}
|
||||||
@@ -99,3 +119,11 @@ abstract class ConeFunctionType : ConeClassLikeType() {
|
|||||||
abstract val parameterTypes: List<ConeKotlinType>
|
abstract val parameterTypes: List<ConeKotlinType>
|
||||||
abstract val returnType: ConeKotlinType
|
abstract val returnType: ConeKotlinType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ConeFlexibleType(val lowerBound: ConeKotlinType, val upperBound: ConeKotlinType) : ConeKotlinType() {
|
||||||
|
override val typeArguments: Array<out ConeKotlinTypeProjection>
|
||||||
|
get() = emptyArray()
|
||||||
|
|
||||||
|
override val nullability: ConeNullability
|
||||||
|
get() = lowerBound.nullability.takeIf { it == upperBound.nullability } ?: ConeNullability.UNKNOWN
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,13 +9,17 @@ import org.jetbrains.kotlin.fir.symbols.ConeClassLikeSymbol
|
|||||||
import org.jetbrains.kotlin.fir.types.ConeFunctionType
|
import org.jetbrains.kotlin.fir.types.ConeFunctionType
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinTypeProjection
|
import org.jetbrains.kotlin.fir.types.ConeKotlinTypeProjection
|
||||||
|
import org.jetbrains.kotlin.fir.types.ConeNullability
|
||||||
|
|
||||||
class ConeFunctionTypeImpl(
|
class ConeFunctionTypeImpl(
|
||||||
override val receiverType: ConeKotlinType?,
|
override val receiverType: ConeKotlinType?,
|
||||||
override val parameterTypes: List<ConeKotlinType>,
|
override val parameterTypes: List<ConeKotlinType>,
|
||||||
override val returnType: ConeKotlinType,
|
override val returnType: ConeKotlinType,
|
||||||
override val symbol: ConeClassLikeSymbol
|
override val symbol: ConeClassLikeSymbol,
|
||||||
|
isNullable: Boolean
|
||||||
) : ConeFunctionType() {
|
) : ConeFunctionType() {
|
||||||
override val typeArguments: Array<out ConeKotlinTypeProjection>
|
override val typeArguments: Array<out ConeKotlinTypeProjection>
|
||||||
get() = EMPTY_ARRAY
|
get() = EMPTY_ARRAY
|
||||||
|
|
||||||
|
override val nullability: ConeNullability = ConeNullability.create(isNullable)
|
||||||
}
|
}
|
||||||
@@ -11,19 +11,30 @@ import org.jetbrains.kotlin.fir.types.*
|
|||||||
|
|
||||||
open class ConeClassTypeImpl(
|
open class ConeClassTypeImpl(
|
||||||
override val symbol: ConeClassLikeSymbol,
|
override val symbol: ConeClassLikeSymbol,
|
||||||
override val typeArguments: Array<ConeKotlinTypeProjection>
|
override val typeArguments: Array<ConeKotlinTypeProjection>,
|
||||||
) : ConeClassLikeType()
|
isNullable: Boolean
|
||||||
|
) : ConeClassLikeType() {
|
||||||
|
override val nullability: ConeNullability = ConeNullability.create(isNullable)
|
||||||
|
}
|
||||||
|
|
||||||
class ConeAbbreviatedTypeImpl(
|
class ConeAbbreviatedTypeImpl(
|
||||||
override val abbreviationSymbol: ConeClassLikeSymbol,
|
override val abbreviationSymbol: ConeClassLikeSymbol,
|
||||||
override val typeArguments: Array<ConeKotlinTypeProjection>,
|
override val typeArguments: Array<ConeKotlinTypeProjection>,
|
||||||
override val directExpansion: ConeClassLikeType
|
override val directExpansion: ConeClassLikeType,
|
||||||
|
isNullable: Boolean
|
||||||
) : ConeAbbreviatedType() {
|
) : ConeAbbreviatedType() {
|
||||||
override val symbol: ConeClassLikeSymbol
|
override val symbol: ConeClassLikeSymbol
|
||||||
get() = abbreviationSymbol
|
get() = abbreviationSymbol
|
||||||
|
|
||||||
|
override val nullability: ConeNullability = ConeNullability.create(isNullable)
|
||||||
}
|
}
|
||||||
|
|
||||||
class ConeTypeParameterTypeImpl(override val symbol: ConeTypeParameterSymbol) : ConeTypeParameterType() {
|
class ConeTypeParameterTypeImpl(
|
||||||
|
override val symbol: ConeTypeParameterSymbol,
|
||||||
|
isNullable: Boolean
|
||||||
|
) : ConeTypeParameterType() {
|
||||||
override val typeArguments: Array<out ConeKotlinTypeProjection>
|
override val typeArguments: Array<out ConeKotlinTypeProjection>
|
||||||
get() = EMPTY_ARRAY
|
get() = EMPTY_ARRAY
|
||||||
|
|
||||||
|
override val nullability: ConeNullability = ConeNullability.create(isNullable)
|
||||||
}
|
}
|
||||||
@@ -23,10 +23,7 @@ import org.jetbrains.kotlin.fir.symbols.ConeClassSymbol
|
|||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.ConeClassErrorType
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinErrorType
|
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinTypeProjection
|
|
||||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeClassTypeImpl
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||||
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
|
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
|
||||||
@@ -53,7 +50,7 @@ class JavaSymbolProvider(
|
|||||||
annotationTypeRef = FirResolvedTypeRefImpl(
|
annotationTypeRef = FirResolvedTypeRefImpl(
|
||||||
session = session,
|
session = session,
|
||||||
psi = null,
|
psi = null,
|
||||||
type = ConeClassTypeImpl(FirClassSymbol(classId!!), emptyArray()),
|
type = ConeClassTypeImpl(FirClassSymbol(classId!!), emptyArray(), isNullable = false),
|
||||||
isMarkedNullable = true,
|
isMarkedNullable = true,
|
||||||
annotations = emptyList()
|
annotations = emptyList()
|
||||||
)
|
)
|
||||||
@@ -87,18 +84,24 @@ class JavaSymbolProvider(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun flexibleType(create: (isNullable: Boolean) -> ConeKotlinType): ConeFlexibleType {
|
||||||
|
return ConeFlexibleType(create(false), create(true))
|
||||||
|
}
|
||||||
|
|
||||||
private fun JavaClassifierType.toFirResolvedTypeRef(): FirResolvedTypeRef {
|
private fun JavaClassifierType.toFirResolvedTypeRef(): FirResolvedTypeRef {
|
||||||
val coneType = when (val classifier = classifier) {
|
val coneType = when (val classifier = classifier) {
|
||||||
is JavaClass -> {
|
is JavaClass -> {
|
||||||
val symbol = session.service<FirSymbolProvider>().getClassLikeSymbolByFqName(classifier.classId!!) as? ConeClassSymbol
|
val symbol = session.service<FirSymbolProvider>().getClassLikeSymbolByFqName(classifier.classId!!) as? ConeClassSymbol
|
||||||
if (symbol == null) ConeKotlinErrorType("Symbol not found, for `${classifier.classId}`")
|
if (symbol == null) ConeKotlinErrorType("Symbol not found, for `${classifier.classId}`")
|
||||||
else ConeClassTypeImpl(symbol, typeArguments = typeArguments.map { it.toConeProjection() }.toTypedArray())
|
else flexibleType { isNullable ->
|
||||||
|
ConeClassTypeImpl(symbol, typeArguments.map { it.toConeProjection() }.toTypedArray(), isNullable)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
is JavaTypeParameter -> {
|
is JavaTypeParameter -> {
|
||||||
// TODO: it's unclear how to identify type parameter by the symbol
|
// TODO: it's unclear how to identify type parameter by the symbol
|
||||||
// TODO: some type parameter cache (provider?)
|
// TODO: some type parameter cache (provider?)
|
||||||
val symbol = createTypeParameterSymbol(classifier.name)
|
val symbol = createTypeParameterSymbol(classifier.name)
|
||||||
ConeTypeParameterTypeImpl(symbol)
|
flexibleType { isNullable -> ConeTypeParameterTypeImpl(symbol, isNullable) }
|
||||||
}
|
}
|
||||||
else -> ConeClassErrorType(reason = "Unexpected classifier: $classifier")
|
else -> ConeClassErrorType(reason = "Unexpected classifier: $classifier")
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-3
@@ -46,7 +46,8 @@ class FirTypeDeserializer(
|
|||||||
val id = nameResolver.getString(proto.flexibleTypeCapabilitiesId)
|
val id = nameResolver.getString(proto.flexibleTypeCapabilitiesId)
|
||||||
val lowerBound = classLikeType(proto)
|
val lowerBound = classLikeType(proto)
|
||||||
val upperBound = classLikeType(proto.flexibleUpperBound(typeTable)!!)
|
val upperBound = classLikeType(proto.flexibleUpperBound(typeTable)!!)
|
||||||
return ConeKotlinErrorType("Not supported: Flexible types")//c.components.flexibleTypeDeserializer.create(proto, id, lowerBound, upperBound)
|
return ConeFlexibleType(lowerBound!!, upperBound!!)
|
||||||
|
//c.components.flexibleTypeDeserializer.create(proto, id, lowerBound, upperBound)
|
||||||
}
|
}
|
||||||
|
|
||||||
return classLikeType(proto) ?: ConeKotlinErrorType("?!id:0")
|
return classLikeType(proto) ?: ConeKotlinErrorType("?!id:0")
|
||||||
@@ -97,12 +98,12 @@ class FirTypeDeserializer(
|
|||||||
//createSuspendFunctionType(annotations, constructor, arguments, proto.nullable)
|
//createSuspendFunctionType(annotations, constructor, arguments, proto.nullable)
|
||||||
ConeClassErrorType("createSuspendFunctionType not supported")
|
ConeClassErrorType("createSuspendFunctionType not supported")
|
||||||
} else {
|
} else {
|
||||||
ConeClassTypeImpl(constructor, arguments)
|
ConeClassTypeImpl(constructor, arguments, isNullable = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
val abbreviatedTypeProto = proto.abbreviatedType(typeTable) ?: return simpleType
|
val abbreviatedTypeProto = proto.abbreviatedType(typeTable) ?: return simpleType
|
||||||
|
|
||||||
return ConeAbbreviatedTypeImpl(typeSymbol(abbreviatedTypeProto) as ConeClassLikeSymbol, arguments, simpleType)
|
return ConeAbbreviatedTypeImpl(typeSymbol(abbreviatedTypeProto) as ConeClassLikeSymbol, arguments, simpleType, isNullable = false)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-7
@@ -42,20 +42,21 @@ class FirTypeResolverImpl : FirTypeResolver {
|
|||||||
}
|
}
|
||||||
}.toTypedArray()
|
}.toTypedArray()
|
||||||
|
|
||||||
private fun ConeSymbol.toConeKotlinType(parts: List<FirQualifierPart>): ConeKotlinType? {
|
private fun ConeSymbol.toConeKotlinType(parts: List<FirQualifierPart>, isNullable: Boolean): ConeKotlinType? {
|
||||||
|
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is ConeTypeParameterSymbol -> {
|
is ConeTypeParameterSymbol -> {
|
||||||
ConeTypeParameterTypeImpl(this)
|
ConeTypeParameterTypeImpl(this, isNullable)
|
||||||
}
|
}
|
||||||
is ConeClassSymbol -> {
|
is ConeClassSymbol -> {
|
||||||
ConeClassTypeImpl(this, parts.toTypeProjections())
|
ConeClassTypeImpl(this, parts.toTypeProjections(), isNullable)
|
||||||
}
|
}
|
||||||
is FirTypeAliasSymbol -> {
|
is FirTypeAliasSymbol -> {
|
||||||
ConeAbbreviatedTypeImpl(
|
ConeAbbreviatedTypeImpl(
|
||||||
abbreviationSymbol = this as ConeClassLikeSymbol,
|
abbreviationSymbol = this as ConeClassLikeSymbol,
|
||||||
typeArguments = parts.toTypeProjections(),
|
typeArguments = parts.toTypeProjections(),
|
||||||
directExpansion = fir.expandedConeType ?: ConeClassErrorType("Unresolved expansion")
|
directExpansion = fir.expandedConeType ?: ConeClassErrorType("Unresolved expansion"),
|
||||||
|
isNullable = isNullable
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
else -> error("!")
|
else -> error("!")
|
||||||
@@ -118,7 +119,8 @@ class FirTypeResolverImpl : FirTypeResolver {
|
|||||||
|
|
||||||
override fun resolveUserType(typeRef: FirUserTypeRef, symbol: ConeSymbol?, scope: FirScope): ConeKotlinType {
|
override fun resolveUserType(typeRef: FirUserTypeRef, symbol: ConeSymbol?, scope: FirScope): ConeKotlinType {
|
||||||
symbol ?: return ConeKotlinErrorType("Symbol not found, for `${typeRef.render()}`")
|
symbol ?: return ConeKotlinErrorType("Symbol not found, for `${typeRef.render()}`")
|
||||||
return symbol.toConeKotlinType(typeRef.qualifier) ?: ConeKotlinErrorType("Failed to resolve qualified type")
|
return symbol.toConeKotlinType(typeRef.qualifier, typeRef.isMarkedNullable)
|
||||||
|
?: ConeKotlinErrorType("Failed to resolve qualified type")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun resolveType(
|
override fun resolveType(
|
||||||
@@ -139,11 +141,12 @@ class FirTypeResolverImpl : FirTypeResolver {
|
|||||||
(typeRef.receiverTypeRef as FirResolvedTypeRef?)?.type,
|
(typeRef.receiverTypeRef as FirResolvedTypeRef?)?.type,
|
||||||
typeRef.valueParameters.map { it.returnTypeRef.coneTypeUnsafe() },
|
typeRef.valueParameters.map { it.returnTypeRef.coneTypeUnsafe() },
|
||||||
typeRef.returnTypeRef.coneTypeUnsafe(),
|
typeRef.returnTypeRef.coneTypeUnsafe(),
|
||||||
resolveBuiltInQualified(KotlinBuiltIns.getFunctionClassId(typeRef.parametersCount), typeRef.session)
|
resolveBuiltInQualified(KotlinBuiltIns.getFunctionClassId(typeRef.parametersCount), typeRef.session),
|
||||||
|
typeRef.isMarkedNullable
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is FirImplicitBuiltinTypeRef -> {
|
is FirImplicitBuiltinTypeRef -> {
|
||||||
resolveToSymbol(typeRef, scope, position)!!.toConeKotlinType(emptyList())!!
|
resolveToSymbol(typeRef, scope, position)!!.toConeKotlinType(emptyList(), isNullable = false)!!
|
||||||
}
|
}
|
||||||
is FirDynamicTypeRef, is FirImplicitTypeRef, is FirDelegatedTypeRef -> {
|
is FirDynamicTypeRef, is FirImplicitTypeRef, is FirDelegatedTypeRef -> {
|
||||||
ConeKotlinErrorType("Not supported: ${typeRef::class.simpleName}")
|
ConeKotlinErrorType("Not supported: ${typeRef::class.simpleName}")
|
||||||
|
|||||||
+4
-2
@@ -63,14 +63,16 @@ class FirClassSubstitutionScope(
|
|||||||
return when (this) {
|
return when (this) {
|
||||||
is ConeKotlinErrorType -> error("Trying to substitute arguments for error type")
|
is ConeKotlinErrorType -> error("Trying to substitute arguments for error type")
|
||||||
is ConeTypeParameterType -> error("Trying to substitute arguments for type parameter")
|
is ConeTypeParameterType -> error("Trying to substitute arguments for type parameter")
|
||||||
is ConeClassTypeImpl -> ConeClassTypeImpl(symbol, newArguments as Array<ConeKotlinTypeProjection>)
|
is ConeClassTypeImpl -> ConeClassTypeImpl(symbol, newArguments as Array<ConeKotlinTypeProjection>, nullability.isNullable)
|
||||||
is ConeAbbreviatedTypeImpl -> ConeAbbreviatedTypeImpl(
|
is ConeAbbreviatedTypeImpl -> ConeAbbreviatedTypeImpl(
|
||||||
abbreviationSymbol,
|
abbreviationSymbol,
|
||||||
newArguments as Array<ConeKotlinTypeProjection>,
|
newArguments as Array<ConeKotlinTypeProjection>,
|
||||||
directExpansion.substitute() as? ConeClassLikeType ?: directExpansion
|
directExpansion.substitute() as? ConeClassLikeType ?: directExpansion,
|
||||||
|
nullability.isNullable
|
||||||
)
|
)
|
||||||
is ConeFunctionType -> TODO("Substitute function type properly")
|
is ConeFunctionType -> TODO("Substitute function type properly")
|
||||||
is ConeClassLikeType -> error("Unknown class-like type to substitute: $this, ${this::class}")
|
is ConeClassLikeType -> error("Unknown class-like type to substitute: $this, ${this::class}")
|
||||||
|
is ConeFlexibleType -> error("Trying to substitute arguments for flexible type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
FILE: genericFunctions.kt
|
FILE: genericFunctions.kt
|
||||||
public abstract interface Any {
|
public abstract interface Any {
|
||||||
}
|
}
|
||||||
<reified T : R|Any|> public final inline function safeAs R|Any|.(): R|T| {
|
<reified T : R|Any|> public final inline function safeAs R|Any|.(): R|T|? {
|
||||||
return@@@safeAs as?/R|T|(this#)
|
return@@@safeAs as?/R|T|(this#)
|
||||||
}
|
}
|
||||||
public abstract class Summator {
|
public abstract class Summator {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ FILE: simpleFakeOverride.kt
|
|||||||
public constructor(): super<R|A<Some>|>()
|
public constructor(): super<R|A<Some>|>()
|
||||||
|
|
||||||
public final function test(): R|kotlin/Unit| {
|
public final function test(): R|kotlin/Unit| {
|
||||||
R|FakeOverride</A.foo>|(<Unresolved name: Some>#())
|
R|FakeOverride</A.foo: R|T|>|(<Unresolved name: Some>#())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.expressions.impl.*
|
|||||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeSymbol
|
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
|
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef
|
import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef
|
||||||
@@ -652,6 +653,15 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
|
|||||||
append(returnType.asString())
|
append(returnType.asString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
is ConeFlexibleType -> {
|
||||||
|
buildString {
|
||||||
|
append("ft<")
|
||||||
|
append(lowerBound.asString())
|
||||||
|
append(", ")
|
||||||
|
append(upperBound.asString())
|
||||||
|
append(">")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -661,7 +671,9 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
|
|||||||
val coneType = resolvedTypeRef.type
|
val coneType = resolvedTypeRef.type
|
||||||
print(coneType.asString())
|
print(coneType.asString())
|
||||||
print("|")
|
print("|")
|
||||||
visitTypeRefWithNullability(resolvedTypeRef)
|
if (coneType !is ConeKotlinErrorType && coneType !is ConeClassErrorType) {
|
||||||
|
print(coneType.nullability.suffix)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitUserTypeRef(userTypeRef: FirUserTypeRef) {
|
override fun visitUserTypeRef(userTypeRef: FirUserTypeRef) {
|
||||||
@@ -704,8 +716,19 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
|
|||||||
if (isFakeOverride) {
|
if (isFakeOverride) {
|
||||||
print("FakeOverride<")
|
print("FakeOverride<")
|
||||||
}
|
}
|
||||||
print(resolvedCallableReference.callableSymbol.callableId)
|
val symbol = resolvedCallableReference.callableSymbol
|
||||||
|
print(symbol.callableId)
|
||||||
if (isFakeOverride) {
|
if (isFakeOverride) {
|
||||||
|
when (symbol) {
|
||||||
|
is FirFunctionSymbol -> {
|
||||||
|
print(": ")
|
||||||
|
symbol.fir.returnTypeRef.accept(this)
|
||||||
|
}
|
||||||
|
is FirPropertySymbol -> {
|
||||||
|
print(": ")
|
||||||
|
symbol.fir.returnTypeRef.accept(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
print(">")
|
print(">")
|
||||||
}
|
}
|
||||||
print("|")
|
print("|")
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
public class A<T> {
|
||||||
|
public T foo(T t) {
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
class Some
|
||||||
|
|
||||||
|
class B : A<Some>() {
|
||||||
|
fun test() {
|
||||||
|
foo(Some())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
FILE: simpleFakeOverride.kt
|
||||||
|
public final class Some {
|
||||||
|
public constructor(): super<R|kotlin/Any|>()
|
||||||
|
|
||||||
|
}
|
||||||
|
public final class B : R|A<Some>| {
|
||||||
|
public constructor(): super<R|A<Some>|>()
|
||||||
|
|
||||||
|
public final function test(): R|kotlin/Unit| {
|
||||||
|
R|FakeOverride</A.foo: R|ft<T, T>|!>|(<Unresolved name: Some>#())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -14,8 +14,8 @@ FILE: jvm.kt
|
|||||||
public constructor(): super<R|C|>()
|
public constructor(): super<R|C|>()
|
||||||
|
|
||||||
public final function test(): R|kotlin/Unit| {
|
public final function test(): R|kotlin/Unit| {
|
||||||
R|FakeOverride</A.foo>|(String())
|
R|FakeOverride</A.foo: R|kotlin/Unit|>|(String())
|
||||||
R|FakeOverride</A.bar>|(String())
|
R|FakeOverride</A.bar: R|T|>|(String())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+5
@@ -39,6 +39,11 @@ public class FirMultiModuleResolveTestGenerated extends AbstractFirMultiModuleRe
|
|||||||
runTest("idea/testData/fir/multiModule/basicWithJava/");
|
runTest("idea/testData/fir/multiModule/basicWithJava/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("basicWithJavaFakeOverride")
|
||||||
|
public void testBasicWithJavaFakeOverride() throws Exception {
|
||||||
|
runTest("idea/testData/fir/multiModule/basicWithJavaFakeOverride/");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("mppFakeOverrides")
|
@TestMetadata("mppFakeOverrides")
|
||||||
public void testMppFakeOverrides() throws Exception {
|
public void testMppFakeOverrides() throws Exception {
|
||||||
runTest("idea/testData/fir/multiModule/mppFakeOverrides/");
|
runTest("idea/testData/fir/multiModule/mppFakeOverrides/");
|
||||||
|
|||||||
Reference in New Issue
Block a user