Augment. Report augmentationPositionalFormalParameterName.
PS1: rename the test file. Change-Id: I0e38a25c9c6d2b573766eb9a088fadbc8a4fc5b4 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/509202 Reviewed-by: Paul Berry <paulberry@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
@@ -255,6 +255,8 @@ augmentation_of_mixin_application_class:
|
||||
status: needsEvaluation
|
||||
augmentation_optional_positional_formal_parameter_count:
|
||||
status: needsEvaluation
|
||||
augmentation_positional_formal_parameter_name:
|
||||
status: needsEvaluation
|
||||
augmentation_required_positional_formal_parameter_count:
|
||||
status: needsEvaluation
|
||||
augmentation_return_type_mismatch:
|
||||
|
||||
@@ -1073,6 +1073,27 @@ augmentationOptionalPositionalFormalParameterCount = DiagnosticWithArguments(
|
||||
expectedTypes: [ExpectedType.int, ExpectedType.int],
|
||||
);
|
||||
|
||||
/// Parameters:
|
||||
/// String expectedName: the name from a preceding declaration.
|
||||
/// String actualName: the name in the augmentation.
|
||||
const DiagnosticWithArguments<
|
||||
LocatableDiagnostic Function({
|
||||
required String expectedName,
|
||||
required String actualName,
|
||||
})
|
||||
>
|
||||
augmentationPositionalFormalParameterName = DiagnosticWithArguments(
|
||||
name: 'augmentation_positional_formal_parameter_name',
|
||||
problemMessage:
|
||||
"The parameter name '{1}' must either match the name '{0}' from a "
|
||||
"preceding declaration or be '_'.",
|
||||
correctionMessage: "Try changing the name to '{0}', or changing it to '_'.",
|
||||
type: DiagnosticType.COMPILE_TIME_ERROR,
|
||||
uniqueName: 'augmentation_positional_formal_parameter_name',
|
||||
withArguments: _withArgumentsAugmentationPositionalFormalParameterName,
|
||||
expectedTypes: [ExpectedType.string, ExpectedType.string],
|
||||
);
|
||||
|
||||
/// Parameters:
|
||||
/// int expectedCount: the number of required positional formal parameters in
|
||||
/// the declaration.
|
||||
@@ -18739,6 +18760,16 @@ _withArgumentsAugmentationOptionalPositionalFormalParameterCount({
|
||||
);
|
||||
}
|
||||
|
||||
LocatableDiagnostic _withArgumentsAugmentationPositionalFormalParameterName({
|
||||
required String expectedName,
|
||||
required String actualName,
|
||||
}) {
|
||||
return LocatableDiagnosticImpl(
|
||||
diag.augmentationPositionalFormalParameterName,
|
||||
[expectedName, actualName],
|
||||
);
|
||||
}
|
||||
|
||||
LocatableDiagnostic
|
||||
_withArgumentsAugmentationRequiredPositionalFormalParameterCount({
|
||||
required int expectedCount,
|
||||
|
||||
@@ -80,6 +80,7 @@ const List<DiagnosticCode> diagnosticCodeValues = [
|
||||
diag.augmentationOfDifferentDeclarationKind,
|
||||
diag.augmentationOfMixinApplicationClass,
|
||||
diag.augmentationOptionalPositionalFormalParameterCount,
|
||||
diag.augmentationPositionalFormalParameterName,
|
||||
diag.augmentationRequiredPositionalFormalParameterCount,
|
||||
diag.augmentationReturnTypeMismatch,
|
||||
diag.augmentationTypeParameterBound,
|
||||
|
||||
@@ -2793,6 +2793,13 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
|
||||
.where((parameter) => parameter.isRequiredPositional)
|
||||
.length;
|
||||
|
||||
var firstOptionalPositionalCount = firstParameters
|
||||
.where((parameter) => parameter.isOptionalPositional)
|
||||
.length;
|
||||
var currentOptionalPositionalCount = currentParameters
|
||||
.where((parameter) => parameter.isOptionalPositional)
|
||||
.length;
|
||||
|
||||
FormalParameter? formalParameterAtPositionalIndex(int index) {
|
||||
return formalParameterList.parameters
|
||||
.where((parameter) => parameter.isPositional)
|
||||
@@ -2838,13 +2845,6 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
|
||||
),
|
||||
);
|
||||
} else {
|
||||
var firstOptionalPositionalCount = firstParameters
|
||||
.where((parameter) => parameter.isOptionalPositional)
|
||||
.length;
|
||||
var currentOptionalPositionalCount = currentParameters
|
||||
.where((parameter) => parameter.isOptionalPositional)
|
||||
.length;
|
||||
|
||||
if (currentOptionalPositionalCount < firstOptionalPositionalCount) {
|
||||
diagnosticReporter.report(
|
||||
diag.augmentationOptionalPositionalFormalParameterCount
|
||||
@@ -2883,6 +2883,57 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
|
||||
}
|
||||
}
|
||||
|
||||
// Positional parameter names can be `_`, but every non-wildcard name must
|
||||
// match all preceding non-wildcard declarations for the same parameter.
|
||||
if (currentRequiredPositionalCount == firstRequiredPositionalCount &&
|
||||
currentOptionalPositionalCount == firstOptionalPositionalCount) {
|
||||
for (var formalParameter in formalParameterList.parameters) {
|
||||
if (!formalParameter.isPositional) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var currentParameter = formalParameter.declaredFragment;
|
||||
if (currentParameter is! FormalParameterFragmentImpl ||
|
||||
currentParameter.isOriginOtherFragmentOfEnclosing) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var currentName = currentParameter.name;
|
||||
if (currentName == null || currentName == '_') {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (var precedingParameter in currentParameter.precedingFragments) {
|
||||
if (precedingParameter.isOriginOtherFragmentOfEnclosing ||
|
||||
precedingParameter.nameOffset == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var precedingName = precedingParameter.name;
|
||||
if (precedingName == null ||
|
||||
precedingName == '_' ||
|
||||
precedingName == currentName) {
|
||||
continue;
|
||||
}
|
||||
|
||||
diagnosticReporter.report(
|
||||
diag.augmentationPositionalFormalParameterName
|
||||
.withArguments(
|
||||
expectedName: precedingName,
|
||||
actualName: currentName,
|
||||
)
|
||||
.withContextMessages([
|
||||
?precedingParameter.contextMessageAt(
|
||||
'The preceding declaration is here.',
|
||||
),
|
||||
])
|
||||
.at(formalParameterErrorEntity(formalParameter)),
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var firstNamedParametersByName = <String, FormalParameterFragmentImpl>{};
|
||||
for (var parameter in firstParameters) {
|
||||
var name = parameter.name;
|
||||
|
||||
@@ -1857,6 +1857,15 @@ CompileTimeErrorCode:
|
||||
problemMessage: "The augmentation has #actualCount optional positional formal parameters, but the declaration has #expectedCount."
|
||||
correctionMessage: Try changing the augmentation's formal parameters to match the declaration.
|
||||
hasPublishedDocs: false
|
||||
augmentationPositionalFormalParameterName:
|
||||
type: compileTimeError
|
||||
parameters:
|
||||
String expectedName: the name from a preceding declaration.
|
||||
String actualName: the name in the augmentation.
|
||||
experiment: augmentations
|
||||
problemMessage: "The parameter name '#actualName' must either match the name '#expectedName' from a preceding declaration or be '_'."
|
||||
correctionMessage: "Try changing the name to '#expectedName', or changing it to '_'."
|
||||
hasPublishedDocs: false
|
||||
augmentationOfDifferentDeclarationKind:
|
||||
type: compileTimeError
|
||||
parameters:
|
||||
|
||||
+190
@@ -9,11 +9,190 @@ import '../dart/resolution/node_text_expectations.dart';
|
||||
|
||||
main() {
|
||||
defineReflectiveSuite(() {
|
||||
defineReflectiveTests(AugmentationFormalParameterNameTest);
|
||||
defineReflectiveTests(AugmentationFormalParameterShapeTest);
|
||||
defineReflectiveTests(UpdateNodeTextExpectations);
|
||||
});
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class AugmentationFormalParameterNameTest extends PubPackageResolutionTest {
|
||||
test_class_constructor_fP1__rP2() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
class A {
|
||||
final int p1;
|
||||
A(this.p1);
|
||||
// ^^
|
||||
// [context 1] The preceding declaration is here.
|
||||
augment A(int p2);
|
||||
// ^^
|
||||
// [diag.augmentationPositionalFormalParameterName][context 1] The parameter name 'p2' must either match the name 'p1' from a preceding declaration or be '_'.
|
||||
}
|
||||
''');
|
||||
}
|
||||
|
||||
test_class_constructor_sp1__rp2() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
class A {
|
||||
A([int? p1]);
|
||||
}
|
||||
class B extends A {
|
||||
B([super.p1]);
|
||||
// ^^
|
||||
// [context 1] The preceding declaration is here.
|
||||
augment B([int? p2]);
|
||||
// ^^
|
||||
// [diag.augmentationPositionalFormalParameterName][context 1] The parameter name 'p2' must either match the name 'p1' from a preceding declaration or be '_'.
|
||||
}
|
||||
''');
|
||||
}
|
||||
|
||||
test_class_instanceMethod_rP__x__y() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
abstract class A {
|
||||
void foo(int x);
|
||||
// ^
|
||||
// [context 1] The preceding declaration is here.
|
||||
augment void foo(int y) {}
|
||||
// ^
|
||||
// [diag.augmentationPositionalFormalParameterName][context 1] The parameter name 'y' must either match the name 'x' from a preceding declaration or be '_'.
|
||||
}
|
||||
''');
|
||||
}
|
||||
|
||||
test_topLevelFunction_rP__wildcard__x__wildcard() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
void f(int _);
|
||||
augment void f(int x);
|
||||
augment void f(int _) {}
|
||||
''');
|
||||
}
|
||||
|
||||
test_topLevelFunction_rP__wildcard__x__y() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
void f(int _);
|
||||
augment void f(int x);
|
||||
// ^
|
||||
// [context 1] The preceding declaration is here.
|
||||
augment void f(int y) {}
|
||||
// ^
|
||||
// [diag.augmentationPositionalFormalParameterName][context 1] The parameter name 'y' must either match the name 'x' from a preceding declaration or be '_'.
|
||||
''');
|
||||
}
|
||||
|
||||
test_topLevelFunction_rP__x__wildcard() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
void f(int x);
|
||||
augment void f(int _) {}
|
||||
''');
|
||||
}
|
||||
|
||||
test_topLevelFunction_rp__x__wildcard() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
void f([int? x]);
|
||||
augment void f([int? _]) {}
|
||||
''');
|
||||
}
|
||||
|
||||
test_topLevelFunction_rP__x__wildcard__x() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
void f(int x);
|
||||
augment void f(int _);
|
||||
augment void f(int x) {}
|
||||
''');
|
||||
}
|
||||
|
||||
test_topLevelFunction_rP__x__wildcard__y() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
void f(int x);
|
||||
// ^
|
||||
// [context 1] The preceding declaration is here.
|
||||
augment void f(int _);
|
||||
augment void f(int y) {}
|
||||
// ^
|
||||
// [diag.augmentationPositionalFormalParameterName][context 1] The parameter name 'y' must either match the name 'x' from a preceding declaration or be '_'.
|
||||
''');
|
||||
}
|
||||
|
||||
test_topLevelFunction_rP__x__y() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
void f(int x);
|
||||
// ^
|
||||
// [context 1] The preceding declaration is here.
|
||||
augment void f(int y) {}
|
||||
// ^
|
||||
// [diag.augmentationPositionalFormalParameterName][context 1] The parameter name 'y' must either match the name 'x' from a preceding declaration or be '_'.
|
||||
''');
|
||||
}
|
||||
|
||||
test_topLevelFunction_rp__x__y() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
void f([int? x]);
|
||||
// ^
|
||||
// [context 1] The preceding declaration is here.
|
||||
augment void f([int? y]) {}
|
||||
// ^
|
||||
// [diag.augmentationPositionalFormalParameterName][context 1] The parameter name 'y' must either match the name 'x' from a preceding declaration or be '_'.
|
||||
''');
|
||||
}
|
||||
|
||||
test_topLevelFunction_rP_rP__x_y__a_b() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
void f(int x, int y);
|
||||
// ^
|
||||
// [context 1] The preceding declaration is here.
|
||||
// ^
|
||||
// [context 2] The preceding declaration is here.
|
||||
augment void f(int a, int b) {}
|
||||
// ^
|
||||
// [diag.augmentationPositionalFormalParameterName][context 1] The parameter name 'a' must either match the name 'x' from a preceding declaration or be '_'.
|
||||
// ^
|
||||
// [diag.augmentationPositionalFormalParameterName][context 2] The parameter name 'b' must either match the name 'y' from a preceding declaration or be '_'.
|
||||
''');
|
||||
}
|
||||
|
||||
test_topLevelFunction_rP_rp__x_y__x_z() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
void f(int x, [int? y]);
|
||||
// ^
|
||||
// [context 1] The preceding declaration is here.
|
||||
augment void f(int x, [int? z]) {}
|
||||
// ^
|
||||
// [diag.augmentationPositionalFormalParameterName][context 1] The parameter name 'z' must either match the name 'y' from a preceding declaration or be '_'.
|
||||
''');
|
||||
}
|
||||
|
||||
test_topLevelSetter_rP__wildcard__x__y() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
set foo(int _);
|
||||
augment set foo(int x);
|
||||
// ^
|
||||
// [context 1] The preceding declaration is here.
|
||||
augment set foo(int y) {}
|
||||
// ^
|
||||
// [diag.augmentationPositionalFormalParameterName][context 1] The parameter name 'y' must either match the name 'x' from a preceding declaration or be '_'.
|
||||
''');
|
||||
}
|
||||
|
||||
test_topLevelSetter_rP__x__wildcard() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
set foo(int x);
|
||||
augment set foo(int _) {}
|
||||
''');
|
||||
}
|
||||
|
||||
test_topLevelSetter_rP__x__y() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
set foo(int x);
|
||||
// ^
|
||||
// [context 1] The preceding declaration is here.
|
||||
augment set foo(int y) {}
|
||||
// ^
|
||||
// [diag.augmentationPositionalFormalParameterName][context 1] The parameter name 'y' must either match the name 'x' from a preceding declaration or be '_'.
|
||||
''');
|
||||
}
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class AugmentationFormalParameterShapeTest extends PubPackageResolutionTest {
|
||||
test_class_constructor_rP1__rP1_rP2() async {
|
||||
@@ -198,6 +377,17 @@ augment void f(int? p1, [int? p2, int? p3]) {}
|
||||
''');
|
||||
}
|
||||
|
||||
test_topLevelFunction_rP1__rP2_rP3_nameMismatch() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
void f(int p1);
|
||||
// ^
|
||||
// [context 1] The declaration being augmented.
|
||||
augment void f(int p2, int p3) {}
|
||||
// ^^
|
||||
// [diag.augmentationRequiredPositionalFormalParameterCount][context 1] The augmentation has 2 required positional formal parameters, but the declaration has 1.
|
||||
''');
|
||||
}
|
||||
|
||||
test_topLevelFunction_rP1_rn1__rP1() async {
|
||||
await resolveTestCodeWithDiagnostics(r'''
|
||||
void f(int? p1, {int? n1});
|
||||
@@ -42,8 +42,8 @@ import 'async_keyword_used_as_identifier_test.dart'
|
||||
as async_keyword_used_as_identifier;
|
||||
import 'augmentation_extends_clause_already_present_test.dart'
|
||||
as augmentation_extends_clause_already_present;
|
||||
import 'augmentation_formal_parameter_shape_test.dart'
|
||||
as augmentation_formal_parameter_shape;
|
||||
import 'augmentation_formal_parameter_test.dart'
|
||||
as augmentation_formal_parameter;
|
||||
import 'augmentation_modifier_extra_test.dart' as augmentation_modifier_extra;
|
||||
import 'augmentation_modifier_missing_test.dart'
|
||||
as augmentation_modifier_missing;
|
||||
@@ -993,7 +993,7 @@ main() {
|
||||
async_for_in_wrong_context.main();
|
||||
async_keyword_used_as_identifier.main();
|
||||
augmentation_extends_clause_already_present.main();
|
||||
augmentation_formal_parameter_shape.main();
|
||||
augmentation_formal_parameter.main();
|
||||
augmentation_modifier_extra.main();
|
||||
augmentation_modifier_missing.main();
|
||||
augmentation_of_different_declaration_kind.main();
|
||||
|
||||
Reference in New Issue
Block a user