Description
One of the concerns that some people have raised around primary constructors is that with longer parameter lists, it moves the extends and implements clauses a significant distance from the start of the class. For example:
class const PasswordField({
super.key,
final String? restorationId,
final Key? fieldKey,
final String? hintText,
final String? labelText,
final String? helperText,
final FormFieldSetter<String>? onSaved,
final FormFieldValidator<String>? validator,
final ValueChanged<String>? onFieldSubmitted,
final FocusNode? focusNode,
final TextInputAction? textInputAction,
}) extends StatefulWidget {
@override
State<PasswordField> createState() => _PasswordFieldState();
}
Here, the extends StatefulWidget
clause is pushed to the bottom where it is (at least in some people's eyes) hard to find.
One thing we could consider is allowing the primary constructor to be moved towards the end notably including the class name. The above would then become:
class extends StatefulWidget
const PasswordField({
super.key,
final String? restorationId,
final Key? fieldKey,
final String? hintText,
final String? labelText,
final String? helperText,
final FormFieldSetter<String>? onSaved,
final FormFieldValidator<String>? validator,
final ValueChanged<String>? onFieldSubmitted,
final FocusNode? focusNode,
final TextInputAction? textInputAction,
}) {
@override
State<PasswordField> createState() => _PasswordFieldState();
}
Possibly we require the constructor to be prefixed with either new
or const
to make parser recovery better.
For shorter classes with no members besides the fields (POD classes) we allow the class body to be elided as before.
class extends Point new Cartesian({int x, int y});
For generic classes, we allow the generic parameters to be placed on the class
keyword in the same way that we allow generic to be attached to the extension
keyword:
class<S, T> extends Pair<S, T> new ColorPair({S fst, T snd, Color color});
cc @dart-lang/language-team