FIR: Minor. Drop old FirSupertypeResolverTransformer
This commit is contained in:
-228
@@ -1,228 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 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.fir.resolve.transformers
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||
import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic
|
||||
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.firProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.scopes.addImportingScopes
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirErrorTypeRefImpl
|
||||
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
|
||||
import org.jetbrains.kotlin.fir.visitors.compose
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
|
||||
class FirSupertypeResolverTransformer : FirAbstractTreeTransformer<Nothing?>(phase = FirResolvePhase.SUPER_TYPES) {
|
||||
override lateinit var session: FirSession
|
||||
private lateinit var file: FirFile
|
||||
|
||||
override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult<FirFile> {
|
||||
initFromFile(file)
|
||||
return transformDeclaration(file, data) as CompositeTransformResult<FirFile>
|
||||
}
|
||||
|
||||
fun initFromFile(file: FirFile) {
|
||||
session = file.session
|
||||
this.file = file
|
||||
}
|
||||
|
||||
override fun transformRegularClass(regularClass: FirRegularClass, data: Nothing?): CompositeTransformResult<FirStatement> {
|
||||
val transformedClass = resolveSupertypesOrExpansions(regularClass) as? FirRegularClass ?: regularClass
|
||||
|
||||
// resolve supertypes for nested classes
|
||||
return transformDeclaration(transformedClass, data) as CompositeTransformResult<FirStatement>
|
||||
}
|
||||
|
||||
override fun transformEnumEntry(enumEntry: FirEnumEntry, data: Nothing?): CompositeTransformResult<FirStatement> {
|
||||
return transformRegularClass(enumEntry, data)
|
||||
}
|
||||
|
||||
override fun transformTypeAlias(typeAlias: FirTypeAlias, data: Nothing?): CompositeTransformResult<FirDeclaration> {
|
||||
val result = resolveSupertypesOrExpansions(typeAlias)
|
||||
return result.compose()
|
||||
}
|
||||
|
||||
override fun transformAnonymousInitializer(
|
||||
anonymousInitializer: FirAnonymousInitializer,
|
||||
data: Nothing?
|
||||
): CompositeTransformResult<FirDeclaration> {
|
||||
return anonymousInitializer.compose()
|
||||
}
|
||||
|
||||
override fun transformConstructor(constructor: FirConstructor, data: Nothing?): CompositeTransformResult<FirDeclaration> {
|
||||
return constructor.compose()
|
||||
}
|
||||
|
||||
override fun transformSimpleFunction(simpleFunction: FirSimpleFunction, data: Nothing?): CompositeTransformResult<FirDeclaration> {
|
||||
return simpleFunction.compose()
|
||||
}
|
||||
|
||||
override fun transformProperty(property: FirProperty, data: Nothing?): CompositeTransformResult<FirDeclaration> {
|
||||
return property.compose()
|
||||
}
|
||||
|
||||
override fun <F : FirFunction<F>> transformFunction(function: FirFunction<F>, data: Nothing?): CompositeTransformResult<FirStatement> {
|
||||
return function.compose()
|
||||
}
|
||||
|
||||
private fun resolveSupertypesOrExpansions(classLikeDeclaration: FirClassLikeDeclaration<*>): FirDeclaration {
|
||||
if (classLikeDeclaration.areSupertypesComputed() || classLikeDeclaration.areSupertypesComputing()) {
|
||||
return classLikeDeclaration
|
||||
}
|
||||
|
||||
val classId = classLikeDeclaration.symbol.classId
|
||||
|
||||
val visitor = ResolveSuperTypesTask(session, classId, file, classLikeDeclaration)
|
||||
file.accept(visitor, null).single
|
||||
|
||||
return visitor.resultingClass
|
||||
}
|
||||
|
||||
private class ResolveSuperTypesTask(
|
||||
override val session: FirSession,
|
||||
private val requestedClassId: ClassId,
|
||||
file: FirFile,
|
||||
private val knownFirClassLikeDeclaration: FirClassLikeDeclaration<*>? = null
|
||||
) : FirAbstractTreeTransformerWithSuperTypes(phase = FirResolvePhase.SUPER_TYPES, reversedScopePriority = true) {
|
||||
|
||||
lateinit var resultingClass: FirDeclaration
|
||||
|
||||
init {
|
||||
val scopeSession = ScopeSession()
|
||||
towerScope.addImportingScopes(file, session, scopeSession)
|
||||
}
|
||||
|
||||
override fun transformEnumEntry(enumEntry: FirEnumEntry, data: Nothing?): CompositeTransformResult<FirStatement> {
|
||||
return transformRegularClass(enumEntry, data)
|
||||
}
|
||||
|
||||
override fun transformRegularClass(regularClass: FirRegularClass, data: Nothing?): CompositeTransformResult<FirStatement> {
|
||||
val classId = regularClass.classId
|
||||
if (!isOuterClass(classId, requestedClassId)) return regularClass.compose()
|
||||
val transformedClass = withScopeCleanup {
|
||||
if (regularClass.areSupertypesComputed() || regularClass.areSupertypesComputing()) return@withScopeCleanup regularClass
|
||||
|
||||
regularClass.addTypeParametersScope()
|
||||
|
||||
val transformer = FirSpecificTypeResolverTransformer(towerScope, session)
|
||||
val resolvedTypesRefs = regularClass.superTypeRefs.map {
|
||||
transformer.transformTypeRef(it, data).single
|
||||
}
|
||||
|
||||
val resultingTypeRefs = resolveLoops(regularClass, classId, resolvedTypesRefs)
|
||||
regularClass.replaceSuperTypeRefs(resultingTypeRefs)
|
||||
regularClass
|
||||
}
|
||||
|
||||
if (regularClass.matchesRequestedDeclaration()) {
|
||||
resultingClass = transformedClass
|
||||
return transformedClass.compose()
|
||||
}
|
||||
|
||||
return resolveNestedClassesSupertypes(transformedClass, data)
|
||||
}
|
||||
|
||||
private fun FirClassLikeDeclaration<*>.matchesRequestedDeclaration(): Boolean {
|
||||
if (knownFirClassLikeDeclaration != null) return knownFirClassLikeDeclaration == this
|
||||
return symbol.classId == requestedClassId
|
||||
}
|
||||
|
||||
override fun transformTypeAlias(typeAlias: FirTypeAlias, data: Nothing?): CompositeTransformResult<FirDeclaration> {
|
||||
val classId = typeAlias.symbol.classId
|
||||
// nested type aliases
|
||||
if (typeAlias.areSupertypesComputed() || !typeAlias.matchesRequestedDeclaration()) return typeAlias.compose()
|
||||
|
||||
return withScopeCleanup {
|
||||
typeAlias.addTypeParametersScope()
|
||||
|
||||
val transformer = FirSpecificTypeResolverTransformer(towerScope, session)
|
||||
val resolvedTypesRef = transformer.transformTypeRef(typeAlias.expandedTypeRef, data).single
|
||||
val resultingTypeRef = resolveLoops(typeAlias, classId, listOf(resolvedTypesRef)).firstOrNull()
|
||||
|
||||
typeAlias.replaceExpandedTypeRef(resultingTypeRef ?: resolvedTypesRef)
|
||||
resultingClass = typeAlias
|
||||
typeAlias
|
||||
}.compose()
|
||||
}
|
||||
|
||||
private fun resolveLoops(
|
||||
firClassLikeDeclaration: FirClassLikeDeclaration<*>,
|
||||
classId: ClassId,
|
||||
resolvedTypesRefs: List<FirTypeRef>
|
||||
): List<FirTypeRef> {
|
||||
firClassLikeDeclaration.replaceSupertypesComputationStatus(SupertypesComputationStatus.COMPUTING)
|
||||
|
||||
val resultingTypeRefs = mutableListOf<FirTypeRef>()
|
||||
for (superTypeRef in resolvedTypesRefs) {
|
||||
val coneType = (superTypeRef as FirResolvedTypeRef).type
|
||||
if (coneType is ConeTypeParameterType) {
|
||||
resultingTypeRefs.add(
|
||||
FirErrorTypeRefImpl(superTypeRef.source, FirSimpleDiagnostic("Type parameter cannot be a super-type: ${coneType.render()}", DiagnosticKind.TypeParameterAsSupertype))
|
||||
)
|
||||
continue
|
||||
}
|
||||
val resolvedType = coneType as ConeClassLikeType
|
||||
val superTypeClassId = resolvedType.lookupTag.classId
|
||||
|
||||
if (superTypeClassId.outerClasses().any { it.areSupertypesComputing() }) {
|
||||
resultingTypeRefs.add(
|
||||
FirErrorTypeRefImpl(superTypeRef.source, FirSimpleDiagnostic("Recursion detected: ${superTypeRef.render()}", DiagnosticKind.RecursionInSupertypes))
|
||||
)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
val sessionForSupertype = session.firSymbolProvider.getSessionForClass(superTypeClassId) ?: continue
|
||||
|
||||
val firClassForSupertype =
|
||||
sessionForSupertype
|
||||
.firSymbolProvider
|
||||
.getClassLikeSymbolByFqName(superTypeClassId)
|
||||
?.fir
|
||||
|
||||
// TODO: this if is a temporary hack for built-in types (because we can't load file for them)
|
||||
if (firClassForSupertype == null ||
|
||||
(firClassForSupertype is FirClass &&
|
||||
firClassForSupertype.superTypeRefs.any { it !is FirResolvedTypeRef })
|
||||
) {
|
||||
val provider = sessionForSupertype.firProvider
|
||||
val firForSuperClassFile = provider.getFirClassifierContainerFile(superTypeClassId)
|
||||
|
||||
ResolveSuperTypesTask(
|
||||
sessionForSupertype, superTypeClassId, firForSuperClassFile
|
||||
).transformFile(firForSuperClassFile, null)
|
||||
}
|
||||
|
||||
resultingTypeRefs.add(superTypeRef)
|
||||
}
|
||||
|
||||
firClassLikeDeclaration.replaceSupertypesComputationStatus(SupertypesComputationStatus.COMPUTED)
|
||||
return resultingTypeRefs
|
||||
}
|
||||
|
||||
private fun ClassId.areSupertypesComputing(): Boolean {
|
||||
val fir = session.firSymbolProvider.getClassLikeSymbolByFqName(this)?.fir ?: return false
|
||||
return fir.areSupertypesComputing()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun isOuterClass(outerCandidate: ClassId, innerCandidate: ClassId) =
|
||||
innerCandidate.outerClasses().any { outerCandidate == it }
|
||||
|
||||
private fun ClassId.outerClasses() = generateSequence(this, ClassId::getOuterClassId)
|
||||
|
||||
private fun FirClassLikeDeclaration<*>.areSupertypesComputed() =
|
||||
supertypesComputationStatus == SupertypesComputationStatus.COMPUTED
|
||||
|
||||
private fun FirClassLikeDeclaration<*>.areSupertypesComputing() =
|
||||
supertypesComputationStatus == SupertypesComputationStatus.COMPUTING
|
||||
Reference in New Issue
Block a user