Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit f709764

Browse files
author
Dart CI
committed
Version 2.19.0-425.0.dev
Merge 38ac261 into dev
2 parents a7d1f80 + 38ac261 commit f709764

File tree

72 files changed

+3301
-29
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+3301
-29
lines changed

pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1864,6 +1864,11 @@ class ForwardingListener implements Listener {
18641864
listener?.handleSpreadExpression(spreadToken);
18651865
}
18661866

1867+
@override
1868+
void handleRestPattern(Token dots, {required bool hasSubPattern}) {
1869+
listener?.handleRestPattern(dots, hasSubPattern: hasSubPattern);
1870+
}
1871+
18671872
@override
18681873
void handleStringJuxtaposition(Token startToken, int literalCount) {
18691874
listener?.handleStringJuxtaposition(startToken, literalCount);

pkg/_fe_analyzer_shared/lib/src/parser/identifier_context.dart

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,36 @@ bool looksLikeExpressionStart(Token next) =>
370370
optional('++', next) ||
371371
optional('--', next);
372372

373+
/// Returns `true` if the given [token] should be treated like the start of a
374+
/// pattern for the purposes of recovery.
375+
///
376+
/// Note: since the syntax for patterns is very similar to that for expressions,
377+
/// we mostly re-use [looksLikeExpressionStart].
378+
bool looksLikePatternStart(Token next) =>
379+
next.isIdentifier ||
380+
next.type == TokenType.DOUBLE ||
381+
next.type == TokenType.HASH ||
382+
next.type == TokenType.HEXADECIMAL ||
383+
next.type == TokenType.IDENTIFIER ||
384+
next.type == TokenType.INT ||
385+
next.type == TokenType.STRING ||
386+
optional('null', next) ||
387+
optional('false', next) ||
388+
optional('true', next) ||
389+
optional('{', next) ||
390+
optional('(', next) ||
391+
optional('[', next) ||
392+
optional('[]', next) ||
393+
optional('<', next) ||
394+
optional('<=', next) ||
395+
optional('>', next) ||
396+
optional('>=', next) ||
397+
optional('!=', next) ||
398+
optional('==', next) ||
399+
optional('var', next) ||
400+
optional('final', next) ||
401+
optional('const', next);
402+
373403
/// Return `true` if the given [token] should be treated like the start of
374404
/// a new statement for the purposes of recovery.
375405
bool looksLikeStatementStart(Token token) => isOneOfOrEof(token, const [

pkg/_fe_analyzer_shared/lib/src/parser/listener.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1673,6 +1673,13 @@ class Listener implements UnescapeErrorListener {
16731673
logEvent("SpreadExpression");
16741674
}
16751675

1676+
/// Called after parsing an element of a list or map pattern that starts with
1677+
/// `...`. Substructures:
1678+
/// - pattern (if hasSubPattern is `true`)
1679+
void handleRestPattern(Token dots, {required bool hasSubPattern}) {
1680+
logEvent('RestPattern');
1681+
}
1682+
16761683
/// Handle the start of a function typed formal parameter. Substructures:
16771684
/// - type variables
16781685
void beginFunctionTypedFormalParameter(Token token) {}

pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ import 'identifier_context.dart'
7575
show
7676
IdentifierContext,
7777
looksLikeExpressionStart,
78+
looksLikePatternStart,
7879
okNextValueInFormalParameter;
7980

8081
import 'identifier_context_impl.dart'
@@ -9493,7 +9494,18 @@ class Parser {
94939494
token = next;
94949495
break;
94959496
}
9496-
token = parsePattern(token, isRefutableContext: isRefutableContext);
9497+
if (optional('...', next)) {
9498+
Token dots = next;
9499+
token = next;
9500+
next = token.next!;
9501+
bool hasSubPattern = looksLikePatternStart(next);
9502+
if (hasSubPattern) {
9503+
token = parsePattern(token, isRefutableContext: isRefutableContext);
9504+
}
9505+
listener.handleRestPattern(dots, hasSubPattern: hasSubPattern);
9506+
} else {
9507+
token = parsePattern(token, isRefutableContext: isRefutableContext);
9508+
}
94979509
next = token.next!;
94989510
++count;
94999511
if (!optional(',', next)) {

pkg/_fe_analyzer_shared/lib/src/parser/type_info.dart

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -359,14 +359,15 @@ TypeInfo computeVariablePatternType(Token token) {
359359
if (!identical(afterType, token)) {
360360
Token next = afterType.next!;
361361
if (next.isIdentifier) {
362-
if (optional('as', next)) {
363-
// We've seen `TYPE as`. `as` is a built-in identifier, so this
364-
// *could* be a variable pattern. Or it could be that TYPE should
365-
// have been parsed as a pattern. It's probably not a variable
366-
// pattern (since `as` is an unusual variable name), so we'll only
367-
// treat it as a variable pattern if the token following `as` is
368-
// something that could legitimately follow a variable pattern (and
369-
// hence couldn't introduce a type).
362+
if (optional('as', next) || optional('when', next)) {
363+
// We've seen `TYPE as` or `TYPE when`. `as` is a built-in identifier
364+
// and `when` is a pseudo-keyword, so this *could* be a variable
365+
// pattern. Or it could be that TYPE should have been parsed as a
366+
// pattern. It's probably not a variable pattern (since `as` and `when`
367+
// are unusual variable names), so we'll only treat it as a variable
368+
// pattern if the token following `as` or `when` is something that could
369+
// legitimately follow a variable pattern (and hence couldn't introduce
370+
// a type).
370371
if (!mayFollowVariablePattern(next.next!)) {
371372
return noType;
372373
}
@@ -448,6 +449,7 @@ const Set<String> _allowedTokensAfterVariablePattern = {
448449
'}',
449450
']',
450451
'as',
452+
'when',
451453
'?',
452454
'!'
453455
};

pkg/analyzer/lib/src/clients/build_resolvers/build_resolvers.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import 'package:analyzer/src/summary/summary_sdk.dart';
1818
import 'package:analyzer/src/summary2/package_bundle_format.dart';
1919

2020
export 'package:analyzer/src/context/packages.dart' show Packages, Package;
21+
export 'package:analyzer/src/dart/analysis/byte_store.dart' show ByteStore;
2122
export 'package:analyzer/src/dart/analysis/experiments.dart'
2223
show ExperimentStatus;
2324
export 'package:analyzer/src/generated/engine.dart'
@@ -37,6 +38,7 @@ AnalysisDriverForPackageBuild createAnalysisDriver({
3738
required AnalysisOptions analysisOptions,
3839
required List<UriResolver> uriResolvers,
3940
required Packages packages,
41+
ByteStore? byteStore,
4042
}) {
4143
var sdkBundle = PackageBundleReader(sdkSummaryBytes);
4244
var sdk = SummaryBasedDartSdk.forBundle(sdkBundle);
@@ -55,7 +57,7 @@ AnalysisDriverForPackageBuild createAnalysisDriver({
5557
scheduler: scheduler,
5658
logger: logger,
5759
resourceProvider: resourceProvider,
58-
byteStore: MemoryByteStore(),
60+
byteStore: byteStore ?? MemoryByteStore(),
5961
sourceFactory: sourceFactory,
6062
analysisOptions: analysisOptions as AnalysisOptionsImpl,
6163
externalSummaries: dataStore,

pkg/analyzer/lib/src/fasta/ast_builder.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4972,6 +4972,12 @@ class AstBuilder extends StackListener {
49724972
operator: token, operand: pop() as ExpressionImpl));
49734973
}
49744974

4975+
@override
4976+
void handleRestPattern(Token dots, {required bool hasSubPattern}) {
4977+
var subPattern = hasSubPattern ? pop() as DartPatternImpl : null;
4978+
push(RestPatternElementImpl(operator: dots, pattern: subPattern));
4979+
}
4980+
49754981
@override
49764982
void handleScript(Token token) {
49774983
assert(identical(token.type, TokenType.SCRIPT_TAG));

0 commit comments

Comments
 (0)