FIR: fix type approximation by visibility
This commit is contained in:
+52
-54
@@ -6,6 +6,8 @@
|
||||
package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
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
|
||||
@@ -45,6 +47,17 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
||||
private var containingClass: FirRegularClass? = null
|
||||
private val statusResolver: FirStatusResolver = FirStatusResolver(session, scopeSession)
|
||||
|
||||
private fun FirDeclaration.visibilityForApproximation(): Visibility {
|
||||
if (this !is FirMemberDeclaration) return Visibilities.Local
|
||||
val container = context.containers.getOrNull(context.containers.size - 2)
|
||||
val containerVisibility =
|
||||
if (container == null) Visibilities.Public
|
||||
else (container as? FirRegularClass)?.visibility ?: Visibilities.Local
|
||||
if (containerVisibility == Visibilities.Local || visibility == Visibilities.Local) return Visibilities.Local
|
||||
if (containerVisibility == Visibilities.Private) return Visibilities.Private
|
||||
return visibility
|
||||
}
|
||||
|
||||
private inline fun <T> withFirArrayOfCallTransformer(block: () -> T): T {
|
||||
transformer.expressionsTransformer.enableArrayOfCallTransformation = true
|
||||
return try {
|
||||
@@ -560,7 +573,9 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
||||
transformer,
|
||||
withExpectedType(
|
||||
returnExpression.resultType.approximatedIfNeededOrSelf(
|
||||
inferenceComponents.approximator, simpleFunction?.visibility, simpleFunction?.isInline == true
|
||||
inferenceComponents.approximator,
|
||||
simpleFunction?.visibilityForApproximation(),
|
||||
simpleFunction?.isInline == true
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -990,67 +1005,50 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
||||
private fun storeVariableReturnType(variable: FirVariable<*>) {
|
||||
val initializer = variable.initializer
|
||||
if (variable.returnTypeRef is FirImplicitTypeRef) {
|
||||
when {
|
||||
val resultType = when {
|
||||
initializer != null -> {
|
||||
val unwrappedInitializer = (initializer as? FirExpressionWithSmartcast)?.originalExpression ?: initializer
|
||||
val expectedType = when (val resultType = unwrappedInitializer.resultType) {
|
||||
is FirImplicitTypeRef -> buildErrorTypeRef {
|
||||
diagnostic = ConeSimpleDiagnostic("No result type for initializer", DiagnosticKind.InferenceError)
|
||||
}
|
||||
else -> {
|
||||
buildResolvedTypeRef {
|
||||
type = resultType.coneType
|
||||
annotations.addAll(resultType.annotations)
|
||||
resultType.source?.fakeElement(FirFakeSourceElementKind.PropertyFromParameter)?.let {
|
||||
source = it
|
||||
}
|
||||
unwrappedInitializer.resultType
|
||||
}
|
||||
variable.getter != null && variable.getter !is FirDefaultPropertyAccessor -> variable.getter?.returnTypeRef
|
||||
else -> null
|
||||
}
|
||||
if (resultType != null) {
|
||||
val expectedType = when (resultType) {
|
||||
is FirImplicitTypeRef -> buildErrorTypeRef {
|
||||
diagnostic = ConeSimpleDiagnostic("No result type for initializer", DiagnosticKind.InferenceError)
|
||||
}
|
||||
else -> {
|
||||
buildResolvedTypeRef {
|
||||
type = resultType.coneType
|
||||
annotations.addAll(resultType.annotations)
|
||||
resultType.source?.fakeElement(FirFakeSourceElementKind.PropertyFromParameter)?.let {
|
||||
source = it
|
||||
}
|
||||
}
|
||||
}
|
||||
variable.transformReturnTypeRef(
|
||||
transformer,
|
||||
withExpectedType(
|
||||
expectedType.approximatedIfNeededOrSelf(inferenceComponents.approximator, (variable as? FirProperty)?.visibility)
|
||||
}
|
||||
variable.transformReturnTypeRef(
|
||||
transformer,
|
||||
withExpectedType(
|
||||
expectedType.approximatedIfNeededOrSelf(
|
||||
inferenceComponents.approximator,
|
||||
variable.visibilityForApproximation()
|
||||
)
|
||||
)
|
||||
}
|
||||
variable.getter != null && variable.getter !is FirDefaultPropertyAccessor -> {
|
||||
val expectedType = when (val resultType = variable.getter?.returnTypeRef) {
|
||||
is FirImplicitTypeRef -> buildErrorTypeRef {
|
||||
diagnostic = ConeSimpleDiagnostic("No result type for getter", DiagnosticKind.InferenceError)
|
||||
}
|
||||
else -> {
|
||||
resultType?.let {
|
||||
buildResolvedTypeRef {
|
||||
type = resultType.coneType
|
||||
annotations.addAll(resultType.annotations)
|
||||
resultType.source?.fakeElement(FirFakeSourceElementKind.PropertyFromParameter)?.let {
|
||||
source = it
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
variable.transformReturnTypeRef(
|
||||
transformer,
|
||||
withExpectedType(
|
||||
expectedType?.approximatedIfNeededOrSelf(inferenceComponents.approximator, (variable as? FirProperty)?.visibility)
|
||||
)
|
||||
)
|
||||
} else {
|
||||
variable.transformReturnTypeRef(
|
||||
transformer,
|
||||
withExpectedType(
|
||||
buildErrorTypeRef {
|
||||
diagnostic = ConeSimpleDiagnostic(
|
||||
"Cannot infer variable type without initializer / getter / delegate",
|
||||
DiagnosticKind.InferenceError,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
variable.transformReturnTypeRef(
|
||||
transformer,
|
||||
withExpectedType(
|
||||
buildErrorTypeRef {
|
||||
diagnostic = ConeSimpleDiagnostic(
|
||||
"Cannot infer variable type without initializer / getter / delegate",
|
||||
DiagnosticKind.InferenceError,
|
||||
)
|
||||
},
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
if (variable.getter?.returnTypeRef is FirImplicitTypeRef) {
|
||||
variable.getter?.transformReturnTypeRef(transformer, withExpectedType(variable.returnTypeRef))
|
||||
|
||||
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.fir.types
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.declarations.classId
|
||||
import org.jetbrains.kotlin.fir.declarations.FirAnonymousObject
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||
@@ -309,7 +309,8 @@ private fun FirTypeRef.hideLocalTypeIfNeeded(
|
||||
?.type as? ConeClassLikeType)
|
||||
?.lookupTag as? ConeClassLookupTagWithFixedSymbol)
|
||||
?.symbol?.fir
|
||||
if (firClass?.classId?.isLocal != true) {
|
||||
if (firClass !is FirAnonymousObject) {
|
||||
// NB: local classes are acceptable here, but reported by EXPOSED_* checkers as errors
|
||||
return this
|
||||
}
|
||||
if (firClass.superTypeRefs.size > 1) {
|
||||
@@ -318,7 +319,7 @@ private fun FirTypeRef.hideLocalTypeIfNeeded(
|
||||
}
|
||||
}
|
||||
val superType = firClass.superTypeRefs.single()
|
||||
if (superType is FirResolvedTypeRef && !superType.isAny) {
|
||||
if (superType is FirResolvedTypeRef) {
|
||||
return superType
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user