Version 2.16.0-145.0.dev
Merge commit '7ab78c48052c9a3c15e572303f20412be07df6ed' into 'dev'
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index 455a0f6..576a41f 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -31,6 +31,7 @@
templateExpectedButGot,
templateExpectedIdentifier,
templateExperimentNotEnabled,
+ templateExtraneousModifier,
templateInternalProblemUnhandled,
templateUnexpectedToken;
import 'package:_fe_analyzer_shared/src/parser/parser.dart'
@@ -51,7 +52,7 @@
show translateErrorToken;
import 'package:_fe_analyzer_shared/src/scanner/scanner.dart' hide StringToken;
import 'package:_fe_analyzer_shared/src/scanner/token.dart'
- show StringToken, SyntheticStringToken, SyntheticToken;
+ show KeywordToken, StringToken, SyntheticStringToken, SyntheticToken;
import 'package:_fe_analyzer_shared/src/scanner/token_constants.dart';
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
@@ -1552,6 +1553,13 @@
if (superKeyword != null) {
assert(thisKeyword == null,
"Can't have both 'this' and 'super' in a parameter.");
+ if (keyword is KeywordToken && keyword.keyword == Keyword.VAR) {
+ handleRecoverableError(
+ templateExtraneousModifier.withArguments(keyword),
+ keyword,
+ keyword,
+ );
+ }
node = ast.superFormalParameter(
comment: comment,
metadata: metadata,
diff --git a/pkg/analyzer/test/src/diagnostics/extraneous_modifier_test.dart b/pkg/analyzer/test/src/diagnostics/extraneous_modifier_test.dart
new file mode 100644
index 0000000..915db60
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/extraneous_modifier_test.dart
@@ -0,0 +1,66 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// 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/dart/error/syntactic_errors.dart';
+import 'package:analyzer_utilities/check/check.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../util/ast_check.dart';
+import '../../util/token_check.dart';
+import 'parser_diagnostics.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ExtraneousModifierTest);
+ });
+}
+
+@reflectiveTest
+class ExtraneousModifierTest extends ParserDiagnosticsTest {
+ test_simpleFormalParameter_const() async {
+ var parseResult = parseStringWithErrors(r'''
+class A {
+ A(const a);
+}
+''');
+ parseResult.assertErrors([
+ error(ParserErrorCode.EXTRANEOUS_MODIFIER, 14, 5),
+ ]);
+ check(parseResult.findNode.simpleFormalParameter('a);'))
+ ..keyword.isKeywordConst
+ ..type.isNull
+ ..identifier.isNotNull;
+ }
+
+ test_simpleFormalParameter_var() async {
+ var parseResult = parseStringWithErrors(r'''
+class A {
+ A(var a);
+}
+''');
+ parseResult.assertNoErrors();
+ check(parseResult.findNode.simpleFormalParameter('a);'))
+ ..keyword.isKeywordVar
+ ..type.isNull
+ ..identifier.isNotNull;
+ }
+
+ test_superFormalParameter_var() async {
+ var parseResult = parseStringWithErrors(r'''
+class A {
+ A(var super.a);
+}
+''');
+ parseResult.assertErrors([
+ error(ParserErrorCode.EXTRANEOUS_MODIFIER, 14, 3),
+ ]);
+ check(parseResult.findNode.superFormalParameter('super.a'))
+ ..keyword.isKeywordVar
+ ..superKeyword.isKeywordSuper
+ ..type.isNull
+ ..identifier.isNotNull
+ ..typeParameters.isNull
+ ..parameters.isNull;
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/function_typed_parameter_var_test.dart b/pkg/analyzer/test/src/diagnostics/function_typed_parameter_var_test.dart
new file mode 100644
index 0000000..b9c031c
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/function_typed_parameter_var_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// 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/dart/error/syntactic_errors.dart';
+import 'package:analyzer_utilities/check/check.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../util/ast_check.dart';
+import '../../util/token_check.dart';
+import 'parser_diagnostics.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(FunctionTypedParameterVarTest);
+ });
+}
+
+@reflectiveTest
+class FunctionTypedParameterVarTest extends ParserDiagnosticsTest {
+ test_superFormalParameter_var_functionTyped() async {
+ var parseResult = parseStringWithErrors(r'''
+class A {
+ A(var super.a<T>());
+}
+''');
+ parseResult.assertErrors([
+ error(ParserErrorCode.FUNCTION_TYPED_PARAMETER_VAR, 14, 3),
+ ]);
+ check(parseResult.findNode.superFormalParameter('super.a'))
+ ..keyword.isNull
+ ..superKeyword.isKeywordSuper
+ ..type.isNull
+ ..identifier.isNotNull
+ ..typeParameters.isNotNull.typeParameters.hasLength(1)
+ ..parameters.isNotNull;
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/parser_diagnostics.dart b/pkg/analyzer/test/src/diagnostics/parser_diagnostics.dart
new file mode 100644
index 0000000..975d781
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/parser_diagnostics.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// 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/dart/analysis/features.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/analysis/utilities.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer/src/test_utilities/find_node.dart';
+
+import '../../generated/test_support.dart';
+
+class ParserDiagnosticsTest {
+ ExpectedError error(
+ ErrorCode code,
+ int offset,
+ int length, {
+ Pattern? correctionContains,
+ String? text,
+ List<Pattern> messageContains = const [],
+ List<ExpectedContextMessage> contextMessages = const [],
+ }) {
+ return ExpectedError(
+ code,
+ offset,
+ length,
+ correctionContains: correctionContains,
+ message: text,
+ messageContains: messageContains,
+ expectedContextMessages: contextMessages,
+ );
+ }
+
+ ParseStringResult parseStringWithErrors(String content) {
+ return parseString(
+ content: content,
+ featureSet: FeatureSet.fromEnableFlags2(
+ sdkLanguageVersion: ExperimentStatus.currentVersion,
+ flags: [
+ Feature.enhanced_enums.enableString,
+ Feature.super_parameters.enableString,
+ ],
+ ),
+ throwIfDiagnostics: false,
+ );
+ }
+}
+
+extension ParseStringResultExtension on ParseStringResult {
+ FindNode get findNode {
+ return FindNode(content, unit);
+ }
+
+ void assertErrors(List<ExpectedError> expectedErrors) {
+ var errorListener = GatheringErrorListener();
+ errorListener.addAll(errors);
+ errorListener.assertErrors(expectedErrors);
+ }
+
+ void assertNoErrors() {
+ assertErrors(const []);
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 639450e..8bed89d 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -194,6 +194,7 @@
as extra_annotation_on_struct_field;
import 'extra_positional_arguments_test.dart' as extra_positional_arguments;
import 'extra_size_annotation_carray_test.dart' as extra_size_annotation_carray;
+import 'extraneous_modifier_test.dart' as extraneous_modifier;
import 'ffi_leaf_call_must_not_use_handle_test.dart'
as ffi_leaf_call_must_not_use_handle;
import 'ffi_native_test.dart' as ffi_native_test;
@@ -227,6 +228,7 @@
as for_in_of_invalid_element_type;
import 'for_in_of_invalid_type_test.dart' as for_in_of_invalid_type;
import 'for_in_with_const_variable_test.dart' as for_in_with_const_variable;
+import 'function_typed_parameter_var_test.dart' as function_typed_parameter_var;
import 'generic_function_type_cannot_be_bound_test.dart'
as generic_function_type_cannot_be_bound;
import 'generic_struct_subclass_test.dart' as generic_struct_subclass;
@@ -857,6 +859,7 @@
extra_annotation_on_struct_field.main();
extra_positional_arguments.main();
extra_size_annotation_carray.main();
+ extraneous_modifier.main();
ffi_leaf_call_must_not_use_handle.main();
ffi_native_test.main();
field_in_struct_with_initializer.main();
@@ -876,6 +879,7 @@
for_in_of_invalid_element_type.main();
for_in_of_invalid_type.main();
for_in_with_const_variable.main();
+ function_typed_parameter_var.main();
generic_function_type_cannot_be_bound.main();
generic_struct_subclass.main();
getter_not_assignable_setter_types.main();
diff --git a/pkg/analyzer/test/util/ast_check.dart b/pkg/analyzer/test/util/ast_check.dart
new file mode 100644
index 0000000..d990153
--- /dev/null
+++ b/pkg/analyzer/test/util/ast_check.dart
@@ -0,0 +1,85 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// 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/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer_utilities/check/check.dart';
+
+extension FormalParameterExtension on CheckTarget<FormalParameter> {
+ CheckTarget<SimpleIdentifier?> get identifier {
+ return nest(
+ value.identifier,
+ (selected) => 'has identifier ${valueStr(selected)}',
+ );
+ }
+}
+
+extension SimpleFormalParameterExtension on CheckTarget<SimpleFormalParameter> {
+ CheckTarget<Token?> get keyword {
+ return nest(
+ value.keyword,
+ (selected) => 'has keyword ${valueStr(selected)}',
+ );
+ }
+
+ CheckTarget<TypeAnnotation?> get type {
+ return nest(
+ value.type,
+ (selected) => 'has type ${valueStr(selected)}',
+ );
+ }
+}
+
+extension SuperFormalParameterExtension on CheckTarget<SuperFormalParameter> {
+ CheckTarget<SimpleIdentifier> get identifier {
+ return nest(
+ value.identifier,
+ (selected) => 'has identifier ${valueStr(selected)}',
+ );
+ }
+
+ CheckTarget<Token?> get keyword {
+ return nest(
+ value.keyword,
+ (selected) => 'has keyword ${valueStr(selected)}',
+ );
+ }
+
+ CheckTarget<FormalParameterList?> get parameters {
+ return nest(
+ value.parameters,
+ (selected) => 'has parameters ${valueStr(selected)}',
+ );
+ }
+
+ CheckTarget<Token?> get superKeyword {
+ return nest(
+ value.superKeyword,
+ (selected) => 'has superKeyword ${valueStr(selected)}',
+ );
+ }
+
+ CheckTarget<TypeAnnotation?> get type {
+ return nest(
+ value.type,
+ (selected) => 'has type ${valueStr(selected)}',
+ );
+ }
+
+ CheckTarget<TypeParameterList?> get typeParameters {
+ return nest(
+ value.typeParameters,
+ (selected) => 'has typeParameters ${valueStr(selected)}',
+ );
+ }
+}
+
+extension TypeParameterListExtension on CheckTarget<TypeParameterList> {
+ CheckTarget<List<TypeParameter>> get typeParameters {
+ return nest(
+ value.typeParameters,
+ (selected) => 'has typeParameters ${valueStr(selected)}',
+ );
+ }
+}
diff --git a/pkg/analyzer/test/util/token_check.dart b/pkg/analyzer/test/util/token_check.dart
new file mode 100644
index 0000000..7d8fc24
--- /dev/null
+++ b/pkg/analyzer/test/util/token_check.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// 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/dart/ast/token.dart';
+import 'package:analyzer/src/dart/ast/token.dart';
+import 'package:analyzer_utilities/check/check.dart';
+
+extension KeywordTokenExtension on CheckTarget<KeywordToken> {
+ CheckTarget<Keyword> get keyword {
+ return nest(
+ value.keyword,
+ (selected) => 'has keyword ${valueStr(selected)}',
+ );
+ }
+}
+
+extension TokenExtension on CheckTarget<Token?> {
+ CheckTarget<KeywordToken> get isKeyword {
+ return isA<KeywordToken>();
+ }
+
+ void get isKeywordConst {
+ isKeyword.keyword.isEqualTo(Keyword.CONST);
+ }
+
+ void get isKeywordSuper {
+ isKeyword.keyword.isEqualTo(Keyword.SUPER);
+ }
+
+ void get isKeywordVar {
+ isKeyword.keyword.isEqualTo(Keyword.VAR);
+ }
+}
diff --git a/tools/VERSION b/tools/VERSION
index 0516db1..e94eb46 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 16
PATCH 0
-PRERELEASE 144
+PRERELEASE 145
PRERELEASE_PATCH 0
\ No newline at end of file