FIR: Move deprecation resolve earlier

This commit is contained in:
Mikhail Glukhikh
2022-03-01 17:18:22 +03:00
committed by Space
parent 3505b285f7
commit 34998473f5
10 changed files with 176 additions and 26 deletions
@@ -20,7 +20,7 @@ internal class LLFirDesignatedAnnotationArgumentsResolveTransformer(
private val designation: FirDeclarationDesignationWithFile,
session: FirSession,
scopeSession: ScopeSession,
) : LLFirLazyTransformer, FirAnnotationArgumentsResolveTransformer(session, scopeSession) {
) : LLFirLazyTransformer, FirAnnotationArgumentsResolveTransformer(session, scopeSession, FirResolvePhase.ARGUMENTS_OF_ANNOTATIONS) {
private fun moveNextDeclaration(designationIterator: Iterator<FirDeclaration>) {
if (!designationIterator.hasNext()) {
@@ -0,0 +1,74 @@
/*
* Copyright 2010-2022 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.analysis.low.level.api.fir.transformers
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirPhaseRunner
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDeclarationDesignationWithFile
import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.ResolveTreeBuilder
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.ensurePhase
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.transformers.plugin.FirCompilerRequiredAnnotationsResolveTransformer
internal class LLFirDesignatedAnnotationsResolveTransformed(
private val designation: FirDeclarationDesignationWithFile,
session: FirSession,
scopeSession: ScopeSession,
) : LLFirLazyTransformer, FirCompilerRequiredAnnotationsResolveTransformer(session, scopeSession) {
private fun moveNextDeclaration(designationIterator: Iterator<FirDeclaration>) {
if (!designationIterator.hasNext()) {
val declaration = designation.declaration
if (declaration is FirRegularClass || declaration is FirTypeAlias) {
declaration.transform<FirDeclaration, ResolutionMode>(this, ResolutionMode.ContextIndependent)
}
return
}
when (val nextElement = designationIterator.next()) {
is FirFile -> {
withFileAndScopes(nextElement) {
moveNextDeclaration(designationIterator)
}
}
is FirRegularClass -> {
moveNextDeclaration(designationIterator)
}
else -> {
error("Unexpected declaration in designation: ${nextElement::class.qualifiedName}")
}
}
}
override fun transformDeclaration(phaseRunner: LLFirPhaseRunner) {
if (designation.declaration.resolvePhase >= FirResolvePhase.COMPILER_REQUIRED_ANNOTATIONS) return
val designationIterator = designation.toSequenceWithFile(includeTarget = false).iterator()
ResolveTreeBuilder.resolvePhase(designation.declaration, FirResolvePhase.COMPILER_REQUIRED_ANNOTATIONS) {
phaseRunner.runPhaseWithCustomResolve(FirResolvePhase.COMPILER_REQUIRED_ANNOTATIONS) {
moveNextDeclaration(designationIterator)
}
}
LLFirLazyTransformer.updatePhaseDeep(designation.declaration, FirResolvePhase.COMPILER_REQUIRED_ANNOTATIONS)
ensureResolved(designation.declaration)
ensureResolvedDeep(designation.declaration)
}
override fun ensureResolved(declaration: FirDeclaration) {
when (declaration) {
is FirClass, is FirTypeAlias ->
declaration.ensurePhase(FirResolvePhase.COMPILER_REQUIRED_ANNOTATIONS)
is FirFunction, is FirProperty, is FirEnumEntry, is FirField, is FirAnonymousInitializer ->
Unit
else ->
error("Unexpected type: ${declaration::class.simpleName}")
}
}
}
@@ -48,6 +48,11 @@ internal object LazyTransformerFactory {
designation.firFile.moduleData.session,
scopeSession,
)
FirResolvePhase.COMPILER_REQUIRED_ANNOTATIONS -> LLFirDesignatedAnnotationsResolveTransformed(
designation,
designation.firFile.moduleData.session,
scopeSession,
)
FirResolvePhase.ARGUMENTS_OF_ANNOTATIONS -> LLFirDesignatedAnnotationArgumentsResolveTransformer(
designation,
designation.firFile.moduleData.session,
@@ -28,6 +28,9 @@ abstract class FirPredicateBasedProvider : FirSessionComponent {
abstract fun fileHasPluginAnnotations(file: FirFile): Boolean
abstract fun matches(predicate: DeclarationPredicate, declaration: FirDeclaration): Boolean
open fun registerAnnotatedDeclaration(declaration: FirDeclaration, owners: PersistentList<FirDeclaration>) {
}
fun matches(predicates: List<DeclarationPredicate>, declaration: FirDeclaration): Boolean {
return predicates.any { matches(it, declaration) }
}
@@ -51,7 +54,7 @@ class FirPredicateBasedProviderImpl(private val session: FirSession) : FirPredic
return file in cache.filesWithPluginAnnotations
}
fun registerAnnotatedDeclaration(declaration: FirDeclaration, owners: PersistentList<FirDeclaration>) {
override fun registerAnnotatedDeclaration(declaration: FirDeclaration, owners: PersistentList<FirDeclaration>) {
cache.ownersForDeclaration[declaration] = owners
registerOwnersDeclarations(declaration, owners)
@@ -112,7 +112,6 @@ open class FirStatusResolveTransformer(
*/
if (computationStatus != StatusComputationSession.StatusComputationStatus.Computed) {
regularClass.transformStatus(this, statusResolver.resolveStatus(regularClass, containingClass, isLocal = false))
calculateDeprecations(regularClass)
}
return transformClass(regularClass, data).also {
statusComputationSession.endComputing(regularClass)
@@ -310,7 +309,6 @@ abstract class AbstractFirStatusResolveTransformer(
): FirStatement {
typeAlias.typeParameters.forEach { transformDeclaration(it, data) }
typeAlias.transformStatus(this, statusResolver.resolveStatus(typeAlias, containingClass, isLocal = false))
calculateDeprecations(typeAlias)
return transformDeclaration(typeAlias, data) as FirTypeAlias
}
@@ -554,12 +552,6 @@ abstract class AbstractFirStatusResolveTransformer(
return block
}
protected fun calculateDeprecations(regularClass: FirClassLikeDeclaration) {
if (regularClass.deprecation == null) {
regularClass.replaceDeprecation(regularClass.getDeprecationInfos(session.languageVersionSettings.apiVersion))
}
}
protected fun calculateDeprecations(simpleFunction: FirCallableDeclaration) {
if (simpleFunction.deprecation == null) {
simpleFunction.replaceDeprecation(simpleFunction.getDeprecationInfos(session.languageVersionSettings.apiVersion))
@@ -25,11 +25,23 @@ internal abstract class FirAbstractAnnotationResolveTransformer<D, S>(
protected lateinit var scopes: List<FirScope>
override fun transformFile(file: FirFile, data: D): FirFile {
inline fun <T> withFileScopes(file: FirFile, f: () -> T): T {
scopes = createImportingScopes(file, session, scopeSession, useCaching = false)
val state = beforeTransformingChildren(file)
file.transformDeclarations(this, data)
afterTransformingChildren(state)
try {
return f()
} finally {
afterTransformingChildren(state)
}
}
override fun transformFile(file: FirFile, data: D): FirFile {
withFileScopes(file) {
scopes = createImportingScopes(file, session, scopeSession, useCaching = false)
val state = beforeTransformingChildren(file)
file.transformDeclarations(this, data)
afterTransformingChildren(state)
}
return transformDeclaration(file, data) as FirFile
}
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.resolve.transformers.plugin
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.transformers.AdapterForResolveProcessor
@@ -24,7 +25,7 @@ class FirAnnotationArgumentsResolveProcessor(
@AdapterForResolveProcessor
class FirAnnotationArgumentsResolveTransformerAdapter(session: FirSession, scopeSession: ScopeSession) : FirTransformer<Any?>() {
private val transformer = FirAnnotationArgumentsResolveTransformer(session, scopeSession)
private val transformer = FirAnnotationArgumentsResolveTransformer(session, scopeSession, FirResolvePhase.ARGUMENTS_OF_ANNOTATIONS)
override fun <E : FirElement> transformElement(element: E, data: Any?): E {
return element
@@ -19,10 +19,11 @@ import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirExpressions
open class FirAnnotationArgumentsResolveTransformer(
session: FirSession,
scopeSession: ScopeSession,
resolvePhase: FirResolvePhase,
outerBodyResolveContext: BodyResolveContext? = null
) : FirBodyResolveTransformer(
session,
FirResolvePhase.ARGUMENTS_OF_ANNOTATIONS,
resolvePhase,
implicitTypeOnly = false,
scopeSession,
outerBodyResolveContext = outerBodyResolveContext
@@ -13,15 +13,23 @@ import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase.COMPILER_REQUIRED_ANNOTATIONS
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.extensions.*
import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.fqName
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
import org.jetbrains.kotlin.fir.resolve.transformers.*
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.FirUserTypeRef
import org.jetbrains.kotlin.fir.types.coneTypeSafe
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.Deprecated
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.DeprecatedSinceKotlin
class FirCompilerRequiredAnnotationsResolveProcessor(
session: FirSession,
@@ -40,10 +48,10 @@ class FirCompilerRequiredAnnotationsResolveProcessor(
}
}
class FirCompilerRequiredAnnotationsResolveTransformer(
override val session: FirSession,
open class FirCompilerRequiredAnnotationsResolveTransformer(
final override val session: FirSession,
scopeSession: ScopeSession
) : FirAbstractPhaseTransformer<Any?>(FirResolvePhase.COMPILER_REQUIRED_ANNOTATIONS) {
) : FirAbstractPhaseTransformer<Any?>(COMPILER_REQUIRED_ANNOTATIONS) {
private val annotationTransformer = FirAnnotationResolveTransformer(session, scopeSession)
private val importTransformer = FirPartialImportResolveTransformer(session)
@@ -55,7 +63,6 @@ class FirCompilerRequiredAnnotationsResolveTransformer(
override fun transformFile(file: FirFile, data: Any?): FirFile {
checkSessionConsistency(file)
val registeredPluginAnnotations = session.registeredPluginAnnotations
if (!registeredPluginAnnotations.hasRegisteredAnnotations) return file
val newAnnotations = file.resolveAnnotations(registeredPluginAnnotations.annotations, registeredPluginAnnotations.metaAnnotations)
if (!newAnnotations.isEmpty) {
for (metaAnnotation in newAnnotations.keySet()) {
@@ -67,6 +74,22 @@ class FirCompilerRequiredAnnotationsResolveTransformer(
return file
}
fun <T> withFile(file: FirFile, f: () -> T): T = annotationTransformer.withFile(file, f)
fun <T> withFileAndScopes(file: FirFile, f: () -> T): T {
annotationTransformer.withFile(file) {
return annotationTransformer.withFileScopes(file, f)
}
}
override fun transformRegularClass(regularClass: FirRegularClass, data: Any?): FirStatement {
return annotationTransformer.transformRegularClass(regularClass, LinkedHashMultimap.create())
}
override fun transformTypeAlias(typeAlias: FirTypeAlias, data: Any?): FirStatement {
return annotationTransformer.transformTypeAlias(typeAlias, LinkedHashMultimap.create())
}
private fun FirFile.resolveAnnotations(
annotations: Set<AnnotationFqn>,
metaAnnotations: Set<AnnotationFqn>
@@ -74,6 +97,7 @@ class FirCompilerRequiredAnnotationsResolveTransformer(
importTransformer.acceptableFqNames = annotations
this.transformImports(importTransformer, null)
annotationTransformer.acceptableFqNames = annotations
annotationTransformer.metaAnnotations = metaAnnotations
val newAnnotations = LinkedHashMultimap.create<AnnotationFqn, FirRegularClass>()
this.transform<FirFile, Multimap<AnnotationFqn, FirRegularClass>>(annotationTransformer, newAnnotations)
@@ -83,7 +107,7 @@ class FirCompilerRequiredAnnotationsResolveTransformer(
private class FirPartialImportResolveTransformer(
session: FirSession
) : FirImportResolveTransformer(session, FirResolvePhase.COMPILER_REQUIRED_ANNOTATIONS) {
) : FirImportResolveTransformer(session, COMPILER_REQUIRED_ANNOTATIONS) {
var acceptableFqNames: Set<FqName> = emptySet()
override val FqName.isAcceptable: Boolean
@@ -93,15 +117,20 @@ private class FirPartialImportResolveTransformer(
private class FirAnnotationResolveTransformer(
session: FirSession,
scopeSession: ScopeSession
) : FirAbstractAnnotationResolveTransformer<Multimap<AnnotationFqn, FirRegularClass>, PersistentList<FirDeclaration>>(session, scopeSession) {
private val predicateBasedProvider = session.predicateBasedProvider as FirPredicateBasedProviderImpl
) : FirAbstractAnnotationResolveTransformer<Multimap<AnnotationFqn, FirRegularClass>, PersistentList<FirDeclaration>>(
session, scopeSession
) {
private val predicateBasedProvider = session.predicateBasedProvider
var acceptableFqNames: Set<AnnotationFqn> = emptySet()
var metaAnnotations: Set<AnnotationFqn> = emptySet()
private val typeResolverTransformer: FirSpecificTypeResolverTransformer = FirSpecificTypeResolverTransformer(
session,
errorTypeAsResolved = false
)
private val argumentsTransformer = FirAnnotationArgumentsResolveTransformer(session, scopeSession, COMPILER_REQUIRED_ANNOTATIONS)
private var owners: PersistentList<FirDeclaration> = persistentListOf()
private val classDeclarationsStack = ArrayDeque<FirClass>()
@@ -124,10 +153,22 @@ private class FirAnnotationResolveTransformer(
annotation: FirAnnotation,
data: Multimap<AnnotationFqn, FirRegularClass>
): FirStatement {
return annotation.transformAnnotationTypeRef(
val annotationTypeRef = annotation.annotationTypeRef
if (annotationTypeRef !is FirUserTypeRef) return annotation
val name = annotationTypeRef.qualifier.last().name
if (name != Deprecated.shortClassName && name != DeprecatedSinceKotlin.shortClassName &&
acceptableFqNames.none { it.shortName() == name }
) return annotation
val transformedAnnotation = annotation.transformAnnotationTypeRef(
typeResolverTransformer,
ScopeClassDeclaration(scopes, classDeclarationsStack)
ScopeClassDeclaration(scopes.asReversed(), classDeclarationsStack)
)
// TODO: what if we have type alias here?
if (transformedAnnotation.annotationTypeRef.coneTypeSafe<ConeClassLikeType>()?.lookupTag?.classId == Deprecated) {
argumentsTransformer.transformAnnotation(transformedAnnotation, ResolutionMode.ContextDependent)
}
return transformedAnnotation
}
override fun transformRegularClass(
@@ -142,10 +183,17 @@ private class FirAnnotationResolveTransformer(
data.put(annotation, regularClass)
}
}
calculateDeprecations(regularClass)
}
}
}
override fun transformTypeAlias(typeAlias: FirTypeAlias, data: Multimap<AnnotationFqn, FirRegularClass>): FirTypeAlias {
return super.transformTypeAlias(typeAlias, data).also {
calculateDeprecations(typeAlias)
}
}
override fun transformDeclaration(declaration: FirDeclaration, data: Multimap<AnnotationFqn, FirRegularClass>): FirDeclaration {
return super.transformDeclaration(declaration, data).also {
predicateBasedProvider.registerAnnotatedDeclaration(declaration, owners)
@@ -153,8 +201,22 @@ private class FirAnnotationResolveTransformer(
}
override fun transformFile(file: FirFile, data: Multimap<AnnotationFqn, FirRegularClass>): FirFile {
typeResolverTransformer.withFile(file) {
withFile(file) {
return super.transformFile(file, data)
}
}
inline fun <T> withFile(file: FirFile, f: () -> T): T {
typeResolverTransformer.withFile(file) {
argumentsTransformer.context.withFile(file, argumentsTransformer.components) {
return f()
}
}
}
private fun calculateDeprecations(classLikeDeclaration: FirClassLikeDeclaration) {
if (classLikeDeclaration.deprecation == null) {
classLikeDeclaration.replaceDeprecation(classLikeDeclaration.getDeprecationInfos(session.languageVersionSettings.apiVersion))
}
}
}
@@ -26,7 +26,7 @@ sealed class FirClassLikeSymbol<D : FirClassLikeDeclaration>(
val deprecation: DeprecationsPerUseSite?
get() {
ensureResolved(FirResolvePhase.STATUS)
ensureResolved(FirResolvePhase.COMPILER_REQUIRED_ANNOTATIONS)
return fir.deprecation
}