diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolveTransformer.kt index 75d791044f5..9d4dc123d0e 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolveTransformer.kt @@ -109,7 +109,7 @@ class FirStatusResolveTransformer( } } -private class FirDesignatedStatusResolveTransformer( +open class FirDesignatedStatusResolveTransformer( session: FirSession, scopeSession: ScopeSession, private val designation: Iterator, @@ -245,7 +245,7 @@ abstract class AbstractFirStatusResolveTransformer( protected val designationMapForLocalClasses: Map, FirClassLikeDeclaration<*>?>, private val scopeForLocalClass: FirScope? ) : FirAbstractTreeTransformer(phase = FirResolvePhase.STATUS) { - private val classes = mutableListOf>() + protected val classes = mutableListOf>() 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 { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSupertypesResolution.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSupertypesResolution.kt index 592f8221548..bc2c3400c4d 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSupertypesResolution.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSupertypesResolution.kt @@ -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(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.runSupertypeResolvePhaseForLocalClass( return this.transform(applySupertypesTransformer, null) } -private class FirApplySupertypesTransformer( +class FirApplySupertypesTransformer( private val supertypeComputationSession: SupertypeComputationSession ) : FirDefaultTransformer() { override fun transformElement(element: E, data: Any?): E { @@ -170,7 +172,7 @@ fun FirRegularClass.resolveSupertypesInTheAir(session: FirSession): List() { 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() private val scopesForNestedClassesMap = hashMapOf, ScopePersistentList>() private val supertypeStatusMap = linkedMapOf, SupertypeComputationStatus>() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt index 1ceb46e4520..31f545d60cd 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt @@ -37,7 +37,7 @@ fun > F.runTypeResolvePhaseForLocalClass( return this.transform(transformer, null) } -class FirTypeResolveTransformer( +open class FirTypeResolveTransformer( override val session: FirSession, scopeSession: ScopeSession, initialScopes: List = emptyList() diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/FirDesignatedBodyResolveTransformerForIDE.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/FirDesignatedBodyResolveTransformerForIDE.kt index b3485ca5c38..e744bf117d3 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/FirDesignatedBodyResolveTransformerForIDE.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/FirDesignatedBodyResolveTransformerForIDE.kt @@ -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(this, ResolutionMode.ContextDependent) + } } diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/FirDesignatedContractsResolveTransformerForIDE.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/FirDesignatedContractsResolveTransformerForIDE.kt index a5af6911d8c..aa83403e296 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/FirDesignatedContractsResolveTransformerForIDE.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/FirDesignatedContractsResolveTransformerForIDE.kt @@ -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(this, ResolutionMode.ContextDependent) + } } diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/FirDesignatedImplicitTypesTransformerForIDE.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/FirDesignatedImplicitTypesTransformerForIDE.kt index c791b5e24af..0c645941de8 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/FirDesignatedImplicitTypesTransformerForIDE.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/FirDesignatedImplicitTypesTransformerForIDE.kt @@ -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(this, ResolutionMode.ContextDependent) } } diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/FirDesignatedStatusResolveTransformerForIDE.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/FirDesignatedStatusResolveTransformerForIDE.kt new file mode 100644 index 00000000000..69d6173ba30 --- /dev/null +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/FirDesignatedStatusResolveTransformerForIDE.kt @@ -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 > transformClass( + klass: FirClass, + 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}") + } + } +} \ No newline at end of file diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/FirDesignatedSupertypeResolverTransformerForIDE.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/FirDesignatedSupertypeResolverTransformerForIDE.kt new file mode 100644 index 00000000000..6f0320d0516 --- /dev/null +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/FirDesignatedSupertypeResolverTransformerForIDE.kt @@ -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>, + private val classIdToElementMap: Map> + ) : 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>() + val classIdToElementMap = mutableMapOf>() + 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(applySupertypesTransformer, null) + } +} \ No newline at end of file diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/FirDesignatedTypeResolverTransformerForIDE.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/FirDesignatedTypeResolverTransformerForIDE.kt new file mode 100644 index 00000000000..6cf78db659b --- /dev/null +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/FirDesignatedTypeResolverTransformerForIDE.kt @@ -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(this, null) + } +} \ No newline at end of file diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/FirDesignation.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/FirDesignationIterator.kt similarity index 73% rename from idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/FirDesignation.kt rename to idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/FirDesignationIterator.kt index 42d41270d79..6e5eabbf638 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/FirDesignation.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/FirDesignationIterator.kt @@ -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) { +internal fun FirDeclarationDesignation.toDesignationIterator() = + FirDesignationIterator(fullDesignation) + +internal class FirDesignationIterator(val designation: List) { private var currentIndex = 0 fun canGoNext(): Boolean = currentIndex <= designation.lastIndex diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/FirLazyTransformerForIDE.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/FirLazyTransformerForIDE.kt new file mode 100644 index 00000000000..e0a4184f834 --- /dev/null +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/FirLazyTransformerForIDE.kt @@ -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}" + } + } + } + } +} \ No newline at end of file diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/IDEDeclarationTransformer.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/IDEDeclarationTransformer.kt index 2c1c13bfeb2..94f6598b2f9 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/IDEDeclarationTransformer.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/trasformers/IDEDeclarationTransformer.kt @@ -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 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 transformDeclarationContent( + transformer: FirAbstractPhaseTransformer, + 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) }