FIR IDE: do not mark declaration with some lazy resolve phase if only some children are resolved to that phase
Otherwise, we will not be able to resolve parent one
This commit is contained in:
+8
@@ -60,6 +60,14 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb
|
|||||||
context.addLocalScope(localScope)
|
context.addLocalScope(localScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected open fun needReplacePhase(firDeclaration: FirDeclaration) = true
|
||||||
|
|
||||||
|
fun replaceDeclarationResolvePhaseIfNeeded(firDeclaration: FirDeclaration, newResolvePhase: FirResolvePhase) {
|
||||||
|
if (needReplacePhase(firDeclaration)) {
|
||||||
|
firDeclaration.replaceResolvePhase(newResolvePhase)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@OptIn(PrivateForInline::class)
|
@OptIn(PrivateForInline::class)
|
||||||
internal inline fun <T> withFullBodyResolve(crossinline l: () -> T): T {
|
internal inline fun <T> withFullBodyResolve(crossinline l: () -> T): T {
|
||||||
val shouldSwitchMode = implicitTypeOnly
|
val shouldSwitchMode = implicitTypeOnly
|
||||||
|
|||||||
+8
-8
@@ -57,7 +57,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
|||||||
): CompositeTransformResult<FirDeclaration> {
|
): CompositeTransformResult<FirDeclaration> {
|
||||||
transformer.onBeforeDeclarationContentResolve(declaration)
|
transformer.onBeforeDeclarationContentResolve(declaration)
|
||||||
return context.withContainer(declaration) {
|
return context.withContainer(declaration) {
|
||||||
declaration.replaceResolvePhase(transformerPhase)
|
transformer.replaceDeclarationResolvePhaseIfNeeded(declaration, transformerPhase)
|
||||||
transformer.transformDeclarationContent(declaration, data)
|
transformer.transformDeclarationContent(declaration, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -84,7 +84,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
|||||||
if (declaration.typeParameters.isEmpty()) return null
|
if (declaration.typeParameters.isEmpty()) return null
|
||||||
|
|
||||||
for (typeParameter in declaration.typeParameters) {
|
for (typeParameter in declaration.typeParameters) {
|
||||||
(typeParameter as? FirTypeParameter)?.replaceResolvePhase(FirResolvePhase.STATUS)
|
(typeParameter as? FirTypeParameter)?.let { transformer.replaceDeclarationResolvePhaseIfNeeded(it, FirResolvePhase.STATUS) }
|
||||||
typeParameter.transformChildren(transformer, ResolutionMode.ContextIndependent)
|
typeParameter.transformChildren(transformer, ResolutionMode.ContextIndependent)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,7 +115,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
|||||||
if (returnTypeRef !is FirImplicitTypeRef && implicitTypeOnly) return@withTypeParametersOf property.compose()
|
if (returnTypeRef !is FirImplicitTypeRef && implicitTypeOnly) return@withTypeParametersOf property.compose()
|
||||||
if (property.resolvePhase == transformerPhase) return@withTypeParametersOf property.compose()
|
if (property.resolvePhase == transformerPhase) return@withTypeParametersOf property.compose()
|
||||||
if (property.resolvePhase == FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE && transformerPhase == FirResolvePhase.BODY_RESOLVE) {
|
if (property.resolvePhase == FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE && transformerPhase == FirResolvePhase.BODY_RESOLVE) {
|
||||||
property.replaceResolvePhase(transformerPhase)
|
transformer.replaceDeclarationResolvePhaseIfNeeded(property, transformerPhase)
|
||||||
return@withTypeParametersOf property.compose()
|
return@withTypeParametersOf property.compose()
|
||||||
}
|
}
|
||||||
dataFlowAnalyzer.enterProperty(property)
|
dataFlowAnalyzer.enterProperty(property)
|
||||||
@@ -142,7 +142,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
property.replaceResolvePhase(transformerPhase)
|
transformer.replaceDeclarationResolvePhaseIfNeeded(property, transformerPhase)
|
||||||
dataFlowAnalyzer.exitProperty(property)?.let {
|
dataFlowAnalyzer.exitProperty(property)?.let {
|
||||||
property.replaceControlFlowGraphReference(FirControlFlowGraphReferenceImpl(it))
|
property.replaceControlFlowGraphReference(FirControlFlowGraphReferenceImpl(it))
|
||||||
}
|
}
|
||||||
@@ -267,7 +267,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
|||||||
variable.transformAccessors()
|
variable.transformAccessors()
|
||||||
}
|
}
|
||||||
context.storeVariable(variable)
|
context.storeVariable(variable)
|
||||||
variable.replaceResolvePhase(transformerPhase)
|
transformer.replaceDeclarationResolvePhaseIfNeeded(variable, transformerPhase)
|
||||||
dataFlowAnalyzer.exitLocalVariableDeclaration(variable)
|
dataFlowAnalyzer.exitLocalVariableDeclaration(variable)
|
||||||
return variable.compose()
|
return variable.compose()
|
||||||
}
|
}
|
||||||
@@ -449,7 +449,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
|||||||
): CompositeTransformResult<FirSimpleFunction> {
|
): CompositeTransformResult<FirSimpleFunction> {
|
||||||
if (simpleFunction.resolvePhase == transformerPhase) return simpleFunction.compose()
|
if (simpleFunction.resolvePhase == transformerPhase) return simpleFunction.compose()
|
||||||
if (simpleFunction.resolvePhase == FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE && transformerPhase == FirResolvePhase.BODY_RESOLVE) {
|
if (simpleFunction.resolvePhase == FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE && transformerPhase == FirResolvePhase.BODY_RESOLVE) {
|
||||||
simpleFunction.replaceResolvePhase(transformerPhase)
|
transformer.replaceDeclarationResolvePhaseIfNeeded(simpleFunction, transformerPhase)
|
||||||
return simpleFunction.compose()
|
return simpleFunction.compose()
|
||||||
}
|
}
|
||||||
val returnTypeRef = simpleFunction.returnTypeRef
|
val returnTypeRef = simpleFunction.returnTypeRef
|
||||||
@@ -546,7 +546,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
|||||||
|
|
||||||
private fun doTransformConstructor(constructor: FirConstructor, data: ResolutionMode): CompositeTransformResult<FirConstructor> {
|
private fun doTransformConstructor(constructor: FirConstructor, data: ResolutionMode): CompositeTransformResult<FirConstructor> {
|
||||||
return context.withContainer(constructor) {
|
return context.withContainer(constructor) {
|
||||||
constructor.replaceResolvePhase(transformerPhase)
|
transformer.replaceDeclarationResolvePhaseIfNeeded(constructor, transformerPhase)
|
||||||
dataFlowAnalyzer.enterFunction(constructor)
|
dataFlowAnalyzer.enterFunction(constructor)
|
||||||
|
|
||||||
constructor.transformTypeParameters(transformer, data)
|
constructor.transformTypeParameters(transformer, data)
|
||||||
@@ -640,7 +640,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
|||||||
override fun transformValueParameter(valueParameter: FirValueParameter, data: ResolutionMode): CompositeTransformResult<FirStatement> {
|
override fun transformValueParameter(valueParameter: FirValueParameter, data: ResolutionMode): CompositeTransformResult<FirStatement> {
|
||||||
context.storeVariable(valueParameter)
|
context.storeVariable(valueParameter)
|
||||||
if (valueParameter.returnTypeRef is FirImplicitTypeRef) {
|
if (valueParameter.returnTypeRef is FirImplicitTypeRef) {
|
||||||
valueParameter.replaceResolvePhase(transformerPhase)
|
transformer.replaceDeclarationResolvePhaseIfNeeded(valueParameter, transformerPhase)
|
||||||
return valueParameter.compose()
|
return valueParameter.compose()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -275,7 +275,7 @@ open class FirContractResolveTransformer(
|
|||||||
get() = contractDescription is FirLegacyRawContractDescription || contractDescription is FirRawContractDescription
|
get() = contractDescription is FirLegacyRawContractDescription || contractDescription is FirRawContractDescription
|
||||||
|
|
||||||
private fun FirDeclaration.updatePhase() {
|
private fun FirDeclaration.updatePhase() {
|
||||||
replaceResolvePhase(FirResolvePhase.CONTRACTS)
|
replaceDeclarationResolvePhaseIfNeeded(this, FirResolvePhase.CONTRACTS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-1
@@ -155,7 +155,13 @@ internal class FirLazyDeclarationResolver(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val transformer = phase.createLazyTransformer(designation, containerFirFile, scopeSession, towerDataContextCollector)
|
val transformer = phase.createLazyTransformer(
|
||||||
|
designation,
|
||||||
|
firDeclarationToResolve,
|
||||||
|
containerFirFile,
|
||||||
|
scopeSession,
|
||||||
|
towerDataContextCollector
|
||||||
|
)
|
||||||
|
|
||||||
firFileBuilder.firPhaseRunner.runPhaseWithCustomResolve(phase) {
|
firFileBuilder.firPhaseRunner.runPhaseWithCustomResolve(phase) {
|
||||||
containerFirFile.transform<FirFile, ResolutionMode>(transformer, ResolutionMode.ContextDependent)
|
containerFirFile.transform<FirFile, ResolutionMode>(transformer, ResolutionMode.ContextDependent)
|
||||||
@@ -164,22 +170,26 @@ internal class FirLazyDeclarationResolver(
|
|||||||
|
|
||||||
private fun FirResolvePhase.createLazyTransformer(
|
private fun FirResolvePhase.createLazyTransformer(
|
||||||
designation: List<FirDeclaration>,
|
designation: List<FirDeclaration>,
|
||||||
|
targetDeclaration: FirDeclaration,
|
||||||
containerFirFile: FirFile,
|
containerFirFile: FirFile,
|
||||||
scopeSession: ScopeSession,
|
scopeSession: ScopeSession,
|
||||||
towerDataContextCollector: FirTowerDataContextCollector?
|
towerDataContextCollector: FirTowerDataContextCollector?
|
||||||
) = when (this) {
|
) = when (this) {
|
||||||
FirResolvePhase.CONTRACTS -> FirDesignatedContractsResolveTransformerForIDE(
|
FirResolvePhase.CONTRACTS -> FirDesignatedContractsResolveTransformerForIDE(
|
||||||
designation.iterator(),
|
designation.iterator(),
|
||||||
|
targetDeclaration,
|
||||||
containerFirFile.session,
|
containerFirFile.session,
|
||||||
scopeSession,
|
scopeSession,
|
||||||
)
|
)
|
||||||
FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE -> FirDesignatedImplicitTypesTransformerForIDE(
|
FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE -> FirDesignatedImplicitTypesTransformerForIDE(
|
||||||
designation.iterator(),
|
designation.iterator(),
|
||||||
|
targetDeclaration,
|
||||||
containerFirFile.session,
|
containerFirFile.session,
|
||||||
scopeSession,
|
scopeSession,
|
||||||
)
|
)
|
||||||
FirResolvePhase.BODY_RESOLVE -> FirDesignatedBodyResolveTransformerForIDE(
|
FirResolvePhase.BODY_RESOLVE -> FirDesignatedBodyResolveTransformerForIDE(
|
||||||
designation.iterator(),
|
designation.iterator(),
|
||||||
|
targetDeclaration,
|
||||||
containerFirFile.session,
|
containerFirFile.session,
|
||||||
scopeSession,
|
scopeSession,
|
||||||
towerDataContextCollector
|
towerDataContextCollector
|
||||||
|
|||||||
+7
-3
@@ -21,7 +21,8 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.FirIdeDesigna
|
|||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.FirTowerDataContextCollector
|
import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.FirTowerDataContextCollector
|
||||||
|
|
||||||
internal class FirDesignatedBodyResolveTransformerForIDE(
|
internal class FirDesignatedBodyResolveTransformerForIDE(
|
||||||
private val designation: Iterator<FirElement>,
|
private val designation: Iterator<FirDeclaration>,
|
||||||
|
targetDeclaration: FirDeclaration,
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
scopeSession: ScopeSession,
|
scopeSession: ScopeSession,
|
||||||
private val towerDataContextCollector: FirTowerDataContextCollector? = null
|
private val towerDataContextCollector: FirTowerDataContextCollector? = null
|
||||||
@@ -37,10 +38,11 @@ internal class FirDesignatedBodyResolveTransformerForIDE(
|
|||||||
::FirIdeDesignatedBodyResolveTransformerForReturnTypeCalculator
|
::FirIdeDesignatedBodyResolveTransformerForReturnTypeCalculator
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
|
private val phaseReplaceOracle = PhaseReplaceOracle(targetDeclaration)
|
||||||
|
|
||||||
override fun transformDeclarationContent(declaration: FirDeclaration, data: ResolutionMode): CompositeTransformResult<FirDeclaration> {
|
override fun transformDeclarationContent(declaration: FirDeclaration, data: ResolutionMode): CompositeTransformResult<FirDeclaration> {
|
||||||
if (designation.hasNext()) {
|
if (designation.hasNext()) phaseReplaceOracle.transformDeclarationInside(designation.next()) {
|
||||||
designation.next().visitNoTransform(this, data)
|
it.visitNoTransform(this, data)
|
||||||
return declaration.compose()
|
return declaration.compose()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,4 +56,6 @@ internal class FirDesignatedBodyResolveTransformerForIDE(
|
|||||||
override fun onBeforeStatementResolution(statement: FirStatement) {
|
override fun onBeforeStatementResolution(statement: FirStatement) {
|
||||||
towerDataContextCollector?.addStatementContext(statement, context.towerDataContext)
|
towerDataContextCollector?.addStatementContext(statement, context.towerDataContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun needReplacePhase(firDeclaration: FirDeclaration): Boolean = phaseReplaceOracle.needReplacePhase(firDeclaration)
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-3
@@ -15,16 +15,20 @@ import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
|
|||||||
import org.jetbrains.kotlin.fir.visitors.compose
|
import org.jetbrains.kotlin.fir.visitors.compose
|
||||||
|
|
||||||
internal class FirDesignatedContractsResolveTransformerForIDE(
|
internal class FirDesignatedContractsResolveTransformerForIDE(
|
||||||
private val designation: Iterator<FirElement>,
|
private val designation: Iterator<FirDeclaration>,
|
||||||
|
targetDeclaration: FirDeclaration,
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
scopeSession: ScopeSession,
|
scopeSession: ScopeSession,
|
||||||
) : FirContractResolveTransformer(session, scopeSession) {
|
) : FirContractResolveTransformer(session, scopeSession) {
|
||||||
|
private val phaseReplaceOracle = PhaseReplaceOracle(targetDeclaration)
|
||||||
|
|
||||||
override fun transformDeclarationContent(declaration: FirDeclaration, data: ResolutionMode): CompositeTransformResult<FirDeclaration> {
|
override fun transformDeclarationContent(declaration: FirDeclaration, data: ResolutionMode): CompositeTransformResult<FirDeclaration> {
|
||||||
if (designation.hasNext()) {
|
if (designation.hasNext()) phaseReplaceOracle.transformDeclarationInside(designation.next()) {
|
||||||
designation.next().visitNoTransform(this, data)
|
it.visitNoTransform(this, data)
|
||||||
return declaration.compose()
|
return declaration.compose()
|
||||||
}
|
}
|
||||||
return super.transformDeclarationContent(declaration, data)
|
return super.transformDeclarationContent(declaration, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun needReplacePhase(firDeclaration: FirDeclaration): Boolean = phaseReplaceOracle.needReplacePhase(firDeclaration)
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-3
@@ -19,7 +19,8 @@ import org.jetbrains.kotlin.fir.visitors.compose
|
|||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.FirIdeDesignatedBodyResolveTransformerForReturnTypeCalculator
|
import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.FirIdeDesignatedBodyResolveTransformerForReturnTypeCalculator
|
||||||
|
|
||||||
internal class FirDesignatedImplicitTypesTransformerForIDE(
|
internal class FirDesignatedImplicitTypesTransformerForIDE(
|
||||||
private val designation: Iterator<FirElement>,
|
private val designation: Iterator<FirDeclaration>,
|
||||||
|
targetDeclaration: FirDeclaration,
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
scopeSession: ScopeSession,
|
scopeSession: ScopeSession,
|
||||||
implicitBodyResolveComputationSession: ImplicitBodyResolveComputationSession = ImplicitBodyResolveComputationSession(),
|
implicitBodyResolveComputationSession: ImplicitBodyResolveComputationSession = ImplicitBodyResolveComputationSession(),
|
||||||
@@ -36,12 +37,15 @@ internal class FirDesignatedImplicitTypesTransformerForIDE(
|
|||||||
::FirIdeDesignatedBodyResolveTransformerForReturnTypeCalculator
|
::FirIdeDesignatedBodyResolveTransformerForReturnTypeCalculator
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
|
private val phaseReplaceOracle = PhaseReplaceOracle(targetDeclaration)
|
||||||
|
|
||||||
override fun transformDeclarationContent(declaration: FirDeclaration, data: ResolutionMode): CompositeTransformResult<FirDeclaration> {
|
override fun transformDeclarationContent(declaration: FirDeclaration, data: ResolutionMode): CompositeTransformResult<FirDeclaration> {
|
||||||
if (designation.hasNext()) {
|
if (designation.hasNext()) phaseReplaceOracle.transformDeclarationInside(designation.next()) {
|
||||||
designation.next().visitNoTransform(this, data)
|
it.visitNoTransform(this, data)
|
||||||
return declaration.compose()
|
return declaration.compose()
|
||||||
}
|
}
|
||||||
return super.transformDeclarationContent(declaration, data)
|
return super.transformDeclarationContent(declaration, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun needReplacePhase(firDeclaration: FirDeclaration): Boolean = phaseReplaceOracle.needReplacePhase(firDeclaration)
|
||||||
}
|
}
|
||||||
|
|||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.fir.low.level.api.trasformers
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||||
|
|
||||||
|
internal class PhaseReplaceOracle(private val targetDeclaration: FirDeclaration) {
|
||||||
|
private var isInsideCurrentDeclaration = false
|
||||||
|
|
||||||
|
fun needReplacePhase(firDeclaration: FirDeclaration): Boolean =
|
||||||
|
isInsideCurrentDeclaration
|
||||||
|
|
||||||
|
inline fun <T> transformDeclarationInside(declaration: FirDeclaration, transform: (FirDeclaration) -> T): T {
|
||||||
|
if (declaration == targetDeclaration) isInsideCurrentDeclaration = true
|
||||||
|
return try {
|
||||||
|
transform(declaration)
|
||||||
|
} finally {
|
||||||
|
if (declaration == targetDeclaration) isInsideCurrentDeclaration = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
FILE: classMembers.kt
|
FILE: classMembers.kt
|
||||||
public final [BODY_RESOLVE] class A : R|kotlin/Any| {
|
public final [CONTRACTS] class A : R|kotlin/Any| {
|
||||||
public [CONTRACTS] constructor(): R|A| {
|
public [CONTRACTS] constructor(): R|A| {
|
||||||
super<R|kotlin/Any|>()
|
super<R|kotlin/Any|>()
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
FILE: main.kt
|
FILE: main.kt
|
||||||
public final [BODY_RESOLVE] class WithElvis : R|kotlin/Any| {
|
public final [CONTRACTS] class WithElvis : R|kotlin/Any| {
|
||||||
public [CONTRACTS] constructor(value: R|kotlin/String?|): R|elvis/WithElvis| {
|
public [CONTRACTS] constructor(value: R|kotlin/String?|): R|elvis/WithElvis| {
|
||||||
super<R|kotlin/Any|>()
|
super<R|kotlin/Any|>()
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
FILE: main.kt
|
FILE: main.kt
|
||||||
public final [BODY_RESOLVE] class Foo : R|kotlin/Any| {
|
public final [CONTRACTS] class Foo : R|kotlin/Any| {
|
||||||
public final [CONTRACTS] val x: R|kotlin/Int|
|
public final [CONTRACTS] val x: R|kotlin/Int|
|
||||||
public get(): R|kotlin/Int|
|
public get(): R|kotlin/Int|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user