[FIR IDE] Add types, supertypes and status lazy designated transformers
This commit is contained in:
committed by
TeamCityServer
parent
95acb6121b
commit
779a06e86f
+3
-3
@@ -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 {
|
||||
|
||||
+18
-10
@@ -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>()
|
||||
|
||||
+1
-1
@@ -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()
|
||||
|
||||
+9
-3
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-3
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
+8
-13
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
+90
@@ -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}")
|
||||
}
|
||||
}
|
||||
}
|
||||
+62
@@ -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)
|
||||
}
|
||||
}
|
||||
+43
@@ -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)
|
||||
}
|
||||
}
|
||||
+5
-1
@@ -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
|
||||
+28
@@ -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}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
-13
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user