Memoize deprecations-related computations

It might be helpful for performance as these methods are called
for each resolution candidate and in the same time they scan
the whole overridden tree of a callable member
This commit is contained in:
Denis Zharkov
2017-08-08 14:36:52 +07:00
parent 4eb0f245a6
commit b905ddeac9
28 changed files with 276 additions and 223 deletions
@@ -33,7 +33,6 @@ import org.jetbrains.kotlin.codegen.serialization.JvmStringTable;
import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper; import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
import org.jetbrains.kotlin.config.JvmTarget; import org.jetbrains.kotlin.config.JvmTarget;
import org.jetbrains.kotlin.config.LanguageFeature;
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl; import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.lexer.KtTokens; 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.name.FqName;
import org.jetbrains.kotlin.protobuf.MessageLite; import org.jetbrains.kotlin.protobuf.MessageLite;
import org.jetbrains.kotlin.renderer.DescriptorRenderer; import org.jetbrains.kotlin.renderer.DescriptorRenderer;
import org.jetbrains.kotlin.resolve.DeprecationUtilKt;
import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt; import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt;
import org.jetbrains.kotlin.resolve.inline.InlineUtil; import org.jetbrains.kotlin.resolve.inline.InlineUtil;
@@ -204,7 +202,7 @@ public class AsmUtil {
} }
public static int getMethodAsmFlags(FunctionDescriptor functionDescriptor, OwnerKind kind, GenerationState state) { 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) { for (AnnotationCodegen.JvmFlagAnnotation flagAnnotation : AnnotationCodegen.METHOD_FLAGS) {
if (flagAnnotation.hasAnnotation(functionDescriptor.getOriginal())) { if (flagAnnotation.hasAnnotation(functionDescriptor.getOriginal())) {
@@ -245,17 +243,11 @@ public class AsmUtil {
return flags; return flags;
} }
public static int getCommonCallableFlags(FunctionDescriptor functionDescriptor) { public static int getCommonCallableFlags(FunctionDescriptor functionDescriptor, @NotNull GenerationState state) {
int flags = getVisibilityAccessFlag(functionDescriptor); int flags = getVisibilityAccessFlag(functionDescriptor);
flags |= getVarargsFlag(functionDescriptor); flags |= getVarargsFlag(functionDescriptor);
flags |= getDeprecatedAccessFlag(functionDescriptor); flags |= getDeprecatedAccessFlag(functionDescriptor);
if (DeprecationUtilKt.isDeprecatedHidden(functionDescriptor, LanguageVersionSettingsImpl.DEFAULT) if (state.getDeprecationProvider().isDeprecatedHidden(functionDescriptor)) {
|| functionDescriptor instanceof PropertyAccessorDescriptor
&& DeprecationUtilKt.isDeprecatedHidden(
((PropertyAccessorDescriptor) functionDescriptor).getCorrespondingProperty(),
LanguageVersionSettingsImpl.DEFAULT
)
) {
flags |= ACC_SYNTHETIC; flags |= ACC_SYNTHETIC;
} }
return flags; return flags;
@@ -26,7 +26,6 @@ import org.jetbrains.kotlin.psi.KtPureElement
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
import org.jetbrains.kotlin.resolve.jvm.AsmTypes import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.resolve.jvm.annotations.findJvmOverloadsAnnotation 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.kotlin.resolve.jvm.diagnostics.OtherOriginFromPure
import org.jetbrains.org.objectweb.asm.Label import org.jetbrains.org.objectweb.asm.Label
import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.Opcodes
@@ -129,7 +128,7 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
) { ) {
val typeMapper = state.typeMapper val typeMapper = state.typeMapper
val isStatic = AsmUtil.isStaticMethod(contextKind, functionDescriptor) 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 remainingParameters = getRemainingParameters(functionDescriptor.original, substituteCount)
val flags = val flags =
baseMethodFlags or baseMethodFlags or
@@ -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.JvmDeclarationOrigin
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind.* import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind.*
import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import java.io.File import java.io.File
class GenerationState @JvmOverloads constructor( class GenerationState @JvmOverloads constructor(
@@ -95,6 +96,8 @@ class GenerationState @JvmOverloads constructor(
val deserializationConfiguration: DeserializationConfiguration = val deserializationConfiguration: DeserializationConfiguration =
CompilerDeserializationConfiguration(configuration.languageVersionSettings) CompilerDeserializationConfiguration(configuration.languageVersionSettings)
val deprecationProvider = DeprecationResolver(LockBasedStorageManager.NO_LOCKS, configuration.languageVersionSettings)
init { init {
val icComponents = configuration.get(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS) val icComponents = configuration.get(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS)
if (icComponents != null) { if (icComponents != null) {
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryPackageSourceElement
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement
import org.jetbrains.kotlin.load.kotlin.VirtualFileKotlinClass import org.jetbrains.kotlin.load.kotlin.VirtualFileKotlinClass
import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.DeprecationResolver
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker
@@ -102,7 +103,8 @@ class JvmModuleAccessibilityChecker(project: Project) : CallChecker {
targetDescriptor: ClassifierDescriptor, targetDescriptor: ClassifierDescriptor,
trace: BindingTrace, trace: BindingTrace,
element: PsiElement, element: PsiElement,
languageVersionSettings: LanguageVersionSettings languageVersionSettings: LanguageVersionSettings,
deprecationResolver: DeprecationResolver
) { ) {
val virtualFile = element.containingFile.virtualFile val virtualFile = element.containingFile.virtualFile
when (targetDescriptor) { when (targetDescriptor) {
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.synthetic
import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.load.java.components.SamConversionResolver 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.resolve.scopes.SyntheticScopes
import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.StorageManager
@@ -26,10 +27,11 @@ class JavaSyntheticScopes(
storageManager: StorageManager, storageManager: StorageManager,
lookupTracker: LookupTracker, lookupTracker: LookupTracker,
languageVersionSettings: LanguageVersionSettings, languageVersionSettings: LanguageVersionSettings,
samConventionResolver: SamConversionResolver samConventionResolver: SamConversionResolver,
deprecationResolver: DeprecationResolver
): SyntheticScopes { ): SyntheticScopes {
override val scopes = listOf( override val scopes = listOf(
JavaSyntheticPropertiesScope(storageManager, lookupTracker), JavaSyntheticPropertiesScope(storageManager, lookupTracker),
SamAdapterFunctionsScope(storageManager, languageVersionSettings, samConventionResolver) SamAdapterFunctionsScope(storageManager, languageVersionSettings, samConventionResolver, deprecationResolver)
) )
} }
@@ -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.SamConstructorDescriptor
import org.jetbrains.kotlin.load.java.sam.SingleAbstractMethodUtils import org.jetbrains.kotlin.load.java.sam.SingleAbstractMethodUtils
import org.jetbrains.kotlin.name.Name 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.calls.inference.wrapWithCapturingSubstitution
import org.jetbrains.kotlin.resolve.isHiddenInResolution
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.ResolutionScope import org.jetbrains.kotlin.resolve.scopes.ResolutionScope
import org.jetbrains.kotlin.resolve.scopes.SyntheticScope import org.jetbrains.kotlin.resolve.scopes.SyntheticScope
@@ -51,7 +51,8 @@ interface SamAdapterExtensionFunctionDescriptor : FunctionDescriptor, SyntheticM
class SamAdapterFunctionsScope( class SamAdapterFunctionsScope(
storageManager: StorageManager, storageManager: StorageManager,
private val languageVersionSettings: LanguageVersionSettings, private val languageVersionSettings: LanguageVersionSettings,
private val samResolver: SamConversionResolver private val samResolver: SamConversionResolver,
private val deprecationResolver: DeprecationResolver
) : SyntheticScope { ) : SyntheticScope {
private val extensionForFunction = storageManager.createMemoizedFunctionWithNullableValues<FunctionDescriptor, FunctionDescriptor> { function -> private val extensionForFunction = storageManager.createMemoizedFunctionWithNullableValues<FunctionDescriptor, FunctionDescriptor> { function ->
extensionForFunctionNotCached(function) extensionForFunctionNotCached(function)
@@ -83,7 +84,7 @@ class SamAdapterFunctionsScope(
if (!function.hasJavaOriginInHierarchy()) return null //TODO: should we go into base at all? if (!function.hasJavaOriginInHierarchy()) return null //TODO: should we go into base at all?
if (!SingleAbstractMethodUtils.isSamAdapterNecessary(function)) return null if (!SingleAbstractMethodUtils.isSamAdapterNecessary(function)) return null
if (function.returnType == null) 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) return MyFunctionDescriptor.create(function, samResolver)
} }
@@ -48,6 +48,7 @@ class LazyTopDownAnalyzer(
private val qualifiedExpressionResolver: QualifiedExpressionResolver, private val qualifiedExpressionResolver: QualifiedExpressionResolver,
private val identifierChecker: IdentifierChecker, private val identifierChecker: IdentifierChecker,
private val languageVersionSettings: LanguageVersionSettings, private val languageVersionSettings: LanguageVersionSettings,
private val deprecationResolver: DeprecationResolver,
private val classifierUsageCheckers: Iterable<ClassifierUsageChecker> private val classifierUsageCheckers: Iterable<ClassifierUsageChecker>
) { ) {
fun analyzeDeclarations( fun analyzeDeclarations(
@@ -215,7 +216,7 @@ class LazyTopDownAnalyzer(
resolveImportsInAllFiles(c) resolveImportsInAllFiles(c)
ClassifierUsageChecker.check(declarations, trace, languageVersionSettings, classifierUsageCheckers) ClassifierUsageChecker.check(declarations, trace, languageVersionSettings, deprecationResolver, classifierUsageCheckers)
return c return c
} }
@@ -60,7 +60,8 @@ class CallCompleter(
private val dataFlowAnalyzer: DataFlowAnalyzer, private val dataFlowAnalyzer: DataFlowAnalyzer,
private val callCheckers: Iterable<CallChecker>, private val callCheckers: Iterable<CallChecker>,
private val builtIns: KotlinBuiltIns, private val builtIns: KotlinBuiltIns,
private val languageVersionSettings: LanguageVersionSettings private val languageVersionSettings: LanguageVersionSettings,
private val deprecationResolver: DeprecationResolver
) { ) {
fun <D : CallableDescriptor> completeCall( fun <D : CallableDescriptor> completeCall(
context: BasicCallResolutionContext, context: BasicCallResolutionContext,
@@ -91,7 +92,7 @@ class CallCompleter(
if (calleeExpression != null && !calleeExpression.isFakeElement) calleeExpression if (calleeExpression != null && !calleeExpression.isFakeElement) calleeExpression
else resolvedCall.call.callElement else resolvedCall.call.callElement
val callCheckerContext = CallCheckerContext(context, languageVersionSettings) val callCheckerContext = CallCheckerContext(context, languageVersionSettings, deprecationResolver)
for (callChecker in callCheckers) { for (callChecker in callCheckers) {
callChecker.check(resolvedCall, reportOn, callCheckerContext) callChecker.check(resolvedCall, reportOn, callCheckerContext)
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve.calls.checkers
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.resolve.BindingTrace 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.context.ResolutionContext
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
@@ -37,7 +38,8 @@ interface CallChecker {
class CallCheckerContext( class CallCheckerContext(
val resolutionContext: ResolutionContext<*>, val resolutionContext: ResolutionContext<*>,
val trace: BindingTrace, val trace: BindingTrace,
val languageVersionSettings: LanguageVersionSettings val languageVersionSettings: LanguageVersionSettings,
val deprecationResolver: DeprecationResolver
) { ) {
val scope: LexicalScope val scope: LexicalScope
get() = resolutionContext.scope get() = resolutionContext.scope
@@ -48,7 +50,11 @@ class CallCheckerContext(
val isAnnotationContext: Boolean val isAnnotationContext: Boolean
get() = resolutionContext.isAnnotationContext 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. // Use this utility to avoid premature computation of deferred return type of a resolved callable descriptor.
@@ -29,27 +29,29 @@ import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
import org.jetbrains.kotlin.psi.KtReferenceExpression import org.jetbrains.kotlin.psi.KtReferenceExpression
import org.jetbrains.kotlin.psi.KtUnaryExpression import org.jetbrains.kotlin.psi.KtUnaryExpression
import org.jetbrains.kotlin.resolve.BindingTrace 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.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
import org.jetbrains.kotlin.resolve.createDeprecationDiagnostic import org.jetbrains.kotlin.resolve.createDeprecationDiagnostic
import org.jetbrains.kotlin.resolve.getDeprecations
object DeprecatedCallChecker : CallChecker { object DeprecatedCallChecker : CallChecker {
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) { 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( 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 // Objects will be checked by DeprecatedClassifierUsageChecker
if (targetDescriptor is FakeCallableDescriptorForObject) return 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 // avoid duplicating diagnostic when deprecation for property effectively deprecates setter
if (targetDescriptor is PropertySetterDescriptor) { if (targetDescriptor is PropertySetterDescriptor) {
deprecations -= targetDescriptor.correspondingProperty.getDeprecations(languageVersionSettings) deprecations -= deprecationResolver.getDeprecations(targetDescriptor.correspondingProperty)
} }
if (deprecations.isNotEmpty()) { if (deprecations.isNotEmpty()) {
@@ -58,7 +60,7 @@ object DeprecatedCallChecker : CallChecker {
} }
} }
else if (targetDescriptor is PropertyDescriptor && shouldCheckPropertyGetter(element)) { else if (targetDescriptor is PropertyDescriptor && shouldCheckPropertyGetter(element)) {
targetDescriptor.getter?.let { check(it, trace, element, languageVersionSettings) } targetDescriptor.getter?.let { check(it, trace, element, languageVersionSettings, deprecationResolver) }
} }
} }
@@ -16,10 +16,10 @@
package org.jetbrains.kotlin.resolve.calls.tower package org.jetbrains.kotlin.resolve.calls.tower
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.psi.KtSuperExpression import org.jetbrains.kotlin.psi.KtSuperExpression
import org.jetbrains.kotlin.resolve.DeprecationResolver
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isConventionCall import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isConventionCall
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isInfixCall 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.CallableReferenceKotlinCallArgument
import org.jetbrains.kotlin.resolve.calls.model.KotlinCall import org.jetbrains.kotlin.resolve.calls.model.KotlinCall
import org.jetbrains.kotlin.resolve.calls.model.SimpleKotlinCallArgument import org.jetbrains.kotlin.resolve.calls.model.SimpleKotlinCallArgument
import org.jetbrains.kotlin.resolve.isHiddenInResolution
import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.addToStdlib.safeAs
class KotlinResolutionStatelessCallbacksImpl( class KotlinResolutionStatelessCallbacksImpl(
private val languageVersionSettings: LanguageVersionSettings private val deprecationResolver: DeprecationResolver
) : KotlinResolutionStatelessCallbacks { ) : KotlinResolutionStatelessCallbacks {
override fun isDescriptorFromSource(descriptor: CallableDescriptor) = override fun isDescriptorFromSource(descriptor: CallableDescriptor) =
DescriptorToSourceUtils.descriptorToDeclaration(descriptor) != null DescriptorToSourceUtils.descriptorToDeclaration(descriptor) != null
@@ -48,7 +47,7 @@ class KotlinResolutionStatelessCallbacksImpl(
kotlinCall is PSIKotlinCallImpl && isSuperOrDelegatingConstructorCall(kotlinCall.psiCall) kotlinCall is PSIKotlinCallImpl && isSuperOrDelegatingConstructorCall(kotlinCall.psiCall)
override fun isHiddenInResolution(descriptor: DeclarationDescriptor, kotlinCall: KotlinCall) = override fun isHiddenInResolution(descriptor: DeclarationDescriptor, kotlinCall: KotlinCall) =
descriptor.isHiddenInResolution(languageVersionSettings, isSuperOrDelegatingConstructorCall(kotlinCall)) deprecationResolver.isHiddenInResolution(descriptor, isSuperOrDelegatingConstructorCall(kotlinCall))
override fun isSuperExpression(receiver: SimpleKotlinCallArgument?): Boolean = override fun isSuperExpression(receiver: SimpleKotlinCallArgument?): Boolean =
receiver?.psiExpression is KtSuperExpression receiver?.psiExpression is KtSuperExpression
@@ -58,4 +57,4 @@ class KotlinResolutionStatelessCallbacksImpl(
override fun getVariableCandidateIfInvoke(functionCall: KotlinCall) = override fun getVariableCandidateIfInvoke(functionCall: KotlinCall) =
functionCall.safeAs<PSIKotlinCallForInvoke>()?.variableCall functionCall.safeAs<PSIKotlinCallForInvoke>()?.variableCall
} }
@@ -66,10 +66,11 @@ class KotlinToResolvedCallTransformer(
private val dataFlowAnalyzer: DataFlowAnalyzer, private val dataFlowAnalyzer: DataFlowAnalyzer,
private val argumentTypeResolver: ArgumentTypeResolver, private val argumentTypeResolver: ArgumentTypeResolver,
private val constantExpressionEvaluator: ConstantExpressionEvaluator, private val constantExpressionEvaluator: ConstantExpressionEvaluator,
private val deprecationResolver: DeprecationResolver,
private val expressionTypingServices: ExpressionTypingServices, private val expressionTypingServices: ExpressionTypingServices,
private val doubleColonExpressionResolver: DoubleColonExpressionResolver, private val doubleColonExpressionResolver: DoubleColonExpressionResolver,
private val additionalDiagnosticReporter: AdditionalDiagnosticReporter private val additionalDiagnosticReporter: AdditionalDiagnosticReporter
) { ) {
fun <D : CallableDescriptor> onlyTransform( fun <D : CallableDescriptor> onlyTransform(
resolvedCallAtom: ResolvedCallAtom resolvedCallAtom: ResolvedCallAtom
@@ -90,7 +91,7 @@ class KotlinToResolvedCallTransformer(
val resultSubstitutor = baseResolvedCall.constraintSystem.buildResultingSubstitutor() val resultSubstitutor = baseResolvedCall.constraintSystem.buildResultingSubstitutor()
val ktPrimitiveCompleter = ResolvedAtomCompleter(resultSubstitutor, context.trace, context, this, val ktPrimitiveCompleter = ResolvedAtomCompleter(resultSubstitutor, context.trace, context, this,
expressionTypingServices, argumentTypeResolver, doubleColonExpressionResolver, expressionTypingServices, argumentTypeResolver, doubleColonExpressionResolver,
languageFeatureSettings) languageFeatureSettings, deprecationResolver)
for (subKtPrimitive in candidate.subResolvedAtoms) { for (subKtPrimitive in candidate.subResolvedAtoms) {
ktPrimitiveCompleter.completeAll(subKtPrimitive) ktPrimitiveCompleter.completeAll(subKtPrimitive)
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.Call import org.jetbrains.kotlin.psi.Call
import org.jetbrains.kotlin.psi.KtReferenceExpression import org.jetbrains.kotlin.psi.KtReferenceExpression
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DeprecationResolver
import org.jetbrains.kotlin.resolve.TemporaryBindingTrace import org.jetbrains.kotlin.resolve.TemporaryBindingTrace
import org.jetbrains.kotlin.resolve.calls.CallTransformer import org.jetbrains.kotlin.resolve.calls.CallTransformer
import org.jetbrains.kotlin.resolve.calls.CandidateResolver 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.callUtil.createLookupLocation
import org.jetbrains.kotlin.resolve.calls.context.* import org.jetbrains.kotlin.resolve.calls.context.*
import org.jetbrains.kotlin.resolve.calls.inference.CoroutineInferenceSupport 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.model.*
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResultsImpl import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResultsImpl
import org.jetbrains.kotlin.resolve.calls.results.ResolutionResultsHandler 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.smartcasts.DataFlowValueFactory
import org.jetbrains.kotlin.resolve.calls.tasks.* import org.jetbrains.kotlin.resolve.calls.tasks.*
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDynamicExtensionAnnotation 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.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
@@ -66,7 +67,8 @@ class NewResolutionOldInference(
private val dynamicCallableDescriptors: DynamicCallableDescriptors, private val dynamicCallableDescriptors: DynamicCallableDescriptors,
private val syntheticScopes: SyntheticScopes, private val syntheticScopes: SyntheticScopes,
private val languageVersionSettings: LanguageVersionSettings, private val languageVersionSettings: LanguageVersionSettings,
private val coroutineInferenceSupport: CoroutineInferenceSupport private val coroutineInferenceSupport: CoroutineInferenceSupport,
private val deprecationResolver: DeprecationResolver
) { ) {
sealed class ResolutionKind<D : CallableDescriptor>(val kotlinCallKind: KotlinCallKind = KotlinCallKind.UNSUPPORTED) { sealed class ResolutionKind<D : CallableDescriptor>(val kotlinCallKind: KotlinCallKind = KotlinCallKind.UNSUPPORTED) {
abstract internal fun createTowerProcessor( abstract internal fun createTowerProcessor(
@@ -200,7 +202,7 @@ class NewResolutionOldInference(
val candidateTrace = TemporaryBindingTrace.create(basicCallContext.trace, "Context for resolve candidate") val candidateTrace = TemporaryBindingTrace.create(basicCallContext.trace, "Context for resolve candidate")
val resolvedCall = ResolvedCallImpl.create(candidate, candidateTrace, tracing, basicCallContext.dataFlowInfoForArguments) 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) 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) return MyCandidate(listOf(HiddenDescriptor), candidateCall)
} }
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.DeprecationResolver
import org.jetbrains.kotlin.resolve.TemporaryBindingTrace import org.jetbrains.kotlin.resolve.TemporaryBindingTrace
import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver
import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext 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.ExplicitReceiverKind
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategyImpl import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategyImpl
import org.jetbrains.kotlin.resolve.calls.util.CallMaker 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.DoubleColonExpressionResolver
import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
@@ -51,9 +55,10 @@ class ResolvedAtomCompleter(
private val expressionTypingServices: ExpressionTypingServices, private val expressionTypingServices: ExpressionTypingServices,
private val argumentTypeResolver: ArgumentTypeResolver, private val argumentTypeResolver: ArgumentTypeResolver,
private val doubleColonExpressionResolver: DoubleColonExpressionResolver, 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) { fun completeAndReport(resolvedAtom: ResolvedAtom) {
when (resolvedAtom) { when (resolvedAtom) {
@@ -198,4 +203,4 @@ class ResolvedAtomCompleter(
expressionTypingServices.getTypeInfo(psiCallArgument.collectionLiteralExpression, actualContext) expressionTypingServices.getTypeInfo(psiCallArgument.collectionLiteralExpression, actualContext)
} }
} }
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.DeprecationResolver
import org.jetbrains.kotlin.resolve.checkSinceKotlinVersionAccessibility import org.jetbrains.kotlin.resolve.checkSinceKotlinVersionAccessibility
object ApiVersionClassifierUsageChecker : ClassifierUsageChecker { object ApiVersionClassifierUsageChecker : ClassifierUsageChecker {
@@ -28,7 +29,8 @@ object ApiVersionClassifierUsageChecker : ClassifierUsageChecker {
targetDescriptor: ClassifierDescriptor, targetDescriptor: ClassifierDescriptor,
trace: BindingTrace, trace: BindingTrace,
element: PsiElement, element: PsiElement,
languageVersionSettings: LanguageVersionSettings languageVersionSettings: LanguageVersionSettings,
deprecationResolver: DeprecationResolver
) { ) {
targetDescriptor.checkSinceKotlinVersionAccessibility(languageVersionSettings) { version -> targetDescriptor.checkSinceKotlinVersionAccessibility(languageVersionSettings) { version ->
trace.report(Errors.API_NOT_AVAILABLE.on(element, version.versionString, languageVersionSettings.apiVersion.versionString)) trace.report(Errors.API_NOT_AVAILABLE.on(element, version.versionString, languageVersionSettings.apiVersion.versionString))
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.psi.KtReferenceExpression
import org.jetbrains.kotlin.psi.KtTreeVisitorVoid import org.jetbrains.kotlin.psi.KtTreeVisitorVoid
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.DeprecationResolver
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.addToStdlib.safeAs
@@ -36,7 +37,8 @@ interface ClassifierUsageChecker {
targetDescriptor: ClassifierDescriptor, targetDescriptor: ClassifierDescriptor,
trace: BindingTrace, trace: BindingTrace,
element: PsiElement, element: PsiElement,
languageVersionSettings: LanguageVersionSettings languageVersionSettings: LanguageVersionSettings,
deprecationResolver: DeprecationResolver
) )
companion object { companion object {
@@ -44,6 +46,7 @@ interface ClassifierUsageChecker {
declarations: Collection<PsiElement>, declarations: Collection<PsiElement>,
trace: BindingTrace, trace: BindingTrace,
languageVersionSettings: LanguageVersionSettings, languageVersionSettings: LanguageVersionSettings,
deprecationResolver: DeprecationResolver,
checkers: Iterable<ClassifierUsageChecker> checkers: Iterable<ClassifierUsageChecker>
) { ) {
val visitor = object : KtTreeVisitorVoid() { val visitor = object : KtTreeVisitorVoid() {
@@ -71,7 +74,7 @@ interface ClassifierUsageChecker {
private fun runCheckersWithTarget(target: ClassifierDescriptor, expression: KtReferenceExpression) { private fun runCheckersWithTarget(target: ClassifierDescriptor, expression: KtReferenceExpression) {
for (checker in checkers) { for (checker in checkers) {
checker.check(target, trace, expression, languageVersionSettings) checker.check(target, trace, expression, languageVersionSettings, deprecationResolver)
} }
} }
@@ -21,18 +21,19 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.psi.KtThisExpression import org.jetbrains.kotlin.psi.KtThisExpression
import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.DeprecationResolver
import org.jetbrains.kotlin.resolve.createDeprecationDiagnostic import org.jetbrains.kotlin.resolve.createDeprecationDiagnostic
import org.jetbrains.kotlin.resolve.getDeprecations
class DeprecatedClassifierUsageChecker : ClassifierUsageChecker { class DeprecatedClassifierUsageChecker : ClassifierUsageChecker {
override fun check( override fun check(
targetDescriptor: ClassifierDescriptor, targetDescriptor: ClassifierDescriptor,
trace: BindingTrace, trace: BindingTrace,
element: PsiElement, element: PsiElement,
languageVersionSettings: LanguageVersionSettings languageVersionSettings: LanguageVersionSettings,
deprecationResolver: DeprecationResolver
) { ) {
if (element.parent is KtThisExpression) return if (element.parent is KtThisExpression) return
for (deprecation in targetDescriptor.getDeprecations(languageVersionSettings)) { for (deprecation in deprecationResolver.getDeprecations(targetDescriptor)) {
trace.report(createDeprecationDiagnostic(element, deprecation, languageVersionSettings)) trace.report(createDeprecationDiagnostic(element, deprecation, languageVersionSettings))
} }
} }
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.Errors.* import org.jetbrains.kotlin.diagnostics.Errors.*
import org.jetbrains.kotlin.resolve.BindingTrace 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.CallChecker
import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext
import org.jetbrains.kotlin.resolve.calls.checkers.isComputingDeferredType import org.jetbrains.kotlin.resolve.calls.checkers.isComputingDeferredType
@@ -95,7 +96,8 @@ object MissingDependencyClassChecker : CallChecker {
targetDescriptor: ClassifierDescriptor, targetDescriptor: ClassifierDescriptor,
trace: BindingTrace, trace: BindingTrace,
element: PsiElement, element: PsiElement,
languageVersionSettings: LanguageVersionSettings languageVersionSettings: LanguageVersionSettings,
deprecationResolver: DeprecationResolver
) { ) {
diagnosticFor(targetDescriptor, element)?.let(trace::report) diagnosticFor(targetDescriptor, element)?.let(trace::report)
@@ -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.DeserializedClassDescriptor
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedMemberDescriptor import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedMemberDescriptor
import org.jetbrains.kotlin.serialization.deserialization.descriptors.SinceKotlinInfo 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.KotlinType
import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.utils.SmartList import org.jetbrains.kotlin.utils.SmartList
@@ -146,133 +147,6 @@ private fun Deprecation.wrapInTypeAliasExpansion(typeAliasDescriptor: TypeAliasD
else -> this else -> this
} }
fun DeclarationDescriptor.getDeprecations(languageVersionSettings: LanguageVersionSettings): List<Deprecation> {
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<Deprecation> =
SmartList<Deprecation>().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<CallableMemberDescriptor>()
val deprecations = LinkedHashSet<Deprecation>()
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<Deprecation> {
// 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<Deprecation>()
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( internal fun createDeprecationDiagnostic(
element: PsiElement, deprecation: Deprecation, languageVersionSettings: LanguageVersionSettings element: PsiElement, deprecation: Deprecation, languageVersionSettings: LanguageVersionSettings
): Diagnostic { ): Diagnostic {
@@ -310,17 +184,157 @@ enum class DeprecationLevelValue {
WARNING, ERROR, HIDDEN WARNING, ERROR, HIDDEN
} }
fun DeclarationDescriptor.isDeprecatedHidden(languageVersionSettings: LanguageVersionSettings): Boolean = class DeprecationResolver(
getDeprecations(languageVersionSettings).any { it.deprecationLevel == HIDDEN } storageManager: StorageManager,
private val languageVersionSettings: LanguageVersionSettings
@JvmOverloads ) {
fun DeclarationDescriptor.isHiddenInResolution(languageVersionSettings: LanguageVersionSettings, isSuperCall: Boolean = false): Boolean { private val deprecations = storageManager.createMemoizedFunction { descriptor: DeclarationDescriptor ->
if (this is FunctionDescriptor) { val deprecations = descriptor.getOwnDeprecations()
if (isHiddenToOvercomeSignatureClash) return true when {
if (isHiddenForResolutionEverywhereBesideSupercalls && !isSuperCall) return true 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<Deprecation> =
SmartList<Deprecation>().also { deprecations ->
TypeUtils.contains(this) { type ->
type.constructor.declarationDescriptor?.let {
deprecations.addAll(getDeprecations(it))
}
false
}
}
private fun deprecationByOverridden(root: CallableMemberDescriptor): Deprecation? {
val visited = HashSet<CallableMemberDescriptor>()
val deprecations = LinkedHashSet<Deprecation>()
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<Deprecation> {
// 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<Deprecation>()
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()
}
} }
@@ -26,10 +26,7 @@ import org.jetbrains.kotlin.platform.PlatformToKotlinClassMap
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtImportDirective import org.jetbrains.kotlin.psi.KtImportDirective
import org.jetbrains.kotlin.psi.KtImportsFactory import org.jetbrains.kotlin.psi.KtImportsFactory
import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.ImportPath
import org.jetbrains.kotlin.resolve.QualifiedExpressionResolver
import org.jetbrains.kotlin.resolve.TemporaryBindingTrace
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.ImportingScope import org.jetbrains.kotlin.resolve.scopes.ImportingScope
import org.jetbrains.kotlin.resolve.scopes.LexicalScope import org.jetbrains.kotlin.resolve.scopes.LexicalScope
@@ -51,7 +48,8 @@ class FileScopeFactory(
private val ktImportsFactory: KtImportsFactory, private val ktImportsFactory: KtImportsFactory,
private val platformToKotlinClassMap: PlatformToKotlinClassMap, private val platformToKotlinClassMap: PlatformToKotlinClassMap,
private val defaultImportProvider: DefaultImportProvider, 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) */ /* avoid constructing psi for default imports prematurely (time consuming in some scenarios) */
private val defaultImports by storageManager.createLazyValue { private val defaultImports by storageManager.createLazyValue {
@@ -112,7 +110,8 @@ class FileScopeFactory(
fun createImportResolver(indexedImports: IndexedImports, trace: BindingTrace, excludedImports: List<FqName>? = null) = fun createImportResolver(indexedImports: IndexedImports, trace: BindingTrace, excludedImports: List<FqName>? = null) =
LazyImportResolver( LazyImportResolver(
storageManager, qualifiedExpressionResolver, moduleDescriptor, platformToKotlinClassMap, languageVersionSettings, storageManager, qualifiedExpressionResolver, moduleDescriptor, platformToKotlinClassMap, languageVersionSettings,
indexedImports, aliasImportNames concat excludedImports, trace, packageFragment indexedImports, aliasImportNames concat excludedImports, trace, packageFragment,
deprecationResolver
) )
@@ -81,7 +81,8 @@ class LazyImportResolver(
val indexedImports: IndexedImports, val indexedImports: IndexedImports,
excludedImportNames: Collection<FqName>, excludedImportNames: Collection<FqName>,
private val traceForImportResolve: BindingTrace, private val traceForImportResolve: BindingTrace,
private val packageFragment: PackageFragmentDescriptor private val packageFragment: PackageFragmentDescriptor,
val deprecationResolver: DeprecationResolver
) : ImportResolver { ) : ImportResolver {
private val importedScopesProvider = storageManager.createMemoizedFunctionWithNullableValues { private val importedScopesProvider = storageManager.createMemoizedFunctionWithNullableValues {
directive: KtImportDirective -> directive: KtImportDirective ->
@@ -208,7 +209,7 @@ class LazyImportScope(
private fun isClassifierVisible(descriptor: ClassifierDescriptor): Boolean { private fun isClassifierVisible(descriptor: ClassifierDescriptor): Boolean {
if (filteringKind == FilteringKind.ALL) return true 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 visibility = (descriptor as DeclarationDescriptorWithVisibility).visibility
val includeVisible = filteringKind == FilteringKind.VISIBLE_CLASSES val includeVisible = filteringKind == FilteringKind.VISIBLE_CLASSES
@@ -633,7 +633,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
trace.record(CALL, expression, call); trace.record(CALL, expression, call);
if (context.trace.wantsDiagnostics()) { if (context.trace.wantsDiagnostics()) {
CallCheckerContext callCheckerContext = new CallCheckerContext(context, components.languageVersionSettings); CallCheckerContext callCheckerContext =
createCallCheckerContext(context);
for (CallChecker checker : components.callCheckers) { for (CallChecker checker : components.callCheckers) {
checker.check(resolvedCall, expression, callCheckerContext); checker.check(resolvedCall, expression, callCheckerContext);
} }
@@ -934,7 +935,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
if (resolvedCall != null && trace.wantsDiagnostics()) { if (resolvedCall != null && trace.wantsDiagnostics()) {
// Call must be validated with the actual, not temporary trace in order to report operator diagnostic // 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 // 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) { for (CallChecker checker : components.callCheckers) {
checker.check(resolvedCall, expression, callCheckerContext); checker.check(resolvedCall, expression, callCheckerContext);
} }
@@ -1001,13 +1003,19 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
resolvedCall.markCallAsCompleted(); resolvedCall.markCallAsCompleted();
if (context.trace.wantsDiagnostics()) { if (context.trace.wantsDiagnostics()) {
CallCheckerContext callCheckerContext = new CallCheckerContext(context, components.languageVersionSettings); CallCheckerContext callCheckerContext =
createCallCheckerContext(context);
for (CallChecker checker : components.callCheckers) { for (CallChecker checker : components.callCheckers) {
checker.check(resolvedCall, expression, callCheckerContext); checker.check(resolvedCall, expression, callCheckerContext);
} }
} }
} }
@NotNull
private CallCheckerContext createCallCheckerContext(@NotNull ExpressionTypingContext context) {
return new CallCheckerContext(context, components.languageVersionSettings, components.deprecationResolver);
}
@Override @Override
public KotlinTypeInfo visitBinaryExpression(@NotNull KtBinaryExpression expression, ExpressionTypingContext contextWithExpectedType) { public KotlinTypeInfo visitBinaryExpression(@NotNull KtBinaryExpression expression, ExpressionTypingContext contextWithExpectedType) {
ExpressionTypingContext context = isBinaryExpressionDependentOnExpectedType(expression) ExpressionTypingContext context = isBinaryExpressionDependentOnExpectedType(expression)
@@ -63,6 +63,7 @@ public class ExpressionTypingComponents {
/*package*/ Iterable<RttiExpressionChecker> rttiExpressionCheckers; /*package*/ Iterable<RttiExpressionChecker> rttiExpressionCheckers;
/*package*/ WrappedTypeFactory wrappedTypeFactory; /*package*/ WrappedTypeFactory wrappedTypeFactory;
/*package*/ CollectionLiteralResolver collectionLiteralResolver; /*package*/ CollectionLiteralResolver collectionLiteralResolver;
/*package*/ DeprecationResolver deprecationResolver;
@Inject @Inject
public void setGlobalContext(@NotNull GlobalContext globalContext) { public void setGlobalContext(@NotNull GlobalContext globalContext) {
@@ -213,4 +214,9 @@ public class ExpressionTypingComponents {
public void setCollectionLiteralResolver(CollectionLiteralResolver collectionLiteralResolver) { public void setCollectionLiteralResolver(CollectionLiteralResolver collectionLiteralResolver) {
this.collectionLiteralResolver = collectionLiteralResolver; this.collectionLiteralResolver = collectionLiteralResolver;
} }
@Inject
public void setDeprecationResolver(DeprecationResolver deprecationResolver) {
this.deprecationResolver = deprecationResolver;
}
} }
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.idea.codeInsight package org.jetbrains.kotlin.idea.codeInsight
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.resolve.frontendService 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.KtVariableDeclaration
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DeprecationResolver
import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfoBefore import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfoBefore
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension 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.*
import org.jetbrains.kotlin.resolve.scopes.receivers.ClassQualifier import org.jetbrains.kotlin.resolve.scopes.receivers.ClassQualifier
import org.jetbrains.kotlin.resolve.scopes.utils.collectAllFromMeAndParent import org.jetbrains.kotlin.resolve.scopes.utils.collectAllFromMeAndParent
@@ -77,7 +76,7 @@ class ReferenceVariantsHelper(
): Collection<DeclarationDescriptor> { ): Collection<DeclarationDescriptor> {
var variants: Collection<DeclarationDescriptor> var variants: Collection<DeclarationDescriptor>
= getReferenceVariantsNoVisibilityFilter(contextElement, kindFilter, nameFilter, callTypeAndReceiver, useReceiverType) = getReferenceVariantsNoVisibilityFilter(contextElement, kindFilter, nameFilter, callTypeAndReceiver, useReceiverType)
.filter { !it.isHiddenInResolution(resolutionFacade.frontendService<LanguageVersionSettings>()) && visibilityFilter(it) } .filter { !resolutionFacade.frontendService<DeprecationResolver>().isHiddenInResolution(it) && visibilityFilter(it) }
if (filterOutShadowed) { if (filterOutShadowed) {
ShadowedDeclarationsFilter.create(bindingContext, resolutionFacade, contextElement, callTypeAndReceiver)?.let { ShadowedDeclarationsFilter.create(bindingContext, resolutionFacade, contextElement, callTypeAndReceiver)?.let {
@@ -415,4 +414,4 @@ fun ResolutionScope.collectSyntheticStaticMembersAndConstructors(
val syntheticScopes = resolutionFacade.getFrontendService(SyntheticScopes::class.java) val syntheticScopes = resolutionFacade.getFrontendService(SyntheticScopes::class.java)
return (syntheticScopes.collectSyntheticStaticFunctions(this) + syntheticScopes.collectSyntheticConstructors(this)) return (syntheticScopes.collectSyntheticStaticFunctions(this) + syntheticScopes.collectSyntheticConstructors(this))
.filter { kindFilter.accepts(it) && nameFilter(it.name) } .filter { kindFilter.accepts(it) && nameFilter(it.name) }
} }
@@ -24,7 +24,6 @@ import com.intellij.psi.search.PsiShortNamesCache
import com.intellij.psi.stubs.StringStubIndexExtension import com.intellij.psi.stubs.StringStubIndexExtension
import com.intellij.util.indexing.IdFilter import com.intellij.util.indexing.IdFilter
import org.jetbrains.kotlin.asJava.elements.KtLightElement import org.jetbrains.kotlin.asJava.elements.KtLightElement
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.caches.KotlinShortNamesCache import org.jetbrains.kotlin.idea.caches.KotlinShortNamesCache
import org.jetbrains.kotlin.idea.caches.resolve.* 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.*
import org.jetbrains.kotlin.psi.psiUtil.contains import org.jetbrains.kotlin.psi.psiUtil.contains
import org.jetbrains.kotlin.resolve.BindingContext 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.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
import org.jetbrains.kotlin.resolve.scopes.collectSyntheticStaticFunctions import org.jetbrains.kotlin.resolve.scopes.collectSyntheticStaticFunctions
@@ -68,7 +67,7 @@ class KotlinIndicesHelper(
private val scopeWithoutKotlin = scope.excludeKotlinSources() as GlobalSearchScope private val scopeWithoutKotlin = scope.excludeKotlinSources() as GlobalSearchScope
private val descriptorFilter: (DeclarationDescriptor) -> Boolean = filter@ { private val descriptorFilter: (DeclarationDescriptor) -> Boolean = filter@ {
if (it.isHiddenInResolution(resolutionFacade.frontendService<LanguageVersionSettings>())) return@filter false if (resolutionFacade.frontendService<DeprecationResolver>().isHiddenInResolution(it)) return@filter false
if (!visibilityFilter(it)) return@filter false if (!visibilityFilter(it)) return@filter false
if (applyExcludeSettings && it.isExcludedFromAutoImport(project, file)) return@filter false if (applyExcludeSettings && it.isExcludedFromAutoImport(project, file)) return@filter false
true true
@@ -27,7 +27,6 @@ import com.intellij.psi.PsiManager
import com.intellij.psi.PsiWhiteSpace import com.intellij.psi.PsiWhiteSpace
import org.jetbrains.kotlin.asJava.LightClassUtil import org.jetbrains.kotlin.asJava.LightClassUtil
import org.jetbrains.kotlin.asJava.elements.KtLightDeclaration import org.jetbrains.kotlin.asJava.elements.KtLightDeclaration
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade 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.findKDoc
import org.jetbrains.kotlin.idea.kdoc.isBoringBuiltinClass import org.jetbrains.kotlin.idea.kdoc.isBoringBuiltinClass
import org.jetbrains.kotlin.idea.kdoc.resolveKDocLink 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.references.mainReference
import org.jetbrains.kotlin.idea.resolve.frontendService
import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
import org.jetbrains.kotlin.kdoc.psi.api.KDoc import org.jetbrains.kotlin.kdoc.psi.api.KDoc
import org.jetbrains.kotlin.kdoc.psi.impl.KDocSection 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.ClassifierNamePolicy
import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DeprecationResolver
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.deprecatedByAnnotationReplaceWithExpression import org.jetbrains.kotlin.resolve.deprecatedByAnnotationReplaceWithExpression
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
import org.jetbrains.kotlin.resolve.getDeprecations
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.utils.addToStdlib.constant import org.jetbrains.kotlin.utils.addToStdlib.constant
@@ -246,20 +245,20 @@ class KotlinQuickDocumentationProvider : AbstractDocumentationProvider() {
return "No documentation available" 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? { private fun renderKotlinImplicitLambdaParameter(element: KtReferenceExpression, quickNavigation: Boolean): String? {
val context = element.analyze(BodyResolveMode.PARTIAL) val context = element.analyze(BodyResolveMode.PARTIAL)
val target = element.mainReference.resolveToDescriptors(context).singleOrNull() as? ValueParameterDescriptor? ?: return null 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( private fun renderKotlin(
context: BindingContext, context: BindingContext,
declarationDescriptor: DeclarationDescriptor, declarationDescriptor: DeclarationDescriptor,
quickNavigation: Boolean, quickNavigation: Boolean,
languageVersionSettings: LanguageVersionSettings ktElement: KtElement
): String { ): String {
@Suppress("NAME_SHADOWING") @Suppress("NAME_SHADOWING")
var declarationDescriptor = declarationDescriptor var declarationDescriptor = declarationDescriptor
@@ -278,7 +277,8 @@ class KotlinQuickDocumentationProvider : AbstractDocumentationProvider() {
renderedDecl = "<pre>$renderedDecl</pre>" renderedDecl = "<pre>$renderedDecl</pre>"
} }
renderedDecl += renderDeprecationInfo(declarationDescriptor, languageVersionSettings) val deprecationProvider = ktElement.getResolutionFacade().frontendService<DeprecationResolver>()
renderedDecl += renderDeprecationInfo(declarationDescriptor, deprecationProvider)
if (!quickNavigation) { if (!quickNavigation) {
val comment = declarationDescriptor.findKDoc() val comment = declarationDescriptor.findKDoc()
@@ -310,9 +310,9 @@ class KotlinQuickDocumentationProvider : AbstractDocumentationProvider() {
private fun renderDeprecationInfo( private fun renderDeprecationInfo(
declarationDescriptor: DeclarationDescriptor, declarationDescriptor: DeclarationDescriptor,
languageVersionSettings: LanguageVersionSettings deprecationResolver: DeprecationResolver
): String { ): String {
val deprecation = declarationDescriptor.getDeprecations(languageVersionSettings).firstOrNull() ?: return "" val deprecation = deprecationResolver.getDeprecations(declarationDescriptor).firstOrNull() ?: return ""
return buildString { return buildString {
wrapTag("DL") { wrapTag("DL") {
@@ -30,7 +30,6 @@ import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.searches.ReferencesSearch import com.intellij.psi.search.searches.ReferencesSearch
import com.intellij.ui.GuiUtils import com.intellij.ui.GuiUtils
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyze 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.*
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.renderer.render 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.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess 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.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
import org.jetbrains.kotlin.resolve.scopes.collectSyntheticExtensionProperties import org.jetbrains.kotlin.resolve.scopes.collectSyntheticExtensionProperties
@@ -76,7 +75,7 @@ class ConflictingExtensionPropertyInspection : AbstractKotlinInspection(), Clean
val conflictingExtension = conflictingSyntheticExtension(propertyDescriptor, syntheticScopes) ?: return val conflictingExtension = conflictingSyntheticExtension(propertyDescriptor, syntheticScopes) ?: return
// don't report on hidden declarations // don't report on hidden declarations
if (propertyDescriptor.isHiddenInResolution(resolutionFacade.frontendService<LanguageVersionSettings>())) return if (resolutionFacade.frontendService<DeprecationResolver>().isHiddenInResolution(propertyDescriptor)) return
val fixes = createFixes(property, conflictingExtension, isOnTheFly) val fixes = createFixes(property, conflictingExtension, isOnTheFly)
@@ -251,4 +250,4 @@ class ConflictingExtensionPropertyInspection : AbstractKotlinInspection(), Clean
} }
} }
} }
} }
@@ -21,14 +21,15 @@ import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.PsiElementVisitor import com.intellij.psi.PsiElementVisitor
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor 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.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.KtDeclaration
import org.jetbrains.kotlin.psi.KtNamedDeclaration import org.jetbrains.kotlin.psi.KtNamedDeclaration
import org.jetbrains.kotlin.psi.KtPropertyAccessor import org.jetbrains.kotlin.psi.KtPropertyAccessor
import org.jetbrains.kotlin.psi.KtVisitorVoid import org.jetbrains.kotlin.psi.KtVisitorVoid
import org.jetbrains.kotlin.resolve.DeprecationResolver
import org.jetbrains.kotlin.resolve.deprecatedByOverriddenMessage import org.jetbrains.kotlin.resolve.deprecatedByOverriddenMessage
import org.jetbrains.kotlin.resolve.getDeprecations
class OverridingDeprecatedMemberInspection : AbstractKotlinInspection() { class OverridingDeprecatedMemberInspection : AbstractKotlinInspection() {
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
@@ -44,7 +45,9 @@ class OverridingDeprecatedMemberInspection : AbstractKotlinInspection() {
private fun registerProblemIfNeeded(declaration: KtDeclaration, targetForProblem: PsiElement) { private fun registerProblemIfNeeded(declaration: KtDeclaration, targetForProblem: PsiElement) {
val accessorDescriptor = declaration.resolveToDescriptorIfAny() as? CallableMemberDescriptor ?: return val accessorDescriptor = declaration.resolveToDescriptorIfAny() as? CallableMemberDescriptor ?: return
val message = accessorDescriptor.getDeprecations(declaration.languageVersionSettings) val deprecationProvider = declaration.getResolutionFacade().frontendService<DeprecationResolver>()
val message = deprecationProvider.getDeprecations(accessorDescriptor)
.firstOrNull() .firstOrNull()
?.deprecatedByOverriddenMessage() ?: return ?.deprecatedByOverriddenMessage() ?: return
val problem = holder.manager.createProblemDescriptor( val problem = holder.manager.createProblemDescriptor(