[cfe] Desugar BinaryPattern
Part of https://github.com/dart-lang/sdk/issues/49749
Change-Id: I98dd7d63c560eb4c48350c32826e51df1491d9d9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/271708
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index edc8f99..a3764b3 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -2616,19 +2616,32 @@
reportIfNotEnabled(
libraryFeatures.patterns, token.charOffset, token.charCount);
// ignore: unused_local_variable
- Pattern left = toPattern(pop());
- // ignore: unused_local_variable
Pattern right = toPattern(pop());
+ // ignore: unused_local_variable
+ Pattern left = toPattern(pop());
// TODO(johnniwinther): Create a binary pattern.
String operator = token.lexeme;
- BinaryPatternKind kind;
switch (operator) {
case '&':
- kind = BinaryPatternKind.and;
+ push(new AndPattern(left, right, token.charOffset));
break;
case '|':
- kind = BinaryPatternKind.or;
+ Map<String, VariableDeclaration> leftVariablesByName = {
+ for (VariableDeclaration leftVariable in left.declaredVariables)
+ leftVariable.name!: leftVariable
+ };
+ if (!leftVariablesByName.keys.toSet().containsAll(
+ right.declaredVariables.map((variable) => variable.name!)) &&
+ leftVariablesByName.length == right.declaredVariables.length) {
+ // TODO(cstefantsova): Report a compile-time error.
+ }
+ push(new OrPattern(left, right, token.charOffset,
+ orPatternJointVariables: [
+ for (VariableDeclaration leftVariable in left.declaredVariables)
+ forest.createVariableDeclaration(
+ leftVariable.fileOffset, leftVariable.name)
+ ]));
break;
default:
internalProblem(
@@ -2637,7 +2650,6 @@
token.charOffset,
uri);
}
- push(new BinaryPattern(left, kind, right, token.charOffset));
}
void doBinaryExpression(Token token) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/forest.dart b/pkg/front_end/lib/src/fasta/kernel/forest.dart
index b83a9f9..cf5d623 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forest.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forest.dart
@@ -413,8 +413,11 @@
/// [fileOffset]. The [condition] is the expression preceding the question
/// mark. The [thenExpression] is the expression following the question mark.
/// The [elseExpression] is the expression following the colon.
- Expression createConditionalExpression(int fileOffset, Expression condition,
- Expression thenExpression, Expression elseExpression) {
+ ConditionalExpression createConditionalExpression(
+ int fileOffset,
+ Expression condition,
+ Expression thenExpression,
+ Expression elseExpression) {
return new ConditionalExpression(
condition, thenExpression, elseExpression, const UnknownType())
..fileOffset = fileOffset;
diff --git a/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart b/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
index de8361f5..3c9e153 100644
--- a/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
@@ -5117,7 +5117,9 @@
InferenceVisitorBase inferenceVisitor) {
return new PatternTransformationResult([
new PatternTransformationElement(
- condition: null, variableInitializers: <Statement>[])
+ kind: PatternTransformationElementKind.regular,
+ condition: null,
+ variableInitializers: <Statement>[])
]);
}
@@ -5166,7 +5168,9 @@
target.member as Procedure);
return new PatternTransformationResult([
new PatternTransformationElement(
- condition: result, variableInitializers: [])
+ kind: PatternTransformationElementKind.regular,
+ condition: result,
+ variableInitializers: [])
]);
}
@@ -5181,23 +5185,16 @@
}
}
-enum BinaryPatternKind {
- and,
- or,
-}
-
-/// A [Pattern] for `pattern | pattern` and `pattern & pattern`.
-class BinaryPattern extends Pattern {
+/// A [Pattern] for `pattern & pattern`.
+class AndPattern extends Pattern {
Pattern left;
- BinaryPatternKind kind;
Pattern right;
@override
List<VariableDeclaration> get declaredVariables =>
[...left.declaredVariables, ...right.declaredVariables];
- BinaryPattern(this.left, this.kind, this.right, int fileOffset)
- : super(fileOffset) {
+ AndPattern(this.left, this.right, int fileOffset) : super(fileOffset) {
left.parent = this;
right.parent = this;
}
@@ -5208,7 +5205,7 @@
required DartType matchedType,
required SharedMatchContext context,
}) {
- return visitor.visitBinaryPattern(this,
+ return visitor.visitAndPattern(this,
matchedType: matchedType, context: context);
}
@@ -5218,25 +5215,277 @@
DartType matchedType,
Expression variableInitializingContext,
InferenceVisitorBase inferenceVisitor) {
- return new PatternTransformationResult([
- new PatternTransformationElement(
- condition:
- new InvalidExpression("Unimplemented BinaryPattern.transform"),
- variableInitializers: [])
- ]);
+ // intermediateVariable: `matchedType` VAR = `matchedExpression`
+ VariableDeclaration intermediateVariable = inferenceVisitor.engine.forest
+ .createVariableDeclarationForValue(matchedExpression,
+ type: matchedType);
+
+ PatternTransformationResult transformationResult = left.transform(
+ inferenceVisitor.engine.forest
+ .createVariableGet(fileOffset, intermediateVariable),
+ matchedType,
+ inferenceVisitor.engine.forest
+ .createVariableGet(fileOffset, intermediateVariable),
+ inferenceVisitor);
+
+ transformationResult = transformationResult.combine(
+ right.transform(
+ inferenceVisitor.engine.forest
+ .createVariableGet(fileOffset, intermediateVariable),
+ matchedType,
+ inferenceVisitor.engine.forest
+ .createVariableGet(fileOffset, intermediateVariable),
+ inferenceVisitor),
+ inferenceVisitor);
+
+ transformationResult = transformationResult.prependElement(
+ new PatternTransformationElement(
+ kind: PatternTransformationElementKind.regular,
+ condition: null,
+ variableInitializers: [intermediateVariable]),
+ inferenceVisitor);
+
+ return transformationResult;
}
@override
void toTextInternal(AstPrinter printer) {
left.toTextInternal(printer);
- switch (kind) {
- case BinaryPatternKind.and:
- printer.write(' & ');
- break;
- case BinaryPatternKind.or:
- printer.write(' | ');
- break;
+ printer.write(' & ');
+ right.toTextInternal(printer);
+ }
+
+ @override
+ String toString() {
+ return "BinaryPattern(${toStringInternal()})";
+ }
+}
+
+/// A [Pattern] for `pattern | pattern`.
+class OrPattern extends Pattern {
+ Pattern left;
+ Pattern right;
+ List<VariableDeclaration> _orPatternJointVariables;
+
+ @override
+ List<VariableDeclaration> get declaredVariables => _orPatternJointVariables;
+
+ OrPattern(this.left, this.right, int fileOffset,
+ {required List<VariableDeclaration> orPatternJointVariables})
+ : _orPatternJointVariables = orPatternJointVariables,
+ super(fileOffset) {
+ left.parent = this;
+ right.parent = this;
+ }
+
+ @override
+ PatternInferenceResult acceptInference(
+ InferenceVisitorImpl visitor, {
+ required DartType matchedType,
+ required SharedMatchContext context,
+ }) {
+ return visitor.visitOrPattern(this,
+ matchedType: matchedType, context: context);
+ }
+
+ @override
+ PatternTransformationResult transform(
+ Expression matchedExpression,
+ DartType matchedType,
+ Expression variableInitializingContext,
+ InferenceVisitorBase inferenceVisitor) {
+ // intermediateVariable: `matchedType` VAR = `matchedExpression`
+ VariableDeclaration intermediateVariable = inferenceVisitor.engine.forest
+ .createVariableDeclarationForValue(matchedExpression,
+ type: matchedType);
+
+ // leftConditionIsTrue: bool LVAR = false;
+ VariableDeclaration leftConditionIsTrue = inferenceVisitor.engine.forest
+ .createVariableDeclarationForValue(
+ inferenceVisitor.engine.forest.createBoolLiteral(fileOffset, false),
+ type: inferenceVisitor.coreTypes.boolNonNullableRawType);
+
+ Map<String, VariableDeclaration> leftVariablesByName = {
+ for (VariableDeclaration variable in left.declaredVariables)
+ variable.name!: variable
+ };
+ Map<String, VariableDeclaration> rightVariablesByName = {
+ for (VariableDeclaration variable in right.declaredVariables)
+ variable.name!: variable
+ };
+ List<VariableDeclaration> declaredVariables = this.declaredVariables;
+ for (VariableDeclaration variable in declaredVariables) {
+ VariableDeclaration leftVariable = leftVariablesByName[variable.name!]!;
+ VariableDeclaration rightVariable = rightVariablesByName[variable.name!]!;
+ variable.initializer = inferenceVisitor.engine.forest
+ .createConditionalExpression(
+ fileOffset,
+ inferenceVisitor.engine.forest.createVariableGet(
+ fileOffset, leftConditionIsTrue),
+ inferenceVisitor.engine.forest
+ .createVariableGet(fileOffset, leftVariable)
+ ..promotedType = leftVariable.type,
+ inferenceVisitor.engine.forest
+ .createVariableGet(fileOffset, rightVariable)
+ ..promotedType = rightVariable.type)
+ ..staticType = inferenceVisitor.typeSchemaEnvironment
+ .getStandardUpperBound(leftVariable.type, rightVariable.type,
+ inferenceVisitor.libraryBuilder.library)
+ ..parent = variable;
}
+
+ // setLeftConditionIsTrue: `leftConditionIsTrue` = true;
+ // ==> VAR = true;
+ Statement setLeftConditionIsTrue = inferenceVisitor.engine.forest
+ .createExpressionStatement(
+ fileOffset,
+ inferenceVisitor.engine.forest.createVariableSet(
+ fileOffset,
+ leftConditionIsTrue,
+ inferenceVisitor.engine.forest
+ .createBoolLiteral(fileOffset, true)));
+
+ PatternTransformationResult leftTransformationResult = left.transform(
+ inferenceVisitor.engine.forest
+ .createVariableGet(fileOffset, intermediateVariable),
+ matchedType,
+ inferenceVisitor.engine.forest
+ .createVariableGet(fileOffset, intermediateVariable),
+ inferenceVisitor);
+ leftTransformationResult = leftTransformationResult.prependElement(
+ new PatternTransformationElement(
+ kind: PatternTransformationElementKind.logicalOrPatternLeftBegin,
+ condition: null,
+ variableInitializers: []),
+ inferenceVisitor);
+ // Initialize variables to values captured by [left].
+ leftTransformationResult = leftTransformationResult.combine(
+ new PatternTransformationResult([
+ new PatternTransformationElement(
+ kind: PatternTransformationElementKind.regular,
+ condition: null,
+ variableInitializers: [
+ setLeftConditionIsTrue,
+ for (VariableDeclaration variable in left.declaredVariables)
+ inferenceVisitor.engine.forest.createExpressionStatement(
+ fileOffset,
+ inferenceVisitor.engine.forest.createVariableSet(
+ fileOffset, variable, variable.initializer!))
+ ])
+ ]),
+ inferenceVisitor);
+ for (VariableDeclaration variable in left.declaredVariables) {
+ variable.name = null;
+ variable.initializer = null;
+ variable.type = const DynamicType();
+ }
+
+ // rightConditionIsTrue: bool RVAR = false;
+ VariableDeclaration rightConditionIsTrue = inferenceVisitor.engine.forest
+ .createVariableDeclarationForValue(
+ inferenceVisitor.engine.forest.createBoolLiteral(fileOffset, false),
+ type: inferenceVisitor.coreTypes.boolNonNullableRawType);
+
+ // setRightConditionIsTrue: `rightConditionIsTrue` = true;
+ // ==> VAR = true;
+ Statement setRightConditionIsTrue = inferenceVisitor.engine.forest
+ .createExpressionStatement(
+ fileOffset,
+ inferenceVisitor.engine.forest.createVariableSet(
+ fileOffset,
+ rightConditionIsTrue,
+ inferenceVisitor.engine.forest
+ .createBoolLiteral(fileOffset, true)));
+
+ PatternTransformationResult rightTransformationResult = right.transform(
+ inferenceVisitor.engine.forest
+ .createVariableGet(fileOffset, intermediateVariable),
+ matchedType,
+ inferenceVisitor.engine.forest
+ .createVariableGet(fileOffset, intermediateVariable),
+ inferenceVisitor);
+ rightTransformationResult = rightTransformationResult.prependElement(
+ new PatternTransformationElement(
+ kind: PatternTransformationElementKind.regular,
+ // condition: !`leftConditionIsTrue`
+ condition: inferenceVisitor.engine.forest.createNot(
+ fileOffset,
+ inferenceVisitor.engine.forest
+ .createVariableGet(fileOffset, leftConditionIsTrue)),
+ variableInitializers: []),
+ inferenceVisitor);
+ rightTransformationResult = rightTransformationResult.prependElement(
+ new PatternTransformationElement(
+ kind: PatternTransformationElementKind.logicalOrPatternRightBegin,
+ condition: null,
+ variableInitializers: []),
+ inferenceVisitor);
+ // Initialize variables to values captured by [right].
+ rightTransformationResult = rightTransformationResult.combine(
+ new PatternTransformationResult([
+ new PatternTransformationElement(
+ kind: PatternTransformationElementKind.regular,
+ condition: null,
+ variableInitializers: [
+ setRightConditionIsTrue,
+ for (VariableDeclaration variable in right.declaredVariables)
+ inferenceVisitor.engine.forest.createExpressionStatement(
+ fileOffset,
+ inferenceVisitor.engine.forest.createVariableSet(
+ fileOffset, variable, variable.initializer!))
+ ])
+ ]),
+ inferenceVisitor);
+ for (VariableDeclaration variable in right.declaredVariables) {
+ variable.name = null;
+ variable.initializer = null;
+ variable.type = const DynamicType();
+ }
+
+ PatternTransformationResult transformationResult = leftTransformationResult
+ .combine(rightTransformationResult, inferenceVisitor)
+ .combine(
+ new PatternTransformationResult([
+ new PatternTransformationElement(
+ kind: PatternTransformationElementKind.logicalOrPatternEnd,
+ condition: null,
+ variableInitializers: []),
+ new PatternTransformationElement(
+ kind: PatternTransformationElementKind.regular,
+ // condition:
+ // `leftConditionIsTrue` || `rightConditionIsTrue`
+ condition: inferenceVisitor.engine.forest
+ .createLogicalExpression(
+ fileOffset,
+ inferenceVisitor.engine.forest.createVariableGet(
+ fileOffset, leftConditionIsTrue),
+ doubleBarName.text,
+ inferenceVisitor.engine.forest.createVariableGet(
+ fileOffset, rightConditionIsTrue)),
+ variableInitializers: [])
+ ]),
+ inferenceVisitor);
+
+ transformationResult = transformationResult.prependElement(
+ new PatternTransformationElement(
+ kind: PatternTransformationElementKind.regular,
+ condition: null,
+ variableInitializers: [
+ intermediateVariable,
+ leftConditionIsTrue,
+ rightConditionIsTrue,
+ ...left.declaredVariables,
+ ...right.declaredVariables
+ ]),
+ inferenceVisitor);
+
+ return transformationResult;
+ }
+
+ @override
+ void toTextInternal(AstPrinter printer) {
+ left.toTextInternal(printer);
+ printer.write(' | ');
right.toTextInternal(printer);
}
@@ -5294,7 +5543,9 @@
transformationResult = transformationResult.prependElement(
new PatternTransformationElement(
- condition: null, variableInitializers: [intermediateVariable]),
+ kind: PatternTransformationElementKind.regular,
+ condition: null,
+ variableInitializers: [intermediateVariable]),
inferenceVisitor);
return transformationResult;
@@ -5363,7 +5614,9 @@
transformationResult = transformationResult.prependElement(
new PatternTransformationElement(
- condition: null, variableInitializers: [intermediateVariable]),
+ kind: PatternTransformationElementKind.regular,
+ condition: null,
+ variableInitializers: [intermediateVariable]),
inferenceVisitor);
return transformationResult;
@@ -5437,11 +5690,15 @@
// condition in the last transformation element.
transformationResult = transformationResult.prependElement(
new PatternTransformationElement(
- condition: nullCheckCondition, variableInitializers: []),
+ kind: PatternTransformationElementKind.regular,
+ condition: nullCheckCondition,
+ variableInitializers: []),
inferenceVisitor);
transformationResult = transformationResult.prependElement(
new PatternTransformationElement(
- condition: null, variableInitializers: [intermediateVariable]),
+ kind: PatternTransformationElementKind.regular,
+ condition: null,
+ variableInitializers: [intermediateVariable]),
inferenceVisitor);
return transformationResult;
@@ -5618,13 +5875,16 @@
transformationResult = transformationResult.prependElement(
new PatternTransformationElement(
+ kind: PatternTransformationElementKind.regular,
condition: typeAndLengthCheck,
variableInitializers: elementAccessVariables),
inferenceVisitor);
transformationResult = transformationResult.prependElement(
new PatternTransformationElement(
- condition: null, variableInitializers: [listVariable]),
+ kind: PatternTransformationElementKind.regular,
+ condition: null,
+ variableInitializers: [listVariable]),
inferenceVisitor);
return transformationResult;
@@ -5759,7 +6019,9 @@
}
return new PatternTransformationResult([
new PatternTransformationElement(
- condition: condition, variableInitializers: [])
+ kind: PatternTransformationElementKind.regular,
+ condition: condition,
+ variableInitializers: [])
]);
}
@@ -5828,7 +6090,9 @@
}
return new PatternTransformationResult([
new PatternTransformationElement(
- condition: condition, variableInitializers: [])
+ kind: PatternTransformationElementKind.regular,
+ condition: condition,
+ variableInitializers: [])
]);
}
@@ -6188,13 +6452,16 @@
transformationResult = transformationResult.prependElement(
new PatternTransformationElement(
+ kind: PatternTransformationElementKind.regular,
condition: typeAndKeysCheck,
variableInitializers: valueAccessVariables),
inferenceVisitor);
transformationResult = transformationResult.prependElement(
new PatternTransformationElement(
- condition: null, variableInitializers: [mapVariable]),
+ kind: PatternTransformationElementKind.regular,
+ condition: null,
+ variableInitializers: [mapVariable]),
inferenceVisitor);
return transformationResult;
@@ -6242,6 +6509,7 @@
InferenceVisitorBase inferenceVisitor) {
return new PatternTransformationResult([
new PatternTransformationElement(
+ kind: PatternTransformationElementKind.regular,
condition:
new InvalidExpression("Unimplemented NamedPattern.transform"),
variableInitializers: [])
@@ -6384,6 +6652,7 @@
// ==> [RVAR is `type`]?
transformationResult = transformationResult.prependElement(
new PatternTransformationElement(
+ kind: PatternTransformationElementKind.regular,
condition: !typeCheckNeeded
? null
: inferenceVisitor.engine.forest.createIsExpression(
@@ -6398,7 +6667,9 @@
transformationResult = transformationResult.prependElement(
new PatternTransformationElement(
- condition: null, variableInitializers: [recordVariable]),
+ kind: PatternTransformationElementKind.regular,
+ condition: null,
+ variableInitializers: [recordVariable]),
inferenceVisitor);
return transformationResult;
@@ -6447,9 +6718,13 @@
forNonNullableByDefault: false);
transformationResult = new PatternTransformationResult([
new PatternTransformationElement(
- condition: null, variableInitializers: [matchedExpressionVariable]),
+ kind: PatternTransformationElementKind.regular,
+ condition: null,
+ variableInitializers: [matchedExpressionVariable]),
new PatternTransformationElement(
- condition: condition, variableInitializers: [])
+ kind: PatternTransformationElementKind.regular,
+ condition: condition,
+ variableInitializers: [])
]);
variable.initializer = inferenceVisitor.engine.forest
.createVariableGet(fileOffset, matchedExpressionVariable)
@@ -6513,6 +6788,13 @@
}
}
+enum PatternTransformationElementKind {
+ regular,
+ logicalOrPatternLeftBegin,
+ logicalOrPatternRightBegin,
+ logicalOrPatternEnd
+}
+
class PatternTransformationElement {
/// Part of a matching condition of a pattern
///
@@ -6528,8 +6810,15 @@
/// variables.
final List<Statement> variableInitializers;
+ final PatternTransformationResult? otherwise;
+
+ final PatternTransformationElementKind kind;
+
PatternTransformationElement(
- {required this.condition, required this.variableInitializers});
+ {required this.condition,
+ required this.variableInitializers,
+ required this.kind,
+ this.otherwise});
bool get isEmpty => condition == null && variableInitializers.isEmpty;
}
@@ -6556,6 +6845,9 @@
} else if (other.elements.isEmpty) {
return this;
} else {
+ // TODO(cstefantsova): Does it make sense to use [prependElement] on each
+ // element from [elements], last to the first, prepending them to the
+ // accumulated result?
return new PatternTransformationResult([
...elements.sublist(0, elements.length - 1),
...other.prependElement(elements.last, inferenceVisitor).elements
@@ -6577,11 +6869,16 @@
if (elements.isEmpty) {
return new PatternTransformationResult([element]);
}
+ if (element.kind != PatternTransformationElementKind.regular ||
+ elements.first.kind != PatternTransformationElementKind.regular) {
+ return new PatternTransformationResult([element, ...elements]);
+ }
PatternTransformationElement outermost = elements.first;
Expression? elementCondition = element.condition;
Expression? outermostCondition = outermost.condition;
if (outermostCondition == null) {
elements[0] = new PatternTransformationElement(
+ kind: PatternTransformationElementKind.regular,
condition: elementCondition,
variableInitializers: [
...element.variableInitializers,
@@ -6594,6 +6891,7 @@
return this;
} else {
elements[0] = new PatternTransformationElement(
+ kind: PatternTransformationElementKind.regular,
condition: inferenceVisitor.engine.forest.createLogicalExpression(
elementCondition.fileOffset,
elementCondition,
@@ -6607,3 +6905,9 @@
}
}
}
+
+class ContinuationStackElement {
+ List<Statement> statements;
+
+ ContinuationStackElement(this.statements);
+}
diff --git a/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart b/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart
index 4c75b37..5f1ef57 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart
@@ -1828,25 +1828,62 @@
])
];
}
+
+ List<ContinuationStackElement> continuationStack = [];
for (int i = transformationResult.elements.length - 1; i >= 0; i--) {
PatternTransformationElement transformationElement =
transformationResult.elements[i];
- replacementStatements = [
- ...transformationElement.variableInitializers,
- ...replacementStatements
- ];
- Expression? condition = transformationElement.condition;
- if (condition != null) {
- replacementStatements = [
- engine.forest.createIfStatement(
- node.fileOffset,
- condition,
- engine.forest.createBlock(
- node.fileOffset, node.fileOffset, replacementStatements),
- null)
- ];
+
+ switch (transformationElement.kind) {
+ case PatternTransformationElementKind.regular:
+ replacementStatements = [
+ ...transformationElement.variableInitializers,
+ ...replacementStatements
+ ];
+ Expression? condition = transformationElement.condition;
+ if (condition != null) {
+ replacementStatements = [
+ engine.forest.createIfStatement(
+ node.fileOffset,
+ condition,
+ engine.forest.createBlock(
+ node.fileOffset, node.fileOffset, replacementStatements),
+ null)
+ ];
+ }
+ break;
+
+ case PatternTransformationElementKind.logicalOrPatternLeftBegin:
+ ContinuationStackElement leftContinuation =
+ continuationStack.removeLast();
+ ContinuationStackElement rightContinuation =
+ continuationStack.removeLast();
+
+ List<Statement> leftConditionDesugaring = replacementStatements;
+ replacementStatements = [
+ ...leftConditionDesugaring,
+ ...leftContinuation.statements,
+ ...rightContinuation.statements,
+ ];
+
+ break;
+
+ case PatternTransformationElementKind.logicalOrPatternRightBegin:
+ continuationStack
+ .add(new ContinuationStackElement(replacementStatements));
+ replacementStatements = [];
+ break;
+
+ case PatternTransformationElementKind.logicalOrPatternEnd:
+ continuationStack
+ .add(new ContinuationStackElement(replacementStatements));
+ replacementStatements = [];
+ break;
}
}
+ assert(continuationStack.isEmpty,
+ "Continuation stack is not empty at the end of desugaring.");
+
replacementStatements = [
matchedExpressionVariable,
if (otherwise != null) isPatternMatchingFailed,
@@ -8802,8 +8839,20 @@
return const PatternInferenceResult();
}
- PatternInferenceResult visitBinaryPattern(
- BinaryPattern pattern, {
+ PatternInferenceResult visitAndPattern(
+ AndPattern pattern, {
+ required DartType matchedType,
+ required SharedMatchContext context,
+ }) {
+ pattern.left
+ .acceptInference(this, matchedType: matchedType, context: context);
+ pattern.right
+ .acceptInference(this, matchedType: matchedType, context: context);
+ return const PatternInferenceResult();
+ }
+
+ PatternInferenceResult visitOrPattern(
+ OrPattern pattern, {
required DartType matchedType,
required SharedMatchContext context,
}) {
diff --git a/pkg/front_end/test/spell_checking_list_common.txt b/pkg/front_end/test/spell_checking_list_common.txt
index acd7a90..68058b9 100644
--- a/pkg/front_end/test/spell_checking_list_common.txt
+++ b/pkg/front_end/test/spell_checking_list_common.txt
@@ -1676,6 +1676,7 @@
joined
joining
joins
+joint
judgment
judgments
jump
diff --git a/pkg/front_end/test/text_representation/internal_ast_text_representation_test.dart b/pkg/front_end/test/text_representation/internal_ast_text_representation_test.dart
index f29e612..a3a1421 100644
--- a/pkg/front_end/test/text_representation/internal_ast_text_representation_test.dart
+++ b/pkg/front_end/test/text_representation/internal_ast_text_representation_test.dart
@@ -1067,20 +1067,15 @@
void _testBinaryMatcher() {
testMatcher(
- new BinaryPattern(
- new ExpressionPattern(new IntLiteral(0)),
- BinaryPatternKind.and,
- new ExpressionPattern(new IntLiteral(1)),
- TreeNode.noOffset),
+ new AndPattern(new ExpressionPattern(new IntLiteral(0)),
+ new ExpressionPattern(new IntLiteral(1)), TreeNode.noOffset),
'''
0 & 1''');
testMatcher(
- new BinaryPattern(
- new ExpressionPattern(new IntLiteral(0)),
- BinaryPatternKind.or,
- new ExpressionPattern(new IntLiteral(1)),
- TreeNode.noOffset),
+ new OrPattern(new ExpressionPattern(new IntLiteral(0)),
+ new ExpressionPattern(new IntLiteral(1)), TreeNode.noOffset,
+ orPatternJointVariables: []),
'''
0 | 1''');
}
diff --git a/pkg/front_end/testcases/patterns/logical_and_inside_if_case.dart.strong.expect b/pkg/front_end/testcases/patterns/logical_and_inside_if_case.dart.strong.expect
index 4d4b15e..9a8da7a 100644
--- a/pkg/front_end/testcases/patterns/logical_and_inside_if_case.dart.strong.expect
+++ b/pkg/front_end/testcases/patterns/logical_and_inside_if_case.dart.strong.expect
@@ -1,8 +1,10 @@
library /*isNonNullableByDefault*/;
import self as self;
+import "dart:core" as core;
static method test(dynamic x) → dynamic {
final dynamic #t1 = x;
- if(invalid-expression "Unimplemented BinaryPattern.transform") {
+ final dynamic #t2 = #t1;
+ if(#t2 is core::int? && #t2 is core::double?) {
}
}
diff --git a/pkg/front_end/testcases/patterns/logical_and_inside_if_case.dart.strong.transformed.expect b/pkg/front_end/testcases/patterns/logical_and_inside_if_case.dart.strong.transformed.expect
index 4d4b15e..9a8da7a 100644
--- a/pkg/front_end/testcases/patterns/logical_and_inside_if_case.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/patterns/logical_and_inside_if_case.dart.strong.transformed.expect
@@ -1,8 +1,10 @@
library /*isNonNullableByDefault*/;
import self as self;
+import "dart:core" as core;
static method test(dynamic x) → dynamic {
final dynamic #t1 = x;
- if(invalid-expression "Unimplemented BinaryPattern.transform") {
+ final dynamic #t2 = #t1;
+ if(#t2 is core::int? && #t2 is core::double?) {
}
}
diff --git a/pkg/front_end/testcases/patterns/logical_and_inside_if_case.dart.weak.expect b/pkg/front_end/testcases/patterns/logical_and_inside_if_case.dart.weak.expect
index 4d4b15e..9a8da7a 100644
--- a/pkg/front_end/testcases/patterns/logical_and_inside_if_case.dart.weak.expect
+++ b/pkg/front_end/testcases/patterns/logical_and_inside_if_case.dart.weak.expect
@@ -1,8 +1,10 @@
library /*isNonNullableByDefault*/;
import self as self;
+import "dart:core" as core;
static method test(dynamic x) → dynamic {
final dynamic #t1 = x;
- if(invalid-expression "Unimplemented BinaryPattern.transform") {
+ final dynamic #t2 = #t1;
+ if(#t2 is core::int? && #t2 is core::double?) {
}
}
diff --git a/pkg/front_end/testcases/patterns/logical_and_inside_if_case.dart.weak.modular.expect b/pkg/front_end/testcases/patterns/logical_and_inside_if_case.dart.weak.modular.expect
index 4d4b15e..9a8da7a 100644
--- a/pkg/front_end/testcases/patterns/logical_and_inside_if_case.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/patterns/logical_and_inside_if_case.dart.weak.modular.expect
@@ -1,8 +1,10 @@
library /*isNonNullableByDefault*/;
import self as self;
+import "dart:core" as core;
static method test(dynamic x) → dynamic {
final dynamic #t1 = x;
- if(invalid-expression "Unimplemented BinaryPattern.transform") {
+ final dynamic #t2 = #t1;
+ if(#t2 is core::int? && #t2 is core::double?) {
}
}
diff --git a/pkg/front_end/testcases/patterns/logical_and_inside_if_case.dart.weak.transformed.expect b/pkg/front_end/testcases/patterns/logical_and_inside_if_case.dart.weak.transformed.expect
index 4d4b15e..9a8da7a 100644
--- a/pkg/front_end/testcases/patterns/logical_and_inside_if_case.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/patterns/logical_and_inside_if_case.dart.weak.transformed.expect
@@ -1,8 +1,10 @@
library /*isNonNullableByDefault*/;
import self as self;
+import "dart:core" as core;
static method test(dynamic x) → dynamic {
final dynamic #t1 = x;
- if(invalid-expression "Unimplemented BinaryPattern.transform") {
+ final dynamic #t2 = #t1;
+ if(#t2 is core::int? && #t2 is core::double?) {
}
}
diff --git a/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart b/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart
index 8e2c853..84cc965 100644
--- a/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart
+++ b/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart
@@ -2,6 +2,22 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-test(dynamic x) {
+test1(dynamic x) {
if (x case int? _ | double? _) {}
}
+
+test2(dynamic x) {
+ if (x case [int y, var _] | [var _, String y]) {
+ return y;
+ } else {
+ return null;
+ }
+}
+
+test3(dynamic x) {
+ if (x case == 1 | == 2 | == 3) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
diff --git a/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart.strong.expect b/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart.strong.expect
index 4d4b15e..b92d69a 100644
--- a/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart.strong.expect
+++ b/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart.strong.expect
@@ -1,8 +1,90 @@
library /*isNonNullableByDefault*/;
import self as self;
+import "dart:core" as core;
-static method test(dynamic x) → dynamic {
+static method test1(dynamic x) → dynamic {
final dynamic #t1 = x;
- if(invalid-expression "Unimplemented BinaryPattern.transform") {
+ final dynamic #t2 = #t1;
+ final core::bool #t3 = false;
+ final core::bool #t4 = false;
+ if(#t2 is core::int?) {
+ #t3 = true;
+ }
+ if(!#t3 && #t2 is core::double?) {
+ #t4 = true;
+ }
+ if(#t3 || #t4) {
+ }
+}
+static method test2(dynamic x) → dynamic {
+ final dynamic #t5 = x;
+ final core::bool #t6 = true;
+ final dynamic #t7 = #t5;
+ final core::bool #t8 = false;
+ final core::bool #t9 = false;
+ dynamic #t10;
+ dynamic #t11;
+ final dynamic #t12 = #t7;
+ if(#t12 is core::List<dynamic> && #t12{core::List<dynamic>}.{core::List::length}{core::int}.{core::num::>=}(2){(core::num) → core::bool}) {
+ final dynamic #t13 = #t12{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic};
+ final dynamic #t14 = #t13;
+ if(#t14 is core::int) {
+ #t8 = true;
+ #t10 = #t14{core::int};
+ }
+ }
+ if(!#t8) {
+ final dynamic #t15 = #t7;
+ if(#t15 is core::List<dynamic> && #t15{core::List<dynamic>}.{core::List::length}{core::int}.{core::num::>=}(2){(core::num) → core::bool}) {
+ final dynamic #t16 = #t15{core::List<dynamic>}.{core::List::[]}(1){(core::int) → dynamic};
+ final dynamic #t17 = #t16;
+ if(#t17 is core::String) {
+ #t9 = true;
+ #t11 = #t17{core::String};
+ }
+ }
+ }
+ if(#t8 || #t9) {
+ #t6 = false;
+ {
+ dynamic y = #t8 ?{core::Object} #t10{core::int} : #t11{core::String};
+ {
+ return y;
+ }
+ }
+ }
+ if(#t6) {
+ return null;
+ }
+}
+static method test3(dynamic x) → dynamic {
+ final dynamic #t18 = x;
+ final core::bool #t19 = true;
+ final dynamic #t20 = #t18;
+ final core::bool #t21 = false;
+ final core::bool #t22 = false;
+ final dynamic #t23 = #t20;
+ final core::bool #t24 = false;
+ final core::bool #t25 = false;
+ if(#t23 =={core::Object::==}{(core::Object) → core::bool} 1) {
+ #t24 = true;
+ }
+ if(!#t24 && #t23 =={core::Object::==}{(core::Object) → core::bool} 2) {
+ #t25 = true;
+ }
+ if(#t24 || #t25) {
+ #t21 = true;
+ }
+ if(!#t21 && #t20 =={core::Object::==}{(core::Object) → core::bool} 3) {
+ #t22 = true;
+ }
+ if(#t21 || #t22) {
+ #t19 = false;
+ {
+ return 0;
+ }
+ }
+ if(#t19) {
+ return 1;
}
}
diff --git a/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart.strong.transformed.expect b/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart.strong.transformed.expect
index 4d4b15e..b92d69a 100644
--- a/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart.strong.transformed.expect
@@ -1,8 +1,90 @@
library /*isNonNullableByDefault*/;
import self as self;
+import "dart:core" as core;
-static method test(dynamic x) → dynamic {
+static method test1(dynamic x) → dynamic {
final dynamic #t1 = x;
- if(invalid-expression "Unimplemented BinaryPattern.transform") {
+ final dynamic #t2 = #t1;
+ final core::bool #t3 = false;
+ final core::bool #t4 = false;
+ if(#t2 is core::int?) {
+ #t3 = true;
+ }
+ if(!#t3 && #t2 is core::double?) {
+ #t4 = true;
+ }
+ if(#t3 || #t4) {
+ }
+}
+static method test2(dynamic x) → dynamic {
+ final dynamic #t5 = x;
+ final core::bool #t6 = true;
+ final dynamic #t7 = #t5;
+ final core::bool #t8 = false;
+ final core::bool #t9 = false;
+ dynamic #t10;
+ dynamic #t11;
+ final dynamic #t12 = #t7;
+ if(#t12 is core::List<dynamic> && #t12{core::List<dynamic>}.{core::List::length}{core::int}.{core::num::>=}(2){(core::num) → core::bool}) {
+ final dynamic #t13 = #t12{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic};
+ final dynamic #t14 = #t13;
+ if(#t14 is core::int) {
+ #t8 = true;
+ #t10 = #t14{core::int};
+ }
+ }
+ if(!#t8) {
+ final dynamic #t15 = #t7;
+ if(#t15 is core::List<dynamic> && #t15{core::List<dynamic>}.{core::List::length}{core::int}.{core::num::>=}(2){(core::num) → core::bool}) {
+ final dynamic #t16 = #t15{core::List<dynamic>}.{core::List::[]}(1){(core::int) → dynamic};
+ final dynamic #t17 = #t16;
+ if(#t17 is core::String) {
+ #t9 = true;
+ #t11 = #t17{core::String};
+ }
+ }
+ }
+ if(#t8 || #t9) {
+ #t6 = false;
+ {
+ dynamic y = #t8 ?{core::Object} #t10{core::int} : #t11{core::String};
+ {
+ return y;
+ }
+ }
+ }
+ if(#t6) {
+ return null;
+ }
+}
+static method test3(dynamic x) → dynamic {
+ final dynamic #t18 = x;
+ final core::bool #t19 = true;
+ final dynamic #t20 = #t18;
+ final core::bool #t21 = false;
+ final core::bool #t22 = false;
+ final dynamic #t23 = #t20;
+ final core::bool #t24 = false;
+ final core::bool #t25 = false;
+ if(#t23 =={core::Object::==}{(core::Object) → core::bool} 1) {
+ #t24 = true;
+ }
+ if(!#t24 && #t23 =={core::Object::==}{(core::Object) → core::bool} 2) {
+ #t25 = true;
+ }
+ if(#t24 || #t25) {
+ #t21 = true;
+ }
+ if(!#t21 && #t20 =={core::Object::==}{(core::Object) → core::bool} 3) {
+ #t22 = true;
+ }
+ if(#t21 || #t22) {
+ #t19 = false;
+ {
+ return 0;
+ }
+ }
+ if(#t19) {
+ return 1;
}
}
diff --git a/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart.textual_outline.expect b/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart.textual_outline.expect
index 8655004..51cd7fc 100644
--- a/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart.textual_outline.expect
@@ -1 +1,3 @@
-test(dynamic x) {}
+test1(dynamic x) {}
+test2(dynamic x) {}
+test3(dynamic x) {}
diff --git a/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart.textual_outline_modelled.expect
index 8655004..51cd7fc 100644
--- a/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart.textual_outline_modelled.expect
@@ -1 +1,3 @@
-test(dynamic x) {}
+test1(dynamic x) {}
+test2(dynamic x) {}
+test3(dynamic x) {}
diff --git a/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart.weak.expect b/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart.weak.expect
index 4d4b15e..b92d69a 100644
--- a/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart.weak.expect
+++ b/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart.weak.expect
@@ -1,8 +1,90 @@
library /*isNonNullableByDefault*/;
import self as self;
+import "dart:core" as core;
-static method test(dynamic x) → dynamic {
+static method test1(dynamic x) → dynamic {
final dynamic #t1 = x;
- if(invalid-expression "Unimplemented BinaryPattern.transform") {
+ final dynamic #t2 = #t1;
+ final core::bool #t3 = false;
+ final core::bool #t4 = false;
+ if(#t2 is core::int?) {
+ #t3 = true;
+ }
+ if(!#t3 && #t2 is core::double?) {
+ #t4 = true;
+ }
+ if(#t3 || #t4) {
+ }
+}
+static method test2(dynamic x) → dynamic {
+ final dynamic #t5 = x;
+ final core::bool #t6 = true;
+ final dynamic #t7 = #t5;
+ final core::bool #t8 = false;
+ final core::bool #t9 = false;
+ dynamic #t10;
+ dynamic #t11;
+ final dynamic #t12 = #t7;
+ if(#t12 is core::List<dynamic> && #t12{core::List<dynamic>}.{core::List::length}{core::int}.{core::num::>=}(2){(core::num) → core::bool}) {
+ final dynamic #t13 = #t12{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic};
+ final dynamic #t14 = #t13;
+ if(#t14 is core::int) {
+ #t8 = true;
+ #t10 = #t14{core::int};
+ }
+ }
+ if(!#t8) {
+ final dynamic #t15 = #t7;
+ if(#t15 is core::List<dynamic> && #t15{core::List<dynamic>}.{core::List::length}{core::int}.{core::num::>=}(2){(core::num) → core::bool}) {
+ final dynamic #t16 = #t15{core::List<dynamic>}.{core::List::[]}(1){(core::int) → dynamic};
+ final dynamic #t17 = #t16;
+ if(#t17 is core::String) {
+ #t9 = true;
+ #t11 = #t17{core::String};
+ }
+ }
+ }
+ if(#t8 || #t9) {
+ #t6 = false;
+ {
+ dynamic y = #t8 ?{core::Object} #t10{core::int} : #t11{core::String};
+ {
+ return y;
+ }
+ }
+ }
+ if(#t6) {
+ return null;
+ }
+}
+static method test3(dynamic x) → dynamic {
+ final dynamic #t18 = x;
+ final core::bool #t19 = true;
+ final dynamic #t20 = #t18;
+ final core::bool #t21 = false;
+ final core::bool #t22 = false;
+ final dynamic #t23 = #t20;
+ final core::bool #t24 = false;
+ final core::bool #t25 = false;
+ if(#t23 =={core::Object::==}{(core::Object) → core::bool} 1) {
+ #t24 = true;
+ }
+ if(!#t24 && #t23 =={core::Object::==}{(core::Object) → core::bool} 2) {
+ #t25 = true;
+ }
+ if(#t24 || #t25) {
+ #t21 = true;
+ }
+ if(!#t21 && #t20 =={core::Object::==}{(core::Object) → core::bool} 3) {
+ #t22 = true;
+ }
+ if(#t21 || #t22) {
+ #t19 = false;
+ {
+ return 0;
+ }
+ }
+ if(#t19) {
+ return 1;
}
}
diff --git a/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart.weak.modular.expect b/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart.weak.modular.expect
index 4d4b15e..b92d69a 100644
--- a/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart.weak.modular.expect
@@ -1,8 +1,90 @@
library /*isNonNullableByDefault*/;
import self as self;
+import "dart:core" as core;
-static method test(dynamic x) → dynamic {
+static method test1(dynamic x) → dynamic {
final dynamic #t1 = x;
- if(invalid-expression "Unimplemented BinaryPattern.transform") {
+ final dynamic #t2 = #t1;
+ final core::bool #t3 = false;
+ final core::bool #t4 = false;
+ if(#t2 is core::int?) {
+ #t3 = true;
+ }
+ if(!#t3 && #t2 is core::double?) {
+ #t4 = true;
+ }
+ if(#t3 || #t4) {
+ }
+}
+static method test2(dynamic x) → dynamic {
+ final dynamic #t5 = x;
+ final core::bool #t6 = true;
+ final dynamic #t7 = #t5;
+ final core::bool #t8 = false;
+ final core::bool #t9 = false;
+ dynamic #t10;
+ dynamic #t11;
+ final dynamic #t12 = #t7;
+ if(#t12 is core::List<dynamic> && #t12{core::List<dynamic>}.{core::List::length}{core::int}.{core::num::>=}(2){(core::num) → core::bool}) {
+ final dynamic #t13 = #t12{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic};
+ final dynamic #t14 = #t13;
+ if(#t14 is core::int) {
+ #t8 = true;
+ #t10 = #t14{core::int};
+ }
+ }
+ if(!#t8) {
+ final dynamic #t15 = #t7;
+ if(#t15 is core::List<dynamic> && #t15{core::List<dynamic>}.{core::List::length}{core::int}.{core::num::>=}(2){(core::num) → core::bool}) {
+ final dynamic #t16 = #t15{core::List<dynamic>}.{core::List::[]}(1){(core::int) → dynamic};
+ final dynamic #t17 = #t16;
+ if(#t17 is core::String) {
+ #t9 = true;
+ #t11 = #t17{core::String};
+ }
+ }
+ }
+ if(#t8 || #t9) {
+ #t6 = false;
+ {
+ dynamic y = #t8 ?{core::Object} #t10{core::int} : #t11{core::String};
+ {
+ return y;
+ }
+ }
+ }
+ if(#t6) {
+ return null;
+ }
+}
+static method test3(dynamic x) → dynamic {
+ final dynamic #t18 = x;
+ final core::bool #t19 = true;
+ final dynamic #t20 = #t18;
+ final core::bool #t21 = false;
+ final core::bool #t22 = false;
+ final dynamic #t23 = #t20;
+ final core::bool #t24 = false;
+ final core::bool #t25 = false;
+ if(#t23 =={core::Object::==}{(core::Object) → core::bool} 1) {
+ #t24 = true;
+ }
+ if(!#t24 && #t23 =={core::Object::==}{(core::Object) → core::bool} 2) {
+ #t25 = true;
+ }
+ if(#t24 || #t25) {
+ #t21 = true;
+ }
+ if(!#t21 && #t20 =={core::Object::==}{(core::Object) → core::bool} 3) {
+ #t22 = true;
+ }
+ if(#t21 || #t22) {
+ #t19 = false;
+ {
+ return 0;
+ }
+ }
+ if(#t19) {
+ return 1;
}
}
diff --git a/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart.weak.outline.expect b/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart.weak.outline.expect
index 303aa9b..8bb8687 100644
--- a/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart.weak.outline.expect
@@ -1,5 +1,9 @@
library /*isNonNullableByDefault*/;
import self as self;
-static method test(dynamic x) → dynamic
+static method test1(dynamic x) → dynamic
+ ;
+static method test2(dynamic x) → dynamic
+ ;
+static method test3(dynamic x) → dynamic
;
diff --git a/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart.weak.transformed.expect b/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart.weak.transformed.expect
index 4d4b15e..b92d69a 100644
--- a/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/patterns/logical_or_inside_if_case.dart.weak.transformed.expect
@@ -1,8 +1,90 @@
library /*isNonNullableByDefault*/;
import self as self;
+import "dart:core" as core;
-static method test(dynamic x) → dynamic {
+static method test1(dynamic x) → dynamic {
final dynamic #t1 = x;
- if(invalid-expression "Unimplemented BinaryPattern.transform") {
+ final dynamic #t2 = #t1;
+ final core::bool #t3 = false;
+ final core::bool #t4 = false;
+ if(#t2 is core::int?) {
+ #t3 = true;
+ }
+ if(!#t3 && #t2 is core::double?) {
+ #t4 = true;
+ }
+ if(#t3 || #t4) {
+ }
+}
+static method test2(dynamic x) → dynamic {
+ final dynamic #t5 = x;
+ final core::bool #t6 = true;
+ final dynamic #t7 = #t5;
+ final core::bool #t8 = false;
+ final core::bool #t9 = false;
+ dynamic #t10;
+ dynamic #t11;
+ final dynamic #t12 = #t7;
+ if(#t12 is core::List<dynamic> && #t12{core::List<dynamic>}.{core::List::length}{core::int}.{core::num::>=}(2){(core::num) → core::bool}) {
+ final dynamic #t13 = #t12{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic};
+ final dynamic #t14 = #t13;
+ if(#t14 is core::int) {
+ #t8 = true;
+ #t10 = #t14{core::int};
+ }
+ }
+ if(!#t8) {
+ final dynamic #t15 = #t7;
+ if(#t15 is core::List<dynamic> && #t15{core::List<dynamic>}.{core::List::length}{core::int}.{core::num::>=}(2){(core::num) → core::bool}) {
+ final dynamic #t16 = #t15{core::List<dynamic>}.{core::List::[]}(1){(core::int) → dynamic};
+ final dynamic #t17 = #t16;
+ if(#t17 is core::String) {
+ #t9 = true;
+ #t11 = #t17{core::String};
+ }
+ }
+ }
+ if(#t8 || #t9) {
+ #t6 = false;
+ {
+ dynamic y = #t8 ?{core::Object} #t10{core::int} : #t11{core::String};
+ {
+ return y;
+ }
+ }
+ }
+ if(#t6) {
+ return null;
+ }
+}
+static method test3(dynamic x) → dynamic {
+ final dynamic #t18 = x;
+ final core::bool #t19 = true;
+ final dynamic #t20 = #t18;
+ final core::bool #t21 = false;
+ final core::bool #t22 = false;
+ final dynamic #t23 = #t20;
+ final core::bool #t24 = false;
+ final core::bool #t25 = false;
+ if(#t23 =={core::Object::==}{(core::Object) → core::bool} 1) {
+ #t24 = true;
+ }
+ if(!#t24 && #t23 =={core::Object::==}{(core::Object) → core::bool} 2) {
+ #t25 = true;
+ }
+ if(#t24 || #t25) {
+ #t21 = true;
+ }
+ if(!#t21 && #t20 =={core::Object::==}{(core::Object) → core::bool} 3) {
+ #t22 = true;
+ }
+ if(#t21 || #t22) {
+ #t19 = false;
+ {
+ return 0;
+ }
+ }
+ if(#t19) {
+ return 1;
}
}