diff --git a/DEPS b/DEPS index 6a842ff1a6867..e7a5c4e9596d7 100644 --- a/DEPS +++ b/DEPS @@ -51,7 +51,7 @@ vars = { # co19 is a cipd package. Use update.sh in tests/co19[_2] to update these # hashes. - "co19_rev": "2a9309cd36effe3b083df6a2761fea6b7213c670", + "co19_rev": "c38e027467efb69c754b198fe0d4029c38cfe72b", # This line prevents conflicts when both packages are rolled simultaneously. "co19_2_rev": "cdab7e4e26f3dd534bcb297ff3f9e9aa5c7a04fb", diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/value_kind.dart b/pkg/_fe_analyzer_shared/lib/src/parser/value_kind.dart index 9b05436fb76cd..d9aaa699006c7 100644 --- a/pkg/_fe_analyzer_shared/lib/src/parser/value_kind.dart +++ b/pkg/_fe_analyzer_shared/lib/src/parser/value_kind.dart @@ -71,10 +71,20 @@ class UnionValueKind implements ValueKind { /// Helper method for creating a list of [ValueKind]s of the given length /// [count]. -List repeatedKinds(ValueKind kind, int count) { +List repeatedKind(ValueKind kind, int count) { return new List.generate(count, (_) => kind); } +/// Helper method for creating a list of [count] repetitions of a sequence of +/// [ValueKind]s. +List repeatedKinds(List kinds, int count) { + List list = []; + for (int i = 0; i < count; i++) { + list.addAll(kinds); + } + return list; +} + /// Helper method for creating a union of a list of [ValueKind]s. ValueKind unionOfKinds(List kinds) { return new UnionValueKind(kinds); 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 a3764b3722f5c..65979cb30c8e0 100644 --- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart +++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart @@ -884,7 +884,7 @@ class BodyBuilder extends StackListenerImpl @override void endMetadataStar(int count) { - assert(checkState(null, repeatedKinds(ValueKinds.Expression, count))); + assert(checkState(null, repeatedKind(ValueKinds.Expression, count))); debugEvent("MetadataStar"); if (count == 0) { push(NullValue.Metadata); @@ -2275,7 +2275,7 @@ class BodyBuilder extends StackListenerImpl libraryFeatures.patterns, case_.charOffset, case_.charCount); Pattern pattern = toPattern(pop()); Expression expression = popForValue(); - push(new Condition(expression, pattern, guard)); + push(new Condition(expression, new PatternGuard(pattern, guard))); } else { assert(checkState(token, [ unionOfKinds([ @@ -2517,20 +2517,19 @@ class BodyBuilder extends StackListenerImpl ])); debugEvent("endCaseExpression"); Object? value = pop(); + constantContext = pop() as ConstantContext; if (value is Pattern) { - constantContext = pop() as ConstantContext; - // TODO(paulberry): handle guard - super.push(toPattern(value)); + super.push(new PatternGuard(value, guard)); + } else if (guard != null) { + super.push(new PatternGuard(toPattern(value), guard)); } else { Expression expression = toValue(value); - constantContext = pop() as ConstantContext; - // TODO(paulberry): handle guard super.push(expression); } assert(checkState(colon, [ unionOfKinds([ ValueKinds.Expression, - ValueKinds.Pattern, + ValueKinds.PatternGuard, ]) ])); } @@ -3434,9 +3433,10 @@ class BodyBuilder extends StackListenerImpl typeInferrer.assignedVariables.beginNode(); Condition condition = peek() as Condition; enterLocalScope("then"); - Pattern? pattern = condition.pattern; - if (pattern != null) { - for (VariableDeclaration variable in pattern.declaredVariables) { + PatternGuard? patternGuard = condition.patternGuard; + if (patternGuard != null) { + for (VariableDeclaration variable + in patternGuard.pattern.declaredVariables) { declareVariable(variable, scope); typeInferrer.assignedVariables.declare(variable); } @@ -3468,13 +3468,12 @@ class BodyBuilder extends StackListenerImpl pop() as AssignedVariablesNodeInfo; Statement thenPart = popStatement(); Condition condition = pop() as Condition; - Pattern? pattern = condition.pattern; - Expression? guard = condition.guard; + PatternGuard? patternGuard = condition.patternGuard; Expression expression = condition.expression; Statement node; - if (pattern != null) { + if (patternGuard != null) { node = new IfCaseStatement( - expression, pattern, guard, thenPart, elsePart, ifToken.charOffset); + expression, patternGuard, thenPart, elsePart, ifToken.charOffset); } else { node = forest.createIfStatement( offsetForToken(ifToken), expression, thenPart, elsePart); @@ -3962,7 +3961,7 @@ class BodyBuilder extends StackListenerImpl Token forKeyword = pop() as Token; assert(checkState(endToken, [ - /* expressions */ ...repeatedKinds( + /* expressions */ ...repeatedKind( unionOfKinds( [ValueKinds.Expression, ValueKinds.Generator]), updateExpressionCount), @@ -4067,7 +4066,7 @@ class BodyBuilder extends StackListenerImpl int count, Token leftBracket, Token? constKeyword, Token rightBracket) { debugEvent("LiteralList"); assert(checkState(leftBracket, [ - ...repeatedKinds( + ...repeatedKind( unionOfKinds([ ValueKinds.Generator, ValueKinds.Expression, @@ -4120,7 +4119,7 @@ class BodyBuilder extends StackListenerImpl void handleListPattern(int count, Token leftBracket, Token rightBracket) { debugEvent("ListPattern"); assert(checkState(leftBracket, [ - ...repeatedKinds( + ...repeatedKind( unionOfKinds([ ValueKinds.Generator, ValueKinds.Expression, @@ -4167,7 +4166,7 @@ class BodyBuilder extends StackListenerImpl debugEvent("RecordLiteral"); assert(checkState( token, - repeatedKinds( + repeatedKind( unionOfKinds([ ValueKinds.Generator, ValueKinds.Expression, @@ -4260,7 +4259,7 @@ class BodyBuilder extends StackListenerImpl debugEvent("RecordPattern"); assert(checkState( token, - repeatedKinds( + repeatedKind( unionOfKinds([ ValueKinds.Generator, ValueKinds.Expression, @@ -4331,7 +4330,7 @@ class BodyBuilder extends StackListenerImpl ) { debugEvent("LiteralSetOrMap"); assert(checkState(leftBrace, [ - ...repeatedKinds( + ...repeatedKind( unionOfKinds([ ValueKinds.Expression, ValueKinds.Generator, @@ -4429,7 +4428,7 @@ class BodyBuilder extends StackListenerImpl void handleMapPattern(int count, Token leftBrace, Token rightBrace) { debugEvent('MapPattern'); assert(checkState(leftBrace, [ - ...repeatedKinds(ValueKinds.MapPatternEntry, count), + ...repeatedKind(ValueKinds.MapPatternEntry, count), ValueKinds.TypeArgumentsOrNull, ])); @@ -4678,7 +4677,7 @@ class BodyBuilder extends StackListenerImpl debugEvent("RecordType"); assert(checkState(leftBracket, [ if (hasNamedFields) ValueKinds.RecordTypeFieldBuilderListOrNull, - ...repeatedKinds(ValueKinds.RecordTypeFieldBuilder, + ...repeatedKind(ValueKinds.RecordTypeFieldBuilder, hasNamedFields ? count - 1 : count), ])); @@ -4746,7 +4745,7 @@ class BodyBuilder extends StackListenerImpl void endRecordTypeNamedFields(int count, Token leftBracket) { debugEvent("RecordTypeNamedFields"); assert(checkState(leftBracket, [ - ...repeatedKinds(ValueKinds.RecordTypeFieldBuilder, count), + ...repeatedKind(ValueKinds.RecordTypeFieldBuilder, count), ])); List? fields = const FixedNullableList() @@ -6271,8 +6270,8 @@ class BodyBuilder extends StackListenerImpl Object? entry = pop(); Condition condition = pop() as Condition; - assert(condition.pattern == null, - "Unexpected pattern in control flow if: ${condition.pattern}."); + assert(condition.patternGuard == null, + "Unexpected pattern in control flow if: ${condition.patternGuard}."); Token ifToken = pop() as Token; TreeNode node; @@ -6315,8 +6314,8 @@ class BodyBuilder extends StackListenerImpl AssignedVariablesNodeInfo assignedVariablesInfo = pop() as AssignedVariablesNodeInfo; Condition condition = pop() as Condition; // parenthesized expression - assert(condition.pattern == null, - "Unexpected pattern in control flow if: ${condition.pattern}."); + assert(condition.patternGuard == null, + "Unexpected pattern in control flow if: ${condition.patternGuard}."); Token ifToken = pop() as Token; TreeNode node; @@ -6721,8 +6720,8 @@ class BodyBuilder extends StackListenerImpl /* break target = */ ValueKinds.BreakTarget, ])); Condition condition = pop() as Condition; - assert(condition.pattern == null, - "Unexpected pattern in do statement: ${condition.pattern}."); + assert(condition.patternGuard == null, + "Unexpected pattern in do statement: ${condition.patternGuard}."); Expression expression = condition.expression; Statement body = popStatement(); JumpTarget continueTarget = exitContinueTarget()!; @@ -7060,8 +7059,8 @@ class BodyBuilder extends StackListenerImpl ])); Statement body = popStatement(); Condition condition = pop() as Condition; - assert(condition.pattern == null, - "Unexpected pattern in while statement: ${condition.pattern}."); + assert(condition.patternGuard == null, + "Unexpected pattern in while statement: ${condition.patternGuard}."); Expression expression = condition.expression; JumpTarget continueTarget = exitContinueTarget()!; JumpTarget breakTarget = exitBreakTarget()!; @@ -7192,24 +7191,36 @@ class BodyBuilder extends StackListenerImpl void beginSwitchCase(int labelCount, int expressionCount, Token firstToken) { debugEvent("beginSwitchCase"); int count = labelCount + expressionCount; + assert(checkState( + firstToken, + repeatedKind( + unionOfKinds([ + ValueKinds.Label, + ValueKinds.Expression, + ValueKinds.PatternGuard, + ]), + count))); List? labelsExpressionsAndPatterns = const FixedNullableList() .popNonNullable(stack, count, dummyLabel); List