Added 'isExternal' to ValueArgument
'subject' is external for 'in(contains)' resolve in 'when' condition:
when (subject) {
in range -> ...
}
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
+6
-7
@@ -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<FunctionDescriptor> 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);
|
||||
|
||||
+8
-4
@@ -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);
|
||||
|
||||
|
||||
+8
-2
@@ -74,8 +74,14 @@ public class ExpressionTypingVisitorDispatcher extends JetVisitor<JetTypeInfo, E
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JetTypeInfo checkInExpression(JetElement callElement, @NotNull JetSimpleNameExpression operationSign, @Nullable JetExpression left, @NotNull JetExpression right, ExpressionTypingContext context) {
|
||||
return basic.checkInExpression(callElement, operationSign, left, right, context);
|
||||
public JetTypeInfo checkInExpression(
|
||||
@NotNull JetElement callElement,
|
||||
@NotNull JetSimpleNameExpression operationSign,
|
||||
@NotNull ValueArgument leftArgument,
|
||||
@Nullable JetExpression right,
|
||||
@NotNull ExpressionTypingContext context
|
||||
) {
|
||||
return basic.checkInExpression(callElement, operationSign, leftArgument, right, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+6
-5
@@ -28,6 +28,7 @@ import org.jetbrains.jet.lang.resolve.TypeResolutionContext;
|
||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowValue;
|
||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowValueFactory;
|
||||
import org.jetbrains.jet.lang.resolve.calls.util.CallMaker;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||
@@ -148,7 +149,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
|
||||
|
||||
DataFlowInfos infos = null;
|
||||
for (JetWhenCondition condition : whenEntry.getConditions()) {
|
||||
DataFlowInfos conditionInfos = checkWhenCondition(subjectExpression, subjectExpression == null, subjectType, condition,
|
||||
DataFlowInfos conditionInfos = checkWhenCondition(subjectExpression, subjectType, condition,
|
||||
context, subjectDataFlowValue);
|
||||
if (infos != null) {
|
||||
infos = new DataFlowInfos(infos.thenInfo.or(conditionInfos.thenInfo), infos.elseInfo.and(conditionInfos.elseInfo));
|
||||
@@ -162,7 +163,6 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
|
||||
|
||||
private DataFlowInfos checkWhenCondition(
|
||||
@Nullable final JetExpression subjectExpression,
|
||||
final boolean expectedCondition,
|
||||
final JetType subjectType,
|
||||
JetWhenCondition condition,
|
||||
final ExpressionTypingContext context,
|
||||
@@ -174,14 +174,15 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
|
||||
public void visitWhenConditionInRange(@NotNull JetWhenConditionInRange condition) {
|
||||
JetExpression rangeExpression = condition.getRangeExpression();
|
||||
if (rangeExpression == null) return;
|
||||
if (expectedCondition) {
|
||||
if (subjectExpression == null) {
|
||||
context.trace.report(EXPECTED_CONDITION.on(condition));
|
||||
DataFlowInfo dataFlowInfo = facade.getTypeInfo(rangeExpression, context).getDataFlowInfo();
|
||||
newDataFlowInfo.set(new DataFlowInfos(dataFlowInfo, dataFlowInfo));
|
||||
return;
|
||||
}
|
||||
ValueArgument argumentForSubject = CallMaker.makeExternalValueArgument(subjectExpression);
|
||||
JetTypeInfo typeInfo = facade.checkInExpression(condition, condition.getOperationReference(),
|
||||
subjectExpression, rangeExpression, context);
|
||||
argumentForSubject, rangeExpression, context);
|
||||
DataFlowInfo dataFlowInfo = typeInfo.getDataFlowInfo();
|
||||
newDataFlowInfo.set(new DataFlowInfos(dataFlowInfo, dataFlowInfo));
|
||||
if (!KotlinBuiltIns.getInstance().getBooleanType().equals(typeInfo.getType())) {
|
||||
@@ -191,7 +192,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
|
||||
|
||||
@Override
|
||||
public void visitWhenConditionIsPattern(@NotNull JetWhenConditionIsPattern condition) {
|
||||
if (expectedCondition) {
|
||||
if (subjectExpression == null) {
|
||||
context.trace.report(EXPECTED_CONDITION.on(condition));
|
||||
}
|
||||
if (condition.getTypeRef() != null) {
|
||||
|
||||
Reference in New Issue
Block a user