Skip to content

Commit

Permalink
Here's a weird strawman idea. There are two changes:
Browse files Browse the repository at this point in the history
- A "this." parameter can implicitly introduce a new field if there
  isn't already a field with its name. If so, the field's type is the
  same as the parameter's.

- The constructor doesn't have to repeat the class name and can instead
  be just "const" or "new".
  • Loading branch information
munificent committed Aug 18, 2023
1 parent b460d15 commit aa86068
Show file tree
Hide file tree
Showing 40 changed files with 334 additions and 626 deletions.
27 changes: 9 additions & 18 deletions lib/codeviewer/code_style.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,19 @@
import 'package:flutter/material.dart';

class CodeStyle extends InheritedWidget {
const CodeStyle({
const ({
super.key,
this.baseStyle,
this.numberStyle,
this.commentStyle,
this.keywordStyle,
this.stringStyle,
this.punctuationStyle,
this.classStyle,
this.constantStyle,
final TextStyle? this.baseStyle,
final TextStyle? this.numberStyle,
final TextStyle? this.commentStyle,
final TextStyle? this.keywordStyle,
final TextStyle? this.stringStyle,
final TextStyle? this.punctuationStyle,
final TextStyle? this.classStyle,
final TextStyle? this.constantStyle,
required super.child,

This comment has been minimized.

Copy link
@mit-mit

mit-mit Aug 18, 2023

Is the this. prefix required; I mean isn't the preceeding type enough to disambiguate?

This comment has been minimized.

Copy link
@lrhn

lrhn Aug 18, 2023

Having both final and a type is allowed on an initializing formal today, so no.

This comment has been minimized.

Copy link
@munificent

munificent Aug 18, 2023

Author Owner

What Lasse said. :)

This comment has been minimized.

Copy link
@leafpetersen

leafpetersen Aug 21, 2023

I don't follow, what needs disambiguation? Are we saying that you can have non-field parameters here? Why not just say that in one of these new constructors, all named parameters declare fields, just like in primary constructors? In other words, why not just treat this exactly as a primary constructor, with different syntax?

This comment has been minimized.

Copy link
@lrhn

lrhn Aug 23, 2023

As I understand it, @mit-mit asks why we can't just remove the this. on the individual parameters on the right, and have it still mean the same thing.

The proposal here is that any constructor can introduce a field, by having an initializing formal with no corresponding field bing declared. That initializing formal then implies a field.

The constructor is not restricted the same way as a primary constructor, to only have field-declaring paramters, initializing formals and super parameters, so final TextStyle? baseStyle would be a valid parameter, and can not be used to imply a field.

(My comment that it's "allowed on an initializing formal today" is misleading, it's allowed on a normal parameter today, and normal parameters are allowed by this strawman proposal, as I read it.)

This proposal also may either allow multiple constructors with initializing formals for the same missing field, and require them to have the same type, or disallow having multiple initializing formals for the same missing field. Either can work.

This comment has been minimized.

Copy link
@munificent

munificent Aug 28, 2023

Author Owner

Why not just say that in one of these new constructors, all named parameters declare fields, just like in primary constructors? In other words, why not just treat this exactly as a primary constructor, with different syntax?

Primary constructors can't have initializer lists or bodies, so there's no point in having a parameter at all unless it initializes a field or gets passed to the superclass constructor.

In the strawman here, constructors can have initializer lists or bodies, so it's useful to have parameters that don't implicitly declare fields. Thus you need a syntax to distinguish the two.

This comment has been minimized.

Copy link
@leafpetersen

leafpetersen Aug 29, 2023

Ok, if the proposal is to allow any constructor to add fields as one among many parameters, I think this is basically the same as the proposal here, which I raised some objections to here. In general, I'm quite skeptical of allowing more than one constructor to add fields.

If we drop that part of the proposal and say that there is one designated constructor which may add fields, then the question is should we allow that constructor to also have non field-defining parameters. My personal take here is that the generalization is not worth the substantial loss of brevity in what seems to be the common case. Better to do one thing well than two things poorly.

});

final TextStyle? baseStyle;
final TextStyle? numberStyle;
final TextStyle? commentStyle;
final TextStyle? keywordStyle;
final TextStyle? stringStyle;
final TextStyle? punctuationStyle;
final TextStyle? classStyle;
final TextStyle? constantStyle;

static CodeStyle of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<CodeStyle>()!;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/demos/cupertino/cupertino_activity_indicator_demo.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import 'package:flutter_gen/gen_l10n/gallery_localizations.dart';
// BEGIN cupertinoActivityIndicatorDemo

class CupertinoProgressIndicatorDemo extends StatelessWidget {
const CupertinoProgressIndicatorDemo({super.key});
const ({super.key});

This comment has been minimized.

Copy link
@leafpetersen

leafpetersen Aug 21, 2023

Is this really not ambiguous? It just seems inconceivable that without const this doesn't collide somewhere. I guess the fact that every member ends in a semi-colon or a } saves you?

This comment has been minimized.

Copy link
@munificent

munificent Aug 28, 2023

Author Owner

I think it's unambiguous, but I'm honestly not sure. Constant fields have to be static so that rules out one potential collision.


@override
Widget build(BuildContext context) {
Expand Down
2 changes: 1 addition & 1 deletion lib/demos/cupertino/cupertino_button_demo.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import 'package:flutter_gen/gen_l10n/gallery_localizations.dart';
// BEGIN cupertinoButtonDemo

class CupertinoButtonDemo extends StatelessWidget {
const CupertinoButtonDemo({super.key});
const ({super.key});

@override
Widget build(BuildContext context) {
Expand Down
10 changes: 3 additions & 7 deletions lib/demos/cupertino/cupertino_picker_demo.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import 'package:intl/intl.dart';
// BEGIN cupertinoPickersDemo

class CupertinoPickerDemo extends StatefulWidget {
const CupertinoPickerDemo({super.key});
const ({super.key});

@override
State<CupertinoPickerDemo> createState() => _CupertinoPickerDemoState();
Expand Down Expand Up @@ -262,9 +262,7 @@ class _CupertinoPickerDemoState extends State<CupertinoPickerDemo> {
}

class _BottomPicker extends StatelessWidget {
const _BottomPicker({required this.child});

final Widget child;
const ({required final Widget this.child});

@override
Widget build(BuildContext context) {
Expand Down Expand Up @@ -294,9 +292,7 @@ class _BottomPicker extends StatelessWidget {
}

class _Menu extends StatelessWidget {
const _Menu({required this.children});

final List<Widget> children;
const ({required final List<Widget> children this.children});

@override
Widget build(BuildContext context) {
Expand Down
2 changes: 1 addition & 1 deletion lib/demos/cupertino/cupertino_switch_demo.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import 'package:flutter_gen/gen_l10n/gallery_localizations.dart';
// BEGIN cupertinoSwitchDemo

class CupertinoSwitchDemo extends StatefulWidget {
const CupertinoSwitchDemo({super.key});
const ({super.key});

@override
State<CupertinoSwitchDemo> createState() => _CupertinoSwitchDemoState();
Expand Down
16 changes: 5 additions & 11 deletions lib/demos/cupertino/cupertino_tab_bar_demo.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,11 @@ import 'package:flutter_gen/gen_l10n/gallery_localizations.dart';
// BEGIN cupertinoNavigationDemo

class _TabInfo {
const _TabInfo(this.title, this.icon);

This comment has been minimized.

Copy link
@leafpetersen

leafpetersen Aug 21, 2023

This is the level at which it starts to feel pretty underwhelming to me. Yeah, it's slightly less redundant, but really only a little bit.


final String title;
final IconData icon;
const (final String this.title, final IconData this.icon);
}

class CupertinoTabBarDemo extends StatelessWidget {
const CupertinoTabBarDemo({super.key});
const ({super.key});

@override
Widget build(BuildContext context) {
Expand Down Expand Up @@ -65,14 +62,11 @@ class CupertinoTabBarDemo extends StatelessWidget {
}

class _CupertinoDemoTab extends StatelessWidget {
const _CupertinoDemoTab({
required this.title,
required this.icon,
const ({
required final String this.title,
required final IconData this.icon,
});

final String title;
final IconData icon;

@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
Expand Down
2 changes: 1 addition & 1 deletion lib/demos/material/app_bar_demo.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import 'package:flutter_gen/gen_l10n/gallery_localizations.dart';
// BEGIN appbarDemo

class AppBarDemo extends StatelessWidget {
const AppBarDemo({super.key});
const ({super.key});

@override
Widget build(BuildContext context) {
Expand Down
6 changes: 2 additions & 4 deletions lib/demos/material/bottom_sheet_demo.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,11 @@ import 'package:flutter_gen/gen_l10n/gallery_localizations.dart';
import 'package:gallery/demos/material/material_demo_types.dart';

class BottomSheetDemo extends StatelessWidget {
const BottomSheetDemo({
const ({
super.key,
required this.type,
required final BottomSheetDemoType this.type,
});

final BottomSheetDemoType type;

String _title(BuildContext context) {
final localizations = GalleryLocalizations.of(context)!;
switch (type) {
Expand Down
4 changes: 1 addition & 3 deletions lib/demos/material/picker_demo.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ import 'package:intl/intl.dart';
// BEGIN pickerDemo

class PickerDemo extends StatefulWidget {
const PickerDemo({super.key, required this.type});

final PickerDemoType type;
const ({super.key, required final PickerDemoType this.type});

@override
State<PickerDemo> createState() => _PickerDemoState();
Expand Down
4 changes: 1 addition & 3 deletions lib/demos/material/progress_indicator_demo.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ import 'package:gallery/demos/material/material_demo_types.dart';
// BEGIN progressIndicatorsDemo

class ProgressIndicatorDemo extends StatefulWidget {
const ProgressIndicatorDemo({super.key, required this.type});

final ProgressIndicatorDemoType type;
const ({super.key, required final ProgressIndicatorDemoType this.type});

@override
State<ProgressIndicatorDemo> createState() => _ProgressIndicatorDemoState();
Expand Down
37 changes: 13 additions & 24 deletions lib/demos/material/text_field_demo.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import 'package:flutter_gen/gen_l10n/gallery_localizations.dart';
// BEGIN textFieldDemo

class TextFieldDemo extends StatelessWidget {
const TextFieldDemo({super.key});
const ({super.key});

@override
Widget build(BuildContext context) {
Expand All @@ -24,7 +24,7 @@ class TextFieldDemo extends StatelessWidget {
}

class TextFormFieldDemo extends StatefulWidget {
const TextFormFieldDemo({super.key});
const ({super.key});

@override
TextFormFieldDemoState createState() => TextFormFieldDemoState();
Expand All @@ -38,31 +38,20 @@ class PersonData {
}

class PasswordField extends StatefulWidget {
const PasswordField({
const ({
super.key,
this.restorationId,
this.fieldKey,
this.hintText,
this.labelText,
this.helperText,
this.onSaved,
this.validator,
this.onFieldSubmitted,
this.focusNode,
this.textInputAction,
final String? this.restorationId,
final Key? this.fieldKey,
final String? this.hintText,
final String? this.labelText,
final String? this.helperText,
final FormFieldSetter<String>? this.onSaved,
final FormFieldValidator<String>? this.validator,
final ValueChanged<String>? this.onFieldSubmitted,
final FocusNode? this.focusNode,
final TextInputAction? this.textInputAction,
});

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();
}
Expand Down
2 changes: 1 addition & 1 deletion lib/demos/reference/motion_demo_fade_scale_transition.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import 'package:flutter_gen/gen_l10n/gallery_localizations.dart';
// BEGIN fadeScaleTransitionDemo

class FadeScaleTransitionDemo extends StatefulWidget {
const FadeScaleTransitionDemo({super.key});
const ({super.key});

@override
State<FadeScaleTransitionDemo> createState() =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import 'package:flutter_gen/gen_l10n/gallery_localizations.dart';
// BEGIN fadeThroughTransitionDemo

class FadeThroughTransitionDemo extends StatefulWidget {
const FadeThroughTransitionDemo({super.key});
const ({super.key});

@override
State<FadeThroughTransitionDemo> createState() =>
Expand Down
12 changes: 5 additions & 7 deletions lib/demos/reference/motion_demo_shared_x_axis_transition.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import 'package:flutter_gen/gen_l10n/gallery_localizations.dart';
// BEGIN sharedXAxisTransitionDemo

class SharedXAxisTransitionDemo extends StatefulWidget {
const SharedXAxisTransitionDemo({super.key});
const ({super.key});
@override
State<SharedXAxisTransitionDemo> createState() =>
_SharedXAxisTransitionDemoState();
Expand Down Expand Up @@ -91,7 +91,7 @@ class _SharedXAxisTransitionDemoState extends State<SharedXAxisTransitionDemo> {
}

class _CoursePage extends StatelessWidget {
const _CoursePage();
const ();

@override
Widget build(BuildContext context) {
Expand Down Expand Up @@ -130,12 +130,10 @@ class _CoursePage extends StatelessWidget {
}

class _CourseSwitch extends StatefulWidget {
const _CourseSwitch({
this.course,
const ({
final String? this.course,
});

final String? course;

@override
_CourseSwitchState createState() => _CourseSwitchState();
}
Expand Down Expand Up @@ -164,7 +162,7 @@ class _CourseSwitchState extends State<_CourseSwitch> {
}

class _SignInPage extends StatelessWidget {
const _SignInPage();
const ();

@override
Widget build(BuildContext context) {
Expand Down
24 changes: 8 additions & 16 deletions lib/demos/reference/transformations_demo_color_picker.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,13 @@ import 'package:flutter/material.dart';
// A generic widget for a list of selectable colors.
@immutable
class ColorPicker extends StatelessWidget {
const ColorPicker({
const ({
super.key,
required this.colors,
required this.selectedColor,
this.onColorSelection,
required final Set<Color> this.colors,
required final Color this.selectedColor,
final ValueChanged<Color>? this.onColorSelection,
});

final Set<Color> colors;
final Color selectedColor;
final ValueChanged<Color>? onColorSelection;

@override
Widget build(BuildContext context) {
return Row(
Expand All @@ -40,16 +36,12 @@ class ColorPicker extends StatelessWidget {
// A single selectable color widget in the ColorPicker.
@immutable
class _ColorPickerSwatch extends StatelessWidget {
const _ColorPickerSwatch({
required this.color,
required this.selected,
this.onTap,
const ({
required final Color this.color,
required final bool this.selected,
final Function? this.onTap,
});

final Color color;
final bool selected;
final Function? onTap;

@override
Widget build(BuildContext context) {
return Container(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,12 @@ const backgroundColor = Color(0xFF272727);
// The panel for editing a board point.
@immutable
class EditBoardPoint extends StatelessWidget {
const EditBoardPoint({
const ({
super.key,
required this.boardPoint,
this.onColorSelection,
required final BoardPoint this.boardPoint,
final ValueChanged<Color>? this.onColorSelection,
});

final BoardPoint boardPoint;
final ValueChanged<Color>? onColorSelection;

@override
Widget build(BuildContext context) {
final boardPointColors = <Color>{
Expand Down
11 changes: 4 additions & 7 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,12 @@ void main() async {
}

class GalleryApp extends StatelessWidget {
const GalleryApp({
const ({
super.key,
this.initialRoute,
this.isTestMode = false,
final String? this.initialRoute,
final bool this.isTestMode = false,
});

final String? initialRoute;
final bool isTestMode;

@override
Widget build(BuildContext context) {
return ModelBinding(
Expand Down Expand Up @@ -106,7 +103,7 @@ class GalleryApp extends StatelessWidget {
}

class RootPage extends StatelessWidget {
const RootPage({
const ({
super.key,
});

Expand Down
Loading

0 comments on commit aa86068

Please sign in to comment.