Multiple conditions in when entries

This commit is contained in:
Andrey Breslav
2011-07-06 19:36:09 +04:00
parent b621e89396
commit d1b8a6b5c7
5 changed files with 54 additions and 13 deletions
@@ -1774,7 +1774,9 @@ public class ExpressionCodegen extends JetVisitor {
} }
nextEntry = new Label(); nextEntry = new Label();
if (!whenEntry.isElse()) { if (!whenEntry.isElse()) {
JetWhenCondition condition = whenEntry.getCondition(); JetWhenCondition[] conditions = whenEntry.getConditions();
assert conditions.length == 1 : "Support many conditions"; // TODO
JetWhenCondition condition = conditions[0];
StackValue conditionValue; StackValue conditionValue;
if (condition instanceof JetWhenConditionWithExpression) { if (condition instanceof JetWhenConditionWithExpression) {
v.load(subjectLocal, subjectType); v.load(subjectLocal, subjectType);
@@ -640,8 +640,11 @@ public class JetControlFlowProcessor {
} }
} }
JetWhenCondition condition = whenEntry.getCondition(); Label bodyLabel = builder.createUnboundLabel();
if (condition != null) {
JetWhenCondition[] conditions = whenEntry.getConditions();
for (int i = 0; i < conditions.length; i++) {
JetWhenCondition condition = conditions[i];
condition.accept(new JetVisitor() { condition.accept(new JetVisitor() {
private final JetVisitor conditionVisitor = this; private final JetVisitor conditionVisitor = this;
@@ -714,10 +717,14 @@ public class JetControlFlowProcessor {
throw new UnsupportedOperationException("[JetControlFlowProcessor] " + element.toString()); throw new UnsupportedOperationException("[JetControlFlowProcessor] " + element.toString());
} }
}); });
if (i + 1 < conditions.length) {
builder.nondeterministicJump(bodyLabel);
}
} }
builder.nondeterministicJump(nextLabel); builder.nondeterministicJump(nextLabel);
builder.bindLabel(bodyLabel);
value(whenEntry.getExpression(), true, inCondition); value(whenEntry.getExpression(), true, inCondition);
builder.jump(doneLabel); builder.jump(doneLabel);
builder.bindLabel(nextLabel); builder.bindLabel(nextLabel);
@@ -771,4 +778,4 @@ public class JetControlFlowProcessor {
// Nothing // Nothing
} }
}; };
} }
@@ -38,8 +38,8 @@ public class JetWhenEntry extends JetElement {
visitor.visitWhenEntry(this); visitor.visitWhenEntry(this);
} }
@Nullable @NotNull
public JetWhenCondition getCondition() { public JetWhenCondition[] getConditions() {
return findChildByClass(JetWhenCondition.class); return findChildrenByClass(JetWhenCondition.class);
} }
} }
@@ -764,7 +764,7 @@ public class JetTypeInferrer {
return getTypeWithNewContext(expression, new TypeInferenceContext(context.trace, scope, preferBlock, context.dataFlowInfo, context.expectedType, context.expectedReturnType)); return getTypeWithNewContext(expression, new TypeInferenceContext(context.trace, scope, preferBlock, context.dataFlowInfo, context.expectedType, context.expectedReturnType));
} }
private JetType getTypeWithNewDataFlowInfo(JetScope scope, JetExpression expression, boolean preferBlock, DataFlowInfo newDataFlowInfo) { private JetType getTypeWithNewDataFlowInfo(JetScope scope, JetExpression expression, boolean preferBlock, @NotNull DataFlowInfo newDataFlowInfo) {
return getTypeWithNewContext(expression, new TypeInferenceContext(context.trace, scope, preferBlock, newDataFlowInfo, context.expectedType, context.expectedReturnType)); return getTypeWithNewContext(expression, new TypeInferenceContext(context.trace, scope, preferBlock, newDataFlowInfo, context.expectedType, context.expectedReturnType));
} }
@@ -1294,11 +1294,35 @@ public class JetTypeInferrer {
Set<JetType> expressionTypes = Sets.newHashSet(); Set<JetType> expressionTypes = Sets.newHashSet();
for (JetWhenEntry whenEntry : expression.getEntries()) { for (JetWhenEntry whenEntry : expression.getEntries()) {
JetWhenCondition condition = whenEntry.getCondition(); JetWhenCondition[] conditions = whenEntry.getConditions();
WritableScope scopeToExtend = newWritableScopeImpl().setDebugName("Scope extended in when entry"); DataFlowInfo newDataFlowInfo;
DataFlowInfo newDataFlowInfo = context.dataFlowInfo; WritableScope scopeToExtend;
if (condition != null) { if (conditions.length == 1) {
newDataFlowInfo = checkWhenCondition(subjectExpression, subjectType, condition, scopeToExtend, variableDescriptor); scopeToExtend = newWritableScopeImpl().setDebugName("Scope extended in when entry");
newDataFlowInfo = context.dataFlowInfo;
JetWhenCondition condition = conditions[0];
if (condition != null) {
newDataFlowInfo = checkWhenCondition(subjectExpression, subjectType, condition, scopeToExtend, variableDescriptor);
}
}
else {
scopeToExtend = newWritableScopeImpl(); // We don't write to this scope
newDataFlowInfo = null;
for (JetWhenCondition condition : conditions) {
DataFlowInfo dataFlowInfo = checkWhenCondition(subjectExpression, subjectType, condition, newWritableScopeImpl(), variableDescriptor);
if (newDataFlowInfo == null) {
newDataFlowInfo = dataFlowInfo;
}
else {
newDataFlowInfo = newDataFlowInfo.or(dataFlowInfo);
}
}
if (newDataFlowInfo == null) {
newDataFlowInfo = context.dataFlowInfo;
}
else {
newDataFlowInfo = newDataFlowInfo.and(context.dataFlowInfo);
}
} }
JetWhenExpression subWhen = whenEntry.getSubWhen(); JetWhenExpression subWhen = whenEntry.getSubWhen();
JetExpression bodyExpression = subWhen == null ? whenEntry.getExpression() : subWhen; JetExpression bodyExpression = subWhen == null ? whenEntry.getExpression() : subWhen;
@@ -0,0 +1,8 @@
fun set(key : String, value : String) {
val a : String? = ""
when (a) {
"" => a<error>.</error>get(0)
is String, is Any => a.compareTo("")
else => a.toString()
}
}