diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java index 35e828a9f55..3d65515ed24 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java @@ -33,7 +33,6 @@ import org.jetbrains.kotlin.codegen.serialization.JvmStringTable; import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper; import org.jetbrains.kotlin.config.JvmTarget; -import org.jetbrains.kotlin.config.LanguageFeature; import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.lexer.KtTokens; @@ -43,7 +42,6 @@ import org.jetbrains.kotlin.name.ClassId; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.protobuf.MessageLite; import org.jetbrains.kotlin.renderer.DescriptorRenderer; -import org.jetbrains.kotlin.resolve.DeprecationUtilKt; import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt; import org.jetbrains.kotlin.resolve.inline.InlineUtil; @@ -204,7 +202,7 @@ public class AsmUtil { } public static int getMethodAsmFlags(FunctionDescriptor functionDescriptor, OwnerKind kind, GenerationState state) { - int flags = getCommonCallableFlags(functionDescriptor); + int flags = getCommonCallableFlags(functionDescriptor, state); for (AnnotationCodegen.JvmFlagAnnotation flagAnnotation : AnnotationCodegen.METHOD_FLAGS) { if (flagAnnotation.hasAnnotation(functionDescriptor.getOriginal())) { @@ -245,17 +243,11 @@ public class AsmUtil { return flags; } - public static int getCommonCallableFlags(FunctionDescriptor functionDescriptor) { + public static int getCommonCallableFlags(FunctionDescriptor functionDescriptor, @NotNull GenerationState state) { int flags = getVisibilityAccessFlag(functionDescriptor); flags |= getVarargsFlag(functionDescriptor); flags |= getDeprecatedAccessFlag(functionDescriptor); - if (DeprecationUtilKt.isDeprecatedHidden(functionDescriptor, LanguageVersionSettingsImpl.DEFAULT) - || functionDescriptor instanceof PropertyAccessorDescriptor - && DeprecationUtilKt.isDeprecatedHidden( - ((PropertyAccessorDescriptor) functionDescriptor).getCorrespondingProperty(), - LanguageVersionSettingsImpl.DEFAULT - ) - ) { + if (state.getDeprecationProvider().isDeprecatedHidden(functionDescriptor)) { flags |= ACC_SYNTHETIC; } return flags; diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/DefaultParameterValueSubstitutor.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/DefaultParameterValueSubstitutor.kt index 564c468f69c..1de47c6265f 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/DefaultParameterValueSubstitutor.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/DefaultParameterValueSubstitutor.kt @@ -26,7 +26,6 @@ import org.jetbrains.kotlin.psi.KtPureElement import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue import org.jetbrains.kotlin.resolve.jvm.AsmTypes import org.jetbrains.kotlin.resolve.jvm.annotations.findJvmOverloadsAnnotation -import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOriginFromPure import org.jetbrains.org.objectweb.asm.Label import org.jetbrains.org.objectweb.asm.Opcodes @@ -129,7 +128,7 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) { ) { val typeMapper = state.typeMapper val isStatic = AsmUtil.isStaticMethod(contextKind, functionDescriptor) - val baseMethodFlags = AsmUtil.getCommonCallableFlags(functionDescriptor) and Opcodes.ACC_VARARGS.inv() + val baseMethodFlags = AsmUtil.getCommonCallableFlags(functionDescriptor, state) and Opcodes.ACC_VARARGS.inv() val remainingParameters = getRemainingParameters(functionDescriptor.original, substituteCount) val flags = baseMethodFlags or diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt index 95b31d648f1..05a3857c684 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt @@ -45,6 +45,7 @@ import org.jetbrains.kotlin.resolve.jvm.JvmClassName import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind.* import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration +import org.jetbrains.kotlin.storage.LockBasedStorageManager import java.io.File class GenerationState @JvmOverloads constructor( @@ -95,6 +96,8 @@ class GenerationState @JvmOverloads constructor( val deserializationConfiguration: DeserializationConfiguration = CompilerDeserializationConfiguration(configuration.languageVersionSettings) + val deprecationProvider = DeprecationResolver(LockBasedStorageManager.NO_LOCKS, configuration.languageVersionSettings) + init { val icComponents = configuration.get(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS) if (icComponents != null) { diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/JvmModuleAccessibilityChecker.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/JvmModuleAccessibilityChecker.kt index b8279d76d15..3cfbba64a15 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/JvmModuleAccessibilityChecker.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/JvmModuleAccessibilityChecker.kt @@ -28,6 +28,7 @@ import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryPackageSourceElement import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement import org.jetbrains.kotlin.load.kotlin.VirtualFileKotlinClass import org.jetbrains.kotlin.resolve.BindingTrace +import org.jetbrains.kotlin.resolve.DeprecationResolver import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker @@ -102,7 +103,8 @@ class JvmModuleAccessibilityChecker(project: Project) : CallChecker { targetDescriptor: ClassifierDescriptor, trace: BindingTrace, element: PsiElement, - languageVersionSettings: LanguageVersionSettings + languageVersionSettings: LanguageVersionSettings, + deprecationResolver: DeprecationResolver ) { val virtualFile = element.containingFile.virtualFile when (targetDescriptor) { diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/JavaSyntheticScopes.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/JavaSyntheticScopes.kt index 4baf193cd43..c0ac565d8aa 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/JavaSyntheticScopes.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/JavaSyntheticScopes.kt @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.synthetic import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.load.java.components.SamConversionResolver +import org.jetbrains.kotlin.resolve.DeprecationResolver import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes import org.jetbrains.kotlin.storage.StorageManager @@ -26,10 +27,11 @@ class JavaSyntheticScopes( storageManager: StorageManager, lookupTracker: LookupTracker, languageVersionSettings: LanguageVersionSettings, - samConventionResolver: SamConversionResolver + samConventionResolver: SamConversionResolver, + deprecationResolver: DeprecationResolver ): SyntheticScopes { override val scopes = listOf( JavaSyntheticPropertiesScope(storageManager, lookupTracker), - SamAdapterFunctionsScope(storageManager, languageVersionSettings, samConventionResolver) + SamAdapterFunctionsScope(storageManager, languageVersionSettings, samConventionResolver, deprecationResolver) ) } diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SamAdapterFunctionsScope.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SamAdapterFunctionsScope.kt index ddb01337536..3729ba7b7cc 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SamAdapterFunctionsScope.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SamAdapterFunctionsScope.kt @@ -34,8 +34,8 @@ import org.jetbrains.kotlin.load.java.sam.SamAdapterDescriptor import org.jetbrains.kotlin.load.java.sam.SamConstructorDescriptor import org.jetbrains.kotlin.load.java.sam.SingleAbstractMethodUtils import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.DeprecationResolver import org.jetbrains.kotlin.resolve.calls.inference.wrapWithCapturingSubstitution -import org.jetbrains.kotlin.resolve.isHiddenInResolution import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.ResolutionScope import org.jetbrains.kotlin.resolve.scopes.SyntheticScope @@ -51,7 +51,8 @@ interface SamAdapterExtensionFunctionDescriptor : FunctionDescriptor, SyntheticM class SamAdapterFunctionsScope( storageManager: StorageManager, private val languageVersionSettings: LanguageVersionSettings, - private val samResolver: SamConversionResolver + private val samResolver: SamConversionResolver, + private val deprecationResolver: DeprecationResolver ) : SyntheticScope { private val extensionForFunction = storageManager.createMemoizedFunctionWithNullableValues { function -> extensionForFunctionNotCached(function) @@ -83,7 +84,7 @@ class SamAdapterFunctionsScope( if (!function.hasJavaOriginInHierarchy()) return null //TODO: should we go into base at all? if (!SingleAbstractMethodUtils.isSamAdapterNecessary(function)) return null if (function.returnType == null) return null - if (function.isHiddenInResolution(languageVersionSettings)) return null + if (deprecationResolver.isHiddenInResolution(function)) return null return MyFunctionDescriptor.create(function, samResolver) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/LazyTopDownAnalyzer.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/LazyTopDownAnalyzer.kt index 5453579f8b5..aa37df4b3a4 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/LazyTopDownAnalyzer.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/LazyTopDownAnalyzer.kt @@ -48,6 +48,7 @@ class LazyTopDownAnalyzer( private val qualifiedExpressionResolver: QualifiedExpressionResolver, private val identifierChecker: IdentifierChecker, private val languageVersionSettings: LanguageVersionSettings, + private val deprecationResolver: DeprecationResolver, private val classifierUsageCheckers: Iterable ) { fun analyzeDeclarations( @@ -215,7 +216,7 @@ class LazyTopDownAnalyzer( resolveImportsInAllFiles(c) - ClassifierUsageChecker.check(declarations, trace, languageVersionSettings, classifierUsageCheckers) + ClassifierUsageChecker.check(declarations, trace, languageVersionSettings, deprecationResolver, classifierUsageCheckers) return c } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallCompleter.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallCompleter.kt index 7f95a98921b..bca8fd9d655 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallCompleter.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallCompleter.kt @@ -60,7 +60,8 @@ class CallCompleter( private val dataFlowAnalyzer: DataFlowAnalyzer, private val callCheckers: Iterable, private val builtIns: KotlinBuiltIns, - private val languageVersionSettings: LanguageVersionSettings + private val languageVersionSettings: LanguageVersionSettings, + private val deprecationResolver: DeprecationResolver ) { fun completeCall( context: BasicCallResolutionContext, @@ -91,7 +92,7 @@ class CallCompleter( if (calleeExpression != null && !calleeExpression.isFakeElement) calleeExpression else resolvedCall.call.callElement - val callCheckerContext = CallCheckerContext(context, languageVersionSettings) + val callCheckerContext = CallCheckerContext(context, languageVersionSettings, deprecationResolver) for (callChecker in callCheckers) { callChecker.check(resolvedCall, reportOn, callCheckerContext) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/CallChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/CallChecker.kt index f36865c5145..076b58d72cc 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/CallChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/CallChecker.kt @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve.calls.checkers import com.intellij.psi.PsiElement import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.resolve.BindingTrace +import org.jetbrains.kotlin.resolve.DeprecationResolver import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo @@ -37,7 +38,8 @@ interface CallChecker { class CallCheckerContext( val resolutionContext: ResolutionContext<*>, val trace: BindingTrace, - val languageVersionSettings: LanguageVersionSettings + val languageVersionSettings: LanguageVersionSettings, + val deprecationResolver: DeprecationResolver ) { val scope: LexicalScope get() = resolutionContext.scope @@ -48,7 +50,11 @@ class CallCheckerContext( val isAnnotationContext: Boolean get() = resolutionContext.isAnnotationContext - constructor(c: ResolutionContext<*>, languageVersionSettings: LanguageVersionSettings) : this(c, c.trace, languageVersionSettings) + constructor( + c: ResolutionContext<*>, + languageVersionSettings: LanguageVersionSettings, + deprecationResolver: DeprecationResolver + ) : this(c, c.trace, languageVersionSettings, deprecationResolver) } // Use this utility to avoid premature computation of deferred return type of a resolved callable descriptor. diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/DeprecatedCallChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/DeprecatedCallChecker.kt index 2fd5adb5055..c2b970aa8d6 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/DeprecatedCallChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/DeprecatedCallChecker.kt @@ -29,27 +29,29 @@ import org.jetbrains.kotlin.psi.KtCallableReferenceExpression import org.jetbrains.kotlin.psi.KtReferenceExpression import org.jetbrains.kotlin.psi.KtUnaryExpression import org.jetbrains.kotlin.resolve.BindingTrace +import org.jetbrains.kotlin.resolve.DeprecationResolver import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject import org.jetbrains.kotlin.resolve.createDeprecationDiagnostic -import org.jetbrains.kotlin.resolve.getDeprecations object DeprecatedCallChecker : CallChecker { override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) { - check(resolvedCall.resultingDescriptor, context.trace, reportOn, context.languageVersionSettings) + check(resolvedCall.resultingDescriptor, context.trace, reportOn, context.languageVersionSettings, context.deprecationResolver) } private fun check( - targetDescriptor: CallableDescriptor, trace: BindingTrace, element: PsiElement, languageVersionSettings: LanguageVersionSettings + targetDescriptor: CallableDescriptor, trace: BindingTrace, element: PsiElement, + languageVersionSettings: LanguageVersionSettings, + deprecationResolver: DeprecationResolver ) { // Objects will be checked by DeprecatedClassifierUsageChecker if (targetDescriptor is FakeCallableDescriptorForObject) return - val deprecations = targetDescriptor.getDeprecations(languageVersionSettings).toMutableList() + val deprecations = deprecationResolver.getDeprecations(targetDescriptor).toMutableList() // avoid duplicating diagnostic when deprecation for property effectively deprecates setter if (targetDescriptor is PropertySetterDescriptor) { - deprecations -= targetDescriptor.correspondingProperty.getDeprecations(languageVersionSettings) + deprecations -= deprecationResolver.getDeprecations(targetDescriptor.correspondingProperty) } if (deprecations.isNotEmpty()) { @@ -58,7 +60,7 @@ object DeprecatedCallChecker : CallChecker { } } else if (targetDescriptor is PropertyDescriptor && shouldCheckPropertyGetter(element)) { - targetDescriptor.getter?.let { check(it, trace, element, languageVersionSettings) } + targetDescriptor.getter?.let { check(it, trace, element, languageVersionSettings, deprecationResolver) } } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinResolutionStatelessCallbacksImpl.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinResolutionStatelessCallbacksImpl.kt index cda4f375e1c..14dea6aafb2 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinResolutionStatelessCallbacksImpl.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinResolutionStatelessCallbacksImpl.kt @@ -16,10 +16,10 @@ package org.jetbrains.kotlin.resolve.calls.tower -import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.psi.KtSuperExpression +import org.jetbrains.kotlin.resolve.DeprecationResolver import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isConventionCall import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isInfixCall @@ -28,11 +28,10 @@ import org.jetbrains.kotlin.resolve.calls.components.KotlinResolutionStatelessCa import org.jetbrains.kotlin.resolve.calls.model.CallableReferenceKotlinCallArgument import org.jetbrains.kotlin.resolve.calls.model.KotlinCall import org.jetbrains.kotlin.resolve.calls.model.SimpleKotlinCallArgument -import org.jetbrains.kotlin.resolve.isHiddenInResolution import org.jetbrains.kotlin.utils.addToStdlib.safeAs class KotlinResolutionStatelessCallbacksImpl( - private val languageVersionSettings: LanguageVersionSettings + private val deprecationResolver: DeprecationResolver ) : KotlinResolutionStatelessCallbacks { override fun isDescriptorFromSource(descriptor: CallableDescriptor) = DescriptorToSourceUtils.descriptorToDeclaration(descriptor) != null @@ -48,7 +47,7 @@ class KotlinResolutionStatelessCallbacksImpl( kotlinCall is PSIKotlinCallImpl && isSuperOrDelegatingConstructorCall(kotlinCall.psiCall) override fun isHiddenInResolution(descriptor: DeclarationDescriptor, kotlinCall: KotlinCall) = - descriptor.isHiddenInResolution(languageVersionSettings, isSuperOrDelegatingConstructorCall(kotlinCall)) + deprecationResolver.isHiddenInResolution(descriptor, isSuperOrDelegatingConstructorCall(kotlinCall)) override fun isSuperExpression(receiver: SimpleKotlinCallArgument?): Boolean = receiver?.psiExpression is KtSuperExpression @@ -58,4 +57,4 @@ class KotlinResolutionStatelessCallbacksImpl( override fun getVariableCandidateIfInvoke(functionCall: KotlinCall) = functionCall.safeAs()?.variableCall -} \ No newline at end of file +} diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt index 8192e1a631f..3f4102ac76f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt @@ -66,10 +66,11 @@ class KotlinToResolvedCallTransformer( private val dataFlowAnalyzer: DataFlowAnalyzer, private val argumentTypeResolver: ArgumentTypeResolver, private val constantExpressionEvaluator: ConstantExpressionEvaluator, + private val deprecationResolver: DeprecationResolver, private val expressionTypingServices: ExpressionTypingServices, private val doubleColonExpressionResolver: DoubleColonExpressionResolver, private val additionalDiagnosticReporter: AdditionalDiagnosticReporter - ) { +) { fun onlyTransform( resolvedCallAtom: ResolvedCallAtom @@ -90,7 +91,7 @@ class KotlinToResolvedCallTransformer( val resultSubstitutor = baseResolvedCall.constraintSystem.buildResultingSubstitutor() val ktPrimitiveCompleter = ResolvedAtomCompleter(resultSubstitutor, context.trace, context, this, expressionTypingServices, argumentTypeResolver, doubleColonExpressionResolver, - languageFeatureSettings) + languageFeatureSettings, deprecationResolver) for (subKtPrimitive in candidate.subResolvedAtoms) { ktPrimitiveCompleter.completeAll(subKtPrimitive) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewResolutionOldInference.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewResolutionOldInference.kt index 108df969cca..70e096bcf32 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewResolutionOldInference.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewResolutionOldInference.kt @@ -28,6 +28,7 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.Call import org.jetbrains.kotlin.psi.KtReferenceExpression import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.DeprecationResolver import org.jetbrains.kotlin.resolve.TemporaryBindingTrace import org.jetbrains.kotlin.resolve.calls.CallTransformer import org.jetbrains.kotlin.resolve.calls.CandidateResolver @@ -37,6 +38,7 @@ import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isInfixCall import org.jetbrains.kotlin.resolve.calls.callUtil.createLookupLocation import org.jetbrains.kotlin.resolve.calls.context.* import org.jetbrains.kotlin.resolve.calls.inference.CoroutineInferenceSupport +import org.jetbrains.kotlin.resolve.calls.model.KotlinCallKind import org.jetbrains.kotlin.resolve.calls.model.* import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResultsImpl import org.jetbrains.kotlin.resolve.calls.results.ResolutionResultsHandler @@ -45,7 +47,6 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory import org.jetbrains.kotlin.resolve.calls.tasks.* import org.jetbrains.kotlin.resolve.descriptorUtil.hasDynamicExtensionAnnotation -import org.jetbrains.kotlin.resolve.isHiddenInResolution import org.jetbrains.kotlin.resolve.scopes.LexicalScope import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes @@ -66,7 +67,8 @@ class NewResolutionOldInference( private val dynamicCallableDescriptors: DynamicCallableDescriptors, private val syntheticScopes: SyntheticScopes, private val languageVersionSettings: LanguageVersionSettings, - private val coroutineInferenceSupport: CoroutineInferenceSupport + private val coroutineInferenceSupport: CoroutineInferenceSupport, + private val deprecationResolver: DeprecationResolver ) { sealed class ResolutionKind(val kotlinCallKind: KotlinCallKind = KotlinCallKind.UNSUPPORTED) { abstract internal fun createTowerProcessor( @@ -200,7 +202,7 @@ class NewResolutionOldInference( val candidateTrace = TemporaryBindingTrace.create(basicCallContext.trace, "Context for resolve candidate") val resolvedCall = ResolvedCallImpl.create(candidate, candidateTrace, tracing, basicCallContext.dataFlowInfoForArguments) - if (candidate.descriptor.isHiddenInResolution(languageVersionSettings, basicCallContext.isSuperCall)) { + if (deprecationResolver.isHiddenInResolution(candidate.descriptor, basicCallContext.isSuperCall)) { return@map MyCandidate(listOf(HiddenDescriptor), resolvedCall) } @@ -357,7 +359,8 @@ class NewResolutionOldInference( } } - if (towerCandidate.descriptor.isHiddenInResolution(languageVersionSettings, basicCallContext.isSuperCall)) { + + if (deprecationResolver.isHiddenInResolution(towerCandidate.descriptor, basicCallContext.isSuperCall)) { return MyCandidate(listOf(HiddenDescriptor), candidateCall) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt index da28ba2831d..03f01ce589d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingTrace +import org.jetbrains.kotlin.resolve.DeprecationResolver import org.jetbrains.kotlin.resolve.TemporaryBindingTrace import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext @@ -37,7 +38,10 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategyImpl import org.jetbrains.kotlin.resolve.calls.util.CallMaker -import org.jetbrains.kotlin.types.* +import org.jetbrains.kotlin.types.IndexedParametersSubstitution +import org.jetbrains.kotlin.types.TypeUtils +import org.jetbrains.kotlin.types.UnwrappedType +import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.expressions.DoubleColonExpressionResolver import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices import org.jetbrains.kotlin.types.typeUtil.asTypeProjection @@ -51,9 +55,10 @@ class ResolvedAtomCompleter( private val expressionTypingServices: ExpressionTypingServices, private val argumentTypeResolver: ArgumentTypeResolver, private val doubleColonExpressionResolver: DoubleColonExpressionResolver, - languageVersionSettings: LanguageVersionSettings + languageVersionSettings: LanguageVersionSettings, + deprecationResolver: DeprecationResolver ) { - private val callCheckerContext = CallCheckerContext(topLevelCallContext, languageVersionSettings) + private val callCheckerContext = CallCheckerContext(topLevelCallContext, languageVersionSettings, deprecationResolver) fun completeAndReport(resolvedAtom: ResolvedAtom) { when (resolvedAtom) { @@ -198,4 +203,4 @@ class ResolvedAtomCompleter( expressionTypingServices.getTypeInfo(psiCallArgument.collectionLiteralExpression, actualContext) } -} \ No newline at end of file +} diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ApiVersionClassifierUsageChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ApiVersionClassifierUsageChecker.kt index 3e03593ac65..fef87dbf858 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ApiVersionClassifierUsageChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ApiVersionClassifierUsageChecker.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.ClassifierDescriptor import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.resolve.BindingTrace +import org.jetbrains.kotlin.resolve.DeprecationResolver import org.jetbrains.kotlin.resolve.checkSinceKotlinVersionAccessibility object ApiVersionClassifierUsageChecker : ClassifierUsageChecker { @@ -28,7 +29,8 @@ object ApiVersionClassifierUsageChecker : ClassifierUsageChecker { targetDescriptor: ClassifierDescriptor, trace: BindingTrace, element: PsiElement, - languageVersionSettings: LanguageVersionSettings + languageVersionSettings: LanguageVersionSettings, + deprecationResolver: DeprecationResolver ) { targetDescriptor.checkSinceKotlinVersionAccessibility(languageVersionSettings) { version -> trace.report(Errors.API_NOT_AVAILABLE.on(element, version.versionString, languageVersionSettings.apiVersion.versionString)) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ClassifierUsageChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ClassifierUsageChecker.kt index 7179f44f78c..ea0d52a30f2 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ClassifierUsageChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ClassifierUsageChecker.kt @@ -28,6 +28,7 @@ import org.jetbrains.kotlin.psi.KtReferenceExpression import org.jetbrains.kotlin.psi.KtTreeVisitorVoid import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingTrace +import org.jetbrains.kotlin.resolve.DeprecationResolver import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.utils.addToStdlib.safeAs @@ -36,7 +37,8 @@ interface ClassifierUsageChecker { targetDescriptor: ClassifierDescriptor, trace: BindingTrace, element: PsiElement, - languageVersionSettings: LanguageVersionSettings + languageVersionSettings: LanguageVersionSettings, + deprecationResolver: DeprecationResolver ) companion object { @@ -44,6 +46,7 @@ interface ClassifierUsageChecker { declarations: Collection, trace: BindingTrace, languageVersionSettings: LanguageVersionSettings, + deprecationResolver: DeprecationResolver, checkers: Iterable ) { val visitor = object : KtTreeVisitorVoid() { @@ -71,7 +74,7 @@ interface ClassifierUsageChecker { private fun runCheckersWithTarget(target: ClassifierDescriptor, expression: KtReferenceExpression) { for (checker in checkers) { - checker.check(target, trace, expression, languageVersionSettings) + checker.check(target, trace, expression, languageVersionSettings, deprecationResolver) } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/DeprecatedClassifierUsageChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/DeprecatedClassifierUsageChecker.kt index 69575ed226f..b50f00f9baf 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/DeprecatedClassifierUsageChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/DeprecatedClassifierUsageChecker.kt @@ -21,18 +21,19 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.ClassifierDescriptor import org.jetbrains.kotlin.psi.KtThisExpression import org.jetbrains.kotlin.resolve.BindingTrace +import org.jetbrains.kotlin.resolve.DeprecationResolver import org.jetbrains.kotlin.resolve.createDeprecationDiagnostic -import org.jetbrains.kotlin.resolve.getDeprecations class DeprecatedClassifierUsageChecker : ClassifierUsageChecker { override fun check( targetDescriptor: ClassifierDescriptor, trace: BindingTrace, element: PsiElement, - languageVersionSettings: LanguageVersionSettings + languageVersionSettings: LanguageVersionSettings, + deprecationResolver: DeprecationResolver ) { if (element.parent is KtThisExpression) return - for (deprecation in targetDescriptor.getDeprecations(languageVersionSettings)) { + for (deprecation in deprecationResolver.getDeprecations(targetDescriptor)) { trace.report(createDeprecationDiagnostic(element, deprecation, languageVersionSettings)) } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/MissingDependencyClassChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/MissingDependencyClassChecker.kt index 3756d0350e6..bfc2ba978ba 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/MissingDependencyClassChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/MissingDependencyClassChecker.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.Errors.* import org.jetbrains.kotlin.resolve.BindingTrace +import org.jetbrains.kotlin.resolve.DeprecationResolver import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext import org.jetbrains.kotlin.resolve.calls.checkers.isComputingDeferredType @@ -95,7 +96,8 @@ object MissingDependencyClassChecker : CallChecker { targetDescriptor: ClassifierDescriptor, trace: BindingTrace, element: PsiElement, - languageVersionSettings: LanguageVersionSettings + languageVersionSettings: LanguageVersionSettings, + deprecationResolver: DeprecationResolver ) { diagnosticFor(targetDescriptor, element)?.let(trace::report) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecationUtil.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecationUtil.kt index bdd92c66b18..3ee0f147b26 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecationUtil.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecationUtil.kt @@ -37,6 +37,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedMemberDescriptor import org.jetbrains.kotlin.serialization.deserialization.descriptors.SinceKotlinInfo +import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.utils.SmartList @@ -146,133 +147,6 @@ private fun Deprecation.wrapInTypeAliasExpansion(typeAliasDescriptor: TypeAliasD else -> this } -fun DeclarationDescriptor.getDeprecations(languageVersionSettings: LanguageVersionSettings): List { - val deprecations = this.getOwnDeprecations(languageVersionSettings) - if (deprecations.isNotEmpty()) { - return deprecations - } - - if (this is CallableMemberDescriptor) { - return listOfNotNull(deprecationByOverridden(this, languageVersionSettings)) - } - - return emptyList() -} - -private fun KotlinType.deprecationsByConstituentTypes(languageVersionSettings: LanguageVersionSettings): List = - SmartList().also { deprecations -> - TypeUtils.contains(this) { type -> - type.constructor.declarationDescriptor?.run { - deprecations.addAll(getDeprecations(languageVersionSettings)) - } - false - } - } - -private fun deprecationByOverridden(root: CallableMemberDescriptor, languageVersionSettings: LanguageVersionSettings): Deprecation? { - val visited = HashSet() - val deprecations = LinkedHashSet() - var hasUndeprecatedOverridden = false - - fun traverse(node: CallableMemberDescriptor) { - if (node in visited) return - - visited.add(node) - - val deprecationsByAnnotation = node.getOwnDeprecations(languageVersionSettings) - val overriddenDescriptors = node.original.overriddenDescriptors - when { - deprecationsByAnnotation.isNotEmpty() -> { - deprecations.addAll(deprecationsByAnnotation) - } - overriddenDescriptors.isEmpty() -> { - hasUndeprecatedOverridden = true - return - } - else -> { - overriddenDescriptors.forEach(::traverse) - } - } - } - - traverse(root) - - if (hasUndeprecatedOverridden || deprecations.isEmpty()) return null - - return DeprecatedByOverridden(deprecations) -} - -private fun DeclarationDescriptor.getOwnDeprecations(languageVersionSettings: LanguageVersionSettings): List { - // The problem is that declaration `mod` in built-ins has @Deprecated annotation but actually it was deprecated only in version 1.1 - if (this is FunctionDescriptor && this.isOperatorMod() && KotlinBuiltIns.isUnderKotlinPackage(this)) { - if (!shouldWarnAboutDeprecatedModFromBuiltIns(languageVersionSettings)) { - return emptyList() - } - } - - val result = SmartList() - - fun addDeprecationIfPresent(target: DeclarationDescriptor) { - val annotation = target.annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.deprecated) - ?: target.annotations.findAnnotation(JAVA_DEPRECATED) - if (annotation != null) { - val deprecatedByAnnotation = DeprecatedByAnnotation(annotation, target) - val deprecation = when (target) { - is TypeAliasConstructorDescriptor -> DeprecatedTypealiasByAnnotation(target.typeAliasDescriptor, deprecatedByAnnotation) - else -> deprecatedByAnnotation - } - result.add(deprecation) - } - - val sinceKotlinInfo = - (target as? DeserializedMemberDescriptor)?.sinceKotlinInfo - ?: (target as? DeserializedClassDescriptor)?.sinceKotlinInfo - if (sinceKotlinInfo != null) { - // We're using ApiVersion because it's convenient to compare versions, "-api-version" is not involved in any way - // TODO: usage of ApiVersion is confusing here, refactor - if (ApiVersion.createBySinceKotlinInfo(sinceKotlinInfo) > - ApiVersion.createByLanguageVersion(languageVersionSettings.languageVersion)) { - result.add(DeprecatedBySinceKotlinInfo(sinceKotlinInfo, target)) - } - } - } - - fun addUseSiteTargetedDeprecationIfPresent(annotatedDescriptor: DeclarationDescriptor, useSiteTarget: AnnotationUseSiteTarget?) { - if (useSiteTarget != null) { - val annotation = Annotations.findUseSiteTargetedAnnotation(annotatedDescriptor.annotations, useSiteTarget, KotlinBuiltIns.FQ_NAMES.deprecated) - ?: Annotations.findUseSiteTargetedAnnotation(annotatedDescriptor.annotations, useSiteTarget, JAVA_DEPRECATED) - if (annotation != null) { - result.add(DeprecatedByAnnotation(annotation, this)) - } - } - } - - addDeprecationIfPresent(this) - addUseSiteTargetedDeprecationIfPresent(this, AnnotationUseSiteTarget.getAssociatedUseSiteTarget(this)) - - when (this) { - is TypeAliasDescriptor -> { - expandedType.deprecationsByConstituentTypes(languageVersionSettings).mapTo(result) { it.wrapInTypeAliasExpansion(this) } - } - is DescriptorDerivedFromTypeAlias -> { - result.addAll(typeAliasDescriptor.getOwnDeprecations(languageVersionSettings)) - } - is ConstructorDescriptor -> { - addDeprecationIfPresent(containingDeclaration) - } - is PropertyAccessorDescriptor -> { - addDeprecationIfPresent(correspondingProperty) - - addUseSiteTargetedDeprecationIfPresent( - correspondingProperty, - if (this is PropertyGetterDescriptor) AnnotationUseSiteTarget.PROPERTY_GETTER else AnnotationUseSiteTarget.PROPERTY_SETTER - ) - } - } - - return result.distinct() -} - internal fun createDeprecationDiagnostic( element: PsiElement, deprecation: Deprecation, languageVersionSettings: LanguageVersionSettings ): Diagnostic { @@ -310,17 +184,157 @@ enum class DeprecationLevelValue { WARNING, ERROR, HIDDEN } -fun DeclarationDescriptor.isDeprecatedHidden(languageVersionSettings: LanguageVersionSettings): Boolean = - getDeprecations(languageVersionSettings).any { it.deprecationLevel == HIDDEN } - -@JvmOverloads -fun DeclarationDescriptor.isHiddenInResolution(languageVersionSettings: LanguageVersionSettings, isSuperCall: Boolean = false): Boolean { - if (this is FunctionDescriptor) { - if (isHiddenToOvercomeSignatureClash) return true - if (isHiddenForResolutionEverywhereBesideSupercalls && !isSuperCall) return true +class DeprecationResolver( + storageManager: StorageManager, + private val languageVersionSettings: LanguageVersionSettings +) { + private val deprecations = storageManager.createMemoizedFunction { descriptor: DeclarationDescriptor -> + val deprecations = descriptor.getOwnDeprecations() + when { + deprecations.isNotEmpty() -> deprecations + descriptor is CallableMemberDescriptor -> listOfNotNull(deprecationByOverridden(descriptor)) + else -> emptyList() + } } - if (!checkSinceKotlinVersionAccessibility(languageVersionSettings)) return true + private val isHiddenBecauseOfKotlinVersionAccessibility = storageManager.createMemoizedFunction { descriptor: DeclarationDescriptor -> + descriptor.checkSinceKotlinVersionAccessibility(languageVersionSettings) + } - return isDeprecatedHidden(languageVersionSettings) + fun getDeprecations( + descriptor: DeclarationDescriptor + ) = deprecations(descriptor.original) + + + fun isDeprecatedHidden(descriptor: DeclarationDescriptor): Boolean = + getDeprecations(descriptor).any { it.deprecationLevel == HIDDEN } + + @JvmOverloads + fun isHiddenInResolution( + descriptor: DeclarationDescriptor, + isSuperCall: Boolean = false + ): Boolean { + if (descriptor is FunctionDescriptor) { + if (descriptor.isHiddenToOvercomeSignatureClash) return true + if (descriptor.isHiddenForResolutionEverywhereBesideSupercalls && !isSuperCall) return true + } + + if (!isHiddenBecauseOfKotlinVersionAccessibility(descriptor.original)) return true + + return isDeprecatedHidden(descriptor) + } + + private fun KotlinType.deprecationsByConstituentTypes(): List = + SmartList().also { deprecations -> + TypeUtils.contains(this) { type -> + type.constructor.declarationDescriptor?.let { + deprecations.addAll(getDeprecations(it)) + } + false + } + } + + private fun deprecationByOverridden(root: CallableMemberDescriptor): Deprecation? { + val visited = HashSet() + val deprecations = LinkedHashSet() + var hasUndeprecatedOverridden = false + + fun traverse(node: CallableMemberDescriptor) { + if (node in visited) return + + visited.add(node) + + val deprecationsByAnnotation = node.getOwnDeprecations() + val overriddenDescriptors = node.original.overriddenDescriptors + when { + deprecationsByAnnotation.isNotEmpty() -> { + deprecations.addAll(deprecationsByAnnotation) + } + overriddenDescriptors.isEmpty() -> { + hasUndeprecatedOverridden = true + return + } + else -> { + overriddenDescriptors.forEach(::traverse) + } + } + } + + traverse(root) + + if (hasUndeprecatedOverridden || deprecations.isEmpty()) return null + + return DeprecatedByOverridden(deprecations) + } + + private fun DeclarationDescriptor.getOwnDeprecations(): List { + // The problem is that declaration `mod` in built-ins has @Deprecated annotation but actually it was deprecated only in version 1.1 + if (this is FunctionDescriptor && this.isOperatorMod() && KotlinBuiltIns.isUnderKotlinPackage(this)) { + if (!shouldWarnAboutDeprecatedModFromBuiltIns(languageVersionSettings)) { + return emptyList() + } + } + + val result = SmartList() + + fun addDeprecationIfPresent(target: DeclarationDescriptor) { + val annotation = target.annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.deprecated) + ?: target.annotations.findAnnotation(JAVA_DEPRECATED) + if (annotation != null) { + val deprecatedByAnnotation = DeprecatedByAnnotation(annotation, target) + val deprecation = when (target) { + is TypeAliasConstructorDescriptor -> DeprecatedTypealiasByAnnotation(target.typeAliasDescriptor, deprecatedByAnnotation) + else -> deprecatedByAnnotation + } + result.add(deprecation) + } + + val sinceKotlinInfo = + (target as? DeserializedMemberDescriptor)?.sinceKotlinInfo + ?: (target as? DeserializedClassDescriptor)?.sinceKotlinInfo + if (sinceKotlinInfo != null) { + // We're using ApiVersion because it's convenient to compare versions, "-api-version" is not involved in any way + // TODO: usage of ApiVersion is confusing here, refactor + if (ApiVersion.createBySinceKotlinInfo(sinceKotlinInfo) > + ApiVersion.createByLanguageVersion(languageVersionSettings.languageVersion)) { + result.add(DeprecatedBySinceKotlinInfo(sinceKotlinInfo, target)) + } + } + } + + fun addUseSiteTargetedDeprecationIfPresent(annotatedDescriptor: DeclarationDescriptor, useSiteTarget: AnnotationUseSiteTarget?) { + if (useSiteTarget != null) { + val annotation = Annotations.findUseSiteTargetedAnnotation(annotatedDescriptor.annotations, useSiteTarget, KotlinBuiltIns.FQ_NAMES.deprecated) + ?: Annotations.findUseSiteTargetedAnnotation(annotatedDescriptor.annotations, useSiteTarget, JAVA_DEPRECATED) + if (annotation != null) { + result.add(DeprecatedByAnnotation(annotation, this)) + } + } + } + + addDeprecationIfPresent(this) + addUseSiteTargetedDeprecationIfPresent(this, AnnotationUseSiteTarget.getAssociatedUseSiteTarget(this)) + + when (this) { + is TypeAliasDescriptor -> { + expandedType.deprecationsByConstituentTypes().mapTo(result) { it.wrapInTypeAliasExpansion(this) } + } + is DescriptorDerivedFromTypeAlias -> { + result.addAll(typeAliasDescriptor.getOwnDeprecations()) + } + is ConstructorDescriptor -> { + addDeprecationIfPresent(containingDeclaration) + } + is PropertyAccessorDescriptor -> { + addDeprecationIfPresent(correspondingProperty) + + addUseSiteTargetedDeprecationIfPresent( + correspondingProperty, + if (this is PropertyGetterDescriptor) AnnotationUseSiteTarget.PROPERTY_GETTER else AnnotationUseSiteTarget.PROPERTY_SETTER + ) + } + } + + return result.distinct() + } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/FileScopeFactory.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/FileScopeFactory.kt index 84658c822fb..52ded343428 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/FileScopeFactory.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/FileScopeFactory.kt @@ -26,10 +26,7 @@ import org.jetbrains.kotlin.platform.PlatformToKotlinClassMap import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtImportDirective import org.jetbrains.kotlin.psi.KtImportsFactory -import org.jetbrains.kotlin.resolve.BindingTrace -import org.jetbrains.kotlin.resolve.ImportPath -import org.jetbrains.kotlin.resolve.QualifiedExpressionResolver -import org.jetbrains.kotlin.resolve.TemporaryBindingTrace +import org.jetbrains.kotlin.resolve.* import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.ImportingScope import org.jetbrains.kotlin.resolve.scopes.LexicalScope @@ -51,7 +48,8 @@ class FileScopeFactory( private val ktImportsFactory: KtImportsFactory, private val platformToKotlinClassMap: PlatformToKotlinClassMap, private val defaultImportProvider: DefaultImportProvider, - private val languageVersionSettings: LanguageVersionSettings + private val languageVersionSettings: LanguageVersionSettings, + private val deprecationResolver: DeprecationResolver ) { /* avoid constructing psi for default imports prematurely (time consuming in some scenarios) */ private val defaultImports by storageManager.createLazyValue { @@ -112,7 +110,8 @@ class FileScopeFactory( fun createImportResolver(indexedImports: IndexedImports, trace: BindingTrace, excludedImports: List? = null) = LazyImportResolver( storageManager, qualifiedExpressionResolver, moduleDescriptor, platformToKotlinClassMap, languageVersionSettings, - indexedImports, aliasImportNames concat excludedImports, trace, packageFragment + indexedImports, aliasImportNames concat excludedImports, trace, packageFragment, + deprecationResolver ) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt index 09e3a994da6..5ea473866b9 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt @@ -81,7 +81,8 @@ class LazyImportResolver( val indexedImports: IndexedImports, excludedImportNames: Collection, private val traceForImportResolve: BindingTrace, - private val packageFragment: PackageFragmentDescriptor + private val packageFragment: PackageFragmentDescriptor, + val deprecationResolver: DeprecationResolver ) : ImportResolver { private val importedScopesProvider = storageManager.createMemoizedFunctionWithNullableValues { directive: KtImportDirective -> @@ -208,7 +209,7 @@ class LazyImportScope( private fun isClassifierVisible(descriptor: ClassifierDescriptor): Boolean { if (filteringKind == FilteringKind.ALL) return true - if (descriptor.isHiddenInResolution(importResolver.languageVersionSettings)) return false + if (importResolver.deprecationResolver.isHiddenInResolution(descriptor)) return false val visibility = (descriptor as DeclarationDescriptorWithVisibility).visibility val includeVisible = filteringKind == FilteringKind.VISIBLE_CLASSES diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java index 1a9e2e8b78b..890fff4eae4 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java @@ -633,7 +633,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { trace.record(CALL, expression, call); if (context.trace.wantsDiagnostics()) { - CallCheckerContext callCheckerContext = new CallCheckerContext(context, components.languageVersionSettings); + CallCheckerContext callCheckerContext = + createCallCheckerContext(context); for (CallChecker checker : components.callCheckers) { checker.check(resolvedCall, expression, callCheckerContext); } @@ -934,7 +935,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { if (resolvedCall != null && trace.wantsDiagnostics()) { // Call must be validated with the actual, not temporary trace in order to report operator diagnostic // Only unary assignment expressions (++, --) and +=/... must be checked, normal assignments have the proper trace - CallCheckerContext callCheckerContext = new CallCheckerContext(context, trace, components.languageVersionSettings); + CallCheckerContext callCheckerContext = + new CallCheckerContext(context, trace, components.languageVersionSettings, components.deprecationResolver); for (CallChecker checker : components.callCheckers) { checker.check(resolvedCall, expression, callCheckerContext); } @@ -1001,13 +1003,19 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { resolvedCall.markCallAsCompleted(); if (context.trace.wantsDiagnostics()) { - CallCheckerContext callCheckerContext = new CallCheckerContext(context, components.languageVersionSettings); + CallCheckerContext callCheckerContext = + createCallCheckerContext(context); for (CallChecker checker : components.callCheckers) { checker.check(resolvedCall, expression, callCheckerContext); } } } + @NotNull + private CallCheckerContext createCallCheckerContext(@NotNull ExpressionTypingContext context) { + return new CallCheckerContext(context, components.languageVersionSettings, components.deprecationResolver); + } + @Override public KotlinTypeInfo visitBinaryExpression(@NotNull KtBinaryExpression expression, ExpressionTypingContext contextWithExpectedType) { ExpressionTypingContext context = isBinaryExpressionDependentOnExpectedType(expression) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingComponents.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingComponents.java index c2fcad22b48..d083d4a7f92 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingComponents.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingComponents.java @@ -63,6 +63,7 @@ public class ExpressionTypingComponents { /*package*/ Iterable rttiExpressionCheckers; /*package*/ WrappedTypeFactory wrappedTypeFactory; /*package*/ CollectionLiteralResolver collectionLiteralResolver; + /*package*/ DeprecationResolver deprecationResolver; @Inject public void setGlobalContext(@NotNull GlobalContext globalContext) { @@ -213,4 +214,9 @@ public class ExpressionTypingComponents { public void setCollectionLiteralResolver(CollectionLiteralResolver collectionLiteralResolver) { this.collectionLiteralResolver = collectionLiteralResolver; } + + @Inject + public void setDeprecationResolver(DeprecationResolver deprecationResolver) { + this.deprecationResolver = deprecationResolver; + } } diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/codeInsight/ReferenceVariantsHelper.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/codeInsight/ReferenceVariantsHelper.kt index b5e79b68794..b437d4b19e7 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/idea/codeInsight/ReferenceVariantsHelper.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/codeInsight/ReferenceVariantsHelper.kt @@ -17,7 +17,6 @@ package org.jetbrains.kotlin.idea.codeInsight import com.intellij.psi.PsiElement -import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.idea.resolve.ResolutionFacade import org.jetbrains.kotlin.idea.resolve.frontendService @@ -31,10 +30,10 @@ import org.jetbrains.kotlin.psi.KtSimpleNameExpression import org.jetbrains.kotlin.psi.KtVariableDeclaration import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.DeprecationResolver import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfoBefore import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension -import org.jetbrains.kotlin.resolve.isHiddenInResolution import org.jetbrains.kotlin.resolve.scopes.* import org.jetbrains.kotlin.resolve.scopes.receivers.ClassQualifier import org.jetbrains.kotlin.resolve.scopes.utils.collectAllFromMeAndParent @@ -77,7 +76,7 @@ class ReferenceVariantsHelper( ): Collection { var variants: Collection = getReferenceVariantsNoVisibilityFilter(contextElement, kindFilter, nameFilter, callTypeAndReceiver, useReceiverType) - .filter { !it.isHiddenInResolution(resolutionFacade.frontendService()) && visibilityFilter(it) } + .filter { !resolutionFacade.frontendService().isHiddenInResolution(it) && visibilityFilter(it) } if (filterOutShadowed) { ShadowedDeclarationsFilter.create(bindingContext, resolutionFacade, contextElement, callTypeAndReceiver)?.let { @@ -415,4 +414,4 @@ fun ResolutionScope.collectSyntheticStaticMembersAndConstructors( val syntheticScopes = resolutionFacade.getFrontendService(SyntheticScopes::class.java) return (syntheticScopes.collectSyntheticStaticFunctions(this) + syntheticScopes.collectSyntheticConstructors(this)) .filter { kindFilter.accepts(it) && nameFilter(it.name) } -} \ No newline at end of file +} diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/KotlinIndicesHelper.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/KotlinIndicesHelper.kt index c6f0238d345..b0f6985fac8 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/KotlinIndicesHelper.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/KotlinIndicesHelper.kt @@ -24,7 +24,6 @@ import com.intellij.psi.search.PsiShortNamesCache import com.intellij.psi.stubs.StringStubIndexExtension import com.intellij.util.indexing.IdFilter import org.jetbrains.kotlin.asJava.elements.KtLightElement -import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.idea.caches.KotlinShortNamesCache import org.jetbrains.kotlin.idea.caches.resolve.* @@ -44,7 +43,7 @@ import org.jetbrains.kotlin.load.java.sam.SamAdapterDescriptor import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.contains import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.isHiddenInResolution +import org.jetbrains.kotlin.resolve.DeprecationResolver import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes import org.jetbrains.kotlin.resolve.scopes.collectSyntheticStaticFunctions @@ -68,7 +67,7 @@ class KotlinIndicesHelper( private val scopeWithoutKotlin = scope.excludeKotlinSources() as GlobalSearchScope private val descriptorFilter: (DeclarationDescriptor) -> Boolean = filter@ { - if (it.isHiddenInResolution(resolutionFacade.frontendService())) return@filter false + if (resolutionFacade.frontendService().isHiddenInResolution(it)) return@filter false if (!visibilityFilter(it)) return@filter false if (applyExcludeSettings && it.isExcludedFromAutoImport(project, file)) return@filter false true diff --git a/idea/src/org/jetbrains/kotlin/idea/KotlinQuickDocumentationProvider.kt b/idea/src/org/jetbrains/kotlin/idea/KotlinQuickDocumentationProvider.kt index 6b644166062..bf07b3f2904 100644 --- a/idea/src/org/jetbrains/kotlin/idea/KotlinQuickDocumentationProvider.kt +++ b/idea/src/org/jetbrains/kotlin/idea/KotlinQuickDocumentationProvider.kt @@ -27,7 +27,6 @@ import com.intellij.psi.PsiManager import com.intellij.psi.PsiWhiteSpace import org.jetbrains.kotlin.asJava.LightClassUtil import org.jetbrains.kotlin.asJava.elements.KtLightDeclaration -import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade @@ -39,8 +38,8 @@ import org.jetbrains.kotlin.idea.kdoc.KDocRenderer import org.jetbrains.kotlin.idea.kdoc.findKDoc import org.jetbrains.kotlin.idea.kdoc.isBoringBuiltinClass import org.jetbrains.kotlin.idea.kdoc.resolveKDocLink -import org.jetbrains.kotlin.idea.project.languageVersionSettings import org.jetbrains.kotlin.idea.references.mainReference +import org.jetbrains.kotlin.idea.resolve.frontendService import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi import org.jetbrains.kotlin.kdoc.psi.api.KDoc import org.jetbrains.kotlin.kdoc.psi.impl.KDocSection @@ -49,12 +48,12 @@ import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.renderer.ClassifierNamePolicy import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.DeprecationResolver import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.deprecatedByAnnotationReplaceWithExpression import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny -import org.jetbrains.kotlin.resolve.getDeprecations import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.utils.addToStdlib.constant @@ -246,20 +245,20 @@ class KotlinQuickDocumentationProvider : AbstractDocumentationProvider() { return "No documentation available" } - return renderKotlin(context, declarationDescriptor, quickNavigation, declaration.languageVersionSettings) + return renderKotlin(context, declarationDescriptor, quickNavigation, declaration) } private fun renderKotlinImplicitLambdaParameter(element: KtReferenceExpression, quickNavigation: Boolean): String? { val context = element.analyze(BodyResolveMode.PARTIAL) val target = element.mainReference.resolveToDescriptors(context).singleOrNull() as? ValueParameterDescriptor? ?: return null - return renderKotlin(context, target, quickNavigation, element.languageVersionSettings) + return renderKotlin(context, target, quickNavigation, element) } private fun renderKotlin( context: BindingContext, declarationDescriptor: DeclarationDescriptor, quickNavigation: Boolean, - languageVersionSettings: LanguageVersionSettings + ktElement: KtElement ): String { @Suppress("NAME_SHADOWING") var declarationDescriptor = declarationDescriptor @@ -278,7 +277,8 @@ class KotlinQuickDocumentationProvider : AbstractDocumentationProvider() { renderedDecl = "
$renderedDecl
" } - renderedDecl += renderDeprecationInfo(declarationDescriptor, languageVersionSettings) + val deprecationProvider = ktElement.getResolutionFacade().frontendService() + renderedDecl += renderDeprecationInfo(declarationDescriptor, deprecationProvider) if (!quickNavigation) { val comment = declarationDescriptor.findKDoc() @@ -310,9 +310,9 @@ class KotlinQuickDocumentationProvider : AbstractDocumentationProvider() { private fun renderDeprecationInfo( declarationDescriptor: DeclarationDescriptor, - languageVersionSettings: LanguageVersionSettings + deprecationResolver: DeprecationResolver ): String { - val deprecation = declarationDescriptor.getDeprecations(languageVersionSettings).firstOrNull() ?: return "" + val deprecation = deprecationResolver.getDeprecations(declarationDescriptor).firstOrNull() ?: return "" return buildString { wrapTag("DL") { diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/ConflictingExtensionPropertyInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/ConflictingExtensionPropertyInspection.kt index df00c93e5e1..9dcbf09e010 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/ConflictingExtensionPropertyInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/ConflictingExtensionPropertyInspection.kt @@ -30,7 +30,6 @@ import com.intellij.psi.PsiElementVisitor import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.searches.ReferencesSearch import com.intellij.ui.GuiUtils -import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.idea.caches.resolve.analyze @@ -50,9 +49,9 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType import org.jetbrains.kotlin.renderer.render +import org.jetbrains.kotlin.resolve.DeprecationResolver import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess -import org.jetbrains.kotlin.resolve.isHiddenInResolution import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes import org.jetbrains.kotlin.resolve.scopes.collectSyntheticExtensionProperties @@ -76,7 +75,7 @@ class ConflictingExtensionPropertyInspection : AbstractKotlinInspection(), Clean val conflictingExtension = conflictingSyntheticExtension(propertyDescriptor, syntheticScopes) ?: return // don't report on hidden declarations - if (propertyDescriptor.isHiddenInResolution(resolutionFacade.frontendService())) return + if (resolutionFacade.frontendService().isHiddenInResolution(propertyDescriptor)) return val fixes = createFixes(property, conflictingExtension, isOnTheFly) @@ -251,4 +250,4 @@ class ConflictingExtensionPropertyInspection : AbstractKotlinInspection(), Clean } } } -} \ No newline at end of file +} diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/OverridingDeprecatedMemberInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/OverridingDeprecatedMemberInspection.kt index ebdcc729247..7b298fa3601 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/OverridingDeprecatedMemberInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/OverridingDeprecatedMemberInspection.kt @@ -21,14 +21,15 @@ import com.intellij.codeInspection.ProblemsHolder import com.intellij.psi.PsiElement import com.intellij.psi.PsiElementVisitor import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor +import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny -import org.jetbrains.kotlin.idea.project.languageVersionSettings +import org.jetbrains.kotlin.idea.resolve.frontendService import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtNamedDeclaration import org.jetbrains.kotlin.psi.KtPropertyAccessor import org.jetbrains.kotlin.psi.KtVisitorVoid +import org.jetbrains.kotlin.resolve.DeprecationResolver import org.jetbrains.kotlin.resolve.deprecatedByOverriddenMessage -import org.jetbrains.kotlin.resolve.getDeprecations class OverridingDeprecatedMemberInspection : AbstractKotlinInspection() { override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { @@ -44,7 +45,9 @@ class OverridingDeprecatedMemberInspection : AbstractKotlinInspection() { private fun registerProblemIfNeeded(declaration: KtDeclaration, targetForProblem: PsiElement) { val accessorDescriptor = declaration.resolveToDescriptorIfAny() as? CallableMemberDescriptor ?: return - val message = accessorDescriptor.getDeprecations(declaration.languageVersionSettings) + val deprecationProvider = declaration.getResolutionFacade().frontendService() + + val message = deprecationProvider.getDeprecations(accessorDescriptor) .firstOrNull() ?.deprecatedByOverriddenMessage() ?: return val problem = holder.manager.createProblemDescriptor(