FIR: migrate type-related utils to relevant file
This commit is contained in:
committed by
Mikhail Glukhikh
parent
0436a555d5
commit
721248f883
-1
@@ -17,7 +17,6 @@ import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.*
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeIntermediateDiagnostic
|
||||
import org.jetbrains.kotlin.fir.typeContext
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
|
||||
import org.jetbrains.kotlin.fir.serialization.FirElementSerializer
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
|
||||
@@ -24,7 +24,6 @@ import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.*
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolved
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
|
||||
import org.jetbrains.kotlin.fir.symbols.*
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
|
||||
+1
-5
@@ -15,13 +15,9 @@ import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirClassSubstitutionScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
|
||||
import org.jetbrains.kotlin.fir.scopes.scope
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
import org.jetbrains.kotlin.fir.types.coneTypeUnsafe
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
private operator fun <T> Pair<T, *>?.component1() = this?.first
|
||||
|
||||
-1
@@ -28,7 +28,6 @@ import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.remapArguments
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.writeResultType
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperatorCall
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
|
||||
-1
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.fir.declarations.FirTypedDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.references.*
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.visitors.*
|
||||
|
||||
|
||||
+1
-5
@@ -14,12 +14,8 @@ import org.jetbrains.kotlin.fir.expressions.FirBlock
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirReturnExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildVarargArgumentsExpression
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.arrayElementType
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
import kotlin.math.min
|
||||
|
||||
+9
-92
@@ -6,11 +6,6 @@
|
||||
package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities.Internal
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities.Private
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities.Protected
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities.Public
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter
|
||||
@@ -34,9 +29,7 @@ import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.*
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirMemberTypeParameterScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
|
||||
import org.jetbrains.kotlin.fir.symbols.constructStarProjectedType
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLookupTagWithFixedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
|
||||
@@ -44,7 +37,6 @@ import org.jetbrains.kotlin.fir.types.builder.buildImplicitTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.visitors.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) : FirPartialBodyResolveTransformer(transformer) {
|
||||
@@ -511,7 +503,9 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
||||
result.transformReturnTypeRef(
|
||||
transformer,
|
||||
withExpectedType(
|
||||
body.resultType.approximateTypeIfNeeded(simpleFunction?.visibility, simpleFunction?.isInline == true)
|
||||
body.resultType.approximatedIfNeededOrSelf(
|
||||
inferenceComponents.approximator, simpleFunction?.visibility, simpleFunction?.isInline == true
|
||||
)
|
||||
)
|
||||
)
|
||||
} else {
|
||||
@@ -923,7 +917,9 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
||||
}
|
||||
variable.transformReturnTypeRef(
|
||||
transformer,
|
||||
withExpectedType(expectedType.approximateTypeIfNeeded((variable as? FirProperty)?.visibility))
|
||||
withExpectedType(
|
||||
expectedType.approximatedIfNeededOrSelf(inferenceComponents.approximator, (variable as? FirProperty)?.visibility)
|
||||
)
|
||||
)
|
||||
}
|
||||
variable.getter != null && variable.getter !is FirDefaultPropertyAccessor -> {
|
||||
@@ -945,7 +941,9 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
||||
}
|
||||
variable.transformReturnTypeRef(
|
||||
transformer,
|
||||
withExpectedType(expectedType?.approximateTypeIfNeeded((variable as? FirProperty)?.visibility))
|
||||
withExpectedType(
|
||||
expectedType?.approximatedIfNeededOrSelf(inferenceComponents.approximator, (variable as? FirProperty)?.visibility)
|
||||
)
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
@@ -968,87 +966,6 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
||||
}
|
||||
}
|
||||
|
||||
private fun ConeKotlinType.requiresApproximationInPublicPosition(): Boolean {
|
||||
return when (this) {
|
||||
is ConeIntegerLiteralType,
|
||||
is ConeCapturedType,
|
||||
is ConeDefinitelyNotNullType,
|
||||
is ConeIntersectionType -> true
|
||||
is ConeClassLikeType -> typeArguments.any {
|
||||
it is ConeKotlinTypeProjection && it.type.requiresApproximationInPublicPosition()
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirTypeRef.approximateTypeIfNeeded(
|
||||
containingCallableVisibility: Visibility?,
|
||||
isInlineFunction: Boolean = false
|
||||
): FirTypeRef {
|
||||
val approximatedType = if (this is FirResolvedTypeRef &&
|
||||
(containingCallableVisibility == Public || containingCallableVisibility == Protected)
|
||||
) {
|
||||
if (type.requiresApproximationInPublicPosition()) {
|
||||
this.withReplacedConeType(
|
||||
inferenceComponents.approximator.approximateToSuperType(
|
||||
this.type, TypeApproximatorConfiguration.PublicDeclaration
|
||||
) as? ConeKotlinType
|
||||
)
|
||||
} else {
|
||||
this
|
||||
}
|
||||
} else {
|
||||
this
|
||||
}
|
||||
return approximatedType.hideLocalTypeIfNeeded(containingCallableVisibility, isInlineFunction)
|
||||
}
|
||||
|
||||
/*
|
||||
* Suppose a function without an explicit return type just returns an anonymous object:
|
||||
*
|
||||
* fun foo(...) = object : ObjectSuperType {
|
||||
* override fun ...
|
||||
* }
|
||||
*
|
||||
* Without unwrapping, the return type ended up with that anonymous object (<no name provided>), while the resolved super type, which
|
||||
* acts like an implementing interface, is a better fit. In fact, exposing an anonymous object types is prohibited for certain cases,
|
||||
* e.g., KT-33917. We can also apply this to any local types.
|
||||
*/
|
||||
private fun FirTypeRef.hideLocalTypeIfNeeded(
|
||||
containingCallableVisibility: Visibility?,
|
||||
isInlineFunction: Boolean = false
|
||||
): FirTypeRef {
|
||||
if (containingCallableVisibility == null) {
|
||||
return this
|
||||
}
|
||||
// Approximate types for non-private (all but package private or private) members.
|
||||
// Also private inline functions, as per KT-33917.
|
||||
if (containingCallableVisibility == Public ||
|
||||
containingCallableVisibility == Protected ||
|
||||
containingCallableVisibility == Internal ||
|
||||
(containingCallableVisibility == Private && isInlineFunction)
|
||||
) {
|
||||
val firClass =
|
||||
(((this as? FirResolvedTypeRef)
|
||||
?.type as? ConeClassLikeType)
|
||||
?.lookupTag as? ConeClassLookupTagWithFixedSymbol)
|
||||
?.symbol?.fir
|
||||
if (firClass?.classId?.isLocal != true) {
|
||||
return this
|
||||
}
|
||||
if (firClass.superTypeRefs.size > 1) {
|
||||
return buildErrorTypeRef {
|
||||
diagnostic = ConeSimpleDiagnostic("Cannot hide local type ${firClass.render()}")
|
||||
}
|
||||
}
|
||||
val superType = firClass.superTypeRefs.single()
|
||||
if (superType is FirResolvedTypeRef && !superType.isAny) {
|
||||
return superType
|
||||
}
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
private object ImplicitToErrorTypeTransformer : FirTransformer<Nothing?>() {
|
||||
override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> {
|
||||
return element.compose()
|
||||
|
||||
-1
@@ -27,7 +27,6 @@ import org.jetbrains.kotlin.fir.resolve.inference.FirStubInferenceSession
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.InvocationKindTransformer
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.StoreReceiver
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.firClassLike
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
|
||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
|
||||
-30
@@ -626,33 +626,3 @@ class FirClassSubstitutionScope(
|
||||
return useSiteMemberScope.getClassifierNames()
|
||||
}
|
||||
}
|
||||
|
||||
// Unlike other cases, return types may be implicit, i.e. unresolved
|
||||
// But in that cases newType should also be `null`
|
||||
fun FirTypeRef.withReplacedReturnType(newType: ConeKotlinType?): FirTypeRef {
|
||||
require(this is FirResolvedTypeRef || newType == null)
|
||||
if (newType == null) return this
|
||||
|
||||
return buildResolvedTypeRef {
|
||||
source = this@withReplacedReturnType.source
|
||||
type = newType
|
||||
annotations += this@withReplacedReturnType.annotations
|
||||
}
|
||||
}
|
||||
|
||||
fun FirTypeRef.withReplacedConeType(
|
||||
newType: ConeKotlinType?,
|
||||
firFakeSourceElementKind: FirFakeSourceElementKind? = null
|
||||
): FirResolvedTypeRef {
|
||||
require(this is FirResolvedTypeRef)
|
||||
if (newType == null) return this
|
||||
|
||||
return buildResolvedTypeRef {
|
||||
source = if (firFakeSourceElementKind != null)
|
||||
this@withReplacedConeType.source?.fakeElement(firFakeSourceElementKind)
|
||||
else
|
||||
this@withReplacedConeType.source
|
||||
type = newType
|
||||
annotations += this@withReplacedConeType.annotations
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,18 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.types
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.classId
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||
import org.jetbrains.kotlin.fir.fakeElement
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLookupTagWithFixedSymbol
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||
import org.jetbrains.kotlin.resolve.calls.NewCommonSuperTypeCalculator
|
||||
@@ -174,6 +183,36 @@ fun FirTypeRef.isUnsafeVarianceType(session: FirSession): Boolean {
|
||||
return coneTypeSafe<ConeKotlinType>()?.isUnsafeVarianceType(session) == true
|
||||
}
|
||||
|
||||
// Unlike other cases, return types may be implicit, i.e. unresolved
|
||||
// But in that cases newType should also be `null`
|
||||
fun FirTypeRef.withReplacedReturnType(newType: ConeKotlinType?): FirTypeRef {
|
||||
require(this is FirResolvedTypeRef || newType == null)
|
||||
if (newType == null) return this
|
||||
|
||||
return buildResolvedTypeRef {
|
||||
source = this@withReplacedReturnType.source
|
||||
type = newType
|
||||
annotations += this@withReplacedReturnType.annotations
|
||||
}
|
||||
}
|
||||
|
||||
fun FirTypeRef.withReplacedConeType(
|
||||
newType: ConeKotlinType?,
|
||||
firFakeSourceElementKind: FirFakeSourceElementKind? = null
|
||||
): FirResolvedTypeRef {
|
||||
require(this is FirResolvedTypeRef)
|
||||
if (newType == null) return this
|
||||
|
||||
return buildResolvedTypeRef {
|
||||
source = if (firFakeSourceElementKind != null)
|
||||
this@withReplacedConeType.source?.fakeElement(firFakeSourceElementKind)
|
||||
else
|
||||
this@withReplacedConeType.source
|
||||
type = newType
|
||||
annotations += this@withReplacedConeType.annotations
|
||||
}
|
||||
}
|
||||
|
||||
fun FirTypeRef.approximated(
|
||||
typeApproximator: AbstractTypeApproximator,
|
||||
toSuper: Boolean,
|
||||
@@ -186,3 +225,77 @@ fun FirTypeRef.approximated(
|
||||
return withReplacedConeType(approximatedType as? ConeKotlinType)
|
||||
}
|
||||
|
||||
fun FirTypeRef.approximatedIfNeededOrSelf(
|
||||
approximator: AbstractTypeApproximator,
|
||||
containingCallableVisibility: Visibility?,
|
||||
isInlineFunction: Boolean = false
|
||||
): FirTypeRef {
|
||||
val approximatedType = if (this is FirResolvedTypeRef &&
|
||||
(containingCallableVisibility == Visibilities.Public || containingCallableVisibility == Visibilities.Protected)
|
||||
) {
|
||||
if (type.requiresApproximationInPublicPosition()) this.approximated(approximator, toSuper = true) else this
|
||||
} else {
|
||||
this
|
||||
}
|
||||
return approximatedType.hideLocalTypeIfNeeded(containingCallableVisibility, isInlineFunction)
|
||||
}
|
||||
|
||||
private fun ConeKotlinType.requiresApproximationInPublicPosition(): Boolean {
|
||||
return when (this) {
|
||||
is ConeIntegerLiteralType,
|
||||
is ConeCapturedType,
|
||||
is ConeDefinitelyNotNullType,
|
||||
is ConeIntersectionType -> true
|
||||
is ConeClassLikeType -> typeArguments.any {
|
||||
it is ConeKotlinTypeProjection && it.type.requiresApproximationInPublicPosition()
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Suppose a function without an explicit return type just returns an anonymous object:
|
||||
*
|
||||
* fun foo(...) = object : ObjectSuperType {
|
||||
* override fun ...
|
||||
* }
|
||||
*
|
||||
* Without unwrapping, the return type ended up with that anonymous object (<no name provided>), while the resolved super type, which
|
||||
* acts like an implementing interface, is a better fit. In fact, exposing an anonymous object types is prohibited for certain cases,
|
||||
* e.g., KT-33917. We can also apply this to any local types.
|
||||
*/
|
||||
private fun FirTypeRef.hideLocalTypeIfNeeded(
|
||||
containingCallableVisibility: Visibility?,
|
||||
isInlineFunction: Boolean = false
|
||||
): FirTypeRef {
|
||||
if (containingCallableVisibility == null) {
|
||||
return this
|
||||
}
|
||||
// Approximate types for non-private (all but package private or private) members.
|
||||
// Also private inline functions, as per KT-33917.
|
||||
if (containingCallableVisibility == Visibilities.Public ||
|
||||
containingCallableVisibility == Visibilities.Protected ||
|
||||
containingCallableVisibility == Visibilities.Internal ||
|
||||
(containingCallableVisibility == Visibilities.Private && isInlineFunction)
|
||||
) {
|
||||
val firClass =
|
||||
(((this as? FirResolvedTypeRef)
|
||||
?.type as? ConeClassLikeType)
|
||||
?.lookupTag as? ConeClassLookupTagWithFixedSymbol)
|
||||
?.symbol?.fir
|
||||
if (firClass?.classId?.isLocal != true) {
|
||||
return this
|
||||
}
|
||||
if (firClass.superTypeRefs.size > 1) {
|
||||
return buildErrorTypeRef {
|
||||
diagnostic = ConeSimpleDiagnostic("Cannot hide local type ${firClass.render()}")
|
||||
}
|
||||
}
|
||||
val superType = firClass.superTypeRefs.single()
|
||||
if (superType is FirResolvedTypeRef && !superType.isAny) {
|
||||
return superType
|
||||
}
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user