104ac30cf4
The listener API for variable patterns is split into three separate functions, to handle the three separate behaviors: - `handleAssignedVariablePattern` for variable names appearing in an assignment context (these assign to an existing variable upon a successful match). - `handleDeclaredVariablePattern` for variable declarations appearing in a declaration or matching context (these cause a new variable name to come into scope). - `handleWildcardPattern` for wildcards in any context (these don't capture the matched value). Also, responsibility is shifted to the parser for reporting the following error conditions: - VariablePatternKeywordInDeclarationContext (e.g. `var (var x) = ...;`) - PatternAssignmentDeclaresVariable (e.g. `[x, var y] = ...;`) Previously these errors were detected by the implementations, and weren't fully covering all possible error scenarios. In the case of VariablePatternKeywordInDeclarationContext, the listener method `handleDeclaredVariablePattern` is called instead of `handleAssignedVariablePattern`. This ensures that no tokens are dropped from the analyzer AST. The CFE uses the `inAssignmentPattern` argument of `handleDeclaredVariablePattern` to distinguish this error recovery case from a legitimate declared variable pattern. Fixes #51868. Bug: https://github.com/dart-lang/sdk/issues/51868 Change-Id: I28ec679b73d64033166721c6460be35f15e23171 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/291583 Reviewed-by: Jens Johansen <jensj@google.com> Commit-Queue: Paul Berry <paulberry@google.com>
79 lines
5.0 KiB
Plaintext
79 lines
5.0 KiB
Plaintext
library /*isNonNullableByDefault*/;
|
|
//
|
|
// Problems in library:
|
|
//
|
|
// pkg/front_end/testcases/patterns/pattern_assignment_declares.dart:12:11: Error: Variable 'b' can't be declared in a pattern assignment.
|
|
// Try using a preexisting variable or changing the assignment to a pattern variable declaration.
|
|
// (a, int b, final int c) = x;
|
|
// ^
|
|
//
|
|
// pkg/front_end/testcases/patterns/pattern_assignment_declares.dart:12:24: Error: Variable 'c' can't be declared in a pattern assignment.
|
|
// Try using a preexisting variable or changing the assignment to a pattern variable declaration.
|
|
// (a, int b, final int c) = x;
|
|
// ^
|
|
//
|
|
// pkg/front_end/testcases/patterns/pattern_assignment_declares.dart:13:13: Error: Variable 'd' can't be declared in a pattern assignment.
|
|
// Try using a preexisting variable or changing the assignment to a pattern variable declaration.
|
|
// [a, final d] = y;
|
|
// ^
|
|
//
|
|
// pkg/front_end/testcases/patterns/pattern_assignment_declares.dart:14:34: Error: Variable 'e' can't be declared in a pattern assignment.
|
|
// Try using a preexisting variable or changing the assignment to a pattern variable declaration.
|
|
// Class(field1: a, field2: [[var e, _], [1, var f]]) = z;
|
|
// ^
|
|
//
|
|
// pkg/front_end/testcases/patterns/pattern_assignment_declares.dart:14:49: Error: Variable 'f' can't be declared in a pattern assignment.
|
|
// Try using a preexisting variable or changing the assignment to a pattern variable declaration.
|
|
// Class(field1: a, field2: [[var e, _], [1, var f]]) = z;
|
|
// ^
|
|
//
|
|
// pkg/front_end/testcases/patterns/pattern_assignment_declares.dart:14:42: Error: Refutable patterns can't be used in an irrefutable context.
|
|
// Try using an if-case, a 'switch' statement, or a 'switch' expression instead.
|
|
// Class(field1: a, field2: [[var e, _], [1, var f]]) = z;
|
|
// ^
|
|
//
|
|
import self as self;
|
|
import "dart:core" as core;
|
|
|
|
class Class extends core::Object {
|
|
field dynamic field1 = null;
|
|
field dynamic field2 = null;
|
|
synthetic constructor •() → self::Class
|
|
: super core::Object::•()
|
|
;
|
|
}
|
|
static method method(dynamic x, dynamic y, dynamic z) → dynamic {
|
|
dynamic a;
|
|
block {
|
|
dynamic #t1;
|
|
final synthesized dynamic #0#0 = x as{TypeError,ForDynamic,ForNonNullableByDefault} (dynamic, invalid-type, invalid-type);
|
|
if(!(#0#0 is{ForNonNullableByDefault} (core::Object?, core::Object?, core::Object?) && (let final dynamic #t2 = #t1 = #0#0{(core::Object?, core::Object?, core::Object?)}.$1{core::Object?} in true) && invalid-expression "declared variable pattern in assignment" && invalid-expression "declared variable pattern in assignment"))
|
|
throw new core::StateError::•("Pattern matching error");
|
|
a = #t1;
|
|
} =>#0#0;
|
|
block {
|
|
dynamic #t3;
|
|
final synthesized dynamic #1#0 = y as{TypeError,ForDynamic,ForNonNullableByDefault} core::List<invalid-type>;
|
|
if(!(#1#0 is{ForNonNullableByDefault} core::List<dynamic> && #1#0{core::List<dynamic>}.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (let final dynamic #t4 = #t3 = #1#0{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic} in true) && invalid-expression "declared variable pattern in assignment"))
|
|
throw new core::StateError::•("Pattern matching error");
|
|
a = #t3;
|
|
} =>#1#0;
|
|
block {
|
|
dynamic #t5;
|
|
final synthesized dynamic #2#0 = z as{TypeError,ForDynamic,ForNonNullableByDefault} self::Class;
|
|
late final synthesized dynamic #2#3 = #2#0{self::Class}.{self::Class::field2}{dynamic};
|
|
late final synthesized dynamic #2#9 = #2#3{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic};
|
|
late final synthesized dynamic #2#16 = #2#3{core::List<dynamic>}.{core::List::[]}(1){(core::int) → dynamic};
|
|
if(!(#2#0 is{ForNonNullableByDefault} self::Class && (let final dynamic #t6 = #t5 = #2#0{self::Class}.{self::Class::field1}{dynamic} in true) && (#2#3 is{ForNonNullableByDefault} core::List<dynamic> && #2#3{core::List<dynamic>}.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (#2#9 is{ForNonNullableByDefault} core::List<dynamic> && #2#9{core::List<dynamic>}.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && invalid-expression "declared variable pattern in assignment") && (#2#16 is{ForNonNullableByDefault} core::List<dynamic> && #2#16{core::List<dynamic>}.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && invalid-expression "pkg/front_end/testcases/patterns/pattern_assignment_declares.dart:14:42: Error: Refutable patterns can't be used in an irrefutable context.
|
|
Try using an if-case, a 'switch' statement, or a 'switch' expression instead.
|
|
Class(field1: a, field2: [[var e, _], [1, var f]]) = z;
|
|
^" && invalid-expression "declared variable pattern in assignment"))))
|
|
throw new core::StateError::•("Pattern matching error");
|
|
a = #t5;
|
|
} =>#2#0;
|
|
}
|
|
|
|
constants {
|
|
#C1 = 2
|
|
}
|