Skip to content

Commit 9317ff2

Browse files
author
Dart CI
committed
Version 2.19.0-399.0.dev
Merge bf48667 into dev
2 parents 6f5478a + bf48667 commit 9317ff2

File tree

41 files changed

+635
-89
lines changed

Some content is hidden

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

41 files changed

+635
-89
lines changed

pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,17 @@ Message _withArgumentsAbstractRedirectedClassInstantiation(String name) {
143143
arguments: {'name': name});
144144
}
145145

146+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
147+
const Code<Null> codeAbstractSealedClass = messageAbstractSealedClass;
148+
149+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
150+
const MessageCode messageAbstractSealedClass = const MessageCode(
151+
"AbstractSealedClass",
152+
index: 132,
153+
problemMessage:
154+
r"""A class can't be declared both 'sealed' and 'abstract'.""",
155+
correctionMessage: r"""Try removing the 'abstract' or 'sealed' keyword.""");
156+
146157
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
147158
const Code<Null> codeAbstractStaticField = messageAbstractStaticField;
148159

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

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -545,11 +545,17 @@ class Parser {
545545
optional('class', next.next!)) {
546546
macroToken = next;
547547
next = next.next!;
548-
} else if (next.isIdentifier &&
549-
next.lexeme == 'sealed' &&
550-
optional('class', next.next!)) {
548+
} else if (next.isIdentifier && next.lexeme == 'sealed') {
551549
sealedToken = next;
552-
next = next.next!;
550+
if (optional('class', next.next!)) {
551+
next = next.next!;
552+
} else if (optional('abstract', next.next!) &&
553+
optional('class', next.next!.next!)) {
554+
// Defer error handling of sealed abstract to
555+
// [parseClassOrNamedMixinApplication] after the abstract is parsed.
556+
start = next;
557+
next = next.next!.next!;
558+
}
553559
}
554560
if (next.isTopLevelKeyword) {
555561
return parseTopLevelKeywordDeclaration(
@@ -2457,6 +2463,9 @@ class Parser {
24572463
Token token = computeTypeParamOrArg(
24582464
name, /* inDeclaration = */ true, /* allowsVariance = */ true)
24592465
.parseVariables(name, this);
2466+
if (abstractToken != null && sealedToken != null) {
2467+
reportRecoverableError(sealedToken, codes.messageAbstractSealedClass);
2468+
}
24602469
if (optional('=', token.next!)) {
24612470
listener.beginNamedMixinApplication(
24622471
begin, abstractToken, macroToken, viewToken, augmentToken, name);

pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2138,6 +2138,8 @@ ParserErrorCode.ABSTRACT_EXTERNAL_FIELD:
21382138
status: needsEvaluation
21392139
ParserErrorCode.ABSTRACT_LATE_FIELD:
21402140
status: needsEvaluation
2141+
ParserErrorCode.ABSTRACT_SEALED_CLASS:
2142+
status: needsEvaluation
21412143
ParserErrorCode.ABSTRACT_STATIC_FIELD:
21422144
status: needsEvaluation
21432145
ParserErrorCode.ABSTRACT_STATIC_METHOD:

pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ final fastaAnalyzerErrorCodes = <ErrorCode?>[
146146
ParserErrorCode.EMPTY_RECORD_TYPE_NAMED_FIELDS_LIST,
147147
ParserErrorCode.EMPTY_RECORD_TYPE_WITH_COMMA,
148148
ParserErrorCode.RECORD_TYPE_ONE_POSITIONAL_NO_TRAILING_COMMA,
149+
ParserErrorCode.ABSTRACT_SEALED_CLASS,
149150
];
150151

151152
class ParserErrorCode extends ErrorCode {
@@ -175,6 +176,12 @@ class ParserErrorCode extends ErrorCode {
175176
correctionMessage: "Try removing the 'abstract' or 'late' keyword.",
176177
);
177178

179+
static const ParserErrorCode ABSTRACT_SEALED_CLASS = ParserErrorCode(
180+
'ABSTRACT_SEALED_CLASS',
181+
"A class can't be declared both 'sealed' and 'abstract'.",
182+
correctionMessage: "Try removing the 'abstract' or 'sealed' keyword.",
183+
);
184+
178185
static const ParserErrorCode ABSTRACT_STATIC_FIELD = ParserErrorCode(
179186
'ABSTRACT_STATIC_FIELD',
180187
"Static fields can't be declared 'abstract'.",

pkg/analyzer/lib/src/error/error_code_values.g.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,7 @@ const List<ErrorCode> errorCodeValues = [
700700
ParserErrorCode.ABSTRACT_ENUM,
701701
ParserErrorCode.ABSTRACT_EXTERNAL_FIELD,
702702
ParserErrorCode.ABSTRACT_LATE_FIELD,
703+
ParserErrorCode.ABSTRACT_SEALED_CLASS,
703704
ParserErrorCode.ABSTRACT_STATIC_FIELD,
704705
ParserErrorCode.ABSTRACT_STATIC_METHOD,
705706
ParserErrorCode.ABSTRACT_TOP_LEVEL_FUNCTION,

pkg/analyzer/test/src/fasta/ast_builder_test.dart

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,26 @@ main() {
1515

1616
@reflectiveTest
1717
class AstBuilderTest extends ParserDiagnosticsTest {
18+
void test_class_abstract_sealed() {
19+
var parseResult = parseStringWithErrors(r'''
20+
abstract sealed class A {}
21+
''');
22+
parseResult.assertErrors([
23+
error(ParserErrorCode.ABSTRACT_SEALED_CLASS, 9, 6),
24+
]);
25+
26+
var node = parseResult.findNode.classDeclaration('class A {}');
27+
assertParsedNodeText(node, r'''
28+
ClassDeclaration
29+
abstractKeyword: abstract
30+
sealedKeyword: sealed
31+
classKeyword: class
32+
name: A
33+
leftBracket: {
34+
rightBracket: }
35+
''');
36+
}
37+
1838
void test_class_augment() {
1939
var parseResult = parseStringWithErrors(r'''
2040
augment class A {}
@@ -294,6 +314,26 @@ ClassDeclaration
294314
''');
295315
}
296316

317+
void test_class_sealed_abstract() {
318+
var parseResult = parseStringWithErrors(r'''
319+
sealed abstract class A {}
320+
''');
321+
parseResult.assertErrors([
322+
error(ParserErrorCode.ABSTRACT_SEALED_CLASS, 0, 6),
323+
]);
324+
325+
var node = parseResult.findNode.classDeclaration('class A {}');
326+
assertParsedNodeText(node, r'''
327+
ClassDeclaration
328+
abstractKeyword: abstract
329+
sealedKeyword: sealed
330+
classKeyword: class
331+
name: A
332+
leftBracket: {
333+
rightBracket: }
334+
''');
335+
}
336+
297337
void test_class_view() {
298338
var parseResult = parseStringWithErrors(r'''
299339
view class A {}

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1540,7 +1540,11 @@ class SourceClassBuilder extends ClassBuilderImpl
15401540
procedure.isInstanceMember &&
15411541
!procedure.isAbstract &&
15421542
_isPrivateNameInThisLibrary(procedure.name)) {
1543-
unpromotablePrivateFieldNames.add(procedure.name.text);
1543+
ProcedureStubKind procedureStubKind = procedure.stubKind;
1544+
if (procedureStubKind == ProcedureStubKind.Regular ||
1545+
procedureStubKind == ProcedureStubKind.NoSuchMethodForwarder) {
1546+
unpromotablePrivateFieldNames.add(procedure.name.text);
1547+
}
15441548
}
15451549
}
15461550
}

pkg/front_end/messages.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,16 @@ AbstractLateField:
788788
script:
789789
- "abstract class C {abstract late var f;}"
790790

791+
AbstractSealedClass:
792+
index: 132
793+
problemMessage: "A class can't be declared both 'sealed' and 'abstract'."
794+
correctionMessage: "Try removing the 'abstract' or 'sealed' keyword."
795+
analyzerCode: ParserErrorCode.ABSTRACT_SEALED_CLASS
796+
experiments: sealed-class
797+
script:
798+
- "sealed abstract class C {}"
799+
- "abstract sealed class C {}"
800+
791801
ClassInClass:
792802
index: 53
793803
problemMessage: "Classes can't be declared inside other classes."
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
abstract sealed class A {}
6+
sealed abstract class A {}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/sealed_class/sealed_abstract_class_declaration.dart:5:10: Error: A class can't be declared both 'sealed' and 'abstract'.
6+
// Try removing the 'abstract' or 'sealed' keyword.
7+
// abstract sealed class A {}
8+
// ^^^^^^
9+
//
10+
// pkg/front_end/testcases/sealed_class/sealed_abstract_class_declaration.dart:6:1: Error: A class can't be declared both 'sealed' and 'abstract'.
11+
// Try removing the 'abstract' or 'sealed' keyword.
12+
// sealed abstract class A {}
13+
// ^^^^^^
14+
//
15+
// pkg/front_end/testcases/sealed_class/sealed_abstract_class_declaration.dart:6:23: Error: 'A' is already declared in this scope.
16+
// sealed abstract class A {}
17+
// ^
18+
// pkg/front_end/testcases/sealed_class/sealed_abstract_class_declaration.dart:5:23: Context: Previous declaration of 'A'.
19+
// abstract sealed class A {}
20+
// ^
21+
//
22+
import self as self;
23+
import "dart:core" as core;
24+
25+
abstract class A#1#0 extends core::Object {
26+
synthetic constructor •() → self::A#1#0
27+
: super core::Object::•()
28+
;
29+
}
30+
abstract class A extends core::Object {
31+
synthetic constructor •() → self::A
32+
: super core::Object::•()
33+
;
34+
}

0 commit comments

Comments
 (0)