From ceb54492e6896c452ae3fafe30a15a5542eb0391 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 5 Jul 2016 18:58:33 +0300 Subject: [PATCH] Get rid of CallChecker#checkPropertyCall, create fake ResolvedCall --- ...otectedInSuperClassCompanionCallChecker.kt | 10 +---- .../resolve/calls/checkers/CallChecker.kt | 10 ----- .../calls/checkers/DeprecatedCallChecker.kt | 7 +--- .../resolve/calls/checkers/InlineChecker.java | 7 ---- ...ifiedTypeParameterSubstitutionChecker.java | 12 ++---- .../BasicExpressionTypingVisitor.java | 37 ++++++++++++++++--- 6 files changed, 38 insertions(+), 45 deletions(-) diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/ProtectedInSuperClassCompanionCallChecker.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/ProtectedInSuperClassCompanionCallChecker.kt index 33bd2bf9a06..a0edbb71d23 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/ProtectedInSuperClassCompanionCallChecker.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/ProtectedInSuperClassCompanionCallChecker.kt @@ -17,9 +17,7 @@ package org.jetbrains.kotlin.resolve.jvm.checkers import com.intellij.psi.PsiElement -import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.annotations.hasJvmStaticAnnotation @@ -31,14 +29,8 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm class ProtectedInSuperClassCompanionCallChecker : CallChecker { override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) { - check(resolvedCall.resultingDescriptor.original, reportOn, context) - } + val targetDescriptor = resolvedCall.resultingDescriptor.original - override fun checkPropertyCall(descriptor: PropertyAccessorDescriptor, reportOn: PsiElement, context: CallCheckerContext) { - check(descriptor, reportOn, context) - } - - private fun check(targetDescriptor: CallableDescriptor, reportOn: PsiElement, context: CallCheckerContext) { // Protected non-JVM static if (targetDescriptor.visibility != Visibilities.PROTECTED) return if (targetDescriptor.hasJvmStaticAnnotation()) return diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/CallChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/CallChecker.kt index ed9a2d48164..470f0a1bed7 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/CallChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/CallChecker.kt @@ -18,7 +18,6 @@ package org.jetbrains.kotlin.resolve.calls.checkers import com.intellij.psi.PsiElement import org.jetbrains.kotlin.config.LanguageFeatureSettings -import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall @@ -33,15 +32,6 @@ interface CallChecker { * Logic of the checker should not depend on what element is the target of the diagnostic! */ fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) - - /** - * This method is needed because for the simple assignment expression like "a = b" there is no resolved call that points to a's setter - * (the only resolved call is the one pointing to the property 'a' itself). So [check] which takes [ResolvedCall] is not applicable here - * - * TODO: construct a special ResolvedCall instead and call [check] - */ - fun checkPropertyCall(descriptor: PropertyAccessorDescriptor, reportOn: PsiElement, context: CallCheckerContext) { - } } class CallCheckerContext( diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/DeprecatedCallChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/DeprecatedCallChecker.kt index 6eabae1752d..80c6162fe6b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/DeprecatedCallChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/DeprecatedCallChecker.kt @@ -20,7 +20,6 @@ import com.intellij.psi.PsiElement import com.intellij.psi.tree.TokenSet import com.intellij.psi.util.PsiTreeUtil import org.jetbrains.kotlin.descriptors.CallableDescriptor -import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.PropertySetterDescriptor import org.jetbrains.kotlin.lexer.KtTokens @@ -38,11 +37,7 @@ object DeprecatedCallChecker : CallChecker { check(resolvedCall.resultingDescriptor, context.trace, reportOn) } - override fun checkPropertyCall(descriptor: PropertyAccessorDescriptor, reportOn: PsiElement, context: CallCheckerContext) { - check(descriptor, context.trace, reportOn) - } - - internal fun check(targetDescriptor: CallableDescriptor, trace: BindingTrace, element: PsiElement) { + private fun check(targetDescriptor: CallableDescriptor, trace: BindingTrace, element: PsiElement) { val deprecation = targetDescriptor.getDeprecation() // avoid duplicating diagnostic when deprecation for property effectively deprecates setter diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/InlineChecker.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/InlineChecker.java index 2e9fcf4ddd1..e4f766a9022 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/InlineChecker.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/InlineChecker.java @@ -65,13 +65,6 @@ class InlineChecker implements CallChecker { } } - @Override - public void checkPropertyCall( - @NotNull PropertyAccessorDescriptor descriptor, @NotNull PsiElement reportOn, @NotNull CallCheckerContext context - ) { - CallChecker.DefaultImpls.checkPropertyCall(this, descriptor, reportOn, context); - } - @Override public void check(@NotNull ResolvedCall resolvedCall, @NotNull PsiElement reportOn, @NotNull CallCheckerContext context) { KtExpression expression = resolvedCall.getCall().getCalleeExpression(); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/ReifiedTypeParameterSubstitutionChecker.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/ReifiedTypeParameterSubstitutionChecker.java index 7a9f2d78a68..f8e3bbc9723 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/ReifiedTypeParameterSubstitutionChecker.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/ReifiedTypeParameterSubstitutionChecker.java @@ -20,7 +20,10 @@ import com.intellij.psi.PsiElement; import kotlin.collections.CollectionsKt; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.builtins.KotlinBuiltIns; -import org.jetbrains.kotlin.descriptors.*; +import org.jetbrains.kotlin.descriptors.ClassDescriptor; +import org.jetbrains.kotlin.descriptors.ClassifierDescriptor; +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor; +import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor; import org.jetbrains.kotlin.diagnostics.Errors; import org.jetbrains.kotlin.psi.KtTypeProjection; import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; @@ -30,13 +33,6 @@ import org.jetbrains.kotlin.types.typeUtil.TypeUtilsKt; import java.util.Map; public class ReifiedTypeParameterSubstitutionChecker implements CallChecker { - @Override - public void checkPropertyCall( - @NotNull PropertyAccessorDescriptor descriptor, @NotNull PsiElement reportOn, @NotNull CallCheckerContext context - ) { - CallChecker.DefaultImpls.checkPropertyCall(this, descriptor, reportOn, context); - } - @Override public void check(@NotNull ResolvedCall resolvedCall, @NotNull PsiElement reportOn, @NotNull CallCheckerContext context) { Map typeArguments = resolvedCall.getTypeArguments(); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java index 1806780ba48..6b1efdff635 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java @@ -34,10 +34,12 @@ import org.jetbrains.kotlin.lexer.KtKeywordToken; import org.jetbrains.kotlin.lexer.KtTokens; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.psi.*; +import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt; import org.jetbrains.kotlin.resolve.*; import org.jetbrains.kotlin.resolve.bindingContextUtil.BindingContextUtilsKt; import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver; import org.jetbrains.kotlin.resolve.calls.CallExpressionResolver; +import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt; import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker; import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext; import org.jetbrains.kotlin.resolve.calls.model.DataFlowInfoForArgumentsImpl; @@ -943,11 +945,10 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { result = false; } else if (setter != null) { - CallCheckerContext callCheckerContext = - new CallCheckerContext(trace, context.scope, components.languageFeatureSettings, context.dataFlowInfo, false); - for (CallChecker checker : components.callCheckers) { - checker.checkPropertyCall(setter, reportOn, callCheckerContext); - } + ResolvedCall resolvedCall = CallUtilKt.getResolvedCall(expressionWithParenthesis, context.trace.getBindingContext()); + assert resolvedCall != null + : "Call is not resolved for property setter: " + PsiUtilsKt.getElementTextWithContext(expressionWithParenthesis); + checkPropertySetterCall(context.replaceBindingTrace(trace), setter, resolvedCall, reportOn); } } @@ -962,6 +963,32 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { return result; } + private void checkPropertySetterCall( + @NotNull ExpressionTypingContext context, + @NotNull PropertySetterDescriptor descriptor, + @NotNull ResolvedCall propertyResolvedCall, + @NotNull KtExpression expression + ) { + Call call = propertyResolvedCall.getCall(); + + ResolutionCandidate resolutionCandidate = ResolutionCandidate.create( + call, descriptor, propertyResolvedCall.getDispatchReceiver(), propertyResolvedCall.getExplicitReceiverKind(), null + ); + + ResolvedCallImpl resolvedCall = ResolvedCallImpl.create( + resolutionCandidate, + TemporaryBindingTrace.create(context.trace, "Trace for fake property setter resolved call"), + TracingStrategy.EMPTY, + new DataFlowInfoForArgumentsImpl(propertyResolvedCall.getDataFlowInfoForArguments().getResultInfo(), call) + ); + resolvedCall.markCallAsCompleted(); + + CallCheckerContext callCheckerContext = new CallCheckerContext(context, components.languageFeatureSettings); + for (CallChecker checker : components.callCheckers) { + checker.check(resolvedCall, expression, callCheckerContext); + } + } + @Override public KotlinTypeInfo visitBinaryExpression(@NotNull KtBinaryExpression expression, ExpressionTypingContext contextWithExpectedType) { ExpressionTypingContext context = isBinaryExpressionDependentOnExpectedType(expression)