[FIR] move deprecation calculation to COMPILER_REQUIRED_ANNOTATIONS phase

Also, this change adds SinceKotlin and Java.Deprecated to this phase
It fixes some problems with API_NOT_AVAILABLE, so now it is closer to K1

^KT-57648 Fixed
^KT-55723 Fixed
This commit is contained in:
Dmitrii Gridin
2023-05-10 16:26:25 +02:00
committed by Space Team
parent add47aa041
commit 9a267176f5
23 changed files with 171 additions and 122 deletions
@@ -45,7 +45,6 @@ internal class KtFirSymbolInfoProvider(
return when (val firSymbol = symbol.firSymbol) { return when (val firSymbol = symbol.firSymbol) {
is FirPropertySymbol -> { is FirPropertySymbol -> {
firSymbol.getDeprecationForCallSite(apiVersion, AnnotationUseSiteTarget.PROPERTY) firSymbol.getDeprecationForCallSite(apiVersion, AnnotationUseSiteTarget.PROPERTY)
?: firSymbol.backingFieldSymbol?.getDeprecationForCallSite(apiVersion, AnnotationUseSiteTarget.FIELD)
} }
is FirBackingFieldSymbol -> { is FirBackingFieldSymbol -> {
firSymbol.getDeprecationForCallSite(apiVersion, AnnotationUseSiteTarget.FIELD) firSymbol.getDeprecationForCallSite(apiVersion, AnnotationUseSiteTarget.FIELD)
@@ -77,13 +76,21 @@ internal class KtFirSymbolInfoProvider(
override fun getGetterDeprecation(symbol: KtPropertySymbol): DeprecationInfo? { override fun getGetterDeprecation(symbol: KtPropertySymbol): DeprecationInfo? {
require(symbol is KtFirSymbol<*>) require(symbol is KtFirSymbol<*>)
return symbol.firSymbol.getDeprecationForCallSite(apiVersion, AnnotationUseSiteTarget.PROPERTY_GETTER, AnnotationUseSiteTarget.PROPERTY) return symbol.firSymbol.getDeprecationForCallSite(
apiVersion,
AnnotationUseSiteTarget.PROPERTY_GETTER,
AnnotationUseSiteTarget.PROPERTY,
)
} }
override fun getSetterDeprecation(symbol: KtPropertySymbol): DeprecationInfo? { override fun getSetterDeprecation(symbol: KtPropertySymbol): DeprecationInfo? {
require(symbol is KtFirSymbol<*>) require(symbol is KtFirSymbol<*>)
return symbol.firSymbol.getDeprecationForCallSite(apiVersion, AnnotationUseSiteTarget.PROPERTY_SETTER, AnnotationUseSiteTarget.PROPERTY) return symbol.firSymbol.getDeprecationForCallSite(
apiVersion,
AnnotationUseSiteTarget.PROPERTY_SETTER,
AnnotationUseSiteTarget.PROPERTY,
)
} }
override fun getJavaGetterName(symbol: KtPropertySymbol): Name { override fun getJavaGetterName(symbol: KtPropertySymbol): Name {
@@ -837,7 +837,7 @@ KtKotlinPropertySymbol:
symbolKind: LOCAL symbolKind: LOCAL
typeParameters: [] typeParameters: []
getContainingModule: KtSourceModule "Sources of main" getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null deprecationStatus: DeprecationInfo(deprecationLevel=WARNING, propagatesToOverrides=false, message=null)
callableIdIfNonLocal: /j3 callableIdIfNonLocal: /j3
contextReceivers: [] contextReceivers: []
getter: KtPropertyGetterSymbol: getter: KtPropertyGetterSymbol:
@@ -262,7 +262,6 @@ private abstract class FirLazyAnnotationTransformer : FirTransformer<FirLazyAnno
} }
private val COMPILER_ANNOTATION_NAMES: Set<Name> = CompilerRequiredAnnotationsHelper.REQUIRED_ANNOTATIONS private val COMPILER_ANNOTATION_NAMES: Set<Name> = CompilerRequiredAnnotationsHelper.REQUIRED_ANNOTATIONS
.plus(SinceKotlin)
.mapTo(mutableSetOf()) { it.shortClassName } .mapTo(mutableSetOf()) { it.shortClassName }
private fun canBeCompilerAnnotation(annotationCall: FirAnnotationCall, session: FirSession): Boolean { private fun canBeCompilerAnnotation(annotationCall: FirAnnotationCall, session: FirSession): Boolean {
@@ -9500,6 +9500,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
runTest("compiler/testData/diagnostics/tests/deprecated/deprecatedConstructor.kt"); runTest("compiler/testData/diagnostics/tests/deprecated/deprecatedConstructor.kt");
} }
@Test
@TestMetadata("deprecatedConstructorProperty.kt")
public void testDeprecatedConstructorProperty() throws Exception {
runTest("compiler/testData/diagnostics/tests/deprecated/deprecatedConstructorProperty.kt");
}
@Test @Test
@TestMetadata("deprecatedEnumEntry.kt") @TestMetadata("deprecatedEnumEntry.kt")
public void testDeprecatedEnumEntry() throws Exception { public void testDeprecatedEnumEntry() throws Exception {
@@ -9500,6 +9500,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
runTest("compiler/testData/diagnostics/tests/deprecated/deprecatedConstructor.kt"); runTest("compiler/testData/diagnostics/tests/deprecated/deprecatedConstructor.kt");
} }
@Test
@TestMetadata("deprecatedConstructorProperty.kt")
public void testDeprecatedConstructorProperty() throws Exception {
runTest("compiler/testData/diagnostics/tests/deprecated/deprecatedConstructorProperty.kt");
}
@Test @Test
@TestMetadata("deprecatedEnumEntry.kt") @TestMetadata("deprecatedEnumEntry.kt")
public void testDeprecatedEnumEntry() throws Exception { public void testDeprecatedEnumEntry() throws Exception {
@@ -9500,6 +9500,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
runTest("compiler/testData/diagnostics/tests/deprecated/deprecatedConstructor.kt"); runTest("compiler/testData/diagnostics/tests/deprecated/deprecatedConstructor.kt");
} }
@Test
@TestMetadata("deprecatedConstructorProperty.kt")
public void testDeprecatedConstructorProperty() throws Exception {
runTest("compiler/testData/diagnostics/tests/deprecated/deprecatedConstructorProperty.kt");
}
@Test @Test
@TestMetadata("deprecatedEnumEntry.kt") @TestMetadata("deprecatedEnumEntry.kt")
public void testDeprecatedEnumEntry() throws Exception { public void testDeprecatedEnumEntry() throws Exception {
@@ -9506,6 +9506,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
runTest("compiler/testData/diagnostics/tests/deprecated/deprecatedConstructor.kt"); runTest("compiler/testData/diagnostics/tests/deprecated/deprecatedConstructor.kt");
} }
@Test
@TestMetadata("deprecatedConstructorProperty.kt")
public void testDeprecatedConstructorProperty() throws Exception {
runTest("compiler/testData/diagnostics/tests/deprecated/deprecatedConstructorProperty.kt");
}
@Test @Test
@TestMetadata("deprecatedEnumEntry.kt") @TestMetadata("deprecatedEnumEntry.kt")
public void testDeprecatedEnumEntry() throws Exception { public void testDeprecatedEnumEntry() throws Exception {
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.SymbolInternals import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
@@ -33,7 +32,6 @@ import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintSystemError import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintSystemError
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
import org.jetbrains.kotlin.resolve.deprecation.DeprecationInfo
import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue
import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled
@@ -105,13 +103,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
} }
if (resolveDeprecations) { if (resolveDeprecations) {
// TODO: drop this condition after KT-57648 val deprecation = symbol.getDeprecation(session, useSiteFile)
val deprecation = if (symbol is FirClassLikeSymbol<*>) {
symbol.getDeprecation(session, useSiteFile)
} else {
null
}
if (deprecation != null && deprecation.deprecationLevel == DeprecationLevelValue.HIDDEN) { if (deprecation != null && deprecation.deprecationLevel == DeprecationLevelValue.HIDDEN) {
symbolApplicability = minOf(CandidateApplicability.HIDDEN, symbolApplicability) symbolApplicability = minOf(CandidateApplicability.HIDDEN, symbolApplicability)
diagnostic = null diagnostic = null
@@ -5,14 +5,12 @@
package org.jetbrains.kotlin.fir.resolve.transformers package org.jetbrains.kotlin.fir.resolve.transformers
import kotlinx.collections.immutable.* import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.toPersistentList
import org.jetbrains.kotlin.KtFakeSourceElementKind import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.* import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.PrivateForInline
import org.jetbrains.kotlin.fir.correspondingProperty
import org.jetbrains.kotlin.fir.copyWithNewSourceKind
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.isFromVararg import org.jetbrains.kotlin.fir.declarations.utils.isFromVararg
import org.jetbrains.kotlin.fir.declarations.utils.isInner import org.jetbrains.kotlin.fir.declarations.utils.isInner
@@ -31,7 +29,6 @@ import org.jetbrains.kotlin.fir.scopes.impl.wrapNestedClassifierScopeWithSubstit
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
import org.jetbrains.kotlin.fir.visitors.transformSingle import org.jetbrains.kotlin.fir.visitors.transformSingle
import org.jetbrains.kotlin.fir.whileAnalysing
import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled
class FirTypeResolveProcessor( class FirTypeResolveProcessor(
@@ -153,7 +150,6 @@ open class FirTypeResolveTransformer(
} }
} }
calculateDeprecations(result)
result result
} }
} }
@@ -169,7 +165,6 @@ open class FirTypeResolveTransformer(
enumEntry.transformReturnTypeRef(this, data) enumEntry.transformReturnTypeRef(this, data)
enumEntry.transformTypeParameters(this, data) enumEntry.transformTypeParameters(this, data)
enumEntry.transformAnnotations(this, data) enumEntry.transformAnnotations(this, data)
calculateDeprecations(enumEntry)
enumEntry enumEntry
} }
@@ -220,7 +215,6 @@ open class FirTypeResolveTransformer(
unboundCyclesInTypeParametersSupertypes(property) unboundCyclesInTypeParametersSupertypes(property)
property.moveOrDeleteIrrelevantAnnotations() property.moveOrDeleteIrrelevantAnnotations()
calculateDeprecations(property)
property property
} }
} }
@@ -234,14 +228,12 @@ open class FirTypeResolveTransformer(
override fun transformField(field: FirField, data: Any?): FirField = whileAnalysing(session, field) { override fun transformField(field: FirField, data: Any?): FirField = whileAnalysing(session, field) {
withScopeCleanup { withScopeCleanup {
field.transformReturnTypeRef(this, data).transformAnnotations(this, data) field.transformReturnTypeRef(this, data).transformAnnotations(this, data)
calculateDeprecations(field)
field field
} }
} }
override fun transformBackingField(backingField: FirBackingField, data: Any?): FirStatement = whileAnalysing(session, backingField) { override fun transformBackingField(backingField: FirBackingField, data: Any?): FirStatement = whileAnalysing(session, backingField) {
backingField.transformAnnotations(this, data) backingField.transformAnnotations(this, data)
calculateDeprecations(backingField)
super.transformBackingField(backingField, data) super.transformBackingField(backingField, data)
} }
@@ -254,7 +246,6 @@ open class FirTypeResolveTransformer(
addTypeParametersScope(simpleFunction) addTypeParametersScope(simpleFunction)
transformDeclaration(simpleFunction, data).also { transformDeclaration(simpleFunction, data).also {
unboundCyclesInTypeParametersSupertypes(it as FirTypeParametersOwner) unboundCyclesInTypeParametersSupertypes(it as FirTypeParametersOwner)
calculateDeprecations(simpleFunction)
} }
} }
} as FirSimpleFunction } as FirSimpleFunction
@@ -319,7 +310,6 @@ open class FirTypeResolveTransformer(
valueParameter.transformReturnTypeRef(this, data) valueParameter.transformReturnTypeRef(this, data)
valueParameter.transformAnnotations(this, data) valueParameter.transformAnnotations(this, data)
valueParameter.transformVarargTypeToArrayType() valueParameter.transformVarargTypeToArrayType()
calculateDeprecations(valueParameter)
valueParameter valueParameter
} }
} }
@@ -522,11 +512,4 @@ open class FirTypeResolveTransformer(
private fun annotationShouldBeMovedToField(allowedTargets: Set<AnnotationUseSiteTarget>): Boolean = private fun annotationShouldBeMovedToField(allowedTargets: Set<AnnotationUseSiteTarget>): Boolean =
(FIELD in allowedTargets || PROPERTY_DELEGATE_FIELD in allowedTargets) && PROPERTY !in allowedTargets (FIELD in allowedTargets || PROPERTY_DELEGATE_FIELD in allowedTargets) && PROPERTY !in allowedTargets
private fun calculateDeprecations(callableDeclaration: FirCallableDeclaration) {
if (callableDeclaration.deprecationsProvider is UnresolvedDeprecationProvider) {
callableDeclaration.replaceDeprecationsProvider(callableDeclaration.getDeprecationsProvider(session))
}
}
} }
@@ -32,7 +32,10 @@ import org.jetbrains.kotlin.fir.scopes.impl.FirAbstractImportingScope
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirEnumEntrySymbol import org.jetbrains.kotlin.fir.symbols.impl.FirEnumEntrySymbol
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.builder.* import org.jetbrains.kotlin.fir.types.builder.buildPlaceholderProjection
import org.jetbrains.kotlin.fir.types.builder.buildStarProjection
import org.jetbrains.kotlin.fir.types.builder.buildTypeProjectionWithVariance
import org.jetbrains.kotlin.fir.types.builder.buildUserTypeRef
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.fir.types.impl.FirImplicitUnitTypeRef import org.jetbrains.kotlin.fir.types.impl.FirImplicitUnitTypeRef
import org.jetbrains.kotlin.fir.types.impl.FirQualifierPartImpl import org.jetbrains.kotlin.fir.types.impl.FirQualifierPartImpl
@@ -41,12 +44,13 @@ import org.jetbrains.kotlin.fir.visitors.FirDefaultTransformer
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.Deprecated import org.jetbrains.kotlin.name.StandardClassIds.Annotations.Deprecated
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.DeprecatedSinceKotlin import org.jetbrains.kotlin.name.StandardClassIds.Annotations.DeprecatedSinceKotlin
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.Java
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.JvmRecord import org.jetbrains.kotlin.name.StandardClassIds.Annotations.JvmRecord
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.WasExperimental import org.jetbrains.kotlin.name.StandardClassIds.Annotations.SinceKotlin
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.Target import org.jetbrains.kotlin.name.StandardClassIds.Annotations.Target
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.WasExperimental
import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled
/** /**
@@ -56,11 +60,13 @@ object CompilerRequiredAnnotationsHelper {
internal val REQUIRED_ANNOTATIONS_WITH_ARGUMENTS: Set<ClassId> = setOf( internal val REQUIRED_ANNOTATIONS_WITH_ARGUMENTS: Set<ClassId> = setOf(
Deprecated, Deprecated,
Target, Target,
StandardClassIds.Annotations.Java.Target, Java.Target,
) )
val REQUIRED_ANNOTATIONS: Set<ClassId> = REQUIRED_ANNOTATIONS_WITH_ARGUMENTS + setOf( val REQUIRED_ANNOTATIONS: Set<ClassId> = REQUIRED_ANNOTATIONS_WITH_ARGUMENTS + setOf(
Java.Deprecated,
DeprecatedSinceKotlin, DeprecatedSinceKotlin,
SinceKotlin,
WasExperimental, WasExperimental,
JvmRecord, JvmRecord,
) )
@@ -361,12 +367,27 @@ abstract class AbstractFirSpecificAnnotationResolveTransformer(
fun calculateDeprecations(classLikeDeclaration: FirClassLikeDeclaration) { fun calculateDeprecations(classLikeDeclaration: FirClassLikeDeclaration) {
if (classLikeDeclaration.deprecationsProvider == UnresolvedDeprecationProvider) { if (classLikeDeclaration.deprecationsProvider == UnresolvedDeprecationProvider) {
classLikeDeclaration.replaceDeprecationsProvider( classLikeDeclaration.replaceDeprecationsProvider(classLikeDeclaration.getDeprecationsProvider(session))
classLikeDeclaration.getDeprecationsProvider(session)
)
} }
} }
private fun calculateDeprecations(callableDeclaration: FirCallableDeclaration) {
if (callableDeclaration.deprecationsProvider == UnresolvedDeprecationProvider) {
callableDeclaration.replaceDeprecationsProvider(callableDeclaration.getDeprecationsProvider(session))
}
}
private fun <T> transformCallableDeclarationForDeprecations(
callableDeclaration: T,
data: Nothing?,
): FirStatement where T : FirCallableDeclaration, T : FirStatement {
if (!shouldTransformDeclaration(callableDeclaration)) return callableDeclaration
computationSession.recordThatAnnotationsAreResolved(callableDeclaration)
return transformDeclaration(callableDeclaration, data).also {
calculateDeprecations(callableDeclaration)
} as FirStatement
}
lateinit var scopes: List<FirScope> lateinit var scopes: List<FirScope>
inline fun <T> withFileScopes(file: FirFile, f: () -> T): T { inline fun <T> withFileScopes(file: FirFile, f: () -> T): T {
@@ -376,10 +397,43 @@ abstract class AbstractFirSpecificAnnotationResolveTransformer(
abstract fun shouldTransformDeclaration(declaration: FirDeclaration): Boolean abstract fun shouldTransformDeclaration(declaration: FirDeclaration): Boolean
override fun transformProperty(property: FirProperty, data: Nothing?): FirProperty { override fun transformBackingField(backingField: FirBackingField, data: Nothing?): FirStatement {
return transformCallableDeclarationForDeprecations(backingField, data)
}
override fun transformPropertyAccessor(propertyAccessor: FirPropertyAccessor, data: Nothing?): FirStatement {
return transformCallableDeclarationForDeprecations(propertyAccessor, data)
}
override fun transformProperty(property: FirProperty, data: Nothing?): FirStatement {
if (!shouldTransformDeclaration(property)) return property if (!shouldTransformDeclaration(property)) return property
computationSession.recordThatAnnotationsAreResolved(property) computationSession.recordThatAnnotationsAreResolved(property)
return transformDeclaration(property, data) as FirProperty return transformDeclaration(property, data).also {
property.moveJavaDeprecatedAnnotationToBackingField()
transformChildren(property) {
property.transformSetter(this, data)
property.transformGetter(this, data)
property.transformBackingField(this, data)
}
calculateDeprecations(property)
} as FirStatement
}
private fun FirProperty.moveJavaDeprecatedAnnotationToBackingField() {
val annotations = this.annotations
val backingField = this.backingField
if (annotations.isNotEmpty() && backingField != null) {
val (backingFieldAnnotations, propertyAnnotations) = annotations.partition {
it.toAnnotationClassIdSafe(session) == Java.Deprecated
}
if (backingFieldAnnotations.isNotEmpty()) {
this.replaceAnnotations(propertyAnnotations)
backingField.replaceAnnotations(backingField.annotations + backingFieldAnnotations)
}
}
} }
override fun transformSimpleFunction( override fun transformSimpleFunction(
@@ -392,6 +446,8 @@ abstract class AbstractFirSpecificAnnotationResolveTransformer(
transformChildren(simpleFunction) { transformChildren(simpleFunction) {
simpleFunction.transformValueParameters(this, data) simpleFunction.transformValueParameters(this, data)
} }
calculateDeprecations(simpleFunction)
} as FirSimpleFunction } as FirSimpleFunction
} }
@@ -405,16 +461,21 @@ abstract class AbstractFirSpecificAnnotationResolveTransformer(
transformChildren(constructor) { transformChildren(constructor) {
constructor.transformValueParameters(this, data) constructor.transformValueParameters(this, data)
} }
calculateDeprecations(constructor)
} as FirConstructor } as FirConstructor
} }
override fun transformValueParameter( override fun transformEnumEntry(enumEntry: FirEnumEntry, data: Nothing?): FirStatement {
valueParameter: FirValueParameter, return transformCallableDeclarationForDeprecations(enumEntry, data)
data: Nothing? }
): FirStatement {
if (!shouldTransformDeclaration(valueParameter)) return valueParameter override fun transformField(field: FirField, data: Nothing?): FirStatement {
computationSession.recordThatAnnotationsAreResolved(valueParameter) return transformCallableDeclarationForDeprecations(field, data)
return transformDeclaration(valueParameter, data) as FirStatement }
override fun transformValueParameter(valueParameter: FirValueParameter, data: Nothing?): FirStatement {
return transformCallableDeclarationForDeprecations(valueParameter, data)
} }
override fun transformTypeRef(typeRef: FirTypeRef, data: Nothing?): FirTypeRef { override fun transformTypeRef(typeRef: FirTypeRef, data: Nothing?): FirTypeRef {
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. * Copyright 2010-2023 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. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@@ -67,18 +67,10 @@ abstract class FirCallableSymbol<D : FirCallableDeclaration> : FirBasedSymbol<D>
get() = callableId.callableName get() = callableId.callableName
fun getDeprecation(apiVersion: ApiVersion): DeprecationsPerUseSite? { fun getDeprecation(apiVersion: ApiVersion): DeprecationsPerUseSite? {
if (!canBeDeprecated()) return null lazyResolveToPhase(FirResolvePhase.COMPILER_REQUIRED_ANNOTATIONS)
lazyResolveToPhase(FirResolvePhase.TYPES)
return fir.deprecationsProvider.getDeprecationsInfo(apiVersion) return fir.deprecationsProvider.getDeprecationsInfo(apiVersion)
} }
/**
* Checks if symbol can be deprecated by syntax
* @return `true` if symbol might have some deprecation status, or `false` if it's definitely not deprecated
*/
internal open fun canBeDeprecated(): Boolean = true
private fun ensureType(typeRef: FirTypeRef?) { private fun ensureType(typeRef: FirTypeRef?) {
when (typeRef) { when (typeRef) {
null, is FirResolvedTypeRef -> {} null, is FirResolvedTypeRef -> {}
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. * Copyright 2010-2023 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. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.fir.symbols.impl
import org.jetbrains.kotlin.fir.FirLabel import org.jetbrains.kotlin.fir.FirLabel
import org.jetbrains.kotlin.fir.contracts.FirResolvedContractDescription import org.jetbrains.kotlin.fir.contracts.FirResolvedContractDescription
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference
import org.jetbrains.kotlin.fir.references.toResolvedConstructorSymbol import org.jetbrains.kotlin.fir.references.toResolvedConstructorSymbol
@@ -42,12 +41,7 @@ sealed class FirFunctionSymbol<D : FirFunction>(
open class FirNamedFunctionSymbol( open class FirNamedFunctionSymbol(
callableId: CallableId, callableId: CallableId,
) : FirFunctionSymbol<FirSimpleFunction>(callableId) { ) : FirFunctionSymbol<FirSimpleFunction>(callableId)
override fun canBeDeprecated(): Boolean {
if (isLocal || callableId.className == null) return annotations.isNotEmpty()
return true
}
}
interface FirIntersectionCallableSymbol { interface FirIntersectionCallableSymbol {
val intersections: Collection<FirCallableSymbol<*>> val intersections: Collection<FirCallableSymbol<*>>
@@ -81,10 +75,6 @@ class FirConstructorSymbol(
val delegatedConstructorCallIsSuper: Boolean val delegatedConstructorCallIsSuper: Boolean
get() = fir.delegatedConstructor?.isSuper ?: false get() = fir.delegatedConstructor?.isSuper ?: false
override fun canBeDeprecated(): Boolean {
return annotations.isNotEmpty()
}
} }
/** /**
@@ -109,20 +99,12 @@ sealed class FirFunctionWithoutNameSymbol<F : FirFunction>(
class FirAnonymousFunctionSymbol : FirFunctionWithoutNameSymbol<FirAnonymousFunction>(Name.identifier("anonymous")) { class FirAnonymousFunctionSymbol : FirFunctionWithoutNameSymbol<FirAnonymousFunction>(Name.identifier("anonymous")) {
val label: FirLabel? get() = fir.label val label: FirLabel? get() = fir.label
override fun canBeDeprecated(): Boolean {
return annotations.isNotEmpty()
}
} }
class FirPropertyAccessorSymbol : FirFunctionWithoutNameSymbol<FirPropertyAccessor>(Name.identifier("accessor")) { class FirPropertyAccessorSymbol : FirFunctionWithoutNameSymbol<FirPropertyAccessor>(Name.identifier("accessor")) {
val isGetter: Boolean get() = fir.isGetter val isGetter: Boolean get() = fir.isGetter
val isSetter: Boolean get() = fir.isSetter val isSetter: Boolean get() = fir.isSetter
val propertySymbol get() = fir.propertySymbol val propertySymbol get() = fir.propertySymbol
override fun canBeDeprecated(): Boolean {
return propertySymbol.canBeDeprecated()
}
} }
class FirErrorFunctionSymbol : FirFunctionWithoutNameSymbol<FirErrorFunction>(Name.identifier("error")) class FirErrorFunctionSymbol : FirFunctionWithoutNameSymbol<FirErrorFunction>(Name.identifier("error"))
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. * Copyright 2010-2023 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. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@@ -64,15 +64,6 @@ open class FirPropertySymbol(
val isVar: Boolean val isVar: Boolean
get() = fir.isVar get() = fir.isVar
override fun canBeDeprecated(): Boolean {
if (isLocal || callableId.className == null) {
return annotations.isNotEmpty()
|| getterSymbol?.annotations?.isNotEmpty() == true
|| setterSymbol?.annotations?.isNotEmpty() == true
}
return true
}
} }
class FirIntersectionOverridePropertySymbol( class FirIntersectionOverridePropertySymbol(
@@ -132,10 +123,6 @@ class FirValueParameterSymbol(name: Name) : FirVariableSymbol<FirValueParameter>
val containingFunctionSymbol: FirFunctionSymbol<*> val containingFunctionSymbol: FirFunctionSymbol<*>
get() = fir.containingFunctionSymbol get() = fir.containingFunctionSymbol
override fun canBeDeprecated(): Boolean {
return false
}
} }
class FirErrorPropertySymbol( class FirErrorPropertySymbol(
@@ -0,0 +1,16 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNUSED_PARAMETER
// FILE: A.kt
class A(@Deprecated("") val s: String) {
constructor(i: Int) : this(i.toString()) {
}
}
// FILE: use.kt
fun use() {
A("").<!DEPRECATION!>s<!>
A(42).<!DEPRECATION!>s<!>
}
@@ -23,16 +23,16 @@ class A {
import p1.* import p1.*
import p2.* import p2.*
fun test(a: <!OVERLOAD_RESOLUTION_AMBIGUITY!>A<!>) { <!CONFLICTING_OVERLOADS!>fun test(a: A)<!> {
a.<!UNRESOLVED_REFERENCE!>m1<!>() a.<!UNRESOLVED_REFERENCE!>m1<!>()
a.<!UNRESOLVED_REFERENCE!>m2<!>() a.m2()
} }
// FILE: explicitlyImportP1.kt // FILE: explicitlyImportP1.kt
import p1.A import p1.<!API_NOT_AVAILABLE!>A<!>
import p2.* import p2.*
fun test(a: A) { <!CONFLICTING_OVERLOADS!>fun test(a: A)<!> {
a.m1() a.<!UNRESOLVED_REFERENCE!>m1<!>()
a.<!UNRESOLVED_REFERENCE!>m2<!>() a.m2()
} }
@@ -26,12 +26,12 @@ class A(val v3: Unit)
// MODULE: m4(m1, m2, m3) // MODULE: m4(m1, m2, m3)
// FILE: oneExplicitImportOtherStars.kt // FILE: oneExplicitImportOtherStars.kt
import p1.* import p1.*
import p2.A import p2.<!API_NOT_AVAILABLE!>A<!>
import p3.* import p3.*
fun test(a: A) { fun test(a: <!NONE_APPLICABLE!>A<!>) {
a.<!UNRESOLVED_REFERENCE!>v1<!> a.<!UNRESOLVED_REFERENCE!>v1<!>
a.v2 a.<!UNRESOLVED_REFERENCE!>v2<!>
a.<!UNRESOLVED_REFERENCE!>v3<!> a.<!UNRESOLVED_REFERENCE!>v3<!>
} }
@@ -40,7 +40,7 @@ import p1.*
import p2.* import p2.*
import p3.* import p3.*
fun test(a: <!OVERLOAD_RESOLUTION_AMBIGUITY!>A<!>) { fun test(a: <!NONE_APPLICABLE!>A<!>) {
a.<!UNRESOLVED_REFERENCE!>v1<!> a.<!UNRESOLVED_REFERENCE!>v1<!>
a.<!UNRESOLVED_REFERENCE!>v2<!> a.<!UNRESOLVED_REFERENCE!>v2<!>
a.<!UNRESOLVED_REFERENCE!>v3<!> a.<!UNRESOLVED_REFERENCE!>v3<!>
@@ -6,6 +6,6 @@ annotation class Anno1(val s: String)
annotation class Anno2 @SinceKotlin("1.1") constructor() annotation class Anno2 @SinceKotlin("1.1") constructor()
@Anno1("") @<!API_NOT_AVAILABLE!>Anno1<!>("")
@<!UNRESOLVED_REFERENCE!>Anno2<!> @<!UNRESOLVED_REFERENCE!>Anno2<!>
fun t1() {} fun t1() {}
@@ -11,13 +11,13 @@ class Baz @SinceKotlin("1.1") constructor()
@SinceKotlin("1.1") @SinceKotlin("1.1")
class Quux @SinceKotlin("1.0") constructor() class Quux @SinceKotlin("1.0") constructor()
fun t1(): Foo = Foo() fun t1(): <!API_NOT_AVAILABLE!>Foo<!> = <!API_NOT_AVAILABLE!>Foo<!>()
// TODO: do not report API_NOT_AVAILABLE twice // TODO: do not report API_NOT_AVAILABLE twice
fun t2() = object : Foo() {} fun t2() = object : <!API_NOT_AVAILABLE!>Foo<!>() {}
fun t3(): Bar? = <!UNRESOLVED_REFERENCE!>Bar<!>() fun t3(): Bar? = <!UNRESOLVED_REFERENCE!>Bar<!>()
fun t4(): Baz = <!UNRESOLVED_REFERENCE!>Baz<!>() fun t4(): Baz = <!UNRESOLVED_REFERENCE!>Baz<!>()
fun t5(): Quux = Quux() fun t5(): <!API_NOT_AVAILABLE!>Quux<!> = <!API_NOT_AVAILABLE!>Quux<!>()
@@ -3,7 +3,7 @@
@SinceKotlin("1.1") @SinceKotlin("1.1")
open class C1 open class C1
typealias C1_Alias = C1 typealias C1_Alias = <!API_NOT_AVAILABLE!>C1<!>
open class C2(val x: Int) { open class C2(val x: Int) {
@SinceKotlin("1.1") @SinceKotlin("1.1")
@@ -12,9 +12,9 @@ open class C2(val x: Int) {
typealias C2_Alias = C2 typealias C2_Alias = C2
val test1 = C1_Alias() val test1 = <!API_NOT_AVAILABLE!>C1_Alias<!>()
val test2 = <!NO_VALUE_FOR_PARAMETER!>C2_Alias()<!> val test2 = <!NO_VALUE_FOR_PARAMETER!>C2_Alias()<!>
class Test3 : C1_Alias() class Test3 : <!API_NOT_AVAILABLE!>C1_Alias<!>()
class Test4 : <!NO_VALUE_FOR_PARAMETER!>C2_Alias<!>() class Test4 : <!NO_VALUE_FOR_PARAMETER!>C2_Alias<!>()
@@ -5,7 +5,7 @@ object Since_1_1 {
val x = 42 val x = 42
} }
typealias Since_1_1_Alias = Since_1_1 typealias Since_1_1_Alias = <!API_NOT_AVAILABLE!>Since_1_1<!>
val test1 = Since_1_1_Alias val test1 = Since_1_1_Alias
val test2 = Since_1_1_Alias.x val test2 = Since_1_1_Alias.x
@@ -5,17 +5,17 @@ class Since_1_1
class C class C
typealias Since_1_1_Alias = Since_1_1 typealias Since_1_1_Alias = <!API_NOT_AVAILABLE!>Since_1_1<!>
typealias L = List<Since_1_1> typealias L = List<<!API_NOT_AVAILABLE!>Since_1_1<!>>
@SinceKotlin("1.1") @SinceKotlin("1.1")
typealias C_1_1_Alias = C typealias C_1_1_Alias = C
fun test1(x: Since_1_1_Alias) = x fun test1(x: <!API_NOT_AVAILABLE!>Since_1_1_Alias<!>) = x
fun test2(x: C_1_1_Alias) = x fun test2(x: <!API_NOT_AVAILABLE!>C_1_1_Alias<!>) = x
fun test3(x: List<C_1_1_Alias>) = x fun test3(x: List<<!API_NOT_AVAILABLE!>C_1_1_Alias<!>>) = x
fun test4(x: L) = x fun test4(x: <!API_NOT_AVAILABLE!>L<!>) = x
@@ -6,7 +6,7 @@ package a
@SinceKotlin("1.1") @SinceKotlin("1.1")
class Since_1_1 class Since_1_1
typealias Since_1_1_Alias = Since_1_1 typealias Since_1_1_Alias = <!API_NOT_AVAILABLE!>Since_1_1<!>
@SinceKotlin("1.1") @SinceKotlin("1.1")
typealias Alias_1_1 = String typealias Alias_1_1 = String
@@ -14,5 +14,5 @@ typealias Alias_1_1 = String
// FILE: b.kt // FILE: b.kt
package b package b
import a.Since_1_1_Alias import a.<!API_NOT_AVAILABLE!>Since_1_1_Alias<!>
import a.Alias_1_1 import a.Alias_1_1
@@ -9506,6 +9506,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/deprecated/deprecatedConstructor.kt"); runTest("compiler/testData/diagnostics/tests/deprecated/deprecatedConstructor.kt");
} }
@Test
@TestMetadata("deprecatedConstructorProperty.kt")
public void testDeprecatedConstructorProperty() throws Exception {
runTest("compiler/testData/diagnostics/tests/deprecated/deprecatedConstructorProperty.kt");
}
@Test @Test
@TestMetadata("deprecatedEnumEntry.kt") @TestMetadata("deprecatedEnumEntry.kt")
public void testDeprecatedEnumEntry() throws Exception { public void testDeprecatedEnumEntry() throws Exception {