Do not report errors on fake elements in call checkers
#KT-12875 Fixed
This commit is contained in:
@@ -24,14 +24,11 @@ import kotlin.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.config.LanguageFeatureSettings;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
|
||||
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.checkers.OperatorCallChecker;
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystem;
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemCompleter;
|
||||
@@ -67,21 +64,15 @@ public class DelegatedPropertyResolver {
|
||||
private final KotlinBuiltIns builtIns;
|
||||
private final FakeCallResolver fakeCallResolver;
|
||||
private final ExpressionTypingServices expressionTypingServices;
|
||||
private final LanguageFeatureSettings languageFeatureSettings;
|
||||
private final Iterable<CallChecker> callCheckers;
|
||||
|
||||
public DelegatedPropertyResolver(
|
||||
@NotNull KotlinBuiltIns builtIns,
|
||||
@NotNull FakeCallResolver fakeCallResolver,
|
||||
@NotNull ExpressionTypingServices expressionTypingServices,
|
||||
@NotNull LanguageFeatureSettings languageFeatureSettings,
|
||||
@NotNull Iterable<CallChecker> callCheckers
|
||||
@NotNull ExpressionTypingServices expressionTypingServices
|
||||
) {
|
||||
this.builtIns = builtIns;
|
||||
this.fakeCallResolver = fakeCallResolver;
|
||||
this.expressionTypingServices = expressionTypingServices;
|
||||
this.languageFeatureSettings = languageFeatureSettings;
|
||||
this.callCheckers = callCheckers;
|
||||
}
|
||||
|
||||
public void resolvePropertyDelegate(
|
||||
@@ -278,12 +269,6 @@ public class DelegatedPropertyResolver {
|
||||
if (!resultingDescriptor.isOperator()) {
|
||||
OperatorCallChecker.Companion.report(byKeyword, resultingDescriptor, trace);
|
||||
}
|
||||
|
||||
CallCheckerContext callCheckerContext =
|
||||
new CallCheckerContext(trace, delegateFunctionsScope, languageFeatureSettings, dataFlowInfo);
|
||||
for (CallChecker checker : callCheckers) {
|
||||
checker.check(resultingCall, byKeyword, callCheckerContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
trace.record(DELEGATED_PROPERTY_RESOLVED_CALL, accessor, resultingCall);
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.resolve.BindingContext.CONSTRAINT_SYSTEM_COMPLETER
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode.RESOLVE_FUNCTION_ARGUMENTS
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getEffectiveExpectedType
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isInvokeCallOnVariable
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.isFakeElement
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext
|
||||
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
||||
@@ -82,11 +83,13 @@ class CallCompleter(
|
||||
}
|
||||
|
||||
if (resolvedCall != null) {
|
||||
val element = if (resolvedCall is VariableAsFunctionResolvedCall)
|
||||
val calleeExpression = if (resolvedCall is VariableAsFunctionResolvedCall)
|
||||
resolvedCall.variableCall.call.calleeExpression
|
||||
else
|
||||
resolvedCall.call.calleeExpression
|
||||
val reportOn = element ?: resolvedCall.call.callElement
|
||||
val reportOn =
|
||||
if (calleeExpression != null && !calleeExpression.isFakeElement) calleeExpression
|
||||
else resolvedCall.call.callElement
|
||||
|
||||
val callCheckerContext = CallCheckerContext(context, languageFeatureSettings)
|
||||
for (callChecker in callCheckers) {
|
||||
|
||||
+1
-1
@@ -50,7 +50,7 @@ class OperatorCallChecker : CallChecker {
|
||||
|
||||
if (call.callElement is KtDestructuringDeclarationEntry || call is CallTransformer.CallForImplicitInvoke) {
|
||||
if (!functionDescriptor.isOperator) {
|
||||
report(call.callElement, functionDescriptor, context.trace)
|
||||
report(reportOn, functionDescriptor, context.trace)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@ import org.jetbrains.kotlin.resolve.calls.CallTransformer
|
||||
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
import org.jetbrains.kotlin.utils.sure
|
||||
|
||||
// resolved call
|
||||
@@ -211,6 +210,13 @@ fun KtExpression.getType(context: BindingContext): KotlinType? {
|
||||
return null
|
||||
}
|
||||
|
||||
val KtElement.isFakeElement: Boolean
|
||||
get() {
|
||||
// Don't use getContainingKtFile() because in IDE we can get an element with JavaDummyHolder as containing file
|
||||
val file = containingFile
|
||||
return file is KtFile && file.doNotAnalyze != null
|
||||
}
|
||||
|
||||
fun Call.isSafeCall(): Boolean {
|
||||
if (this is CallTransformer.CallForImplicitInvoke) {
|
||||
//implicit safe 'invoke'
|
||||
@@ -223,10 +229,10 @@ fun Call.isSafeCall(): Boolean {
|
||||
|
||||
fun Call.isExplicitSafeCall(): Boolean = callOperationNode?.elementType == KtTokens.SAFE_ACCESS
|
||||
|
||||
fun Call.createLookupLocation() = KotlinLookupLocation(run {
|
||||
calleeExpression?.let {
|
||||
// Can't use getContainingJetFile() because we can get from IDE an element with JavaDummyHolder as containing file
|
||||
if ((it.containingFile as? KtFile)?.doNotAnalyze == null) it else null
|
||||
}
|
||||
?: callElement
|
||||
})
|
||||
fun Call.createLookupLocation(): KotlinLookupLocation {
|
||||
val calleeExpression = calleeExpression
|
||||
val element =
|
||||
if (calleeExpression != null && !calleeExpression.isFakeElement) calleeExpression
|
||||
else callElement
|
||||
return KotlinLookupLocation(element)
|
||||
}
|
||||
|
||||
+1
-11
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.types.expressions
|
||||
|
||||
import org.jetbrains.kotlin.config.LanguageFeatureSettings
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
|
||||
@@ -25,8 +24,6 @@ import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.LocalVariableResolver
|
||||
import org.jetbrains.kotlin.resolve.TypeResolver
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext
|
||||
import org.jetbrains.kotlin.resolve.dataClassUtils.createComponentName
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
@@ -38,9 +35,7 @@ import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
class DestructuringDeclarationResolver(
|
||||
private val fakeCallResolver: FakeCallResolver,
|
||||
private val localVariableResolver: LocalVariableResolver,
|
||||
private val typeResolver: TypeResolver,
|
||||
private val languageFeatureSettings: LanguageFeatureSettings,
|
||||
private val callCheckers: Iterable<CallChecker>
|
||||
private val typeResolver: TypeResolver
|
||||
) {
|
||||
fun defineLocalVariablesFromMultiDeclaration(
|
||||
writableScope: LexicalWritableScope,
|
||||
@@ -84,11 +79,6 @@ class DestructuringDeclarationResolver(
|
||||
|
||||
context.trace.record(BindingContext.COMPONENT_RESOLVED_CALL, entry, results.resultingCall)
|
||||
|
||||
val callCheckerContext = CallCheckerContext(context, languageFeatureSettings)
|
||||
for (checker in callCheckers) {
|
||||
checker.check(results.resultingCall, entry, callCheckerContext)
|
||||
}
|
||||
|
||||
val functionReturnType = results.resultingDescriptor.returnType
|
||||
if (functionReturnType != null && !TypeUtils.noExpectedType(expectedType)
|
||||
&& !KotlinTypeChecker.DEFAULT.isSubtypeOf(functionReturnType, expectedType) ) {
|
||||
|
||||
-11
@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.Call;
|
||||
import org.jetbrains.kotlin.psi.KtExpression;
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker;
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext;
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.OperatorCallChecker;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults;
|
||||
@@ -82,11 +81,6 @@ public class ForLoopConventionsChecker {
|
||||
|
||||
checkIfOperatorModifierPresent(loopRangeExpression, iteratorFunction, context.trace);
|
||||
|
||||
CallCheckerContext callCheckerContext = new CallCheckerContext(context, languageFeatureSettings);
|
||||
for (CallChecker checker : callCheckers) {
|
||||
checker.check(iteratorResolvedCall, loopRangeExpression, callCheckerContext);
|
||||
}
|
||||
|
||||
KotlinType iteratorType = iteratorFunction.getReturnType();
|
||||
//noinspection ConstantConditions
|
||||
KotlinType hasNextType = checkConventionForIterator(
|
||||
@@ -142,11 +136,6 @@ public class ForLoopConventionsChecker {
|
||||
ResolvedCall<FunctionDescriptor> resolvedCall = nextResolutionResults.getResultingCall();
|
||||
context.trace.record(resolvedCallKey, loopRangeExpression, resolvedCall);
|
||||
|
||||
CallCheckerContext callCheckerContext = new CallCheckerContext(context, languageFeatureSettings);
|
||||
for (CallChecker checker : callCheckers) {
|
||||
checker.check(resolvedCall, loopRangeExpression, callCheckerContext);
|
||||
}
|
||||
|
||||
FunctionDescriptor functionDescriptor = resolvedCall.getResultingDescriptor();
|
||||
checkIfOperatorModifierPresent(loopRangeExpression, functionDescriptor, context.trace);
|
||||
|
||||
|
||||
+1
-1
@@ -88,7 +88,7 @@ fun test() {
|
||||
<!OPERATOR_MODIFIER_REQUIRED!>!<!>a
|
||||
!c
|
||||
|
||||
<!OPERATOR_MODIFIER_REQUIRED!>a()<!>
|
||||
<!OPERATOR_MODIFIER_REQUIRED!>a<!>()
|
||||
c()
|
||||
|
||||
<!OPERATOR_MODIFIER_REQUIRED!>Example()()<!>
|
||||
|
||||
@@ -17,8 +17,8 @@ class PropertyHolder {
|
||||
@Deprecated("text")
|
||||
var name = "String"
|
||||
|
||||
val valDelegate <!DEPRECATION!>by<!> Delegate()
|
||||
var varDelegate <!DEPRECATION, DEPRECATION!>by<!> Delegate()
|
||||
val valDelegate by <!DEPRECATION!>Delegate()<!>
|
||||
var varDelegate by <!DEPRECATION, DEPRECATION!>Delegate()<!>
|
||||
|
||||
public val test1: String = ""
|
||||
@Deprecated("val-getter") get
|
||||
|
||||
+2
-2
@@ -13,6 +13,6 @@ operator fun <T, U, V, W> @ExtensionFunctionType Function3<T, U, V, W>.component
|
||||
operator fun <T, U, V, W> @ExtensionFunctionType Function3<T, U, V, W>.component2() = 2
|
||||
|
||||
inline fun <T, U, V, W> inlineFunWithInvoke(s: (p: T, l: U) -> V, ext: T.(p: U, l: V) -> W) {
|
||||
val (d1, e1) = <!USAGE_IS_NOT_INLINABLE, USAGE_IS_NOT_INLINABLE, USAGE_IS_NOT_INLINABLE, USAGE_IS_NOT_INLINABLE!>s<!>
|
||||
val (d2, e2) = <!USAGE_IS_NOT_INLINABLE, USAGE_IS_NOT_INLINABLE, USAGE_IS_NOT_INLINABLE, USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
val (d1, e1) = <!USAGE_IS_NOT_INLINABLE, USAGE_IS_NOT_INLINABLE!>s<!>
|
||||
val (d2, e2) = <!USAGE_IS_NOT_INLINABLE, USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -5,7 +5,7 @@ class D : C {
|
||||
{
|
||||
val s = ""
|
||||
<!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>s<!>()
|
||||
""() // TODO: see KT-12875
|
||||
<!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>""()<!>
|
||||
42
|
||||
}())
|
||||
|
||||
|
||||
Reference in New Issue
Block a user