mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 00:39:49 +00:00
[cfe] Account for parser recovery in const pattern arguments
Part of https://github.com/dart-lang/sdk/issues/49749 Change-Id: I35801c7b0c6046076c8c31e66d684445654a8573 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/286480 Reviewed-by: Johnni Winther <johnniwinther@google.com> Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
This commit is contained in:
parent
2e1dfef731
commit
b1d7d84030
|
@ -6161,7 +6161,8 @@ class BodyBuilder extends StackListenerImpl
|
|||
Token nameToken, int offset, Constness constness,
|
||||
{required bool inMetadata, required bool inImplicitCreationContext}) {
|
||||
assert(checkState(nameToken, [
|
||||
/*arguments*/ ValueKinds.Arguments,
|
||||
/*arguments*/ unionOfKinds(
|
||||
[ValueKinds.Arguments, ValueKinds.ParserRecovery]),
|
||||
/*constructor name identifier*/ ValueKinds.IdentifierOrNull,
|
||||
/*constructor name*/ ValueKinds.Name,
|
||||
/*type arguments*/ ValueKinds.TypeArgumentsOrNull,
|
||||
|
@ -6173,7 +6174,7 @@ class BodyBuilder extends StackListenerImpl
|
|||
]),
|
||||
/*previous constant context*/ ValueKinds.ConstantContext,
|
||||
]));
|
||||
Arguments arguments = pop() as Arguments;
|
||||
Object? arguments = pop();
|
||||
Identifier? nameLastIdentifier = pop(NullValues.Identifier) as Identifier?;
|
||||
Token nameLastToken = nameLastIdentifier?.token ?? nameToken;
|
||||
String name = pop() as String;
|
||||
|
@ -6188,7 +6189,12 @@ class BodyBuilder extends StackListenerImpl
|
|||
Object? type = pop();
|
||||
|
||||
ConstantContext savedConstantContext = pop() as ConstantContext;
|
||||
if (type is Generator) {
|
||||
|
||||
if (arguments is! Arguments) {
|
||||
push(new ParserErrorGenerator(
|
||||
this, nameToken, fasta.messageSyntheticToken));
|
||||
arguments = forest.createArguments(offset, []);
|
||||
} else if (type is Generator) {
|
||||
push(type.invokeConstructor(
|
||||
typeArguments, name, arguments, nameToken, nameLastToken, constness,
|
||||
inImplicitCreationContext: inImplicitCreationContext));
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
// 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.
|
||||
|
||||
class C<T> {
|
||||
final T t;
|
||||
const C(this.t);
|
||||
}
|
||||
|
||||
Map<C<String>, int> foo() => throw 0;
|
||||
|
||||
test() {
|
||||
var {const C(:var t): a1} = foo();
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
library /*isNonNullableByDefault*/;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:16: Error: Expected an identifier, but got ':'.
|
||||
// Try inserting an identifier before ':'.
|
||||
// var {const C(:var t): a1} = foo();
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:17: Error: Expected an identifier, but got 'var'.
|
||||
// Try inserting an identifier before 'var'.
|
||||
// var {const C(:var t): a1} = foo();
|
||||
// ^^^
|
||||
//
|
||||
// pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:17: Error: Expected ')' before this.
|
||||
// var {const C(:var t): a1} = foo();
|
||||
// ^^^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
import "dart:_internal" as _in;
|
||||
|
||||
class C<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/ {
|
||||
final field self::C::T% t;
|
||||
const constructor •(self::C::T% t) → self::C<self::C::T%>
|
||||
: self::C::t = t, super core::Object::•()
|
||||
;
|
||||
}
|
||||
static method foo() → core::Map<self::C<core::String>, core::int>
|
||||
return throw 0;
|
||||
static method test() → dynamic {
|
||||
dynamic a1;
|
||||
{
|
||||
final dynamic #0#0 = self::foo();
|
||||
final const dynamic #0#4 = invalid-expression "pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:14: Error: This couldn't be parsed.
|
||||
var {const C(:var t): a1} = foo();
|
||||
^";
|
||||
if(!(#0#0{core::Map<self::C<core::String>, core::int>}.{core::Map::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && #0#0{core::Map<self::C<core::String>, core::int>}.{core::Map::containsKey}(invalid-expression "pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:14: Error: This couldn't be parsed.
|
||||
var {const C(:var t): a1} = foo();
|
||||
^"){(core::Object?) → core::bool} && (let final dynamic #t1 = a1 = #0#0{core::Map<self::C<core::String>, core::int>}.{core::Map::[]}(invalid-expression "pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:14: Error: This couldn't be parsed.
|
||||
var {const C(:var t): a1} = foo();
|
||||
^"){(core::Object?) → dynamic} in true)))
|
||||
throw new _in::ReachabilityError::•();
|
||||
}
|
||||
}
|
||||
|
||||
constants {
|
||||
#C1 = 1
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
library /*isNonNullableByDefault*/;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:16: Error: Expected an identifier, but got ':'.
|
||||
// Try inserting an identifier before ':'.
|
||||
// var {const C(:var t): a1} = foo();
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:17: Error: Expected an identifier, but got 'var'.
|
||||
// Try inserting an identifier before 'var'.
|
||||
// var {const C(:var t): a1} = foo();
|
||||
// ^^^
|
||||
//
|
||||
// pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:17: Error: Expected ')' before this.
|
||||
// var {const C(:var t): a1} = foo();
|
||||
// ^^^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
import "dart:_internal" as _in;
|
||||
|
||||
class C<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/ {
|
||||
final field self::C::T% t;
|
||||
const constructor •(self::C::T% t) → self::C<self::C::T%>
|
||||
: self::C::t = t, super core::Object::•()
|
||||
;
|
||||
}
|
||||
static method foo() → core::Map<self::C<core::String>, core::int>
|
||||
return throw 0;
|
||||
static method test() → dynamic {
|
||||
dynamic a1;
|
||||
{
|
||||
final dynamic #0#0 = self::foo();
|
||||
final const dynamic #0#4 = invalid-expression "pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:14: Error: This couldn't be parsed.
|
||||
var {const C(:var t): a1} = foo();
|
||||
^";
|
||||
if(!(#0#0{core::Map<self::C<core::String>, core::int>}.{core::Map::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && #0#0{core::Map<self::C<core::String>, core::int>}.{core::Map::containsKey}(invalid-expression "pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:14: Error: This couldn't be parsed.
|
||||
var {const C(:var t): a1} = foo();
|
||||
^"){(core::Object?) → core::bool} && (let final core::int? #t1 = a1 = #0#0{core::Map<self::C<core::String>, core::int>}.{core::Map::[]}(invalid-expression "pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:14: Error: This couldn't be parsed.
|
||||
var {const C(:var t): a1} = foo();
|
||||
^"){(core::Object?) → dynamic} in true)))
|
||||
throw new _in::ReachabilityError::•();
|
||||
}
|
||||
}
|
||||
|
||||
constants {
|
||||
#C1 = 1
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
class C<T> {
|
||||
final T t;
|
||||
const C(this.t);
|
||||
}
|
||||
|
||||
Map<C<String>, int> foo() => throw 0;
|
||||
test() {}
|
|
@ -0,0 +1,8 @@
|
|||
Map<C<String>, int> foo() => throw 0;
|
||||
|
||||
class C<T> {
|
||||
const C(this.t);
|
||||
final T t;
|
||||
}
|
||||
|
||||
test() {}
|
|
@ -0,0 +1,49 @@
|
|||
library /*isNonNullableByDefault*/;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:16: Error: Expected an identifier, but got ':'.
|
||||
// Try inserting an identifier before ':'.
|
||||
// var {const C(:var t): a1} = foo();
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:17: Error: Expected an identifier, but got 'var'.
|
||||
// Try inserting an identifier before 'var'.
|
||||
// var {const C(:var t): a1} = foo();
|
||||
// ^^^
|
||||
//
|
||||
// pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:17: Error: Expected ')' before this.
|
||||
// var {const C(:var t): a1} = foo();
|
||||
// ^^^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
import "dart:_internal" as _in;
|
||||
|
||||
class C<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/ {
|
||||
final field self::C::T% t;
|
||||
const constructor •(self::C::T% t) → self::C<self::C::T%>
|
||||
: self::C::t = t, super core::Object::•()
|
||||
;
|
||||
}
|
||||
static method foo() → core::Map<self::C<core::String>, core::int>
|
||||
return throw 0;
|
||||
static method test() → dynamic {
|
||||
dynamic a1;
|
||||
{
|
||||
final dynamic #0#0 = self::foo();
|
||||
final const dynamic #0#4 = invalid-expression "pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:14: Error: This couldn't be parsed.
|
||||
var {const C(:var t): a1} = foo();
|
||||
^";
|
||||
if(!(#0#0{core::Map<self::C<core::String>, core::int>}.{core::Map::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && #0#0{core::Map<self::C<core::String>, core::int>}.{core::Map::containsKey}(invalid-expression "pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:14: Error: This couldn't be parsed.
|
||||
var {const C(:var t): a1} = foo();
|
||||
^"){(core::Object?) → core::bool} && (let final dynamic #t1 = a1 = #0#0{core::Map<self::C<core::String>, core::int>}.{core::Map::[]}(invalid-expression "pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:14: Error: This couldn't be parsed.
|
||||
var {const C(:var t): a1} = foo();
|
||||
^"){(core::Object?) → dynamic} in true)))
|
||||
throw new _in::ReachabilityError::•();
|
||||
}
|
||||
}
|
||||
|
||||
constants {
|
||||
#C1 = 1
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
library /*isNonNullableByDefault*/;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:16: Error: Expected an identifier, but got ':'.
|
||||
// Try inserting an identifier before ':'.
|
||||
// var {const C(:var t): a1} = foo();
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:17: Error: Expected an identifier, but got 'var'.
|
||||
// Try inserting an identifier before 'var'.
|
||||
// var {const C(:var t): a1} = foo();
|
||||
// ^^^
|
||||
//
|
||||
// pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:17: Error: Expected ')' before this.
|
||||
// var {const C(:var t): a1} = foo();
|
||||
// ^^^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
import "dart:_internal" as _in;
|
||||
|
||||
class C<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/ {
|
||||
final field self::C::T% t;
|
||||
const constructor •(self::C::T% t) → self::C<self::C::T%>
|
||||
: self::C::t = t, super core::Object::•()
|
||||
;
|
||||
}
|
||||
static method foo() → core::Map<self::C<core::String>, core::int>
|
||||
return throw 0;
|
||||
static method test() → dynamic {
|
||||
dynamic a1;
|
||||
{
|
||||
final dynamic #0#0 = self::foo();
|
||||
final const dynamic #0#4 = invalid-expression "pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:14: Error: This couldn't be parsed.
|
||||
var {const C(:var t): a1} = foo();
|
||||
^";
|
||||
if(!(#0#0{core::Map<self::C<core::String>, core::int>}.{core::Map::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && #0#0{core::Map<self::C<core::String>, core::int>}.{core::Map::containsKey}(invalid-expression "pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:14: Error: This couldn't be parsed.
|
||||
var {const C(:var t): a1} = foo();
|
||||
^"){(core::Object?) → core::bool} && (let final dynamic #t1 = a1 = #0#0{core::Map<self::C<core::String>, core::int>}.{core::Map::[]}(invalid-expression "pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:14: Error: This couldn't be parsed.
|
||||
var {const C(:var t): a1} = foo();
|
||||
^"){(core::Object?) → dynamic} in true)))
|
||||
throw new _in::ReachabilityError::•();
|
||||
}
|
||||
}
|
||||
|
||||
constants {
|
||||
#C1 = 1
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
library /*isNonNullableByDefault*/;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
class C<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/ {
|
||||
final field self::C::T% t;
|
||||
const constructor •(self::C::T% t) → self::C<self::C::T%>
|
||||
: self::C::t = t, super core::Object::•()
|
||||
;
|
||||
}
|
||||
static method foo() → core::Map<self::C<core::String>, core::int>
|
||||
;
|
||||
static method test() → dynamic
|
||||
;
|
|
@ -0,0 +1,49 @@
|
|||
library /*isNonNullableByDefault*/;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:16: Error: Expected an identifier, but got ':'.
|
||||
// Try inserting an identifier before ':'.
|
||||
// var {const C(:var t): a1} = foo();
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:17: Error: Expected an identifier, but got 'var'.
|
||||
// Try inserting an identifier before 'var'.
|
||||
// var {const C(:var t): a1} = foo();
|
||||
// ^^^
|
||||
//
|
||||
// pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:17: Error: Expected ')' before this.
|
||||
// var {const C(:var t): a1} = foo();
|
||||
// ^^^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
import "dart:_internal" as _in;
|
||||
|
||||
class C<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/ {
|
||||
final field self::C::T% t;
|
||||
const constructor •(self::C::T% t) → self::C<self::C::T%>
|
||||
: self::C::t = t, super core::Object::•()
|
||||
;
|
||||
}
|
||||
static method foo() → core::Map<self::C<core::String>, core::int>
|
||||
return throw 0;
|
||||
static method test() → dynamic {
|
||||
dynamic a1;
|
||||
{
|
||||
final dynamic #0#0 = self::foo();
|
||||
final const dynamic #0#4 = invalid-expression "pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:14: Error: This couldn't be parsed.
|
||||
var {const C(:var t): a1} = foo();
|
||||
^";
|
||||
if(!(#0#0{core::Map<self::C<core::String>, core::int>}.{core::Map::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && #0#0{core::Map<self::C<core::String>, core::int>}.{core::Map::containsKey}(invalid-expression "pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:14: Error: This couldn't be parsed.
|
||||
var {const C(:var t): a1} = foo();
|
||||
^"){(core::Object?) → core::bool} && (let final core::int? #t1 = a1 = #0#0{core::Map<self::C<core::String>, core::int>}.{core::Map::[]}(invalid-expression "pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:14: Error: This couldn't be parsed.
|
||||
var {const C(:var t): a1} = foo();
|
||||
^"){(core::Object?) → dynamic} in true)))
|
||||
throw new _in::ReachabilityError::•();
|
||||
}
|
||||
}
|
||||
|
||||
constants {
|
||||
#C1 = 1
|
||||
}
|
Loading…
Reference in a new issue