Added utility method to check if variable is iterable.

This commit is contained in:
Evgeny Gerashchenko
2012-02-09 21:45:43 +04:00
parent 3c1758c041
commit 447114f063
2 changed files with 30 additions and 4 deletions
@@ -264,7 +264,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
}
@Nullable
private JetType checkIterableConvention(@NotNull ExpressionReceiver loopRange, ExpressionTypingContext context) {
/*package*/ static JetType checkIterableConvention(@NotNull ExpressionReceiver loopRange, ExpressionTypingContext context) {
JetExpression loopRangeExpression = loopRange.getExpression();
// Make a fake call loopRange.iterator(), and try to resolve it
@@ -328,7 +328,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
return null;
}
private OverloadResolutionResults<FunctionDescriptor> resolveFakeCall(ExpressionReceiver receiver, ExpressionTypingContext context, String name) {
private static OverloadResolutionResults<FunctionDescriptor> resolveFakeCall(ExpressionReceiver receiver, ExpressionTypingContext context, String name) {
JetReferenceExpression fake = JetPsiFactory.createSimpleName(context.getProject(), "fake");
BindingTrace fakeTrace = new BindingTraceContext();
Call call = CallMaker.makeCall(fake, receiver, null, fake, Collections.<ValueArgument>emptyList());
@@ -336,7 +336,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
}
@Nullable
private FunctionDescriptor checkHasNextFunctionSupport(@NotNull JetExpression loopRange, @NotNull JetType iteratorType, ExpressionTypingContext context) {
private static FunctionDescriptor checkHasNextFunctionSupport(@NotNull JetExpression loopRange, @NotNull JetType iteratorType, ExpressionTypingContext context) {
OverloadResolutionResults<FunctionDescriptor> hasNextResolutionResults = context.resolveExactSignature(new TransientReceiver(iteratorType), "hasNext", Collections.<JetType>emptyList());
if (hasNextResolutionResults.isAmbiguity()) {
context.trace.report(HAS_NEXT_FUNCTION_AMBIGUITY.on(loopRange));
@@ -353,7 +353,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
}
@Nullable
private VariableDescriptor checkHasNextPropertySupport(@NotNull JetExpression loopRange, @NotNull JetType iteratorType, ExpressionTypingContext context) {
private static VariableDescriptor checkHasNextPropertySupport(@NotNull JetExpression loopRange, @NotNull JetType iteratorType, ExpressionTypingContext context) {
VariableDescriptor hasNextProperty = DescriptorUtils.filterNonExtensionProperty(iteratorType.getMemberScope().getProperties("hasNext"));
if (hasNextProperty == null) {
return null;
@@ -11,16 +11,24 @@ import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetPattern;
import org.jetbrains.jet.lang.psi.JetPsiFactory;
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.BindingTraceContext;
import org.jetbrains.jet.lang.resolve.TraceBasedRedeclarationHandler;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.jet.lang.types.JetStandardClasses;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeUtils;
import java.util.HashMap;
import java.util.List;
import static org.jetbrains.jet.lang.diagnostics.Errors.RESULT_TYPE_MISMATCH;
import static org.jetbrains.jet.lang.resolve.BindingContext.*;
@@ -126,4 +134,22 @@ public class ExpressionTypingUtils {
trace.record(EXPRESSION_TYPE, expression, type);
return expression;
}
public static boolean isVariableIterable(@NotNull Project project, @NotNull VariableDescriptor variableDescriptor, @NotNull JetScope scope) {
JetExpression expression = JetPsiFactory.createExpression(project, "fake");
ExpressionReceiver expressionReceiver = new ExpressionReceiver(expression, variableDescriptor.getOutType());
ExpressionTypingContext context = ExpressionTypingContext.newContext(
JetSemanticServices.createSemanticServices(project),
new HashMap<JetPattern, DataFlowInfo>(),
new HashMap<JetPattern, List<VariableDescriptor>>(),
new LabelResolver(),
new BindingTraceContext(),
scope,
DataFlowInfo.EMPTY,
TypeUtils.NO_EXPECTED_TYPE,
TypeUtils.NO_EXPECTED_TYPE,
false
);
return ControlStructureTypingVisitor.checkIterableConvention(expressionReceiver, context) != null;
}
}