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