diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/modifier_context.dart b/pkg/_fe_analyzer_shared/lib/src/parser/modifier_context.dart index 9b3402b791a..5d96d959425 100644 --- a/pkg/_fe_analyzer_shared/lib/src/parser/modifier_context.dart +++ b/pkg/_fe_analyzer_shared/lib/src/parser/modifier_context.dart @@ -605,14 +605,16 @@ class ModifierContext { if (covariantToken == null && staticToken == null && !_afterFactory) { staticToken = next; - if (constToken != null) { + if (abstractToken != null && parser.isAugmentationsFeatureEnabled) { + reportModifierOutOfOrder(next, abstractToken!.lexeme); + } else if (constToken != null) { reportModifierOutOfOrder(next, constToken!.lexeme); } else if (finalToken != null) { reportModifierOutOfOrder(next, finalToken!.lexeme); - } else if (varToken != null) { - reportModifierOutOfOrder(next, varToken!.lexeme); } else if (lateToken != null) { reportModifierOutOfOrder(next, lateToken!.lexeme); + } else if (varToken != null) { + reportModifierOutOfOrder(next, varToken!.lexeme); } return next; } diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart index 90f254255cb..1bca1f64a0d 100644 --- a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart +++ b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart @@ -348,7 +348,7 @@ class Parser { bool get allowedToShortcutParseExpression => true; /// `true` if the 'augmentations' feature is enabled. - final bool _isAugmentationsFeatureEnabled; + final bool isAugmentationsFeatureEnabled; Parser( this.listener, { @@ -363,8 +363,9 @@ class Parser { .isExperimentEnabled(ExperimentalFlag.primaryConstructors), _isAnonymousMethodsFeatureEnabled = experimentalFeatures .isExperimentEnabled(ExperimentalFlag.anonymousMethods), - _isAugmentationsFeatureEnabled = experimentalFeatures - .isExperimentEnabled(ExperimentalFlag.augmentations); + isAugmentationsFeatureEnabled = experimentalFeatures.isExperimentEnabled( + ExperimentalFlag.augmentations, + ); /// Executes [callback]; however if `this` is the `TestParser` (from /// `pkg/front_end/test/parser_test_parser.dart`) then no output is printed @@ -4349,7 +4350,7 @@ class Parser { if (getOrSet != null) { reportRecoverableErrorWithToken(getOrSet, diag.extraneousModifier); } - if (!_isAugmentationsFeatureEnabled && abstractToken != null) { + if (!isAugmentationsFeatureEnabled && abstractToken != null) { reportRecoverableErrorWithToken(abstractToken, diag.extraneousModifier); } return parseFields( @@ -4585,7 +4586,7 @@ class Parser { token = parseFunctionBody( token, /* ofFunctionExpression = */ false, - isExternal || _isAugmentationsFeatureEnabled, + isExternal || isAugmentationsFeatureEnabled, ); asyncState = savedAsyncModifier; listener.endTopLevelMethod(beforeStart.next!, getOrSet, token); @@ -5252,7 +5253,7 @@ class Parser { next = token.next!; } if (isModifier(next)) { - if (next.isA(Keyword.STATIC)) { + if (next.isA(Keyword.STATIC) && abstractToken == null) { staticToken = token = next; next = token.next!; } else if (next.isA(Keyword.COVARIANT)) { @@ -6009,7 +6010,7 @@ class Parser { /* ofFunctionExpression = */ false, /* allowAbstract = */ (staticToken == null || externalToken != null || - _isAugmentationsFeatureEnabled) && + isAugmentationsFeatureEnabled) && inPlainSync, ); } @@ -6211,7 +6212,7 @@ class Parser { token = parseFunctionBody( token, /* ofFunctionExpression = */ false, - /* allowAbstract = */ _isAugmentationsFeatureEnabled, + /* allowAbstract = */ isAugmentationsFeatureEnabled, ); } switch (kind) { diff --git a/pkg/analyzer/test/generated/class_member_parser_test.dart b/pkg/analyzer/test/generated/class_member_parser_test.dart index 4de9e116ad7..395c3becdeb 100644 --- a/pkg/analyzer/test/generated/class_member_parser_test.dart +++ b/pkg/analyzer/test/generated/class_member_parser_test.dart @@ -3010,28 +3010,6 @@ FieldDeclaration '''); } - void test_parseField_abstract_static() { - var parseResult = parseTestCodeWithDiagnostics(r''' -class C { - abstract static int? i; -} -'''); - var node = parseResult.findNode.singleClassMember; - assertParsedNodeText(node, r''' -FieldDeclaration - staticKeyword: static - abstractKeyword: abstract - fields: VariableDeclarationList - type: NamedType - name: int - question: ? - variables - VariableDeclaration - name: i - semicolon: ; -'''); - } - void test_parseField_const_late() { var parseResult = parseTestCodeWithDiagnostics(r''' class C { diff --git a/pkg/analyzer/test/src/dart/parser/class_test.dart b/pkg/analyzer/test/src/dart/parser/class_test.dart index 6c2efe8735e..6da12a0d23c 100644 --- a/pkg/analyzer/test/src/dart/parser/class_test.dart +++ b/pkg/analyzer/test/src/dart/parser/class_test.dart @@ -1325,6 +1325,69 @@ ClassDeclaration ''', withOffsets: true); } + test_field_abstract_static() { + var parseResult = parseTestCodeWithDiagnostics(r''' +class A { + abstract static int? foo; +// ^^^^^^ +// [diag.modifierOutOfOrder] The modifier 'static' should be before the modifier 'abstract'. +} +'''); + assertParsedNodeText(parseResult.findNode.singleClassDeclaration, r''' +ClassDeclaration + classKeyword: class + namePart: NameWithTypeParameters + typeName: A + body: BlockClassBody + leftBracket: { + members + FieldDeclaration + staticKeyword: static + abstractKeyword: abstract + fields: VariableDeclarationList + type: NamedType + name: int + question: ? + variables + VariableDeclaration + name: foo + semicolon: ; + rightBracket: } +'''); + } + + test_field_abstract_static_language305() { + var parseResult = parseTestCodeWithDiagnostics(r''' +// @dart = 3.5 +class A { + abstract static int? foo; +//^^^^^^^^ +// [diag.abstractStaticField] Static fields can't be declared 'abstract'. +} +'''); + assertParsedNodeText(parseResult.findNode.singleClassDeclaration, r''' +ClassDeclaration + classKeyword: class + namePart: NameWithTypeParameters + typeName: A + body: BlockClassBody + leftBracket: { + members + FieldDeclaration + staticKeyword: static + abstractKeyword: abstract + fields: VariableDeclarationList + type: NamedType + name: int + question: ? + variables + VariableDeclaration + name: foo + semicolon: ; + rightBracket: } +'''); + } + test_field_augment() { var parseResult = parseTestCodeWithDiagnostics(r''' augment class A {