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.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;
@@ -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
@@ -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) {
@@ -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) {
@@ -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)
)
}
@@ -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<FunctionDescriptor, FunctionDescriptor> { 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)
}
@@ -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<ClassifierUsageChecker>
) {
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
}
@@ -60,7 +60,8 @@ class CallCompleter(
private val dataFlowAnalyzer: DataFlowAnalyzer,
private val callCheckers: Iterable<CallChecker>,
private val builtIns: KotlinBuiltIns,
private val languageVersionSettings: LanguageVersionSettings
private val languageVersionSettings: LanguageVersionSettings,
private val deprecationResolver: DeprecationResolver
) {
fun <D : CallableDescriptor> 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)
@@ -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.
@@ -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) }
}
}
@@ -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<PSIKotlinCallForInvoke>()?.variableCall
}
}
@@ -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 <D : CallableDescriptor> 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)
@@ -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<D : CallableDescriptor>(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)
}
@@ -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)
}
}
}
@@ -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))
@@ -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<PsiElement>,
trace: BindingTrace,
languageVersionSettings: LanguageVersionSettings,
deprecationResolver: DeprecationResolver,
checkers: Iterable<ClassifierUsageChecker>
) {
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)
}
}
@@ -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))
}
}
@@ -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)
@@ -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<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(
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<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.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<FqName>? = null) =
LazyImportResolver(
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,
excludedImportNames: Collection<FqName>,
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
@@ -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)
@@ -63,6 +63,7 @@ public class ExpressionTypingComponents {
/*package*/ Iterable<RttiExpressionChecker> 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;
}
}
@@ -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<DeclarationDescriptor> {
var variants: Collection<DeclarationDescriptor>
= getReferenceVariantsNoVisibilityFilter(contextElement, kindFilter, nameFilter, callTypeAndReceiver, useReceiverType)
.filter { !it.isHiddenInResolution(resolutionFacade.frontendService<LanguageVersionSettings>()) && visibilityFilter(it) }
.filter { !resolutionFacade.frontendService<DeprecationResolver>().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) }
}
}
@@ -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<LanguageVersionSettings>())) return@filter false
if (resolutionFacade.frontendService<DeprecationResolver>().isHiddenInResolution(it)) return@filter false
if (!visibilityFilter(it)) return@filter false
if (applyExcludeSettings && it.isExcludedFromAutoImport(project, file)) return@filter false
true
@@ -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 = "<pre>$renderedDecl</pre>"
}
renderedDecl += renderDeprecationInfo(declarationDescriptor, languageVersionSettings)
val deprecationProvider = ktElement.getResolutionFacade().frontendService<DeprecationResolver>()
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") {
@@ -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<LanguageVersionSettings>())) return
if (resolutionFacade.frontendService<DeprecationResolver>().isHiddenInResolution(propertyDescriptor)) return
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.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<DeprecationResolver>()
val message = deprecationProvider.getDeprecations(accessorDescriptor)
.firstOrNull()
?.deprecatedByOverriddenMessage() ?: return
val problem = holder.manager.createProblemDescriptor(