Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 59600f2

Browse files
MichaelRFairhurstcommit-bot@chromium.org
authored andcommitted
[analyzer] Improve existing non-generative constructor errors
As opposed to the parent CL which creates a new error for cases where no non-generative constructor is available at all, these improvements include a bugfix to the previous error message. The previous message was incorrect in saying 'expected {0} but factory found', because the argument passed to '{0}' was the factory constructor that was found, rather than any kind of expected constructor signature. Fixed. Also, for implicit constructors, break out the error message to deliberately explicitly describe that this affects the implicit constructor. I considered making an error code for implicit super initializers as well, (ie `class Foo extends Bar { Foo(); }`), but don't think it is necessary/common/etc. Change-Id: I0643ad00abbfb2848cbd2f8f1f83e7c33d4fb846 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/155831 Commit-Queue: Mike Fairhurst <mfairhurst@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
1 parent e0164ec commit 59600f2

File tree

6 files changed

+64
-18
lines changed

6 files changed

+64
-18
lines changed

pkg/analyzer/lib/error/error.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,7 @@ const List<ErrorCode> errorCodeValues = [
318318
CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY,
319319
CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT,
320320
CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR,
321+
CompileTimeErrorCode.NON_GENERATIVE_IMPLICIT_CONSTRUCTOR,
321322
CompileTimeErrorCode.NON_SYNC_FACTORY,
322323
CompileTimeErrorCode.NON_TYPE_AS_TYPE_ARGUMENT,
323324
CompileTimeErrorCode.NON_TYPE_IN_CATCH_CLAUSE,

pkg/analyzer/lib/src/error/codes.dart

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6651,14 +6651,39 @@ class CompileTimeErrorCode extends AnalyzerErrorCode {
66516651
* Let <i>k</i> be a generative constructor. It is a compile-time error if
66526652
* class <i>S</i> does not declare a generative constructor named <i>S</i>
66536653
* (respectively <i>S.id</i>)
6654+
*
6655+
* Parameters:
6656+
* 0: the non-generative constructor
66546657
*/
66556658
static const CompileTimeErrorCode NON_GENERATIVE_CONSTRUCTOR =
6656-
CompileTimeErrorCode('NON_GENERATIVE_CONSTRUCTOR',
6657-
"The generative constructor '{0}' expected, but factory found.",
6659+
CompileTimeErrorCode(
6660+
'NON_GENERATIVE_CONSTRUCTOR',
6661+
"The constructor '{0}' is a factory constructor, but must be a"
6662+
" generative constructor to be a valid superinitializer.",
66586663
correction:
6659-
"Try calling a different constructor in the superclass, or "
6664+
"Try calling a different constructor of the superclass, or "
66606665
"making the called constructor not be a factory constructor.");
66616666

6667+
/**
6668+
* An error code for when a class has no explicit constructor, and therefore
6669+
* a constructor is implicitly defined which uses a factory as a
6670+
* superinitializer. See [NON_GENERATIVE_CONSTRUCTOR].
6671+
*
6672+
* Parameters:
6673+
* 0: the name of the superclass
6674+
* 1: the name of the current class
6675+
* 2: the implicitly called factory constructor of the superclass
6676+
*/
6677+
static const CompileTimeErrorCode NON_GENERATIVE_IMPLICIT_CONSTRUCTOR =
6678+
CompileTimeErrorCode(
6679+
'NON_GENERATIVE_IMPLICIT_CONSTRUCTOR',
6680+
"The default constructor of superclass '{0}' (called by the implicit"
6681+
" default constructor of '{1}') must be a generative constructor,"
6682+
" but factory found.",
6683+
correction: 'Try adding an explicit constructor that has a different'
6684+
" superinitializer or changing the superclass constructor '{2}'"
6685+
" to not be a factory constructor.");
6686+
66626687
static const CompileTimeErrorCode NON_SYNC_FACTORY = CompileTimeErrorCode(
66636688
'NON_SYNC_FACTORY',
66646689
"Factory bodies can't use 'async', 'async*', or 'sync*'.");

pkg/analyzer/lib/src/generated/error_verifier.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3404,9 +3404,9 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {
34043404
if (superUnnamedConstructor != null) {
34053405
if (superUnnamedConstructor.isFactory) {
34063406
_errorReporter.reportErrorForNode(
3407-
CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR,
3407+
CompileTimeErrorCode.NON_GENERATIVE_IMPLICIT_CONSTRUCTOR,
34083408
declaration.name,
3409-
[superUnnamedConstructor]);
3409+
[superElement.name, _enclosingClass.name, superUnnamedConstructor]);
34103410
return;
34113411
}
34123412
if (superUnnamedConstructor.isDefaultConstructor) {

pkg/analyzer/test/src/diagnostics/non_generative_constructor_test.dart

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -66,17 +66,4 @@ class B extends A {
6666
error(CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, 73, 1),
6767
]);
6868
}
69-
70-
test_implicit2() async {
71-
await assertErrorsInCode(r'''
72-
class A {
73-
factory A() => throw 0;
74-
A.named();
75-
}
76-
class B extends A {
77-
}
78-
''', [
79-
error(CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, 57, 1),
80-
]);
81-
}
8269
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'package:analyzer/src/error/codes.dart';
6+
import 'package:test_reflective_loader/test_reflective_loader.dart';
7+
8+
import '../dart/resolution/driver_resolution.dart';
9+
10+
main() {
11+
defineReflectiveSuite(() {
12+
defineReflectiveTests(NonGenerativeImplicitConstructorTest);
13+
});
14+
}
15+
16+
@reflectiveTest
17+
class NonGenerativeImplicitConstructorTest extends DriverResolutionTest {
18+
test_implicit() async {
19+
await assertErrorsInCode(r'''
20+
class A {
21+
factory A() => throw 0;
22+
A.named();
23+
}
24+
class B extends A {
25+
}
26+
''', [
27+
error(CompileTimeErrorCode.NON_GENERATIVE_IMPLICIT_CONSTRUCTOR, 57, 1),
28+
]);
29+
}
30+
}

pkg/analyzer/test/src/diagnostics/test_all.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,8 @@ import 'non_constant_map_value_test.dart' as non_constant_map_value;
413413
import 'non_constant_set_element_test.dart' as non_constant_set_element;
414414
import 'non_constant_type_argument_test.dart' as non_constant_type_argument;
415415
import 'non_generative_constructor_test.dart' as non_generative_constructor;
416+
import 'non_generative_implicit_constructor_test.dart'
417+
as non_generative_implicit_constructor;
416418
import 'non_native_function_type_argument_to_pointer_test.dart'
417419
as non_native_function_type_argument_to_pointer;
418420
import 'non_null_opt_out_test.dart' as non_null_opt_out;
@@ -895,6 +897,7 @@ main() {
895897
non_constant_set_element.main();
896898
non_constant_type_argument.main();
897899
non_generative_constructor.main();
900+
non_generative_implicit_constructor.main();
898901
non_native_function_type_argument_to_pointer.main();
899902
non_null_opt_out.main();
900903
non_type_as_type_argument.main();

0 commit comments

Comments
 (0)