FIR: refactor delegating constructors resolve

This commit is contained in:
Mikhail Glukhikh
2021-03-10 18:57:19 +03:00
parent 8a9be56d07
commit 8b7b15f02b
3 changed files with 38 additions and 44 deletions
@@ -408,7 +408,6 @@ class BodyResolveContext(
inline fun <T> forConstructorBody(
constructor: FirConstructor,
parametersScope: FirLocalScope?,
crossinline f: () -> T
): T {
return if (constructor.isPrimary) {
@@ -418,12 +417,12 @@ class BodyResolveContext(
* special towerDataContext
*/
withTowerDataMode(FirTowerDataMode.CONSTRUCTOR_HEADER) {
parametersScope?.let { addLocalScope(it) }
getPrimaryConstructorAllParametersScope()?.let { addLocalScope(it) }
f()
}
} else {
withTowerDataCleanup {
parametersScope?.let { addLocalScope(it) }
addLocalScope(buildSecondaryConstructorParametersScope(constructor))
f()
}
}
@@ -616,17 +615,40 @@ class BodyResolveContext(
}
inline fun <T> forDelegatedConstructor(
parametersScope: FirLocalScope?,
constructor: FirConstructor,
owningClass: FirRegularClass?,
holder: SessionHolder,
crossinline f: () -> T
): T {
if (parametersScope == null) return f()
return withTowerDataCleanup {
addLocalScope(parametersScope)
f()
return withTowerDataMode(FirTowerDataMode.CONSTRUCTOR_HEADER) {
if (constructor.isPrimary) {
getPrimaryConstructorAllParametersScope()?.let {
withTowerDataCleanup {
addLocalScope(it)
f()
}
} ?: f()
} else {
if (owningClass != null) {
addReceiver(
null,
InaccessibleImplicitReceiverValue(
owningClass.symbol,
owningClass.defaultType(),
holder.session,
holder.scopeSession
)
)
}
withTowerDataCleanup {
addLocalScope(buildSecondaryConstructorParametersScope(constructor))
constructor.valueParameters.forEach { storeVariable(it) }
f()
}
}
}
}
fun buildConstructorParametersScope(constructor: FirConstructor): FirLocalScope? =
if (constructor.isPrimary) getPrimaryConstructorAllParametersScope()
else constructor.valueParameters.fold(FirLocalScope()) { acc, param -> acc.storeVariable(param) }
fun buildSecondaryConstructorParametersScope(constructor: FirConstructor): FirLocalScope =
constructor.valueParameters.fold(FirLocalScope()) { acc, param -> acc.storeVariable(param) }
}
@@ -552,11 +552,8 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
context.forConstructorParameters(constructor, owningClass, components) {
constructor.transformValueParameters(transformer, data)
}
val parametersScope = context.buildConstructorParametersScope(constructor)
context.forDelegatedConstructor(parametersScope) {
constructor.transformDelegatedConstructor(transformer, data)
}
context.forConstructorBody(constructor, parametersScope) {
constructor.transformDelegatedConstructor(transformer, data)
context.forConstructorBody(constructor) {
constructor.transformBody(transformer, data)
}
}
@@ -827,35 +827,10 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
var result = delegatedConstructorCall
try {
val lastDispatchReceiver = implicitReceiverStack.lastDispatchReceiver()
// because there's a `context.saveContextForAnonymousFunction(anonymousFunction)`
// call inside of the FirDeclarationResolveTransformer and accessing `this`
// inside a lambda which is a value parameter of a constructor delegate
// is prohibited
context.withTowerDataMode(FirTowerDataMode.CONSTRUCTOR_HEADER) {
context.withTowerDataCleanup {
if ((context.containerIfAny as? FirConstructor)?.isPrimary == true) {
context.getPrimaryConstructorAllParametersScope()?.let(context::addLocalScope)
}
// it's just a constructor parameters scope created in
// `FirDeclarationResolveTransformer::doTransformConstructor()`
context.towerDataContextsForClassParts.forMemberDeclaration.localScopes.lastOrNull()?.let(context::addLocalScope)
if (containingClass is FirRegularClass && !containingConstructor.isPrimary) {
context.addReceiver(
null,
InaccessibleImplicitReceiverValue(
containingClass.symbol,
containingClass.defaultType(),
session,
scopeSession
)
)
}
delegatedConstructorCall.transformChildren(transformer, ResolutionMode.ContextDependent)
}
context.forDelegatedConstructor(containingConstructor, containingClass as? FirRegularClass, components) {
delegatedConstructorCall.transformChildren(transformer, ResolutionMode.ContextDependent)
}
val reference = delegatedConstructorCall.calleeReference
val constructorType: ConeClassLikeType = when (reference) {
is FirThisReference -> {