Extract FirAbstractTreeTransformer and *WithSuperTypes

This commit is contained in:
Mikhail Glukhikh
2019-01-28 17:11:02 +03:00
parent 0e179f6b44
commit 95678a4d64
6 changed files with 103 additions and 80 deletions
@@ -0,0 +1,18 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. 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.FirElement
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
import org.jetbrains.kotlin.fir.visitors.FirTransformer
import org.jetbrains.kotlin.fir.visitors.compose
abstract class FirAbstractTreeTransformer : FirTransformer<Nothing?>() {
override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> {
@Suppress("UNCHECKED_CAST")
return (element.transformChildren(this, data) as E).compose()
}
}
@@ -0,0 +1,62 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. 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.descriptors.ClassKind
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.scopes.impl.FirCompositeScope
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.ConeClassSymbol
import org.jetbrains.kotlin.fir.symbols.ConeTypeAliasSymbol
import org.jetbrains.kotlin.fir.types.ConeAbbreviatedType
import org.jetbrains.kotlin.fir.types.ConeClassErrorType
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
abstract class FirAbstractTreeTransformerWithSuperTypes(reversedScopePriority: Boolean) : FirAbstractTreeTransformer() {
protected var towerScope = FirCompositeScope(mutableListOf(), reversedPriority = reversedScopePriority)
protected inline fun <T> withScopeCleanup(crossinline l: () -> T): T {
val scopeBefore = towerScope
val scopes = towerScope.scopes
val sizeBefore = scopes.size
val result = l()
towerScope = scopeBefore
assert(scopes.size >= sizeBefore)
scopes.subList(sizeBefore + 1, scopes.size).clear()
return result
}
protected fun lookupSuperTypes(klass: FirRegularClass): List<ConeClassLikeType> {
return mutableListOf<ConeClassLikeType>().also { klass.symbol.collectSuperTypes(it) }
}
private tailrec fun ConeClassLikeType.computePartialExpansion(): ConeClassLikeType? {
return when (this) {
is ConeAbbreviatedType -> directExpansion.takeIf { it !is ConeClassErrorType }?.computePartialExpansion()
else -> return this
}
}
private tailrec fun ConeClassLikeSymbol.collectSuperTypes(list: MutableList<ConeClassLikeType>) {
when (this) {
is ConeClassSymbol -> {
val superClassType =
this.superTypes
.map { it.computePartialExpansion() }
.firstOrNull {
it !is ConeClassErrorType && (it?.symbol as? ConeClassSymbol)?.kind == ClassKind.CLASS
} ?: return
list += superClassType
superClassType.symbol.collectSuperTypes(list)
}
is ConeTypeAliasSymbol -> {
val expansion = expansionType?.computePartialExpansion() ?: return
expansion.symbol.collectSuperTypes(list)
}
else -> error("?!id:1")
}
}
}
@@ -13,12 +13,11 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedImportImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedPackageStarImport import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedPackageStarImport
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
import org.jetbrains.kotlin.fir.visitors.FirTransformer
import org.jetbrains.kotlin.fir.visitors.compose import org.jetbrains.kotlin.fir.visitors.compose
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
class FirImportResolveTransformer() : FirTransformer<Nothing?>() { class FirImportResolveTransformer() : FirAbstractTreeTransformer() {
override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> { override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> {
return element.compose() return element.compose()
} }
@@ -9,19 +9,12 @@ import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
import org.jetbrains.kotlin.fir.visitors.FirTransformer
import org.jetbrains.kotlin.fir.visitors.compose import org.jetbrains.kotlin.fir.visitors.compose
class FirStatusResolveTransformer : FirTransformer<Nothing?>() { class FirStatusResolveTransformer : FirAbstractTreeTransformer() {
override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> {
@Suppress("UNCHECKED_CAST")
return (element.transformChildren(this, data) as E).compose()
}
private val declarationsWithStatuses = mutableListOf<FirDeclaration>() private val declarationsWithStatuses = mutableListOf<FirDeclaration>()
private val classes = mutableListOf<FirRegularClass>() private val classes = mutableListOf<FirRegularClass>()
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.fir.resolve.transformers package org.jetbrains.kotlin.fir.resolve.transformers
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
@@ -27,33 +26,20 @@ import org.jetbrains.kotlin.fir.visitors.compose
open class FirTypeResolveTransformer( open class FirTypeResolveTransformer(
private val traversedClassifiers: Set<FirMemberDeclaration> = setOf() private val traversedClassifiers: Set<FirMemberDeclaration> = setOf()
) : FirTransformer<Nothing?>() { ) : FirAbstractTreeTransformerWithSuperTypes(reversedScopePriority = false) {
override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> {
@Suppress("UNCHECKED_CAST")
return (element.transformChildren(this, data) as E).compose()
}
lateinit var scope: FirCompositeScope
override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult<FirFile> { override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult<FirFile> {
val session = file.session val session = file.session
scope = FirCompositeScope( towerScope.scopes += listOf(
mutableListOf( // from high priority to low priority
// from high priority to low priority FirExplicitSimpleImportingScope(file.imports, session),
FirExplicitSimpleImportingScope(file.imports, session), FirSelfImportingScope(file.packageFqName, session),
FirSelfImportingScope(file.packageFqName, session), FirDefaultSimpleImportingScope(session),
FirDefaultSimpleImportingScope(session), FirExplicitStarImportingScope(file.imports, session),
FirExplicitStarImportingScope(file.imports, session), FirDefaultStarImportingScope(session)
FirDefaultStarImportingScope(session)
)
) )
return super.transformFile(file, data) return super.transformFile(file, data)
} }
private fun lookupSuperTypes(klass: FirRegularClass): List<ConeClassLikeType> {
return mutableListOf<ConeClassLikeType>().also { klass.symbol.collectSuperTypes(it) }
}
private fun resolveSuperTypesAndExpansions(element: FirMemberDeclaration) { private fun resolveSuperTypesAndExpansions(element: FirMemberDeclaration) {
try { try {
element.transformChildren(SuperTypeResolver(traversedClassifiers + listOfNotNull(element)), null) element.transformChildren(SuperTypeResolver(traversedClassifiers + listOfNotNull(element)), null)
@@ -70,13 +56,13 @@ open class FirTypeResolveTransformer(
val firProvider = FirProvider.getInstance(regularClass.session) val firProvider = FirProvider.getInstance(regularClass.session)
val classId = regularClass.symbol.classId val classId = regularClass.symbol.classId
scope.scopes += FirNestedClassifierScope(classId, firProvider) towerScope.scopes += FirNestedClassifierScope(classId, firProvider)
val companionObjects = regularClass.declarations.filterIsInstance<FirRegularClass>().filter { it.isCompanion } val companionObjects = regularClass.declarations.filterIsInstance<FirRegularClass>().filter { it.isCompanion }
for (companionObject in companionObjects) { for (companionObject in companionObjects) {
scope.scopes += FirNestedClassifierScope(companionObject.symbol.classId, firProvider) towerScope.scopes += FirNestedClassifierScope(companionObject.symbol.classId, firProvider)
} }
lookupSuperTypes(regularClass).mapTo(scope.scopes) { lookupSuperTypes(regularClass).mapTo(towerScope.scopes) {
val symbol = it.symbol val symbol = it.symbol
if (symbol is FirBasedSymbol<*>) { if (symbol is FirBasedSymbol<*>) {
FirNestedClassifierScope(symbol.classId, FirProvider.getInstance(symbol.fir.session)) FirNestedClassifierScope(symbol.classId, FirProvider.getInstance(symbol.fir.session))
@@ -100,7 +86,7 @@ open class FirTypeResolveTransformer(
private inline fun <T> FirMemberDeclaration.withTypeParametersScope(crossinline l: () -> T): T { private inline fun <T> FirMemberDeclaration.withTypeParametersScope(crossinline l: () -> T): T {
val scopes = scope.scopes val scopes = towerScope.scopes
if (typeParameters.isNotEmpty()) { if (typeParameters.isNotEmpty()) {
scopes += FirMemberTypeParameterScope(this) scopes += FirMemberTypeParameterScope(this)
} }
@@ -111,17 +97,6 @@ open class FirTypeResolveTransformer(
return result return result
} }
private inline fun <T> withScopeCleanup(crossinline l: () -> T): T {
val scopeBefore = scope
val scopes = scope.scopes
val sizeBefore = scopes.size
val result = l()
scope = scopeBefore
assert(scopes.size >= sizeBefore)
scopes.subList(sizeBefore + 1, scopes.size).clear()
return result
}
override fun transformProperty(property: FirProperty, data: Nothing?): CompositeTransformResult<FirDeclaration> { override fun transformProperty(property: FirProperty, data: Nothing?): CompositeTransformResult<FirDeclaration> {
return property.withTypeParametersScope { return property.withTypeParametersScope {
super.transformProperty(property, data) super.transformProperty(property, data)
@@ -137,7 +112,7 @@ open class FirTypeResolveTransformer(
override fun transformType(type: FirType, data: Nothing?): CompositeTransformResult<FirType> { override fun transformType(type: FirType, data: Nothing?): CompositeTransformResult<FirType> {
val typeResolver = FirTypeResolver.getInstance(type.session) val typeResolver = FirTypeResolver.getInstance(type.session)
type.transformChildren(this, null) type.transformChildren(this, null)
return transformType(type, typeResolver.resolveType(type, scope, position = FirPosition.OTHER)) return transformType(type, typeResolver.resolveType(type, towerScope, position = FirPosition.OTHER))
} }
override fun transformFunctionType(functionType: FirFunctionType, data: Nothing?): CompositeTransformResult<FirType> { override fun transformFunctionType(functionType: FirFunctionType, data: Nothing?): CompositeTransformResult<FirType> {
@@ -151,7 +126,7 @@ open class FirTypeResolveTransformer(
functionType.receiverType, functionType.receiverType,
functionType.valueParameters as MutableList<FirValueParameter>, functionType.valueParameters as MutableList<FirValueParameter>,
functionType.returnType, functionType.returnType,
typeResolver.resolveType(functionType, scope, FirPosition.OTHER) typeResolver.resolveType(functionType, towerScope, FirPosition.OTHER)
).compose() ).compose()
} }
@@ -230,7 +205,7 @@ open class FirTypeResolveTransformer(
override fun transformType(type: FirType, data: Nothing?): CompositeTransformResult<FirType> { override fun transformType(type: FirType, data: Nothing?): CompositeTransformResult<FirType> {
val typeResolver = FirTypeResolver.getInstance(type.session) val typeResolver = FirTypeResolver.getInstance(type.session)
val symbol = typeResolver.resolveToSymbol(type, scope, position = FirPosition.SUPER_TYPE_OR_EXPANSION) val symbol = typeResolver.resolveToSymbol(type, towerScope, position = FirPosition.SUPER_TYPE_OR_EXPANSION)
val myTransformer = this@FirTypeResolveTransformer val myTransformer = this@FirTypeResolveTransformer
if (symbol != null) { if (symbol != null) {
@@ -245,35 +220,7 @@ open class FirTypeResolveTransformer(
type.transformChildren(myTransformer, null) type.transformChildren(myTransformer, null)
return myTransformer.transformType(type, typeResolver.resolveUserType(type, symbol, scope)) return myTransformer.transformType(type, typeResolver.resolveUserType(type, symbol, towerScope))
} }
} }
private tailrec fun ConeClassLikeType.computePartialExpansion(): ConeClassLikeType? {
return when (this) {
is ConeAbbreviatedType -> directExpansion.takeIf { it !is ConeClassErrorType }?.computePartialExpansion()
else -> return this
}
}
private tailrec fun ConeClassLikeSymbol.collectSuperTypes(list: MutableList<ConeClassLikeType>) {
when (this) {
is ConeClassSymbol -> {
val superClassType =
this.superTypes
.map { it.computePartialExpansion() }
.firstOrNull {
it !is ConeClassErrorType && (it?.symbol as? ConeClassSymbol)?.kind == ClassKind.CLASS
} ?: return
list += superClassType
superClassType.symbol.collectSuperTypes(list)
}
is ConeTypeAliasSymbol -> {
val expansion = expansionType?.computePartialExpansion() ?: return
expansion.symbol.collectSuperTypes(list)
}
else -> error("?!id:1")
}
}
} }
@@ -11,12 +11,16 @@ import org.jetbrains.kotlin.fir.scopes.FirTypeParameterScope
import org.jetbrains.kotlin.fir.symbols.ConeSymbol import org.jetbrains.kotlin.fir.symbols.ConeSymbol
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
class FirCompositeScope(val scopes: MutableList<FirScope>) : FirScope { class FirCompositeScope(
val scopes: MutableList<FirScope>,
private val reversedPriority: Boolean = false
) : FirScope {
override fun processClassifiersByName( override fun processClassifiersByName(
name: Name, name: Name,
position: FirPosition, position: FirPosition,
processor: (ConeSymbol) -> Boolean processor: (ConeSymbol) -> Boolean
): Boolean { ): Boolean {
val scopes = if (reversedPriority) scopes.asReversed() else scopes
for (scope in scopes) { for (scope in scopes) {
if (!position.allowTypeParameters && scope is FirTypeParameterScope) continue if (!position.allowTypeParameters && scope is FirTypeParameterScope) continue
if (!scope.processClassifiersByName(name, position, processor)) { if (!scope.processClassifiersByName(name, position, processor)) {