Get rid of CallChecker#checkPropertyCall, create fake ResolvedCall
This commit is contained in:
+1
-9
@@ -17,9 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.resolve.jvm.checkers
|
package org.jetbrains.kotlin.resolve.jvm.checkers
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.annotations.hasJvmStaticAnnotation
|
import org.jetbrains.kotlin.resolve.annotations.hasJvmStaticAnnotation
|
||||||
@@ -31,14 +29,8 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
|
|||||||
|
|
||||||
class ProtectedInSuperClassCompanionCallChecker : CallChecker {
|
class ProtectedInSuperClassCompanionCallChecker : CallChecker {
|
||||||
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
|
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
|
// Protected non-JVM static
|
||||||
if (targetDescriptor.visibility != Visibilities.PROTECTED) return
|
if (targetDescriptor.visibility != Visibilities.PROTECTED) return
|
||||||
if (targetDescriptor.hasJvmStaticAnnotation()) return
|
if (targetDescriptor.hasJvmStaticAnnotation()) return
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.resolve.calls.checkers
|
|||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.config.LanguageFeatureSettings
|
import org.jetbrains.kotlin.config.LanguageFeatureSettings
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
|
|
||||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||||
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
|
||||||
@@ -33,15 +32,6 @@ interface CallChecker {
|
|||||||
* Logic of the checker should not depend on what element is the target of the diagnostic!
|
* Logic of the checker should not depend on what element is the target of the diagnostic!
|
||||||
*/
|
*/
|
||||||
fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext)
|
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(
|
class CallCheckerContext(
|
||||||
|
|||||||
+1
-6
@@ -20,7 +20,6 @@ import com.intellij.psi.PsiElement
|
|||||||
import com.intellij.psi.tree.TokenSet
|
import com.intellij.psi.tree.TokenSet
|
||||||
import com.intellij.psi.util.PsiTreeUtil
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PropertySetterDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertySetterDescriptor
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
@@ -38,11 +37,7 @@ object DeprecatedCallChecker : CallChecker {
|
|||||||
check(resolvedCall.resultingDescriptor, context.trace, reportOn)
|
check(resolvedCall.resultingDescriptor, context.trace, reportOn)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun checkPropertyCall(descriptor: PropertyAccessorDescriptor, reportOn: PsiElement, context: CallCheckerContext) {
|
private fun check(targetDescriptor: CallableDescriptor, trace: BindingTrace, element: PsiElement) {
|
||||||
check(descriptor, context.trace, reportOn)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun check(targetDescriptor: CallableDescriptor, trace: BindingTrace, element: PsiElement) {
|
|
||||||
val deprecation = targetDescriptor.getDeprecation()
|
val deprecation = targetDescriptor.getDeprecation()
|
||||||
|
|
||||||
// avoid duplicating diagnostic when deprecation for property effectively deprecates setter
|
// avoid duplicating diagnostic when deprecation for property effectively deprecates setter
|
||||||
|
|||||||
@@ -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
|
@Override
|
||||||
public void check(@NotNull ResolvedCall<?> resolvedCall, @NotNull PsiElement reportOn, @NotNull CallCheckerContext context) {
|
public void check(@NotNull ResolvedCall<?> resolvedCall, @NotNull PsiElement reportOn, @NotNull CallCheckerContext context) {
|
||||||
KtExpression expression = resolvedCall.getCall().getCalleeExpression();
|
KtExpression expression = resolvedCall.getCall().getCalleeExpression();
|
||||||
|
|||||||
+4
-8
@@ -20,7 +20,10 @@ import com.intellij.psi.PsiElement;
|
|||||||
import kotlin.collections.CollectionsKt;
|
import kotlin.collections.CollectionsKt;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
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.diagnostics.Errors;
|
||||||
import org.jetbrains.kotlin.psi.KtTypeProjection;
|
import org.jetbrains.kotlin.psi.KtTypeProjection;
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||||
@@ -30,13 +33,6 @@ import org.jetbrains.kotlin.types.typeUtil.TypeUtilsKt;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class ReifiedTypeParameterSubstitutionChecker implements CallChecker {
|
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
|
@Override
|
||||||
public void check(@NotNull ResolvedCall<?> resolvedCall, @NotNull PsiElement reportOn, @NotNull CallCheckerContext context) {
|
public void check(@NotNull ResolvedCall<?> resolvedCall, @NotNull PsiElement reportOn, @NotNull CallCheckerContext context) {
|
||||||
Map<TypeParameterDescriptor, KotlinType> typeArguments = resolvedCall.getTypeArguments();
|
Map<TypeParameterDescriptor, KotlinType> typeArguments = resolvedCall.getTypeArguments();
|
||||||
|
|||||||
+32
-5
@@ -34,10 +34,12 @@ import org.jetbrains.kotlin.lexer.KtKeywordToken;
|
|||||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||||
import org.jetbrains.kotlin.name.Name;
|
import org.jetbrains.kotlin.name.Name;
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
|
||||||
import org.jetbrains.kotlin.resolve.*;
|
import org.jetbrains.kotlin.resolve.*;
|
||||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.BindingContextUtilsKt;
|
import org.jetbrains.kotlin.resolve.bindingContextUtil.BindingContextUtilsKt;
|
||||||
import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver;
|
import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver;
|
||||||
import org.jetbrains.kotlin.resolve.calls.CallExpressionResolver;
|
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.CallChecker;
|
||||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext;
|
import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext;
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.DataFlowInfoForArgumentsImpl;
|
import org.jetbrains.kotlin.resolve.calls.model.DataFlowInfoForArgumentsImpl;
|
||||||
@@ -943,11 +945,10 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
result = false;
|
result = false;
|
||||||
}
|
}
|
||||||
else if (setter != null) {
|
else if (setter != null) {
|
||||||
CallCheckerContext callCheckerContext =
|
ResolvedCall<?> resolvedCall = CallUtilKt.getResolvedCall(expressionWithParenthesis, context.trace.getBindingContext());
|
||||||
new CallCheckerContext(trace, context.scope, components.languageFeatureSettings, context.dataFlowInfo, false);
|
assert resolvedCall != null
|
||||||
for (CallChecker checker : components.callCheckers) {
|
: "Call is not resolved for property setter: " + PsiUtilsKt.getElementTextWithContext(expressionWithParenthesis);
|
||||||
checker.checkPropertyCall(setter, reportOn, callCheckerContext);
|
checkPropertySetterCall(context.replaceBindingTrace(trace), setter, resolvedCall, reportOn);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -962,6 +963,32 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkPropertySetterCall(
|
||||||
|
@NotNull ExpressionTypingContext context,
|
||||||
|
@NotNull PropertySetterDescriptor descriptor,
|
||||||
|
@NotNull ResolvedCall<?> propertyResolvedCall,
|
||||||
|
@NotNull KtExpression expression
|
||||||
|
) {
|
||||||
|
Call call = propertyResolvedCall.getCall();
|
||||||
|
|
||||||
|
ResolutionCandidate<PropertySetterDescriptor> resolutionCandidate = ResolutionCandidate.create(
|
||||||
|
call, descriptor, propertyResolvedCall.getDispatchReceiver(), propertyResolvedCall.getExplicitReceiverKind(), null
|
||||||
|
);
|
||||||
|
|
||||||
|
ResolvedCallImpl<PropertySetterDescriptor> 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
|
@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)
|
||||||
|
|||||||
Reference in New Issue
Block a user