It is OK to declare a const constructor in a class with a mixin, if it has no fields.

R=brianwilkerson@google.com

Change-Id: I76c427fe24b8f06711c3adcac8bacd45900240b1
Reviewed-on: https://dart-review.googlesource.com/62482
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
Konstantin Shcheglov
2018-06-27 14:23:59 +00:00
committed by commit-bot@chromium.org
parent 88a88b03dc
commit 46167dfd88
10 changed files with 184 additions and 156 deletions
+1 -1
View File
@@ -81,7 +81,7 @@ const List<ErrorCode> errorCodeValues = const [
CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER,
CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION,
CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST,
CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN,
CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD,
CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER,
CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD,
CompileTimeErrorCode.CONST_DEFERRED_CLASS,
@@ -95,7 +95,7 @@ class AnalysisDriver implements AnalysisDriverGeneric {
/**
* The version of data format, should be incremented on every format change.
*/
static const int DATA_VERSION = 61;
static const int DATA_VERSION = 62;
/**
* The number of exception contexts allowed to write. Once this field is
+12 -7
View File
@@ -484,14 +484,19 @@ class CompileTimeErrorCode extends ErrorCode {
* specify a constant constructor of the superclass of the immediately
* enclosing class or a compile-time error occurs.
*
* 9 Mixins: For each generative constructor named ... an implicitly declared
* constructor named ... is declared.
* 12.1 Mixin Application: For each generative constructor named ... an
* implicitly declared constructor named ... is declared. If Sq is a
* generative const constructor, and M does not declare any fields, Cq is
* also a const constructor.
*/
static const CompileTimeErrorCode CONST_CONSTRUCTOR_WITH_MIXIN =
const CompileTimeErrorCode('CONST_CONSTRUCTOR_WITH_MIXIN',
"Const constructor can't be declared for a class with a mixin.",
correction: "Try removing the 'const' keyword, or "
"removing the 'with' clause from the class declaration.");
static const CompileTimeErrorCode CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD =
const CompileTimeErrorCode(
'CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD',
"Const constructor can't be declared for a class with a mixin "
"that declares a field.",
correction: "Try removing the 'const' keyword or "
"removing the 'with' clause from the class declaration, "
"or removing fields from the mixin class.");
/**
* 7.6.3 Constant Constructors: The superinitializer that appears, explicitly
@@ -3242,11 +3242,13 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
return;
}
// check for mixins
if (_enclosingClass.mixins.length != 0) {
_errorReporter.reportErrorForNode(
CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN,
constructor.returnType);
return;
for (var mixin in _enclosingClass.mixins) {
if (mixin.element.fields.isNotEmpty) {
_errorReporter.reportErrorForNode(
CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD,
constructor.returnType);
return;
}
}
// try to find and check super constructor invocation
for (ConstructorInitializer initializer in constructor.initializers) {
@@ -240,9 +240,16 @@ class CompileTimeErrorCodeTest_Kernel extends CompileTimeErrorCodeTest_Driver {
@override
@failingTest
test_constConstructorWithMixin() async {
// Expected 1 errors of type CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN, found 0
await super.test_constConstructorWithMixin();
@FastaProblem('https://github.com/dart-lang/sdk/issues/33645')
test_constConstructorWithMixinWithField() async {
return super.test_constConstructorWithMixinWithField();
}
@override
@failingTest
@FastaProblem('https://github.com/dart-lang/sdk/issues/33645')
test_constConstructorWithMixinWithField_final() async {
return super.test_constConstructorWithMixinWithField_final();
}
@override
@@ -1026,15 +1026,33 @@ int f() {
verify([source]);
}
test_constConstructorWithMixin() async {
test_constConstructorWithMixinWithField() async {
Source source = addSource(r'''
class M {
class A {
var a;
}
class A extends Object with M {
const A();
class B extends Object with A {
const B();
}''');
await computeAnalysisResult(source);
assertErrors(source, [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN]);
assertErrors(source, [
CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD,
CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD
]);
verify([source]);
}
test_constConstructorWithMixinWithField_final() async {
Source source = addSource(r'''
class A {
final int a = 0;
}
class B extends Object with A {
const B();
}''');
await computeAnalysisResult(source);
assertErrors(
source, [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD]);
verify([source]);
}
@@ -1076,7 +1094,7 @@ class B extends Object with A {
}''');
await computeAnalysisResult(source);
assertErrors(source, [
CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN,
CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD,
CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD
]);
verify([source]);
@@ -1617,6 +1635,27 @@ f() { return const T(0, 1, c: 2, d: 3); }''');
verify([source]);
}
test_constWithNonConst_in_const_context() async {
Source source = addSource(r'''
class A {
const A(x);
}
class B {
}
main() {
const A(B());
}
''');
await computeAnalysisResult(source);
// TODO(a14n): the error CONST_WITH_NON_CONSTANT_ARGUMENT is redundant and
// ought to be suppressed.
assertErrors(source, [
CompileTimeErrorCode.CONST_WITH_NON_CONST,
CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT
]);
verify([source]);
}
test_constWithNonConst_with() async {
Source source = addSource(r'''
class B {
@@ -1639,27 +1678,6 @@ main() {
verify([source]);
}
test_constWithNonConst_in_const_context() async {
Source source = addSource(r'''
class A {
const A(x);
}
class B {
}
main() {
const A(B());
}
''');
await computeAnalysisResult(source);
// TODO(a14n): the error CONST_WITH_NON_CONSTANT_ARGUMENT is redundant and
// ought to be suppressed.
assertErrors(source, [
CompileTimeErrorCode.CONST_WITH_NON_CONST,
CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT
]);
verify([source]);
}
test_constWithNonConstantArgument_annotation() async {
Source source = addSource(r'''
class A {
@@ -2749,6 +2767,98 @@ var b2 = const bool.fromEnvironment('x', defaultValue: 1);''');
verify([source]);
}
test_genericFunctionTypeArgument_class() async {
Source source = addSource(r'''
class C<T> {}
C<T Function<T>(T)> c;''');
await computeAnalysisResult(source);
assertErrors(source,
[CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT]);
verify([source]);
}
test_genericFunctionTypeArgument_function() async {
Source source = addSource(r'''
T f<T>(T) => null;
main() { f<S Function<S>(S)>(null); }''');
await computeAnalysisResult(source);
assertErrors(source,
[CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT]);
verify([source]);
}
test_genericFunctionTypeArgument_functionType() async {
Source source = addSource(r'''
T Function<T>(T) f;
main() { f<S Function<S>(S)>(null); }''');
await computeAnalysisResult(source);
assertErrors(source,
[CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT]);
verify([source]);
}
@failingTest
test_genericFunctionTypeArgument_inference_function() async {
// TODO(mfairhurst) how should these inference errors be reported?
Source source = addSource(r'''
T f<T>(T) => null;
main() { f(<S>(S s) => s); }''');
await computeAnalysisResult(source);
assertErrors(source,
[CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT]);
verify([source]);
}
@failingTest
test_genericFunctionTypeArgument_inference_functionType() async {
// TODO(mfairhurst) how should these inference errors be reported?
Source source = addSource(r'''
T Function<T>(T) f;
main() { f(<S>(S s) => s); }''');
await computeAnalysisResult(source);
assertErrors(source,
[CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT]);
verify([source]);
}
@failingTest
test_genericFunctionTypeArgument_inference_method() async {
// TODO(mfairhurst) how should these inference errors be reported?
Source source = addSource(r'''
class C {
T f<T>(T) => null;
}
main() { new C().f(<S>(S s) => s); }''');
await computeAnalysisResult(source);
assertErrors(source,
[CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT]);
verify([source]);
}
test_genericFunctionTypeArgument_method() async {
Source source = addSource(r'''
class C {
T f<T>(T) => null;
}
main() { new C().f<S Function<S>(S)>(null); }''');
await computeAnalysisResult(source);
assertErrors(source,
[CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT]);
verify([source]);
}
@failingTest
test_genericFunctionTypeArgument_typedef() async {
// TODO(mfairhurst) diagnose these parse errors to give the correct error
Source source = addSource(r'''
typedef T f<T>(T t);
final T<Function<S>(int)> x = null;''');
await computeAnalysisResult(source);
assertErrors(source,
[CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT]);
verify([source]);
}
test_genericFunctionTypeAsBound_class() async {
Source source = addSource(r'''
class C<T extends S Function<S>(S)> {
@@ -7063,98 +7173,6 @@ f() { return const G<B>(); }''');
verify([source]);
}
test_genericFunctionTypeArgument_class() async {
Source source = addSource(r'''
class C<T> {}
C<T Function<T>(T)> c;''');
await computeAnalysisResult(source);
assertErrors(source,
[CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT]);
verify([source]);
}
test_genericFunctionTypeArgument_functionType() async {
Source source = addSource(r'''
T Function<T>(T) f;
main() { f<S Function<S>(S)>(null); }''');
await computeAnalysisResult(source);
assertErrors(source,
[CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT]);
verify([source]);
}
test_genericFunctionTypeArgument_function() async {
Source source = addSource(r'''
T f<T>(T) => null;
main() { f<S Function<S>(S)>(null); }''');
await computeAnalysisResult(source);
assertErrors(source,
[CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT]);
verify([source]);
}
test_genericFunctionTypeArgument_method() async {
Source source = addSource(r'''
class C {
T f<T>(T) => null;
}
main() { new C().f<S Function<S>(S)>(null); }''');
await computeAnalysisResult(source);
assertErrors(source,
[CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT]);
verify([source]);
}
@failingTest
test_genericFunctionTypeArgument_inference_functionType() async {
// TODO(mfairhurst) how should these inference errors be reported?
Source source = addSource(r'''
T Function<T>(T) f;
main() { f(<S>(S s) => s); }''');
await computeAnalysisResult(source);
assertErrors(source,
[CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT]);
verify([source]);
}
@failingTest
test_genericFunctionTypeArgument_inference_function() async {
// TODO(mfairhurst) how should these inference errors be reported?
Source source = addSource(r'''
T f<T>(T) => null;
main() { f(<S>(S s) => s); }''');
await computeAnalysisResult(source);
assertErrors(source,
[CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT]);
verify([source]);
}
@failingTest
test_genericFunctionTypeArgument_inference_method() async {
// TODO(mfairhurst) how should these inference errors be reported?
Source source = addSource(r'''
class C {
T f<T>(T) => null;
}
main() { new C().f(<S>(S s) => s); }''');
await computeAnalysisResult(source);
assertErrors(source,
[CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT]);
verify([source]);
}
@failingTest
test_genericFunctionTypeArgument_typedef() async {
// TODO(mfairhurst) diagnose these parse errors to give the correct error
Source source = addSource(r'''
typedef T f<T>(T t);
final T<Function<S>(int)> x = null;''');
await computeAnalysisResult(source);
assertErrors(source,
[CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT]);
verify([source]);
}
test_undefinedAnnotation_unresolved_identifier() async {
Source source = addSource(r'''
@unresolved
@@ -123,13 +123,6 @@ class NonErrorResolverTest_Kernel extends NonErrorResolverTest_Driver {
return super.test_constConstructorWithNonConstSuper_unresolved();
}
@override
@failingTest
@potentialAnalyzerProblem
test_constConstructorWithNonFinalField_mixin() async {
return super.test_constConstructorWithNonFinalField_mixin();
}
@override
@failingTest
@potentialAnalyzerProblem
@@ -1314,6 +1314,18 @@ const int value = 12345;
verify([source]);
}
test_constConstructorWithMixinWithField() async {
Source source = addSource(r'''
class M {
}
class A extends Object with M {
const A();
}''');
await computeAnalysisResult(source);
assertNoErrors(source);
verify([source]);
}
test_constConstructorWithNonConstSuper_explicit() async {
Source source = addSource(r'''
class A {
@@ -1368,19 +1380,6 @@ class A {
verify([source]);
}
test_constConstructorWithNonFinalField_mixin() async {
Source source = addSource(r'''
class A {
a() {}
}
class B extends Object with A {
const B();
}''');
await computeAnalysisResult(source);
assertErrors(source, [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN]);
verify([source]);
}
test_constConstructorWithNonFinalField_static() async {
Source source = addSource(r'''
class A {
@@ -14,6 +14,8 @@ config_import_corelib_test: StaticWarning, OK
conflicting_type_variable_and_setter_test: CompileTimeError # Issue 25525
const_cast2_test/01: CompileTimeError
const_cast2_test/none: CompileTimeError
const_constructor_mixin3_test/01: MissingCompileTimeError # Issue 33644
const_constructor_mixin_test/01: MissingCompileTimeError # Issue 33644
const_for_in_variable_test/01: MissingCompileTimeError # Issue 25161
constructor_call_wrong_argument_count_negative_test: Fail # Issue 11585
constructor_type_parameter_test/00: MissingCompileTimeError # Issue 33110
@@ -33,6 +33,8 @@ conflicting_generic_interfaces_simple_test: MissingCompileTimeError
conflicting_type_variable_and_setter_test: CompileTimeError
const_cast2_test/01: CompileTimeError
const_cast2_test/none: CompileTimeError
const_constructor_mixin3_test/01: MissingCompileTimeError # Issue 33644
const_constructor_mixin_test/01: MissingCompileTimeError # Issue 33644
const_for_in_variable_test/01: MissingCompileTimeError
const_types_test/07: MissingCompileTimeError
const_types_test/08: MissingCompileTimeError