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

Commit 9ae3e22

Browse files
author
Dart CI
committed
Version 2.10.0-22.0.dev
Merge commit '7e42cbf5828ae800853c4baf1745d17ebc01bf2f' into 'dev'
2 parents 0001674 + 7e42cbf commit 9ae3e22

File tree

118 files changed

+1052
-156
lines changed

Some content is hidden

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

118 files changed

+1052
-156
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,8 +1121,8 @@ class ForwardingListener implements Listener {
11211121
}
11221122

11231123
@override
1124-
void handleClassExtends(Token extendsKeyword) {
1125-
listener?.handleClassExtends(extendsKeyword);
1124+
void handleClassExtends(Token extendsKeyword, int typeCount) {
1125+
listener?.handleClassExtends(extendsKeyword, typeCount);
11261126
}
11271127

11281128
@override

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,10 @@ class Listener implements UnescapeErrorListener {
126126

127127
/// Handle an extends clause in a class declaration. Substructures:
128128
/// - supertype (may be a mixin application)
129-
void handleClassExtends(Token extendsKeyword) {
129+
/// The typeCount is for error recovery: Invalid code might have more than one
130+
/// class specified in the extends clause. A parser error has already been
131+
/// issued.
132+
void handleClassExtends(Token extendsKeyword, int typeCount) {
130133
logEvent("ClassExtends");
131134
}
132135

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

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1903,10 +1903,7 @@ class Parser {
19031903
const ['extend', 'on'].contains(token.next.lexeme)) {
19041904
reportRecoverableError(
19051905
token.next, codes.templateExpectedInstead.withArguments('extends'));
1906-
Token incorrectExtendsKeyword = token.next;
1907-
token = computeType(incorrectExtendsKeyword, /* required = */ true)
1908-
.ensureTypeNotVoid(incorrectExtendsKeyword, this);
1909-
listener.handleClassExtends(incorrectExtendsKeyword);
1906+
token = parseClassExtendsSeenExtendsClause(token.next, token);
19101907
} else {
19111908
token = parseClassExtendsOpt(token);
19121909
}
@@ -1966,17 +1963,36 @@ class Parser {
19661963
// extends <typeNotVoid>
19671964
Token next = token.next;
19681965
if (optional('extends', next)) {
1969-
Token extendsKeyword = next;
1970-
token = computeType(next, /* required = */ true)
1971-
.ensureTypeNotVoid(next, this);
1972-
listener.handleClassExtends(extendsKeyword);
1966+
token = parseClassExtendsSeenExtendsClause(next, token);
19731967
} else {
19741968
listener.handleNoType(token);
1975-
listener.handleClassExtends(/* extendsKeyword = */ null);
1969+
listener.handleClassExtends(null, 1);
19761970
}
19771971
return token;
19781972
}
19791973

1974+
Token parseClassExtendsSeenExtendsClause(Token extendsKeyword, Token token) {
1975+
Token next = extendsKeyword;
1976+
token =
1977+
computeType(next, /* required = */ true).ensureTypeNotVoid(next, this);
1978+
int count = 1;
1979+
1980+
// Error recovery: extends <typeNotVoid>, <typeNotVoid> [...]
1981+
if (optional(',', token.next)) {
1982+
reportRecoverableError(token.next, codes.messageMultipleExtends);
1983+
1984+
while (optional(',', token.next)) {
1985+
next = token.next;
1986+
token = computeType(next, /* required = */ true)
1987+
.ensureTypeNotVoid(next, this);
1988+
count++;
1989+
}
1990+
}
1991+
1992+
listener.handleClassExtends(extendsKeyword, count);
1993+
return token;
1994+
}
1995+
19801996
/// ```
19811997
/// implementsClause:
19821998
/// 'implements' typeName (',' typeName)*

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ class ClassHeaderRecoveryListener extends ForwardingListener {
1818
}
1919

2020
@override
21-
void handleClassExtends(Token extendsKeyword) {
21+
void handleClassExtends(Token extendsKeyword, int typeCount) {
2222
this.extendsKeyword = extendsKeyword;
23-
super.handleClassExtends(extendsKeyword);
23+
super.handleClassExtends(extendsKeyword, typeCount);
2424
}
2525

2626
@override

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ abstract class StackListener extends Listener {
306306
}
307307

308308
@override
309-
void handleClassExtends(Token extendsKeyword) {
309+
void handleClassExtends(Token extendsKeyword, int typeCount) {
310310
debugEvent("ClassExtends");
311311
}
312312

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2447,10 +2447,16 @@ class AstBuilder extends StackListener {
24472447
}
24482448

24492449
@override
2450-
void handleClassExtends(Token extendsKeyword) {
2450+
void handleClassExtends(Token extendsKeyword, int typeCount) {
24512451
assert(extendsKeyword == null || extendsKeyword.isKeywordOrIdentifier);
24522452
debugEvent("ClassExtends");
24532453

2454+
// If more extends clauses was specified (parser has already issued an
2455+
// error) throw them away for now and pick the first one.
2456+
while (typeCount > 1) {
2457+
pop();
2458+
typeCount--;
2459+
}
24542460
TypeName supertype = pop();
24552461
if (supertype != null) {
24562462
push(ast.extendsClause(extendsKeyword, supertype));

pkg/analyzer/test/generated/parser_fasta_listener.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,9 +1260,9 @@ class ForwardingTestListener extends ForwardingListener {
12601260
}
12611261

12621262
@override
1263-
void handleClassExtends(Token extendsKeyword) {
1263+
void handleClassExtends(Token extendsKeyword, int typeCount) {
12641264
expectIn('ClassDeclaration');
1265-
listener.handleClassExtends(extendsKeyword);
1265+
listener.handleClassExtends(extendsKeyword, typeCount);
12661266
}
12671267

12681268
@override

pkg/front_end/lib/src/fasta/source/outline_builder.dart

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,11 @@ class OutlineBuilder extends StackListenerImpl {
522522
@override
523523
void handleRecoverClassHeader() {
524524
debugEvent("handleRecoverClassHeader");
525+
// TODO(jensj): Possibly use these instead... E.g. "class A extend B {}"
526+
// will get here (because it's 'extends' with an 's') and discard the B...
527+
// Also Analyzer actually merges the information meaning that the two could
528+
// give different errors (if, say, one later assigns
529+
// A to a variable of type B).
525530
pop(NullValue.TypeBuilderList); // Interfaces.
526531
pop(); // Supertype offset.
527532
pop(); // Supertype.
@@ -530,13 +535,19 @@ class OutlineBuilder extends StackListenerImpl {
530535
@override
531536
void handleRecoverMixinHeader() {
532537
debugEvent("handleRecoverMixinHeader");
538+
// TODO(jensj): Possibly use these instead...
539+
// See also handleRecoverClassHeader
533540
pop(NullValue.TypeBuilderList); // Interfaces.
534541
pop(NullValue.TypeBuilderList); // Supertype constraints.
535542
}
536543

537544
@override
538-
void handleClassExtends(Token extendsKeyword) {
545+
void handleClassExtends(Token extendsKeyword, int typeCount) {
539546
debugEvent("handleClassExtends");
547+
while (typeCount > 1) {
548+
pop();
549+
typeCount--;
550+
}
540551
push(extendsKeyword?.charOffset ?? -1);
541552
}
542553

pkg/front_end/messages.status

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -481,8 +481,6 @@ MixinFunction/script: Fail # TODO(johnniwinther): This message is currently igno
481481
MixinInferenceNoMatchingClass/example: Fail
482482
ModifierOutOfOrder/part_wrapped_script1: Fail
483483
ModifierOutOfOrder/script1: Fail
484-
MultipleExtends/part_wrapped_script: Fail
485-
MultipleExtends/script: Fail
486484
MultipleImplements/part_wrapped_script: Fail
487485
MultipleImplements/script: Fail
488486
MultipleLibraryDirectives/example: Fail

pkg/front_end/messages.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,9 @@ MultipleExtends:
366366
template: "Each class definition can have at most one extends clause."
367367
tip: "Try choosing one superclass and define your class to implement (or mix in) the others."
368368
analyzerCode: ParserErrorCode.MULTIPLE_EXTENDS_CLAUSES
369-
script: "class A extends B extends C {}"
369+
script:
370+
- "class B{} class C{} class A extends B extends C {}"
371+
- "class B{} class C{} class A extends B, C {}"
370372

371373
MultipleWith:
372374
index: 24

0 commit comments

Comments
 (0)