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( inline fun <T> forConstructorBody(
constructor: FirConstructor, constructor: FirConstructor,
parametersScope: FirLocalScope?,
crossinline f: () -> T crossinline f: () -> T
): T { ): T {
return if (constructor.isPrimary) { return if (constructor.isPrimary) {
@@ -418,12 +417,12 @@ class BodyResolveContext(
* special towerDataContext * special towerDataContext
*/ */
withTowerDataMode(FirTowerDataMode.CONSTRUCTOR_HEADER) { withTowerDataMode(FirTowerDataMode.CONSTRUCTOR_HEADER) {
parametersScope?.let { addLocalScope(it) } getPrimaryConstructorAllParametersScope()?.let { addLocalScope(it) }
f() f()
} }
} else { } else {
withTowerDataCleanup { withTowerDataCleanup {
parametersScope?.let { addLocalScope(it) } addLocalScope(buildSecondaryConstructorParametersScope(constructor))
f() f()
} }
} }
@@ -616,17 +615,40 @@ class BodyResolveContext(
} }
inline fun <T> forDelegatedConstructor( inline fun <T> forDelegatedConstructor(
parametersScope: FirLocalScope?, constructor: FirConstructor,
owningClass: FirRegularClass?,
holder: SessionHolder,
crossinline f: () -> T crossinline f: () -> T
): T { ): T {
if (parametersScope == null) return f() return withTowerDataMode(FirTowerDataMode.CONSTRUCTOR_HEADER) {
return withTowerDataCleanup { if (constructor.isPrimary) {
addLocalScope(parametersScope) getPrimaryConstructorAllParametersScope()?.let {
f() 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? = fun buildSecondaryConstructorParametersScope(constructor: FirConstructor): FirLocalScope =
if (constructor.isPrimary) getPrimaryConstructorAllParametersScope() constructor.valueParameters.fold(FirLocalScope()) { acc, param -> acc.storeVariable(param) }
else constructor.valueParameters.fold(FirLocalScope()) { acc, param -> acc.storeVariable(param) }
} }
@@ -552,11 +552,8 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
context.forConstructorParameters(constructor, owningClass, components) { context.forConstructorParameters(constructor, owningClass, components) {
constructor.transformValueParameters(transformer, data) constructor.transformValueParameters(transformer, data)
} }
val parametersScope = context.buildConstructorParametersScope(constructor) constructor.transformDelegatedConstructor(transformer, data)
context.forDelegatedConstructor(parametersScope) { context.forConstructorBody(constructor) {
constructor.transformDelegatedConstructor(transformer, data)
}
context.forConstructorBody(constructor, parametersScope) {
constructor.transformBody(transformer, data) constructor.transformBody(transformer, data)
} }
} }
@@ -827,35 +827,10 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
var result = delegatedConstructorCall var result = delegatedConstructorCall
try { try {
val lastDispatchReceiver = implicitReceiverStack.lastDispatchReceiver() val lastDispatchReceiver = implicitReceiverStack.lastDispatchReceiver()
context.forDelegatedConstructor(containingConstructor, containingClass as? FirRegularClass, components) {
// because there's a `context.saveContextForAnonymousFunction(anonymousFunction)` delegatedConstructorCall.transformChildren(transformer, ResolutionMode.ContextDependent)
// 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)
}
} }
val reference = delegatedConstructorCall.calleeReference val reference = delegatedConstructorCall.calleeReference
val constructorType: ConeClassLikeType = when (reference) { val constructorType: ConeClassLikeType = when (reference) {
is FirThisReference -> { is FirThisReference -> {