pattern matching for tuple and expression patterns
This commit is contained in:
@@ -1634,6 +1634,17 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
StackValue value = StackValue.onStack(Type.BOOLEAN_TYPE);
|
||||
return negated ? StackValue.not(value) : value;
|
||||
}
|
||||
else if (pattern instanceof JetTuplePattern) {
|
||||
return generateTuplePatternMatch((JetTuplePattern) pattern, negated, expressionToMatch);
|
||||
}
|
||||
else if (pattern instanceof JetExpressionPattern) {
|
||||
final Type subjectType = expressionToMatch.type;
|
||||
expressionToMatch.put(subjectType, v);
|
||||
JetExpression condExpression = ((JetExpressionPattern) pattern).getExpression();
|
||||
gen(condExpression, OBJECT_TYPE);
|
||||
generateEqualsForExpressionsOnStack(JetTokens.EQEQ, subjectType, OBJECT_TYPE);
|
||||
return myStack.pop();
|
||||
}
|
||||
else if (pattern instanceof JetWildcardPattern) {
|
||||
return StackValue.constant(!negated, Type.BOOLEAN_TYPE);
|
||||
}
|
||||
@@ -1642,6 +1653,41 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
private StackValue generateTuplePatternMatch(JetTuplePattern pattern, boolean negated, StackValue expressionToMatch) {
|
||||
final List<JetTuplePatternEntry> entries = pattern.getEntries();
|
||||
Label lblFail = new Label();
|
||||
Label lblDone = new Label();
|
||||
expressionToMatch.put(OBJECT_TYPE, v);
|
||||
v.dup();
|
||||
final String tupleClassName = "jet/Tuple" + entries.size();
|
||||
Type tupleType = Type.getObjectType(tupleClassName);
|
||||
v.instanceOf(tupleType);
|
||||
Label lblCheck = new Label();
|
||||
v.ifne(lblCheck);
|
||||
Label lblPopAndFail = new Label();
|
||||
v.mark(lblPopAndFail);
|
||||
v.pop();
|
||||
v.goTo(lblFail);
|
||||
|
||||
v.mark(lblCheck);
|
||||
for (int i = 0; i < entries.size(); i++) {
|
||||
final boolean isLast = i == entries.size() - 1;
|
||||
if (!isLast) {
|
||||
v.dup();
|
||||
}
|
||||
final StackValue tupleField = StackValue.field(OBJECT_TYPE, tupleClassName, "_" + (i + 1), false);
|
||||
final StackValue stackValue = generatePatternMatch(entries.get(i).getPattern(), false, tupleField);
|
||||
stackValue.condJump(isLast ? lblFail : lblPopAndFail, true, v);
|
||||
}
|
||||
|
||||
v.aconst(!negated);
|
||||
v.goTo(lblDone);
|
||||
v.mark(lblFail);
|
||||
v.aconst(negated);
|
||||
v.mark(lblDone);
|
||||
return StackValue.onStack(Type.BOOLEAN_TYPE);
|
||||
}
|
||||
|
||||
private void generateInstanceOf(StackValue expressionToGen, JetType jetType, boolean leaveExpressionOnStack) {
|
||||
DeclarationDescriptor descriptor = jetType.getConstructor().getDeclarationDescriptor();
|
||||
if (jetType.getArguments().size() > 0 || !(descriptor instanceof ClassDescriptor)) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import jet.NoPatternMatchedException;
|
||||
import jet.Tuple2;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
@@ -61,4 +62,11 @@ public class PatternMatchingTest extends CodegenTestCase {
|
||||
Method foo = generateFunction();
|
||||
assertEquals("x", foo.invoke(null, ""));
|
||||
}
|
||||
|
||||
public void testTuplePattern() throws Exception {
|
||||
loadText("fun foo(x: Tuple2<Any, Any>) = when(x) { is (1,2) => \"one,two\"; else => \"something\" }");
|
||||
Method foo = generateFunction();
|
||||
assertEquals("one,two", foo.invoke(null, new Tuple2<Integer, Integer>(1, 2)));
|
||||
assertEquals("something", foo.invoke(null, new Tuple2<String, String>("not", "tuple")));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user