Check 'operator' on next() and hasNext()
This commit is contained in:
@@ -68,6 +68,8 @@ public class OperatorModifierChecker : DeclarationChecker {
|
|||||||
INVOKE == name -> {}
|
INVOKE == name -> {}
|
||||||
CONTAINS == name -> {}
|
CONTAINS == name -> {}
|
||||||
ITERATOR == name -> {}
|
ITERATOR == name -> {}
|
||||||
|
NEXT == name -> {}
|
||||||
|
HAS_NEXT == name -> {}
|
||||||
EQUALS == name -> {}
|
EQUALS == name -> {}
|
||||||
COMPARE_TO == name -> {}
|
COMPARE_TO == name -> {}
|
||||||
UNARY_OPERATION_NAMES.any { it.value == name } && functionDescriptor.valueParameters.isEmpty() -> {}
|
UNARY_OPERATION_NAMES.any { it.value == name } && functionDescriptor.valueParameters.isEmpty() -> {}
|
||||||
|
|||||||
+22
@@ -21,15 +21,22 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
||||||
|
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor;
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1;
|
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1;
|
||||||
|
import org.jetbrains.kotlin.diagnostics.DiagnosticSink;
|
||||||
import org.jetbrains.kotlin.name.Name;
|
import org.jetbrains.kotlin.name.Name;
|
||||||
import org.jetbrains.kotlin.psi.Call;
|
import org.jetbrains.kotlin.psi.Call;
|
||||||
import org.jetbrains.kotlin.psi.JetExpression;
|
import org.jetbrains.kotlin.psi.JetExpression;
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||||
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults;
|
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults;
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.tasks.DynamicCallsKt;
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver;
|
import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver;
|
||||||
|
import org.jetbrains.kotlin.resolve.validation.OperatorValidator;
|
||||||
import org.jetbrains.kotlin.resolve.validation.SymbolUsageValidator;
|
import org.jetbrains.kotlin.resolve.validation.SymbolUsageValidator;
|
||||||
|
import org.jetbrains.kotlin.types.DynamicTypesKt;
|
||||||
|
import org.jetbrains.kotlin.types.ErrorUtils;
|
||||||
import org.jetbrains.kotlin.types.JetType;
|
import org.jetbrains.kotlin.types.JetType;
|
||||||
import org.jetbrains.kotlin.util.slicedMap.WritableSlice;
|
import org.jetbrains.kotlin.util.slicedMap.WritableSlice;
|
||||||
|
|
||||||
@@ -70,6 +77,8 @@ public class ForLoopConventionsChecker {
|
|||||||
context.trace.record(LOOP_RANGE_ITERATOR_RESOLVED_CALL, loopRangeExpression, iteratorResolvedCall);
|
context.trace.record(LOOP_RANGE_ITERATOR_RESOLVED_CALL, loopRangeExpression, iteratorResolvedCall);
|
||||||
FunctionDescriptor iteratorFunction = iteratorResolvedCall.getResultingDescriptor();
|
FunctionDescriptor iteratorFunction = iteratorResolvedCall.getResultingDescriptor();
|
||||||
|
|
||||||
|
checkIfOperatorModifierPresent(loopRangeExpression, iteratorFunction, context.trace);
|
||||||
|
|
||||||
symbolUsageValidator.validateCall(iteratorFunction, context.trace, loopRangeExpression);
|
symbolUsageValidator.validateCall(iteratorFunction, context.trace, loopRangeExpression);
|
||||||
|
|
||||||
JetType iteratorType = iteratorFunction.getReturnType();
|
JetType iteratorType = iteratorFunction.getReturnType();
|
||||||
@@ -94,6 +103,16 @@ public class ForLoopConventionsChecker {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void checkIfOperatorModifierPresent(JetExpression expression, FunctionDescriptor descriptor, DiagnosticSink sink) {
|
||||||
|
if (ErrorUtils.isError(descriptor)) return;
|
||||||
|
ReceiverParameterDescriptor extensionReceiverParameter = descriptor.getExtensionReceiverParameter();
|
||||||
|
if ((extensionReceiverParameter != null) && (DynamicTypesKt.isDynamic(extensionReceiverParameter.getType()))) return;
|
||||||
|
|
||||||
|
if (!descriptor.isOperator()) {
|
||||||
|
OperatorValidator.Companion.report(expression, descriptor, sink);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private JetType checkConventionForIterator(
|
private JetType checkConventionForIterator(
|
||||||
@NotNull ExpressionTypingContext context,
|
@NotNull ExpressionTypingContext context,
|
||||||
@@ -122,6 +141,9 @@ public class ForLoopConventionsChecker {
|
|||||||
context.trace.record(resolvedCallKey, loopRangeExpression, resolvedCall);
|
context.trace.record(resolvedCallKey, loopRangeExpression, resolvedCall);
|
||||||
FunctionDescriptor functionDescriptor = resolvedCall.getResultingDescriptor();
|
FunctionDescriptor functionDescriptor = resolvedCall.getResultingDescriptor();
|
||||||
symbolUsageValidator.validateCall(functionDescriptor, context.trace, loopRangeExpression);
|
symbolUsageValidator.validateCall(functionDescriptor, context.trace, loopRangeExpression);
|
||||||
|
|
||||||
|
checkIfOperatorModifierPresent(loopRangeExpression, functionDescriptor, context.trace);
|
||||||
|
|
||||||
return functionDescriptor.getReturnType();
|
return functionDescriptor.getReturnType();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ public class OperatorConventions {
|
|||||||
public static final Name CONTAINS = Name.identifier("contains");
|
public static final Name CONTAINS = Name.identifier("contains");
|
||||||
public static final Name INVOKE = Name.identifier("invoke");
|
public static final Name INVOKE = Name.identifier("invoke");
|
||||||
public static final Name ITERATOR = Name.identifier("iterator");
|
public static final Name ITERATOR = Name.identifier("iterator");
|
||||||
|
public static final Name NEXT = Name.identifier("next");
|
||||||
|
public static final Name HAS_NEXT = Name.identifier("hasNext");
|
||||||
|
|
||||||
private OperatorConventions() {}
|
private OperatorConventions() {}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user