[FIR] Expand typealiases when checking deprecations
^KT-59901 Fixed
This commit is contained in:
committed by
Space Team
parent
03fdba5aa7
commit
4a9ba1c9ac
+7
-7
@@ -44,13 +44,13 @@ internal class KtFirSymbolInfoProvider(
|
||||
|
||||
return when (val firSymbol = symbol.firSymbol) {
|
||||
is FirPropertySymbol -> {
|
||||
firSymbol.getDeprecationForCallSite(apiVersion, AnnotationUseSiteTarget.PROPERTY)
|
||||
firSymbol.getDeprecationForCallSite(analysisSession.useSiteSession, AnnotationUseSiteTarget.PROPERTY)
|
||||
}
|
||||
is FirBackingFieldSymbol -> {
|
||||
firSymbol.getDeprecationForCallSite(apiVersion, AnnotationUseSiteTarget.FIELD)
|
||||
firSymbol.getDeprecationForCallSite(analysisSession.useSiteSession, AnnotationUseSiteTarget.FIELD)
|
||||
}
|
||||
else -> {
|
||||
firSymbol.getDeprecationForCallSite(apiVersion)
|
||||
firSymbol.getDeprecationForCallSite(analysisSession.useSiteSession)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,9 +67,9 @@ internal class KtFirSymbolInfoProvider(
|
||||
override fun getDeprecation(symbol: KtSymbol, annotationUseSiteTarget: AnnotationUseSiteTarget?): DeprecationInfo? {
|
||||
require(symbol is KtFirSymbol<*>)
|
||||
return if (annotationUseSiteTarget != null) {
|
||||
symbol.firSymbol.getDeprecationForCallSite(apiVersion, annotationUseSiteTarget)
|
||||
symbol.firSymbol.getDeprecationForCallSite(analysisSession.useSiteSession, annotationUseSiteTarget)
|
||||
} else {
|
||||
symbol.firSymbol.getDeprecationForCallSite(apiVersion)
|
||||
symbol.firSymbol.getDeprecationForCallSite(analysisSession.useSiteSession)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -77,7 +77,7 @@ internal class KtFirSymbolInfoProvider(
|
||||
override fun getGetterDeprecation(symbol: KtPropertySymbol): DeprecationInfo? {
|
||||
require(symbol is KtFirSymbol<*>)
|
||||
return symbol.firSymbol.getDeprecationForCallSite(
|
||||
apiVersion,
|
||||
analysisSession.useSiteSession,
|
||||
AnnotationUseSiteTarget.PROPERTY_GETTER,
|
||||
AnnotationUseSiteTarget.PROPERTY,
|
||||
)
|
||||
@@ -87,7 +87,7 @@ internal class KtFirSymbolInfoProvider(
|
||||
override fun getSetterDeprecation(symbol: KtPropertySymbol): DeprecationInfo? {
|
||||
require(symbol is KtFirSymbol<*>)
|
||||
return symbol.firSymbol.getDeprecationForCallSite(
|
||||
apiVersion,
|
||||
analysisSession.useSiteSession,
|
||||
AnnotationUseSiteTarget.PROPERTY_SETTER,
|
||||
AnnotationUseSiteTarget.PROPERTY,
|
||||
)
|
||||
|
||||
-1
@@ -5,7 +5,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.checkers
|
||||
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.type.FirUnsupportedDefaultValueInFunctionTypeParameterChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.type.*
|
||||
|
||||
object CommonTypeCheckers : TypeCheckers() {
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ object FirOptInLanguageVersionSettingsChecker : FirLanguageVersionSettingsChecke
|
||||
rawReport(false, "Class $fqNameAsString is not an opt-in requirement marker")
|
||||
return
|
||||
}
|
||||
val deprecationInfo = symbol.getDeprecation(context.languageVersionSettings.apiVersion)?.all ?: return
|
||||
val deprecationInfo = symbol.getOwnDeprecation(context.languageVersionSettings.apiVersion)?.all ?: return
|
||||
rawReport(
|
||||
deprecationInfo.deprecationLevel != DeprecationLevelValue.WARNING,
|
||||
"Opt-in requirement marker $fqNameAsString is deprecated" + deprecationInfo.message?.let { ". $it" }.orEmpty()
|
||||
|
||||
+3
-2
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.getContainingFile
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.toSymbol
|
||||
import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.declaredMemberScope
|
||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||
@@ -298,7 +299,7 @@ object FirImportsChecker : FirFileChecker() {
|
||||
val importedFqName = import.importedFqName ?: return
|
||||
if (importedFqName.isRoot || importedFqName.shortName().asString().isEmpty()) return
|
||||
val classId = (import as? FirResolvedImport)?.resolvedParentClassId ?: ClassId.topLevel(importedFqName)
|
||||
val classLike: FirRegularClassSymbol = classId.resolveToClass(context) ?: return
|
||||
FirDeprecationChecker.reportApiStatusIfNeeded(import.source, classLike, context, reporter)
|
||||
val symbol = classId.toSymbol(context.session) ?: return
|
||||
FirDeprecationChecker.reportApiStatusIfNeeded(import.source, symbol, context, reporter)
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -14,7 +14,10 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
object FirDeprecatedQualifierChecker : FirResolvedQualifierChecker() {
|
||||
override fun check(expression: FirResolvedQualifier, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
expression.nonFatalDiagnostics.filterIsInstance<ConeDeprecated>().forEach { diagnostic ->
|
||||
FirDeprecationChecker.reportApiStatus(diagnostic.source, diagnostic.symbol, null, diagnostic.deprecationInfo, reporter, context)
|
||||
FirDeprecationChecker.reportApiStatus(
|
||||
diagnostic.source, diagnostic.symbol, isTypealiasExpansion = false,
|
||||
diagnostic.deprecationInfo, reporter, context
|
||||
)
|
||||
}
|
||||
if (expression.resolvedToCompanionObject) {
|
||||
val companionSymbol = (expression.symbol as? FirRegularClassSymbol)?.companionObjectSymbol ?: return
|
||||
|
||||
+43
-34
@@ -12,18 +12,18 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.declarations.FutureApiDeprecationInfo
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.isLhsOfAssignment
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.type.FirDeprecatedTypeChecker
|
||||
import org.jetbrains.kotlin.fir.declarations.getDeprecation
|
||||
import org.jetbrains.kotlin.fir.declarations.getOwnDeprecation
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.references.resolved
|
||||
import org.jetbrains.kotlin.fir.resolve.firClassLike
|
||||
import org.jetbrains.kotlin.fir.resolve.typeAliasForConstructor
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationInfo
|
||||
@@ -43,31 +43,18 @@ object FirDeprecationChecker : FirBasicExpressionChecker() {
|
||||
|
||||
val calleeReference = expression.calleeReference ?: return
|
||||
val resolvedReference = calleeReference.resolved ?: return
|
||||
val source = resolvedReference.source
|
||||
val referencedSymbol = resolvedReference.resolvedSymbol
|
||||
|
||||
// If this is a constructor call through a typealias, we want to check deprecations on the typealias itself as well as any
|
||||
// intermediary expansions.
|
||||
// However, we'll already check the final expansion below, so we don't want to do it here as well to prevent duplicate diagnostics.
|
||||
val typeAliasForConstructor = (referencedSymbol as? FirConstructorSymbol)?.typeAliasForConstructor
|
||||
if (typeAliasForConstructor != null && expression is FirQualifiedAccessExpression) {
|
||||
FirDeprecatedTypeChecker.reportDeprecationsRecursively(
|
||||
typeAliasForConstructor,
|
||||
source,
|
||||
context,
|
||||
reporter,
|
||||
// We pass the containing class symbol to ignore the final expansion.
|
||||
symbolToIgnore = referencedSymbol.getContainingClassSymbol(context.session)
|
||||
)
|
||||
}
|
||||
|
||||
if (expression is FirDelegatedConstructorCall) {
|
||||
// Report deprecations on the constructor itself, not on the declaring class as that will be handled by FirDeprecatedTypeChecker
|
||||
val constructorOnlyDeprecation = referencedSymbol.getDeprecation(context.session, expression) ?: return
|
||||
val typealiasSymbol = expression.constructedTypeRef.firClassLike(context.session)?.symbol as? FirTypeAliasSymbol
|
||||
reportApiStatus(source, referencedSymbol, typealiasSymbol, constructorOnlyDeprecation, reporter, context)
|
||||
val isTypealiasExpansion = expression.constructedTypeRef.firClassLike(context.session)?.symbol is FirTypeAliasSymbol
|
||||
reportApiStatus(
|
||||
resolvedReference.source, referencedSymbol, isTypealiasExpansion,
|
||||
constructorOnlyDeprecation, reporter, context
|
||||
)
|
||||
} else {
|
||||
reportApiStatusIfNeeded(source, referencedSymbol, context, reporter, typeAliasForConstructor, callSite = expression)
|
||||
reportApiStatusIfNeeded(resolvedReference.source, referencedSymbol, context, reporter, callSite = expression)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,17 +63,36 @@ object FirDeprecationChecker : FirBasicExpressionChecker() {
|
||||
referencedSymbol: FirBasedSymbol<*>,
|
||||
context: CheckerContext,
|
||||
reporter: DiagnosticReporter,
|
||||
typealiasSymbol: FirTypeAliasSymbol? = null,
|
||||
callSite: FirElement? = null,
|
||||
) {
|
||||
val deprecation = getWorstDeprecation(callSite, referencedSymbol, context) ?: return
|
||||
reportApiStatus(source, referencedSymbol, typealiasSymbol, deprecation, reporter, context)
|
||||
val isTypealiasExpansion = deprecation.isTypealiasExpansionOf(referencedSymbol, callSite, context)
|
||||
reportApiStatus(source, referencedSymbol, isTypealiasExpansion, deprecation, reporter, context)
|
||||
}
|
||||
|
||||
private fun DeprecationInfo.isTypealiasExpansionOf(
|
||||
referencedSymbol: FirBasedSymbol<*>,
|
||||
callSite: FirElement?,
|
||||
context: CheckerContext,
|
||||
): Boolean = when (referencedSymbol) {
|
||||
is FirConstructorSymbol -> referencedSymbol.typeAliasForConstructor
|
||||
?.let { isTypealiasExpansionOf(it, callSite, context) }
|
||||
?: false
|
||||
!is FirTypeAliasSymbol -> false
|
||||
else -> referencedSymbol.getOwnDeprecation(context.session, callSite).let {
|
||||
// If 2 deprecations along a typealias "expansion chain"
|
||||
// are equivalent (a <= b && a >= b), then getDeprecation()
|
||||
// has returned the first of them.
|
||||
// When calling getWorstDeprecation(), deprecations
|
||||
// from typealiases should come first.
|
||||
it == null || it < this
|
||||
}
|
||||
}
|
||||
|
||||
internal fun reportApiStatus(
|
||||
source: KtSourceElement?,
|
||||
referencedSymbol: FirBasedSymbol<*>,
|
||||
typealiasSymbol: FirTypeAliasSymbol?,
|
||||
isTypealiasExpansion: Boolean,
|
||||
deprecationInfo: DeprecationInfo,
|
||||
reporter: DiagnosticReporter,
|
||||
context: CheckerContext,
|
||||
@@ -94,19 +100,19 @@ object FirDeprecationChecker : FirBasicExpressionChecker() {
|
||||
if (deprecationInfo is FutureApiDeprecationInfo) {
|
||||
reportApiNotAvailable(source, deprecationInfo, reporter, context)
|
||||
} else {
|
||||
reportDeprecation(source, referencedSymbol, typealiasSymbol, deprecationInfo, reporter, context)
|
||||
reportDeprecation(source, referencedSymbol, isTypealiasExpansion, deprecationInfo, reporter, context)
|
||||
}
|
||||
}
|
||||
|
||||
private fun reportDeprecation(
|
||||
source: KtSourceElement?,
|
||||
referencedSymbol: FirBasedSymbol<*>,
|
||||
typealiasSymbol: FirTypeAliasSymbol?,
|
||||
isTypealiasExpansion: Boolean,
|
||||
deprecationInfo: DeprecationInfo,
|
||||
reporter: DiagnosticReporter,
|
||||
context: CheckerContext,
|
||||
context: CheckerContext
|
||||
) {
|
||||
if (typealiasSymbol == null) {
|
||||
if (!isTypealiasExpansion) {
|
||||
val diagnostic = when (deprecationInfo.deprecationLevel) {
|
||||
DeprecationLevelValue.ERROR, DeprecationLevelValue.HIDDEN -> FirErrors.DEPRECATION_ERROR
|
||||
DeprecationLevelValue.WARNING -> FirErrors.DEPRECATION
|
||||
@@ -117,7 +123,7 @@ object FirDeprecationChecker : FirBasicExpressionChecker() {
|
||||
DeprecationLevelValue.ERROR, DeprecationLevelValue.HIDDEN -> FirErrors.TYPEALIAS_EXPANSION_DEPRECATION_ERROR
|
||||
DeprecationLevelValue.WARNING -> FirErrors.TYPEALIAS_EXPANSION_DEPRECATION
|
||||
}
|
||||
reporter.reportOn(source, diagnostic, typealiasSymbol, referencedSymbol, deprecationInfo.message ?: "", context)
|
||||
reporter.reportOn(source, diagnostic, referencedSymbol, referencedSymbol, deprecationInfo.message ?: "", context)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,15 +145,18 @@ object FirDeprecationChecker : FirBasicExpressionChecker() {
|
||||
private fun getWorstDeprecation(
|
||||
callSite: FirElement?,
|
||||
symbol: FirBasedSymbol<*>,
|
||||
context: CheckerContext,
|
||||
context: CheckerContext
|
||||
): DeprecationInfo? {
|
||||
val deprecationInfos = listOfNotNull(
|
||||
symbol.getDeprecation(context.session, callSite),
|
||||
(symbol as? FirConstructorSymbol)
|
||||
?.resolvedReturnTypeRef
|
||||
?.toRegularClassSymbol(context.session)
|
||||
?.getDeprecation(context.session, callSite)
|
||||
?.classSymbolItIsCalledThrough(context)
|
||||
?.getDeprecation(context.session, callSite),
|
||||
symbol.getDeprecation(context.session, callSite),
|
||||
)
|
||||
return deprecationInfos.maxOrNull()
|
||||
}
|
||||
|
||||
private fun FirConstructorSymbol.classSymbolItIsCalledThrough(context: CheckerContext): FirClassLikeSymbol<*>? {
|
||||
return typeAliasForConstructor ?: (resolvedReturnTypeRef.toRegularClassSymbol(context.session))
|
||||
}
|
||||
}
|
||||
|
||||
+2
-52
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirDeprecationCheck
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
@@ -24,58 +23,9 @@ object FirDeprecatedTypeChecker : FirTypeRefChecker() {
|
||||
if (source.kind is KtFakeSourceElementKind) return
|
||||
|
||||
val resolved = typeRef.coneTypeSafe<ConeClassLikeType>() ?: return
|
||||
checkType(resolved, null, source, context, reporter, symbolToIgnore = null)
|
||||
}
|
||||
val symbol = resolved.lookupTag.toSymbol(context.session) ?: return
|
||||
|
||||
private fun checkType(
|
||||
type: ConeClassLikeType,
|
||||
typeAliasSymbol: FirTypeAliasSymbol?,
|
||||
source: KtSourceElement?,
|
||||
context: CheckerContext,
|
||||
reporter: DiagnosticReporter,
|
||||
symbolToIgnore: FirClassLikeSymbol<*>?,
|
||||
) {
|
||||
val symbol = type.lookupTag.toSymbol(context.session) ?: return
|
||||
reportDeprecationsRecursively(symbol, typeAliasSymbol, source, context, reporter, symbolToIgnore)
|
||||
}
|
||||
|
||||
@OptIn(SymbolInternals::class)
|
||||
private fun reportDeprecationsRecursively(
|
||||
symbol: FirClassLikeSymbol<*>,
|
||||
// If not-null, TYPEALIAS_EXPANSION_DEPRECATION will be reported instead of DEPRECATION.
|
||||
typeAliasSymbol: FirTypeAliasSymbol?,
|
||||
source: KtSourceElement?,
|
||||
context: CheckerContext,
|
||||
reporter: DiagnosticReporter,
|
||||
symbolToIgnore: FirClassLikeSymbol<*>?,
|
||||
) {
|
||||
if (symbol == symbolToIgnore) return
|
||||
|
||||
FirDeprecationChecker.reportApiStatusIfNeeded(source, symbol, context, reporter, typealiasSymbol = typeAliasSymbol)
|
||||
if (symbol is FirTypeAliasSymbol) {
|
||||
val typeAlias = symbol.fir
|
||||
typeAlias.lazyResolveToPhase(FirResolvePhase.TYPES)
|
||||
typeAlias.expandedTypeRef.coneType.forEachType {
|
||||
if (it is ConeClassLikeType) checkType(it, symbol, source, context, reporter, symbolToIgnore)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports deprecations on [symbol]. If [symbol] is a typealias, deprecations will be reported on the expansions recursively.
|
||||
*
|
||||
* @param symbolToIgnore If equal to [symbol], no deprecations on the [symbol] and its expansions will be reported.
|
||||
* It's passed to recursive calls and can be used to only report deprecations on a typealias and its intermediary expansions
|
||||
* but not on the final expansion if set to the fully expanded class symbol.
|
||||
*/
|
||||
fun reportDeprecationsRecursively(
|
||||
symbol: FirClassLikeSymbol<*>,
|
||||
source: KtSourceElement?,
|
||||
context: CheckerContext,
|
||||
reporter: DiagnosticReporter,
|
||||
symbolToIgnore: FirClassLikeSymbol<*>?,
|
||||
) {
|
||||
reportDeprecationsRecursively(symbol, typeAliasSymbol = null, source, context, reporter, symbolToIgnore)
|
||||
FirDeprecationChecker.reportApiStatusIfNeeded(source, symbol, context, reporter)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -248,7 +248,7 @@ private fun JavaAnnotation.toFirAnnotationCall(session: FirSession): FirAnnotati
|
||||
}
|
||||
|
||||
/**
|
||||
* This is required to avoid contract violation during [org.jetbrains.kotlin.fir.declarations.getDeprecationForCallSite]
|
||||
* This is required to avoid contract violation during [org.jetbrains.kotlin.fir.declarations.getOwnDeprecationForCallSite]
|
||||
* Because argument transformation may lead to [org.jetbrains.kotlin.fir.declarations.FirResolvePhase.TYPES]+ lazy resolution
|
||||
* See KT-59342
|
||||
* TODO: KT-60520
|
||||
|
||||
+71
-18
@@ -19,6 +19,10 @@ import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.forEachType
|
||||
import org.jetbrains.kotlin.fir.types.toSymbol
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.StandardClassIds
|
||||
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.ParameterNames
|
||||
@@ -71,24 +75,33 @@ inline fun buildDeprecationAnnotationInfoPerUseSiteStorage(builder: DeprecationA
|
||||
return DeprecationAnnotationInfoPerUseSiteStorageBuilder().apply(builder).build()
|
||||
}
|
||||
|
||||
fun FirBasedSymbol<*>.getDeprecation(session: FirSession, callSite: FirElement?): DeprecationInfo? {
|
||||
return getDeprecation(session.languageVersionSettings.apiVersion, callSite)
|
||||
private fun FirBasedSymbol<*>.getUseSitesForCallSite(callSite: FirElement?): Array<AnnotationUseSiteTarget> {
|
||||
return when (this) {
|
||||
is FirPropertySymbol -> when (callSite) {
|
||||
is FirVariableAssignment -> arrayOf(AnnotationUseSiteTarget.PROPERTY_SETTER, AnnotationUseSiteTarget.PROPERTY)
|
||||
is FirPropertyAccessExpression -> arrayOf(AnnotationUseSiteTarget.PROPERTY_GETTER, AnnotationUseSiteTarget.PROPERTY)
|
||||
else -> arrayOf(AnnotationUseSiteTarget.PROPERTY)
|
||||
}
|
||||
else -> arrayOf()
|
||||
}
|
||||
}
|
||||
|
||||
fun FirBasedSymbol<*>.getDeprecation(apiVersion: ApiVersion, callSite: FirElement?): DeprecationInfo? {
|
||||
return when (this) {
|
||||
is FirPropertySymbol ->
|
||||
when (callSite) {
|
||||
is FirVariableAssignment ->
|
||||
getDeprecationForCallSite(apiVersion, AnnotationUseSiteTarget.PROPERTY_SETTER, AnnotationUseSiteTarget.PROPERTY)
|
||||
is FirPropertyAccessExpression ->
|
||||
getDeprecationForCallSite(apiVersion, AnnotationUseSiteTarget.PROPERTY_GETTER, AnnotationUseSiteTarget.PROPERTY)
|
||||
else ->
|
||||
getDeprecationForCallSite(apiVersion, AnnotationUseSiteTarget.PROPERTY)
|
||||
}
|
||||
else ->
|
||||
getDeprecationForCallSite(apiVersion)
|
||||
}
|
||||
/**
|
||||
* Returns deprecation that is declared on the
|
||||
* corresponding declaration.
|
||||
*/
|
||||
fun FirBasedSymbol<*>.getOwnDeprecation(session: FirSession, callSite: FirElement?): DeprecationInfo? {
|
||||
return getOwnDeprecationForCallSite(session.languageVersionSettings.apiVersion, *getUseSitesForCallSite(callSite))
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns deprecation that is declared on
|
||||
* the corresponding declaration directly
|
||||
* or, in case of a typealias, on any of
|
||||
* its expansions.
|
||||
*/
|
||||
fun FirBasedSymbol<*>.getDeprecation(session: FirSession, callSite: FirElement?): DeprecationInfo? {
|
||||
return getDeprecationForCallSite(session, *getUseSitesForCallSite(callSite))
|
||||
}
|
||||
|
||||
fun FirAnnotationContainer.getDeprecationsProvider(session: FirSession): DeprecationsProvider {
|
||||
@@ -162,18 +175,58 @@ fun List<FirAnnotation>.getDeprecationsProviderFromAnnotations(
|
||||
return deprecationAnnotationByUseSite.toDeprecationsProvider(session.firCachesFactory)
|
||||
}
|
||||
|
||||
fun FirBasedSymbol<*>.getDeprecationForCallSite(
|
||||
/**
|
||||
* Returns deprecation that is declared on the
|
||||
* corresponding declaration.
|
||||
*/
|
||||
private fun FirBasedSymbol<*>.getOwnDeprecationForCallSite(
|
||||
apiVersion: ApiVersion,
|
||||
vararg sites: AnnotationUseSiteTarget
|
||||
): DeprecationInfo? {
|
||||
val deprecations = when (this) {
|
||||
is FirCallableSymbol<*> -> getDeprecation(apiVersion)
|
||||
is FirClassLikeSymbol<*> -> getDeprecation(apiVersion)
|
||||
is FirClassLikeSymbol<*> -> getOwnDeprecation(apiVersion)
|
||||
else -> null
|
||||
}
|
||||
return (deprecations ?: EmptyDeprecationsPerUseSite).forUseSite(*sites)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns deprecation that is declared on
|
||||
* the corresponding declaration directly
|
||||
* or, in case of a typealias, on any of
|
||||
* its expansions.
|
||||
*/
|
||||
fun FirBasedSymbol<*>.getDeprecationForCallSite(
|
||||
session: FirSession,
|
||||
vararg sites: AnnotationUseSiteTarget,
|
||||
): DeprecationInfo? {
|
||||
val apiVersion = session.languageVersionSettings.apiVersion
|
||||
|
||||
return when (this) {
|
||||
!is FirTypeAliasSymbol -> getOwnDeprecationForCallSite(apiVersion, *sites)
|
||||
else -> {
|
||||
var worstDeprecationInfo = getOwnDeprecationForCallSite(apiVersion, *sites)
|
||||
val visited = mutableMapOf<ConeKotlinType, DeprecationInfo?>()
|
||||
|
||||
resolvedExpandedTypeRef.type.forEachType {
|
||||
val deprecationInfo = visited.getOrPut(it) {
|
||||
val symbol = it.toSymbol(session) ?: return@forEachType
|
||||
symbol.getDeprecationForCallSite(session, *sites)
|
||||
} ?: return@forEachType
|
||||
|
||||
val currentWorstDeprecation = worstDeprecationInfo
|
||||
|
||||
if (currentWorstDeprecation == null || deprecationInfo > currentWorstDeprecation) {
|
||||
worstDeprecationInfo = deprecationInfo
|
||||
}
|
||||
}
|
||||
|
||||
worstDeprecationInfo
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirAnnotation.getVersionFromArgument(name: Name): ApiVersion? =
|
||||
getStringArgument(name)?.let { ApiVersion.parse(it) }
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.fir
|
||||
|
||||
import org.jetbrains.kotlin.KtSourceElement
|
||||
import org.jetbrains.kotlin.config.ApiVersion
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
import org.jetbrains.kotlin.fir.declarations.fullyExpandedClass
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
|
||||
@@ -22,8 +21,6 @@ import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeDeprecated
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
||||
import org.jetbrains.kotlin.fir.resolve.typeForQualifier
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeProjection
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -201,7 +198,7 @@ internal fun extractNonFatalDiagnostics(
|
||||
val prevDiagnostics = (explicitReceiver as? FirResolvedQualifier)?.nonFatalDiagnostics ?: emptyList()
|
||||
var result: MutableList<ConeDiagnostic>? = null
|
||||
|
||||
val deprecation = symbol.getDeprecation(apiVersion)?.forUseSite()
|
||||
val deprecation = symbol.getOwnDeprecation(apiVersion)?.forUseSite()
|
||||
if (deprecation != null) {
|
||||
result = mutableListOf()
|
||||
result.addAll(prevDiagnostics)
|
||||
|
||||
+1
-1
@@ -103,7 +103,7 @@ private fun FirDeclaration.isInvisibleOrHidden(session: FirSession, bodyResolveC
|
||||
}
|
||||
}
|
||||
|
||||
val deprecation = symbol.getDeprecationForCallSite(session.languageVersionSettings.apiVersion)
|
||||
val deprecation = symbol.getDeprecationForCallSite(session)
|
||||
return deprecation != null && deprecation.deprecationLevel == DeprecationLevelValue.HIDDEN
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -103,7 +103,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
|
||||
}
|
||||
|
||||
if (resolveDeprecations) {
|
||||
val deprecation = symbol.getDeprecation(session, useSiteFile)
|
||||
val deprecation = symbol.getOwnDeprecation(session, useSiteFile)
|
||||
if (deprecation != null && deprecation.deprecationLevel == DeprecationLevelValue.HIDDEN) {
|
||||
symbolApplicability = minOf(CandidateApplicability.HIDDEN, symbolApplicability)
|
||||
diagnostic = null
|
||||
|
||||
@@ -29,7 +29,7 @@ sealed class FirClassLikeSymbol<D : FirClassLikeDeclaration>(
|
||||
|
||||
val name get() = classId.shortClassName
|
||||
|
||||
fun getDeprecation(apiVersion: ApiVersion): DeprecationsPerUseSite? {
|
||||
fun getOwnDeprecation(apiVersion: ApiVersion): DeprecationsPerUseSite? {
|
||||
if (annotations.isEmpty()) return null
|
||||
lazyResolveToPhase(FirResolvePhase.COMPILER_REQUIRED_ANNOTATIONS)
|
||||
return fir.deprecationsProvider.getDeprecationsInfo(apiVersion)
|
||||
|
||||
@@ -33,7 +33,7 @@ fun foo7(x: <!DEPRECATION!>kotlin.native.Throws<!>) {}
|
||||
// FILE: main2.kt
|
||||
package abc2
|
||||
|
||||
import kotlin.native.Throws
|
||||
import <!DEPRECATION!>kotlin.native.Throws<!>
|
||||
|
||||
@<!DEPRECATION!>Throws<!>(Throwable::class)
|
||||
fun foo1() {}
|
||||
@@ -70,7 +70,7 @@ fun foo7(x: <!DEPRECATION!>kotlin.native.Throws<!>) {}
|
||||
package abc4
|
||||
|
||||
import kotlin.<!CONFLICTING_IMPORT!>Throws<!>
|
||||
import kotlin.native.<!CONFLICTING_IMPORT!>Throws<!>
|
||||
import <!DEPRECATION!>kotlin.native.<!CONFLICTING_IMPORT!>Throws<!><!>
|
||||
|
||||
@<!OVERLOAD_RESOLUTION_AMBIGUITY!>Throws<!>(Throwable::class)
|
||||
fun foo1() {}
|
||||
@@ -144,7 +144,7 @@ fun foo7(x: <!DEPRECATION!>kotlin.native.Throws<!>) {}
|
||||
package abc8
|
||||
|
||||
import kotlin.*
|
||||
import kotlin.native.Throws
|
||||
import <!DEPRECATION!>kotlin.native.Throws<!>
|
||||
|
||||
@<!DEPRECATION!>Throws<!>(Throwable::class)
|
||||
fun foo1() {}
|
||||
|
||||
Vendored
-18
@@ -1,18 +0,0 @@
|
||||
// !API_VERSION: 1.0
|
||||
|
||||
// FILE: a.kt
|
||||
package a
|
||||
|
||||
@SinceKotlin("1.1")
|
||||
class Since_1_1
|
||||
|
||||
typealias Since_1_1_Alias = <!API_NOT_AVAILABLE!>Since_1_1<!>
|
||||
|
||||
@SinceKotlin("1.1")
|
||||
typealias Alias_1_1 = String
|
||||
|
||||
// FILE: b.kt
|
||||
package b
|
||||
|
||||
import a.<!API_NOT_AVAILABLE!>Since_1_1_Alias<!>
|
||||
import a.Alias_1_1
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !API_VERSION: 1.0
|
||||
|
||||
// FILE: a.kt
|
||||
|
||||
Reference in New Issue
Block a user