Store resolved calls for loop range's iterator(), next(), hasNext()
+ code duplication removed from expression typing visitor
This commit is contained in:
@@ -81,9 +81,11 @@ public interface BindingContext {
|
|||||||
WritableSlice<CallKey, OverloadResolutionResults<VariableDescriptor>> RESOLUTION_RESULTS_FOR_PROPERTY = Slices.createSimpleSlice();
|
WritableSlice<CallKey, OverloadResolutionResults<VariableDescriptor>> RESOLUTION_RESULTS_FOR_PROPERTY = Slices.createSimpleSlice();
|
||||||
WritableSlice<JetExpression, DelegatingBindingTrace> TRACE_DELTAS_CACHE = Slices.createSimpleSlice();
|
WritableSlice<JetExpression, DelegatingBindingTrace> TRACE_DELTAS_CACHE = Slices.createSimpleSlice();
|
||||||
|
|
||||||
WritableSlice<JetExpression, FunctionDescriptor> LOOP_RANGE_ITERATOR = Slices.createSimpleSlice();
|
WritableSlice<JetExpression, ResolvedCall<FunctionDescriptor>> LOOP_RANGE_ITERATOR_RESOLVED_CALL = Slices.createSimpleSlice();
|
||||||
WritableSlice<JetExpression, CallableDescriptor> LOOP_RANGE_HAS_NEXT = Slices.createSimpleSlice();
|
WritableSlice<JetExpression, Call> LOOP_RANGE_ITERATOR_CALL = Slices.createSimpleSlice();
|
||||||
WritableSlice<JetExpression, FunctionDescriptor> LOOP_RANGE_NEXT = Slices.createSimpleSlice();
|
|
||||||
|
WritableSlice<JetExpression, ResolvedCall<FunctionDescriptor>> LOOP_RANGE_HAS_NEXT_RESOLVED_CALL = Slices.createSimpleSlice();
|
||||||
|
WritableSlice<JetExpression, ResolvedCall<FunctionDescriptor>> LOOP_RANGE_NEXT_RESOLVED_CALL = Slices.createSimpleSlice();
|
||||||
|
|
||||||
WritableSlice<JetMultiDeclarationEntry, ResolvedCall<FunctionDescriptor>> COMPONENT_RESOLVED_CALL = Slices.createSimpleSlice();
|
WritableSlice<JetMultiDeclarationEntry, ResolvedCall<FunctionDescriptor>> COMPONENT_RESOLVED_CALL = Slices.createSimpleSlice();
|
||||||
|
|
||||||
|
|||||||
+42
-37
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.lang.types.expressions;
|
package org.jetbrains.jet.lang.types.expressions;
|
||||||
|
|
||||||
|
import com.intellij.openapi.util.Pair;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import com.intellij.psi.util.PsiTreeUtil;
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -25,11 +26,13 @@ import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
|||||||
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
|
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
||||||
import org.jetbrains.jet.lang.diagnostics.Errors;
|
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||||
|
import org.jetbrains.jet.lang.diagnostics.SimpleDiagnosticFactory;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults;
|
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||||
@@ -41,6 +44,7 @@ import org.jetbrains.jet.lang.types.*;
|
|||||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||||
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
|
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
|
||||||
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
|
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
|
||||||
|
import org.jetbrains.jet.util.slicedmap.WritableSlice;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -324,44 +328,37 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
|
|
||||||
// Make a fake call loopRange.iterator(), and try to resolve it
|
// Make a fake call loopRange.iterator(), and try to resolve it
|
||||||
Name iterator = Name.identifier("iterator");
|
Name iterator = Name.identifier("iterator");
|
||||||
OverloadResolutionResults<FunctionDescriptor> iteratorResolutionResults = resolveFakeCall(loopRange, context, iterator);
|
Pair<Call, OverloadResolutionResults<FunctionDescriptor>> calls = makeAndResolveFakeCall(loopRange, context, iterator);
|
||||||
|
Call iteratorCall = calls.getFirst();
|
||||||
|
OverloadResolutionResults<FunctionDescriptor> iteratorResolutionResults = calls.getSecond();
|
||||||
|
|
||||||
// We allow the loop range to be null (nothing happens), so we make the receiver type non-null
|
// We allow the loop range to be null (nothing happens), so we make the receiver type non-null
|
||||||
if (!iteratorResolutionResults.isSuccess()) {
|
if (!iteratorResolutionResults.isSuccess()) {
|
||||||
ExpressionReceiver nonNullReceiver = new ExpressionReceiver(loopRange.getExpression(), TypeUtils.makeNotNullable(loopRange.getType()));
|
ExpressionReceiver nonNullReceiver = new ExpressionReceiver(loopRange.getExpression(), TypeUtils.makeNotNullable(loopRange.getType()));
|
||||||
OverloadResolutionResults<FunctionDescriptor> iteratorResolutionResultsWithNonNullReceiver = resolveFakeCall(nonNullReceiver, context, iterator);
|
Pair<Call,OverloadResolutionResults<FunctionDescriptor>> callsNonNull = makeAndResolveFakeCall(nonNullReceiver, context, iterator);
|
||||||
|
Call iteratorCallWithNonNullReceiver = callsNonNull.getFirst();
|
||||||
|
OverloadResolutionResults<FunctionDescriptor> iteratorResolutionResultsWithNonNullReceiver = callsNonNull.getSecond();
|
||||||
if (iteratorResolutionResultsWithNonNullReceiver.isSuccess()) {
|
if (iteratorResolutionResultsWithNonNullReceiver.isSuccess()) {
|
||||||
iteratorResolutionResults = iteratorResolutionResultsWithNonNullReceiver;
|
iteratorResolutionResults = iteratorResolutionResultsWithNonNullReceiver;
|
||||||
|
iteratorCall = iteratorCallWithNonNullReceiver;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iteratorResolutionResults.isSuccess()) {
|
if (iteratorResolutionResults.isSuccess()) {
|
||||||
FunctionDescriptor iteratorFunction = iteratorResolutionResults.getResultingCall().getResultingDescriptor();
|
ResolvedCall<FunctionDescriptor> iteratorResolvedCall = iteratorResolutionResults.getResultingCall();
|
||||||
|
context.trace.record(LOOP_RANGE_ITERATOR_RESOLVED_CALL, loopRangeExpression, iteratorResolvedCall);
|
||||||
context.trace.record(LOOP_RANGE_ITERATOR, loopRangeExpression, iteratorFunction);
|
context.trace.record(LOOP_RANGE_ITERATOR_CALL, loopRangeExpression, iteratorCall);
|
||||||
|
|
||||||
|
FunctionDescriptor iteratorFunction = iteratorResolvedCall.getResultingDescriptor();
|
||||||
JetType iteratorType = iteratorFunction.getReturnType();
|
JetType iteratorType = iteratorFunction.getReturnType();
|
||||||
FunctionDescriptor hasNextFunction = checkHasNextFunctionSupport(loopRangeExpression, iteratorType, context);
|
JetType hasNextType = checkConventionForIterator(context, loopRangeExpression, iteratorType, "hasNext",
|
||||||
boolean hasNextFunctionSupported = hasNextFunction != null;
|
HAS_NEXT_FUNCTION_AMBIGUITY, HAS_NEXT_MISSING,
|
||||||
if (!hasNextFunctionSupported) {
|
LOOP_RANGE_HAS_NEXT_RESOLVED_CALL);
|
||||||
context.trace.report(HAS_NEXT_MISSING.on(loopRangeExpression));
|
if (hasNextType != null && !isBoolean(hasNextType)) {
|
||||||
}
|
context.trace.report(HAS_NEXT_FUNCTION_TYPE_MISMATCH.on(loopRangeExpression, hasNextType));
|
||||||
else {
|
|
||||||
context.trace.record(LOOP_RANGE_HAS_NEXT, loopRange.getExpression(), hasNextFunction);
|
|
||||||
}
|
|
||||||
|
|
||||||
OverloadResolutionResults<FunctionDescriptor> nextResolutionResults = context.resolveExactSignature(new TransientReceiver(iteratorType), Name.identifier("next"), Collections.<JetType>emptyList());
|
|
||||||
if (nextResolutionResults.isAmbiguity()) {
|
|
||||||
context.trace.report(NEXT_AMBIGUITY.on(loopRangeExpression));
|
|
||||||
}
|
|
||||||
else if (nextResolutionResults.isNothing()) {
|
|
||||||
context.trace.report(NEXT_MISSING.on(loopRangeExpression));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
FunctionDescriptor nextFunction = nextResolutionResults.getResultingCall().getResultingDescriptor();
|
|
||||||
context.trace.record(LOOP_RANGE_NEXT, loopRange.getExpression(), nextFunction);
|
|
||||||
return nextFunction.getReturnType();
|
|
||||||
}
|
}
|
||||||
|
return checkConventionForIterator(context, loopRangeExpression, iteratorType, "next", NEXT_AMBIGUITY, NEXT_MISSING,
|
||||||
|
LOOP_RANGE_NEXT_RESOLVED_CALL);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (iteratorResolutionResults.isAmbiguity()) {
|
if (iteratorResolutionResults.isAmbiguity()) {
|
||||||
@@ -380,22 +377,30 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private static FunctionDescriptor checkHasNextFunctionSupport(@NotNull JetExpression loopRange, @NotNull JetType iteratorType, ExpressionTypingContext context) {
|
private static JetType checkConventionForIterator(
|
||||||
OverloadResolutionResults<FunctionDescriptor> hasNextResolutionResults = context.resolveExactSignature(new TransientReceiver(iteratorType), Name.identifier("hasNext"), Collections.<JetType>emptyList());
|
@NotNull ExpressionTypingContext context,
|
||||||
if (hasNextResolutionResults.isAmbiguity()) {
|
@NotNull JetExpression loopRangeExpression,
|
||||||
context.trace.report(HAS_NEXT_FUNCTION_AMBIGUITY.on(loopRange));
|
@NotNull JetType iteratorType,
|
||||||
|
@NotNull String name,
|
||||||
|
@NotNull SimpleDiagnosticFactory<JetExpression> ambiguity,
|
||||||
|
@NotNull SimpleDiagnosticFactory<JetExpression> missing,
|
||||||
|
@NotNull WritableSlice<JetExpression, ResolvedCall<FunctionDescriptor>> call
|
||||||
|
) {
|
||||||
|
OverloadResolutionResults<FunctionDescriptor>
|
||||||
|
nextResolutionResults = context.resolveExactSignature(new TransientReceiver(iteratorType), Name.identifier(name), Collections
|
||||||
|
.<JetType>emptyList());
|
||||||
|
if (nextResolutionResults.isAmbiguity()) {
|
||||||
|
context.trace.report(ambiguity.on(loopRangeExpression));
|
||||||
}
|
}
|
||||||
else if (hasNextResolutionResults.isNothing()) {
|
else if (nextResolutionResults.isNothing()) {
|
||||||
return null;
|
context.trace.report(missing.on(loopRangeExpression));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert hasNextResolutionResults.isSuccess();
|
ResolvedCall<FunctionDescriptor> nextCall = nextResolutionResults.getResultingCall();
|
||||||
JetType hasNextReturnType = hasNextResolutionResults.getResultingDescriptor().getReturnType();
|
context.trace.record(call, loopRangeExpression, nextCall);
|
||||||
if (!isBoolean(hasNextReturnType)) {
|
return nextCall.getResultingDescriptor().getReturnType();
|
||||||
context.trace.report(HAS_NEXT_FUNCTION_TYPE_MISMATCH.on(loopRange, hasNextReturnType));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return hasNextResolutionResults.getResultingCall().getResultingDescriptor();
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+15
-2
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.jet.lang.types.expressions;
|
package org.jetbrains.jet.lang.types.expressions;
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
|
import com.intellij.openapi.util.Pair;
|
||||||
import com.intellij.psi.tree.IElementType;
|
import com.intellij.psi.tree.IElementType;
|
||||||
import com.intellij.psi.tree.TokenSet;
|
import com.intellij.psi.tree.TokenSet;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -28,7 +29,10 @@ import org.jetbrains.jet.lang.resolve.*;
|
|||||||
import org.jetbrains.jet.lang.resolve.calls.CallMaker;
|
import org.jetbrains.jet.lang.resolve.calls.CallMaker;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults;
|
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.inference.*;
|
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintPosition;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemImpl;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintsUtil;
|
||||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||||
@@ -248,11 +252,20 @@ public class ExpressionTypingUtils {
|
|||||||
@NotNull ReceiverDescriptor receiver,
|
@NotNull ReceiverDescriptor receiver,
|
||||||
@NotNull ExpressionTypingContext context,
|
@NotNull ExpressionTypingContext context,
|
||||||
@NotNull Name name
|
@NotNull Name name
|
||||||
|
) {
|
||||||
|
return makeAndResolveFakeCall(receiver, context, name).getSecond();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static Pair<Call, OverloadResolutionResults<FunctionDescriptor>> makeAndResolveFakeCall(
|
||||||
|
@NotNull ReceiverDescriptor receiver,
|
||||||
|
@NotNull ExpressionTypingContext context,
|
||||||
|
@NotNull Name name
|
||||||
) {
|
) {
|
||||||
JetReferenceExpression fake = JetPsiFactory.createSimpleName(context.expressionTypingServices.getProject(), "fake");
|
JetReferenceExpression fake = JetPsiFactory.createSimpleName(context.expressionTypingServices.getProject(), "fake");
|
||||||
BindingTrace fakeTrace = TemporaryBindingTrace.create(context.trace);
|
BindingTrace fakeTrace = TemporaryBindingTrace.create(context.trace);
|
||||||
Call call = CallMaker.makeCall(fake, receiver, null, fake, Collections.<ValueArgument>emptyList());
|
Call call = CallMaker.makeCall(fake, receiver, null, fake, Collections.<ValueArgument>emptyList());
|
||||||
return context.replaceBindingTrace(fakeTrace).resolveCallWithGivenName(call, fake, name);
|
return Pair.create(call, context.replaceBindingTrace(fakeTrace).resolveCallWithGivenName(call, fake, name));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void defineLocalVariablesFromMultiDeclaration(
|
public static void defineLocalVariablesFromMultiDeclaration(
|
||||||
|
|||||||
+7
-7
@@ -20,10 +20,10 @@ import com.google.dart.compiler.backend.js.ast.*;
|
|||||||
import com.intellij.openapi.util.Pair;
|
import com.intellij.openapi.util.Pair;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
import org.jetbrains.jet.lang.psi.JetForExpression;
|
import org.jetbrains.jet.lang.psi.JetForExpression;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||||
import org.jetbrains.k2js.translate.general.Translation;
|
import org.jetbrains.k2js.translate.general.Translation;
|
||||||
import org.jetbrains.k2js.translate.reference.CallBuilder;
|
import org.jetbrains.k2js.translate.reference.CallBuilder;
|
||||||
@@ -61,24 +61,24 @@ public final class IteratorForTranslator extends ForTranslator {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsExpression hasNextMethodInvocation() {
|
private JsExpression hasNextMethodInvocation() {
|
||||||
CallableDescriptor hasNextFunction = getHasNextCallable(bindingContext(), getLoopRange(expression));
|
ResolvedCall<FunctionDescriptor> resolvedCall = getHasNextCallable(bindingContext(), getLoopRange(expression));
|
||||||
return translateMethodInvocation(iterator.second, hasNextFunction);
|
return translateMethodInvocation(iterator.second, resolvedCall);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsExpression iteratorMethodInvocation() {
|
private JsExpression iteratorMethodInvocation() {
|
||||||
JetExpression rangeExpression = getLoopRange(expression);
|
JetExpression rangeExpression = getLoopRange(expression);
|
||||||
JsExpression range = Translation.translateAsExpression(rangeExpression, context());
|
JsExpression range = Translation.translateAsExpression(rangeExpression, context());
|
||||||
FunctionDescriptor iteratorFunction = getIteratorFunction(bindingContext(), rangeExpression);
|
ResolvedCall<FunctionDescriptor> resolvedCall = getIteratorFunction(bindingContext(), rangeExpression);
|
||||||
return translateMethodInvocation(range, iteratorFunction);
|
return translateMethodInvocation(range, resolvedCall);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsExpression translateMethodInvocation(@Nullable JsExpression receiver,
|
private JsExpression translateMethodInvocation(@Nullable JsExpression receiver,
|
||||||
@NotNull CallableDescriptor descriptor) {
|
@NotNull ResolvedCall<FunctionDescriptor> resolvedCall) {
|
||||||
return CallBuilder.build(context())
|
return CallBuilder.build(context())
|
||||||
|
.resolvedCall(resolvedCall)
|
||||||
.receiver(receiver)
|
.receiver(receiver)
|
||||||
.descriptor(descriptor)
|
|
||||||
.translate();
|
.translate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -227,35 +227,30 @@ public final class BindingUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static FunctionDescriptor getIteratorFunction(@NotNull BindingContext context,
|
public static ResolvedCall<FunctionDescriptor> getIteratorFunction(@NotNull BindingContext context,
|
||||||
@NotNull JetExpression rangeExpression) {
|
@NotNull JetExpression rangeExpression) {
|
||||||
FunctionDescriptor functionDescriptor = context.get(BindingContext.LOOP_RANGE_ITERATOR, rangeExpression);
|
ResolvedCall<FunctionDescriptor> resolvedCall = context.get(BindingContext.LOOP_RANGE_ITERATOR_RESOLVED_CALL, rangeExpression);
|
||||||
assert functionDescriptor != null :
|
assert resolvedCall != null :
|
||||||
message(rangeExpression, "Range expression must have a descriptor for iterator function");
|
message(rangeExpression, "Range expression must have a descriptor for iterator function");
|
||||||
return functionDescriptor;
|
return resolvedCall;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static FunctionDescriptor getNextFunction(@NotNull BindingContext context,
|
public static ResolvedCall<FunctionDescriptor> getNextFunction(@NotNull BindingContext context,
|
||||||
@NotNull JetExpression rangeExpression) {
|
@NotNull JetExpression rangeExpression) {
|
||||||
FunctionDescriptor functionDescriptor = context.get(BindingContext.LOOP_RANGE_NEXT, rangeExpression);
|
ResolvedCall<FunctionDescriptor> resolvedCall = context.get(BindingContext.LOOP_RANGE_NEXT_RESOLVED_CALL, rangeExpression);
|
||||||
assert functionDescriptor != null : ErrorReportingUtils
|
assert resolvedCall != null : ErrorReportingUtils
|
||||||
.message(rangeExpression, "Range expression must have a descriptor for next function");
|
.message(rangeExpression, "Range expression must have a descriptor for next function");
|
||||||
return functionDescriptor;
|
return resolvedCall;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static CallableDescriptor getHasNextCallable(@NotNull BindingContext context,
|
public static ResolvedCall<FunctionDescriptor> getHasNextCallable(@NotNull BindingContext context,
|
||||||
@NotNull JetExpression rangeExpression) {
|
@NotNull JetExpression rangeExpression) {
|
||||||
CallableDescriptor hasNextDescriptor = context.get(BindingContext.LOOP_RANGE_HAS_NEXT, rangeExpression);
|
ResolvedCall<FunctionDescriptor> resolvedCall = context.get(BindingContext.LOOP_RANGE_HAS_NEXT_RESOLVED_CALL, rangeExpression);
|
||||||
assert hasNextDescriptor != null
|
assert resolvedCall != null
|
||||||
: message(rangeExpression, "Range expression must have a descriptor for hasNext function or property");
|
: message(rangeExpression, "Range expression must have a descriptor for hasNext function or property");
|
||||||
if (hasNextDescriptor instanceof PropertyDescriptor) {
|
return resolvedCall;
|
||||||
PropertyGetterDescriptor getter = ((PropertyDescriptor) hasNextDescriptor).getGetter();
|
|
||||||
assert getter != null : "Loop range hasNext val should have a getter.";
|
|
||||||
return getter;
|
|
||||||
}
|
|
||||||
return hasNextDescriptor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
Reference in New Issue
Block a user