Unverified Commit 734a90eb authored by Michael Goderbauer's avatar Michael Goderbauer Committed by GitHub

migrate semantics to nullsafety (#64055)

parent 6ca9cd7b
...@@ -7,5 +7,6 @@ analyzer: ...@@ -7,5 +7,6 @@ analyzer:
- non-nullable - non-nullable
errors: errors:
always_require_non_null_named_parameters: false # not needed with nnbd always_require_non_null_named_parameters: false # not needed with nnbd
type_init_formals: false # https://github.com/dart-lang/linter/issues/2192
void_checks: false # https://github.com/dart-lang/linter/issues/2185 void_checks: false # https://github.com/dart-lang/linter/issues/2185
unnecessary_null_comparison: false # https://github.com/dart-lang/language/issues/1018 , turned off until https://github.com/flutter/flutter/issues/61042 unnecessary_null_comparison: false # https://github.com/dart-lang/language/issues/1018 , turned off until https://github.com/flutter/flutter/issues/61042
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
/// The Flutter semantics package. /// The Flutter semantics package.
/// ///
/// To use, import `package:flutter/semantics.dart`. /// To use, import `package:flutter/semantics.dart`.
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:ui' as ui show AccessibilityFeatures, SemanticsUpdateBuilder; import 'dart:ui' as ui show AccessibilityFeatures, SemanticsUpdateBuilder;
...@@ -16,8 +15,8 @@ export 'dart:ui' show AccessibilityFeatures; ...@@ -16,8 +15,8 @@ export 'dart:ui' show AccessibilityFeatures;
// TODO(jonahwilliams): move the remaining semantic related bindings here. // TODO(jonahwilliams): move the remaining semantic related bindings here.
mixin SemanticsBinding on BindingBase { mixin SemanticsBinding on BindingBase {
/// The current [SemanticsBinding], if one has been created. /// The current [SemanticsBinding], if one has been created.
static SemanticsBinding get instance => _instance; static SemanticsBinding? get instance => _instance;
static SemanticsBinding _instance; static SemanticsBinding? _instance;
@override @override
void initInstances() { void initInstances() {
...@@ -53,7 +52,7 @@ mixin SemanticsBinding on BindingBase { ...@@ -53,7 +52,7 @@ mixin SemanticsBinding on BindingBase {
/// [WidgetsBindingObserver] and listen to /// [WidgetsBindingObserver] and listen to
/// [WidgetsBindingObserver.didChangeAccessibilityFeatures]. /// [WidgetsBindingObserver.didChangeAccessibilityFeatures].
ui.AccessibilityFeatures get accessibilityFeatures => _accessibilityFeatures; ui.AccessibilityFeatures get accessibilityFeatures => _accessibilityFeatures;
ui.AccessibilityFeatures _accessibilityFeatures; late ui.AccessibilityFeatures _accessibilityFeatures;
/// The platform is requesting that animations be disabled or simplified. /// The platform is requesting that animations be disabled or simplified.
/// ///
...@@ -63,7 +62,7 @@ mixin SemanticsBinding on BindingBase { ...@@ -63,7 +62,7 @@ mixin SemanticsBinding on BindingBase {
bool value = _accessibilityFeatures.disableAnimations; bool value = _accessibilityFeatures.disableAnimations;
assert(() { assert(() {
if (debugSemanticsDisableAnimations != null) if (debugSemanticsDisableAnimations != null)
value = debugSemanticsDisableAnimations; value = debugSemanticsDisableAnimations!;
return true; return true;
}()); }());
return value; return value;
......
...@@ -2,10 +2,9 @@ ...@@ -2,10 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
/// Overrides the setting of [SemanticsBinding.disableAnimations] for debugging /// Overrides the setting of [SemanticsBinding.disableAnimations] for debugging
/// and testing. /// and testing.
/// ///
/// This value is ignored in non-debug builds. /// This value is ignored in non-debug builds.
bool debugSemanticsDisableAnimations; bool? debugSemanticsDisableAnimations;
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:math' as math; import 'dart:math' as math;
import 'dart:typed_data'; import 'dart:typed_data';
...@@ -99,7 +98,7 @@ class CustomSemanticsAction { ...@@ -99,7 +98,7 @@ class CustomSemanticsAction {
/// Creates a new [CustomSemanticsAction]. /// Creates a new [CustomSemanticsAction].
/// ///
/// The [label] must not be null or the empty string. /// The [label] must not be null or the empty string.
const CustomSemanticsAction({@required this.label}) const CustomSemanticsAction({required String this.label})
: assert(label != null), : assert(label != null),
assert(label != ''), assert(label != ''),
hint = null, hint = null,
...@@ -109,20 +108,20 @@ class CustomSemanticsAction { ...@@ -109,20 +108,20 @@ class CustomSemanticsAction {
/// action. /// action.
/// ///
/// The [hint] must not be null or the empty string. /// The [hint] must not be null or the empty string.
const CustomSemanticsAction.overridingAction({@required this.hint, @required this.action}) const CustomSemanticsAction.overridingAction({required String this.hint, required SemanticsAction this.action})
: assert(hint != null), : assert(hint != null),
assert(hint != ''), assert(hint != ''),
assert(action != null), assert(action != null),
label = null; label = null;
/// The user readable name of this custom semantics action. /// The user readable name of this custom semantics action.
final String label; final String? label;
/// The hint description of this custom semantics action. /// The hint description of this custom semantics action.
final String hint; final String? hint;
/// The standard semantics action this action replaces. /// The standard semantics action this action replaces.
final SemanticsAction action; final SemanticsAction? action;
@override @override
int get hashCode => ui.hashValues(label, hint, action); int get hashCode => ui.hashValues(label, hint, action);
...@@ -150,7 +149,7 @@ class CustomSemanticsAction { ...@@ -150,7 +149,7 @@ class CustomSemanticsAction {
/// Get the identifier for a given `action`. /// Get the identifier for a given `action`.
static int getIdentifier(CustomSemanticsAction action) { static int getIdentifier(CustomSemanticsAction action) {
int result = _ids[action]; int? result = _ids[action];
if (result == null) { if (result == null) {
result = _nextId++; result = _nextId++;
_ids[action] = result; _ids[action] = result;
...@@ -160,7 +159,7 @@ class CustomSemanticsAction { ...@@ -160,7 +159,7 @@ class CustomSemanticsAction {
} }
/// Get the `action` for a given identifier. /// Get the `action` for a given identifier.
static CustomSemanticsAction getAction(int id) { static CustomSemanticsAction? getAction(int id) {
return _actions[id]; return _actions[id];
} }
} }
...@@ -181,26 +180,26 @@ class SemanticsData with Diagnosticable { ...@@ -181,26 +180,26 @@ class SemanticsData with Diagnosticable {
/// ///
/// If [label] is not empty, then [textDirection] must also not be null. /// If [label] is not empty, then [textDirection] must also not be null.
const SemanticsData({ const SemanticsData({
@required this.flags, required this.flags,
@required this.actions, required this.actions,
@required this.label, required this.label,
@required this.increasedValue, required this.increasedValue,
@required this.value, required this.value,
@required this.decreasedValue, required this.decreasedValue,
@required this.hint, required this.hint,
@required this.textDirection, required this.textDirection,
@required this.rect, required this.rect,
@required this.elevation, required this.elevation,
@required this.thickness, required this.thickness,
@required this.textSelection, required this.textSelection,
@required this.scrollIndex, required this.scrollIndex,
@required this.scrollChildCount, required this.scrollChildCount,
@required this.scrollPosition, required this.scrollPosition,
@required this.scrollExtentMax, required this.scrollExtentMax,
@required this.scrollExtentMin, required this.scrollExtentMin,
@required this.platformViewId, required this.platformViewId,
@required this.maxValueLength, required this.maxValueLength,
@required this.currentValueLength, required this.currentValueLength,
this.tags, this.tags,
this.transform, this.transform,
this.customSemanticsActionIds, this.customSemanticsActionIds,
...@@ -253,20 +252,20 @@ class SemanticsData with Diagnosticable { ...@@ -253,20 +252,20 @@ class SemanticsData with Diagnosticable {
/// The reading direction for the text in [label], [value], [hint], /// The reading direction for the text in [label], [value], [hint],
/// [increasedValue], and [decreasedValue]. /// [increasedValue], and [decreasedValue].
final TextDirection textDirection; final TextDirection? textDirection;
/// The currently selected text (or the position of the cursor) within [value] /// The currently selected text (or the position of the cursor) within [value]
/// if this node represents a text field. /// if this node represents a text field.
final TextSelection textSelection; final TextSelection? textSelection;
/// The total number of scrollable children that contribute to semantics. /// The total number of scrollable children that contribute to semantics.
/// ///
/// If the number of children are unknown or unbounded, this value will be /// If the number of children are unknown or unbounded, this value will be
/// null. /// null.
final int scrollChildCount; final int? scrollChildCount;
/// The index of the first visible semantic child of a scroll node. /// The index of the first visible semantic child of a scroll node.
final int scrollIndex; final int? scrollIndex;
/// Indicates the current scrolling position in logical pixels if the node is /// Indicates the current scrolling position in logical pixels if the node is
/// scrollable. /// scrollable.
...@@ -278,7 +277,7 @@ class SemanticsData with Diagnosticable { ...@@ -278,7 +277,7 @@ class SemanticsData with Diagnosticable {
/// See also: /// See also:
/// ///
/// * [ScrollPosition.pixels], from where this value is usually taken. /// * [ScrollPosition.pixels], from where this value is usually taken.
final double scrollPosition; final double? scrollPosition;
/// Indicates the maximum in-range value for [scrollPosition] if the node is /// Indicates the maximum in-range value for [scrollPosition] if the node is
/// scrollable. /// scrollable.
...@@ -288,7 +287,7 @@ class SemanticsData with Diagnosticable { ...@@ -288,7 +287,7 @@ class SemanticsData with Diagnosticable {
/// See also: /// See also:
/// ///
/// * [ScrollPosition.maxScrollExtent], from where this value is usually taken. /// * [ScrollPosition.maxScrollExtent], from where this value is usually taken.
final double scrollExtentMax; final double? scrollExtentMax;
/// Indicates the minimum in-range value for [scrollPosition] if the node is /// Indicates the minimum in-range value for [scrollPosition] if the node is
/// scrollable. /// scrollable.
...@@ -298,7 +297,7 @@ class SemanticsData with Diagnosticable { ...@@ -298,7 +297,7 @@ class SemanticsData with Diagnosticable {
/// See also: /// See also:
/// ///
/// * [ScrollPosition.minScrollExtent], from where this value is usually taken. /// * [ScrollPosition.minScrollExtent], from where this value is usually taken.
final double scrollExtentMin; final double? scrollExtentMin;
/// The id of the platform view, whose semantics nodes will be added as /// The id of the platform view, whose semantics nodes will be added as
/// children to this node. /// children to this node.
...@@ -311,7 +310,7 @@ class SemanticsData with Diagnosticable { ...@@ -311,7 +310,7 @@ class SemanticsData with Diagnosticable {
/// ///
/// * [AndroidView], which is the platform view for Android. /// * [AndroidView], which is the platform view for Android.
/// * [UiKitView], which is the platform view for iOS. /// * [UiKitView], which is the platform view for iOS.
final int platformViewId; final int? platformViewId;
/// The maximum number of characters that can be entered into an editable /// The maximum number of characters that can be entered into an editable
/// text field. /// text field.
...@@ -321,7 +320,7 @@ class SemanticsData with Diagnosticable { ...@@ -321,7 +320,7 @@ class SemanticsData with Diagnosticable {
/// ///
/// This should only be set when [SemanticsFlag.isTextField] is set. Defaults /// This should only be set when [SemanticsFlag.isTextField] is set. Defaults
/// to null, which means no limit is imposed on the text field. /// to null, which means no limit is imposed on the text field.
final int maxValueLength; final int? maxValueLength;
/// The current number of characters that have been entered into an editable /// The current number of characters that have been entered into an editable
/// text field. /// text field.
...@@ -331,20 +330,20 @@ class SemanticsData with Diagnosticable { ...@@ -331,20 +330,20 @@ class SemanticsData with Diagnosticable {
/// ///
/// This should only be set when [SemanticsFlag.isTextField] is set. This must /// This should only be set when [SemanticsFlag.isTextField] is set. This must
/// be set when [maxValueLength] is set. /// be set when [maxValueLength] is set.
final int currentValueLength; final int? currentValueLength;
/// The bounding box for this node in its coordinate system. /// The bounding box for this node in its coordinate system.
final Rect rect; final Rect rect;
/// The set of [SemanticsTag]s associated with this node. /// The set of [SemanticsTag]s associated with this node.
final Set<SemanticsTag> tags; final Set<SemanticsTag>? tags;
/// The transform from this node's coordinate system to its parent's coordinate system. /// The transform from this node's coordinate system to its parent's coordinate system.
/// ///
/// By default, the transform is null, which represents the identity /// By default, the transform is null, which represents the identity
/// transformation (i.e., that this node has the same coordinate system as its /// transformation (i.e., that this node has the same coordinate system as its
/// parent). /// parent).
final Matrix4 transform; final Matrix4? transform;
/// The elevation of this node relative to the parent semantics node. /// The elevation of this node relative to the parent semantics node.
/// ///
...@@ -369,7 +368,7 @@ class SemanticsData with Diagnosticable { ...@@ -369,7 +368,7 @@ class SemanticsData with Diagnosticable {
/// See also: /// See also:
/// ///
/// * [CustomSemanticsAction], for an explanation of custom actions. /// * [CustomSemanticsAction], for an explanation of custom actions.
final List<int> customSemanticsActionIds; final List<int>? customSemanticsActionIds;
/// Whether [flags] contains the given flag. /// Whether [flags] contains the given flag.
bool hasFlag(SemanticsFlag flag) => (flags & flag.index) != 0; bool hasFlag(SemanticsFlag flag) => (flags & flag.index) != 0;
...@@ -392,11 +391,11 @@ class SemanticsData with Diagnosticable { ...@@ -392,11 +391,11 @@ class SemanticsData with Diagnosticable {
if ((actions & action.index) != 0) if ((actions & action.index) != 0)
describeEnum(action), describeEnum(action),
]; ];
final List<String> customSemanticsActionSummary = customSemanticsActionIds final List<String?> customSemanticsActionSummary = customSemanticsActionIds!
.map<String>((int actionId) => CustomSemanticsAction.getAction(actionId).label) .map<String?>((int actionId) => CustomSemanticsAction.getAction(actionId)!.label)
.toList(); .toList();
properties.add(IterableProperty<String>('actions', actionSummary, ifEmpty: null)); properties.add(IterableProperty<String>('actions', actionSummary, ifEmpty: null));
properties.add(IterableProperty<String>('customActions', customSemanticsActionSummary, ifEmpty: null)); properties.add(IterableProperty<String?>('customActions', customSemanticsActionSummary, ifEmpty: null));
final List<String> flagSummary = <String>[ final List<String> flagSummary = <String>[
for (final SemanticsFlag flag in SemanticsFlag.values.values) for (final SemanticsFlag flag in SemanticsFlag.values.values)
...@@ -411,7 +410,7 @@ class SemanticsData with Diagnosticable { ...@@ -411,7 +410,7 @@ class SemanticsData with Diagnosticable {
properties.add(StringProperty('hint', hint, defaultValue: '')); properties.add(StringProperty('hint', hint, defaultValue: ''));
properties.add(EnumProperty<TextDirection>('textDirection', textDirection, defaultValue: null)); properties.add(EnumProperty<TextDirection>('textDirection', textDirection, defaultValue: null));
if (textSelection?.isValid == true) if (textSelection?.isValid == true)
properties.add(MessageProperty('textSelection', '[${textSelection.start}, ${textSelection.end}]')); properties.add(MessageProperty('textSelection', '[${textSelection!.start}, ${textSelection!.end}]'));
properties.add(IntProperty('platformViewId', platformViewId, defaultValue: null)); properties.add(IntProperty('platformViewId', platformViewId, defaultValue: null));
properties.add(IntProperty('maxValueLength', maxValueLength, defaultValue: null)); properties.add(IntProperty('maxValueLength', maxValueLength, defaultValue: null));
properties.add(IntProperty('currentValueLength', currentValueLength, defaultValue: null)); properties.add(IntProperty('currentValueLength', currentValueLength, defaultValue: null));
...@@ -481,7 +480,7 @@ class SemanticsData with Diagnosticable { ...@@ -481,7 +480,7 @@ class SemanticsData with Diagnosticable {
); );
} }
static bool _sortedListsEqual(List<int> left, List<int> right) { static bool _sortedListsEqual(List<int>? left, List<int>? right) {
if (left == null && right == null) if (left == null && right == null)
return true; return true;
if (left != null && right != null) { if (left != null && right != null) {
...@@ -498,10 +497,10 @@ class SemanticsData with Diagnosticable { ...@@ -498,10 +497,10 @@ class SemanticsData with Diagnosticable {
class _SemanticsDiagnosticableNode extends DiagnosticableNode<SemanticsNode> { class _SemanticsDiagnosticableNode extends DiagnosticableNode<SemanticsNode> {
_SemanticsDiagnosticableNode({ _SemanticsDiagnosticableNode({
String name, String? name,
@required SemanticsNode value, required SemanticsNode value,
@required DiagnosticsTreeStyle style, required DiagnosticsTreeStyle? style,
@required this.childOrder, required this.childOrder,
}) : super( }) : super(
name: name, name: name,
value: value, value: value,
...@@ -515,7 +514,10 @@ class _SemanticsDiagnosticableNode extends DiagnosticableNode<SemanticsNode> { ...@@ -515,7 +514,10 @@ class _SemanticsDiagnosticableNode extends DiagnosticableNode<SemanticsNode> {
if (value != null) if (value != null)
return value.debugDescribeChildren(childOrder: childOrder); return value.debugDescribeChildren(childOrder: childOrder);
return const <DiagnosticsNode>[]; // `value` has a non-nullable return type, but might be null when
// running with weak checking, so we need to null check it above (and
// ignore the warning below that the null-handling logic is dead code).
return const <DiagnosticsNode>[]; // ignore: dead_code
} }
} }
...@@ -541,7 +543,7 @@ class SemanticsHintOverrides extends DiagnosticableTree { ...@@ -541,7 +543,7 @@ class SemanticsHintOverrides extends DiagnosticableTree {
/// ///
/// Bad: 'Double tap to show movies'. /// Bad: 'Double tap to show movies'.
/// Good: 'show movies'. /// Good: 'show movies'.
final String onTapHint; final String? onTapHint;
/// The hint text for a long press action. /// The hint text for a long press action.
/// ///
...@@ -552,7 +554,7 @@ class SemanticsHintOverrides extends DiagnosticableTree { ...@@ -552,7 +554,7 @@ class SemanticsHintOverrides extends DiagnosticableTree {
/// ///
/// Bad: 'Double tap and hold to show tooltip'. /// Bad: 'Double tap and hold to show tooltip'.
/// Good: 'show tooltip'. /// Good: 'show tooltip'.
final String onLongPressHint; final String? onLongPressHint;
/// Whether there are any non-null hint values. /// Whether there are any non-null hint values.
bool get isNotEmpty => onTapHint != null || onLongPressHint != null; bool get isNotEmpty => onTapHint != null || onLongPressHint != null;
...@@ -643,61 +645,61 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -643,61 +645,61 @@ class SemanticsProperties extends DiagnosticableTree {
/// For example, a button that a user can currently interact with would set /// For example, a button that a user can currently interact with would set
/// this field to true. A button that currently does not respond to user /// this field to true. A button that currently does not respond to user
/// interactions would set this field to false. /// interactions would set this field to false.
final bool enabled; final bool? enabled;
/// If non-null, indicates that this subtree represents a checkbox /// If non-null, indicates that this subtree represents a checkbox
/// or similar widget with a "checked" state, and what its current /// or similar widget with a "checked" state, and what its current
/// state is. /// state is.
/// ///
/// This is mutually exclusive with [toggled]. /// This is mutually exclusive with [toggled].
final bool checked; final bool? checked;
/// If non-null, indicates that this subtree represents a toggle switch /// If non-null, indicates that this subtree represents a toggle switch
/// or similar widget with an "on" state, and what its current /// or similar widget with an "on" state, and what its current
/// state is. /// state is.
/// ///
/// This is mutually exclusive with [checked]. /// This is mutually exclusive with [checked].
final bool toggled; final bool? toggled;
/// If non-null indicates that this subtree represents something that can be /// If non-null indicates that this subtree represents something that can be
/// in a selected or unselected state, and what its current state is. /// in a selected or unselected state, and what its current state is.
/// ///
/// The active tab in a tab bar for example is considered "selected", whereas /// The active tab in a tab bar for example is considered "selected", whereas
/// all other tabs are unselected. /// all other tabs are unselected.
final bool selected; final bool? selected;
/// If non-null, indicates that this subtree represents a button. /// If non-null, indicates that this subtree represents a button.
/// ///
/// TalkBack/VoiceOver provides users with the hint "button" when a button /// TalkBack/VoiceOver provides users with the hint "button" when a button
/// is focused. /// is focused.
final bool button; final bool? button;
/// If non-null, indicates that this subtree represents a link. /// If non-null, indicates that this subtree represents a link.
/// ///
/// iOS's VoiceOver provides users with a unique hint when a link is focused. /// iOS's VoiceOver provides users with a unique hint when a link is focused.
/// Android's Talkback will announce a link hint the same way it does a /// Android's Talkback will announce a link hint the same way it does a
/// button. /// button.
final bool link; final bool? link;
/// If non-null, indicates that this subtree represents a header. /// If non-null, indicates that this subtree represents a header.
/// ///
/// A header divides into sections. For example, an address book application /// A header divides into sections. For example, an address book application
/// might define headers A, B, C, etc. to divide the list of alphabetically /// might define headers A, B, C, etc. to divide the list of alphabetically
/// sorted contacts into sections. /// sorted contacts into sections.
final bool header; final bool? header;
/// If non-null, indicates that this subtree represents a text field. /// If non-null, indicates that this subtree represents a text field.
/// ///
/// TalkBack/VoiceOver provide special affordances to enter text into a /// TalkBack/VoiceOver provide special affordances to enter text into a
/// text field. /// text field.
final bool textField; final bool? textField;
/// If non-null, indicates that this subtree is read only. /// If non-null, indicates that this subtree is read only.
/// ///
/// Only applicable when [textField] is true. /// Only applicable when [textField] is true.
/// ///
/// TalkBack/VoiceOver will treat it as non-editable text field. /// TalkBack/VoiceOver will treat it as non-editable text field.
final bool readOnly; final bool? readOnly;
/// If non-null, whether the node is able to hold input focus. /// If non-null, whether the node is able to hold input focus.
/// ///
...@@ -707,7 +709,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -707,7 +709,7 @@ class SemanticsProperties extends DiagnosticableTree {
/// to be confused with accessibility focus. Accessibility focus is the /// to be confused with accessibility focus. Accessibility focus is the
/// green/black rectangular highlight that TalkBack/VoiceOver draws around the /// green/black rectangular highlight that TalkBack/VoiceOver draws around the
/// element it is reading, and is separate from input focus. /// element it is reading, and is separate from input focus.
final bool focusable; final bool? focusable;
/// If non-null, whether the node currently holds input focus. /// If non-null, whether the node currently holds input focus.
/// ///
...@@ -718,13 +720,13 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -718,13 +720,13 @@ class SemanticsProperties extends DiagnosticableTree {
/// to be confused with accessibility focus. Accessibility focus is the /// to be confused with accessibility focus. Accessibility focus is the
/// green/black rectangular highlight that TalkBack/VoiceOver draws around the /// green/black rectangular highlight that TalkBack/VoiceOver draws around the
/// element it is reading, and is separate from input focus. /// element it is reading, and is separate from input focus.
final bool focused; final bool? focused;
/// If non-null, whether a semantic node is in a mutually exclusive group. /// If non-null, whether a semantic node is in a mutually exclusive group.
/// ///
/// For example, a radio button is in a mutually exclusive group because only /// For example, a radio button is in a mutually exclusive group because only
/// one radio button in that group can be marked as [checked]. /// one radio button in that group can be marked as [checked].
final bool inMutuallyExclusiveGroup; final bool? inMutuallyExclusiveGroup;
/// If non-null, whether the node is considered hidden. /// If non-null, whether the node is considered hidden.
/// ///
...@@ -742,14 +744,14 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -742,14 +744,14 @@ class SemanticsProperties extends DiagnosticableTree {
/// the semantics tree altogether. Hidden elements are only included in the /// the semantics tree altogether. Hidden elements are only included in the
/// semantics tree to work around platform limitations and they are mainly /// semantics tree to work around platform limitations and they are mainly
/// used to implement accessibility scrolling on iOS. /// used to implement accessibility scrolling on iOS.
final bool hidden; final bool? hidden;
/// If non-null, whether [value] should be obscured. /// If non-null, whether [value] should be obscured.
/// ///
/// This option is usually set in combination with [textField] to indicate /// This option is usually set in combination with [textField] to indicate
/// that the text field contains a password (or other sensitive information). /// that the text field contains a password (or other sensitive information).
/// Doing so instructs screen readers to not read out the [value]. /// Doing so instructs screen readers to not read out the [value].
final bool obscured; final bool? obscured;
/// Whether the [value] is coming from a field that supports multiline text /// Whether the [value] is coming from a field that supports multiline text
/// editing. /// editing.
...@@ -758,7 +760,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -758,7 +760,7 @@ class SemanticsProperties extends DiagnosticableTree {
/// whether it's a single-line or multiline text field. /// whether it's a single-line or multiline text field.
/// ///
/// This option is null when [textField] is false. /// This option is null when [textField] is false.
final bool multiline; final bool? multiline;
/// If non-null, whether the node corresponds to the root of a subtree for /// If non-null, whether the node corresponds to the root of a subtree for
/// which a route name should be announced. /// which a route name should be announced.
...@@ -771,21 +773,21 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -771,21 +773,21 @@ class SemanticsProperties extends DiagnosticableTree {
/// ///
/// * [SemanticsFlag.scopesRoute] for a description of how the announced /// * [SemanticsFlag.scopesRoute] for a description of how the announced
/// value is selected. /// value is selected.
final bool scopesRoute; final bool? scopesRoute;
/// If non-null, whether the node contains the semantic label for a route. /// If non-null, whether the node contains the semantic label for a route.
/// ///
/// See also: /// See also:
/// ///
/// * [SemanticsFlag.namesRoute] for a description of how the name is used. /// * [SemanticsFlag.namesRoute] for a description of how the name is used.
final bool namesRoute; final bool? namesRoute;
/// If non-null, whether the node represents an image. /// If non-null, whether the node represents an image.
/// ///
/// See also: /// See also:
/// ///
/// * [SemanticsFlag.isImage], for the flag this setting controls. /// * [SemanticsFlag.isImage], for the flag this setting controls.
final bool image; final bool? image;
/// If non-null, whether the node should be considered a live region. /// If non-null, whether the node should be considered a live region.
/// ///
...@@ -806,7 +808,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -806,7 +808,7 @@ class SemanticsProperties extends DiagnosticableTree {
/// ///
/// * [SemanticsFlag.isLiveRegion], the semantics flag this setting controls. /// * [SemanticsFlag.isLiveRegion], the semantics flag this setting controls.
/// * [SemanticsConfiguration.liveRegion], for a full description of a live region. /// * [SemanticsConfiguration.liveRegion], for a full description of a live region.
final bool liveRegion; final bool? liveRegion;
/// The maximum number of characters that can be entered into an editable /// The maximum number of characters that can be entered into an editable
/// text field. /// text field.
...@@ -816,7 +818,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -816,7 +818,7 @@ class SemanticsProperties extends DiagnosticableTree {
/// ///
/// This should only be set when [textField] is true. Defaults to null, /// This should only be set when [textField] is true. Defaults to null,
/// which means no limit is imposed on the text field. /// which means no limit is imposed on the text field.
final int maxValueLength; final int? maxValueLength;
/// The current number of characters that have been entered into an editable /// The current number of characters that have been entered into an editable
/// text field. /// text field.
...@@ -826,7 +828,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -826,7 +828,7 @@ class SemanticsProperties extends DiagnosticableTree {
/// ///
/// This should only be set when [textField] is true. Must be set when /// This should only be set when [textField] is true. Must be set when
/// [maxValueLength] is set. /// [maxValueLength] is set.
final int currentValueLength; final int? currentValueLength;
/// Provides a textual description of the widget. /// Provides a textual description of the widget.
/// ///
...@@ -837,7 +839,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -837,7 +839,7 @@ class SemanticsProperties extends DiagnosticableTree {
/// ///
/// * [SemanticsConfiguration.label] for a description of how this is exposed /// * [SemanticsConfiguration.label] for a description of how this is exposed
/// in TalkBack and VoiceOver. /// in TalkBack and VoiceOver.
final String label; final String? label;
/// Provides a textual description of the value of the widget. /// Provides a textual description of the value of the widget.
/// ///
...@@ -848,7 +850,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -848,7 +850,7 @@ class SemanticsProperties extends DiagnosticableTree {
/// ///
/// * [SemanticsConfiguration.value] for a description of how this is exposed /// * [SemanticsConfiguration.value] for a description of how this is exposed
/// in TalkBack and VoiceOver. /// in TalkBack and VoiceOver.
final String value; final String? value;
/// The value that [value] will become after a [SemanticsAction.increase] /// The value that [value] will become after a [SemanticsAction.increase]
/// action has been performed on this widget. /// action has been performed on this widget.
...@@ -861,7 +863,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -861,7 +863,7 @@ class SemanticsProperties extends DiagnosticableTree {
/// ///
/// * [SemanticsConfiguration.increasedValue] for a description of how this /// * [SemanticsConfiguration.increasedValue] for a description of how this
/// is exposed in TalkBack and VoiceOver. /// is exposed in TalkBack and VoiceOver.
final String increasedValue; final String? increasedValue;
/// The value that [value] will become after a [SemanticsAction.decrease] /// The value that [value] will become after a [SemanticsAction.decrease]
/// action has been performed on this widget. /// action has been performed on this widget.
...@@ -874,7 +876,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -874,7 +876,7 @@ class SemanticsProperties extends DiagnosticableTree {
/// ///
/// * [SemanticsConfiguration.decreasedValue] for a description of how this /// * [SemanticsConfiguration.decreasedValue] for a description of how this
/// is exposed in TalkBack and VoiceOver. /// is exposed in TalkBack and VoiceOver.
final String decreasedValue; final String? decreasedValue;
/// Provides a brief textual description of the result of an action performed /// Provides a brief textual description of the result of an action performed
/// on the widget. /// on the widget.
...@@ -886,7 +888,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -886,7 +888,7 @@ class SemanticsProperties extends DiagnosticableTree {
/// ///
/// * [SemanticsConfiguration.hint] for a description of how this is exposed /// * [SemanticsConfiguration.hint] for a description of how this is exposed
/// in TalkBack and VoiceOver. /// in TalkBack and VoiceOver.
final String hint; final String? hint;
/// Provides hint values which override the default hints on supported /// Provides hint values which override the default hints on supported
/// platforms. /// platforms.
...@@ -896,13 +898,13 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -896,13 +898,13 @@ class SemanticsProperties extends DiagnosticableTree {
/// as there as at least one non-null hint override. /// as there as at least one non-null hint override.
/// ///
/// On iOS, these are always ignored and the default [hint] is used instead. /// On iOS, these are always ignored and the default [hint] is used instead.
final SemanticsHintOverrides hintOverrides; final SemanticsHintOverrides? hintOverrides;
/// The reading direction of the [label], [value], [hint], [increasedValue], /// The reading direction of the [label], [value], [hint], [increasedValue],
/// and [decreasedValue]. /// and [decreasedValue].
/// ///
/// Defaults to the ambient [Directionality]. /// Defaults to the ambient [Directionality].
final TextDirection textDirection; final TextDirection? textDirection;
/// Determines the position of this node among its siblings in the traversal /// Determines the position of this node among its siblings in the traversal
/// sort order. /// sort order.
...@@ -910,7 +912,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -910,7 +912,7 @@ class SemanticsProperties extends DiagnosticableTree {
/// This is used to describe the order in which the semantic node should be /// This is used to describe the order in which the semantic node should be
/// traversed by the accessibility services on the platform (e.g. VoiceOver /// traversed by the accessibility services on the platform (e.g. VoiceOver
/// on iOS and TalkBack on Android). /// on iOS and TalkBack on Android).
final SemanticsSortKey sortKey; final SemanticsSortKey? sortKey;
/// The handler for [SemanticsAction.tap]. /// The handler for [SemanticsAction.tap].
/// ///
...@@ -920,7 +922,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -920,7 +922,7 @@ class SemanticsProperties extends DiagnosticableTree {
/// ///
/// VoiceOver users on iOS and TalkBack users on Android can trigger this /// VoiceOver users on iOS and TalkBack users on Android can trigger this
/// action by double-tapping the screen while an element is focused. /// action by double-tapping the screen while an element is focused.
final VoidCallback onTap; final VoidCallback? onTap;
/// The handler for [SemanticsAction.longPress]. /// The handler for [SemanticsAction.longPress].
/// ///
...@@ -930,7 +932,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -930,7 +932,7 @@ class SemanticsProperties extends DiagnosticableTree {
/// VoiceOver users on iOS and TalkBack users on Android can trigger this /// VoiceOver users on iOS and TalkBack users on Android can trigger this
/// action by double-tapping the screen without lifting the finger after the /// action by double-tapping the screen without lifting the finger after the
/// second tap. /// second tap.
final VoidCallback onLongPress; final VoidCallback? onLongPress;
/// The handler for [SemanticsAction.scrollLeft]. /// The handler for [SemanticsAction.scrollLeft].
/// ///
...@@ -943,7 +945,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -943,7 +945,7 @@ class SemanticsProperties extends DiagnosticableTree {
/// right and then left in one motion path. On Android, [onScrollUp] and /// right and then left in one motion path. On Android, [onScrollUp] and
/// [onScrollLeft] share the same gesture. Therefore, only on of them should /// [onScrollLeft] share the same gesture. Therefore, only on of them should
/// be provided. /// be provided.
final VoidCallback onScrollLeft; final VoidCallback? onScrollLeft;
/// The handler for [SemanticsAction.scrollRight]. /// The handler for [SemanticsAction.scrollRight].
/// ///
...@@ -956,7 +958,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -956,7 +958,7 @@ class SemanticsProperties extends DiagnosticableTree {
/// left and then right in one motion path. On Android, [onScrollDown] and /// left and then right in one motion path. On Android, [onScrollDown] and
/// [onScrollRight] share the same gesture. Therefore, only on of them should /// [onScrollRight] share the same gesture. Therefore, only on of them should
/// be provided. /// be provided.
final VoidCallback onScrollRight; final VoidCallback? onScrollRight;
/// The handler for [SemanticsAction.scrollUp]. /// The handler for [SemanticsAction.scrollUp].
/// ///
...@@ -969,7 +971,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -969,7 +971,7 @@ class SemanticsProperties extends DiagnosticableTree {
/// right and then left in one motion path. On Android, [onScrollUp] and /// right and then left in one motion path. On Android, [onScrollUp] and
/// [onScrollLeft] share the same gesture. Therefore, only on of them should /// [onScrollLeft] share the same gesture. Therefore, only on of them should
/// be provided. /// be provided.
final VoidCallback onScrollUp; final VoidCallback? onScrollUp;
/// The handler for [SemanticsAction.scrollDown]. /// The handler for [SemanticsAction.scrollDown].
/// ///
...@@ -982,7 +984,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -982,7 +984,7 @@ class SemanticsProperties extends DiagnosticableTree {
/// left and then right in one motion path. On Android, [onScrollDown] and /// left and then right in one motion path. On Android, [onScrollDown] and
/// [onScrollRight] share the same gesture. Therefore, only on of them should /// [onScrollRight] share the same gesture. Therefore, only on of them should
/// be provided. /// be provided.
final VoidCallback onScrollDown; final VoidCallback? onScrollDown;
/// The handler for [SemanticsAction.increase]. /// The handler for [SemanticsAction.increase].
/// ///
...@@ -995,7 +997,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -995,7 +997,7 @@ class SemanticsProperties extends DiagnosticableTree {
/// VoiceOver users on iOS can trigger this action by swiping up with one /// VoiceOver users on iOS can trigger this action by swiping up with one
/// finger. TalkBack users on Android can trigger this action by pressing the /// finger. TalkBack users on Android can trigger this action by pressing the
/// volume up button. /// volume up button.
final VoidCallback onIncrease; final VoidCallback? onIncrease;
/// The handler for [SemanticsAction.decrease]. /// The handler for [SemanticsAction.decrease].
/// ///
...@@ -1008,7 +1010,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -1008,7 +1010,7 @@ class SemanticsProperties extends DiagnosticableTree {
/// VoiceOver users on iOS can trigger this action by swiping down with one /// VoiceOver users on iOS can trigger this action by swiping down with one
/// finger. TalkBack users on Android can trigger this action by pressing the /// finger. TalkBack users on Android can trigger this action by pressing the
/// volume down button. /// volume down button.
final VoidCallback onDecrease; final VoidCallback? onDecrease;
/// The handler for [SemanticsAction.copy]. /// The handler for [SemanticsAction.copy].
/// ///
...@@ -1016,7 +1018,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -1016,7 +1018,7 @@ class SemanticsProperties extends DiagnosticableTree {
/// ///
/// TalkBack users on Android can trigger this action from the local context /// TalkBack users on Android can trigger this action from the local context
/// menu of a text field, for example. /// menu of a text field, for example.
final VoidCallback onCopy; final VoidCallback? onCopy;
/// The handler for [SemanticsAction.cut]. /// The handler for [SemanticsAction.cut].
/// ///
...@@ -1025,7 +1027,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -1025,7 +1027,7 @@ class SemanticsProperties extends DiagnosticableTree {
/// ///
/// TalkBack users on Android can trigger this action from the local context /// TalkBack users on Android can trigger this action from the local context
/// menu of a text field, for example. /// menu of a text field, for example.
final VoidCallback onCut; final VoidCallback? onCut;
/// The handler for [SemanticsAction.paste]. /// The handler for [SemanticsAction.paste].
/// ///
...@@ -1033,7 +1035,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -1033,7 +1035,7 @@ class SemanticsProperties extends DiagnosticableTree {
/// ///
/// TalkBack users on Android can trigger this action from the local context /// TalkBack users on Android can trigger this action from the local context
/// menu of a text field, for example. /// menu of a text field, for example.
final VoidCallback onPaste; final VoidCallback? onPaste;
/// The handler for [SemanticsAction.moveCursorForwardByCharacter]. /// The handler for [SemanticsAction.moveCursorForwardByCharacter].
/// ///
...@@ -1042,7 +1044,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -1042,7 +1044,7 @@ class SemanticsProperties extends DiagnosticableTree {
/// ///
/// TalkBack users can trigger this by pressing the volume up key while the /// TalkBack users can trigger this by pressing the volume up key while the
/// input focus is in a text field. /// input focus is in a text field.
final MoveCursorHandler onMoveCursorForwardByCharacter; final MoveCursorHandler? onMoveCursorForwardByCharacter;
/// The handler for [SemanticsAction.moveCursorBackwardByCharacter]. /// The handler for [SemanticsAction.moveCursorBackwardByCharacter].
/// ///
...@@ -1051,7 +1053,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -1051,7 +1053,7 @@ class SemanticsProperties extends DiagnosticableTree {
/// ///
/// TalkBack users can trigger this by pressing the volume down key while the /// TalkBack users can trigger this by pressing the volume down key while the
/// input focus is in a text field. /// input focus is in a text field.
final MoveCursorHandler onMoveCursorBackwardByCharacter; final MoveCursorHandler? onMoveCursorBackwardByCharacter;
/// The handler for [SemanticsAction.moveCursorForwardByWord]. /// The handler for [SemanticsAction.moveCursorForwardByWord].
/// ///
...@@ -1060,7 +1062,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -1060,7 +1062,7 @@ class SemanticsProperties extends DiagnosticableTree {
/// ///
/// TalkBack users can trigger this by pressing the volume down key while the /// TalkBack users can trigger this by pressing the volume down key while the
/// input focus is in a text field. /// input focus is in a text field.
final MoveCursorHandler onMoveCursorForwardByWord; final MoveCursorHandler? onMoveCursorForwardByWord;
/// The handler for [SemanticsAction.moveCursorBackwardByWord]. /// The handler for [SemanticsAction.moveCursorBackwardByWord].
/// ///
...@@ -1069,7 +1071,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -1069,7 +1071,7 @@ class SemanticsProperties extends DiagnosticableTree {
/// ///
/// TalkBack users can trigger this by pressing the volume down key while the /// TalkBack users can trigger this by pressing the volume down key while the
/// input focus is in a text field. /// input focus is in a text field.
final MoveCursorHandler onMoveCursorBackwardByWord; final MoveCursorHandler? onMoveCursorBackwardByWord;
/// The handler for [SemanticsAction.setSelection]. /// The handler for [SemanticsAction.setSelection].
/// ///
...@@ -1078,7 +1080,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -1078,7 +1080,7 @@ class SemanticsProperties extends DiagnosticableTree {
/// ///
/// TalkBack users can trigger this handler by selecting "Move cursor to /// TalkBack users can trigger this handler by selecting "Move cursor to
/// beginning/end" or "Select all" from the local context menu. /// beginning/end" or "Select all" from the local context menu.
final SetSelectionHandler onSetSelection; final SetSelectionHandler? onSetSelection;
/// The handler for [SemanticsAction.didGainAccessibilityFocus]. /// The handler for [SemanticsAction.didGainAccessibilityFocus].
/// ///
...@@ -1097,7 +1099,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -1097,7 +1099,7 @@ class SemanticsProperties extends DiagnosticableTree {
/// * [onDidLoseAccessibilityFocus], which is invoked when the accessibility /// * [onDidLoseAccessibilityFocus], which is invoked when the accessibility
/// focus is removed from the node. /// focus is removed from the node.
/// * [FocusNode], [FocusScope], [FocusManager], which manage the input focus. /// * [FocusNode], [FocusScope], [FocusManager], which manage the input focus.
final VoidCallback onDidGainAccessibilityFocus; final VoidCallback? onDidGainAccessibilityFocus;
/// The handler for [SemanticsAction.didLoseAccessibilityFocus]. /// The handler for [SemanticsAction.didLoseAccessibilityFocus].
/// ///
...@@ -1116,7 +1118,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -1116,7 +1118,7 @@ class SemanticsProperties extends DiagnosticableTree {
/// * [onDidGainAccessibilityFocus], which is invoked when the node gains /// * [onDidGainAccessibilityFocus], which is invoked when the node gains
/// accessibility focus. /// accessibility focus.
/// * [FocusNode], [FocusScope], [FocusManager], which manage the input focus. /// * [FocusNode], [FocusScope], [FocusManager], which manage the input focus.
final VoidCallback onDidLoseAccessibilityFocus; final VoidCallback? onDidLoseAccessibilityFocus;
/// The handler for [SemanticsAction.dismiss]. /// The handler for [SemanticsAction.dismiss].
/// ///
...@@ -1125,7 +1127,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -1125,7 +1127,7 @@ class SemanticsProperties extends DiagnosticableTree {
/// TalkBack users on Android can trigger this action in the local context /// TalkBack users on Android can trigger this action in the local context
/// menu, and VoiceOver users on iOS can trigger this action with a standard /// menu, and VoiceOver users on iOS can trigger this action with a standard
/// gesture or menu option. /// gesture or menu option.
final VoidCallback onDismiss; final VoidCallback? onDismiss;
/// A map from each supported [CustomSemanticsAction] to a provided handler. /// A map from each supported [CustomSemanticsAction] to a provided handler.
/// ///
...@@ -1137,7 +1139,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -1137,7 +1139,7 @@ class SemanticsProperties extends DiagnosticableTree {
/// See also: /// See also:
/// ///
/// * [CustomSemanticsAction], for an explanation of custom actions. /// * [CustomSemanticsAction], for an explanation of custom actions.
final Map<CustomSemanticsAction, VoidCallback> customSemanticsActions; final Map<CustomSemanticsAction, VoidCallback>? customSemanticsActions;
@override @override
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
...@@ -1175,7 +1177,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -1175,7 +1177,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
/// is created. /// is created.
SemanticsNode({ SemanticsNode({
this.key, this.key,
VoidCallback showOnScreen, VoidCallback? showOnScreen,
}) : id = _generateNewId(), }) : id = _generateNewId(),
_showOnScreen = showOnScreen; _showOnScreen = showOnScreen;
...@@ -1184,8 +1186,8 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -1184,8 +1186,8 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
/// The root node is assigned an identifier of zero. /// The root node is assigned an identifier of zero.
SemanticsNode.root({ SemanticsNode.root({
this.key, this.key,
VoidCallback showOnScreen, VoidCallback? showOnScreen,
SemanticsOwner owner, required SemanticsOwner owner,
}) : id = 0, }) : id = 0,
_showOnScreen = showOnScreen { _showOnScreen = showOnScreen {
attach(owner); attach(owner);
...@@ -1209,7 +1211,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -1209,7 +1211,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
/// ///
/// Keys are used during the construction of the semantics tree. They are not /// Keys are used during the construction of the semantics tree. They are not
/// transferred to the engine. /// transferred to the engine.
final Key key; final Key? key;
/// The unique identifier for this node. /// The unique identifier for this node.
/// ///
...@@ -1217,7 +1219,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -1217,7 +1219,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
/// they are created. /// they are created.
final int id; final int id;
final VoidCallback _showOnScreen; final VoidCallback? _showOnScreen;
// GEOMETRY // GEOMETRY
...@@ -1226,11 +1228,11 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -1226,11 +1228,11 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
/// By default, the transform is null, which represents the identity /// By default, the transform is null, which represents the identity
/// transformation (i.e., that this node has the same coordinate system as its /// transformation (i.e., that this node has the same coordinate system as its
/// parent). /// parent).
Matrix4 get transform => _transform; Matrix4? get transform => _transform;
Matrix4 _transform; Matrix4? _transform;
set transform(Matrix4 value) { set transform(Matrix4? value) {
if (!MatrixUtils.matrixEquals(_transform, value)) { if (!MatrixUtils.matrixEquals(_transform, value)) {
_transform = MatrixUtils.isIdentity(value) ? null : value; _transform = value == null || MatrixUtils.isIdentity(value) ? null : value;
_markDirty(); _markDirty();
} }
} }
...@@ -1264,7 +1266,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -1264,7 +1266,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
/// If this rect is non-null it has to completely enclose /// If this rect is non-null it has to completely enclose
/// [parentPaintClipRect]. If [parentPaintClipRect] is null this property is /// [parentPaintClipRect]. If [parentPaintClipRect] is null this property is
/// also null. /// also null.
Rect parentSemanticsClipRect; Rect? parentSemanticsClipRect;
/// The paint clip from an ancestor that was applied to this node. /// The paint clip from an ancestor that was applied to this node.
/// ///
...@@ -1279,7 +1281,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -1279,7 +1281,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
/// This rect is completely enclosed by [parentSemanticsClipRect]. /// This rect is completely enclosed by [parentSemanticsClipRect].
/// ///
/// If this rect is null [parentSemanticsClipRect] also has to be null. /// If this rect is null [parentSemanticsClipRect] also has to be null.
Rect parentPaintClipRect; Rect? parentPaintClipRect;
/// The elevation adjustment that the parent imposes on this node. /// The elevation adjustment that the parent imposes on this node.
/// ///
...@@ -1296,7 +1298,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -1296,7 +1298,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
/// See also: /// See also:
/// ///
/// * [elevation], the actual elevation of this [SemanticsNode]. /// * [elevation], the actual elevation of this [SemanticsNode].
double elevationAdjustment; double? elevationAdjustment;
/// The index of this node within the parent's list of semantic children. /// The index of this node within the parent's list of semantic children.
/// ///
...@@ -1304,7 +1306,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -1304,7 +1306,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
/// child list. For example, if a scrollable has five children but the first /// child list. For example, if a scrollable has five children but the first
/// two are not visible (and thus not included in the list of children), then /// two are not visible (and thus not included in the list of children), then
/// the index of the last node will still be 4. /// the index of the last node will still be 4.
int indexInParent; int? indexInParent;
/// Whether the node is invisible. /// Whether the node is invisible.
/// ///
...@@ -1350,12 +1352,12 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -1350,12 +1352,12 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
// CHILDREN // CHILDREN
/// Contains the children in inverse hit test order (i.e. paint order). /// Contains the children in inverse hit test order (i.e. paint order).
List<SemanticsNode> _children; List<SemanticsNode>? _children;
/// A snapshot of `newChildren` passed to [_replaceChildren] that we keep in /// A snapshot of `newChildren` passed to [_replaceChildren] that we keep in
/// debug mode. It supports the assertion that user does not mutate the list /// debug mode. It supports the assertion that user does not mutate the list
/// of children. /// of children.
List<SemanticsNode> _debugPreviousSnapshot; late List<SemanticsNode> _debugPreviousSnapshot;
void _replaceChildren(List<SemanticsNode> newChildren) { void _replaceChildren(List<SemanticsNode> newChildren) {
assert(!newChildren.any((SemanticsNode child) => child == this)); assert(!newChildren.any((SemanticsNode child) => child == this));
...@@ -1394,7 +1396,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -1394,7 +1396,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
SemanticsNode ancestor = this; SemanticsNode ancestor = this;
while (ancestor.parent is SemanticsNode) while (ancestor.parent is SemanticsNode)
ancestor = ancestor.parent; ancestor = ancestor.parent!;
assert(!newChildren.any((SemanticsNode child) => child == ancestor)); assert(!newChildren.any((SemanticsNode child) => child == ancestor));
return true; return true;
}()); }());
...@@ -1407,7 +1409,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -1407,7 +1409,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
// The goal of this function is updating sawChange. // The goal of this function is updating sawChange.
if (_children != null) { if (_children != null) {
for (final SemanticsNode child in _children) for (final SemanticsNode child in _children!)
child._dead = true; child._dead = true;
} }
if (newChildren != null) { if (newChildren != null) {
...@@ -1418,7 +1420,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -1418,7 +1420,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
} }
bool sawChange = false; bool sawChange = false;
if (_children != null) { if (_children != null) {
for (final SemanticsNode child in _children) { for (final SemanticsNode child in _children!) {
if (child._dead) { if (child._dead) {
if (child.parent == this) { if (child.parent == this) {
// we might have already had our child stolen from us by // we might have already had our child stolen from us by
...@@ -1448,10 +1450,10 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -1448,10 +1450,10 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
} }
if (!sawChange && _children != null) { if (!sawChange && _children != null) {
assert(newChildren != null); assert(newChildren != null);
assert(newChildren.length == _children.length); assert(newChildren.length == _children!.length);
// Did the order change? // Did the order change?
for (int i = 0; i < _children.length; i++) { for (int i = 0; i < _children!.length; i++) {
if (_children[i].id != newChildren[i].id) { if (_children![i].id != newChildren[i].id) {
sawChange = true; sawChange = true;
break; break;
} }
...@@ -1467,7 +1469,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -1467,7 +1469,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
bool _dead = false; bool _dead = false;
/// The number of children this node has. /// The number of children this node has.
int get childrenCount => hasChildren ? _children.length : 0; int get childrenCount => hasChildren ? _children!.length : 0;
/// Visits the immediate children of this node. /// Visits the immediate children of this node.
/// ///
...@@ -1476,7 +1478,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -1476,7 +1478,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
/// returns false. /// returns false.
void visitChildren(SemanticsNodeVisitor visitor) { void visitChildren(SemanticsNodeVisitor visitor) {
if (_children != null) { if (_children != null) {
for (final SemanticsNode child in _children) { for (final SemanticsNode child in _children!) {
if (!visitor(child)) if (!visitor(child))
return; return;
} }
...@@ -1490,7 +1492,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -1490,7 +1492,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
/// returned true, otherwise returns false. /// returned true, otherwise returns false.
bool _visitDescendants(SemanticsNodeVisitor visitor) { bool _visitDescendants(SemanticsNodeVisitor visitor) {
if (_children != null) { if (_children != null) {
for (final SemanticsNode child in _children) { for (final SemanticsNode child in _children!) {
if (!visitor(child) || !child._visitDescendants(visitor)) if (!visitor(child) || !child._visitDescendants(visitor))
return false; return false;
} }
...@@ -1501,10 +1503,10 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -1501,10 +1503,10 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
// AbstractNode OVERRIDES // AbstractNode OVERRIDES
@override @override
SemanticsOwner get owner => super.owner as SemanticsOwner; SemanticsOwner? get owner => super.owner as SemanticsOwner?;
@override @override
SemanticsNode get parent => super.parent as SemanticsNode; SemanticsNode? get parent => super.parent as SemanticsNode?;
@override @override
void redepthChildren() { void redepthChildren() {
...@@ -1522,21 +1524,21 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -1522,21 +1524,21 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
_markDirty(); _markDirty();
} }
if (_children != null) { if (_children != null) {
for (final SemanticsNode child in _children) for (final SemanticsNode child in _children!)
child.attach(owner); child.attach(owner);
} }
} }
@override @override
void detach() { void detach() {
assert(owner._nodes.containsKey(id)); assert(owner!._nodes.containsKey(id));
assert(!owner._detachedNodes.contains(this)); assert(!owner!._detachedNodes.contains(this));
owner._nodes.remove(id); owner!._nodes.remove(id);
owner._detachedNodes.add(this); owner!._detachedNodes.add(this);
super.detach(); super.detach();
assert(owner == null); assert(owner == null);
if (_children != null) { if (_children != null) {
for (final SemanticsNode child in _children) { for (final SemanticsNode child in _children!) {
// The list of children may be stale and may contain nodes that have // The list of children may be stale and may contain nodes that have
// been assigned to a different parent. // been assigned to a different parent.
if (child.parent == this) if (child.parent == this)
...@@ -1557,8 +1559,8 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -1557,8 +1559,8 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
return; return;
_dirty = true; _dirty = true;
if (attached) { if (attached) {
assert(!owner._detachedNodes.contains(this)); assert(!owner!._detachedNodes.contains(this));
owner._dirtyNodes.add(this); owner!._dirtyNodes.add(this);
} }
} }
...@@ -1596,10 +1598,10 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -1596,10 +1598,10 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
/// ///
/// Tags are used during the construction of the semantics tree. They are not /// Tags are used during the construction of the semantics tree. They are not
/// transferred to the engine. /// transferred to the engine.
Set<SemanticsTag> tags; Set<SemanticsTag>? tags;
/// Whether this node is tagged with `tag`. /// Whether this node is tagged with `tag`.
bool isTagged(SemanticsTag tag) => tags != null && tags.contains(tag); bool isTagged(SemanticsTag tag) => tags != null && tags!.contains(tag);
int _flags = _kEmptyConfig._flags; int _flags = _kEmptyConfig._flags;
...@@ -1712,13 +1714,13 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -1712,13 +1714,13 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
/// Provides hint values which override the default hints on supported /// Provides hint values which override the default hints on supported
/// platforms. /// platforms.
SemanticsHintOverrides get hintOverrides => _hintOverrides; SemanticsHintOverrides? get hintOverrides => _hintOverrides;
SemanticsHintOverrides _hintOverrides; SemanticsHintOverrides? _hintOverrides;
/// The reading direction for [label], [value], [hint], [increasedValue], and /// The reading direction for [label], [value], [hint], [increasedValue], and
/// [decreasedValue]. /// [decreasedValue].
TextDirection get textDirection => _textDirection; TextDirection? get textDirection => _textDirection;
TextDirection _textDirection = _kEmptyConfig.textDirection; TextDirection? _textDirection = _kEmptyConfig.textDirection;
/// Determines the position of this node among its siblings in the traversal /// Determines the position of this node among its siblings in the traversal
/// sort order. /// sort order.
...@@ -1726,29 +1728,29 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -1726,29 +1728,29 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
/// This is used to describe the order in which the semantic node should be /// This is used to describe the order in which the semantic node should be
/// traversed by the accessibility services on the platform (e.g. VoiceOver /// traversed by the accessibility services on the platform (e.g. VoiceOver
/// on iOS and TalkBack on Android). /// on iOS and TalkBack on Android).
SemanticsSortKey get sortKey => _sortKey; SemanticsSortKey? get sortKey => _sortKey;
SemanticsSortKey _sortKey; SemanticsSortKey? _sortKey;
/// The currently selected text (or the position of the cursor) within [value] /// The currently selected text (or the position of the cursor) within [value]
/// if this node represents a text field. /// if this node represents a text field.
TextSelection get textSelection => _textSelection; TextSelection? get textSelection => _textSelection;
TextSelection _textSelection; TextSelection? _textSelection;
/// If this node represents a text field, this indicates whether or not it's /// If this node represents a text field, this indicates whether or not it's
/// a multiline text field. /// a multiline text field.
bool get isMultiline => _isMultiline; bool? get isMultiline => _isMultiline;
bool _isMultiline; bool? _isMultiline;
/// The total number of scrollable children that contribute to semantics. /// The total number of scrollable children that contribute to semantics.
/// ///
/// If the number of children are unknown or unbounded, this value will be /// If the number of children are unknown or unbounded, this value will be
/// null. /// null.
int get scrollChildCount => _scrollChildCount; int? get scrollChildCount => _scrollChildCount;
int _scrollChildCount; int? _scrollChildCount;
/// The index of the first visible semantic child of a scroll node. /// The index of the first visible semantic child of a scroll node.
int get scrollIndex => _scrollIndex; int? get scrollIndex => _scrollIndex;
int _scrollIndex; int? _scrollIndex;
/// Indicates the current scrolling position in logical pixels if the node is /// Indicates the current scrolling position in logical pixels if the node is
/// scrollable. /// scrollable.
...@@ -1760,8 +1762,8 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -1760,8 +1762,8 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
/// See also: /// See also:
/// ///
/// * [ScrollPosition.pixels], from where this value is usually taken. /// * [ScrollPosition.pixels], from where this value is usually taken.
double get scrollPosition => _scrollPosition; double? get scrollPosition => _scrollPosition;
double _scrollPosition; double? _scrollPosition;
/// Indicates the maximum in-range value for [scrollPosition] if the node is /// Indicates the maximum in-range value for [scrollPosition] if the node is
/// scrollable. /// scrollable.
...@@ -1771,8 +1773,8 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -1771,8 +1773,8 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
/// See also: /// See also:
/// ///
/// * [ScrollPosition.maxScrollExtent], from where this value is usually taken. /// * [ScrollPosition.maxScrollExtent], from where this value is usually taken.
double get scrollExtentMax => _scrollExtentMax; double? get scrollExtentMax => _scrollExtentMax;
double _scrollExtentMax; double? _scrollExtentMax;
/// Indicates the minimum in-range value for [scrollPosition] if the node is /// Indicates the minimum in-range value for [scrollPosition] if the node is
/// scrollable. /// scrollable.
...@@ -1782,8 +1784,8 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -1782,8 +1784,8 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
/// See also: /// See also:
/// ///
/// * [ScrollPosition.minScrollExtent] from where this value is usually taken. /// * [ScrollPosition.minScrollExtent] from where this value is usually taken.
double get scrollExtentMin => _scrollExtentMin; double? get scrollExtentMin => _scrollExtentMin;
double _scrollExtentMin; double? _scrollExtentMin;
/// The id of the platform view, whose semantics nodes will be added as /// The id of the platform view, whose semantics nodes will be added as
/// children to this node. /// children to this node.
...@@ -1796,8 +1798,8 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -1796,8 +1798,8 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
/// ///
/// * [AndroidView], which is the platform view for Android. /// * [AndroidView], which is the platform view for Android.
/// * [UiKitView], which is the platform view for iOS. /// * [UiKitView], which is the platform view for iOS.
int get platformViewId => _platformViewId; int? get platformViewId => _platformViewId;
int _platformViewId; int? _platformViewId;
/// The maximum number of characters that can be entered into an editable /// The maximum number of characters that can be entered into an editable
/// text field. /// text field.
...@@ -1807,8 +1809,8 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -1807,8 +1809,8 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
/// ///
/// This should only be set when [SemanticsFlag.isTextField] is set. Defaults /// This should only be set when [SemanticsFlag.isTextField] is set. Defaults
/// to null, which means no limit is imposed on the text field. /// to null, which means no limit is imposed on the text field.
int get maxValueLength => _maxValueLength; int? get maxValueLength => _maxValueLength;
int _maxValueLength; int? _maxValueLength;
/// The current number of characters that have been entered into an editable /// The current number of characters that have been entered into an editable
/// text field. /// text field.
...@@ -1818,8 +1820,8 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -1818,8 +1820,8 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
/// ///
/// This should only be set when [SemanticsFlag.isTextField] is set. Must be /// This should only be set when [SemanticsFlag.isTextField] is set. Must be
/// set when [maxValueLength] is set. /// set when [maxValueLength] is set.
int get currentValueLength => _currentValueLength; int? get currentValueLength => _currentValueLength;
int _currentValueLength; int? _currentValueLength;
bool _canPerformAction(SemanticsAction action) => _actions.containsKey(action); bool _canPerformAction(SemanticsAction action) => _actions.containsKey(action);
...@@ -1835,15 +1837,15 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -1835,15 +1837,15 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
/// No reference is kept to the [SemanticsConfiguration] object, but the child /// No reference is kept to the [SemanticsConfiguration] object, but the child
/// list is used as-is and should therefore not be changed after this call. /// list is used as-is and should therefore not be changed after this call.
void updateWith({ void updateWith({
@required SemanticsConfiguration config, required SemanticsConfiguration? config,
List<SemanticsNode> childrenInInversePaintOrder, List<SemanticsNode>? childrenInInversePaintOrder,
}) { }) {
config ??= _kEmptyConfig; config ??= _kEmptyConfig;
if (_isDifferentFromCurrentSemanticAnnotation(config)) if (_isDifferentFromCurrentSemanticAnnotation(config))
_markDirty(); _markDirty();
assert( assert(
config.platformViewId == null || childrenInInversePaintOrder.isEmpty, config.platformViewId == null || childrenInInversePaintOrder == null || childrenInInversePaintOrder.isEmpty,
'SemanticsNodes with children must not specify a platformViewId.' 'SemanticsNodes with children must not specify a platformViewId.'
); );
...@@ -1899,33 +1901,33 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -1899,33 +1901,33 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
String value = _value; String value = _value;
String increasedValue = _increasedValue; String increasedValue = _increasedValue;
String decreasedValue = _decreasedValue; String decreasedValue = _decreasedValue;
TextDirection textDirection = _textDirection; TextDirection? textDirection = _textDirection;
Set<SemanticsTag> mergedTags = tags == null ? null : Set<SemanticsTag>.from(tags); Set<SemanticsTag>? mergedTags = tags == null ? null : Set<SemanticsTag>.from(tags!);
TextSelection textSelection = _textSelection; TextSelection? textSelection = _textSelection;
int scrollChildCount = _scrollChildCount; int? scrollChildCount = _scrollChildCount;
int scrollIndex = _scrollIndex; int? scrollIndex = _scrollIndex;
double scrollPosition = _scrollPosition; double? scrollPosition = _scrollPosition;
double scrollExtentMax = _scrollExtentMax; double? scrollExtentMax = _scrollExtentMax;
double scrollExtentMin = _scrollExtentMin; double? scrollExtentMin = _scrollExtentMin;
int platformViewId = _platformViewId; int? platformViewId = _platformViewId;
int maxValueLength = _maxValueLength; int? maxValueLength = _maxValueLength;
int currentValueLength = _currentValueLength; int? currentValueLength = _currentValueLength;
final double elevation = _elevation; final double elevation = _elevation;
double thickness = _thickness; double thickness = _thickness;
final Set<int> customSemanticsActionIds = <int>{}; final Set<int> customSemanticsActionIds = <int>{};
for (final CustomSemanticsAction action in _customSemanticsActions.keys) for (final CustomSemanticsAction action in _customSemanticsActions.keys)
customSemanticsActionIds.add(CustomSemanticsAction.getIdentifier(action)); customSemanticsActionIds.add(CustomSemanticsAction.getIdentifier(action));
if (hintOverrides != null) { if (hintOverrides != null) {
if (hintOverrides.onTapHint != null) { if (hintOverrides!.onTapHint != null) {
final CustomSemanticsAction action = CustomSemanticsAction.overridingAction( final CustomSemanticsAction action = CustomSemanticsAction.overridingAction(
hint: hintOverrides.onTapHint, hint: hintOverrides!.onTapHint!,
action: SemanticsAction.tap, action: SemanticsAction.tap,
); );
customSemanticsActionIds.add(CustomSemanticsAction.getIdentifier(action)); customSemanticsActionIds.add(CustomSemanticsAction.getIdentifier(action));
} }
if (hintOverrides.onLongPressHint != null) { if (hintOverrides!.onLongPressHint != null) {
final CustomSemanticsAction action = CustomSemanticsAction.overridingAction( final CustomSemanticsAction action = CustomSemanticsAction.overridingAction(
hint: hintOverrides.onLongPressHint, hint: hintOverrides!.onLongPressHint!,
action: SemanticsAction.longPress, action: SemanticsAction.longPress,
); );
customSemanticsActionIds.add(CustomSemanticsAction.getIdentifier(action)); customSemanticsActionIds.add(CustomSemanticsAction.getIdentifier(action));
...@@ -1955,23 +1957,23 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -1955,23 +1957,23 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
decreasedValue = node._decreasedValue; decreasedValue = node._decreasedValue;
if (node.tags != null) { if (node.tags != null) {
mergedTags ??= <SemanticsTag>{}; mergedTags ??= <SemanticsTag>{};
mergedTags.addAll(node.tags); mergedTags!.addAll(node.tags!);
} }
if (node._customSemanticsActions != null) { if (node._customSemanticsActions != null) {
for (final CustomSemanticsAction action in _customSemanticsActions.keys) for (final CustomSemanticsAction action in _customSemanticsActions.keys)
customSemanticsActionIds.add(CustomSemanticsAction.getIdentifier(action)); customSemanticsActionIds.add(CustomSemanticsAction.getIdentifier(action));
} }
if (node.hintOverrides != null) { if (node.hintOverrides != null) {
if (node.hintOverrides.onTapHint != null) { if (node.hintOverrides!.onTapHint != null) {
final CustomSemanticsAction action = CustomSemanticsAction.overridingAction( final CustomSemanticsAction action = CustomSemanticsAction.overridingAction(
hint: node.hintOverrides.onTapHint, hint: node.hintOverrides!.onTapHint!,
action: SemanticsAction.tap, action: SemanticsAction.tap,
); );
customSemanticsActionIds.add(CustomSemanticsAction.getIdentifier(action)); customSemanticsActionIds.add(CustomSemanticsAction.getIdentifier(action));
} }
if (node.hintOverrides.onLongPressHint != null) { if (node.hintOverrides!.onLongPressHint != null) {
final CustomSemanticsAction action = CustomSemanticsAction.overridingAction( final CustomSemanticsAction action = CustomSemanticsAction.overridingAction(
hint: node.hintOverrides.onLongPressHint, hint: node.hintOverrides!.onLongPressHint!,
action: SemanticsAction.longPress, action: SemanticsAction.longPress,
); );
customSemanticsActionIds.add(CustomSemanticsAction.getIdentifier(action)); customSemanticsActionIds.add(CustomSemanticsAction.getIdentifier(action));
...@@ -2040,7 +2042,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -2040,7 +2042,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
childrenInTraversalOrder = _kEmptyChildList; childrenInTraversalOrder = _kEmptyChildList;
childrenInHitTestOrder = _kEmptyChildList; childrenInHitTestOrder = _kEmptyChildList;
} else { } else {
final int childCount = _children.length; final int childCount = _children!.length;
final List<SemanticsNode> sortedChildren = _childrenInTraversalOrder(); final List<SemanticsNode> sortedChildren = _childrenInTraversalOrder();
childrenInTraversalOrder = Int32List(childCount); childrenInTraversalOrder = Int32List(childCount);
for (int i = 0; i < childCount; i += 1) { for (int i = 0; i < childCount; i += 1) {
...@@ -2050,15 +2052,15 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -2050,15 +2052,15 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
// order. // order.
childrenInHitTestOrder = Int32List(childCount); childrenInHitTestOrder = Int32List(childCount);
for (int i = childCount - 1; i >= 0; i -= 1) { for (int i = childCount - 1; i >= 0; i -= 1) {
childrenInHitTestOrder[i] = _children[childCount - i - 1].id; childrenInHitTestOrder[i] = _children![childCount - i - 1].id;
} }
} }
Int32List customSemanticsActionIds; Int32List? customSemanticsActionIds;
if (data.customSemanticsActionIds?.isNotEmpty == true) { if (data.customSemanticsActionIds?.isNotEmpty == true) {
customSemanticsActionIds = Int32List(data.customSemanticsActionIds.length); customSemanticsActionIds = Int32List(data.customSemanticsActionIds!.length);
for (int i = 0; i < data.customSemanticsActionIds.length; i++) { for (int i = 0; i < data.customSemanticsActionIds!.length; i++) {
customSemanticsActionIds[i] = data.customSemanticsActionIds[i]; customSemanticsActionIds[i] = data.customSemanticsActionIds![i];
customSemanticsActionIdsUpdate.add(data.customSemanticsActionIds[i]); customSemanticsActionIdsUpdate.add(data.customSemanticsActionIds![i]);
} }
} }
builder.updateNode( builder.updateNode(
...@@ -2072,8 +2074,8 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -2072,8 +2074,8 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
increasedValue: data.increasedValue, increasedValue: data.increasedValue,
hint: data.hint, hint: data.hint,
textDirection: data.textDirection, textDirection: data.textDirection,
textSelectionBase: data.textSelection != null ? data.textSelection.baseOffset : -1, textSelectionBase: data.textSelection != null ? data.textSelection!.baseOffset : -1,
textSelectionExtent: data.textSelection != null ? data.textSelection.extentOffset : -1, textSelectionExtent: data.textSelection != null ? data.textSelection!.extentOffset : -1,
platformViewId: data.platformViewId ?? -1, platformViewId: data.platformViewId ?? -1,
maxValueLength: data.maxValueLength ?? -1, maxValueLength: data.maxValueLength ?? -1,
currentValueLength: data.currentValueLength ?? -1, currentValueLength: data.currentValueLength ?? -1,
...@@ -2094,16 +2096,16 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -2094,16 +2096,16 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
/// Builds a new list made of [_children] sorted in semantic traversal order. /// Builds a new list made of [_children] sorted in semantic traversal order.
List<SemanticsNode> _childrenInTraversalOrder() { List<SemanticsNode> _childrenInTraversalOrder() {
TextDirection inheritedTextDirection = textDirection; TextDirection? inheritedTextDirection = textDirection;
SemanticsNode ancestor = parent; SemanticsNode? ancestor = parent;
while (inheritedTextDirection == null && ancestor != null) { while (inheritedTextDirection == null && ancestor != null) {
inheritedTextDirection = ancestor.textDirection; inheritedTextDirection = ancestor.textDirection;
ancestor = ancestor.parent; ancestor = ancestor.parent;
} }
List<SemanticsNode> childrenInDefaultOrder; List<SemanticsNode>? childrenInDefaultOrder;
if (inheritedTextDirection != null) { if (inheritedTextDirection != null) {
childrenInDefaultOrder = _childrenInDefaultOrder(_children, inheritedTextDirection); childrenInDefaultOrder = _childrenInDefaultOrder(_children!, inheritedTextDirection);
} else { } else {
// In the absence of text direction default to paint order. // In the absence of text direction default to paint order.
childrenInDefaultOrder = _children; childrenInDefaultOrder = _children;
...@@ -2115,16 +2117,16 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -2115,16 +2117,16 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
// the same place. Only children within the same group are sorted. // the same place. Only children within the same group are sorted.
final List<_TraversalSortNode> everythingSorted = <_TraversalSortNode>[]; final List<_TraversalSortNode> everythingSorted = <_TraversalSortNode>[];
final List<_TraversalSortNode> sortNodes = <_TraversalSortNode>[]; final List<_TraversalSortNode> sortNodes = <_TraversalSortNode>[];
SemanticsSortKey lastSortKey; SemanticsSortKey? lastSortKey;
for (int position = 0; position < childrenInDefaultOrder.length; position += 1) { for (int position = 0; position < childrenInDefaultOrder!.length; position += 1) {
final SemanticsNode child = childrenInDefaultOrder[position]; final SemanticsNode child = childrenInDefaultOrder[position];
final SemanticsSortKey sortKey = child.sortKey; final SemanticsSortKey? sortKey = child.sortKey;
lastSortKey = position > 0 lastSortKey = position > 0
? childrenInDefaultOrder[position - 1].sortKey ? childrenInDefaultOrder[position - 1].sortKey
: null; : null;
final bool isCompatibleWithPreviousSortKey = position == 0 || final bool isCompatibleWithPreviousSortKey = position == 0 ||
sortKey.runtimeType == lastSortKey.runtimeType && sortKey.runtimeType == lastSortKey.runtimeType &&
(sortKey == null || sortKey.name == lastSortKey.name); (sortKey == null || sortKey.name == lastSortKey!.name);
if (!isCompatibleWithPreviousSortKey && sortNodes.isNotEmpty) { if (!isCompatibleWithPreviousSortKey && sortNodes.isNotEmpty) {
// Do not sort groups with null sort keys. List.sort does not guarantee // Do not sort groups with null sort keys. List.sort does not guarantee
// a stable sort order. // a stable sort order.
...@@ -2172,22 +2174,22 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -2172,22 +2174,22 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
super.debugFillProperties(properties); super.debugFillProperties(properties);
bool hideOwner = true; bool hideOwner = true;
if (_dirty) { if (_dirty) {
final bool inDirtyNodes = owner != null && owner._dirtyNodes.contains(this); final bool inDirtyNodes = owner != null && owner!._dirtyNodes.contains(this);
properties.add(FlagProperty('inDirtyNodes', value: inDirtyNodes, ifTrue: 'dirty', ifFalse: 'STALE')); properties.add(FlagProperty('inDirtyNodes', value: inDirtyNodes, ifTrue: 'dirty', ifFalse: 'STALE'));
hideOwner = inDirtyNodes; hideOwner = inDirtyNodes;
} }
properties.add(DiagnosticsProperty<SemanticsOwner>('owner', owner, level: hideOwner ? DiagnosticLevel.hidden : DiagnosticLevel.info)); properties.add(DiagnosticsProperty<SemanticsOwner>('owner', owner, level: hideOwner ? DiagnosticLevel.hidden : DiagnosticLevel.info));
properties.add(FlagProperty('isMergedIntoParent', value: isMergedIntoParent, ifTrue: 'merged up ⬆️')); properties.add(FlagProperty('isMergedIntoParent', value: isMergedIntoParent, ifTrue: 'merged up ⬆️'));
properties.add(FlagProperty('mergeAllDescendantsIntoThisNode', value: mergeAllDescendantsIntoThisNode, ifTrue: 'merge boundary ⛔️')); properties.add(FlagProperty('mergeAllDescendantsIntoThisNode', value: mergeAllDescendantsIntoThisNode, ifTrue: 'merge boundary ⛔️'));
final Offset offset = transform != null ? MatrixUtils.getAsTranslation(transform) : null; final Offset? offset = transform != null ? MatrixUtils.getAsTranslation(transform!) : null;
if (offset != null) { if (offset != null) {
properties.add(DiagnosticsProperty<Rect>('rect', rect.shift(offset), showName: false)); properties.add(DiagnosticsProperty<Rect>('rect', rect.shift(offset), showName: false));
} else { } else {
final double scale = transform != null ? MatrixUtils.getAsScale(transform) : null; final double? scale = transform != null ? MatrixUtils.getAsScale(transform!) : null;
String description; String? description;
if (scale != null) { if (scale != null) {
description = '$rect scaled by ${scale.toStringAsFixed(1)}x'; description = '$rect scaled by ${scale.toStringAsFixed(1)}x';
} else if (transform != null && !MatrixUtils.isIdentity(transform)) { } else if (transform != null && !MatrixUtils.isIdentity(transform!)) {
final String matrix = transform.toString().split('\n').take(4).map<String>((String line) => line.substring(4)).join('; '); final String matrix = transform.toString().split('\n').take(4).map<String>((String line) => line.substring(4)).join('; ');
description = '$rect with transform [$matrix]'; description = '$rect with transform [$matrix]';
} }
...@@ -2195,11 +2197,11 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -2195,11 +2197,11 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
} }
properties.add(IterableProperty<String>('tags', tags?.map((SemanticsTag tag) => tag.name), defaultValue: null)); properties.add(IterableProperty<String>('tags', tags?.map((SemanticsTag tag) => tag.name), defaultValue: null));
final List<String> actions = _actions.keys.map<String>((SemanticsAction action) => describeEnum(action)).toList()..sort(); final List<String> actions = _actions.keys.map<String>((SemanticsAction action) => describeEnum(action)).toList()..sort();
final List<String> customSemanticsActions = _customSemanticsActions.keys final List<String?> customSemanticsActions = _customSemanticsActions.keys
.map<String>((CustomSemanticsAction action) => action.label) .map<String?>((CustomSemanticsAction action) => action.label)
.toList(); .toList();
properties.add(IterableProperty<String>('actions', actions, ifEmpty: null)); properties.add(IterableProperty<String>('actions', actions, ifEmpty: null));
properties.add(IterableProperty<String>('customActions', customSemanticsActions, ifEmpty: null)); properties.add(IterableProperty<String?>('customActions', customSemanticsActions, ifEmpty: null));
final List<String> flags = SemanticsFlag.values.values.where((SemanticsFlag flag) => hasFlag(flag)).map((SemanticsFlag flag) => flag.toString().substring('SemanticsFlag.'.length)).toList(); final List<String> flags = SemanticsFlag.values.values.where((SemanticsFlag flag) => hasFlag(flag)).map((SemanticsFlag flag) => flag.toString().substring('SemanticsFlag.'.length)).toList();
properties.add(IterableProperty<String>('flags', flags, ifEmpty: null)); properties.add(IterableProperty<String>('flags', flags, ifEmpty: null));
properties.add(FlagProperty('isInvisible', value: isInvisible, ifTrue: 'invisible')); properties.add(FlagProperty('isInvisible', value: isInvisible, ifTrue: 'invisible'));
...@@ -2212,7 +2214,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -2212,7 +2214,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
properties.add(EnumProperty<TextDirection>('textDirection', _textDirection, defaultValue: null)); properties.add(EnumProperty<TextDirection>('textDirection', _textDirection, defaultValue: null));
properties.add(DiagnosticsProperty<SemanticsSortKey>('sortKey', sortKey, defaultValue: null)); properties.add(DiagnosticsProperty<SemanticsSortKey>('sortKey', sortKey, defaultValue: null));
if (_textSelection?.isValid == true) if (_textSelection?.isValid == true)
properties.add(MessageProperty('text selection', '[${_textSelection.start}, ${_textSelection.end}]')); properties.add(MessageProperty('text selection', '[${_textSelection!.start}, ${_textSelection!.end}]'));
properties.add(IntProperty('platformViewId', platformViewId, defaultValue: null)); properties.add(IntProperty('platformViewId', platformViewId, defaultValue: null));
properties.add(IntProperty('maxValueLength', maxValueLength, defaultValue: null)); properties.add(IntProperty('maxValueLength', maxValueLength, defaultValue: null));
properties.add(IntProperty('currentValueLength', currentValueLength, defaultValue: null)); properties.add(IntProperty('currentValueLength', currentValueLength, defaultValue: null));
...@@ -2232,7 +2234,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -2232,7 +2234,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
@override @override
String toStringDeep({ String toStringDeep({
String prefixLineOne = '', String prefixLineOne = '',
String prefixOtherLines, String? prefixOtherLines,
DiagnosticLevel minLevel = DiagnosticLevel.debug, DiagnosticLevel minLevel = DiagnosticLevel.debug,
DebugSemanticsDumpOrder childOrder = DebugSemanticsDumpOrder.traversalOrder, DebugSemanticsDumpOrder childOrder = DebugSemanticsDumpOrder.traversalOrder,
}) { }) {
...@@ -2242,8 +2244,8 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -2242,8 +2244,8 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
@override @override
DiagnosticsNode toDiagnosticsNode({ DiagnosticsNode toDiagnosticsNode({
String name, String? name,
DiagnosticsTreeStyle style = DiagnosticsTreeStyle.sparse, DiagnosticsTreeStyle? style = DiagnosticsTreeStyle.sparse,
DebugSemanticsDumpOrder childOrder = DebugSemanticsDumpOrder.traversalOrder, DebugSemanticsDumpOrder childOrder = DebugSemanticsDumpOrder.traversalOrder,
}) { }) {
return _SemanticsDiagnosticableNode( return _SemanticsDiagnosticableNode(
...@@ -2269,12 +2271,10 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -2269,12 +2271,10 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
switch (childOrder) { switch (childOrder) {
case DebugSemanticsDumpOrder.inverseHitTest: case DebugSemanticsDumpOrder.inverseHitTest:
return _children; return _children!;
case DebugSemanticsDumpOrder.traversalOrder: case DebugSemanticsDumpOrder.traversalOrder:
return _childrenInTraversalOrder(); return _childrenInTraversalOrder();
} }
assert(false);
return null;
} }
} }
...@@ -2288,9 +2288,9 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin { ...@@ -2288,9 +2288,9 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
/// for each [SemanticsNode], one for the top and one for the bottom edge. /// for each [SemanticsNode], one for the top and one for the bottom edge.
class _BoxEdge implements Comparable<_BoxEdge> { class _BoxEdge implements Comparable<_BoxEdge> {
_BoxEdge({ _BoxEdge({
@required this.isLeadingEdge, required this.isLeadingEdge,
@required this.offset, required this.offset,
@required this.node, required this.node,
}) : assert(isLeadingEdge != null), }) : assert(isLeadingEdge != null),
assert(offset != null), assert(offset != null),
assert(offset.isFinite), assert(offset.isFinite),
...@@ -2326,8 +2326,8 @@ class _BoxEdge implements Comparable<_BoxEdge> { ...@@ -2326,8 +2326,8 @@ class _BoxEdge implements Comparable<_BoxEdge> {
/// The [nodes] are sorted among each other separately from other nodes. /// The [nodes] are sorted among each other separately from other nodes.
class _SemanticsSortGroup extends Comparable<_SemanticsSortGroup> { class _SemanticsSortGroup extends Comparable<_SemanticsSortGroup> {
_SemanticsSortGroup({ _SemanticsSortGroup({
@required this.startOffset, required this.startOffset,
@required this.textDirection, required this.textDirection,
}) : assert(startOffset != null); }) : assert(startOffset != null);
/// The offset from the start edge of the parent [SemanticsNode] in the /// The offset from the start edge of the parent [SemanticsNode] in the
...@@ -2370,7 +2370,7 @@ class _SemanticsSortGroup extends Comparable<_SemanticsSortGroup> { ...@@ -2370,7 +2370,7 @@ class _SemanticsSortGroup extends Comparable<_SemanticsSortGroup> {
edges.sort(); edges.sort();
List<_SemanticsSortGroup> horizontalGroups = <_SemanticsSortGroup>[]; List<_SemanticsSortGroup> horizontalGroups = <_SemanticsSortGroup>[];
_SemanticsSortGroup group; _SemanticsSortGroup? group;
int depth = 0; int depth = 0;
for (final _BoxEdge edge in edges) { for (final _BoxEdge edge in edges) {
if (edge.isLeadingEdge) { if (edge.isLeadingEdge) {
...@@ -2384,7 +2384,7 @@ class _SemanticsSortGroup extends Comparable<_SemanticsSortGroup> { ...@@ -2384,7 +2384,7 @@ class _SemanticsSortGroup extends Comparable<_SemanticsSortGroup> {
depth -= 1; depth -= 1;
} }
if (depth == 0) { if (depth == 0) {
horizontalGroups.add(group); horizontalGroups.add(group!);
group = null; group = null;
} }
} }
...@@ -2463,13 +2463,13 @@ class _SemanticsSortGroup extends Comparable<_SemanticsSortGroup> { ...@@ -2463,13 +2463,13 @@ class _SemanticsSortGroup extends Comparable<_SemanticsSortGroup> {
} }
visitedIds.add(id); visitedIds.add(id);
if (edges.containsKey(id)) { if (edges.containsKey(id)) {
search(edges[id]); search(edges[id]!);
} }
sortedIds.add(id); sortedIds.add(id);
} }
startNodes.map<int>((SemanticsNode node) => node.id).forEach(search); startNodes.map<int>((SemanticsNode node) => node.id).forEach(search);
return sortedIds.map<SemanticsNode>((int id) => nodeMap[id]).toList().reversed.toList(); return sortedIds.map<SemanticsNode>((int id) => nodeMap[id]!).toList().reversed.toList();
} }
} }
...@@ -2479,7 +2479,7 @@ Offset _pointInParentCoordinates(SemanticsNode node, Offset point) { ...@@ -2479,7 +2479,7 @@ Offset _pointInParentCoordinates(SemanticsNode node, Offset point) {
return point; return point;
} }
final Vector3 vector = Vector3(point.dx, point.dy, 0.0); final Vector3 vector = Vector3(point.dx, point.dy, 0.0);
node.transform.transform3(vector); node.transform!.transform3(vector);
return Offset(vector.x, vector.y); return Offset(vector.x, vector.y);
} }
...@@ -2514,7 +2514,7 @@ List<SemanticsNode> _childrenInDefaultOrder(List<SemanticsNode> children, TextDi ...@@ -2514,7 +2514,7 @@ List<SemanticsNode> _childrenInDefaultOrder(List<SemanticsNode> children, TextDi
edges.sort(); edges.sort();
final List<_SemanticsSortGroup> verticalGroups = <_SemanticsSortGroup>[]; final List<_SemanticsSortGroup> verticalGroups = <_SemanticsSortGroup>[];
_SemanticsSortGroup group; _SemanticsSortGroup? group;
int depth = 0; int depth = 0;
for (final _BoxEdge edge in edges) { for (final _BoxEdge edge in edges) {
if (edge.isLeadingEdge) { if (edge.isLeadingEdge) {
...@@ -2528,7 +2528,7 @@ List<SemanticsNode> _childrenInDefaultOrder(List<SemanticsNode> children, TextDi ...@@ -2528,7 +2528,7 @@ List<SemanticsNode> _childrenInDefaultOrder(List<SemanticsNode> children, TextDi
depth -= 1; depth -= 1;
} }
if (depth == 0) { if (depth == 0) {
verticalGroups.add(group); verticalGroups.add(group!);
group = null; group = null;
} }
} }
...@@ -2548,9 +2548,9 @@ List<SemanticsNode> _childrenInDefaultOrder(List<SemanticsNode> children, TextDi ...@@ -2548,9 +2548,9 @@ List<SemanticsNode> _childrenInDefaultOrder(List<SemanticsNode> children, TextDi
/// the list of its siblings. [sortKey] takes precedence over position. /// the list of its siblings. [sortKey] takes precedence over position.
class _TraversalSortNode implements Comparable<_TraversalSortNode> { class _TraversalSortNode implements Comparable<_TraversalSortNode> {
_TraversalSortNode({ _TraversalSortNode({
@required this.node, required this.node,
this.sortKey, this.sortKey,
@required this.position, required this.position,
}) })
: assert(node != null), : assert(node != null),
assert(position != null); assert(position != null);
...@@ -2562,7 +2562,7 @@ class _TraversalSortNode implements Comparable<_TraversalSortNode> { ...@@ -2562,7 +2562,7 @@ class _TraversalSortNode implements Comparable<_TraversalSortNode> {
/// ///
/// Sort keys take precedence over other attributes, such as /// Sort keys take precedence over other attributes, such as
/// [position]. /// [position].
final SemanticsSortKey sortKey; final SemanticsSortKey? sortKey;
/// Position within the list of siblings as determined by the default sort /// Position within the list of siblings as determined by the default sort
/// order. /// order.
...@@ -2570,10 +2570,10 @@ class _TraversalSortNode implements Comparable<_TraversalSortNode> { ...@@ -2570,10 +2570,10 @@ class _TraversalSortNode implements Comparable<_TraversalSortNode> {
@override @override
int compareTo(_TraversalSortNode other) { int compareTo(_TraversalSortNode other) {
if (sortKey == null || other?.sortKey == null) { if (sortKey == null || other.sortKey == null) {
return position - other.position; return position - other.position;
} }
return sortKey.compareTo(other.sortKey); return sortKey!.compareTo(other.sortKey!);
} }
} }
...@@ -2591,7 +2591,7 @@ class SemanticsOwner extends ChangeNotifier { ...@@ -2591,7 +2591,7 @@ class SemanticsOwner extends ChangeNotifier {
/// The root node of the semantics tree, if any. /// The root node of the semantics tree, if any.
/// ///
/// If the semantics tree is empty, returns null. /// If the semantics tree is empty, returns null.
SemanticsNode get rootSemanticsNode => _nodes[0]; SemanticsNode? get rootSemanticsNode => _nodes[0];
@override @override
void dispose() { void dispose() {
...@@ -2615,19 +2615,19 @@ class SemanticsOwner extends ChangeNotifier { ...@@ -2615,19 +2615,19 @@ class SemanticsOwner extends ChangeNotifier {
visitedNodes.addAll(localDirtyNodes); visitedNodes.addAll(localDirtyNodes);
for (final SemanticsNode node in localDirtyNodes) { for (final SemanticsNode node in localDirtyNodes) {
assert(node._dirty); assert(node._dirty);
assert(node.parent == null || !node.parent.isPartOfNodeMerging || node.isMergedIntoParent); assert(node.parent == null || !node.parent!.isPartOfNodeMerging || node.isMergedIntoParent);
if (node.isPartOfNodeMerging) { if (node.isPartOfNodeMerging) {
assert(node.mergeAllDescendantsIntoThisNode || node.parent != null); assert(node.mergeAllDescendantsIntoThisNode || node.parent != null);
// if we're merged into our parent, make sure our parent is added to the dirty list // if we're merged into our parent, make sure our parent is added to the dirty list
if (node.parent != null && node.parent.isPartOfNodeMerging) { if (node.parent != null && node.parent!.isPartOfNodeMerging) {
node.parent._markDirty(); // this can add the node to the dirty list node.parent!._markDirty(); // this can add the node to the dirty list
node._dirty = false; // We don't want to send update for this node. node._dirty = false; // We don't want to send update for this node.
} }
} }
} }
} }
visitedNodes.sort((SemanticsNode a, SemanticsNode b) => a.depth - b.depth); visitedNodes.sort((SemanticsNode a, SemanticsNode b) => a.depth - b.depth);
final ui.SemanticsUpdateBuilder builder = SemanticsBinding.instance.createSemanticsUpdateBuilder(); final ui.SemanticsUpdateBuilder builder = SemanticsBinding.instance!.createSemanticsUpdateBuilder();
for (final SemanticsNode node in visitedNodes) { for (final SemanticsNode node in visitedNodes) {
assert(node.parent?._dirty != true); // could be null (no parent) or false (not dirty) assert(node.parent?._dirty != true); // could be null (no parent) or false (not dirty)
// The _serialize() method marks the node as not dirty, and // The _serialize() method marks the node as not dirty, and
...@@ -2645,15 +2645,15 @@ class SemanticsOwner extends ChangeNotifier { ...@@ -2645,15 +2645,15 @@ class SemanticsOwner extends ChangeNotifier {
} }
_dirtyNodes.clear(); _dirtyNodes.clear();
for (final int actionId in customSemanticsActionIds) { for (final int actionId in customSemanticsActionIds) {
final CustomSemanticsAction action = CustomSemanticsAction.getAction(actionId); final CustomSemanticsAction action = CustomSemanticsAction.getAction(actionId)!;
builder.updateCustomAction(id: actionId, label: action.label, hint: action.hint, overrideId: action.action?.index ?? -1); builder.updateCustomAction(id: actionId, label: action.label, hint: action.hint, overrideId: action.action?.index ?? -1);
} }
SemanticsBinding.instance.window.updateSemantics(builder.build()); SemanticsBinding.instance!.window.updateSemantics(builder.build());
notifyListeners(); notifyListeners();
} }
_SemanticsActionHandler _getSemanticsActionHandlerForId(int id, SemanticsAction action) { _SemanticsActionHandler? _getSemanticsActionHandlerForId(int id, SemanticsAction action) {
SemanticsNode result = _nodes[id]; SemanticsNode? result = _nodes[id];
if (result != null && result.isPartOfNodeMerging && !result._canPerformAction(action)) { if (result != null && result.isPartOfNodeMerging && !result._canPerformAction(action)) {
result._visitDescendants((SemanticsNode node) { result._visitDescendants((SemanticsNode node) {
if (node._canPerformAction(action)) { if (node._canPerformAction(action)) {
...@@ -2663,9 +2663,9 @@ class SemanticsOwner extends ChangeNotifier { ...@@ -2663,9 +2663,9 @@ class SemanticsOwner extends ChangeNotifier {
return true; // continue walk return true; // continue walk
}); });
} }
if (result == null || !result._canPerformAction(action)) if (result == null || !result!._canPerformAction(action))
return null; return null;
return result._actions[action]; return result!._actions[action];
} }
/// Asks the [SemanticsNode] with the given id to perform the given action. /// Asks the [SemanticsNode] with the given id to perform the given action.
...@@ -2677,28 +2677,28 @@ class SemanticsOwner extends ChangeNotifier { ...@@ -2677,28 +2677,28 @@ class SemanticsOwner extends ChangeNotifier {
/// the `args` parameter. /// the `args` parameter.
void performAction(int id, SemanticsAction action, [ dynamic args ]) { void performAction(int id, SemanticsAction action, [ dynamic args ]) {
assert(action != null); assert(action != null);
final _SemanticsActionHandler handler = _getSemanticsActionHandlerForId(id, action); final _SemanticsActionHandler? handler = _getSemanticsActionHandlerForId(id, action);
if (handler != null) { if (handler != null) {
handler(args); handler(args);
return; return;
} }
// Default actions if no [handler] was provided. // Default actions if no [handler] was provided.
if (action == SemanticsAction.showOnScreen && _nodes[id]._showOnScreen != null) if (action == SemanticsAction.showOnScreen && _nodes[id]!._showOnScreen != null)
_nodes[id]._showOnScreen(); _nodes[id]!._showOnScreen!();
} }
_SemanticsActionHandler _getSemanticsActionHandlerForPosition(SemanticsNode node, Offset position, SemanticsAction action) { _SemanticsActionHandler? _getSemanticsActionHandlerForPosition(SemanticsNode node, Offset position, SemanticsAction action) {
if (node.transform != null) { if (node.transform != null) {
final Matrix4 inverse = Matrix4.identity(); final Matrix4 inverse = Matrix4.identity();
if (inverse.copyInverse(node.transform) == 0.0) if (inverse.copyInverse(node.transform!) == 0.0)
return null; return null;
position = MatrixUtils.transformPoint(inverse, position); position = MatrixUtils.transformPoint(inverse, position);
} }
if (!node.rect.contains(position)) if (!node.rect.contains(position))
return null; return null;
if (node.mergeAllDescendantsIntoThisNode) { if (node.mergeAllDescendantsIntoThisNode) {
SemanticsNode result; SemanticsNode? result;
node._visitDescendants((SemanticsNode child) { node._visitDescendants((SemanticsNode child) {
if (child._canPerformAction(action)) { if (child._canPerformAction(action)) {
result = child; result = child;
...@@ -2709,8 +2709,8 @@ class SemanticsOwner extends ChangeNotifier { ...@@ -2709,8 +2709,8 @@ class SemanticsOwner extends ChangeNotifier {
return result?._actions[action]; return result?._actions[action];
} }
if (node.hasChildren) { if (node.hasChildren) {
for (final SemanticsNode child in node._children.reversed) { for (final SemanticsNode child in node._children!.reversed) {
final _SemanticsActionHandler handler = _getSemanticsActionHandlerForPosition(child, position, action); final _SemanticsActionHandler? handler = _getSemanticsActionHandlerForPosition(child, position, action);
if (handler != null) if (handler != null)
return handler; return handler;
} }
...@@ -2727,10 +2727,10 @@ class SemanticsOwner extends ChangeNotifier { ...@@ -2727,10 +2727,10 @@ class SemanticsOwner extends ChangeNotifier {
/// the `args` parameter. /// the `args` parameter.
void performActionAt(Offset position, SemanticsAction action, [ dynamic args ]) { void performActionAt(Offset position, SemanticsAction action, [ dynamic args ]) {
assert(action != null); assert(action != null);
final SemanticsNode node = rootSemanticsNode; final SemanticsNode? node = rootSemanticsNode;
if (node == null) if (node == null)
return; return;
final _SemanticsActionHandler handler = _getSemanticsActionHandlerForPosition(node, position, action); final _SemanticsActionHandler? handler = _getSemanticsActionHandlerForPosition(node, position, action);
if (handler != null) if (handler != null)
handler(args); handler(args);
} }
...@@ -2865,10 +2865,10 @@ class SemanticsConfiguration { ...@@ -2865,10 +2865,10 @@ class SemanticsConfiguration {
/// onTap handler should always be wrapping an element that defines a /// onTap handler should always be wrapping an element that defines a
/// semantic [onTap] handler. By default a [GestureDetector] will register its /// semantic [onTap] handler. By default a [GestureDetector] will register its
/// own semantic [onTap] handler that follows this principle. /// own semantic [onTap] handler that follows this principle.
VoidCallback get onTap => _onTap; VoidCallback? get onTap => _onTap;
VoidCallback _onTap; VoidCallback? _onTap;
set onTap(VoidCallback value) { set onTap(VoidCallback? value) {
_addArgumentlessAction(SemanticsAction.tap, value); _addArgumentlessAction(SemanticsAction.tap, value!);
_onTap = value; _onTap = value;
} }
...@@ -2880,10 +2880,10 @@ class SemanticsConfiguration { ...@@ -2880,10 +2880,10 @@ class SemanticsConfiguration {
/// VoiceOver users on iOS and TalkBack users on Android can trigger this /// VoiceOver users on iOS and TalkBack users on Android can trigger this
/// action by double-tapping the screen without lifting the finger after the /// action by double-tapping the screen without lifting the finger after the
/// second tap. /// second tap.
VoidCallback get onLongPress => _onLongPress; VoidCallback? get onLongPress => _onLongPress;
VoidCallback _onLongPress; VoidCallback? _onLongPress;
set onLongPress(VoidCallback value) { set onLongPress(VoidCallback? value) {
_addArgumentlessAction(SemanticsAction.longPress, value); _addArgumentlessAction(SemanticsAction.longPress, value!);
_onLongPress = value; _onLongPress = value;
} }
...@@ -2898,10 +2898,10 @@ class SemanticsConfiguration { ...@@ -2898,10 +2898,10 @@ class SemanticsConfiguration {
/// right and then left in one motion path. On Android, [onScrollUp] and /// right and then left in one motion path. On Android, [onScrollUp] and
/// [onScrollLeft] share the same gesture. Therefore, only on of them should /// [onScrollLeft] share the same gesture. Therefore, only on of them should
/// be provided. /// be provided.
VoidCallback get onScrollLeft => _onScrollLeft; VoidCallback? get onScrollLeft => _onScrollLeft;
VoidCallback _onScrollLeft; VoidCallback? _onScrollLeft;
set onScrollLeft(VoidCallback value) { set onScrollLeft(VoidCallback? value) {
_addArgumentlessAction(SemanticsAction.scrollLeft, value); _addArgumentlessAction(SemanticsAction.scrollLeft, value!);
_onScrollLeft = value; _onScrollLeft = value;
} }
...@@ -2912,10 +2912,10 @@ class SemanticsConfiguration { ...@@ -2912,10 +2912,10 @@ class SemanticsConfiguration {
/// TalkBack users on Android can trigger this action in the local context /// TalkBack users on Android can trigger this action in the local context
/// menu, and VoiceOver users on iOS can trigger this action with a standard /// menu, and VoiceOver users on iOS can trigger this action with a standard
/// gesture or menu option. /// gesture or menu option.
VoidCallback get onDismiss => _onDismiss; VoidCallback? get onDismiss => _onDismiss;
VoidCallback _onDismiss; VoidCallback? _onDismiss;
set onDismiss(VoidCallback value) { set onDismiss(VoidCallback? value) {
_addArgumentlessAction(SemanticsAction.dismiss, value); _addArgumentlessAction(SemanticsAction.dismiss, value!);
_onDismiss = value; _onDismiss = value;
} }
...@@ -2930,10 +2930,10 @@ class SemanticsConfiguration { ...@@ -2930,10 +2930,10 @@ class SemanticsConfiguration {
/// left and then right in one motion path. On Android, [onScrollDown] and /// left and then right in one motion path. On Android, [onScrollDown] and
/// [onScrollRight] share the same gesture. Therefore, only on of them should /// [onScrollRight] share the same gesture. Therefore, only on of them should
/// be provided. /// be provided.
VoidCallback get onScrollRight => _onScrollRight; VoidCallback? get onScrollRight => _onScrollRight;
VoidCallback _onScrollRight; VoidCallback? _onScrollRight;
set onScrollRight(VoidCallback value) { set onScrollRight(VoidCallback? value) {
_addArgumentlessAction(SemanticsAction.scrollRight, value); _addArgumentlessAction(SemanticsAction.scrollRight, value!);
_onScrollRight = value; _onScrollRight = value;
} }
...@@ -2948,10 +2948,10 @@ class SemanticsConfiguration { ...@@ -2948,10 +2948,10 @@ class SemanticsConfiguration {
/// right and then left in one motion path. On Android, [onScrollUp] and /// right and then left in one motion path. On Android, [onScrollUp] and
/// [onScrollLeft] share the same gesture. Therefore, only on of them should /// [onScrollLeft] share the same gesture. Therefore, only on of them should
/// be provided. /// be provided.
VoidCallback get onScrollUp => _onScrollUp; VoidCallback? get onScrollUp => _onScrollUp;
VoidCallback _onScrollUp; VoidCallback? _onScrollUp;
set onScrollUp(VoidCallback value) { set onScrollUp(VoidCallback? value) {
_addArgumentlessAction(SemanticsAction.scrollUp, value); _addArgumentlessAction(SemanticsAction.scrollUp, value!);
_onScrollUp = value; _onScrollUp = value;
} }
...@@ -2966,10 +2966,10 @@ class SemanticsConfiguration { ...@@ -2966,10 +2966,10 @@ class SemanticsConfiguration {
/// left and then right in one motion path. On Android, [onScrollDown] and /// left and then right in one motion path. On Android, [onScrollDown] and
/// [onScrollRight] share the same gesture. Therefore, only on of them should /// [onScrollRight] share the same gesture. Therefore, only on of them should
/// be provided. /// be provided.
VoidCallback get onScrollDown => _onScrollDown; VoidCallback? get onScrollDown => _onScrollDown;
VoidCallback _onScrollDown; VoidCallback? _onScrollDown;
set onScrollDown(VoidCallback value) { set onScrollDown(VoidCallback? value) {
_addArgumentlessAction(SemanticsAction.scrollDown, value); _addArgumentlessAction(SemanticsAction.scrollDown, value!);
_onScrollDown = value; _onScrollDown = value;
} }
...@@ -2984,10 +2984,10 @@ class SemanticsConfiguration { ...@@ -2984,10 +2984,10 @@ class SemanticsConfiguration {
/// VoiceOver users on iOS can trigger this action by swiping up with one /// VoiceOver users on iOS can trigger this action by swiping up with one
/// finger. TalkBack users on Android can trigger this action by pressing the /// finger. TalkBack users on Android can trigger this action by pressing the
/// volume up button. /// volume up button.
VoidCallback get onIncrease => _onIncrease; VoidCallback? get onIncrease => _onIncrease;
VoidCallback _onIncrease; VoidCallback? _onIncrease;
set onIncrease(VoidCallback value) { set onIncrease(VoidCallback? value) {
_addArgumentlessAction(SemanticsAction.increase, value); _addArgumentlessAction(SemanticsAction.increase, value!);
_onIncrease = value; _onIncrease = value;
} }
...@@ -3002,10 +3002,10 @@ class SemanticsConfiguration { ...@@ -3002,10 +3002,10 @@ class SemanticsConfiguration {
/// VoiceOver users on iOS can trigger this action by swiping down with one /// VoiceOver users on iOS can trigger this action by swiping down with one
/// finger. TalkBack users on Android can trigger this action by pressing the /// finger. TalkBack users on Android can trigger this action by pressing the
/// volume down button. /// volume down button.
VoidCallback get onDecrease => _onDecrease; VoidCallback? get onDecrease => _onDecrease;
VoidCallback _onDecrease; VoidCallback? _onDecrease;
set onDecrease(VoidCallback value) { set onDecrease(VoidCallback? value) {
_addArgumentlessAction(SemanticsAction.decrease, value); _addArgumentlessAction(SemanticsAction.decrease, value!);
_onDecrease = value; _onDecrease = value;
} }
...@@ -3015,10 +3015,10 @@ class SemanticsConfiguration { ...@@ -3015,10 +3015,10 @@ class SemanticsConfiguration {
/// ///
/// TalkBack users on Android can trigger this action from the local context /// TalkBack users on Android can trigger this action from the local context
/// menu of a text field, for example. /// menu of a text field, for example.
VoidCallback get onCopy => _onCopy; VoidCallback? get onCopy => _onCopy;
VoidCallback _onCopy; VoidCallback? _onCopy;
set onCopy(VoidCallback value) { set onCopy(VoidCallback? value) {
_addArgumentlessAction(SemanticsAction.copy, value); _addArgumentlessAction(SemanticsAction.copy, value!);
_onCopy = value; _onCopy = value;
} }
...@@ -3029,10 +3029,10 @@ class SemanticsConfiguration { ...@@ -3029,10 +3029,10 @@ class SemanticsConfiguration {
/// ///
/// TalkBack users on Android can trigger this action from the local context /// TalkBack users on Android can trigger this action from the local context
/// menu of a text field, for example. /// menu of a text field, for example.
VoidCallback get onCut => _onCut; VoidCallback? get onCut => _onCut;
VoidCallback _onCut; VoidCallback? _onCut;
set onCut(VoidCallback value) { set onCut(VoidCallback? value) {
_addArgumentlessAction(SemanticsAction.cut, value); _addArgumentlessAction(SemanticsAction.cut, value!);
_onCut = value; _onCut = value;
} }
...@@ -3042,10 +3042,10 @@ class SemanticsConfiguration { ...@@ -3042,10 +3042,10 @@ class SemanticsConfiguration {
/// ///
/// TalkBack users on Android can trigger this action from the local context /// TalkBack users on Android can trigger this action from the local context
/// menu of a text field, for example. /// menu of a text field, for example.
VoidCallback get onPaste => _onPaste; VoidCallback? get onPaste => _onPaste;
VoidCallback _onPaste; VoidCallback? _onPaste;
set onPaste(VoidCallback value) { set onPaste(VoidCallback? value) {
_addArgumentlessAction(SemanticsAction.paste, value); _addArgumentlessAction(SemanticsAction.paste, value!);
_onPaste = value; _onPaste = value;
} }
...@@ -3058,10 +3058,10 @@ class SemanticsConfiguration { ...@@ -3058,10 +3058,10 @@ class SemanticsConfiguration {
/// For elements in a scrollable list the framework provides a default /// For elements in a scrollable list the framework provides a default
/// implementation for this action and it is not advised to provide a /// implementation for this action and it is not advised to provide a
/// custom one via this setter. /// custom one via this setter.
VoidCallback get onShowOnScreen => _onShowOnScreen; VoidCallback? get onShowOnScreen => _onShowOnScreen;
VoidCallback _onShowOnScreen; VoidCallback? _onShowOnScreen;
set onShowOnScreen(VoidCallback value) { set onShowOnScreen(VoidCallback? value) {
_addArgumentlessAction(SemanticsAction.showOnScreen, value); _addArgumentlessAction(SemanticsAction.showOnScreen, value!);
_onShowOnScreen = value; _onShowOnScreen = value;
} }
...@@ -3072,14 +3072,14 @@ class SemanticsConfiguration { ...@@ -3072,14 +3072,14 @@ class SemanticsConfiguration {
/// ///
/// TalkBack users can trigger this by pressing the volume up key while the /// TalkBack users can trigger this by pressing the volume up key while the
/// input focus is in a text field. /// input focus is in a text field.
MoveCursorHandler get onMoveCursorForwardByCharacter => _onMoveCursorForwardByCharacter; MoveCursorHandler? get onMoveCursorForwardByCharacter => _onMoveCursorForwardByCharacter;
MoveCursorHandler _onMoveCursorForwardByCharacter; MoveCursorHandler? _onMoveCursorForwardByCharacter;
set onMoveCursorForwardByCharacter(MoveCursorHandler value) { set onMoveCursorForwardByCharacter(MoveCursorHandler? value) {
assert(value != null); assert(value != null);
_addAction(SemanticsAction.moveCursorForwardByCharacter, (dynamic args) { _addAction(SemanticsAction.moveCursorForwardByCharacter, (dynamic args) {
final bool extentSelection = args as bool; final bool extentSelection = args as bool;
assert(extentSelection != null); assert(extentSelection != null);
value(extentSelection); value!(extentSelection);
}); });
_onMoveCursorForwardByCharacter = value; _onMoveCursorForwardByCharacter = value;
} }
...@@ -3091,14 +3091,14 @@ class SemanticsConfiguration { ...@@ -3091,14 +3091,14 @@ class SemanticsConfiguration {
/// ///
/// TalkBack users can trigger this by pressing the volume down key while the /// TalkBack users can trigger this by pressing the volume down key while the
/// input focus is in a text field. /// input focus is in a text field.
MoveCursorHandler get onMoveCursorBackwardByCharacter => _onMoveCursorBackwardByCharacter; MoveCursorHandler? get onMoveCursorBackwardByCharacter => _onMoveCursorBackwardByCharacter;
MoveCursorHandler _onMoveCursorBackwardByCharacter; MoveCursorHandler? _onMoveCursorBackwardByCharacter;
set onMoveCursorBackwardByCharacter(MoveCursorHandler value) { set onMoveCursorBackwardByCharacter(MoveCursorHandler? value) {
assert(value != null); assert(value != null);
_addAction(SemanticsAction.moveCursorBackwardByCharacter, (dynamic args) { _addAction(SemanticsAction.moveCursorBackwardByCharacter, (dynamic args) {
final bool extentSelection = args as bool; final bool extentSelection = args as bool;
assert(extentSelection != null); assert(extentSelection != null);
value(extentSelection); value!(extentSelection);
}); });
_onMoveCursorBackwardByCharacter = value; _onMoveCursorBackwardByCharacter = value;
} }
...@@ -3110,14 +3110,14 @@ class SemanticsConfiguration { ...@@ -3110,14 +3110,14 @@ class SemanticsConfiguration {
/// ///
/// TalkBack users can trigger this by pressing the volume down key while the /// TalkBack users can trigger this by pressing the volume down key while the
/// input focus is in a text field. /// input focus is in a text field.
MoveCursorHandler get onMoveCursorForwardByWord => _onMoveCursorForwardByWord; MoveCursorHandler? get onMoveCursorForwardByWord => _onMoveCursorForwardByWord;
MoveCursorHandler _onMoveCursorForwardByWord; MoveCursorHandler? _onMoveCursorForwardByWord;
set onMoveCursorForwardByWord(MoveCursorHandler value) { set onMoveCursorForwardByWord(MoveCursorHandler? value) {
assert(value != null); assert(value != null);
_addAction(SemanticsAction.moveCursorForwardByWord, (dynamic args) { _addAction(SemanticsAction.moveCursorForwardByWord, (dynamic args) {
final bool extentSelection = args as bool; final bool extentSelection = args as bool;
assert(extentSelection != null); assert(extentSelection != null);
value(extentSelection); value!(extentSelection);
}); });
_onMoveCursorForwardByCharacter = value; _onMoveCursorForwardByCharacter = value;
} }
...@@ -3129,14 +3129,14 @@ class SemanticsConfiguration { ...@@ -3129,14 +3129,14 @@ class SemanticsConfiguration {
/// ///
/// TalkBack users can trigger this by pressing the volume down key while the /// TalkBack users can trigger this by pressing the volume down key while the
/// input focus is in a text field. /// input focus is in a text field.
MoveCursorHandler get onMoveCursorBackwardByWord => _onMoveCursorBackwardByWord; MoveCursorHandler? get onMoveCursorBackwardByWord => _onMoveCursorBackwardByWord;
MoveCursorHandler _onMoveCursorBackwardByWord; MoveCursorHandler? _onMoveCursorBackwardByWord;
set onMoveCursorBackwardByWord(MoveCursorHandler value) { set onMoveCursorBackwardByWord(MoveCursorHandler? value) {
assert(value != null); assert(value != null);
_addAction(SemanticsAction.moveCursorBackwardByWord, (dynamic args) { _addAction(SemanticsAction.moveCursorBackwardByWord, (dynamic args) {
final bool extentSelection = args as bool; final bool extentSelection = args as bool;
assert(extentSelection != null); assert(extentSelection != null);
value(extentSelection); value!(extentSelection);
}); });
_onMoveCursorBackwardByCharacter = value; _onMoveCursorBackwardByCharacter = value;
} }
...@@ -3148,17 +3148,17 @@ class SemanticsConfiguration { ...@@ -3148,17 +3148,17 @@ class SemanticsConfiguration {
/// ///
/// TalkBack users can trigger this handler by selecting "Move cursor to /// TalkBack users can trigger this handler by selecting "Move cursor to
/// beginning/end" or "Select all" from the local context menu. /// beginning/end" or "Select all" from the local context menu.
SetSelectionHandler get onSetSelection => _onSetSelection; SetSelectionHandler? get onSetSelection => _onSetSelection;
SetSelectionHandler _onSetSelection; SetSelectionHandler? _onSetSelection;
set onSetSelection(SetSelectionHandler value) { set onSetSelection(SetSelectionHandler? value) {
assert(value != null); assert(value != null);
_addAction(SemanticsAction.setSelection, (dynamic args) { _addAction(SemanticsAction.setSelection, (dynamic args) {
assert(args != null && args is Map); assert(args != null && args is Map);
final Map<String, int> selection = (args as Map<dynamic, dynamic>).cast<String, int>(); final Map<String, int> selection = (args as Map<dynamic, dynamic>).cast<String, int>();
assert(selection != null && selection['base'] != null && selection['extent'] != null); assert(selection != null && selection['base'] != null && selection['extent'] != null);
value(TextSelection( value!(TextSelection(
baseOffset: selection['base'], baseOffset: selection['base']!,
extentOffset: selection['extent'], extentOffset: selection['extent']!,
)); ));
}); });
_onSetSelection = value; _onSetSelection = value;
...@@ -3181,10 +3181,10 @@ class SemanticsConfiguration { ...@@ -3181,10 +3181,10 @@ class SemanticsConfiguration {
/// * [onDidLoseAccessibilityFocus], which is invoked when the accessibility /// * [onDidLoseAccessibilityFocus], which is invoked when the accessibility
/// focus is removed from the node. /// focus is removed from the node.
/// * [FocusNode], [FocusScope], [FocusManager], which manage the input focus. /// * [FocusNode], [FocusScope], [FocusManager], which manage the input focus.
VoidCallback get onDidGainAccessibilityFocus => _onDidGainAccessibilityFocus; VoidCallback? get onDidGainAccessibilityFocus => _onDidGainAccessibilityFocus;
VoidCallback _onDidGainAccessibilityFocus; VoidCallback? _onDidGainAccessibilityFocus;
set onDidGainAccessibilityFocus(VoidCallback value) { set onDidGainAccessibilityFocus(VoidCallback? value) {
_addArgumentlessAction(SemanticsAction.didGainAccessibilityFocus, value); _addArgumentlessAction(SemanticsAction.didGainAccessibilityFocus, value!);
_onDidGainAccessibilityFocus = value; _onDidGainAccessibilityFocus = value;
} }
...@@ -3205,16 +3205,16 @@ class SemanticsConfiguration { ...@@ -3205,16 +3205,16 @@ class SemanticsConfiguration {
/// * [onDidGainAccessibilityFocus], which is invoked when the node gains /// * [onDidGainAccessibilityFocus], which is invoked when the node gains
/// accessibility focus. /// accessibility focus.
/// * [FocusNode], [FocusScope], [FocusManager], which manage the input focus. /// * [FocusNode], [FocusScope], [FocusManager], which manage the input focus.
VoidCallback get onDidLoseAccessibilityFocus => _onDidLoseAccessibilityFocus; VoidCallback? get onDidLoseAccessibilityFocus => _onDidLoseAccessibilityFocus;
VoidCallback _onDidLoseAccessibilityFocus; VoidCallback? _onDidLoseAccessibilityFocus;
set onDidLoseAccessibilityFocus(VoidCallback value) { set onDidLoseAccessibilityFocus(VoidCallback? value) {
_addArgumentlessAction(SemanticsAction.didLoseAccessibilityFocus, value); _addArgumentlessAction(SemanticsAction.didLoseAccessibilityFocus, value!);
_onDidLoseAccessibilityFocus = value; _onDidLoseAccessibilityFocus = value;
} }
/// Returns the action handler registered for [action] or null if none was /// Returns the action handler registered for [action] or null if none was
/// registered. /// registered.
_SemanticsActionHandler getActionHandler(SemanticsAction action) => _actions[action]; _SemanticsActionHandler? getActionHandler(SemanticsAction action) => _actions[action];
/// Determines the position of this node among its siblings in the traversal /// Determines the position of this node among its siblings in the traversal
/// sort order. /// sort order.
...@@ -3227,9 +3227,9 @@ class SemanticsConfiguration { ...@@ -3227,9 +3227,9 @@ class SemanticsConfiguration {
/// subject to how this configuration is used. For example, the [absorb] /// subject to how this configuration is used. For example, the [absorb]
/// method may decide to not use this key when it combines multiple /// method may decide to not use this key when it combines multiple
/// [SemanticsConfiguration] objects. /// [SemanticsConfiguration] objects.
SemanticsSortKey get sortKey => _sortKey; SemanticsSortKey? get sortKey => _sortKey;
SemanticsSortKey _sortKey; SemanticsSortKey? _sortKey;
set sortKey(SemanticsSortKey value) { set sortKey(SemanticsSortKey? value) {
assert(value != null); assert(value != null);
_sortKey = value; _sortKey = value;
_hasBeenAnnotated = true; _hasBeenAnnotated = true;
...@@ -3241,9 +3241,9 @@ class SemanticsConfiguration { ...@@ -3241,9 +3241,9 @@ class SemanticsConfiguration {
/// child list. For example, if a scrollable has five children but the first /// child list. For example, if a scrollable has five children but the first
/// two are not visible (and thus not included in the list of children), then /// two are not visible (and thus not included in the list of children), then
/// the index of the last node will still be 4. /// the index of the last node will still be 4.
int get indexInParent => _indexInParent; int? get indexInParent => _indexInParent;
int _indexInParent; int? _indexInParent;
set indexInParent(int value) { set indexInParent(int? value) {
_indexInParent = value; _indexInParent = value;
_hasBeenAnnotated = true; _hasBeenAnnotated = true;
} }
...@@ -3252,9 +3252,9 @@ class SemanticsConfiguration { ...@@ -3252,9 +3252,9 @@ class SemanticsConfiguration {
/// ///
/// If the number of children are unknown or unbounded, this value will be /// If the number of children are unknown or unbounded, this value will be
/// null. /// null.
int get scrollChildCount => _scrollChildCount; int? get scrollChildCount => _scrollChildCount;
int _scrollChildCount; int? _scrollChildCount;
set scrollChildCount(int value) { set scrollChildCount(int? value) {
if (value == scrollChildCount) if (value == scrollChildCount)
return; return;
_scrollChildCount = value; _scrollChildCount = value;
...@@ -3263,9 +3263,9 @@ class SemanticsConfiguration { ...@@ -3263,9 +3263,9 @@ class SemanticsConfiguration {
/// The index of the first visible scrollable child that contributes to /// The index of the first visible scrollable child that contributes to
/// semantics. /// semantics.
int get scrollIndex => _scrollIndex; int? get scrollIndex => _scrollIndex;
int _scrollIndex; int? _scrollIndex;
set scrollIndex(int value) { set scrollIndex(int? value) {
if (value == scrollIndex) if (value == scrollIndex)
return; return;
_scrollIndex = value; _scrollIndex = value;
...@@ -3274,9 +3274,9 @@ class SemanticsConfiguration { ...@@ -3274,9 +3274,9 @@ class SemanticsConfiguration {
/// The id of the platform view, whose semantics nodes will be added as /// The id of the platform view, whose semantics nodes will be added as
/// children to this node. /// children to this node.
int get platformViewId => _platformViewId; int? get platformViewId => _platformViewId;
int _platformViewId; int? _platformViewId;
set platformViewId(int value) { set platformViewId(int? value) {
if (value == platformViewId) if (value == platformViewId)
return; return;
_platformViewId = value; _platformViewId = value;
...@@ -3291,9 +3291,9 @@ class SemanticsConfiguration { ...@@ -3291,9 +3291,9 @@ class SemanticsConfiguration {
/// ///
/// This should only be set when [isTextField] is true. Defaults to null, /// This should only be set when [isTextField] is true. Defaults to null,
/// which means no limit is imposed on the text field. /// which means no limit is imposed on the text field.
int get maxValueLength => _maxValueLength; int? get maxValueLength => _maxValueLength;
int _maxValueLength; int? _maxValueLength;
set maxValueLength(int value) { set maxValueLength(int? value) {
if (value == maxValueLength) if (value == maxValueLength)
return; return;
_maxValueLength = value; _maxValueLength = value;
...@@ -3308,9 +3308,9 @@ class SemanticsConfiguration { ...@@ -3308,9 +3308,9 @@ class SemanticsConfiguration {
/// ///
/// This should only be set when [isTextField] is true. Must be set when /// This should only be set when [isTextField] is true. Must be set when
/// [maxValueLength] is set. /// [maxValueLength] is set.
int get currentValueLength => _currentValueLength; int? get currentValueLength => _currentValueLength;
int _currentValueLength; int? _currentValueLength;
set currentValueLength(int value) { set currentValueLength(int? value) {
if (value == currentValueLength) if (value == currentValueLength)
return; return;
_currentValueLength = value; _currentValueLength = value;
...@@ -3349,10 +3349,10 @@ class SemanticsConfiguration { ...@@ -3349,10 +3349,10 @@ class SemanticsConfiguration {
} }
void _onCustomSemanticsAction(dynamic args) { void _onCustomSemanticsAction(dynamic args) {
final CustomSemanticsAction action = CustomSemanticsAction.getAction(args as int); final CustomSemanticsAction? action = CustomSemanticsAction.getAction(args as int);
if (action == null) if (action == null)
return; return;
final VoidCallback callback = _customSemanticsActions[action]; final VoidCallback? callback = _customSemanticsActions[action];
if (callback != null) if (callback != null)
callback(); callback();
} }
...@@ -3444,9 +3444,9 @@ class SemanticsConfiguration { ...@@ -3444,9 +3444,9 @@ class SemanticsConfiguration {
/// Provides hint values which override the default hints on supported /// Provides hint values which override the default hints on supported
/// platforms. /// platforms.
SemanticsHintOverrides get hintOverrides => _hintOverrides; SemanticsHintOverrides? get hintOverrides => _hintOverrides;
SemanticsHintOverrides _hintOverrides; SemanticsHintOverrides? _hintOverrides;
set hintOverrides(SemanticsHintOverrides value) { set hintOverrides(SemanticsHintOverrides? value) {
if (value == null) if (value == null)
return; return;
_hintOverrides = value; _hintOverrides = value;
...@@ -3532,9 +3532,9 @@ class SemanticsConfiguration { ...@@ -3532,9 +3532,9 @@ class SemanticsConfiguration {
/// The reading direction for the text in [label], [value], [hint], /// The reading direction for the text in [label], [value], [hint],
/// [increasedValue], and [decreasedValue]. /// [increasedValue], and [decreasedValue].
TextDirection get textDirection => _textDirection; TextDirection? get textDirection => _textDirection;
TextDirection _textDirection; TextDirection? _textDirection;
set textDirection(TextDirection textDirection) { set textDirection(TextDirection? textDirection) {
_textDirection = textDirection; _textDirection = textDirection;
_hasBeenAnnotated = true; _hasBeenAnnotated = true;
} }
...@@ -3565,10 +3565,10 @@ class SemanticsConfiguration { ...@@ -3565,10 +3565,10 @@ class SemanticsConfiguration {
/// This property does not control whether semantics are enabled. If you wish to /// This property does not control whether semantics are enabled. If you wish to
/// disable semantics for a particular widget, you should use an [ExcludeSemantics] /// disable semantics for a particular widget, you should use an [ExcludeSemantics]
/// widget. /// widget.
bool get isEnabled => _hasFlag(SemanticsFlag.hasEnabledState) ? _hasFlag(SemanticsFlag.isEnabled) : null; bool? get isEnabled => _hasFlag(SemanticsFlag.hasEnabledState) ? _hasFlag(SemanticsFlag.isEnabled) : null;
set isEnabled(bool value) { set isEnabled(bool? value) {
_setFlag(SemanticsFlag.hasEnabledState, true); _setFlag(SemanticsFlag.hasEnabledState, true);
_setFlag(SemanticsFlag.isEnabled, value); _setFlag(SemanticsFlag.isEnabled, value!);
} }
/// If this node has Boolean state that can be controlled by the user, whether /// If this node has Boolean state that can be controlled by the user, whether
...@@ -3580,10 +3580,10 @@ class SemanticsConfiguration { ...@@ -3580,10 +3580,10 @@ class SemanticsConfiguration {
/// ///
/// The getter returns null if the owning [RenderObject] does not have /// The getter returns null if the owning [RenderObject] does not have
/// checked/unchecked state. /// checked/unchecked state.
bool get isChecked => _hasFlag(SemanticsFlag.hasCheckedState) ? _hasFlag(SemanticsFlag.isChecked) : null; bool? get isChecked => _hasFlag(SemanticsFlag.hasCheckedState) ? _hasFlag(SemanticsFlag.isChecked) : null;
set isChecked(bool value) { set isChecked(bool? value) {
_setFlag(SemanticsFlag.hasCheckedState, true); _setFlag(SemanticsFlag.hasCheckedState, true);
_setFlag(SemanticsFlag.isChecked, value); _setFlag(SemanticsFlag.isChecked, value!);
} }
/// If this node has Boolean state that can be controlled by the user, whether /// If this node has Boolean state that can be controlled by the user, whether
...@@ -3594,10 +3594,10 @@ class SemanticsConfiguration { ...@@ -3594,10 +3594,10 @@ class SemanticsConfiguration {
/// ///
/// The getter returns null if the owning [RenderObject] does not have /// The getter returns null if the owning [RenderObject] does not have
/// on/off state. /// on/off state.
bool get isToggled => _hasFlag(SemanticsFlag.hasToggledState) ? _hasFlag(SemanticsFlag.isToggled) : null; bool? get isToggled => _hasFlag(SemanticsFlag.hasToggledState) ? _hasFlag(SemanticsFlag.isToggled) : null;
set isToggled(bool value) { set isToggled(bool? value) {
_setFlag(SemanticsFlag.hasToggledState, true); _setFlag(SemanticsFlag.hasToggledState, true);
_setFlag(SemanticsFlag.isToggled, value); _setFlag(SemanticsFlag.isToggled, value!);
} }
/// Whether the owning RenderObject corresponds to UI that allows the user to /// Whether the owning RenderObject corresponds to UI that allows the user to
...@@ -3708,9 +3708,9 @@ class SemanticsConfiguration { ...@@ -3708,9 +3708,9 @@ class SemanticsConfiguration {
/// The currently selected text (or the position of the cursor) within [value] /// The currently selected text (or the position of the cursor) within [value]
/// if this node represents a text field. /// if this node represents a text field.
TextSelection get textSelection => _textSelection; TextSelection? get textSelection => _textSelection;
TextSelection _textSelection; TextSelection? _textSelection;
set textSelection(TextSelection value) { set textSelection(TextSelection? value) {
assert(value != null); assert(value != null);
_textSelection = value; _textSelection = value;
_hasBeenAnnotated = true; _hasBeenAnnotated = true;
...@@ -3726,9 +3726,9 @@ class SemanticsConfiguration { ...@@ -3726,9 +3726,9 @@ class SemanticsConfiguration {
/// See also: /// See also:
/// ///
/// * [ScrollPosition.pixels], from where this value is usually taken. /// * [ScrollPosition.pixels], from where this value is usually taken.
double get scrollPosition => _scrollPosition; double? get scrollPosition => _scrollPosition;
double _scrollPosition; double? _scrollPosition;
set scrollPosition(double value) { set scrollPosition(double? value) {
assert(value != null); assert(value != null);
_scrollPosition = value; _scrollPosition = value;
_hasBeenAnnotated = true; _hasBeenAnnotated = true;
...@@ -3742,9 +3742,9 @@ class SemanticsConfiguration { ...@@ -3742,9 +3742,9 @@ class SemanticsConfiguration {
/// See also: /// See also:
/// ///
/// * [ScrollPosition.maxScrollExtent], from where this value is usually taken. /// * [ScrollPosition.maxScrollExtent], from where this value is usually taken.
double get scrollExtentMax => _scrollExtentMax; double? get scrollExtentMax => _scrollExtentMax;
double _scrollExtentMax; double? _scrollExtentMax;
set scrollExtentMax(double value) { set scrollExtentMax(double? value) {
assert(value != null); assert(value != null);
_scrollExtentMax = value; _scrollExtentMax = value;
_hasBeenAnnotated = true; _hasBeenAnnotated = true;
...@@ -3758,9 +3758,9 @@ class SemanticsConfiguration { ...@@ -3758,9 +3758,9 @@ class SemanticsConfiguration {
/// See also: /// See also:
/// ///
/// * [ScrollPosition.minScrollExtent], from where this value is usually taken. /// * [ScrollPosition.minScrollExtent], from where this value is usually taken.
double get scrollExtentMin => _scrollExtentMin; double? get scrollExtentMin => _scrollExtentMin;
double _scrollExtentMin; double? _scrollExtentMin;
set scrollExtentMin(double value) { set scrollExtentMin(double? value) {
assert(value != null); assert(value != null);
_scrollExtentMin = value; _scrollExtentMin = value;
_hasBeenAnnotated = true; _hasBeenAnnotated = true;
...@@ -3775,8 +3775,8 @@ class SemanticsConfiguration { ...@@ -3775,8 +3775,8 @@ class SemanticsConfiguration {
/// ///
/// * [addTagForChildren] to add a tag and for more information about their /// * [addTagForChildren] to add a tag and for more information about their
/// usage. /// usage.
Iterable<SemanticsTag> get tagsForChildren => _tagsForChildren; Iterable<SemanticsTag>? get tagsForChildren => _tagsForChildren;
Set<SemanticsTag> _tagsForChildren; Set<SemanticsTag>? _tagsForChildren;
/// Specifies a [SemanticsTag] that this configuration wants to apply to all /// Specifies a [SemanticsTag] that this configuration wants to apply to all
/// child [SemanticsNode]s. /// child [SemanticsNode]s.
...@@ -3795,7 +3795,7 @@ class SemanticsConfiguration { ...@@ -3795,7 +3795,7 @@ class SemanticsConfiguration {
/// how tags are used. /// how tags are used.
void addTagForChildren(SemanticsTag tag) { void addTagForChildren(SemanticsTag tag) {
_tagsForChildren ??= <SemanticsTag>{}; _tagsForChildren ??= <SemanticsTag>{};
_tagsForChildren.add(tag); _tagsForChildren!.add(tag);
} }
// INTERNAL FLAG MANAGEMENT // INTERNAL FLAG MANAGEMENT
...@@ -3819,7 +3819,7 @@ class SemanticsConfiguration { ...@@ -3819,7 +3819,7 @@ class SemanticsConfiguration {
/// ///
/// Two configurations are said to be compatible if they can be added to the /// Two configurations are said to be compatible if they can be added to the
/// same [SemanticsNode] without losing any semantics information. /// same [SemanticsNode] without losing any semantics information.
bool isCompatibleWith(SemanticsConfiguration other) { bool isCompatibleWith(SemanticsConfiguration? other) {
if (other == null || !other.hasBeenAnnotated || !hasBeenAnnotated) if (other == null || !other.hasBeenAnnotated || !hasBeenAnnotated)
return true; return true;
if (_actionsAsBits & other._actionsAsBits != 0) if (_actionsAsBits & other._actionsAsBits != 0)
...@@ -3953,10 +3953,10 @@ enum DebugSemanticsDumpOrder { ...@@ -3953,10 +3953,10 @@ enum DebugSemanticsDumpOrder {
} }
String _concatStrings({ String _concatStrings({
@required String thisString, required String thisString,
@required String otherString, required String otherString,
@required TextDirection thisTextDirection, required TextDirection? thisTextDirection,
@required TextDirection otherTextDirection, required TextDirection? otherTextDirection,
}) { }) {
if (otherString.isEmpty) if (otherString.isEmpty)
return thisString; return thisString;
...@@ -4004,7 +4004,7 @@ abstract class SemanticsSortKey with Diagnosticable implements Comparable<Semant ...@@ -4004,7 +4004,7 @@ abstract class SemanticsSortKey with Diagnosticable implements Comparable<Semant
/// ///
/// Keys with no [name] are compared to other keys with no [name], and will /// Keys with no [name] are compared to other keys with no [name], and will
/// be traversed before those with a [name]. /// be traversed before those with a [name].
final String name; final String? name;
@override @override
int compareTo(SemanticsSortKey other) { int compareTo(SemanticsSortKey other) {
...@@ -4025,7 +4025,7 @@ abstract class SemanticsSortKey with Diagnosticable implements Comparable<Semant ...@@ -4025,7 +4025,7 @@ abstract class SemanticsSortKey with Diagnosticable implements Comparable<Semant
return 1; return 1;
} }
return name.compareTo(other.name); return name!.compareTo(other.name!);
} }
/// The implementation of [compareTo]. /// The implementation of [compareTo].
...@@ -4071,7 +4071,7 @@ class OrdinalSortKey extends SemanticsSortKey { ...@@ -4071,7 +4071,7 @@ class OrdinalSortKey extends SemanticsSortKey {
/// The [order] must be a finite number, and must not be null. /// The [order] must be a finite number, and must not be null.
const OrdinalSortKey( const OrdinalSortKey(
this.order, { this.order, {
String name, String? name,
}) : assert(order != null), }) : assert(order != null),
assert(order != double.nan), assert(order != double.nan),
assert(order > double.negativeInfinity), assert(order > double.negativeInfinity),
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/painting.dart'; import 'package:flutter/painting.dart';
...@@ -30,7 +29,7 @@ abstract class SemanticsEvent { ...@@ -30,7 +29,7 @@ abstract class SemanticsEvent {
/// ///
/// [nodeId] is the unique identifier of the semantics node associated with /// [nodeId] is the unique identifier of the semantics node associated with
/// the event, or null if the event is not associated with a semantics node. /// the event, or null if the event is not associated with a semantics node.
Map<String, dynamic> toMap({ int nodeId }) { Map<String, dynamic> toMap({ int? nodeId }) {
final Map<String, dynamic> event = <String, dynamic>{ final Map<String, dynamic> event = <String, dynamic>{
'type': type, 'type': type,
'data': getDataMap(), 'data': getDataMap(),
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:async'; import 'dart:async';
import 'dart:ui' show TextDirection; import 'dart:ui' show TextDirection;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment