FIR: extract BodyResolveContext.withConstructor in variations
This commit is contained in:
@@ -132,7 +132,7 @@ class ImplicitExtensionReceiverValue(
|
|||||||
) : ImplicitReceiverValue<FirCallableSymbol<*>>(boundSymbol, type, useSiteSession, scopeSession)
|
) : ImplicitReceiverValue<FirCallableSymbol<*>>(boundSymbol, type, useSiteSession, scopeSession)
|
||||||
|
|
||||||
|
|
||||||
class InaccessibleImplicitReceiverValue internal constructor(
|
class InaccessibleImplicitReceiverValue(
|
||||||
boundSymbol: FirClassSymbol<*>,
|
boundSymbol: FirClassSymbol<*>,
|
||||||
type: ConeKotlinType,
|
type: ConeKotlinType,
|
||||||
useSiteSession: FirSession,
|
useSiteSession: FirSession,
|
||||||
|
|||||||
+69
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.expressions.FirExpression
|
|||||||
import org.jetbrains.kotlin.fir.resolve.*
|
import org.jetbrains.kotlin.fir.resolve.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.ImplicitExtensionReceiverValue
|
import org.jetbrains.kotlin.fir.resolve.calls.ImplicitExtensionReceiverValue
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.ImplicitReceiverValue
|
import org.jetbrains.kotlin.fir.resolve.calls.ImplicitReceiverValue
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.calls.InaccessibleImplicitReceiverValue
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.ResolutionContext
|
import org.jetbrains.kotlin.fir.resolve.calls.ResolutionContext
|
||||||
import org.jetbrains.kotlin.fir.resolve.dfa.DataFlowAnalyzerContext
|
import org.jetbrains.kotlin.fir.resolve.dfa.DataFlowAnalyzerContext
|
||||||
import org.jetbrains.kotlin.fir.resolve.dfa.PersistentFlow
|
import org.jetbrains.kotlin.fir.resolve.dfa.PersistentFlow
|
||||||
@@ -490,4 +491,72 @@ class BodyResolveContext(
|
|||||||
if (typeParameters.isEmpty()) return null
|
if (typeParameters.isEmpty()) return null
|
||||||
return FirMemberTypeParameterScope(this)
|
return FirMemberTypeParameterScope(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline fun <T> withConstructor(constructor: FirConstructor, crossinline f: () -> T): T =
|
||||||
|
withContainer(constructor, f)
|
||||||
|
|
||||||
|
inline fun <T> forConstructorParameters(
|
||||||
|
constructor: FirConstructor,
|
||||||
|
owningClass: FirRegularClass?,
|
||||||
|
holder: SessionHolder,
|
||||||
|
crossinline f: () -> T
|
||||||
|
): T {
|
||||||
|
// Default values of constructor can't access members of constructing class
|
||||||
|
return withTowerDataMode(FirTowerDataMode.CONSTRUCTOR_HEADER) {
|
||||||
|
if (owningClass != null && !constructor.isPrimary) {
|
||||||
|
addReceiver(
|
||||||
|
null,
|
||||||
|
InaccessibleImplicitReceiverValue(
|
||||||
|
owningClass.symbol,
|
||||||
|
owningClass.defaultType(),
|
||||||
|
holder.session,
|
||||||
|
holder.scopeSession
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
withTowerDataCleanup {
|
||||||
|
addLocalScope(FirLocalScope())
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <T> forDelegatedConstructor(
|
||||||
|
constructor: FirConstructor,
|
||||||
|
parametersScope: FirLocalScope? = buildConstructorParametersScope(constructor),
|
||||||
|
crossinline f: () -> T
|
||||||
|
): T {
|
||||||
|
if (parametersScope == null) return f()
|
||||||
|
return withTowerDataCleanup {
|
||||||
|
addLocalScope(parametersScope)
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <T> forConstructorBody(
|
||||||
|
constructor: FirConstructor,
|
||||||
|
parametersScope: FirLocalScope? = buildConstructorParametersScope(constructor),
|
||||||
|
crossinline f: () -> T
|
||||||
|
): T {
|
||||||
|
return if (constructor.isPrimary) {
|
||||||
|
/*
|
||||||
|
* Primary constructor may have body only if class delegates implementation to some property
|
||||||
|
* In it's body we don't have this receiver for building class, so we need to use
|
||||||
|
* special towerDataContext
|
||||||
|
*/
|
||||||
|
withTowerDataMode(FirTowerDataMode.CONSTRUCTOR_HEADER) {
|
||||||
|
parametersScope?.let { addLocalScope(it) }
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
withTowerDataCleanup {
|
||||||
|
parametersScope?.let { addLocalScope(it) }
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun buildConstructorParametersScope(constructor: FirConstructor): FirLocalScope? =
|
||||||
|
if (constructor.isPrimary) getPrimaryConstructorAllParametersScope()
|
||||||
|
else constructor.valueParameters.fold(FirLocalScope()) { acc, param -> acc.storeVariable(param) }
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-65
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
|||||||
import org.jetbrains.kotlin.fir.resolve.*
|
import org.jetbrains.kotlin.fir.resolve.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate
|
import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.ImplicitExtensionReceiverValue
|
import org.jetbrains.kotlin.fir.resolve.calls.ImplicitExtensionReceiverValue
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.InaccessibleImplicitReceiverValue
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.dfa.FirControlFlowGraphReferenceImpl
|
import org.jetbrains.kotlin.fir.resolve.dfa.FirControlFlowGraphReferenceImpl
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.extractLambdaInfoFromFunctionalType
|
import org.jetbrains.kotlin.fir.resolve.inference.extractLambdaInfoFromFunctionalType
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.isSuspendFunctionType
|
import org.jetbrains.kotlin.fir.resolve.inference.isSuspendFunctionType
|
||||||
@@ -568,74 +567,32 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
|||||||
|
|
||||||
private fun doTransformConstructor(constructor: FirConstructor, data: ResolutionMode): CompositeTransformResult<FirConstructor> {
|
private fun doTransformConstructor(constructor: FirConstructor, data: ResolutionMode): CompositeTransformResult<FirConstructor> {
|
||||||
val owningClass = context.containerIfAny as? FirRegularClass
|
val owningClass = context.containerIfAny as? FirRegularClass
|
||||||
return context.withContainer(constructor) {
|
|
||||||
transformer.replaceDeclarationResolvePhaseIfNeeded(constructor, transformerPhase)
|
|
||||||
dataFlowAnalyzer.enterFunction(constructor)
|
|
||||||
|
|
||||||
constructor.transformTypeParameters(transformer, data)
|
transformer.replaceDeclarationResolvePhaseIfNeeded(constructor, transformerPhase)
|
||||||
.transformAnnotations(transformer, data)
|
dataFlowAnalyzer.enterFunction(constructor)
|
||||||
.transformReceiverTypeRef(transformer, data)
|
|
||||||
.transformReturnTypeRef(transformer, data)
|
|
||||||
|
|
||||||
/*
|
constructor.transformTypeParameters(transformer, data)
|
||||||
* Default values of constructor can't access members of constructing class
|
.transformAnnotations(transformer, data)
|
||||||
*/
|
.transformReceiverTypeRef(transformer, data)
|
||||||
context.withTowerDataMode(FirTowerDataMode.CONSTRUCTOR_HEADER) {
|
.transformReturnTypeRef(transformer, data)
|
||||||
if (owningClass != null && !constructor.isPrimary) {
|
|
||||||
context.addReceiver(
|
context.withConstructor(constructor) {
|
||||||
null,
|
context.forConstructorParameters(constructor, owningClass, components) {
|
||||||
InaccessibleImplicitReceiverValue(
|
constructor.transformValueParameters(transformer, data)
|
||||||
owningClass.symbol,
|
|
||||||
owningClass.defaultType(),
|
|
||||||
session,
|
|
||||||
scopeSession
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
withNewLocalScope {
|
|
||||||
constructor.transformValueParameters(transformer, data)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
val parametersScope = context.buildConstructorParametersScope(constructor)
|
||||||
val scopeWithValueParameters = if (constructor.isPrimary) {
|
context.forDelegatedConstructor(constructor, parametersScope) {
|
||||||
context.getPrimaryConstructorAllParametersScope()
|
|
||||||
} else {
|
|
||||||
constructor.scopeWithParameters()
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Delegated constructor call is called before constructor body, so we need to
|
|
||||||
* analyze it before body, so body can access smartcasts from that call
|
|
||||||
*/
|
|
||||||
withLocalScope(scopeWithValueParameters) {
|
|
||||||
constructor.transformDelegatedConstructor(transformer, data)
|
constructor.transformDelegatedConstructor(transformer, data)
|
||||||
}
|
}
|
||||||
|
context.forConstructorBody(constructor, parametersScope) {
|
||||||
if (constructor.body != null) {
|
constructor.transformBody(transformer, data)
|
||||||
if (constructor.isPrimary) {
|
|
||||||
/*
|
|
||||||
* Primary constructor may have body only if class delegates implementation to some property
|
|
||||||
* In it's body we don't have this receiver for building class, so we need to use
|
|
||||||
* special towerDataContext
|
|
||||||
*/
|
|
||||||
context.withTowerDataMode(FirTowerDataMode.CONSTRUCTOR_HEADER) {
|
|
||||||
addLocalScope(scopeWithValueParameters)
|
|
||||||
constructor.transformBody(transformer, data)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
withLocalScopeCleanup {
|
|
||||||
addLocalScope(scopeWithValueParameters)
|
|
||||||
constructor.transformBody(transformer, data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val controlFlowGraphReference = dataFlowAnalyzer.exitFunction(constructor)
|
|
||||||
constructor.replaceControlFlowGraphReference(controlFlowGraphReference)
|
|
||||||
constructor.compose()
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
val controlFlowGraphReference = dataFlowAnalyzer.exitFunction(constructor)
|
||||||
|
constructor.replaceControlFlowGraphReference(controlFlowGraphReference)
|
||||||
|
return constructor.compose()
|
||||||
|
}
|
||||||
|
|
||||||
override fun transformAnonymousInitializer(
|
override fun transformAnonymousInitializer(
|
||||||
anonymousInitializer: FirAnonymousInitializer,
|
anonymousInitializer: FirAnonymousInitializer,
|
||||||
@@ -843,10 +800,6 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirConstructor.scopeWithParameters(): FirLocalScope {
|
|
||||||
return valueParameters.fold(FirLocalScope()) { acc, param -> acc.storeVariable(param) }
|
|
||||||
}
|
|
||||||
|
|
||||||
protected inline fun <T> withLabelAndReceiverType(
|
protected inline fun <T> withLabelAndReceiverType(
|
||||||
labelName: Name?,
|
labelName: Name?,
|
||||||
owner: FirCallableDeclaration<*>,
|
owner: FirCallableDeclaration<*>,
|
||||||
|
|||||||
Reference in New Issue
Block a user