[FIR IDE] Implement lazy designated resolve for all resolve FIR phases

This commit is contained in:
Igor Yakovlev
2021-05-12 00:50:26 +02:00
parent cda1a7edbe
commit f98995f6cb
52 changed files with 1361 additions and 893 deletions
@@ -56,6 +56,8 @@ open class RawFirBuilder(
private val stubMode get() = mode == RawFirBuilderMode.STUBS
protected open fun bindFunctionTarget(target: FirFunctionTarget, function: FirFunction<*>) = target.bind(function)
var mode: RawFirBuilderMode = builderMode
private set
@@ -375,7 +377,7 @@ open class RawFirBuilder(
}
}.also {
it.initContainingClassAttr()
accessorTarget.bind(it)
bindFunctionTarget(accessorTarget, it)
this@RawFirBuilder.context.firFunctionTargets.removeLast()
}
}
@@ -1072,7 +1074,7 @@ open class RawFirBuilder(
}
context.firFunctionTargets.removeLast()
}.build().also {
target.bind(it)
bindFunctionTarget(target, it)
if (it is FirSimpleFunction) {
function.fillDanglingConstraintsTo(it)
}
@@ -1180,7 +1182,7 @@ open class RawFirBuilder(
}
context.firFunctionTargets.removeLast()
}.also {
target.bind(it)
bindFunctionTarget(target, it)
}
}
@@ -1220,7 +1222,7 @@ open class RawFirBuilder(
this@RawFirBuilder.context.firFunctionTargets.removeLast()
}.also {
it.containingClassAttr = currentDispatchReceiverType()!!.lookupTag
target.bind(it)
bindFunctionTarget(target, it)
}
}
@@ -6,9 +6,11 @@
package org.jetbrains.kotlin.fir.resolve
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.FirTypeAlias
import org.jetbrains.kotlin.fir.declarations.expandedConeType
import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolved
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.fir.types.*
@@ -27,14 +27,18 @@ abstract class FirAbstractPhaseTransformer<D>(
override fun transformFile(file: FirFile, data: D): FirFile {
checkSessionConsistency(file)
file.replaceResolvePhase(transformerPhase)
if (file.resolvePhase < transformerPhase) {
file.replaceResolvePhase(transformerPhase)
}
@Suppress("UNCHECKED_CAST")
return super.transformFile(file, data) as FirFile
}
override fun transformDeclaration(declaration: FirDeclaration, data: D): FirDeclaration {
declaration.replaceResolvePhase(transformerPhase)
if (declaration.resolvePhase < transformerPhase) {
declaration.replaceResolvePhase(transformerPhase)
}
return super.transformDeclaration(declaration, data)
}
@@ -33,6 +33,8 @@ abstract class FirAbstractTreeTransformerWithSuperTypes(
protected val scopes = mutableListOf<FirScope>()
protected val towerScope = FirCompositeScope(scopes.asReversed())
protected open fun needReplacePhase(firDeclaration: FirDeclaration): Boolean = transformerPhase > firDeclaration.resolvePhase
protected inline fun <T> withScopeCleanup(crossinline l: () -> T): T {
val sizeBefore = scopes.size
val result = l()
@@ -48,7 +50,9 @@ abstract class FirAbstractTreeTransformerWithSuperTypes(
firClass: FirClass<*>,
data: Any?
): FirStatement {
firClass.replaceResolvePhase(transformerPhase)
if (needReplacePhase(firClass)) {
firClass.replaceResolvePhase(transformerPhase)
}
return withScopeCleanup {
// Otherwise annotations may try to resolve
// themselves as inner classes of the `firClass`
@@ -67,7 +67,7 @@ abstract class ResolvedStatusCalculator {
}
}
class FirStatusResolveTransformer(
open class FirStatusResolveTransformer(
session: FirSession,
scopeSession: ScopeSession,
statusComputationSession: StatusComputationSession,
@@ -253,22 +253,13 @@ abstract class AbstractFirStatusResolveTransformer(
protected abstract fun FirDeclaration.needResolveMembers(): Boolean
protected abstract fun FirDeclaration.needResolveNestedClassifiers(): Boolean
protected open fun needReplacePhase(firDeclaration: FirDeclaration) = transformerPhase > firDeclaration.resolvePhase
override fun transformFile(file: FirFile, data: FirResolvedDeclarationStatus?): FirFile {
file.replaceResolvePhase(transformerPhase)
if (file.needResolveMembers()) {
for (declaration in file.declarations) {
if (declaration !is FirClassLikeDeclaration<*>) {
declaration.transformSingle(this, data)
}
}
}
if (file.needResolveNestedClassifiers()) {
for (declaration in file.declarations) {
if (declaration is FirClassLikeDeclaration<*>) {
declaration.transformSingle(this, data)
}
}
if (needReplacePhase(file)) {
file.replaceResolvePhase(transformerPhase)
}
transformDeclarationContent(file, data)
return file
}
@@ -293,7 +284,9 @@ abstract class AbstractFirStatusResolveTransformer(
declaration: FirDeclaration,
data: FirResolvedDeclarationStatus?
): FirDeclaration {
declaration.replaceResolvePhase(transformerPhase)
if (needReplacePhase(declaration)) {
declaration.replaceResolvePhase(transformerPhase)
}
return when (declaration) {
is FirCallableDeclaration<*> -> {
when (declaration) {
@@ -333,6 +326,36 @@ abstract class AbstractFirStatusResolveTransformer(
return transformClass(anonymousObject, data)
}
open fun transformDeclarationContent(
declaration: FirDeclaration,
data: FirResolvedDeclarationStatus?
): FirDeclaration {
val declarations = when (declaration) {
is FirRegularClass -> declaration.declarations
is FirAnonymousObject -> declaration.declarations
is FirFile -> declaration.declarations
else -> error("Not supported declaration ${declaration::class.simpleName}")
}
if (declaration.needResolveMembers()) {
val members = declarations.filter { it !is FirClassLikeDeclaration<*> }
members.forEach { member ->
if (needReplacePhase(member)) {
member.replaceResolvePhase(transformerPhase)
}
}
members.forEach { member -> member.transformSingle(this, data) }
}
if (declaration.needResolveNestedClassifiers()) {
val members = declarations.filterIsInstance<FirClassLikeDeclaration<*>>()
for (klass in members) {
klass.transformSingle(this, data)
}
}
return declaration
}
@Suppress("UNCHECKED_CAST")
override fun <F : FirClass<F>> transformClass(
klass: FirClass<F>,
@@ -340,27 +363,19 @@ abstract class AbstractFirStatusResolveTransformer(
): FirStatement {
return storeClass(klass) {
klass.typeParameters.forEach { it.transformSingle(this, data) }
klass.replaceResolvePhase(transformerPhase)
if (klass.needResolveMembers()) {
val members = klass.declarations.filter { it !is FirClassLikeDeclaration<*> }
members.forEach { it.replaceResolvePhase(transformerPhase) }
members.forEach { it.transformSingle(this, data) }
if (needReplacePhase(klass)) {
klass.replaceResolvePhase(transformerPhase)
}
if (klass.needResolveNestedClassifiers()) {
for (declaration in klass.declarations) {
if (declaration is FirClassLikeDeclaration<*>) {
declaration.transformSingle(this, data)
}
}
}
klass
transformDeclarationContent(klass, data)
} as FirStatement
}
protected fun updateResolvePhaseOfMembers(regularClass: FirRegularClass) {
for (declaration in regularClass.declarations) {
if (declaration is FirProperty || declaration is FirSimpleFunction) {
declaration.replaceResolvePhase(transformerPhase)
if (needReplacePhase(declaration)) {
declaration.replaceResolvePhase(transformerPhase)
}
}
}
}
@@ -372,7 +387,9 @@ abstract class AbstractFirStatusResolveTransformer(
}
private fun forceResolveStatusOfCorrespondingClass(typeRef: FirTypeRef) {
when (val superClass = typeRef.coneType.toSymbol(session)?.fir) {
val superClass = typeRef.coneType.toSymbol(session)?.fir
superClass?.ensureResolved(FirResolvePhase.SUPER_TYPES, session)
when (superClass) {
is FirRegularClass -> forceResolveStatusesOfClass(superClass)
is FirTypeAlias -> forceResolveStatusOfCorrespondingClass(superClass.expandedTypeRef)
}
@@ -439,7 +456,9 @@ abstract class AbstractFirStatusResolveTransformer(
statusResolver.resolveStatus(propertyAccessor, containingClass, containingProperty, isLocal = false)
)
propertyAccessor.replaceResolvePhase(transformerPhase)
if (needReplacePhase(propertyAccessor)) {
propertyAccessor.replaceResolvePhase(transformerPhase)
}
}
override fun transformConstructor(
@@ -454,7 +473,9 @@ abstract class AbstractFirStatusResolveTransformer(
simpleFunction: FirSimpleFunction,
data: FirResolvedDeclarationStatus?
): FirDeclaration {
simpleFunction.replaceResolvePhase(transformerPhase)
if (needReplacePhase(simpleFunction)) {
simpleFunction.replaceResolvePhase(transformerPhase)
}
simpleFunction.transformStatus(this, statusResolver.resolveStatus(simpleFunction, containingClass, isLocal = false))
return transformDeclaration(simpleFunction, data)
}
@@ -463,7 +484,9 @@ abstract class AbstractFirStatusResolveTransformer(
property: FirProperty,
data: FirResolvedDeclarationStatus?
): FirDeclaration {
property.replaceResolvePhase(transformerPhase)
if (needReplacePhase(property)) {
property.replaceResolvePhase(transformerPhase)
}
property.transformStatus(this, statusResolver.resolveStatus(property, containingClass, isLocal = false))
property.getter?.let { transformPropertyAccessor(it, property) }
@@ -95,23 +95,31 @@ fun <F : FirClassLikeDeclaration<F>> F.runSupertypeResolvePhaseForLocalClass(
return this.transform<F, Nothing?>(applySupertypesTransformer, null)
}
class FirApplySupertypesTransformer(
open class FirApplySupertypesTransformer(
private val supertypeComputationSession: SupertypeComputationSession
) : FirDefaultTransformer<Any?>() {
override fun <E : FirElement> transformElement(element: E, data: Any?): E {
return element
}
override fun transformFile(file: FirFile, data: Any?): FirDeclaration {
file.replaceResolvePhase(FirResolvePhase.SUPER_TYPES)
protected open fun needReplacePhase(firDeclaration: FirDeclaration) = FirResolvePhase.SUPER_TYPES > firDeclaration.resolvePhase
return (file.transformChildren(this, null) as FirFile)
protected open fun transformDeclarationContent(declaration: FirDeclaration, data: Any?): FirDeclaration {
return declaration.transformChildren(this, null) as FirDeclaration
}
override fun transformFile(file: FirFile, data: Any?): FirDeclaration {
if (needReplacePhase(file)) {
file.replaceResolvePhase(FirResolvePhase.SUPER_TYPES)
}
return transformDeclarationContent(file, null) as FirFile
}
override fun transformRegularClass(regularClass: FirRegularClass, data: Any?): FirStatement {
applyResolvedSupertypesToClass(regularClass)
return (regularClass.transformChildren(this, null) as FirRegularClass)
return transformDeclarationContent(regularClass, null) as FirRegularClass
}
private fun applyResolvedSupertypesToClass(firClass: FirClass<*>) {
@@ -121,7 +129,9 @@ class FirApplySupertypesTransformer(
// TODO: Replace with an immutable version or transformer
firClass.replaceSuperTypeRefs(supertypeRefs)
}
firClass.replaceResolvePhase(FirResolvePhase.SUPER_TYPES)
if (needReplacePhase(firClass)) {
firClass.replaceResolvePhase(FirResolvePhase.SUPER_TYPES)
}
}
override fun transformAnonymousObject(anonymousObject: FirAnonymousObject, data: Any?): FirStatement {
@@ -139,7 +149,12 @@ class FirApplySupertypesTransformer(
}
override fun transformTypeAlias(typeAlias: FirTypeAlias, data: Any?): FirDeclaration {
if (typeAlias.expandedTypeRef is FirResolvedTypeRef) return typeAlias
if (typeAlias.expandedTypeRef is FirResolvedTypeRef) {
if (needReplacePhase(typeAlias)) {
typeAlias.replaceResolvePhase(FirResolvePhase.SUPER_TYPES)
}
return typeAlias
}
val supertypeRefs = getResolvedSupertypeRefs(typeAlias)
assert(supertypeRefs.size == 1) {
@@ -148,8 +163,9 @@ class FirApplySupertypesTransformer(
// TODO: Replace with an immutable version or transformer
typeAlias.replaceExpandedTypeRef(supertypeRefs[0])
typeAlias.replaceResolvePhase(FirResolvePhase.SUPER_TYPES)
if (needReplacePhase(typeAlias)) {
typeAlias.replaceResolvePhase(FirResolvePhase.SUPER_TYPES)
}
return typeAlias
}
}
@@ -187,7 +203,7 @@ fun FirRegularClass.resolveSupertypesInTheAir(session: FirSession): List<FirType
.resolveSpecificClassLikeSupertypes(this, superTypeRefs)
}
class FirSupertypeResolverVisitor(
open class FirSupertypeResolverVisitor(
private val session: FirSession,
private val supertypeComputationSession: SupertypeComputationSession,
private val scopeSession: ScopeSession,
@@ -295,14 +311,18 @@ class FirSupertypeResolverVisitor(
return resolvedTypesRefs
}
open fun visitDeclarationContent(declaration: FirDeclaration, data: Any?) {
declaration.acceptChildren(this, null)
}
override fun visitRegularClass(regularClass: FirRegularClass, data: Any?) {
resolveSpecificClassLikeSupertypes(regularClass, regularClass.superTypeRefs)
regularClass.acceptChildren(this, null)
visitDeclarationContent(regularClass, null)
}
override fun visitAnonymousObject(anonymousObject: FirAnonymousObject, data: Any?) {
resolveSpecificClassLikeSupertypes(anonymousObject, anonymousObject.superTypeRefs)
anonymousObject.acceptChildren(this, null)
visitDeclarationContent(anonymousObject, null)
}
fun resolveSpecificClassLikeSupertypes(
@@ -397,7 +417,7 @@ class FirSupertypeResolverVisitor(
}
override fun visitFile(file: FirFile, data: Any?) {
file.acceptChildren(this, null)
visitDeclarationContent(file, null)
}
}
@@ -409,7 +429,7 @@ private fun createErrorTypeRef(fir: FirElement, message: String, kind: Diagnosti
class SupertypeComputationSession {
private val fileScopesMap = hashMapOf<FirFile, ScopePersistentList>()
private val scopesForNestedClassesMap = hashMapOf<FirClass<*>, ScopePersistentList>()
private val supertypeStatusMap = linkedMapOf<FirClassLikeDeclaration<*>, SupertypeComputationStatus>()
val supertypeStatusMap = linkedMapOf<FirClassLikeDeclaration<*>, SupertypeComputationStatus>()
val supertypesSupplier: SupertypeSupplier = object : SupertypeSupplier() {
override fun forClass(firClass: FirClass<*>, useSiteSession: FirSession): List<ConeClassLikeType> {
@@ -94,7 +94,9 @@ open class FirTypeResolveTransformer(
}
override fun transformEnumEntry(enumEntry: FirEnumEntry, data: Any?): FirDeclaration {
enumEntry.replaceResolvePhase(FirResolvePhase.TYPES)
if (needReplacePhase(enumEntry)) {
enumEntry.replaceResolvePhase(FirResolvePhase.TYPES)
}
enumEntry.transformReturnTypeRef(this, data)
enumEntry.transformTypeParameters(this, data)
enumEntry.transformAnnotations(this, data)
@@ -104,7 +106,11 @@ open class FirTypeResolveTransformer(
override fun transformProperty(property: FirProperty, data: Any?): FirDeclaration {
return withScopeCleanup {
property.addTypeParametersScope()
property.replaceResolvePhase(FirResolvePhase.TYPES)
if (needReplacePhase(property)) {
property.replaceResolvePhase(FirResolvePhase.TYPES)
property.getter?.replaceResolvePhase(FirResolvePhase.TYPES)
property.setter?.replaceResolvePhase(FirResolvePhase.TYPES)
}
property.transformTypeParameters(this, data)
.transformReturnTypeRef(this, data)
.transformReceiverTypeRef(this, data)
@@ -125,7 +131,9 @@ open class FirTypeResolveTransformer(
override fun transformField(field: FirField, data: Any?): FirDeclaration {
return withScopeCleanup {
field.replaceResolvePhase(FirResolvePhase.TYPES)
if (needReplacePhase(field)) {
field.replaceResolvePhase(FirResolvePhase.TYPES)
}
field.transformReturnTypeRef(this, data).transformAnnotations(this, data)
field
}
@@ -43,7 +43,7 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb
final override val session: FirSession get() = components.session
protected open fun needReplacePhase(firDeclaration: FirDeclaration) = true
protected open fun needReplacePhase(firDeclaration: FirDeclaration) = transformerPhase > firDeclaration.resolvePhase
fun replaceDeclarationResolvePhaseIfNeeded(firDeclaration: FirDeclaration, newResolvePhase: FirResolvePhase) {
if (needReplacePhase(firDeclaration) && newResolvePhase > firDeclaration.resolvePhase) {
@@ -378,6 +378,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
typeAlias.transformAnnotations(transformer, data)
transformer.firTowerDataContextCollector?.addDeclarationContext(typeAlias, context.towerDataContext)
typeAlias.transformExpandedTypeRef(transformer, data)
transformer.replaceDeclarationResolvePhaseIfNeeded(typeAlias, transformerPhase)
return typeAlias
}
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolved
import org.jetbrains.kotlin.fir.scopes.impl.*
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
@@ -108,7 +109,10 @@ fun ConeKotlinType.scopeForSupertype(
if (this is ConeClassErrorType) return null
val symbol = lookupTag.toSymbol(useSiteSession)
return if (symbol is FirRegularClassSymbol) {
val delegateField = delegateFields?.find { useSiteSession.typeContext.equalTypes(it.returnTypeRef.coneType, this) }
val delegateField = delegateFields?.find {
it.ensureResolved(FirResolvePhase.TYPES, useSiteSession)
useSiteSession.typeContext.equalTypes(it.returnTypeRef.coneType, this)
}
symbol.fir.scopeForSupertype(
substitutor(symbol, this, useSiteSession),
useSiteSession, scopeSession, delegateField,
@@ -56,7 +56,9 @@ fun FirRegularClassBuilder.generateValuesFunction(
}
symbol = FirNamedFunctionSymbol(CallableId(packageFqName, classFqName, ENUM_VALUES))
resolvePhase = FirResolvePhase.BODY_RESOLVE
body = buildEmptyExpressionBlock()
body = buildEmptyExpressionBlock().also {
it.replaceTypeRef(returnTypeRef)
}
}.apply {
containingClassAttr = this@generateValuesFunction.symbol.toLookupTag()
}
@@ -97,7 +99,9 @@ fun FirRegularClassBuilder.generateValueOfFunction(
isVararg = false
}
resolvePhase = FirResolvePhase.BODY_RESOLVE
body = buildEmptyExpressionBlock()
body = buildEmptyExpressionBlock().also {
it.replaceTypeRef(returnTypeRef)
}
}.apply {
containingClassAttr = this@generateValueOfFunction.symbol.toLookupTag()
}
@@ -12,10 +12,7 @@ import org.jetbrains.kotlin.fir.FirImplementationDetail
import org.jetbrains.kotlin.fir.FirModuleData
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.contracts.impl.FirEmptyContractDescription
import org.jetbrains.kotlin.fir.declarations.FirDeclarationAttributes
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.builder.buildDefaultSetterValueParameter
import org.jetbrains.kotlin.fir.expressions.FirBlock
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertyAccessorSymbol
@@ -40,7 +37,7 @@ abstract class FirDefaultPropertyAccessor(
) : FirPropertyAccessorImpl(
source,
moduleData,
resolvePhase = FirResolvePhase.BODY_RESOLVE,
resolvePhase = if (effectiveVisibility != null) FirResolvePhase.BODY_RESOLVE else FirResolvePhase.TYPES,
origin,
FirDeclarationAttributes(),
propertyTypeRef,
@@ -59,7 +56,7 @@ abstract class FirDefaultPropertyAccessor(
typeParameters = mutableListOf(),
) {
override var resolvePhase
get() = FirResolvePhase.BODY_RESOLVE
get() = if (status is FirResolvedDeclarationStatus) FirResolvePhase.BODY_RESOLVE else FirResolvePhase.TYPES
set(_) {}
final override var body: FirBlock?