Add @protected to public State method overrides (#157313)

I don't want to see these methods in my autofill suggestions.

<br>

![navigator
dispose](https://github.com/user-attachments/assets/5d2dc37c-abe9-44f4-ad16-4396a3aeeaf7)
This commit is contained in:
Nate Wilson 2024-11-18 14:28:08 -07:00 committed by GitHub
parent ff47d63235
commit c25790e3db
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
26 changed files with 223 additions and 5 deletions

View File

@ -22,6 +22,7 @@ import 'custom_rules/analyze.dart';
import 'custom_rules/avoid_future_catcherror.dart'; import 'custom_rules/avoid_future_catcherror.dart';
import 'custom_rules/no_double_clamp.dart'; import 'custom_rules/no_double_clamp.dart';
import 'custom_rules/no_stop_watches.dart'; import 'custom_rules/no_stop_watches.dart';
import 'custom_rules/protect_public_state_subtypes.dart';
import 'custom_rules/render_box_intrinsics.dart'; import 'custom_rules/render_box_intrinsics.dart';
import 'run_command.dart'; import 'run_command.dart';
import 'utils.dart'; import 'utils.dart';
@ -180,7 +181,12 @@ Future<void> run(List<String> arguments) async {
// Only run the private lints when the code is free of type errors. The // Only run the private lints when the code is free of type errors. The
// lints are easier to write when they can assume, for example, there is no // lints are easier to write when they can assume, for example, there is no
// inheritance cycles. // inheritance cycles.
final List<AnalyzeRule> rules = <AnalyzeRule>[noDoubleClamp, noStopwatches, renderBoxIntrinsicCalculation]; final List<AnalyzeRule> rules = <AnalyzeRule>[
noDoubleClamp,
noStopwatches,
renderBoxIntrinsicCalculation,
protectPublicStateSubtypes,
];
final String ruleNames = rules.map((AnalyzeRule rule) => '\n * $rule').join(); final String ruleNames = rules.map((AnalyzeRule rule) => '\n * $rule').join();
printProgress('Analyzing code in the framework with the following rules:$ruleNames'); printProgress('Analyzing code in the framework with the following rules:$ruleNames');
await analyzeWithRules(flutterRoot, rules, await analyzeWithRules(flutterRoot, rules,

View File

@ -0,0 +1,101 @@
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// TODO(nate-thegrate): remove this file if @protected changes, or add a test if it doesn't.
// https://github.com/dart-lang/sdk/issues/57094
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import '../utils.dart';
import 'analyze.dart';
final AnalyzeRule protectPublicStateSubtypes = _ProtectPublicStateSubtypes();
class _ProtectPublicStateSubtypes implements AnalyzeRule {
final Map<ResolvedUnitResult, List<MethodDeclaration>> _errors = <ResolvedUnitResult, List<MethodDeclaration>>{};
@override
void applyTo(ResolvedUnitResult unit) {
final _StateSubclassVisitor visitor = _StateSubclassVisitor();
unit.unit.visitChildren(visitor);
final List<MethodDeclaration> unprotected = visitor.unprotectedMethods;
if (unprotected.isNotEmpty) {
_errors.putIfAbsent(unit, () => <MethodDeclaration>[]).addAll(unprotected);
}
}
@override
void reportViolations(String workingDirectory) {
if (_errors.isEmpty) {
return;
}
foundError(
<String>[
for (final MapEntry<ResolvedUnitResult, List<MethodDeclaration>> entry in _errors.entries)
for (final MethodDeclaration method in entry.value)
'${locationInFile(entry.key, method, workingDirectory)}: $method - missing "@protected" annotation.',
'\nPublic State subtypes should add @protected when overriding methods,',
'to avoid exposing internal logic to developers.',
],
);
}
@override
String toString() => 'Add "@protected" to public State subtypes';
}
class _StateSubclassVisitor extends SimpleAstVisitor<void> {
final List<MethodDeclaration> unprotectedMethods = <MethodDeclaration>[];
/// Holds the `State` class [DartType].
static DartType? stateType;
static bool isPublicStateSubtype(InterfaceElement element) {
if (!element.isPublic) {
return false;
}
if (stateType != null) {
return element.allSupertypes.contains(stateType);
}
for (final InterfaceType superType in element.allSupertypes) {
if (superType.element.name == 'State') {
stateType = superType;
return true;
}
}
return false;
}
@override
void visitClassDeclaration(ClassDeclaration node) {
if (isPublicStateSubtype(node.declaredElement!)) {
node.visitChildren(this);
}
}
/// Checks whether overridden `State` methods have the `@protected` annotation,
/// and adds the declaration to [unprotectedMethods] if not.
@override
void visitMethodDeclaration(MethodDeclaration node) {
switch (node.name.lexeme) {
case 'initState':
case 'didUpdateWidget':
case 'didChangeDependencies':
case 'reassemble':
case 'deactivate':
case 'activate':
case 'dispose':
case 'build':
case 'debugFillProperties':
if (!node.declaredElement!.hasProtected) {
unprotectedMethods.add(node);
}
}
}
}

View File

@ -468,6 +468,7 @@ class DrawerController extends StatefulWidget {
/// ///
/// Typically used by a [Scaffold] to [open] and [close] the drawer. /// Typically used by a [Scaffold] to [open] and [close] the drawer.
class DrawerControllerState extends State<DrawerController> with SingleTickerProviderStateMixin { class DrawerControllerState extends State<DrawerController> with SingleTickerProviderStateMixin {
@protected
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -481,6 +482,7 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
..addStatusListener(_animationStatusChanged); ..addStatusListener(_animationStatusChanged);
} }
@protected
@override @override
void dispose() { void dispose() {
_historyEntry?.remove(); _historyEntry?.remove();
@ -489,12 +491,14 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
super.dispose(); super.dispose();
} }
@protected
@override @override
void didChangeDependencies() { void didChangeDependencies() {
super.didChangeDependencies(); super.didChangeDependencies();
_scrimColorTween = _buildScrimColorTween(); _scrimColorTween = _buildScrimColorTween();
} }
@protected
@override @override
void didUpdateWidget(DrawerController oldWidget) { void didUpdateWidget(DrawerController oldWidget) {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
@ -751,6 +755,7 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
} }
} }
@protected
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
assert(debugCheckHasMaterialLocalizations(context)); assert(debugCheckHasMaterialLocalizations(context));

View File

@ -331,6 +331,7 @@ class PaginatedDataTableState extends State<PaginatedDataTable> {
int _selectedRowCount = 0; int _selectedRowCount = 0;
final Map<int, DataRow?> _rows = <int, DataRow?>{}; final Map<int, DataRow?> _rows = <int, DataRow?>{};
@protected
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -339,6 +340,7 @@ class PaginatedDataTableState extends State<PaginatedDataTable> {
_handleDataSourceChanged(); _handleDataSourceChanged();
} }
@protected
@override @override
void didUpdateWidget(PaginatedDataTable oldWidget) { void didUpdateWidget(PaginatedDataTable oldWidget) {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
@ -349,6 +351,7 @@ class PaginatedDataTableState extends State<PaginatedDataTable> {
} }
} }
@protected
@override @override
void reassemble() { void reassemble() {
super.reassemble(); super.reassemble();
@ -366,6 +369,7 @@ class PaginatedDataTableState extends State<PaginatedDataTable> {
_updateCaches(); _updateCaches();
} }
@protected
@override @override
void dispose() { void dispose() {
widget.source.removeListener(_handleDataSourceChanged); widget.source.removeListener(_handleDataSourceChanged);
@ -468,6 +472,7 @@ class PaginatedDataTableState extends State<PaginatedDataTable> {
final GlobalKey _tableKey = GlobalKey(); final GlobalKey _tableKey = GlobalKey();
@protected
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// TODO(ianh): This whole build function doesn't handle RTL yet. // TODO(ianh): This whole build function doesn't handle RTL yet.

View File

@ -356,6 +356,7 @@ class PopupMenuItemState<T, W extends PopupMenuItem<T>> extends State<W> {
widget.onTap?.call(); widget.onTap?.call();
} }
@protected
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context); final ThemeData theme = Theme.of(context);
@ -1544,6 +1545,7 @@ class PopupMenuButtonState<T> extends State<PopupMenuButton<T>> {
}; };
} }
@protected
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final IconThemeData iconTheme = IconTheme.of(context); final IconThemeData iconTheme = IconTheme.of(context);

View File

@ -352,6 +352,7 @@ class RefreshIndicatorState extends State<RefreshIndicator>
end: 0.0, end: 0.0,
); );
@protected
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -365,12 +366,14 @@ class RefreshIndicatorState extends State<RefreshIndicator>
_scaleFactor = _scaleController.drive(_oneToZeroTween); _scaleFactor = _scaleController.drive(_oneToZeroTween);
} }
@protected
@override @override
void didChangeDependencies() { void didChangeDependencies() {
_setupColorTween(); _setupColorTween();
super.didChangeDependencies(); super.didChangeDependencies();
} }
@protected
@override @override
void didUpdateWidget(covariant RefreshIndicator oldWidget) { void didUpdateWidget(covariant RefreshIndicator oldWidget) {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
@ -379,6 +382,7 @@ class RefreshIndicatorState extends State<RefreshIndicator>
} }
} }
@protected
@override @override
void dispose() { void dispose() {
_positionController.dispose(); _positionController.dispose();
@ -636,6 +640,7 @@ class RefreshIndicatorState extends State<RefreshIndicator>
return _pendingRefreshFuture; return _pendingRefreshFuture;
} }
@protected
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
assert(debugCheckHasMaterialLocalizations(context)); assert(debugCheckHasMaterialLocalizations(context));

View File

@ -197,6 +197,7 @@ class ScaffoldMessengerState extends State<ScaffoldMessenger> with TickerProvide
Timer? _snackBarTimer; Timer? _snackBarTimer;
bool? _accessibleNavigation; bool? _accessibleNavigation;
@protected
@override @override
void didChangeDependencies() { void didChangeDependencies() {
final bool accessibleNavigation = MediaQuery.accessibleNavigationOf(context); final bool accessibleNavigation = MediaQuery.accessibleNavigationOf(context);
@ -604,6 +605,7 @@ class ScaffoldMessengerState extends State<ScaffoldMessenger> with TickerProvide
hideCurrentMaterialBanner(); hideCurrentMaterialBanner();
} }
@protected
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
assert(debugCheckHasMediaQuery(context)); assert(debugCheckHasMediaQuery(context));
@ -632,6 +634,7 @@ class ScaffoldMessengerState extends State<ScaffoldMessenger> with TickerProvide
); );
} }
@protected
@override @override
void dispose() { void dispose() {
_materialBannerController?.dispose(); _materialBannerController?.dispose();
@ -2116,6 +2119,7 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto
@override @override
String? get restorationId => widget.restorationId; String? get restorationId => widget.restorationId;
@protected
@override @override
void restoreState(RestorationBucket? oldBucket, bool initialRestore) { void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
registerForRestoration(_drawerOpened, 'drawer_open'); registerForRestoration(_drawerOpened, 'drawer_open');
@ -2676,6 +2680,7 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto
return widget.resizeToAvoidBottomInset ?? true; return widget.resizeToAvoidBottomInset ?? true;
} }
@protected
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -2695,6 +2700,7 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto
); );
} }
@protected
@override @override
void didUpdateWidget(Scaffold oldWidget) { void didUpdateWidget(Scaffold oldWidget) {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
@ -2732,6 +2738,7 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto
} }
} }
@protected
@override @override
void didChangeDependencies() { void didChangeDependencies() {
// Using maybeOf is valid here since both the Scaffold and ScaffoldMessenger // Using maybeOf is valid here since both the Scaffold and ScaffoldMessenger
@ -2750,6 +2757,7 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto
super.didChangeDependencies(); super.didChangeDependencies();
} }
@protected
@override @override
void dispose() { void dispose() {
_geometryNotifier.dispose(); _geometryNotifier.dispose();
@ -2864,6 +2872,7 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto
}); });
} }
@protected
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
assert(debugCheckHasMediaQuery(context)); assert(debugCheckHasMediaQuery(context));

View File

@ -426,6 +426,7 @@ class SegmentedButtonState<T> extends State<SegmentedButton<T>> {
@visibleForTesting @visibleForTesting
final Map<ButtonSegment<T>, MaterialStatesController> statesControllers = <ButtonSegment<T>, MaterialStatesController>{}; final Map<ButtonSegment<T>, MaterialStatesController> statesControllers = <ButtonSegment<T>, MaterialStatesController>{};
@protected
@override @override
void didUpdateWidget(covariant SegmentedButton<T> oldWidget) { void didUpdateWidget(covariant SegmentedButton<T> oldWidget) {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
@ -464,6 +465,7 @@ class SegmentedButtonState<T> extends State<SegmentedButton<T>> {
} }
} }
@protected
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final SegmentedButtonThemeData theme = SegmentedButtonTheme.of(context); final SegmentedButtonThemeData theme = SegmentedButtonTheme.of(context);
@ -605,6 +607,7 @@ class SegmentedButtonState<T> extends State<SegmentedButton<T>> {
); );
} }
@protected
@override @override
void dispose() { void dispose() {
for (final MaterialStatesController controller in statesControllers.values) { for (final MaterialStatesController controller in statesControllers.values) {

View File

@ -113,6 +113,7 @@ class SelectionAreaState extends State<SelectionArea> {
/// The [State] of the [SelectableRegion] for which this [SelectionArea] wraps. /// The [State] of the [SelectableRegion] for which this [SelectionArea] wraps.
SelectableRegionState get selectableRegion => _selectableRegionKey.currentState!; SelectableRegionState get selectableRegion => _selectableRegionKey.currentState!;
@protected
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
assert(debugCheckHasMaterialLocalizations(context)); assert(debugCheckHasMaterialLocalizations(context));

View File

@ -706,6 +706,7 @@ class TooltipState extends State<Tooltip> with SingleTickerProviderStateMixin {
return true; return true;
} }
@protected
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -715,6 +716,7 @@ class TooltipState extends State<Tooltip> with SingleTickerProviderStateMixin {
GestureBinding.instance.pointerRouter.addGlobalRoute(_handleGlobalPointerEvent); GestureBinding.instance.pointerRouter.addGlobalRoute(_handleGlobalPointerEvent);
} }
@protected
@override @override
void didChangeDependencies() { void didChangeDependencies() {
super.didChangeDependencies(); super.didChangeDependencies();
@ -797,6 +799,7 @@ class TooltipState extends State<Tooltip> with SingleTickerProviderStateMixin {
: SelectionContainer.disabled(child: overlayChild); : SelectionContainer.disabled(child: overlayChild);
} }
@protected
@override @override
void dispose() { void dispose() {
GestureBinding.instance.pointerRouter.removeGlobalRoute(_handleGlobalPointerEvent); GestureBinding.instance.pointerRouter.removeGlobalRoute(_handleGlobalPointerEvent);
@ -815,6 +818,7 @@ class TooltipState extends State<Tooltip> with SingleTickerProviderStateMixin {
super.dispose(); super.dispose();
} }
@protected
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// If message is empty then no need to create a tooltip overlay to show // If message is empty then no need to create a tooltip overlay to show

View File

@ -299,7 +299,7 @@ class AnimatedList extends _AnimatedScrollView {
/// [AnimatedList] item input handlers can also refer to their [AnimatedListState] /// [AnimatedList] item input handlers can also refer to their [AnimatedListState]
/// with the static [AnimatedList.of] method. /// with the static [AnimatedList.of] method.
class AnimatedListState extends _AnimatedScrollViewState<AnimatedList> { class AnimatedListState extends _AnimatedScrollViewState<AnimatedList> {
@protected
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return _wrap( return _wrap(
@ -508,7 +508,7 @@ class AnimatedGrid extends _AnimatedScrollView {
/// [AnimatedGrid] item input handlers can also refer to their [AnimatedGridState] /// [AnimatedGrid] item input handlers can also refer to their [AnimatedGridState]
/// with the static [AnimatedGrid.of] method. /// with the static [AnimatedGrid.of] method.
class AnimatedGridState extends _AnimatedScrollViewState<AnimatedGrid> { class AnimatedGridState extends _AnimatedScrollViewState<AnimatedGrid> {
@protected
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return _wrap( return _wrap(
@ -1040,7 +1040,7 @@ class SliverAnimatedList extends _SliverAnimatedMultiBoxAdaptor {
/// [SliverAnimatedList] item input handlers can also refer to their /// [SliverAnimatedList] item input handlers can also refer to their
/// [SliverAnimatedListState] with the static [SliverAnimatedList.of] method. /// [SliverAnimatedListState] with the static [SliverAnimatedList.of] method.
class SliverAnimatedListState extends _SliverAnimatedMultiBoxAdaptorState<SliverAnimatedList> { class SliverAnimatedListState extends _SliverAnimatedMultiBoxAdaptorState<SliverAnimatedList> {
@protected
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SliverList( return SliverList(
@ -1187,7 +1187,7 @@ class SliverAnimatedGrid extends _SliverAnimatedMultiBoxAdaptor {
/// [SliverAnimatedGrid] item input handlers can also refer to their /// [SliverAnimatedGrid] item input handlers can also refer to their
/// [SliverAnimatedGridState] with the static [SliverAnimatedGrid.of] method. /// [SliverAnimatedGridState] with the static [SliverAnimatedGrid.of] method.
class SliverAnimatedGridState extends _SliverAnimatedMultiBoxAdaptorState<SliverAnimatedGrid> { class SliverAnimatedGridState extends _SliverAnimatedMultiBoxAdaptorState<SliverAnimatedGrid> {
@protected
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SliverGrid( return SliverGrid(

View File

@ -213,12 +213,14 @@ class AutofillGroupState extends State<AutofillGroup> with AutofillScopeMixin {
_clients.remove(autofillId); _clients.remove(autofillId);
} }
@protected
@override @override
void didChangeDependencies() { void didChangeDependencies() {
super.didChangeDependencies(); super.didChangeDependencies();
_isTopmostAutofillGroup = AutofillGroup.maybeOf(context) == null; _isTopmostAutofillGroup = AutofillGroup.maybeOf(context) == null;
} }
@protected
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return _AutofillScope( return _AutofillScope(
@ -227,6 +229,7 @@ class AutofillGroupState extends State<AutofillGroup> with AutofillScopeMixin {
); );
} }
@protected
@override @override
void dispose() { void dispose() {
super.dispose(); super.dispose();

View File

@ -2979,6 +2979,7 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
// State lifecycle: // State lifecycle:
@protected
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -3005,6 +3006,7 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
// cursor) are supposed to run. // cursor) are supposed to run.
bool _tickersEnabled = true; bool _tickersEnabled = true;
@protected
@override @override
void didChangeDependencies() { void didChangeDependencies() {
super.didChangeDependencies(); super.didChangeDependencies();
@ -3080,6 +3082,7 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
} }
} }
@protected
@override @override
void didUpdateWidget(EditableText oldWidget) { void didUpdateWidget(EditableText oldWidget) {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
@ -3183,6 +3186,7 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
} }
} }
@protected
@override @override
void dispose() { void dispose() {
_internalScrollController?.dispose(); _internalScrollController?.dispose();
@ -5178,6 +5182,7 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
EditableTextTapOutsideIntent: _makeOverridable(_EditableTextTapOutsideAction()), EditableTextTapOutsideIntent: _makeOverridable(_EditableTextTapOutsideAction()),
}; };
@protected
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
assert(debugCheckHasMediaQuery(context)); assert(debugCheckHasMediaQuery(context));

View File

@ -268,6 +268,7 @@ class FormState extends State<Form> {
} }
} }
@protected
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
switch (widget.autovalidateMode) { switch (widget.autovalidateMode) {
@ -671,24 +672,28 @@ class FormFieldState<T> extends State<FormField<T>> with RestorationMixin {
@override @override
String? get restorationId => widget.restorationId; String? get restorationId => widget.restorationId;
@protected
@override @override
void restoreState(RestorationBucket? oldBucket, bool initialRestore) { void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
registerForRestoration(_errorText, 'error_text'); registerForRestoration(_errorText, 'error_text');
registerForRestoration(_hasInteractedByUser, 'has_interacted_by_user'); registerForRestoration(_hasInteractedByUser, 'has_interacted_by_user');
} }
@protected
@override @override
void deactivate() { void deactivate() {
Form.maybeOf(context)?._unregister(this); Form.maybeOf(context)?._unregister(this);
super.deactivate(); super.deactivate();
} }
@protected
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_errorText = RestorableStringN(widget.forceErrorText); _errorText = RestorableStringN(widget.forceErrorText);
} }
@protected
@override @override
void didUpdateWidget(FormField<T> oldWidget) { void didUpdateWidget(FormField<T> oldWidget) {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
@ -697,6 +702,7 @@ class FormFieldState<T> extends State<FormField<T>> with RestorationMixin {
} }
} }
@protected
@override @override
void dispose() { void dispose() {
_errorText.dispose(); _errorText.dispose();
@ -705,6 +711,7 @@ class FormFieldState<T> extends State<FormField<T>> with RestorationMixin {
super.dispose(); super.dispose();
} }
@protected
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (widget.enabled) { if (widget.enabled) {

View File

@ -1495,6 +1495,9 @@ abstract class State<T extends StatefulWidget> with Diagnosticable {
properties.add(ObjectFlagProperty<T>('_widget', _widget, ifNull: 'no widget')); properties.add(ObjectFlagProperty<T>('_widget', _widget, ifNull: 'no widget'));
properties.add(ObjectFlagProperty<StatefulElement>('_element', _element, ifNull: 'not mounted')); properties.add(ObjectFlagProperty<StatefulElement>('_element', _element, ifNull: 'not mounted'));
} }
// If @protected State methods are added or removed, the analysis rule should be
// updated accordingly (dev/bots/custom_rules/protect_public_state_subtypes.dart)
} }
/// A widget that has a child widget provided to it, instead of building a new /// A widget that has a child widget provided to it, instead of building a new

View File

@ -1405,6 +1405,7 @@ class RawGestureDetectorState extends State<RawGestureDetector> {
Map<Type, GestureRecognizer>? _recognizers = const <Type, GestureRecognizer>{}; Map<Type, GestureRecognizer>? _recognizers = const <Type, GestureRecognizer>{};
SemanticsGestureDelegate? _semantics; SemanticsGestureDelegate? _semantics;
@protected
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -1412,6 +1413,7 @@ class RawGestureDetectorState extends State<RawGestureDetector> {
_syncAll(widget.gestures); _syncAll(widget.gestures);
} }
@protected
@override @override
void didUpdateWidget(RawGestureDetector oldWidget) { void didUpdateWidget(RawGestureDetector oldWidget) {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
@ -1486,6 +1488,7 @@ class RawGestureDetectorState extends State<RawGestureDetector> {
semanticsGestureHandler!.validActions = actions; // will call _markNeedsSemanticsUpdate(), if required. semanticsGestureHandler!.validActions = actions; // will call _markNeedsSemanticsUpdate(), if required.
} }
@protected
@override @override
void dispose() { void dispose() {
for (final GestureRecognizer recognizer in _recognizers!.values) { for (final GestureRecognizer recognizer in _recognizers!.values) {
@ -1538,6 +1541,7 @@ class RawGestureDetectorState extends State<RawGestureDetector> {
_semantics!.assignSemantics(renderObject); _semantics!.assignSemantics(renderObject);
} }
@protected
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Widget result = Listener( Widget result = Listener(
@ -1556,6 +1560,7 @@ class RawGestureDetectorState extends State<RawGestureDetector> {
return result; return result;
} }
@protected
@override @override
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties); super.debugFillProperties(properties);

View File

@ -369,6 +369,7 @@ abstract class ImplicitlyAnimatedWidgetState<T extends ImplicitlyAnimatedWidget>
Animation<double> get animation => _animation; Animation<double> get animation => _animation;
late CurvedAnimation _animation = _createCurve(); late CurvedAnimation _animation = _createCurve();
@protected
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -381,6 +382,7 @@ abstract class ImplicitlyAnimatedWidgetState<T extends ImplicitlyAnimatedWidget>
didUpdateTweens(); didUpdateTweens();
} }
@protected
@override @override
void didUpdateWidget(T oldWidget) { void didUpdateWidget(T oldWidget) {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
@ -405,6 +407,7 @@ abstract class ImplicitlyAnimatedWidgetState<T extends ImplicitlyAnimatedWidget>
return CurvedAnimation(parent: _controller, curve: widget.curve); return CurvedAnimation(parent: _controller, curve: widget.curve);
} }
@protected
@override @override
void dispose() { void dispose() {
_animation.dispose(); _animation.dispose();
@ -554,6 +557,7 @@ abstract class ImplicitlyAnimatedWidgetState<T extends ImplicitlyAnimatedWidget>
/// [AnimatedWidgetBaseState] to iterate through the subclasses' widget's fields /// [AnimatedWidgetBaseState] to iterate through the subclasses' widget's fields
/// and animate them. /// and animate them.
abstract class AnimatedWidgetBaseState<T extends ImplicitlyAnimatedWidget> extends ImplicitlyAnimatedWidgetState<T> { abstract class AnimatedWidgetBaseState<T extends ImplicitlyAnimatedWidget> extends ImplicitlyAnimatedWidgetState<T> {
@protected
@override @override
void initState() { void initState() {
super.initState(); super.initState();

View File

@ -3706,6 +3706,7 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
return true; return true;
} }
@protected
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -3742,6 +3743,7 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
int get _nextPagelessRestorationScopeId => _rawNextPagelessRestorationScopeId.value++; int get _nextPagelessRestorationScopeId => _rawNextPagelessRestorationScopeId.value++;
@protected
@override @override
void restoreState(RestorationBucket? oldBucket, bool initialRestore) { void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
registerForRestoration(_rawNextPagelessRestorationScopeId, 'id'); registerForRestoration(_rawNextPagelessRestorationScopeId, 'id');
@ -3810,6 +3812,7 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
assert(() { _debugLocked = false; return true; }()); assert(() { _debugLocked = false; return true; }());
} }
@protected
@override @override
void didToggleBucket(RestorationBucket? oldBucket) { void didToggleBucket(RestorationBucket? oldBucket) {
super.didToggleBucket(oldBucket); super.didToggleBucket(oldBucket);
@ -3822,6 +3825,7 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
@override @override
String? get restorationId => widget.restorationScopeId; String? get restorationId => widget.restorationScopeId;
@protected
@override @override
void didChangeDependencies() { void didChangeDependencies() {
super.didChangeDependencies(); super.didChangeDependencies();
@ -3915,6 +3919,7 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
} }
} }
@protected
@override @override
void didUpdateWidget(Navigator oldWidget) { void didUpdateWidget(Navigator oldWidget) {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
@ -3969,6 +3974,7 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
}()); }());
} }
@protected
@override @override
void deactivate() { void deactivate() {
for (final NavigatorObserver observer in _effectiveObservers) { for (final NavigatorObserver observer in _effectiveObservers) {
@ -3978,6 +3984,7 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
super.deactivate(); super.deactivate();
} }
@protected
@override @override
void activate() { void activate() {
super.activate(); super.activate();
@ -3988,6 +3995,7 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
} }
} }
@protected
@override @override
void dispose() { void dispose() {
assert(!_debugLocked); assert(!_debugLocked);
@ -5646,6 +5654,7 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
return result; return result;
} }
@protected
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
assert(!_debugLocked); assert(!_debugLocked);

View File

@ -425,6 +425,7 @@ class NestedScrollViewState extends State<NestedScrollView> {
_NestedScrollCoordinator? _coordinator; _NestedScrollCoordinator? _coordinator;
@protected
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -436,12 +437,14 @@ class NestedScrollViewState extends State<NestedScrollView> {
); );
} }
@protected
@override @override
void didChangeDependencies() { void didChangeDependencies() {
super.didChangeDependencies(); super.didChangeDependencies();
_coordinator!.setParent(widget.controller); _coordinator!.setParent(widget.controller);
} }
@protected
@override @override
void didUpdateWidget(NestedScrollView oldWidget) { void didUpdateWidget(NestedScrollView oldWidget) {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
@ -450,6 +453,7 @@ class NestedScrollViewState extends State<NestedScrollView> {
} }
} }
@protected
@override @override
void dispose() { void dispose() {
_coordinator!.dispose(); _coordinator!.dispose();
@ -476,6 +480,7 @@ class NestedScrollViewState extends State<NestedScrollView> {
} }
} }
@protected
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final ScrollPhysics scrollPhysics = widget.physics?.applyTo(const ClampingScrollPhysics()) final ScrollPhysics scrollPhysics = widget.physics?.applyTo(const ClampingScrollPhysics())

View File

@ -604,6 +604,7 @@ class Overlay extends StatefulWidget {
class OverlayState extends State<Overlay> with TickerProviderStateMixin { class OverlayState extends State<Overlay> with TickerProviderStateMixin {
final List<OverlayEntry> _entries = <OverlayEntry>[]; final List<OverlayEntry> _entries = <OverlayEntry>[];
@protected
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -808,6 +809,7 @@ class OverlayState extends State<Overlay> with TickerProviderStateMixin {
}); });
} }
@protected
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// This list is filled backwards and then reversed below before // This list is filled backwards and then reversed below before
@ -842,6 +844,7 @@ class OverlayState extends State<Overlay> with TickerProviderStateMixin {
); );
} }
@protected
@override @override
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties); super.debugFillProperties(properties);

View File

@ -388,6 +388,7 @@ class ReorderableListState extends State<ReorderableList> {
_sliverReorderableListKey.currentState!.cancelReorder(); _sliverReorderableListKey.currentState!.cancelReorder();
} }
@protected
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return CustomScrollView( return CustomScrollView(
@ -630,6 +631,7 @@ class SliverReorderableListState extends State<SliverReorderableList> with Ticke
Axis get _scrollDirection => axisDirectionToAxis(_scrollable.axisDirection); Axis get _scrollDirection => axisDirectionToAxis(_scrollable.axisDirection);
bool get _reverse => axisDirectionIsReversed(_scrollable.axisDirection); bool get _reverse => axisDirectionIsReversed(_scrollable.axisDirection);
@protected
@override @override
void didChangeDependencies() { void didChangeDependencies() {
super.didChangeDependencies(); super.didChangeDependencies();
@ -644,6 +646,7 @@ class SliverReorderableListState extends State<SliverReorderableList> with Ticke
} }
} }
@protected
@override @override
void didUpdateWidget(covariant SliverReorderableList oldWidget) { void didUpdateWidget(covariant SliverReorderableList oldWidget) {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
@ -661,6 +664,7 @@ class SliverReorderableListState extends State<SliverReorderableList> with Ticke
} }
} }
@protected
@override @override
void dispose() { void dispose() {
_dragReset(); _dragReset();
@ -1030,6 +1034,7 @@ class SliverReorderableListState extends State<SliverReorderableList> with Ticke
); );
} }
@protected
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
assert(debugCheckHasOverlay(context)); assert(debugCheckHasOverlay(context));

View File

@ -216,6 +216,7 @@ class ScrollNotificationObserverState extends State<ScrollNotificationObserver>
} }
} }
@protected
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return NotificationListener<ScrollMetricsNotification>( return NotificationListener<ScrollMetricsNotification>(
@ -239,6 +240,7 @@ class ScrollNotificationObserverState extends State<ScrollNotificationObserver>
); );
} }
@protected
@override @override
void dispose() { void dispose() {
assert(_debugAssertNotDisposed()); assert(_debugAssertNotDisposed());

View File

@ -626,6 +626,7 @@ class ScrollableState extends State<Scrollable> with TickerProviderStateMixin, R
_effectiveScrollController.attach(position); _effectiveScrollController.attach(position);
} }
@protected
@override @override
void restoreState(RestorationBucket? oldBucket, bool initialRestore) { void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
registerForRestoration(_persistedScrollOffset, 'offset'); registerForRestoration(_persistedScrollOffset, 'offset');
@ -635,6 +636,7 @@ class ScrollableState extends State<Scrollable> with TickerProviderStateMixin, R
} }
} }
@protected
@override @override
void saveOffset(double offset) { void saveOffset(double offset) {
assert(debugIsSerializableForRestoration(offset)); assert(debugIsSerializableForRestoration(offset));
@ -644,6 +646,7 @@ class ScrollableState extends State<Scrollable> with TickerProviderStateMixin, R
ServicesBinding.instance.restorationManager.flushData(); ServicesBinding.instance.restorationManager.flushData();
} }
@protected
@override @override
void initState() { void initState() {
if (widget.controller == null) { if (widget.controller == null) {
@ -652,6 +655,7 @@ class ScrollableState extends State<Scrollable> with TickerProviderStateMixin, R
super.initState(); super.initState();
} }
@protected
@override @override
void didChangeDependencies() { void didChangeDependencies() {
_mediaQueryGestureSettings = MediaQuery.maybeGestureSettingsOf(context); _mediaQueryGestureSettings = MediaQuery.maybeGestureSettingsOf(context);
@ -680,6 +684,7 @@ class ScrollableState extends State<Scrollable> with TickerProviderStateMixin, R
return widget.controller?.runtimeType != oldWidget.controller?.runtimeType; return widget.controller?.runtimeType != oldWidget.controller?.runtimeType;
} }
@protected
@override @override
void didUpdateWidget(Scrollable oldWidget) { void didUpdateWidget(Scrollable oldWidget) {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
@ -711,6 +716,7 @@ class ScrollableState extends State<Scrollable> with TickerProviderStateMixin, R
} }
} }
@protected
@override @override
void dispose() { void dispose() {
if (widget.controller != null) { if (widget.controller != null) {
@ -980,6 +986,7 @@ class ScrollableState extends State<Scrollable> with TickerProviderStateMixin, R
// DESCRIPTION // DESCRIPTION
@protected
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
assert(_position != null); assert(_position != null);
@ -1064,6 +1071,7 @@ class ScrollableState extends State<Scrollable> with TickerProviderStateMixin, R
return (<Future<void>>[ ensureVisibleFuture ], this); return (<Future<void>>[ ensureVisibleFuture ], this);
} }
@protected
@override @override
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties); super.debugFillProperties(properties);
@ -1934,6 +1942,7 @@ class TwoDimensionalScrollableState extends State<TwoDimensionalScrollable> {
return _horizontalInnerScrollableKey.currentState!; return _horizontalInnerScrollableKey.currentState!;
} }
@protected
@override @override
void initState() { void initState() {
if (widget.verticalDetails.controller == null) { if (widget.verticalDetails.controller == null) {
@ -1945,6 +1954,7 @@ class TwoDimensionalScrollableState extends State<TwoDimensionalScrollable> {
super.initState(); super.initState();
} }
@protected
@override @override
void didUpdateWidget(TwoDimensionalScrollable oldWidget) { void didUpdateWidget(TwoDimensionalScrollable oldWidget) {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
@ -1985,6 +1995,7 @@ class TwoDimensionalScrollableState extends State<TwoDimensionalScrollable> {
} }
} }
@protected
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
assert( assert(
@ -2049,6 +2060,7 @@ class TwoDimensionalScrollableState extends State<TwoDimensionalScrollable> {
); );
} }
@protected
@override @override
void dispose() { void dispose() {
_verticalFallbackController?.dispose(); _verticalFallbackController?.dispose();

View File

@ -1378,6 +1378,7 @@ class RawScrollbarState<T extends RawScrollbar> extends State<T> with TickerProv
@protected @protected
bool get enableGestures => widget.interactive ?? true; bool get enableGestures => widget.interactive ?? true;
@protected
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -1404,6 +1405,7 @@ class RawScrollbarState<T extends RawScrollbar> extends State<T> with TickerProv
); );
} }
@protected
@override @override
void didChangeDependencies() { void didChangeDependencies() {
super.didChangeDependencies(); super.didChangeDependencies();
@ -1562,6 +1564,7 @@ class RawScrollbarState<T extends RawScrollbar> extends State<T> with TickerProv
..ignorePointer = !enableGestures; ..ignorePointer = !enableGestures;
} }
@protected
@override @override
void didUpdateWidget(T oldWidget) { void didUpdateWidget(T oldWidget) {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
@ -2159,6 +2162,7 @@ class RawScrollbarState<T extends RawScrollbar> extends State<T> with TickerProv
} }
} }
@protected
@override @override
void dispose() { void dispose() {
_fadeoutAnimationController.dispose(); _fadeoutAnimationController.dispose();
@ -2168,6 +2172,7 @@ class RawScrollbarState<T extends RawScrollbar> extends State<T> with TickerProv
super.dispose(); super.dispose();
} }
@protected
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
updateScrollbarPainter(); updateScrollbarPainter();

View File

@ -375,6 +375,7 @@ class SelectableRegionState extends State<SelectableRegion> with TextSelectionDe
FocusNode? _localFocusNode; FocusNode? _localFocusNode;
FocusNode get _focusNode => widget.focusNode ?? (_localFocusNode ??= FocusNode(debugLabel: 'SelectableRegion')); FocusNode get _focusNode => widget.focusNode ?? (_localFocusNode ??= FocusNode(debugLabel: 'SelectableRegion'));
@protected
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -398,6 +399,7 @@ class SelectableRegionState extends State<SelectableRegion> with TextSelectionDe
_processTextActions.addAll(await _processTextService.queryTextActions()); _processTextActions.addAll(await _processTextService.queryTextActions());
} }
@protected
@override @override
void didChangeDependencies() { void didChangeDependencies() {
super.didChangeDependencies(); super.didChangeDependencies();
@ -424,6 +426,7 @@ class SelectableRegionState extends State<SelectableRegion> with TextSelectionDe
} }
} }
@protected
@override @override
void didUpdateWidget(SelectableRegion oldWidget) { void didUpdateWidget(SelectableRegion oldWidget) {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
@ -1704,6 +1707,7 @@ class SelectableRegionState extends State<SelectableRegion> with TextSelectionDe
_selectable = null; _selectable = null;
} }
@protected
@override @override
void dispose() { void dispose() {
_selectable?.removeListener(_updateSelectionStatus); _selectable?.removeListener(_updateSelectionStatus);
@ -1720,6 +1724,7 @@ class SelectableRegionState extends State<SelectableRegion> with TextSelectionDe
super.dispose(); super.dispose();
} }
@protected
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
assert(debugCheckHasOverlay(context)); assert(debugCheckHasOverlay(context));

View File

@ -225,6 +225,7 @@ class UndoHistoryState<T> extends State<UndoHistory<T>> with UndoManagerClient {
} }
} }
@protected
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -243,6 +244,7 @@ class UndoHistoryState<T> extends State<UndoHistory<T>> with UndoManagerClient {
_effectiveController.onRedo.addListener(redo); _effectiveController.onRedo.addListener(redo);
} }
@protected
@override @override
void didUpdateWidget(UndoHistory<T> oldWidget) { void didUpdateWidget(UndoHistory<T> oldWidget) {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
@ -265,6 +267,7 @@ class UndoHistoryState<T> extends State<UndoHistory<T>> with UndoManagerClient {
} }
} }
@protected
@override @override
void dispose() { void dispose() {
if (UndoManager.client == this) { if (UndoManager.client == this) {
@ -280,6 +283,7 @@ class UndoHistoryState<T> extends State<UndoHistory<T>> with UndoManagerClient {
super.dispose(); super.dispose();
} }
@protected
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Actions( return Actions(