FIR: Move deprecation resolve earlier
This commit is contained in:
+1
-1
@@ -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()) {
|
||||
|
||||
+74
@@ -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}")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+5
@@ -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,
|
||||
|
||||
+4
-1
@@ -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)
|
||||
|
||||
|
||||
-8
@@ -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))
|
||||
|
||||
+15
-3
@@ -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
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -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
|
||||
|
||||
+2
-1
@@ -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
|
||||
|
||||
+72
-10
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user