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 8be4b88114a..0a4ab68b5bd 100644 --- a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart +++ b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart @@ -6189,7 +6189,7 @@ class Parser { token = parseFunctionBody( token, /* ofFunctionExpression = */ false, - /* allowAbstract = */ false, + /* allowAbstract = */ _isAugmentationsFeatureEnabled, ); } switch (kind) { diff --git a/pkg/analyzer/test/generated/error_parser_test.dart b/pkg/analyzer/test/generated/error_parser_test.dart index 657362b5c72..2c28d0a045f 100644 --- a/pkg/analyzer/test/generated/error_parser_test.dart +++ b/pkg/analyzer/test/generated/error_parser_test.dart @@ -1335,6 +1335,7 @@ class C { ]); } + @FailingTest() // TODO(scheglov): implement augmentation void test_factoryWithoutBody() { var parseResult = parseStringWithErrors(r''' class C { @@ -1344,6 +1345,16 @@ class C { parseResult.assertErrors([error(diag.missingFunctionBody, 23, 1)]); } + void test_factoryWithoutBody_language305() { + var parseResult = parseStringWithErrors(r''' +// @dart = 3.5 +class C { + factory C(); +} +'''); + parseResult.assertErrors([error(diag.missingFunctionBody, 38, 1)]); + } + void test_fieldInitializerOutsideConstructor() { var parseResult = parseStringWithErrors(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 23fa3788fdc..341d9cde9d8 100644 --- a/pkg/analyzer/test/src/dart/parser/class_test.dart +++ b/pkg/analyzer/test/src/dart/parser/class_test.dart @@ -879,6 +879,53 @@ ConstructorDeclaration '''); } + test_constructor_typeName_factory_unnamed_noBody() { + var parseResult = parseStringWithErrors(r''' +class A { + factory A(); +} +'''); + parseResult.assertExpectedDiagnostics(); + + var node = parseResult.findNode.singleConstructorDeclaration; + assertParsedNodeText(node, r''' +ConstructorDeclaration + factoryKeyword: factory + typeName: SimpleIdentifier + token: A + parameters: FormalParameterList + leftParenthesis: ( + rightParenthesis: ) + body: EmptyFunctionBody + semicolon: ; +'''); + } + + test_constructor_typeName_factory_unnamed_noBody_language305() { + var parseResult = parseStringWithErrors(r''' +// @dart = 3.5 +class A { + factory A(); +// ^ +// [diag.missingFunctionBody] A function body must be provided. +} +'''); + parseResult.assertExpectedDiagnostics(); + + var node = parseResult.findNode.singleConstructorDeclaration; + assertParsedNodeText(node, r''' +ConstructorDeclaration + factoryKeyword: factory + typeName: SimpleIdentifier + token: A + parameters: FormalParameterList + leftParenthesis: ( + rightParenthesis: ) + body: EmptyFunctionBody + semicolon: ; +'''); + } + test_constructor_typeName_factory_unnamed_withoutPrimaryConstructors() { var parseResult = parseStringWithErrors(r''' // @dart = 3.10 diff --git a/pkg/analyzer/test/src/diagnostics/constructor_already_complete_test.dart b/pkg/analyzer/test/src/diagnostics/constructor_already_complete_test.dart index 4016507554b..e390a70713e 100644 --- a/pkg/analyzer/test/src/diagnostics/constructor_already_complete_test.dart +++ b/pkg/analyzer/test/src/diagnostics/constructor_already_complete_test.dart @@ -55,7 +55,6 @@ class A { ); } - @FailingTest() // TODO(scheglov): implement augmentation test_secondary_factory_introductory_noBody() async { await assertNoErrorsInCode(r''' class A { diff --git a/pkg/analyzer/test/src/diagnostics/constructor_body_test.dart b/pkg/analyzer/test/src/diagnostics/constructor_body_test.dart index 162e921498e..9868d269e84 100644 --- a/pkg/analyzer/test/src/diagnostics/constructor_body_test.dart +++ b/pkg/analyzer/test/src/diagnostics/constructor_body_test.dart @@ -2,6 +2,7 @@ // 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. +import 'package:analyzer/src/diagnostic/diagnostic.dart' as diag; import 'package:test_reflective_loader/test_reflective_loader.dart'; import '../dart/resolution/context_collection_resolution.dart'; @@ -109,6 +110,7 @@ class C { '''); } + @SkippedTest() // TODO(scheglov): implement augmentation test_class_secondaryConstructor_constFactory_emptyBody() async { await resolveTestCodeWithDiagnostics(r''' class C { @@ -121,6 +123,18 @@ class C { '''); } + test_class_secondaryConstructor_constFactory_emptyBody_language305() async { + await assertErrorsInCode( + r''' +// @dart = 3.5 +class C { + const factory C(); +} +''', + [error(diag.constFactory, 27, 5), error(diag.missingFunctionBody, 44, 1)], + ); + } + test_class_secondaryConstructor_constFactory_expressionBody() async { await resolveTestCodeWithDiagnostics(r''' class C { @@ -470,6 +484,7 @@ enum E { '''); } + @SkippedTest() // TODO(scheglov): implement augmentation test_enum_secondaryConstructor_constFactory_emptyBody() async { await resolveTestCodeWithDiagnostics(r''' enum E { @@ -484,6 +499,20 @@ enum E { '''); } + test_enum_secondaryConstructor_constFactory_emptyBody_language305() async { + await assertErrorsInCode( + r''' +// @dart = 3.5 +enum E { + v; + const E(); + const factory E.named(); +} +''', + [error(diag.constFactory, 44, 5), error(diag.missingFunctionBody, 67, 1)], + ); + } + test_enum_secondaryConstructor_constFactory_expressionBody() async { await resolveTestCodeWithDiagnostics(r''' enum E { @@ -804,6 +833,7 @@ extension type const E(int it) { '''); } + @SkippedTest() // TODO(scheglov): implement augmentation test_extensionType_secondaryConstructor_constFactory_emptyBody() async { await resolveTestCodeWithDiagnostics(r''' extension type const E(int it) { @@ -816,6 +846,18 @@ extension type const E(int it) { '''); } + test_extensionType_secondaryConstructor_constFactory_emptyBody_language305() async { + await assertErrorsInCode( + r''' +// @dart = 3.5 +extension type const E(int it) { + const factory E.named(); +} +''', + [error(diag.constFactory, 50, 5), error(diag.missingFunctionBody, 73, 1)], + ); + } + test_extensionType_secondaryConstructor_constFactory_expressionBody() async { await resolveTestCodeWithDiagnostics(r''' extension type const E(int it) { diff --git a/pkg/analyzer/test/src/diagnostics/field_initializer_factory_constructor_test.dart b/pkg/analyzer/test/src/diagnostics/field_initializer_factory_constructor_test.dart index 948f5568a34..5eb1438bcd0 100644 --- a/pkg/analyzer/test/src/diagnostics/field_initializer_factory_constructor_test.dart +++ b/pkg/analyzer/test/src/diagnostics/field_initializer_factory_constructor_test.dart @@ -2,6 +2,7 @@ // 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. +import 'package:analyzer/src/diagnostic/diagnostic.dart' as diag; import 'package:test_reflective_loader/test_reflective_loader.dart'; import '../dart/resolution/context_collection_resolution.dart'; @@ -26,20 +27,34 @@ class A { } test_class_fieldFormalParameter_functionTyped() async { - // TODO(srawlins): Only report one error. Theoretically change Fasta to - // report "Field initializer in factory constructor" as a parse error. await resolveTestCodeWithDiagnostics(r''' class A { int Function()? x; factory A(int this.x()); // ^^^^^^^^^^^^ // [diag.fieldInitializerFactoryConstructor] Initializing formal parameters can't be used in factory constructors. -// ^ -// [diag.missingFunctionBody] A function body must be provided. } '''); } + test_class_fieldFormalParameter_functionTyped_language305() async { + await assertErrorsInCode( + r''' +// @dart = 3.5 +class A { + int Function()? x; + factory A(int this.x()); +} +''', + [ + // TODO(srawlins): Only report one error. Theoretically change Fasta to + // report "Field initializer in factory constructor" as a parse error. + error(diag.fieldInitializerFactoryConstructor, 58, 12), + error(diag.missingFunctionBody, 71, 1), + ], + ); + } + test_enum_fieldFormalParameter() async { await resolveTestCodeWithDiagnostics(r''' enum E {