From e1fb5a9a0483ba4f7afa558f25c5f0b3c5a67cd0 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Tue, 1 Jul 2014 15:45:10 +0400 Subject: [PATCH] Added 'isExternal' to ValueArgument 'subject' is external for 'in(contains)' resolve in 'when' condition: when (subject) { in range -> ... } --- .../jet/lang/psi/JetValueArgument.java | 5 +++++ .../jetbrains/jet/lang/psi/ValueArgument.java | 3 +++ .../jet/lang/resolve/calls/CallCompleter.kt | 7 ++----- .../lang/resolve/calls/util/CallMaker.java | 21 +++++++++++++++++-- .../BasicExpressionTypingVisitor.java | 13 ++++++------ .../ExpressionTypingInternals.java | 12 +++++++---- .../ExpressionTypingVisitorDispatcher.java | 10 +++++++-- .../PatternMatchingTypingVisitor.java | 11 +++++----- 8 files changed, 57 insertions(+), 25 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetValueArgument.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetValueArgument.java index 812a245abf1..da5346eb60e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetValueArgument.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetValueArgument.java @@ -61,4 +61,9 @@ public class JetValueArgument extends JetElementImpl implements ValueArgument { ASTNode node = getNode().findChildByType(JetTokens.MUL); return node == null ? null : (LeafPsiElement) node.getPsi(); } + + @Override + public boolean isExternal() { + return false; + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/ValueArgument.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/ValueArgument.java index 2fe0c487141..1a5e2512552 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/ValueArgument.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/ValueArgument.java @@ -36,4 +36,7 @@ public interface ValueArgument { /* The '*' in something like foo(*arr) i.e. pass an array as a number of vararg arguments */ @Nullable LeafPsiElement getSpreadElement(); + + /* The argument is placed externally to call element, e.g. in 'when' condition with subject: 'when (a) { in c -> }' */ + boolean isExternal(); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallCompleter.kt b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallCompleter.kt index 348e7851dd8..c83f03aaea3 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallCompleter.kt +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallCompleter.kt @@ -226,14 +226,11 @@ public class CallCompleter( valueArgument: ValueArgument, context: BasicCallResolutionContext ) { + if (valueArgument.isExternal()) return + val expression = valueArgument.getArgumentExpression() if (expression == null) return - // for the 'in' call 'when (b) { in 1..10 -> true }' 'b' is an argument, but an error shouldn't be generated on it - // todo add special call type for such a case, and check this call type instead - val parent = expression.getParent() - if (parent is JetWhenExpression && expression == parent.getSubjectExpression()) return - val recordedType = context.trace[BindingContext.EXPRESSION_TYPE, expression] var updatedType: JetType? = recordedType diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/util/CallMaker.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/util/CallMaker.java index 4ae7105d09a..aac330e9dc4 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/util/CallMaker.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/util/CallMaker.java @@ -37,9 +37,21 @@ public class CallMaker { private final JetElement reportErrorsOn; - private ExpressionValueArgument(@Nullable JetExpression expression, @NotNull JetElement reportErrorsOn) { + private final boolean isExternal; + + private ExpressionValueArgument( + @Nullable JetExpression expression, + @NotNull JetElement reportErrorsOn, + boolean isExternal + ) { this.expression = expression; this.reportErrorsOn = expression == null ? reportErrorsOn : expression; + this.isExternal = isExternal; + } + + @Override + public boolean isExternal() { + return isExternal; } @Override @@ -236,7 +248,12 @@ public class CallMaker { @NotNull public static ValueArgument makeValueArgument(@Nullable JetExpression expression, @NotNull JetElement reportErrorsOn) { - return new ExpressionValueArgument(expression, reportErrorsOn); + return new ExpressionValueArgument(expression, reportErrorsOn, false); + } + + @NotNull + public static ValueArgument makeExternalValueArgument(@NotNull JetExpression expression) { + return new ExpressionValueArgument(expression, expression, true); } @NotNull diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java index 59cbb914568..4a34eec37c6 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java @@ -40,10 +40,7 @@ import org.jetbrains.jet.lang.resolve.calls.autocasts.Nullability; import org.jetbrains.jet.lang.resolve.calls.context.BasicCallResolutionContext; import org.jetbrains.jet.lang.resolve.calls.context.CheckValueArgumentsMode; import org.jetbrains.jet.lang.resolve.calls.context.TemporaryTraceAndCache; -import org.jetbrains.jet.lang.resolve.calls.model.DataFlowInfoForArgumentsImpl; -import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; -import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl; -import org.jetbrains.jet.lang.resolve.calls.model.VariableAsFunctionResolvedCall; +import org.jetbrains.jet.lang.resolve.calls.model.*; import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults; import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl; import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsUtil; @@ -908,7 +905,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { result = JetTypeInfo.create(KotlinBuiltIns.getInstance().getBooleanType(), context.dataFlowInfo); } else if (OperatorConventions.IN_OPERATIONS.contains(operationType)) { - result = checkInExpression(expression, operationSign, left, right, context); + ValueArgument leftArgument = CallMaker.makeValueArgument(left, left != null ? left : operationSign); + result = checkInExpression(expression, operationSign, leftArgument, right, context); } else if (OperatorConventions.BOOLEAN_OPERATIONS.containsKey(operationType)) { result = visitBooleanOperationExpression(operationType, left, right, context); @@ -1076,10 +1074,11 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { public JetTypeInfo checkInExpression( @NotNull JetElement callElement, @NotNull JetSimpleNameExpression operationSign, - @Nullable JetExpression left, + @NotNull ValueArgument leftArgument, @Nullable JetExpression right, @NotNull ExpressionTypingContext context ) { + JetExpression left = leftArgument.getArgumentExpression(); ExpressionTypingContext contextWithNoExpectedType = context.replaceExpectedType(NO_EXPECTED_TYPE); if (right == null) { if (left != null) facade.getTypeInfo(left, contextWithNoExpectedType); @@ -1093,7 +1092,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { OverloadResolutionResults resolutionResult = components.callResolver.resolveCallWithGivenName( contextWithDataFlow, - CallMaker.makeCallWithExpressions(callElement, receiver, null, operationSign, Collections.singletonList(left)), + CallMaker.makeCall(callElement, receiver, null, operationSign, Collections.singletonList(leftArgument)), operationSign, OperatorConventions.CONTAINS); JetType containsType = OverloadResolutionResultsUtil.getResultingType(resolutionResult, context.contextDependency); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingInternals.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingInternals.java index e6432ee9744..b52cb21bd0c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingInternals.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingInternals.java @@ -18,14 +18,18 @@ package org.jetbrains.jet.lang.types.expressions; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.psi.JetElement; -import org.jetbrains.jet.lang.psi.JetExpression; -import org.jetbrains.jet.lang.psi.JetSimpleNameExpression; +import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.types.JetTypeInfo; /*package*/ interface ExpressionTypingInternals extends ExpressionTypingFacade { @NotNull - JetTypeInfo checkInExpression(JetElement callElement, @NotNull JetSimpleNameExpression operationSign, @Nullable JetExpression left, @NotNull JetExpression right, ExpressionTypingContext context); + JetTypeInfo checkInExpression( + @NotNull JetElement callElement, + @NotNull JetSimpleNameExpression operationSign, + @NotNull ValueArgument leftArgument, + @Nullable JetExpression right, + @NotNull ExpressionTypingContext context + ); void checkStatementType(@NotNull JetExpression expression, ExpressionTypingContext context); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorDispatcher.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorDispatcher.java index 0520dd70654..f660736d157 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorDispatcher.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorDispatcher.java @@ -74,8 +74,14 @@ public class ExpressionTypingVisitorDispatcher extends JetVisitor