FIR: Support rewritten implicit types calculator in IDE

Unlike the compiler, in the IDE different files may have different
resolve state.

So using ReturnTypeCalculatorForFullBodyResolve may be not correct there
This commit is contained in:
Denis Zharkov
2020-01-28 14:17:36 +03:00
parent c6c773f6f9
commit 70ce63c8d4
4 changed files with 41 additions and 33 deletions
@@ -127,8 +127,9 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb
override val integerLiteralTypeApproximator: IntegerLiteralTypeApproximationTransformer = override val integerLiteralTypeApproximator: IntegerLiteralTypeApproximationTransformer =
IntegerLiteralTypeApproximationTransformer(symbolProvider, inferenceComponents.ctx) IntegerLiteralTypeApproximationTransformer(symbolProvider, inferenceComponents.ctx)
override val integerOperatorsTypeUpdater: IntegerOperatorsTypeUpdater = IntegerOperatorsTypeUpdater(integerLiteralTypeApproximator) override val integerOperatorsTypeUpdater: IntegerOperatorsTypeUpdater = IntegerOperatorsTypeUpdater(integerLiteralTypeApproximator)
@PublishedApi
internal var containerIfAny: FirDeclaration? = null internal var containerIfAny: FirDeclaration? = null
private set
override var container: FirDeclaration override var container: FirDeclaration
get() = containerIfAny!! get() = containerIfAny!!
@@ -136,7 +137,7 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb
containerIfAny = value containerIfAny = value
} }
internal inline fun <T> withContainer(declaration: FirDeclaration, crossinline f: () -> T): T { inline fun <T> withContainer(declaration: FirDeclaration, crossinline f: () -> T): T {
val prevContainer = containerIfAny val prevContainer = containerIfAny
containerIfAny = declaration containerIfAny = declaration
val result = f() val result = f()
@@ -6,8 +6,6 @@
package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve
import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.resolve.ResolutionMode import org.jetbrains.kotlin.fir.resolve.ResolutionMode
@@ -16,33 +14,6 @@ import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
import org.jetbrains.kotlin.fir.visitors.FirTransformer import org.jetbrains.kotlin.fir.visitors.FirTransformer
import org.jetbrains.kotlin.fir.visitors.compose import org.jetbrains.kotlin.fir.visitors.compose
class FirDesignatedBodyResolveTransformer(
private val designation: Iterator<FirElement>,
session: FirSession,
scopeSession: ScopeSession = ScopeSession(),
implicitTypeOnly: Boolean = true
) : FirBodyResolveTransformer(
session,
phase = FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE,
implicitTypeOnly = implicitTypeOnly,
scopeSession = scopeSession
) {
override fun <E : FirElement> transformElement(element: E, data: ResolutionMode): CompositeTransformResult<E> {
if (designation.hasNext()) {
designation.next().visitNoTransform(this, data)
return element.compose()
}
return super.transformElement(element, data)
}
override fun transformDeclaration(declaration: FirDeclaration, data: ResolutionMode): CompositeTransformResult<FirDeclaration> {
return components.withContainer(declaration) {
declaration.replaceResolvePhase(transformerPhase)
transformElement(declaration, data)
}
}
}
@Deprecated("It is temp", level = DeprecationLevel.WARNING, replaceWith = ReplaceWith("TODO(\"что-то нормальное\")")) @Deprecated("It is temp", level = DeprecationLevel.WARNING, replaceWith = ReplaceWith("TODO(\"что-то нормальное\")"))
class FirBodyResolveTransformerAdapter : FirTransformer<Nothing?>() { class FirBodyResolveTransformerAdapter : FirTransformer<Nothing?>() {
private val scopeSession = ScopeSession() private val scopeSession = ScopeSession()
@@ -49,6 +49,9 @@ class FirImplicitTypeBodyResolveTransformerAdapter : FirTransformer<Nothing?>()
} }
} }
fun createReturnTypeCalculatorForIDE(session: FirSession, scopeSession: ScopeSession): ReturnTypeCalculator =
ReturnTypeCalculatorWithJump(session, scopeSession, ImplicitBodyResolveComputationSession())
// TODO: This class is unused because it's effectively unneeded while we have mutable trees // TODO: This class is unused because it's effectively unneeded while we have mutable trees
// Once we decide to switch to persistent trees this, it should be applied to each file // Once we decide to switch to persistent trees this, it should be applied to each file
// If the decision is to stay with mutable trees, this class should be removed // If the decision is to stay with mutable trees, this class should be removed
@@ -8,21 +8,26 @@ package org.jetbrains.kotlin.idea.fir
import com.intellij.openapi.progress.ProgressIndicatorProvider import com.intellij.openapi.progress.ProgressIndicatorProvider
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.psi import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.fir.references.* import org.jetbrains.kotlin.fir.references.*
import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.FirProvider import org.jetbrains.kotlin.fir.resolve.FirProvider
import org.jetbrains.kotlin.fir.resolve.ResolutionMode import org.jetbrains.kotlin.fir.resolve.ResolutionMode
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.getClassDeclaredCallableSymbols import org.jetbrains.kotlin.fir.resolve.getClassDeclaredCallableSymbols
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirDesignatedBodyResolveTransformer import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirBodyResolveTransformer
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.createReturnTypeCalculatorForIDE
import org.jetbrains.kotlin.fir.resolve.transformers.runResolve import org.jetbrains.kotlin.fir.resolve.transformers.runResolve
import org.jetbrains.kotlin.fir.scopes.impl.FirPackageMemberScope import org.jetbrains.kotlin.fir.scopes.impl.FirPackageMemberScope
import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
import org.jetbrains.kotlin.fir.types.FirUserTypeRef import org.jetbrains.kotlin.fir.types.FirUserTypeRef
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
import org.jetbrains.kotlin.fir.visitors.compose
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -188,13 +193,41 @@ private fun FirDeclaration.runResolve(
if (designation.all { it.resolvePhase >= toPhase }) { if (designation.all { it.resolvePhase >= toPhase }) {
return return
} }
val transformer = FirDesignatedBodyResolveTransformer( val transformer = FirDesignatedBodyResolveTransformerForIDE(
designation.iterator(), state.getSession(psi as KtElement), designation.iterator(), state.getSession(psi as KtElement),
implicitTypeOnly = toPhase == FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE implicitTypeOnly = toPhase == FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE
) )
file.transform<FirFile, ResolutionMode>(transformer, ResolutionMode.ContextDependent) file.transform<FirFile, ResolutionMode>(transformer, ResolutionMode.ContextDependent)
} }
private class FirDesignatedBodyResolveTransformerForIDE(
private val designation: Iterator<FirElement>,
session: FirSession,
scopeSession: ScopeSession = ScopeSession(),
implicitTypeOnly: Boolean = true
) : FirBodyResolveTransformer(
session,
phase = FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE,
implicitTypeOnly = implicitTypeOnly,
scopeSession = scopeSession,
returnTypeCalculator = createReturnTypeCalculatorForIDE(session, scopeSession)
) {
override fun <E : FirElement> transformElement(element: E, data: ResolutionMode): CompositeTransformResult<E> {
if (designation.hasNext()) {
designation.next().visitNoTransform(this, data)
return element.compose()
}
return super.transformElement(element, data)
}
override fun transformDeclaration(declaration: FirDeclaration, data: ResolutionMode): CompositeTransformResult<FirDeclaration> {
return components.withContainer(declaration) {
declaration.replaceResolvePhase(transformerPhase)
transformElement(declaration, data)
}
}
}
fun KtElement.getOrBuildFir( fun KtElement.getOrBuildFir(
state: FirModuleResolveState, state: FirModuleResolveState,
phase: FirResolvePhase = FirResolvePhase.BODY_RESOLVE phase: FirResolvePhase = FirResolvePhase.BODY_RESOLVE