Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add documentation and clean up code. (flutter#11330)
Mainly, this adds documentation to members that were previously
lacking documentation.

It also adds a big block of documentation about improving performance
of widgets.

This also removes some references to package:collection and adds
global setEquals and listEquals methods in foundation that we can use.
(setEquals in particular should be much faster than the
package:collection equivalent, though both should be faster as they
avoid allocating new objects.) All remaining references now qualify
the import so we know what our remaining dependencies are.

Also lots of code reordering in Flutter driver to make the code
consistent and apply the style guide more thoroughly.
  • Loading branch information
Hixie authored Jul 21, 2017
commit 8f56f6fdd1c6b4586518b927623bc87341452b50
2 changes: 1 addition & 1 deletion dev/devicelab/test/adb_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import 'dart:async';

import 'package:test/test.dart';
import 'package:collection/collection.dart';
import 'package:collection/collection.dart' show ListEquality, MapEquality;

import 'package:flutter_devicelab/framework/adb.dart';

Expand Down
1 change: 1 addition & 0 deletions packages/flutter/lib/foundation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export 'src/foundation/assertions.dart';
export 'src/foundation/basic_types.dart';
export 'src/foundation/binding.dart';
export 'src/foundation/change_notifier.dart';
export 'src/foundation/collections.dart';
export 'src/foundation/debug.dart';
export 'src/foundation/licenses.dart';
export 'src/foundation/observer_list.dart';
Expand Down
3 changes: 3 additions & 0 deletions packages/flutter/lib/src/foundation/annotations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
/// * [Summary], which is used to provide a one-line description of a
/// class that overrides the inline documentations' own description.
class Category {
/// Create an annotation to provide a categorization of a class.
const Category(this.sections) : assert(sections != null);

/// The strings the correspond to the section and subsection of the
Expand Down Expand Up @@ -67,6 +68,7 @@ class Category {
/// * [Summary], which is used to provide a one-line description of a
/// class that overrides the inline documentations' own description.
class DocumentationIcon {
/// Create an annotation to provide a URL to an image describing a class.
const DocumentationIcon(this.url) : assert(url != null);

/// The URL to an image that represents the annotated class.
Expand Down Expand Up @@ -102,6 +104,7 @@ class DocumentationIcon {
/// * [DocumentationIcon], which is used to give the URL to an image that
/// represents the class.
class Summary {
/// Create an annotation to provide a short description of a class.
const Summary(this.text) : assert(text != null);

/// The text of the summary of the annotated class.
Expand Down
47 changes: 47 additions & 0 deletions packages/flutter/lib/src/foundation/collections.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright 2017 The Chromium 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(ianh): These should be on the Set and List classes themselves.

/// Compares two sets for deep equality.
///
/// Returns true if the sets are both null, or if they are both non-null, have
/// the same length, and contain the same members. Returns false otherwise.
/// Order is not compared.
///
/// See also:
///
/// * [listEquals], which does something similar for lists.
bool setEquals<T>(Set<T> a, Set<T> b) {
if (a == null)
return b == null;
if (b == null || a.length != b.length)
return false;
for (T value in a) {
if (!b.contains(value))
return false;
}
return true;
}

/// Compares two lists for deep equality.
///
/// Returns true if the lists are both null, or if they are both non-null, have
/// the same length, and contain the same members in the same order. Returns
/// false otherwise.
///
/// See also:
///
/// * [setEquals], which does something similar for sets.
bool listEquals<T>(List<T> a, List<T> b) {
if (a == null)
return b == null;
if (b == null || a.length != b.length)
return false;
for (int index = 0; index < a.length; index += 1) {
if (a[index] != b[index])
return false;
}
return true;
}
3 changes: 2 additions & 1 deletion packages/flutter/lib/src/material/back_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ class BackButtonIcon extends StatelessWidget {
/// See also:
///
/// * [AppBar], which automatically uses a [BackButton] in its
/// [AppBar.leading] slot when appropriate.
/// [AppBar.leading] slot when the [Scaffold] has no [Drawer] and the
/// current [Route] is not the [Navigator]'s first route.
/// * [BackButtonIcon], which is useful if you need to create a back button
/// that responds differently to being pressed.
/// * [IconButton], which is a more general widget for creating buttons with
Expand Down
8 changes: 7 additions & 1 deletion packages/flutter/lib/src/material/date_picker.dart
Original file line number Diff line number Diff line change
Expand Up @@ -268,13 +268,19 @@ class DayPicker extends StatelessWidget {
}

// Do not use this directly - call getDaysInMonth instead.
static const List<int> _kDaysInMonth = const <int>[31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
static const List<int> _kDaysInMonth = const <int>[31, -1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

/// Returns the number of days in a month, according to the proleptic
/// Gregorian calendar.
///
/// This applies the leap year logic introduced by the Gregorian reforms of
/// 1582. It will not give valid results for dates prior to that time.
static int getDaysInMonth(int year, int month) {
if (month == DateTime.FEBRUARY) {
final bool isLeapYear = (year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0);
if (isLeapYear)
return 29;
return 28;
}
return _kDaysInMonth[month - 1];
}
Expand Down
19 changes: 17 additions & 2 deletions packages/flutter/lib/src/material/input_decorator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,18 @@ class _InputDecoratorChildGlobalKey extends GlobalObjectKey {

/// Text and styles used to label an input field.
///
/// The [TextField] and [InputDecorator] classes use [InputDecoration] objects
/// to describe their decoration. (In fact, this class is merely the
/// configuration of an [InputDecorator], which does all the heavy lifting.)
///
/// See also:
///
/// * [TextField], which is a text input widget that uses an
/// [InputDecoration].
/// * [InputDecorator], which is a widget that draws an [InputDecoration]
/// around an arbitrary child widget.
/// * [Decoration] and [DecoratedBox], for drawing arbitrary decorations
/// around other widgets.
@immutable
class InputDecoration {
/// Creates a bundle of text and styles used to label an input field.
Expand Down Expand Up @@ -307,15 +313,22 @@ class InputDecoration {
/// Use [InputDecorator] to create widgets that look and behave like a
/// [TextField] but can be used to input information other than text.
///
/// The configuration of this widget is primarily provided in the form of an
/// [InputDecoration] object.
///
/// Requires one of its ancestors to be a [Material] widget.
///
/// See also:
///
/// * [TextField], which uses an [InputDecorator] to draw labels and other
/// * [TextField], which uses an [InputDecorator] to draw labels and other
/// visual elements around a text entry widget.
/// * [Decoration] and [DecoratedBox], for drawing arbitrary decorations
/// around other widgets.
class InputDecorator extends StatelessWidget {
/// Creates a widget that displayes labels and other visual elements similar
/// to a [TextField].
///
/// The [isFocused] and [isEmpty] arguments must not be null.
const InputDecorator({
Key key,
@required this.decoration,
Expand All @@ -324,7 +337,9 @@ class InputDecorator extends StatelessWidget {
this.isFocused: false,
this.isEmpty: false,
this.child,
}) : super(key: key);
}) : assert(isFocused != null),
assert(isEmpty != null),
super(key: key);

/// The text and styles to use when decorating the child.
final InputDecoration decoration;
Expand Down
2 changes: 1 addition & 1 deletion packages/flutter/lib/src/painting/basic_types.dart
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export 'dart:ui' show
/// For example, [layout] (index 3) implies [paint] (2).
enum RenderComparison {
/// The two objects are identical (meaning deeply equal, not necessarily
/// [identical]).
/// [dart:core.identical]).
identical,

/// The two objects are identical for the purpose of layout, but may be different
Expand Down
15 changes: 1 addition & 14 deletions packages/flutter/lib/src/painting/text_span.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,6 @@ import 'package:flutter/services.dart';
import 'basic_types.dart';
import 'text_style.dart';

// TODO(ianh): This should be on List itself.
bool _deepEquals(List<Object> a, List<Object> b) {
if (a == null)
return b == null;
if (b == null || a.length != b.length)
return false;
for (int i = 0; i < a.length; i += 1) {
if (a[i] != b[i])
return false;
}
return true;
}

/// An immutable span of text.
///
/// A [TextSpan] object can be styled using its [style] property.
Expand Down Expand Up @@ -360,7 +347,7 @@ class TextSpan {
return typedOther.text == text
&& typedOther.style == style
&& typedOther.recognizer == recognizer
&& _deepEquals(typedOther.children, children);
&& listEquals<TextSpan>(typedOther.children, children);
}

@override
Expand Down
5 changes: 3 additions & 2 deletions packages/flutter/lib/src/rendering/debug.dart
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,9 @@ bool debugCheckIntrinsicSizes = false;
/// * [debugPrintLayouts], which does something similar for layout but using
/// console output.
///
/// * [debugPrintRebuildDirtyWidgets], which does something similar for widgets
/// being rebuilt.
/// * [debugProfileBuildsEnabled], which does something similar for widgets
/// being rebuilt, and [debugPrintRebuildDirtyWidgets], its console
/// equivalent.
///
/// * The discussion at [RendererBinding.drawFrame].
bool debugProfilePaintsEnabled = false;
Expand Down
1 change: 1 addition & 0 deletions packages/flutter/lib/src/rendering/layer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ abstract class Layer extends AbstractNode with TreeDiagnosticsMixin {
///
/// Picture layers are always leaves in the layer tree.
class PictureLayer extends Layer {
/// Creates a leaf layer for the layer tree.
PictureLayer(this.canvasBounds);

/// The bounds that were used for the canvas that drew this layer's [picture].
Expand Down
16 changes: 14 additions & 2 deletions packages/flutter/lib/src/rendering/proxy_box.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/painting.dart';

import 'package:collection/collection.dart';
import 'package:vector_math/vector_math_64.dart';

import 'box.dart';
Expand Down Expand Up @@ -2736,10 +2735,23 @@ class RenderSemanticsGestureHandler extends RenderProxyBox implements SemanticsA
_onVerticalDragUpdate = onVerticalDragUpdate,
super(child);

/// If non-null, the set of actions to allow. Other actions will be omitted,
/// even if their callback is provided.
///
/// For example, if [onTap] is non-null but [validActions] does not contain
/// [SemanticsAction.tap], then the semantic description of this node will
/// not claim to support taps.
///
/// This is normally used to filter the actions made available by
/// [onHorizontalDragUpdate] and [onVerticalDragUpdate]. Normally, these make
/// both the right and left, or up and down, actions available. For example,
/// if [onHorizontalDragUpdate] is set but [validActions] only contains
/// [SemanticsAction.scrollLeft], then the [SemanticsAction.scrollRight]
/// action will be omitted.
Set<SemanticsAction> get validActions => _validActions;
Set<SemanticsAction> _validActions;
set validActions(Set<SemanticsAction> value) {
if (const SetEquality<SemanticsAction>().equals(value, _validActions))
if (setEquals<SemanticsAction>(value, _validActions))
return;
_validActions = value;
markNeedsSemanticsUpdate(onlyChanges: true);
Expand Down
43 changes: 41 additions & 2 deletions packages/flutter/lib/src/rendering/sliver_persistent_header.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,13 @@ import 'viewport_offset.dart';
///
/// * hit testing, painting, and other details of the sliver protocol.
///
/// Subclasses must implement [performLayout], [minExtent], and [maxExtent].
/// Subclasses must implement [performLayout], [minExtent], and [maxExtent], and
/// typically also will implement [updateChild].
abstract class RenderSliverPersistentHeader extends RenderSliver with RenderObjectWithChildMixin<RenderBox>, RenderSliverHelpers {
/// Creates a sliver that changes its size when scrolled to the start of the
/// viewport.
///
/// This is an abstract class; this constructor only initializes the [child].
RenderSliverPersistentHeader({ RenderBox child }) {
this.child = child;
}
Expand Down Expand Up @@ -101,6 +106,15 @@ abstract class RenderSliverPersistentHeader extends RenderSliver with RenderObje
super.markNeedsLayout();
}

/// Lays out the [child].
///
/// This is called by [performLayout]. It applies the given `scrollOffset`
/// (which need not match the offset given by the [constraints]) and the
/// `maxExtent` (which need not match the value returned by the [maxExtent]
/// getter).
///
/// The `overlapsContent` argument is passed to [updateChild].
@protected
void layoutChild(double scrollOffset, double maxExtent, { bool overlapsContent: false }) {
assert(maxExtent != null);
final double shrinkOffset = math.min(scrollOffset, maxExtent);
Expand Down Expand Up @@ -211,6 +225,8 @@ abstract class RenderSliverPersistentHeader extends RenderSliver with RenderObje
///
/// This sliver makes no effort to avoid overlapping other content.
abstract class RenderSliverScrollingPersistentHeader extends RenderSliverPersistentHeader {
/// Creates a sliver that shrinks when it hits the start of the viewport, then
/// scrolls off.
RenderSliverScrollingPersistentHeader({
RenderBox child,
}) : super(child: child);
Expand Down Expand Up @@ -247,6 +263,8 @@ abstract class RenderSliverScrollingPersistentHeader extends RenderSliverPersist
///
/// This sliver avoids overlapping other earlier slivers where possible.
abstract class RenderSliverPinnedPersistentHeader extends RenderSliverPersistentHeader {
/// Creates a sliver that shrinks when it hits the start of the viewport, then
/// stays pinned there.
RenderSliverPinnedPersistentHeader({
RenderBox child,
}) : super(child: child);
Expand Down Expand Up @@ -304,7 +322,15 @@ class FloatingHeaderSnapConfiguration {
/// A sliver with a [RenderBox] child which shrinks and scrolls like a
/// [RenderSliverScrollingPersistentHeader], but immediately comes back when the
/// user scrolls in the reverse direction.
///
/// See also:
///
/// * [RenderSliverFloatingPinnedPersistentHeader], which is similar but sticks
/// to the start of the viewport rather than scrolling off.
abstract class RenderSliverFloatingPersistentHeader extends RenderSliverPersistentHeader {
/// Creates a sliver that shrinks when it hits the start of the viewport, then
/// scrolls off, and comes back immediately when the user reverses the scroll
/// direction.
RenderSliverFloatingPersistentHeader({
RenderBox child,
FloatingHeaderSnapConfiguration snapConfiguration,
Expand Down Expand Up @@ -352,7 +378,9 @@ abstract class RenderSliverFloatingPersistentHeader extends RenderSliverPersiste
_snapConfiguration = value;
}

// Update [geometry] and return the new value for [childMainAxisPosition].
/// Updates [geometry], and returns the new value for [childMainAxisPosition].
///
/// This is used by [performLayout].
@protected
double updateGeometry() {
final double maxExtent = this.maxExtent;
Expand Down Expand Up @@ -443,7 +471,18 @@ abstract class RenderSliverFloatingPersistentHeader extends RenderSliverPersiste
}
}

/// A sliver with a [RenderBox] child which shrinks and then remains pinned to
/// the start of the viewport like a [RenderSliverPinnedPersistentHeader], but
/// immediately grows when the user scrolls in the reverse direction.
///
/// See also:
///
/// * [RenderSliverFloatingPersistentHeader], which is similar but scrolls off
/// the top rather than sticking to it.
abstract class RenderSliverFloatingPinnedPersistentHeader extends RenderSliverFloatingPersistentHeader {
/// Creates a sliver that shrinks when it hits the start of the viewport, then
/// stays pinned there, and grows immediately when the user reverses the
/// scroll direction.
RenderSliverFloatingPinnedPersistentHeader({
RenderBox child,
FloatingHeaderSnapConfiguration snapConfiguration,
Expand Down
2 changes: 1 addition & 1 deletion packages/flutter/lib/src/scheduler/binding.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import 'dart:developer';
import 'dart:ui' as ui show window;
import 'dart:ui' show VoidCallback;

import 'package:collection/collection.dart';
import 'package:collection/collection.dart' show PriorityQueue, HeapPriorityQueue;
import 'package:flutter/foundation.dart';

import 'debug.dart';
Expand Down
8 changes: 8 additions & 0 deletions packages/flutter/lib/src/widgets/animated_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,14 @@ class AnimatedList extends StatefulWidget {
/// view is scrolled.
///
/// Must be null if [primary] is true.
///
/// A [ScrollController] serves several purposes. It can be used to control
/// the initial scroll position (see [ScrollController.initialScrollOffset]).
/// It can be used to control whether the scroll view should automatically
/// save and restore its scroll position in the [PageStorage] (see
/// [ScrollController.keepScrollOffset]). It can be used to read the current
/// scroll position (see [ScrollController.offset]), or change it (see
/// [ScrollController.animateTo]).
final ScrollController controller;

/// Whether this is the primary scroll view associated with the parent
Expand Down
Loading