FIR: Merge FirAbstractTreeTransformerWithSuperTypes and FirTypeResolveTransformer

This commit is contained in:
Denis.Zharkov
2021-10-04 13:13:29 +03:00
committed by teamcityserver
parent b6ebed0c96
commit f038b575f1
4 changed files with 86 additions and 122 deletions
@@ -11,10 +11,13 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.expandedConeType
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
import org.jetbrains.kotlin.fir.declarations.utils.superConeTypes
import org.jetbrains.kotlin.fir.resolve.transformers.createSubstitutionForSupertype
import org.jetbrains.kotlin.fir.symbols.ensureResolved
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
import org.jetbrains.kotlin.fir.symbols.ensureResolved
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.fir.types.*
@@ -206,3 +209,12 @@ private fun ConeClassLikeType?.isClassBasedType(
is FirRegularClassSymbol -> symbol.fir.classKind == ClassKind.CLASS
}
}
fun createSubstitutionForSupertype(superType: ConeLookupTagBasedType, session: FirSession): ConeSubstitutor {
val klass = superType.lookupTag.toSymbol(session)?.fir as? FirRegularClass ?: return ConeSubstitutor.Empty
val arguments = superType.typeArguments.map {
it as? ConeKotlinType ?: ConeClassErrorType(ConeSimpleDiagnostic("illegal projection usage", DiagnosticKind.IllegalProjectionUsage))
}
val mapping = klass.typeParameters.map { it.symbol }.zip(arguments).toMap()
return ConeSubstitutorByMap(mapping, session)
}
@@ -1,111 +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.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.scopes.FirCompositeScope
import org.jetbrains.kotlin.fir.scopes.FirScope
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.types.ConeClassErrorType
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.ConeLookupTagBasedType
abstract class FirAbstractTreeTransformerWithSuperTypes(
phase: FirResolvePhase,
protected val scopeSession: ScopeSession
) : FirAbstractTreeTransformer<Any?>(phase) {
protected val scopes = mutableListOf<FirScope>()
protected val classDeclarationsStack = ArrayDeque<FirRegularClass>()
protected val towerScope = FirCompositeScope(scopes.asReversed())
protected inline fun <T> withScopeCleanup(crossinline l: () -> T): T {
val sizeBefore = scopes.size
val result = l()
val size = scopes.size
assert(size >= sizeBefore)
repeat(size - sizeBefore) {
scopes.removeAt(scopes.lastIndex)
}
return result
}
protected inline fun <T> withClassDeclarationCleanup(declaration: FirRegularClass, crossinline l: () -> T): T {
withClassDeclarationCleanup(classDeclarationsStack, declaration) {
return l()
}
}
protected fun resolveNestedClassesSupertypes(
firClass: FirClass,
data: Any?
): FirStatement {
return withScopeCleanup {
// Otherwise annotations may try to resolve
// themselves as inner classes of the `firClass`
// if their names match
firClass.transformAnnotations(this, null)
// ? Is it Ok to use original file session here ?
val superTypes = lookupSuperTypes(
firClass,
lookupInterfaces = false,
deep = true,
substituteTypes = true,
useSiteSession = session
).asReversed()
for (superType in superTypes) {
superType.lookupTag.getNestedClassifierScope(session, scopeSession)?.let { nestedClassifierScope ->
val scope = nestedClassifierScope.wrapNestedClassifierScopeWithSubstitutionForSuperType(superType, session)
scopes.add(scope)
}
}
if (firClass is FirRegularClass) {
firClass.addTypeParametersScope()
val companionObject = firClass.companionObject
if (companionObject != null) {
session.nestedClassifierScope(companionObject)?.let(scopes::add)
}
}
session.nestedClassifierScope(firClass)?.let(scopes::add)
// Note that annotations are still visited here
// again, although there's no need in it
transformDeclarationContent(firClass, data) as FirClass
}
}
protected fun FirMemberDeclaration.addTypeParametersScope() {
if (typeParameters.isNotEmpty()) {
scopes.add(FirMemberTypeParameterScope(this))
}
}
open fun transformDeclarationContent(declaration: FirDeclaration, data: Any?): FirDeclaration {
return transformElement(declaration, data)
}
}
fun createSubstitutionForSupertype(superType: ConeLookupTagBasedType, session: FirSession): ConeSubstitutor {
val klass = superType.lookupTag.toSymbol(session)?.fir as? FirRegularClass ?: return ConeSubstitutor.Empty
val arguments = superType.typeArguments.map {
it as? ConeKotlinType ?: ConeClassErrorType(ConeSimpleDiagnostic("illegal projection usage", DiagnosticKind.IllegalProjectionUsage))
}
val mapping = klass.typeParameters.map { it.symbol }.zip(arguments).toMap()
return ConeSubstitutorByMap(mapping, session)
}
@@ -12,8 +12,14 @@ import org.jetbrains.kotlin.fir.declarations.utils.isFromVararg
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeCyclicTypeBound
import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes
import org.jetbrains.kotlin.fir.scopes.FirCompositeScope
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.createImportingScopes
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.types.*
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
@@ -36,12 +42,12 @@ fun <F : FirClassLikeDeclaration> F.runTypeResolvePhaseForLocalClass(
open class FirTypeResolveTransformer(
final override val session: FirSession,
scopeSession: ScopeSession,
private val scopeSession: ScopeSession,
initialScopes: List<FirScope> = emptyList()
) : FirAbstractTreeTransformerWithSuperTypes(
phase = FirResolvePhase.TYPES,
scopeSession
) {
) : FirAbstractTreeTransformer<Any?>(FirResolvePhase.TYPES) {
private val classDeclarationsStack = ArrayDeque<FirRegularClass>()
private val scopes = mutableListOf<FirScope>()
private val towerScope = FirCompositeScope(scopes.asReversed())
init {
scopes.addAll(initialScopes.asReversed())
@@ -60,7 +66,7 @@ open class FirTypeResolveTransformer(
}
override fun transformRegularClass(regularClass: FirRegularClass, data: Any?): FirStatement {
return withClassDeclarationCleanup(regularClass) {
withClassDeclarationCleanup(classDeclarationsStack, regularClass) {
withScopeCleanup {
regularClass.addTypeParametersScope()
regularClass.typeParameters.forEach {
@@ -69,12 +75,12 @@ open class FirTypeResolveTransformer(
unboundCyclesInTypeParametersSupertypes(regularClass)
}
resolveNestedClassesSupertypes(regularClass, data)
return resolveClassContent(regularClass, data)
}
}
override fun transformAnonymousObject(anonymousObject: FirAnonymousObject, data: Any?): FirStatement {
return resolveNestedClassesSupertypes(anonymousObject, data)
return resolveClassContent(anonymousObject, data)
}
override fun transformConstructor(constructor: FirConstructor, data: Any?): FirConstructor {
@@ -208,4 +214,61 @@ open class FirTypeResolveTransformer(
override fun transformAnnotationCall(annotationCall: FirAnnotationCall, data: Any?): FirStatement {
return transformAnnotation(annotationCall, data)
}
private inline fun <T> withScopeCleanup(crossinline l: () -> T): T {
val sizeBefore = scopes.size
val result = l()
val size = scopes.size
assert(size >= sizeBefore)
repeat(size - sizeBefore) {
scopes.removeAt(scopes.lastIndex)
}
return result
}
private fun resolveClassContent(
firClass: FirClass,
data: Any?
): FirStatement {
return withScopeCleanup {
// Otherwise annotations may try to resolve
// themselves as inner classes of the `firClass`
// if their names match
firClass.transformAnnotations(this, null)
// ? Is it Ok to use original file session here ?
val superTypes = lookupSuperTypes(
firClass,
lookupInterfaces = false,
deep = true,
substituteTypes = true,
useSiteSession = session
).asReversed()
for (superType in superTypes) {
superType.lookupTag.getNestedClassifierScope(session, scopeSession)?.let { nestedClassifierScope ->
val scope = nestedClassifierScope.wrapNestedClassifierScopeWithSubstitutionForSuperType(superType, session)
scopes.add(scope)
}
}
if (firClass is FirRegularClass) {
firClass.addTypeParametersScope()
val companionObject = firClass.companionObject
if (companionObject != null) {
session.nestedClassifierScope(companionObject)?.let(scopes::add)
}
}
session.nestedClassifierScope(firClass)?.let(scopes::add)
// Note that annotations are still visited here
// again, although there's no need in it
transformElement(firClass, data) as FirClass
}
}
private fun FirMemberDeclaration.addTypeParametersScope() {
if (typeParameters.isNotEmpty()) {
scopes.add(FirMemberTypeParameterScope(this))
}
}
}
@@ -7,8 +7,8 @@ package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.utils.isInner
import org.jetbrains.kotlin.fir.resolve.createSubstitutionForSupertype
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.transformers.createSubstitutionForSupertype
import org.jetbrains.kotlin.fir.scopes.*
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.ConeClassLikeType