Flutter Widget Key to be nullable

Fixes #46913

Change-Id: Id2d72ce497eaa1512c2bb95f023c9ff0160c5005
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/210128
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
Ahmed Ashour 2022-05-11 19:20:24 +00:00 committed by Commit Bot
parent a93a648e7f
commit 3c10e484c9
11 changed files with 77 additions and 98 deletions

View file

@ -6,7 +6,7 @@ import 'package:flutter/widgets.dart';
class AppBar extends StatefulWidget {
AppBar({
Key key,
Key? key,
title,
backgroundColor,
});

View file

@ -6,7 +6,7 @@ import 'package:flutter/widgets.dart';
class Scaffold extends StatefulWidget {
const Scaffold({
Key key,
Key? key,
Widget body,
});
}

View file

@ -10,8 +10,8 @@ typedef AsyncWidgetBuilder<T> = Widget Function(
class AsyncSnapshot<T> {}
class StreamBuilder<T> {
final T initialData;
final T? initialData;
final AsyncWidgetBuilder<T> builder;
const StreamBuilder(
{Key key, this.initialData, Stream<T> stream, @required this.builder});
{Key? key, this.initialData, Stream<T>? stream, @required this.builder});
}

View file

@ -32,22 +32,22 @@ class Align extends SingleChildRenderObjectWidget {
/// If non-null, sets its width to the child's width multiplied by this factor.
///
/// Can be both greater and less than 1.0 but must be positive.
final double widthFactor;
final double? widthFactor;
/// If non-null, sets its height to the child's height multiplied by this factor.
///
/// Can be both greater and less than 1.0 but must be positive.
final double heightFactor;
final double? heightFactor;
/// Creates an alignment widget.
///
/// The alignment defaults to [Alignment.center].
const Align({
Key key,
Key? key,
this.alignment = Alignment.center,
this.widthFactor,
this.heightFactor,
Widget child,
Widget? child,
}) : assert(alignment != null),
assert(widthFactor == null || widthFactor >= 0.0),
assert(heightFactor == null || heightFactor >= 0.0),
@ -56,50 +56,51 @@ class Align extends SingleChildRenderObjectWidget {
class AspectRatio extends SingleChildRenderObjectWidget {
const AspectRatio({
Key key,
Key? key,
@required double aspectRatio,
Widget child,
Widget? child,
});
}
class Center extends StatelessWidget {
const Center({Key key, double heightFactor, Widget child});
const Center({Key? key, double? heightFactor, Widget? child});
}
class SizedBox extends SingleChildRenderObjectWidget {
const SizedBox({Key key, this.width, this.height, Widget child})
const SizedBox({Key? key, this.width, this.height, Widget? child})
: super(key: key, child: child);
const SizedBox.expand({Key key, Widget child})
const SizedBox.expand({Key? key, Widget? child})
: width = double.infinity,
height = double.infinity,
super(key: key, child: child);
const SizedBox.shrink({Key key, Widget child})
const SizedBox.shrink({Key? key, Widget? child})
: width = 0.0,
height = 0.0,
super(key: key, child: child);
SizedBox.fromSize({Key key, Widget child, Size size})
SizedBox.fromSize({Key? key, Widget? child, Size? size})
: width = size?.width,
height = size?.height,
super(key: key, child: child);
final double width;
final double? width;
final double height;
final double? height;
}
class ClipRect extends SingleChildRenderObjectWidget {
const ClipRect({Key key, Widget child}) : super(key: key, child: child);
const ClipRect({Key? key, Widget? child}) : super(key: key, child: child);
/// Does not actually exist in Flutter.
const ClipRect.rect({Key key, Widget child}) : super(key: key, child: child);
const ClipRect.rect({Key? key, Widget? child})
: super(key: key, child: child);
}
class Column extends Flex {
Column({
Key key,
Key? key,
MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
MainAxisSize mainAxisSize = MainAxisSize.max,
CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
@ -112,7 +113,7 @@ class Column extends Flex {
class Expanded extends StatelessWidget {
const Expanded({
Key key,
Key? key,
int flex = 1,
@required Widget child,
});
@ -120,7 +121,7 @@ class Expanded extends StatelessWidget {
class Flex extends Widget {
Flex({
Key key,
Key? key,
List<Widget> children = const <Widget>[],
});
}
@ -129,15 +130,15 @@ class Padding extends SingleChildRenderObjectWidget {
final EdgeInsetsGeometry padding;
const Padding({
Key key,
Key? key,
@required this.padding,
Widget child,
Widget? child,
});
}
class Row extends Flex {
Row({
Key key,
Key? key,
MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
MainAxisSize mainAxisSize = MainAxisSize.max,
CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
@ -150,12 +151,12 @@ class Row extends Flex {
class Transform extends SingleChildRenderObjectWidget {
const Transform({
Key key,
Key? key,
@required transform,
origin,
alignment,
transformHitTests = true,
Widget child,
Widget? child,
});
}
@ -163,5 +164,5 @@ typedef WidgetBuilder = Widget Function(BuildContext context);
class Builder {
final WidgetBuilder builder;
const Builder({Key key, @required this.builder});
const Builder({Key? key, @required this.builder});
}

View file

@ -7,7 +7,7 @@ import 'package:flutter/painting.dart';
import 'framework.dart';
class Container extends StatelessWidget {
final Widget child;
final Widget? child;
/// Align the [child] within the container.
///
@ -23,14 +23,14 @@ class Container extends StatelessWidget {
/// specify an [AlignmentGeometry].
/// * [AlignmentDirectional], like [Alignment] for specifying alignments
/// relative to text direction.
final AlignmentGeometry alignment;
final AlignmentGeometry? alignment;
/// Empty space to inscribe inside the [decoration]. The [child], if any, is
/// placed inside this padding.
///
/// This padding is in addition to any padding inherent in the [decoration];
/// see [Decoration.padding].
final EdgeInsetsGeometry padding;
final EdgeInsetsGeometry? padding;
/// The decoration to paint behind the [child].
///
@ -40,23 +40,23 @@ class Container extends StatelessWidget {
///
/// The [child] is not clipped to the decoration. To clip a child to the shape
/// of a particular [ShapeDecoration], consider using a [ClipPath] widget.
final Decoration decoration;
final Decoration? decoration;
/// The decoration to paint in front of the [child].
final Decoration foregroundDecoration;
final Decoration? foregroundDecoration;
/// Empty space to surround the [decoration] and [child].
final EdgeInsetsGeometry margin;
final EdgeInsetsGeometry? margin;
Container({
Key key,
Key? key,
this.alignment,
this.padding,
Color color,
Decoration decoration,
Color? color,
Decoration? decoration,
this.foregroundDecoration,
double width,
double height,
double? width,
double? height,
this.margin,
this.child,
}) : decoration = decoration,

View file

@ -14,13 +14,13 @@ abstract class BuildContext {
}
abstract class RenderObjectWidget extends Widget {
const RenderObjectWidget({Key key}) : super(key: key);
const RenderObjectWidget({Key? key}) : super(key: key);
}
abstract class SingleChildRenderObjectWidget extends RenderObjectWidget {
final Widget child;
final Widget? child;
const SingleChildRenderObjectWidget({Key key, this.child}) : super(key: key);
const SingleChildRenderObjectWidget({Key? key, this.child}) : super(key: key);
}
abstract class State<T extends StatefulWidget> {
@ -36,19 +36,19 @@ abstract class State<T extends StatefulWidget> {
}
abstract class StatefulWidget extends Widget {
const StatefulWidget({Key key}) : super(key: key);
const StatefulWidget({Key? key}) : super(key: key);
State createState() => null;
}
abstract class StatelessWidget extends Widget {
const StatelessWidget({Key key}) : super(key: key);
const StatelessWidget({Key? key}) : super(key: key);
Widget build(BuildContext context) => null;
}
class Widget extends DiagnosticableTree {
final Key key;
final Key? key;
const Widget({this.key});

View file

@ -6,8 +6,8 @@ import 'package:flutter/widgets.dart';
class GestureDetector extends StatelessWidget {
GestureDetector({
Key key,
Widget child,
Key? key,
Widget? child,
onTap,
});
}

View file

@ -5,17 +5,17 @@
import 'framework.dart';
class Icon extends StatelessWidget {
final IconData icon;
final IconData? icon;
const Icon(
this.icon, {
Key key,
Key? key,
}) : super(key: key);
}
class IconData {
final int codePoint;
final String fontFamily;
final String? fontFamily;
const IconData(
this.codePoint, {

View file

@ -16,17 +16,17 @@ class Text extends StatelessWidget {
/// The text to display.
///
/// This will be null if a [textSpan] is provided instead.
final String data;
final String? data;
/// If non-null, the style to use for this text.
///
/// If the style's "inherit" property is true, the style will be merged with
/// the closest enclosing [DefaultTextStyle]. Otherwise, the style will
/// replace the closest enclosing [DefaultTextStyle].
final TextStyle style;
final TextStyle? style;
/// How the text should be aligned horizontally.
final TextAlign textAlign;
final TextAlign? textAlign;
/// The directionality of the text.
///
@ -41,15 +41,15 @@ class Text extends StatelessWidget {
/// its left.
///
/// Defaults to the ambient [Directionality], if any.
final TextDirection textDirection;
final TextDirection? textDirection;
/// Whether the text should break at soft line breaks.
///
/// If false, the glyphs in the text will be positioned as if there was unlimited horizontal space.
final bool softWrap;
final bool? softWrap;
/// How visual overflow should be handled.
final TextOverflow overflow;
final TextOverflow? overflow;
/// The number of font pixels for each logical pixel.
///
@ -59,7 +59,7 @@ class Text extends StatelessWidget {
/// The value given to the constructor as textScaleFactor. If null, will
/// use the [MediaQueryData.textScaleFactor] obtained from the ambient
/// [MediaQuery], or 1.0 if there is no [MediaQuery] in scope.
final double textScaleFactor;
final double? textScaleFactor;
/// An optional maximum number of lines for the text to span, wrapping if necessary.
/// If the text exceeds the given number of lines, it will be truncated according
@ -72,7 +72,7 @@ class Text extends StatelessWidget {
/// an explicit number for its [DefaultTextStyle.maxLines], then the
/// [DefaultTextStyle] value will take precedence. You can use a [RichText]
/// widget directly to entirely override the [DefaultTextStyle].
final int maxLines;
final int? maxLines;
/// An alternative semantics label for this text.
///
@ -86,10 +86,10 @@ class Text extends StatelessWidget {
/// ```dart
/// Text(r'$$', semanticsLabel: 'Double dollars')
/// ```
final String semanticsLabel;
final String? semanticsLabel;
/// {@macro flutter.dart:ui.text.TextWidthBasis}
final TextWidthBasis textWidthBasis;
final TextWidthBasis? textWidthBasis;
/// Creates a text widget.
///
@ -99,7 +99,7 @@ class Text extends StatelessWidget {
/// The [data] parameter must not be null.
const Text(
this.data, {
Key key,
Key? key,
this.style,
this.textAlign,
this.textDirection,

View file

@ -64,10 +64,7 @@ class FakeFlutter {
await assertNoAssist();
}
@failingTest
Future<void> test_inConstantContext() async {
// TODO(brianwilkerson) Get this test to pass again. Not clear whether it's
// a problem with the test code or the mock flutter package.
await resolveTestCode('''
import 'package:flutter/widgets.dart';
class FakeFlutter {

View file

@ -4,7 +4,6 @@
import 'package:analysis_server/src/services/correction/fix.dart';
import 'package:analysis_server/src/services/linter/lint_names.dart';
import 'package:analyzer/src/dart/error/lint_codes.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@ -211,7 +210,7 @@ class A extends StatelessWidget {
class MyWidget extends A {
MyWidget({super.key}) : super(text: '');
}
''', errorFilter: (error) => error.errorCode is LintCode);
''');
}
Future<void>
@ -241,7 +240,7 @@ class A extends StatelessWidget {
class MyWidget extends A {
MyWidget({super.key}) : super(text: '',);
}
''', errorFilter: (error) => error.errorCode is LintCode);
''');
}
Future<void>
@ -271,9 +270,7 @@ class A extends StatelessWidget {
class B extends A {
B({super.key}) : super(const Text(''),);
}
''',
//TODO(asashour) there should be no other errors
errorFilter: (error) => error.errorCode is LintCode);
''');
}
Future<void> test_initializer_final_constant() async {
@ -292,9 +289,7 @@ class MyWidget extends StatelessWidget {
const MyWidget({super.key});
}
''',
//TODO(asashour) there should be no other errors
errorFilter: (error) => error.errorCode is LintCode);
''');
}
Future<void> test_initializer_final_not_constant() async {
@ -332,9 +327,7 @@ class MyWidget extends StatelessWidget {
MyWidget({super.key});
}
''',
//TODO(asashour) there should be no other errors
errorFilter: (error) => error.errorCode is LintCode);
''');
}
Future<void> test_initializer_not_final_not_constant() async {
@ -372,9 +365,7 @@ class MyWidget extends StatelessWidget {
const MyWidget({super.key});
}
''',
//TODO(asashour) there should be no other errors
errorFilter: (error) => error.errorCode is LintCode);
''');
}
Future<void> test_super_not_constant() async {
@ -402,7 +393,7 @@ class ParentWidget extends StatelessWidget {
class MyWidget extends ParentWidget {
MyWidget({super.key});
}
''', errorFilter: (error) => error.errorCode is LintCode);
''');
}
}
@ -452,9 +443,7 @@ class A extends StatelessWidget {
class B extends A {
B({Key? key}) : super(const Text(''), key: key);
}
''',
//TODO(asashour) there should be no other errors
errorFilter: (error) => error.errorCode is LintCode);
''');
}
}
@ -637,7 +626,7 @@ class A extends StatelessWidget {
class MyWidget extends A {
MyWidget({Key? key}) : super(key: key, text: '');
}
''', errorFilter: (error) => error.errorCode is LintCode);
''');
}
Future<void>
@ -667,7 +656,7 @@ class A extends StatelessWidget {
class MyWidget extends A {
MyWidget({Key? key}) : super(key: key, text: '',);
}
''', errorFilter: (error) => error.errorCode is LintCode);
''');
}
Future<void>
@ -697,9 +686,7 @@ class A extends StatelessWidget {
class B extends A {
B({Key? key}) : super(const Text(''), key: key,);
}
''',
//TODO(asashour) there should be no other errors
errorFilter: (error) => error.errorCode is LintCode);
''');
}
Future<void> test_initializer_final_constant() async {
@ -718,9 +705,7 @@ class MyWidget extends StatelessWidget {
const MyWidget({Key? key}) : super(key: key);
}
''',
//TODO(asashour) there should be no other errors
errorFilter: (error) => error.errorCode is LintCode);
''');
}
Future<void> test_initializer_final_not_constant() async {
@ -758,9 +743,7 @@ class MyWidget extends StatelessWidget {
MyWidget({Key? key}) : super(key: key);
}
''',
//TODO(asashour) there should be no other errors
errorFilter: (error) => error.errorCode is LintCode);
''');
}
Future<void> test_initializer_not_final_not_constant() async {
@ -798,9 +781,7 @@ class MyWidget extends StatelessWidget {
const MyWidget({Key? key}) : super(key: key);
}
''',
//TODO(asashour) there should be no other errors
errorFilter: (error) => error.errorCode is LintCode);
''');
}
Future<void> test_super_not_constant() async {
@ -828,6 +809,6 @@ class ParentWidget extends StatelessWidget {
class MyWidget extends ParentWidget {
MyWidget({Key? key}) : super(key: key);
}
''', errorFilter: (error) => error.errorCode is LintCode);
''');
}
}