[FIR IDE] Add types, supertypes and status lazy designated transformers

This commit is contained in:
Igor Yakovlev
2021-05-04 17:03:17 +02:00
committed by TeamCityServer
parent 95acb6121b
commit 779a06e86f
12 changed files with 289 additions and 47 deletions
@@ -109,7 +109,7 @@ class FirStatusResolveTransformer(
}
}
private class FirDesignatedStatusResolveTransformer(
open class FirDesignatedStatusResolveTransformer(
session: FirSession,
scopeSession: ScopeSession,
private val designation: Iterator<FirDeclaration>,
@@ -245,7 +245,7 @@ abstract class AbstractFirStatusResolveTransformer(
protected val designationMapForLocalClasses: Map<FirClassLikeDeclaration<*>, FirClassLikeDeclaration<*>?>,
private val scopeForLocalClass: FirScope?
) : FirAbstractTreeTransformer<FirResolvedDeclarationStatus?>(phase = FirResolvePhase.STATUS) {
private val classes = mutableListOf<FirClass<*>>()
protected val classes = mutableListOf<FirClass<*>>()
protected val statusResolver = FirStatusResolver(session, scopeSession)
protected val containingClass: FirClass<*>? get() = classes.lastOrNull()
@@ -279,7 +279,7 @@ abstract class AbstractFirStatusResolveTransformer(
return (data ?: declarationStatus)
}
private inline fun storeClass(
protected inline fun storeClass(
klass: FirClass<*>,
computeResult: () -> FirDeclaration
): FirDeclaration {
@@ -26,10 +26,12 @@ import org.jetbrains.kotlin.fir.scopes.getNestedClassifierScope
import org.jetbrains.kotlin.fir.scopes.impl.FirMemberTypeParameterScope
import org.jetbrains.kotlin.fir.scopes.impl.nestedClassifierScope
import org.jetbrains.kotlin.fir.scopes.impl.wrapNestedClassifierScopeWithSubstitutionForSuperType
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
import org.jetbrains.kotlin.fir.visitors.*
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
@@ -37,11 +39,11 @@ class FirSupertypeResolverProcessor(session: FirSession, scopeSession: ScopeSess
override val transformer = FirSupertypeResolverTransformer(session, scopeSession)
}
class FirSupertypeResolverTransformer(
override val session: FirSession,
open class FirSupertypeResolverTransformer(
final override val session: FirSession,
scopeSession: ScopeSession
) : FirAbstractPhaseTransformer<Any?>(FirResolvePhase.SUPER_TYPES) {
private val supertypeComputationSession = SupertypeComputationSession()
protected val supertypeComputationSession = SupertypeComputationSession()
private val supertypeResolverVisitor = FirSupertypeResolverVisitor(session, supertypeComputationSession, scopeSession)
private val applySupertypesTransformer = FirApplySupertypesTransformer(supertypeComputationSession)
@@ -78,7 +80,7 @@ fun <F : FirClassLikeDeclaration<F>> F.runSupertypeResolvePhaseForLocalClass(
return this.transform<F, Nothing?>(applySupertypesTransformer, null)
}
private class FirApplySupertypesTransformer(
class FirApplySupertypesTransformer(
private val supertypeComputationSession: SupertypeComputationSession
) : FirDefaultTransformer<Any?>() {
override fun <E : FirElement> transformElement(element: E, data: Any?): E {
@@ -170,7 +172,7 @@ fun FirRegularClass.resolveSupertypesInTheAir(session: FirSession): List<FirType
.resolveSpecificClassLikeSupertypes(this, superTypeRefs)
}
private class FirSupertypeResolverVisitor(
open class FirSupertypeResolverVisitor(
private val session: FirSession,
private val supertypeComputationSession: SupertypeComputationSession,
private val scopeSession: ScopeSession,
@@ -179,6 +181,12 @@ private class FirSupertypeResolverVisitor(
) : FirDefaultVisitor<Unit, Any?>() {
private val supertypeGenerationExtensions = session.extensionService.supertypeGenerators
open fun getFirClassifierContainerFile(symbol: FirClassLikeSymbol<*>): FirFile =
session.firProvider.getFirClassifierContainerFile(symbol.classId)
open fun getFirClassifierByFqName(classId: ClassId): FirClassLikeDeclaration<*>? =
session.firProvider.getFirClassifierByFqName(classId)
override fun visitElement(element: FirElement, data: Any?) {}
private fun prepareFileScopes(file: FirFile): ScopePersistentList {
@@ -207,7 +215,7 @@ private class FirSupertypeResolverVisitor(
for (supertype in supertypes) {
if (supertype !is ConeClassLikeType) continue
val fir = session.firProvider.getFirClassifierByFqName(supertype.lookupTag.classId) ?: continue
val fir = getFirClassifierByFqName(supertype.lookupTag.classId) ?: continue
resolveAllSupertypes(fir, fir.supertypeRefs(), visited)
}
}
@@ -235,10 +243,10 @@ private class FirSupertypeResolverVisitor(
}
}
classId.isNestedClass -> {
val outerClassFir = classId.outerClassId?.let(session.firProvider::getFirClassifierByFqName) as? FirRegularClass
val outerClassFir = classId.outerClassId?.let(::getFirClassifierByFqName) as? FirRegularClass
prepareScopeForNestedClasses(outerClassFir ?: return persistentListOf())
}
else -> prepareFileScopes(session.firProvider.getFirClassifierContainerFile(classLikeDeclaration.symbol))
else -> prepareFileScopes(getFirClassifierContainerFile(classLikeDeclaration.symbol))
}
return result.pushIfNotNull(classLikeDeclaration.typeParametersScope())
@@ -282,7 +290,7 @@ private class FirSupertypeResolverVisitor(
return resolveSpecificClassLikeSupertypes(classLikeDeclaration) { transformer, scope ->
if (!classLikeDeclaration.isLocalClassOrAnonymousObject()) {
session.lookupTracker?.let {
val fileSource = session.firProvider.getFirClassifierContainerFile(classLikeDeclaration.symbol).source
val fileSource = getFirClassifierContainerFile(classLikeDeclaration.symbol).source
for (supertypeRef in supertypeRefs) {
it.recordTypeLookup(supertypeRef, scope.scopeOwnerLookupNames, fileSource)
}
@@ -364,7 +372,7 @@ private fun createErrorTypeRef(fir: FirElement, message: String) = buildErrorTyp
diagnostic = ConeSimpleDiagnostic(message)
}
private class SupertypeComputationSession {
class SupertypeComputationSession {
private val fileScopesMap = hashMapOf<FirFile, ScopePersistentList>()
private val scopesForNestedClassesMap = hashMapOf<FirClass<*>, ScopePersistentList>()
private val supertypeStatusMap = linkedMapOf<FirClassLikeDeclaration<*>, SupertypeComputationStatus>()
@@ -37,7 +37,7 @@ fun <F : FirClassLikeDeclaration<F>> F.runTypeResolvePhaseForLocalClass(
return this.transform<F, Nothing?>(transformer, null)
}
class FirTypeResolveTransformer(
open class FirTypeResolveTransformer(
override val session: FirSession,
scopeSession: ScopeSession,
initialScopes: List<FirScope> = emptyList()
@@ -15,15 +15,17 @@ import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirBodyResolveTransformer
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.ImplicitBodyResolveComputationSession
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.createReturnTypeCalculatorForIDE
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirDeclarationDesignation
import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.FirIdeDesignatedBodyResolveTransformerForReturnTypeCalculator
import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.FirTowerDataContextCollector
internal class FirDesignatedBodyResolveTransformerForIDE(
designation: FirDesignation,
private val firFile: FirFile,
designation: FirDeclarationDesignation,
session: FirSession,
scopeSession: ScopeSession,
private val towerDataContextCollector: FirTowerDataContextCollector? = null
) : FirBodyResolveTransformer(
) : FirLazyTransformerForIDE, FirBodyResolveTransformer(
session,
phase = FirResolvePhase.BODY_RESOLVE,
implicitTypeOnly = false,
@@ -35,7 +37,7 @@ internal class FirDesignatedBodyResolveTransformerForIDE(
::FirIdeDesignatedBodyResolveTransformerForReturnTypeCalculator
)
) {
private val ideDeclarationTransformer = IDEDeclarationTransformer(designation)
private val ideDeclarationTransformer = IDEDeclarationTransformer(designation.toDesignationIterator())
@Suppress("NAME_SHADOWING")
override fun transformDeclarationContent(declaration: FirDeclaration, data: ResolutionMode): FirDeclaration =
@@ -57,5 +59,9 @@ internal class FirDesignatedBodyResolveTransformerForIDE(
override fun needReplacePhase(firDeclaration: FirDeclaration): Boolean =
ideDeclarationTransformer.needReplacePhase(firDeclaration)
override fun transformDeclaration() {
firFile.transform<FirFile, ResolutionMode>(this, ResolutionMode.ContextDependent)
}
}
@@ -7,16 +7,19 @@ package org.jetbrains.kotlin.idea.fir.low.level.api.trasformers
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.resolve.ResolutionMode
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.transformers.contracts.FirContractResolveTransformer
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirDeclarationDesignation
internal class FirDesignatedContractsResolveTransformerForIDE(
designation: FirDesignation,
private val firFile: FirFile,
designation: FirDeclarationDesignation,
session: FirSession,
scopeSession: ScopeSession,
) : FirContractResolveTransformer(session, scopeSession) {
private val ideDeclarationTransformer = IDEDeclarationTransformer(designation)
) : FirLazyTransformerForIDE, FirContractResolveTransformer(session, scopeSession) {
private val ideDeclarationTransformer = IDEDeclarationTransformer(designation.toDesignationIterator())
@Suppress("NAME_SHADOWING")
override fun transformDeclarationContent(declaration: FirDeclaration, data: ResolutionMode): FirDeclaration =
@@ -26,4 +29,8 @@ internal class FirDesignatedContractsResolveTransformerForIDE(
override fun needReplacePhase(firDeclaration: FirDeclaration): Boolean = ideDeclarationTransformer.needReplacePhase(firDeclaration)
override fun transformDeclaration() {
firFile.transform<FirFile, ResolutionMode>(this, ResolutionMode.ContextDependent)
}
}
@@ -7,23 +7,23 @@ package org.jetbrains.kotlin.idea.fir.low.level.api.trasformers
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.FirResolvePhase
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirImplicitAwareBodyResolveTransformer
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.ImplicitBodyResolveComputationSession
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.createReturnTypeCalculatorForIDE
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirDeclarationDesignation
import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.FirIdeDesignatedBodyResolveTransformerForReturnTypeCalculator
import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.FirTowerDataContextCollector
internal class FirDesignatedImplicitTypesTransformerForIDE(
designation: FirDesignation,
private val firFile: FirFile,
designation: FirDeclarationDesignation,
session: FirSession,
scopeSession: ScopeSession,
private val towerDataContextCollector: FirTowerDataContextCollector?,
implicitBodyResolveComputationSession: ImplicitBodyResolveComputationSession = ImplicitBodyResolveComputationSession(),
) : FirImplicitAwareBodyResolveTransformer(
) : FirLazyTransformerForIDE, FirImplicitAwareBodyResolveTransformer(
session,
implicitBodyResolveComputationSession = implicitBodyResolveComputationSession,
phase = FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE,
@@ -36,7 +36,7 @@ internal class FirDesignatedImplicitTypesTransformerForIDE(
::FirIdeDesignatedBodyResolveTransformerForReturnTypeCalculator
)
) {
private val ideDeclarationTransformer = IDEDeclarationTransformer(designation)
private val ideDeclarationTransformer = IDEDeclarationTransformer(designation.toDesignationIterator())
@Suppress("NAME_SHADOWING")
override fun transformDeclarationContent(declaration: FirDeclaration, data: ResolutionMode): FirDeclaration =
@@ -44,14 +44,9 @@ internal class FirDesignatedImplicitTypesTransformerForIDE(
super.transformDeclarationContent(declaration, data)
}
override fun needReplacePhase(firDeclaration: FirDeclaration): Boolean = ideDeclarationTransformer.needReplacePhase(firDeclaration)
override fun onBeforeStatementResolution(statement: FirStatement) {
towerDataContextCollector?.addStatementContext(statement, context.towerDataContext)
}
override fun onBeforeDeclarationContentResolve(declaration: FirDeclaration) {
towerDataContextCollector?.addDeclarationContext(declaration, context.towerDataContext)
override fun transformDeclaration() {
firFile.transform<FirFile, ResolutionMode>(this, ResolutionMode.ContextDependent)
}
}
@@ -0,0 +1,90 @@
/*
* Copyright 2010-2021 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.FirSession
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.transformers.FirDesignatedStatusResolveTransformer
import org.jetbrains.kotlin.fir.resolve.transformers.FirStatusResolveTransformer
import org.jetbrains.kotlin.fir.resolve.transformers.StatusComputationSession
import org.jetbrains.kotlin.fir.visitors.transformSingle
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirDeclarationDesignation
import org.jetbrains.kotlin.idea.fir.low.level.api.trasformers.FirLazyTransformerForIDE.Companion.ensurePhase
class FirDesignatedStatusResolveTransformerForIDE(
private val designation: FirDeclarationDesignation,
private val session: FirSession,
private val scopeSession: ScopeSession,
): FirLazyTransformerForIDE {
private fun resolveClass(targetClass: FirClass<*>) {
val transformer = FirDesignatedStatusResolveTransformer(
session = session,
scopeSession = scopeSession,
designation = designation.fullDesignation.iterator(),
targetClass = targetClass,
statusComputationSession = StatusComputationSession.Regular(),
designationMapForLocalClasses = emptyMap(),
scopeForLocalClass = null)
val firstClass = designation.fullDesignation.first()
firstClass.transformSingle(transformer, null)
}
private fun resolveTopLevelMethod(targetCallable: FirCallableDeclaration<*>) {
val transformer = FirStatusResolveTransformer(
session = session,
scopeSession = scopeSession,
statusComputationSession = StatusComputationSession.Regular()
)
targetCallable.transformSingle(transformer, null)
}
private fun resolveClassMember(containingClass: FirClass<*>, targetCallable: FirCallableDeclaration<*>) {
val transformer = object : FirDesignatedStatusResolveTransformer(
session = session,
scopeSession = scopeSession,
designation = designation.fullDesignation.iterator(),
targetClass = containingClass,
statusComputationSession = StatusComputationSession.Regular(),
designationMapForLocalClasses = emptyMap(),
scopeForLocalClass = null) {
override fun <F : FirClass<F>> transformClass(
klass: FirClass<F>,
data: FirResolvedDeclarationStatus?
): FirStatement {
return storeClass(klass) {
targetCallable.transformSingle(this, data)
} as FirStatement
}
}
val firstClass = designation.fullDesignation.first()
firstClass.transformSingle(transformer, null)
}
override fun transformDeclaration() {
designation.ensurePhase(FirResolvePhase.STATUS, exceptLast = true)
when(val resolveTarget = designation.declaration) {
is FirClass<*> -> resolveClass(resolveTarget)
is FirCallableDeclaration<*> -> {
val containingClass = designation.path.lastOrNull()
if (containingClass == null) {
check(designation.fullDesignation.size == 1) { "Invalid designation - should be single element designation for top level declaration" }
resolveTopLevelMethod(resolveTarget)
} else {
check(containingClass is FirClass<*>) { "Invalid designation - the parent of callable is not a class" }
resolveClassMember(containingClass, resolveTarget)
}
}
else -> error("Declaration should be ${FirClass::class.simpleName} but given ${resolveTarget::class.simpleName}")
}
}
}
@@ -0,0 +1,62 @@
/*
* Copyright 2010-2021 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.FirElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.firProvider
import org.jetbrains.kotlin.fir.resolve.transformers.FirApplySupertypesTransformer
import org.jetbrains.kotlin.fir.resolve.transformers.FirSupertypeResolverVisitor
import org.jetbrains.kotlin.fir.resolve.transformers.SupertypeComputationSession
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirDeclarationDesignation
import org.jetbrains.kotlin.idea.fir.low.level.api.trasformers.FirLazyTransformerForIDE.Companion.ensurePhase
import org.jetbrains.kotlin.name.ClassId
internal class FirDesignatedSupertypeResolverTransformerForIDE(
private val designation: FirDeclarationDesignation,
private val firFile: FirFile,
private val session: FirSession,
private val scopeSession: ScopeSession,
) : FirLazyTransformerForIDE {
private val supertypeComputationSession = SupertypeComputationSession()
private inner class SupertypeResolver(
private val symbolSet: Set<FirClassLikeSymbol<*>>,
private val classIdToElementMap: Map<ClassId, FirClassLikeDeclaration<*>>
) : FirSupertypeResolverVisitor(session, supertypeComputationSession, scopeSession) {
override fun getFirClassifierContainerFile(symbol: FirClassLikeSymbol<*>): FirFile =
if (symbolSet.contains(symbol)) firFile else session.firProvider.getFirClassifierContainerFile(symbol)
override fun getFirClassifierByFqName(classId: ClassId): FirClassLikeDeclaration<*>? =
classIdToElementMap[classId] ?: session.firProvider.getFirClassifierByFqName(classId)
}
override fun transformDeclaration() {
designation.ensurePhase(FirResolvePhase.SUPER_TYPES, exceptLast = true)
val nodeInfoCollector = object : FirVisitorVoid() {
val symbolSet = mutableSetOf<FirClassLikeSymbol<*>>()
val classIdToElementMap = mutableMapOf<ClassId, FirClassLikeDeclaration<*>>()
override fun visitElement(element: FirElement) {
if (element is FirClassLikeDeclaration<*>) {
symbolSet.add(element.symbol)
classIdToElementMap[element.symbol.classId] = element
}
element.acceptChildren(this)
}
}
nodeInfoCollector.visitElement(designation.declaration)
val resolver = SupertypeResolver(nodeInfoCollector.symbolSet, nodeInfoCollector.classIdToElementMap)
designation.declaration.accept(resolver, null)
val applySupertypesTransformer = FirApplySupertypesTransformer(supertypeComputationSession)
designation.declaration.transform<FirElement, Void?>(applySupertypesTransformer, null)
}
}
@@ -0,0 +1,43 @@
/*
* Copyright 2010-2021 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.FirSession
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.transformers.FirTypeResolveTransformer
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirDeclarationDesignation
import org.jetbrains.kotlin.idea.fir.low.level.api.trasformers.FirLazyTransformerForIDE.Companion.ensurePhase
class FirDesignatedTypeResolverTransformerForIDE(
private val originalFile: FirFile,
private val designation: FirDeclarationDesignation,
session: FirSession,
scopeSession: ScopeSession,
): FirLazyTransformerForIDE, FirTypeResolveTransformer(session, scopeSession) {
private val ideDeclarationTransformer = IDEDeclarationTransformer(FirDesignationIterator(designation.fullDesignation))
@Suppress("NAME_SHADOWING")
override fun transformRegularClass(regularClass: FirRegularClass, data: Any?): FirStatement {
return ideDeclarationTransformer.transformDeclarationContent(this, regularClass, data) { klass, data ->
super.transformRegularClass(klass, data) as FirRegularClass
}
}
@Suppress("NAME_SHADOWING")
override fun transformAnonymousObject(anonymousObject: FirAnonymousObject, data: Any?): FirStatement {
return ideDeclarationTransformer.transformDeclarationContent(this, anonymousObject, data) { anonymousObject, data ->
super.transformAnonymousObject(anonymousObject, data) as FirAnonymousObject
}
}
override fun transformDeclaration() {
designation.ensurePhase(FirResolvePhase.TYPES, exceptLast = true)
originalFile.transform<FirFile, Any?>(this, null)
}
}
@@ -6,8 +6,12 @@
package org.jetbrains.kotlin.idea.fir.low.level.api.trasformers
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirDeclarationDesignation
class FirDesignation(val designation: List<FirDeclaration>) {
internal fun FirDeclarationDesignation.toDesignationIterator() =
FirDesignationIterator(fullDesignation)
internal class FirDesignationIterator(val designation: List<FirDeclaration>) {
private var currentIndex = 0
fun canGoNext(): Boolean = currentIndex <= designation.lastIndex
@@ -0,0 +1,28 @@
/*
* Copyright 2010-2021 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.FirResolvePhase
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirDeclarationDesignation
internal interface FirLazyTransformerForIDE {
fun transformDeclaration()
companion object {
val EMPTY = object : FirLazyTransformerForIDE {
override fun transformDeclaration() = Unit
}
fun FirDeclarationDesignation.ensurePhase(firResolvePhase: FirResolvePhase, exceptLast: Boolean) {
val designationList = if (exceptLast) path else fullDesignation
designationList.forEach { firDeclaration ->
check (firDeclaration.resolvePhase >= firResolvePhase) {
"Designation element phase required to be $firResolvePhase but element resolved to ${firDeclaration.resolvePhase}"
}
}
}
}
}
@@ -8,11 +8,10 @@ package org.jetbrains.kotlin.idea.fir.low.level.api.trasformers
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirAbstractBodyResolveTransformer
import org.jetbrains.kotlin.fir.resolve.transformers.FirAbstractPhaseTransformer
import org.jetbrains.kotlin.fir.visitors.FirTransformer
internal class IDEDeclarationTransformer(private val designation: FirDesignation) {
internal class IDEDeclarationTransformer(private val designationIterator: FirDesignationIterator) {
private var isInsideTargetDeclaration: Boolean = false
private inline fun <R> insideTargetDeclaration(insideCurrent: Boolean, action: () -> R): R {
@@ -25,16 +24,16 @@ internal class IDEDeclarationTransformer(private val designation: FirDesignation
}
}
inline fun transformDeclarationContent(
transformer: FirAbstractBodyResolveTransformer,
declaration: FirDeclaration,
data: ResolutionMode,
transformDeclaration: (FirDeclaration, ResolutionMode) -> FirDeclaration
): FirDeclaration {
return if (designation.canGoNext()) {
val declarationToTransform = designation.currentDeclaration
val isTargetDeclaration = designation.isTargetDeclaration()
designation.goNext()
inline fun <K, D> transformDeclarationContent(
transformer: FirAbstractPhaseTransformer<D>,
declaration: K,
data: D,
transformDeclaration: (K, D) -> K
): K {
return if (designationIterator.canGoNext()) {
val declarationToTransform = designationIterator.currentDeclaration
val isTargetDeclaration = designationIterator.isTargetDeclaration()
designationIterator.goNext()
insideTargetDeclaration(isTargetDeclaration) {
declarationToTransform.visitNoTransform(transformer, data)
}