Remove INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES warnings

Fixes https://github.com/dart-lang/sdk/issues/49112

It was decided to remove the "override with equal default value"
restriction both for null safe code, and for pre-null safe code.

CFE had never issued this static warning, and her we remove it from
analyzer.

Change-Id: I1244e4fe46da8bb4bd8c3a77ec8beb95811e30a1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/262267
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
Sam Rawlins 2022-10-04 18:23:10 +00:00 committed by Samuel Rawlins
parent 33c1ff60da
commit 15be61ed9a
9 changed files with 2 additions and 899 deletions

View file

@ -28,7 +28,7 @@
# - 206 for ParserErrorCodes.
# - 68 "needsFix"
# - 287 "hasFix"
# - 57 "noFix"
# - 55 "noFix"
AnalysisOptionsErrorCode.INCLUDED_FILE_PARSE_ERROR:
status: noFix
@ -2599,14 +2599,6 @@ StaticWarningCode.INVALID_NULL_AWARE_OPERATOR:
status: hasFix
StaticWarningCode.INVALID_NULL_AWARE_OPERATOR_AFTER_SHORT_CIRCUIT:
status: hasFix
StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED:
status: noFix
notes: |-
This is a pre-null safety code. No need to add a fix.
StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL:
status: noFix
notes: |-
This is a pre-null safety code. No need to add a fix.
StaticWarningCode.MISSING_ENUM_CONSTANT_IN_SWITCH:
status: hasFix
StaticWarningCode.UNNECESSARY_NON_NULL_ASSERTION:

View file

@ -953,8 +953,6 @@ const List<ErrorCode> errorCodeValues = [
StaticWarningCode.DEAD_NULL_AWARE_EXPRESSION,
StaticWarningCode.INVALID_NULL_AWARE_OPERATOR,
StaticWarningCode.INVALID_NULL_AWARE_OPERATOR_AFTER_SHORT_CIRCUIT,
StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED,
StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL,
StaticWarningCode.MISSING_ENUM_CONSTANT_IN_SWITCH,
StaticWarningCode.UNNECESSARY_NON_NULL_ASSERTION,
TodoCode.TODO,

View file

@ -5213,40 +5213,6 @@ class StaticWarningCode extends AnalyzerErrorCode {
uniqueName: 'INVALID_NULL_AWARE_OPERATOR_AFTER_SHORT_CIRCUIT',
);
/// 7.1 Instance Methods: It is a static warning if an instance method
/// <i>m1</i> overrides an instance member <i>m2</i>, the signature of
/// <i>m2</i> explicitly specifies a default value for a formal parameter
/// <i>p</i> and the signature of <i>m1</i> specifies a different default value
/// for <i>p</i>.
///
/// Parameters:
/// 0: the name of the super class
/// 1: the name of the super method
/// 2: the name of the overriding method
static const StaticWarningCode
INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED = StaticWarningCode(
'INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED',
"Parameters can't override default values, this method overrides '{0}.{1}' "
"where '{2}' has a different value.",
correctionMessage: "Try using the same default value in both methods.",
);
/// 7.1 Instance Methods: It is a static warning if an instance method
/// <i>m1</i> overrides an instance member <i>m2</i>, the signature of
/// <i>m2</i> explicitly specifies a default value for a formal parameter
/// <i>p</i> and the signature of <i>m1</i> specifies a different default value
/// for <i>p</i>.
/// Parameters:
/// 0: the name of the super class
/// 1: the name of the super method
static const StaticWarningCode
INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL = StaticWarningCode(
'INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL',
"Parameters can't override default values, this method overrides '{0}.{1}' "
"where this positional parameter has a different value.",
correctionMessage: "Try using the same default value in both methods.",
);
/// Parameters:
/// 0: the name of the constant that is missing
static const StaticWarningCode MISSING_ENUM_CONSTANT_IN_SWITCH =

View file

@ -6,7 +6,6 @@ import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/syntactic_entity.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/constant/value.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/type_provider.dart';
@ -355,17 +354,6 @@ class _ClassVerifier {
errorReporter: reporter,
errorNode: node,
);
if (!_isNonNullableByDefault &&
superMember is MethodElement &&
member is MethodElement &&
methodParameterNodes != null) {
_checkForOptionalParametersDifferentDefaultValues(
superMember,
member,
methodParameterNodes,
);
}
}
if (mixinIndex == -1) {
@ -504,98 +492,6 @@ class _ClassVerifier {
return true;
}
void _checkForOptionalParametersDifferentDefaultValues(
MethodElement baseExecutable,
MethodElement derivedExecutable,
List<FormalParameter> derivedParameterNodes,
) {
var derivedIsAbstract = derivedExecutable.isAbstract;
var derivedOptionalNodes = <FormalParameter>[];
var derivedOptionalElements = <ParameterElementImpl>[];
var derivedParameterElements = derivedExecutable.parameters;
for (var i = 0; i < derivedParameterElements.length; i++) {
var parameterElement =
derivedParameterElements[i] as ParameterElementImpl;
if (parameterElement.isOptional) {
derivedOptionalNodes.add(derivedParameterNodes[i]);
derivedOptionalElements.add(parameterElement);
}
}
var baseOptionalElements = <ParameterElementImpl>[];
var baseParameterElements = baseExecutable.parameters;
for (var i = 0; i < baseParameterElements.length; ++i) {
var baseParameter = baseParameterElements[i];
if (baseParameter.isOptional) {
baseOptionalElements
.add(baseParameter.declaration as ParameterElementImpl);
}
}
// Stop if no optional parameters.
if (baseOptionalElements.isEmpty || derivedOptionalElements.isEmpty) {
return;
}
if (derivedOptionalElements[0].isNamed) {
for (int i = 0; i < derivedOptionalElements.length; i++) {
var derivedElement = derivedOptionalElements[i];
if (_isNonNullableByDefault &&
derivedIsAbstract &&
!derivedElement.hasDefaultValue) {
continue;
}
var name = derivedElement.name;
for (var j = 0; j < baseOptionalElements.length; j++) {
var baseParameter = baseOptionalElements[j];
if (name == baseParameter.name && baseParameter.hasDefaultValue) {
var baseValue = baseParameter.computeConstantValue();
var derivedResult = derivedElement.evaluationResult!;
if (!_constantValuesEqual(derivedResult.value, baseValue)) {
reporter.reportErrorForNode(
StaticWarningCode
.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED,
derivedOptionalNodes[i],
[
baseExecutable.enclosingElement.displayName,
baseExecutable.displayName,
name
],
);
}
}
}
}
} else {
for (var i = 0;
i < derivedOptionalElements.length && i < baseOptionalElements.length;
i++) {
var derivedElement = derivedOptionalElements[i];
if (_isNonNullableByDefault &&
derivedIsAbstract &&
!derivedElement.hasDefaultValue) {
continue;
}
var baseElement = baseOptionalElements[i];
if (baseElement.hasDefaultValue) {
var baseValue = baseElement.computeConstantValue();
var derivedResult = derivedElement.evaluationResult!;
if (!_constantValuesEqual(derivedResult.value, baseValue)) {
reporter.reportErrorForNode(
StaticWarningCode
.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL,
derivedOptionalNodes[i],
[
baseExecutable.enclosingElement.displayName,
baseExecutable.displayName
],
);
}
}
}
}
}
/// Check that [classElement] is not a superinterface to itself.
/// The [path] is a list containing the potentially cyclic implements path.
///
@ -1030,12 +926,4 @@ class _ClassVerifier {
);
}
}
static bool _constantValuesEqual(DartObject? x, DartObject? y) {
// If either constant value couldn't be computed due to an error, the
// corresponding DartObject will be `null`. Since an error has already been
// reported, there's no need to report another.
if (x == null || y == null) return true;
return x == y;
}
}

View file

@ -22816,32 +22816,6 @@ StaticWarningCode:
Parameters:
0: the null-aware operator that is invalid
1: the non-null-aware operator that can replace the invalid operator
INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED:
problemMessage: "Parameters can't override default values, this method overrides '{0}.{1}' where '{2}' has a different value."
correctionMessage: Try using the same default value in both methods.
comment: |-
7.1 Instance Methods: It is a static warning if an instance method
<i>m1</i> overrides an instance member <i>m2</i>, the signature of
<i>m2</i> explicitly specifies a default value for a formal parameter
<i>p</i> and the signature of <i>m1</i> specifies a different default value
for <i>p</i>.
Parameters:
0: the name of the super class
1: the name of the super method
2: the name of the overriding method
INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL:
problemMessage: "Parameters can't override default values, this method overrides '{0}.{1}' where this positional parameter has a different value."
correctionMessage: Try using the same default value in both methods.
comment: |-
7.1 Instance Methods: It is a static warning if an instance method
<i>m1</i> overrides an instance member <i>m2</i>, the signature of
<i>m2</i> explicitly specifies a default value for a formal parameter
<i>p</i> and the signature of <i>m1</i> specifies a different default value
for <i>p</i>.
Parameters:
0: the name of the super class
1: the name of the super method
MISSING_ENUM_CONSTANT_IN_SWITCH:
problemMessage: "Missing case clause for '{0}'."
correctionMessage: Try adding a case clause for the missing constant, or adding a default clause.

View file

@ -1,346 +0,0 @@
// Copyright (c) 2019, 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/error/codes.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(InvalidOverrideDifferentDefaultValuesNamedTest);
defineReflectiveTests(
InvalidOverrideDifferentDefaultValuesNamedWithoutNullSafetyTest,
);
});
}
@reflectiveTest
class InvalidOverrideDifferentDefaultValuesNamedTest
extends InvalidOverrideDifferentDefaultValuesNamedWithoutNullSafetyTest {
test_concrete_equal_optIn_extends_optOut() async {
newFile('$testPackageLibPath/a.dart', r'''
// @dart = 2.7
class A {
void foo({int a = 0}) {}
}
''');
await assertErrorsInCode(r'''
import 'a.dart';
class B extends A {
void foo({int a = 0}) {}
}
''', [
error(HintCode.IMPORT_OF_LEGACY_LIBRARY_INTO_NULL_SAFE, 7, 8),
]);
}
test_concrete_equal_optOut_extends_optIn() async {
newFile('$testPackageLibPath/a.dart', r'''
class A {
void foo({int a = 0}) {}
}
''');
await assertNoErrorsInCode(r'''
// @dart = 2.7
import 'a.dart';
class B extends A {
void foo({int a = 0}) {}
}
''');
}
}
@reflectiveTest
class InvalidOverrideDifferentDefaultValuesNamedWithoutNullSafetyTest
extends PubPackageResolutionTest {
test_abstract_different_base_value() async {
await assertErrorsInCode(
r'''
abstract class A {
void foo({x = 0}) {}
}
abstract class B extends A {
void foo({x = 1});
}
''',
expectedErrorsByNullability(nullable: [], legacy: [
error(StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED,
86, 5),
]),
);
}
test_abstract_noDefault_base_noDefault() async {
await assertNoErrorsInCode(r'''
abstract class A {
void foo({x});
}
abstract class B extends A {
void foo({x});
}
''');
}
test_abstract_noDefault_base_value() async {
await assertErrorsInCode(
r'''
abstract class A {
void foo({x = 0}) {}
}
abstract class B extends A {
void foo({x});
}
''',
expectedErrorsByNullability(nullable: [], legacy: [
error(
StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED,
86,
1),
]));
}
test_abstract_noDefault_multipleBase_differentValue() async {
await assertErrorsInCode(
r'''
abstract class A {
void foo({x = 0}) {}
}
abstract class B {
void foo({x = 1});
}
abstract class C extends A implements B {
void foo({x});
}
''',
expectedErrorsByNullability(nullable: [], legacy: [
error(
StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED,
142,
1),
error(
StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED,
142,
1),
]));
}
test_abstract_noDefault_multipleBase_sameValue() async {
await assertErrorsInCode(
r'''
abstract class A {
void foo({x = 0});
}
abstract class B {
void foo({x = 0});
}
abstract class C extends A implements B {
void foo({x});
}
''',
expectedErrorsByNullability(nullable: [], legacy: [
error(
StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED,
140,
1),
error(
StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED,
140,
1),
]));
}
test_abstract_value_base_noDefault() async {
await assertNoErrorsInCode(r'''
abstract class A {
void foo({x});
}
abstract class B extends A {
void foo({x = 0});
}
''');
}
test_concrete_different() async {
await assertErrorsInCode(
r'''
class A {
void foo({x = 0}) {}
}
class B extends A {
void foo({x = 1}) {}
}''',
expectedErrorsByNullability(nullable: [], legacy: [
error(StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED,
67, 5),
]),
);
}
test_concrete_equal() async {
await assertNoErrorsInCode(r'''
abstract class A {
void foo({x = 1});
}
class C extends A {
void foo({x = 3 - 2}) {}
}
''');
}
test_concrete_equal_function() async {
await assertNoErrorsInCode(r'''
nothing() => 'nothing';
class A {
void foo(String a, {orElse = nothing}) {}
}
class B extends A {
void foo(String a, {orElse = nothing}) {}
}
''');
}
test_concrete_equal_otherLibrary() async {
newFile('$testPackageLibPath/a.dart', r'''
class A {
void foo([a = 0]) {}
}
''');
await assertNoErrorsInCode(r'''
import 'a.dart';
class C extends A {
void foo([a = 0]) {}
}
''');
}
test_concrete_equal_otherLibrary_listLiteral() async {
newFile('$testPackageLibPath/other.dart', '''
class C {
void foo({x: const ['x']}) {}
}
''');
await assertNoErrorsInCode('''
import 'other.dart';
class D extends C {
void foo({x: const ['x']}) {}
}
''');
}
test_concrete_explicitNull_overriddenWith_implicitNull() async {
// If the base class provided an explicit null value for a default
// parameter, then it is ok for the derived class to let the default value
// be implicit, because the implicit default value of null matches the
// explicit default value of null.
await assertNoErrorsInCode(r'''
class A {
void foo({x: null}) {}
}
class B extends A {
void foo({x}) {}
}
''');
}
test_concrete_implicitNull_overriddenWith_value() async {
// If the base class lets the default parameter be implicit, then it is ok
// for the derived class to provide an explicit default value, even if it's
// not null.
await assertNoErrorsInCode(r'''
class A {
void foo({x}) {}
}
class B extends A {
void foo({x = 1}) {}
}
''');
}
test_concrete_undefined_base() async {
// Note: we expect some errors due to the constant referring to undefined
// values, but there should not be any INVALID_OVERRIDE... error.
await assertErrorsInCode('''
class A {
void foo({x = Undefined.value}) {}
}
class B extends A {
void foo({x = 1}) {}
}
''', [
error(CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE, 26, 9),
error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 26, 9),
]);
}
test_concrete_undefined_both() async {
// Note: we expect some errors due to the constant referring to undefined
// values, but there should not be any INVALID_OVERRIDE... error.
await assertErrorsInCode('''
class A {
void foo({x = Undefined.value}) {}
}
class B extends A {
void foo({x = Undefined2.value2}) {}
}
''', [
error(CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE, 26, 9),
error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 26, 9),
error(CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE, 85, 10),
error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 85, 10),
]);
}
test_concrete_undefined_derived() async {
// Note: we expect some errors due to the constant referring to undefined
// values, but there should not be any INVALID_OVERRIDE... error.
await assertErrorsInCode('''
class A {
void foo({x = 1}) {}
}
class B extends A {
void foo({x = Undefined.value}) {}
}
''', [
error(CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE, 71, 9),
error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 71, 9),
]);
}
test_concrete_value_overriddenWith_implicitNull() async {
// If the base class provided an explicit value for a default parameter,
// then it is a static warning for the derived class to provide a different
// value, even if implicitly.
await assertErrorsInCode(
r'''
class A {
void foo({x: 1}) {}
}
class B extends A {
void foo({x}) {}
}
''',
expectedErrorsByNullability(nullable: [], legacy: [
error(StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED,
66, 1),
]),
);
}
}

View file

@ -1,363 +0,0 @@
// Copyright (c) 2019, 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/error/codes.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(
InvalidOverrideDifferentDefaultValuesPositionalTest,
);
defineReflectiveTests(
InvalidOverrideDifferentDefaultValuesPositionalWithoutNullSafetyTest,
);
});
}
@reflectiveTest
class InvalidOverrideDifferentDefaultValuesPositionalTest
extends InvalidOverrideDifferentDefaultValuesPositionalWithoutNullSafetyTest {
test_concrete_equal_optIn_extends_optOut() async {
newFile('$testPackageLibPath/a.dart', r'''
// @dart = 2.7
class A {
void foo([int a = 0]) {}
}
''');
await assertErrorsInCode(r'''
import 'a.dart';
class B extends A {
void foo([int a = 0]) {}
}
''', [
error(HintCode.IMPORT_OF_LEGACY_LIBRARY_INTO_NULL_SAFE, 7, 8),
]);
}
test_concrete_equal_optOut_extends_optIn() async {
newFile('$testPackageLibPath/a.dart', r'''
class A {
void foo([int a = 0]) {}
}
''');
await assertNoErrorsInCode(r'''
// @dart = 2.7
import 'a.dart';
class B extends A {
void foo([int a = 0]) {}
}
''');
}
}
@reflectiveTest
class InvalidOverrideDifferentDefaultValuesPositionalWithoutNullSafetyTest
extends PubPackageResolutionTest {
test_abstract_different_base_value() async {
await assertErrorsInCode(
r'''
abstract class A {
void foo([x = 0]) {}
}
abstract class B extends A {
void foo([x = 1]);
}
''',
expectedErrorsByNullability(nullable: [], legacy: [
error(
StaticWarningCode
.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL,
86,
5),
]),
);
}
test_abstract_noDefault_base_noDefault() async {
await assertNoErrorsInCode(r'''
abstract class A {
void foo([x]);
}
abstract class B extends A {
void foo([x]);
}
''');
}
test_abstract_noDefault_base_value() async {
await assertErrorsInCode(
r'''
abstract class A {
void foo([x = 0]) {}
}
abstract class B extends A {
void foo([x]);
}
''',
expectedErrorsByNullability(nullable: [], legacy: [
error(
StaticWarningCode
.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL,
86,
1),
]));
}
test_abstract_noDefault_multipleBase_differentValue() async {
await assertErrorsInCode(
r'''
abstract class A {
void foo([x = 0]) {}
}
abstract class B {
void foo([x = 1]);
}
abstract class C extends A implements B {
void foo([x]);
}
''',
expectedErrorsByNullability(nullable: [], legacy: [
error(
StaticWarningCode
.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL,
142,
1),
error(
StaticWarningCode
.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL,
142,
1),
]));
}
test_abstract_noDefault_multipleBase_sameValue() async {
await assertErrorsInCode(
r'''
abstract class A {
void foo([x = 0]);
}
abstract class B {
void foo([x = 0]);
}
abstract class C extends A implements B {
void foo([x]);
}
''',
expectedErrorsByNullability(nullable: [], legacy: [
error(
StaticWarningCode
.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL,
140,
1),
error(
StaticWarningCode
.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL,
140,
1),
]));
}
test_abstract_value_base_noDefault() async {
await assertNoErrorsInCode(r'''
abstract class A {
void foo([x]);
}
abstract class B extends A {
void foo([x = 0]);
}
''');
}
test_concrete_different() async {
await assertErrorsInCode(
r'''
class A {
void foo([x = 0]) {}
}
class B extends A {
void foo([x = 1]) {}
}
''',
expectedErrorsByNullability(nullable: [], legacy: [
error(
StaticWarningCode
.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL,
67,
5),
]),
);
}
test_concrete_equal() async {
await assertNoErrorsInCode(r'''
abstract class A {
void foo([x = 1]);
}
class C extends A {
void foo([x = 3 - 2]) {}
}
''');
}
test_concrete_equal_function() async {
await assertNoErrorsInCode(r'''
nothing() => 'nothing';
class A {
void foo(String a, [orElse = nothing]) {}
}
class B extends A {
void foo(String a, [orElse = nothing]) {}
}
''');
}
test_concrete_equal_otherLibrary() async {
newFile('$testPackageLibPath/a.dart', r'''
class A {
void foo([x = 0]) {}
}
''');
await assertNoErrorsInCode(r'''
import 'a.dart';
class C extends A {
void foo([a = 0]) {}
}
''');
}
test_concrete_equal_otherLibrary_listLiteral() async {
newFile('$testPackageLibPath/other.dart', '''
class C {
void foo([x = const ['x']]) {}
}
''');
await assertNoErrorsInCode('''
import 'other.dart';
class D extends C {
void foo([x = const ['x']]) {}
}
''');
}
test_concrete_explicitNull_overriddenWith_implicitNull() async {
// If the base class provided an explicit null value for a default
// parameter, then it is ok for the derived class to let the default value
// be implicit, because the implicit default value of null matches the
// explicit default value of null.
await assertNoErrorsInCode(r'''
class A {
void foo([x = null]) {}
}
class B extends A {
void foo([x]) {}
}
''');
}
test_concrete_implicitNull_overriddenWith_value() async {
// If the base class lets the default parameter be implicit, then it is ok
// for the derived class to provide an explicit default value, even if it's
// not null.
await assertNoErrorsInCode(r'''
class A {
void foo([x]) {}
}
class B extends A {
void foo([x = 1]) {}
}
''');
}
test_concrete_undefined_base() async {
// Note: we expect some errors due to the constant referring to undefined
// values, but there should not be any INVALID_OVERRIDE... error.
await assertErrorsInCode('''
class A {
void foo([x = Undefined.value]) {}
}
class B extends A {
void foo([x = 1]) {}
}
''', [
error(CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE, 26, 9),
error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 26, 9),
]);
}
test_concrete_undefined_both() async {
// Note: we expect some errors due to the constant referring to undefined
// values, but there should not be any INVALID_OVERRIDE... error.
await assertErrorsInCode('''
class A {
void foo([x = Undefined.value]) {}
}
class B extends A {
void foo([x = Undefined2.value2]) {}
}
''', [
error(CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE, 26, 9),
error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 26, 9),
error(CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE, 85, 10),
error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 85, 10),
]);
}
test_concrete_undefined_derived() async {
// Note: we expect some errors due to the constant referring to undefined
// values, but there should not be any INVALID_OVERRIDE... error.
await assertErrorsInCode('''
class A {
void foo([x = 1]) {}
}
class B extends A {
void foo([x = Undefined.value]) {}
}
''', [
error(CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE, 71, 9),
error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 71, 9),
]);
}
test_concrete_value_overriddenWith_implicitNull() async {
// If the base class provided an explicit value for a default parameter,
// then it is a static warning for the derived class to provide a different
// value, even if implicitly.
await assertErrorsInCode(
r'''
class A {
void foo([x = 1]) {}
}
class B extends A {
void foo([x]) {}
}
''',
expectedErrorsByNullability(nullable: [], legacy: [
error(
StaticWarningCode
.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL,
67,
1),
]),
);
}
}

View file

@ -369,10 +369,6 @@ import 'invalid_modifier_on_setter_test.dart' as invalid_modifier_on_setter;
import 'invalid_non_virtual_annotation_test.dart'
as invalid_non_virtual_annotation;
import 'invalid_null_aware_operator_test.dart' as invalid_null_aware_operator;
import 'invalid_override_different_default_values_named_test.dart'
as invalid_override_different_default_values_named;
import 'invalid_override_different_default_values_positional_test.dart'
as invalid_override_different_default_values_positional;
import 'invalid_override_of_non_virtual_member_test.dart'
as invalid_override_of_non_virtual_member;
import 'invalid_override_test.dart' as invalid_override;
@ -1050,8 +1046,6 @@ main() {
invalid_modifier_on_setter.main();
invalid_non_virtual_annotation.main();
invalid_null_aware_operator.main();
invalid_override_different_default_values_named.main();
invalid_override_different_default_values_positional.main();
invalid_override_of_non_virtual_member.main();
invalid_override.main();
invalid_reference_to_generative_enum_constructor.main();

View file

@ -75,7 +75,7 @@ class B extends A {
fooIntercept28() => confuse(super.lastWhere)(3, orElse: 77);
// Warning: overrides should not change default parameter values.
bar([var optional]) => -1; // //# 01: static type warning
bar([var optional]) => -1; // //# 01: ok
bar2({namedOptional}) => -1; // //# 01: continued
bar3(x, [var optional]) => -1; // //# 01: continued
bar4(x, {namedOptional}) => -1; //# 01: continued