diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DelegatedPropertyResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DelegatedPropertyResolver.java index 128fabb3730..abe5ef6d4a5 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DelegatedPropertyResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DelegatedPropertyResolver.java @@ -24,11 +24,14 @@ 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; @@ -62,21 +65,27 @@ import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.creat public class DelegatedPropertyResolver { public static final Name PROPERTY_DELEGATED_FUNCTION_NAME = Name.identifier("propertyDelegated"); - private final ExpressionTypingServices expressionTypingServices; - private final FakeCallResolver fakeCallResolver; private final KotlinBuiltIns builtIns; + private final FakeCallResolver fakeCallResolver; + private final ExpressionTypingServices expressionTypingServices; + private final LanguageFeatureSettings languageFeatureSettings; + private final Iterable callCheckers; private final Iterable symbolUsageValidators; public DelegatedPropertyResolver( - @NotNull Iterable symbolUsageValidators, @NotNull KotlinBuiltIns builtIns, @NotNull FakeCallResolver fakeCallResolver, - @NotNull ExpressionTypingServices expressionTypingServices + @NotNull ExpressionTypingServices expressionTypingServices, + @NotNull LanguageFeatureSettings languageFeatureSettings, + @NotNull Iterable callCheckers, + @NotNull Iterable symbolUsageValidators ) { - this.symbolUsageValidators = symbolUsageValidators; this.builtIns = builtIns; this.fakeCallResolver = fakeCallResolver; this.expressionTypingServices = expressionTypingServices; + this.languageFeatureSettings = languageFeatureSettings; + this.callCheckers = callCheckers; + this.symbolUsageValidators = symbolUsageValidators; } public void resolvePropertyDelegate( @@ -274,6 +283,11 @@ public class DelegatedPropertyResolver { OperatorCallChecker.Companion.report(byKeyword, resultingDescriptor, trace); } + CallCheckerContext callCheckerContext = + new CallCheckerContext(trace, delegateFunctionsScope, languageFeatureSettings, dataFlowInfo); + for (CallChecker checker : callCheckers) { + checker.check(resultingCall, byKeyword, callCheckerContext); + } for (SymbolUsageValidator validator : symbolUsageValidators) { validator.validateCall(resultingCall, trace, byKeyword); } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DestructuringDeclarationResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DestructuringDeclarationResolver.kt index d80fd7da77b..88e0fa39b9f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DestructuringDeclarationResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DestructuringDeclarationResolver.kt @@ -16,6 +16,7 @@ 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 @@ -24,6 +25,8 @@ 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 @@ -37,6 +40,8 @@ class DestructuringDeclarationResolver( private val fakeCallResolver: FakeCallResolver, private val localVariableResolver: LocalVariableResolver, private val typeResolver: TypeResolver, + private val languageFeatureSettings: LanguageFeatureSettings, + private val callCheckers: Iterable, private val symbolUsageValidators: Iterable ) { fun defineLocalVariablesFromMultiDeclaration( @@ -81,6 +86,10 @@ 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) + } for (validator in symbolUsageValidators) { validator.validateCall(results.resultingCall, context.trace, entry) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ForLoopConventionsChecker.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ForLoopConventionsChecker.java index 4bd9335df1a..7f5a418cc70 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ForLoopConventionsChecker.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ForLoopConventionsChecker.java @@ -20,6 +20,7 @@ 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.FunctionDescriptor; import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor; import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1; @@ -27,6 +28,8 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticSink; 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; @@ -36,6 +39,7 @@ import org.jetbrains.kotlin.resolve.validation.SymbolUsageValidator; import org.jetbrains.kotlin.types.DynamicTypesKt; import org.jetbrains.kotlin.types.ErrorUtils; import org.jetbrains.kotlin.types.KotlinType; +import org.jetbrains.kotlin.util.OperatorNameConventions; import org.jetbrains.kotlin.util.slicedMap.WritableSlice; import java.util.Collections; @@ -45,16 +49,22 @@ import static org.jetbrains.kotlin.resolve.BindingContext.*; public class ForLoopConventionsChecker { private final KotlinBuiltIns builtIns; - private final Iterable symbolUsageValidators; private final FakeCallResolver fakeCallResolver; + private final LanguageFeatureSettings languageFeatureSettings; + private final Iterable callCheckers; + private final Iterable symbolUsageValidators; public ForLoopConventionsChecker( @NotNull KotlinBuiltIns builtIns, @NotNull FakeCallResolver fakeCallResolver, + @NotNull LanguageFeatureSettings languageFeatureSettings, + @NotNull Iterable callCheckers, @NotNull Iterable symbolUsageValidators ) { this.builtIns = builtIns; this.fakeCallResolver = fakeCallResolver; + this.languageFeatureSettings = languageFeatureSettings; + this.callCheckers = callCheckers; this.symbolUsageValidators = symbolUsageValidators; } @@ -63,10 +73,10 @@ public class ForLoopConventionsChecker { KtExpression loopRangeExpression = loopRange.getExpression(); // Make a fake call loopRange.iterator(), and try to resolve it - Name iterator = Name.identifier("iterator"); - Pair> calls = - fakeCallResolver.makeAndResolveFakeCall(loopRange, context, Collections.emptyList(), iterator, - loopRangeExpression, FakeCallKind.ITERATOR, loopRangeExpression); + Pair> calls = fakeCallResolver.makeAndResolveFakeCall( + loopRange, context, Collections.emptyList(), OperatorNameConventions.ITERATOR, loopRangeExpression, + FakeCallKind.ITERATOR, loopRangeExpression + ); OverloadResolutionResults iteratorResolutionResults = calls.getSecond(); if (iteratorResolutionResults.isSuccess()) { @@ -76,20 +86,27 @@ public class ForLoopConventionsChecker { checkIfOperatorModifierPresent(loopRangeExpression, iteratorFunction, context.trace); + CallCheckerContext callCheckerContext = new CallCheckerContext(context, languageFeatureSettings); + for (CallChecker checker : callCheckers) { + checker.check(iteratorResolvedCall, loopRangeExpression, callCheckerContext); + } for (SymbolUsageValidator validator : symbolUsageValidators) { validator.validateCall(iteratorResolvedCall, context.trace, loopRangeExpression); } KotlinType iteratorType = iteratorFunction.getReturnType(); - KotlinType hasNextType = checkConventionForIterator(context, loopRangeExpression, iteratorType, "hasNext", - HAS_NEXT_FUNCTION_AMBIGUITY, HAS_NEXT_MISSING, HAS_NEXT_FUNCTION_NONE_APPLICABLE, - LOOP_RANGE_HAS_NEXT_RESOLVED_CALL); + //noinspection ConstantConditions + KotlinType hasNextType = checkConventionForIterator( + context, loopRangeExpression, iteratorType, OperatorNameConventions.HAS_NEXT, + HAS_NEXT_FUNCTION_AMBIGUITY, HAS_NEXT_MISSING, HAS_NEXT_FUNCTION_NONE_APPLICABLE, LOOP_RANGE_HAS_NEXT_RESOLVED_CALL + ); if (hasNextType != null && !builtIns.isBooleanOrSubtype(hasNextType)) { context.trace.report(HAS_NEXT_FUNCTION_TYPE_MISMATCH.on(loopRangeExpression, hasNextType)); } - return checkConventionForIterator(context, loopRangeExpression, iteratorType, "next", - NEXT_AMBIGUITY, NEXT_MISSING, NEXT_NONE_APPLICABLE, - LOOP_RANGE_NEXT_RESOLVED_CALL); + return checkConventionForIterator( + context, loopRangeExpression, iteratorType, OperatorNameConventions.NEXT, + NEXT_AMBIGUITY, NEXT_MISSING, NEXT_NONE_APPLICABLE, LOOP_RANGE_NEXT_RESOLVED_CALL + ); } return null; } @@ -109,14 +126,15 @@ public class ForLoopConventionsChecker { @NotNull ExpressionTypingContext context, @NotNull KtExpression loopRangeExpression, @NotNull KotlinType iteratorType, - @NotNull String name, + @NotNull Name name, @NotNull DiagnosticFactory1 ambiguity, @NotNull DiagnosticFactory1 missing, @NotNull DiagnosticFactory1 noneApplicable, @NotNull WritableSlice> resolvedCallKey ) { OverloadResolutionResults nextResolutionResults = fakeCallResolver.resolveFakeCall( - context, new TransientReceiver(iteratorType), Name.identifier(name), loopRangeExpression); + context, new TransientReceiver(iteratorType), name, loopRangeExpression + ); if (nextResolutionResults.isAmbiguity()) { context.trace.report(ambiguity.on(loopRangeExpression, iteratorType)); } @@ -131,6 +149,11 @@ public class ForLoopConventionsChecker { ResolvedCall resolvedCall = nextResolutionResults.getResultingCall(); context.trace.record(resolvedCallKey, loopRangeExpression, resolvedCall); FunctionDescriptor functionDescriptor = resolvedCall.getResultingDescriptor(); + + CallCheckerContext callCheckerContext = new CallCheckerContext(context, languageFeatureSettings); + for (CallChecker checker : callCheckers) { + checker.check(resolvedCall, loopRangeExpression, callCheckerContext); + } for (SymbolUsageValidator validator : symbolUsageValidators) { validator.validateCall(resolvedCall, context.trace, loopRangeExpression); } diff --git a/compiler/testData/diagnostics/tests/inline/binaryExpressions/componentAccess.kt b/compiler/testData/diagnostics/tests/inline/binaryExpressions/componentAccess.kt index 52baa63c0d5..28d9e646bc1 100644 --- a/compiler/testData/diagnostics/tests/inline/binaryExpressions/componentAccess.kt +++ b/compiler/testData/diagnostics/tests/inline/binaryExpressions/componentAccess.kt @@ -13,6 +13,6 @@ operator fun @ExtensionFunctionType Function3.component operator fun @ExtensionFunctionType Function3.component2() = 2 inline fun inlineFunWithInvoke(s: (p: T, l: U) -> V, ext: T.(p: U, l: V) -> W) { - val (d1, e1) = s - val (d2, e2) = ext + val (d1, e1) = s + val (d2, e2) = ext }