Files
sdk/pkg/front_end/testcases/patterns/const_patterns.dart
T
Paul Berry d2184a9d03 Patterns parsing: disallow unaryPattern or relationalPattern in unaryPattern.
The precedence-based pattern parser can understand a unary pattern
inside another unary pattern (e.g. `_ as int as num`) or a relational
pattern inside a unary pattern (e.g. `> 1?`), but the specification
prohibits these constructions because they're difficult to read and
not very useful.

This change updates the implementation to match the spec, by producing
the appropriate error.  The offset and length of the error cover the
inner pattern, so it should be easy to construct an analysis server
quick fix that inserts the necessary parentheses.

Bug: https://github.com/dart-lang/sdk/issues/50035
Change-Id: I33e74d6d1f863e7162851d26fefbacd4fd17277c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/292120
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2023-03-31 16:43:01 +00:00

129 lines
3.9 KiB
Dart

// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
// 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.
import 'const_patterns.dart' as prefix;
const int value = 42;
void func() {}
class Class {
const Class([a]);
const Class.named();
call() {}
test(o) async {
const dynamic local = 0;
dynamic variable = 0;
switch (o) {
case true: // Ok
case null: // Ok
case this: // Error
case this(): // Error
case super(): // Error
case 42: // Ok
case -42: // Ok
case 42.5: // Ok
case -42.5: // Ok
case 'foo': // Ok
case 'foo' 'bar': // Ok
case value: // Ok
case value!: // Ok
case value?: // Ok
case (value?)!: // Ok
case (value!)?: // Ok
case -42!: // Ok
case -42?: // Ok
case (-42!)?: // Ok
case (-42?)!: // Ok
case value as int: // Ok
case -value: // Error
case local: // Ok
case -local: // Error
case func: // Ok
case prefix.value: // Ok
case -prefix.value: // Error
case prefix.Class.named: // Ok
case 1 + 2: // Error
case 1 * 2: // Error
case void fun() {}: // Error
case assert(false): // Error
case switch (o) { _ => true }: // Error
case await 0: // Error
case !false: // Error
case ~0: // Error
case ++variable: // Error
case const 0: // Error
case const 0x0: // Error
case const 0.5: // Error
case const true: // Error
case const null: // Error
case const -0: // Error
case const 'foo': // Error
case const #a: // Error
case const value: // Error
case const local: // Error
case const prefix.value: // Error
case const -prefix.value: // Error
case const prefix.Class.named: // Error
case const 1 + 2: // Error
case const void fun() {}: // Error
case const assert(false): // Error
case const switch (o) { _ => true }: // Error
case const await 0: // Error
case const !false: // Error
case const ~0: // Error
case const ++variable: // Error
case const Class(): // Ok
case const Class(0): // Ok
case const GenericClass(): // Ok
case const GenericClass(a: 0): // Ok
case const GenericClass<int>(): // Ok
case const GenericClass<int>(a: 0): // Ok
case const GenericClass<int>.new(): // Ok
case const GenericClass<int>.new(a: 1): // Ok
case const []: // Ok
case const <int>[]: // Ok
case const {}: // Ok
case const <int, String>{}: // Ok
case const const Class(): // Error
case const const Class(0): // Error
case const const GenericClass(): // Error
case const const GenericClass(a: 0): // Error
case const const GenericClass<int>(): // Error
case const const GenericClass<int>(a: 0): // Error
case const const []: // Error
case const const <int>[]: // Error
case const const {}: // Error
case const const <int, String>{}: // Error
case const new Class(): // Error
case new Class(): // Error
case const (): // Error
case const const (): // Error
case const (1): // Ok
case const (-1): // Ok
case const (value): // Ok
case const (-value): // Ok
case const (1 + 2): // Ok
case GenericClass<int>: // Error
case prefix.GenericClass<int>: // Error
case GenericClass<int>.new: // Error
case prefix.GenericClass<int>.new: // Error
case const GenericClass<int>: // Error
case const prefix.GenericClass<int>: // Error
case const (GenericClass<int>): // Ok
case const (prefix.GenericClass<int>): // Ok
case const (GenericClass<int>.new): // Ok
case const (prefix.GenericClass<int>.new): // Ok
print(0);
}
}
}
class GenericClass<T> {
const GenericClass({a});
}