FIR: Fix VerifyError caused by private delegates

^KT-45048 Fixed
This commit is contained in:
Denis.Zharkov
2021-02-20 15:01:57 +03:00
parent ace66b7179
commit 4fffe7b9c8
13 changed files with 153 additions and 45 deletions
@@ -284,10 +284,6 @@ abstract class AbstractFirStatusResolveTransformer(
return when (declaration) {
is FirCallableDeclaration<*> -> {
when (declaration) {
is FirProperty -> {
declaration.getter?.let { transformPropertyAccessor(it, data) }
declaration.setter?.let { transformPropertyAccessor(it, data) }
}
is FirFunction<*> -> {
for (valueParameter in declaration.valueParameters) {
transformValueParameter(valueParameter, data)
@@ -296,9 +292,6 @@ abstract class AbstractFirStatusResolveTransformer(
}
declaration.compose()
}
is FirPropertyAccessor -> {
declaration.compose()
}
else -> {
transformElement(declaration, data)
}
@@ -433,13 +426,16 @@ abstract class AbstractFirStatusResolveTransformer(
statusComputationSession.endComputing(regularClass)
}
override fun transformPropertyAccessor(
private fun transformPropertyAccessor(
propertyAccessor: FirPropertyAccessor,
data: FirResolvedDeclarationStatus?
): CompositeTransformResult<FirDeclaration> {
propertyAccessor.transformStatus(this, statusResolver.resolveStatus(propertyAccessor, containingClass, isLocal = false))
@Suppress("UNCHECKED_CAST")
return transformDeclaration(propertyAccessor, data)
containingProperty: FirProperty,
) {
propertyAccessor.transformStatus(
this,
statusResolver.resolveStatus(propertyAccessor, containingClass, containingProperty, isLocal = false)
)
propertyAccessor.replaceResolvePhase(transformerPhase)
}
override fun transformConstructor(
@@ -465,7 +461,11 @@ abstract class AbstractFirStatusResolveTransformer(
): CompositeTransformResult<FirDeclaration> {
property.replaceResolvePhase(transformerPhase)
property.transformStatus(this, statusResolver.resolveStatus(property, containingClass, isLocal = false))
return transformDeclaration(property, data)
property.getter?.let { transformPropertyAccessor(it, property) }
property.setter?.let { transformPropertyAccessor(it, property) }
return property.compose()
}
override fun transformField(
@@ -17,7 +17,6 @@ import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
class FirStatusResolver(
val session: FirSession,
@@ -36,11 +35,16 @@ class FirStatusResolver(
FirDeclarationStatusImpl.Modifier.values().toList() - NOT_INHERITED_MODIFIERS
}
fun resolveStatus(declaration: FirDeclaration, containingClass: FirClass<*>?, isLocal: Boolean): FirResolvedDeclarationStatus {
fun resolveStatus(
declaration: FirDeclaration,
containingClass: FirClass<*>?,
containingProperty: FirProperty?,
isLocal: Boolean
): FirResolvedDeclarationStatus {
return when (declaration) {
is FirProperty -> resolveStatus(declaration, containingClass, isLocal)
is FirSimpleFunction -> resolveStatus(declaration, containingClass, isLocal)
is FirPropertyAccessor -> resolveStatus(declaration, containingClass, isLocal)
is FirPropertyAccessor -> resolveStatus(declaration, containingClass, containingProperty, isLocal)
is FirRegularClass -> resolveStatus(declaration, containingClass, isLocal)
is FirTypeAlias -> resolveStatus(declaration, containingClass, isLocal)
is FirConstructor -> resolveStatus(declaration, containingClass, isLocal)
@@ -51,7 +55,7 @@ class FirStatusResolver(
@OptIn(ExperimentalStdlibApi::class)
fun resolveStatus(property: FirProperty, containingClass: FirClass<*>?, isLocal: Boolean): FirResolvedDeclarationStatus {
return resolveStatus(property, property.status, containingClass, isLocal) l@{
return resolveStatus(property, property.status, containingClass, null, isLocal) l@{
if (containingClass == null) return@l emptyList()
@Suppress("RemoveExplicitTypeArguments") // Workaround for KT-42175
buildList<FirProperty> {
@@ -69,7 +73,7 @@ class FirStatusResolver(
@OptIn(ExperimentalStdlibApi::class)
fun resolveStatus(function: FirSimpleFunction, containingClass: FirClass<*>?, isLocal: Boolean): FirResolvedDeclarationStatus {
return resolveStatus(function, function.status, containingClass, isLocal) l@{
return resolveStatus(function, function.status, containingClass, null, isLocal) l@{
if (containingClass == null) return@l emptyList()
@Suppress("RemoveExplicitTypeArguments") // Workaround for KT-42175
buildList<FirCallableMemberDeclaration<*>> {
@@ -91,7 +95,7 @@ class FirStatusResolver(
containingClass: FirClass<*>?,
isLocal: Boolean
): FirResolvedDeclarationStatus {
return resolveStatus(regularClass, regularClass.status, containingClass, isLocal) { emptyList() }
return resolveStatus(regularClass, regularClass.status, containingClass, null, isLocal) { emptyList() }
}
fun resolveStatus(
@@ -99,33 +103,35 @@ class FirStatusResolver(
containingClass: FirClass<*>?,
isLocal: Boolean
): FirResolvedDeclarationStatus {
return resolveStatus(typeAlias, typeAlias.status, containingClass, isLocal) { emptyList() }
return resolveStatus(typeAlias, typeAlias.status, containingClass, null, isLocal) { emptyList() }
}
fun resolveStatus(
propertyAccessor: FirPropertyAccessor,
containingClass: FirClass<*>?,
containingProperty: FirProperty?,
isLocal: Boolean
): FirResolvedDeclarationStatus {
return resolveStatus(propertyAccessor, propertyAccessor.status, containingClass, isLocal) { emptyList() }
return resolveStatus(propertyAccessor, propertyAccessor.status, containingClass, containingProperty, isLocal) { emptyList() }
}
fun resolveStatus(constructor: FirConstructor, containingClass: FirClass<*>?, isLocal: Boolean): FirResolvedDeclarationStatus {
return resolveStatus(constructor, constructor.status, containingClass, isLocal) { emptyList() }
return resolveStatus(constructor, constructor.status, containingClass, null, isLocal) { emptyList() }
}
fun resolveStatus(field: FirField, containingClass: FirClass<*>?, isLocal: Boolean): FirResolvedDeclarationStatus {
return resolveStatus(field, field.status, containingClass, isLocal) { emptyList() }
return resolveStatus(field, field.status, containingClass, null, isLocal) { emptyList() }
}
fun resolveStatus(enumEntry: FirEnumEntry, containingClass: FirClass<*>?, isLocal: Boolean): FirResolvedDeclarationStatus {
return resolveStatus(enumEntry, enumEntry.status, containingClass, isLocal) { emptyList() }
return resolveStatus(enumEntry, enumEntry.status, containingClass, null, isLocal) { emptyList() }
}
private inline fun resolveStatus(
declaration: FirDeclaration,
status: FirDeclarationStatus,
containingClass: FirClass<*>?,
containingProperty: FirProperty?,
isLocal: Boolean,
overriddenExtractor: () -> List<FirResolvedDeclarationStatus>
): FirResolvedDeclarationStatus {
@@ -137,7 +143,7 @@ class FirStatusResolver(
val visibility = when (status.visibility) {
Visibilities.Unknown -> when {
isLocal -> Visibilities.Local
else -> resolveVisibility(declaration, containingClass, overriddenStatuses)
else -> resolveVisibility(declaration, containingClass, containingProperty, overriddenStatuses)
}
else -> status.visibility
}
@@ -162,14 +168,20 @@ class FirStatusResolver(
private fun resolveVisibility(
declaration: FirDeclaration,
containingClass: FirClass<*>?,
containingProperty: FirProperty?,
overriddenStatuses: List<FirResolvedDeclarationStatusImpl>
): Visibility {
if (declaration is FirConstructor && containingClass?.hasPrivateConstructor() == true) return Visibilities.Private
val fallbackVisibility = when {
declaration is FirPropertyAccessor && containingProperty != null -> containingProperty.visibility
else -> Visibilities.Public
}
return overriddenStatuses.map { it.visibility }
.maxWithOrNull { v1, v2 -> Visibilities.compare(v1, v2) ?: -1 }
?.normalize()
?: Visibilities.Public
?: fallbackVisibility
}
private fun FirClass<*>.hasPrivateConstructor(): Boolean {
@@ -126,8 +126,8 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
if (property.isLocal) {
prepareSignatureForBodyResolve(property)
property.transformStatus(this, property.resolveStatus().mode())
property.getter?.let { it.transformStatus(this, it.resolveStatus().mode()) }
property.setter?.let { it.transformStatus(this, it.resolveStatus().mode()) }
property.getter?.let { it.transformStatus(this, it.resolveStatus(containingProperty = property).mode()) }
property.setter?.let { it.transformStatus(this, it.resolveStatus(containingProperty = property).mode()) }
return transformLocalVariable(property)
}
@@ -380,11 +380,15 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
}
}
private fun FirDeclaration.resolveStatus(containingClass: FirClass<*>? = null): FirDeclarationStatus {
private fun FirDeclaration.resolveStatus(
containingClass: FirClass<*>? = null,
containingProperty: FirProperty? = null,
): FirDeclarationStatus {
val containingDeclaration = context.containerIfAny
return statusResolver.resolveStatus(
this,
containingClass as? FirRegularClass,
containingProperty,
isLocal = containingDeclaration != null && containingClass == null
)
}