Migrate swarm's swarm_ui_lib/layout

Change-Id: I3c0809b8115d0b3244824e542c408ece78368bc5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/248346
Reviewed-by: Bob Nystrom <rnystrom@google.com>
Commit-Queue: Vijay Menon <vsm@google.com>
diff --git a/samples-dev/swarm/swarm_ui_lib/layout/GridLayout.dart b/samples-dev/swarm/swarm_ui_lib/layout/GridLayout.dart
index 45773c0..005f182 100644
--- a/samples-dev/swarm/swarm_ui_lib/layout/GridLayout.dart
+++ b/samples-dev/swarm/swarm_ui_lib/layout/GridLayout.dart
@@ -2,9 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
-
 part of layout;
 
 /**
@@ -47,9 +44,9 @@
 //  - Optimize for the "incremental update" cases
 class GridLayout extends ViewLayout {
   /** Configuration parameters defined in CSS. */
-  final GridTrackList rows;
-  final GridTrackList columns;
-  final GridTemplate template;
+  final GridTrackList? rows;
+  final GridTrackList? columns;
+  final GridTemplate? template;
 
   /** The default sizing for new rows. */
   final TrackSizing rowSizing;
@@ -61,33 +58,33 @@
    * This stores the grid's size during a layout.
    * Used for rows/columns with % or fr units.
    */
-  int _gridWidth, _gridHeight;
+  int? _gridWidth, _gridHeight;
 
   /**
    * During a layout, this stores all row/column size information.
    * Because grid-items can implicitly specify their own rows/columns, we can't
    * compute this until we know the set of items.
    */
-  List<GridTrack> _rowTracks, _columnTracks;
+  late List<GridTrack> _rowTracks, _columnTracks;
 
   /** During a layout, tracks which dimension we're processing. */
-  Dimension _dimension;
+  Dimension? _dimension;
 
   GridLayout(Positionable view)
       : rows = _GridTrackParser.parse(view.customStyle['grid-rows']),
         columns = _GridTrackParser.parse(view.customStyle['grid-columns']),
         template = _GridTemplateParser.parse(view.customStyle['grid-template']),
-        rowSizing = _GridTrackParser
-            .parseTrackSizing(view.customStyle['grid-row-sizing']),
-        columnSizing = _GridTrackParser
-            .parseTrackSizing(view.customStyle['grid-column-sizing']),
+        rowSizing = _GridTrackParser.parseTrackSizing(
+            view.customStyle['grid-row-sizing']),
+        columnSizing = _GridTrackParser.parseTrackSizing(
+            view.customStyle['grid-column-sizing']),
         super(view) {
-    _rowTracks = rows != null ? rows.tracks : new List<GridTrack>();
-    _columnTracks = columns != null ? columns.tracks : new List<GridTrack>();
+    _rowTracks = rows?.tracks ?? [];
+    _columnTracks = columns?.tracks ?? [];
   }
 
-  int get currentWidth => _gridWidth;
-  int get currentHeight => _gridHeight;
+  int? get currentWidth => _gridWidth;
+  int? get currentHeight => _gridHeight;
 
   void cacheExistingBrowserLayout() {
     // We don't need to do anything as we don't rely on the _cachedViewRect
@@ -97,11 +94,11 @@
   // TODO(jacobr): cleanup this method so that it returns a Future
   // rather than taking a Completer as an argument.
   /** The main entry point for layout computation. */
-  void measureLayout(Future<Size> size, Completer<bool> changed) {
+  void measureLayout(Future<Size> size, Completer<bool>? changed) {
     _ensureAllTracks();
     size.then((value) {
-      _gridWidth = value.width;
-      _gridHeight = value.height;
+      _gridWidth = value.width as int?;
+      _gridHeight = value.height as int?;
 
       if (_rowTracks.length > 0 && _columnTracks.length > 0) {
         _measureTracks();
@@ -135,7 +132,7 @@
   }
 
   num _getRemainingSpace(List<GridTrack> tracks) {
-    num remaining = _getGridContentSize();
+    num remaining = _getGridContentSize()!;
     remaining -= CollectionUtils.sum(tracks, (t) => t.usedBreadth);
     return Math.max(0, remaining);
   }
@@ -152,7 +149,7 @@
   void _computeUsedBreadthOfTracks(List<GridTrack> tracks) {
     // TODO(jmesserly): as a performance optimization we could cache this
     final items = view.childViews.map((view_) => view_.layout).toList();
-    CollectionUtils.sortBy(items, (item) => _getSpanCount(item));
+    CollectionUtils.sortBy(items, (item) => _getSpanCount(item)!);
 
     // 1. Initialize per Grid Track variables
     for (final t in tracks) {
@@ -224,7 +221,7 @@
     num finalPosition = position;
 
     for (int i = 0; i < tracks.length; i++) {
-      int startEdge = tracks[i].start;
+      int startEdge = tracks[i].start as int;
       int endEdge;
       if (i < tracks.length - 1) {
         endEdge = tracks[i + 1].start.round();
@@ -266,7 +263,7 @@
     CollectionUtils.sortBy(fractionTracks, (t) => t.tempBreadth);
 
     num spaceNeededFromFractionTracks = _getRemainingSpace(tracks);
-    num currentBandFractionBreadth = 0;
+    num? currentBandFractionBreadth = 0;
     num accumulatedFractions = 0;
     for (final t in fractionTracks) {
       if (t.tempBreadth != currentBandFractionBreadth) {
@@ -287,7 +284,7 @@
    * computed, updatedBreadth, that represents the Grid Track's share of
    * freeSpace.
    */
-  void _distributeSpaceToTracks(List<GridTrack> tracks, num freeSpace,
+  void _distributeSpaceToTracks(List<GridTrack?> tracks, num? freeSpace,
       _BreadthAccumulator breadth, bool ignoreMaxBreadth) {
     // TODO(jmesserly): in some cases it would be safe to sort the passed in
     // list in place. Not always though.
@@ -298,9 +295,9 @@
     // their maxBreadth values. Because there are different MaxBreadths
     // assigned to the different Grid Tracks, this can result in uneven growth.
     for (int i = 0; i < tracks.length; i++) {
-      num share = freeSpace / (tracks.length - i);
-      share = Math.min(share, tracks[i].maxBreadth);
-      tracks[i].tempBreadth = share;
+      num share = freeSpace! / (tracks.length - i);
+      share = Math.min(share, tracks[i]!.maxBreadth);
+      tracks[i]!.tempBreadth = share;
       freeSpace -= share;
     }
 
@@ -309,10 +306,10 @@
     // evenly and assign it to each Grid Track without regard for its
     // maxBreadth. This phase of growth will always be even, but only occurs
     // when the ignoreMaxBreadth flag is true.
-    if (freeSpace > 0 && ignoreMaxBreadth) {
+    if (freeSpace! > 0 && ignoreMaxBreadth) {
       for (int i = 0; i < tracks.length; i++) {
-        final share = freeSpace / (tracks.length - i);
-        tracks[i].tempBreadth += share;
+        final share = freeSpace! / (tracks.length - i);
+        tracks[i]!.tempBreadth = tracks[i]!.tempBreadth + share;
         freeSpace -= share;
       }
     }
@@ -320,7 +317,7 @@
     // Note: the spec has us updating all grid tracks, not just the passed in
     // tracks, but I think that's a spec bug.
     for (final t in tracks) {
-      t.updatedBreadth = Math.max(t.updatedBreadth, t.tempBreadth);
+      t!.updatedBreadth = Math.max(t.updatedBreadth, t.tempBreadth);
     }
   }
 
@@ -352,7 +349,7 @@
       // Remember that we need to update the sizes on these tracks
       tracks.addAll(spannedTracks);
 
-      // Each time we transition to a new spanCount, update any modified tracks
+      // Each time we transition to a spanCount, update any modified tracks
       bool spanCountFinished = false;
       if (i + 1 == items.length) {
         spanCountFinished = true;
@@ -362,7 +359,7 @@
 
       if (spanCountFinished) {
         for (final t in tracks) {
-          breadth.setSize(t, Math.max(breadth.getSize(t), t.updatedBreadth));
+          breadth.setSize(t, Math.max(breadth.getSize(t)!, t.updatedBreadth));
         }
         tracks = [];
       }
@@ -373,14 +370,14 @@
    * Returns true if we have an appropriate content sized dimension, and don't
    * cross a fractional track.
    */
-  static bool _hasContentSizedTracks(Iterable<GridTrack> tracks,
+  static bool _hasContentSizedTracks(Iterable<GridTrack?> tracks,
       ContentSizeMode sizeMode, _BreadthAccumulator breadth) {
     for (final t in tracks) {
       final fn = breadth.getSizingFunction(t);
       if (sizeMode == ContentSizeMode.MAX && fn.isMaxContentSized ||
           sizeMode == ContentSizeMode.MIN && fn.isContentSized) {
         // Make sure we don't cross a fractional track
-        return tracks.length == 1 || !tracks.any((t_) => t_.isFractional);
+        return tracks.length == 1 || !tracks.any((t_) => t_!.isFractional);
       }
     }
     return false;
@@ -400,7 +397,7 @@
     // Fill in tracks
     for (int i = first; i < length; i++) {
       if (tracks[i] == null) {
-        tracks[i] = new GridTrack(sizing);
+        tracks[i] = GridTrack(sizing);
       }
     }
   }
@@ -409,7 +406,7 @@
    * Scans children creating GridLayoutParams as needed, and creates all of the
    * rows and columns that we will need.
    *
-   * Note: this can potentially create new rows/columns, so this needs to be
+   * Note: this can potentially create new qrows/columns, so this needs to be
    * run before the track sizing algorithm.
    */
   void _ensureAllTracks() {
@@ -417,9 +414,9 @@
 
     for (final child in items) {
       if (child.layoutParams == null) {
-        final p = new GridLayoutParams(child.view, this);
-        _ensureTrack(_rowTracks, rowSizing, p.row, p.rowSpan);
-        _ensureTrack(_columnTracks, columnSizing, p.column, p.columnSpan);
+        final p = GridLayoutParams(child.view, this);
+        _ensureTrack(_rowTracks, rowSizing, p.row!, p.rowSpan!);
+        _ensureTrack(_columnTracks, columnSizing, p.column!, p.columnSpan!);
         child.layoutParams = p;
       }
       child.cacheExistingBrowserLayout();
@@ -433,12 +430,12 @@
     final items = view.childViews.map((view_) => view_.layout);
 
     for (final item in items) {
-      GridLayoutParams childLayout = item.layoutParams;
+      GridLayoutParams childLayout = item.layoutParams as GridLayoutParams;
       var xPos = _getTrackLocationX(childLayout);
       var yPos = _getTrackLocationY(childLayout);
 
-      int left = xPos.start, width = xPos.length;
-      int top = yPos.start, height = yPos.length;
+      int? left = xPos.start, width = xPos.length;
+      int? top = yPos.start, height = yPos.length;
 
       // Somewhat counterintuitively (at least to me):
       //   grid-col-align is the horizontal alignment
@@ -446,11 +443,11 @@
       xPos = childLayout.columnAlign.align(xPos, item.currentWidth);
       yPos = childLayout.rowAlign.align(yPos, item.currentHeight);
 
-      item.setBounds(xPos.start, yPos.start, xPos.length, yPos.length);
+      item.setBounds(xPos.start, yPos.start, xPos.length!, yPos.length!);
     }
   }
 
-  num _getGridContentSize() {
+  num? _getGridContentSize() {
     if (_dimension == Dimension.WIDTH) {
       return _gridWidth;
     } else if (_dimension == Dimension.HEIGHT) {
@@ -459,55 +456,52 @@
   }
 
   _GridLocation _getTrackLocationX(GridLayoutParams childLayout) {
-    int start = childLayout.column - 1;
-    int end = start + childLayout.columnSpan - 1;
+    int start = childLayout.column! - 1;
+    int end = start + childLayout.columnSpan! - 1;
 
-    start = _columnTracks[start].start;
-    end = _columnTracks[end].end;
+    start = _columnTracks[start].start as int;
+    end = _columnTracks[end].end as int;
 
-    return new _GridLocation(start, end - start);
+    return _GridLocation(start, end - start);
   }
 
   _GridLocation _getTrackLocationY(GridLayoutParams childLayout) {
-    int start = childLayout.row - 1;
-    int end = start + childLayout.rowSpan - 1;
+    int start = childLayout.row! - 1;
+    int end = start + childLayout.rowSpan! - 1;
 
-    start = _rowTracks[start].start;
-    end = _rowTracks[end].end;
+    start = _rowTracks[start].start as int;
+    end = _rowTracks[end].end as int;
 
-    return new _GridLocation(start, end - start);
+    return _GridLocation(start, end - start);
   }
 
   /** Gets the tracks that this item crosses. */
   // TODO(jmesserly): might be better to return an iterable
-  List<GridTrack> _getTracks(ViewLayout item) {
-    GridLayoutParams childLayout = item.layoutParams;
+  List<GridTrack?> _getTracks(ViewLayout item) {
+    GridLayoutParams? childLayout = item.layoutParams as GridLayoutParams?;
 
-    int start, span;
-    List<GridTrack> tracks;
+    int? start, span;
+    List<GridTrack>? tracks;
     if (_dimension == Dimension.WIDTH) {
-      start = childLayout.column - 1;
+      start = childLayout!.column! - 1;
       span = childLayout.columnSpan;
       tracks = _columnTracks;
     } else if (_dimension == Dimension.HEIGHT) {
-      start = childLayout.row - 1;
+      start = childLayout!.row! - 1;
       span = childLayout.rowSpan;
       tracks = _rowTracks;
     }
 
-    assert(start >= 0 && span >= 1);
+    assert(start! >= 0 && span! >= 1);
 
-    final result = new List<GridTrack>(span);
-    for (int i = 0; i < span; i++) {
-      result[i] = tracks[start + i];
-    }
+    final result = List<GridTrack>.generate(span!, (i) => tracks![start! + i]);
     return result;
   }
 
-  int _getSpanCount(ViewLayout item) {
-    GridLayoutParams childLayout = item.layoutParams;
+  int? _getSpanCount(ViewLayout item) {
+    GridLayoutParams? childLayout = item.layoutParams as GridLayoutParams?;
     return (_dimension == Dimension.WIDTH
-        ? childLayout.columnSpan
-        : childLayout.rowSpan);
+        ? childLayout!.columnSpan
+        : childLayout!.rowSpan);
   }
 }
diff --git a/samples-dev/swarm/swarm_ui_lib/layout/GridLayoutParams.dart b/samples-dev/swarm/swarm_ui_lib/layout/GridLayoutParams.dart
index f2de0f1..c47f2ca 100644
--- a/samples-dev/swarm/swarm_ui_lib/layout/GridLayoutParams.dart
+++ b/samples-dev/swarm/swarm_ui_lib/layout/GridLayoutParams.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 part of layout;
 
 /**
@@ -16,25 +14,24 @@
 // field ends up being mentioned 4 times instead of just twice.
 class GridLayoutParams extends LayoutParams {
   /** The coordinates of this item in the grid. */
-  int row;
-  int column;
-  int rowSpan;
-  int columnSpan;
-  int layer;
+  int? row;
+  int? column;
+  int? rowSpan;
+  int? columnSpan;
+  int? layer;
 
   /** Alignment within its box */
   GridItemAlignment rowAlign;
   GridItemAlignment columnAlign;
 
-  GridLayoutParams(Positionable view, GridLayout layout) : super(view.node) {
+  GridLayoutParams(Positionable view, GridLayout layout)
+      : rowAlign =
+            GridItemAlignment.fromString(view.customStyle['grid-row-align']),
+        columnAlign =
+            GridItemAlignment.fromString(view.customStyle['grid-column-align']),
+        super(view.node) {
     // TODO(jmesserly): this can be cleaned up a lot by just passing "view"
     // into the parsers.
-
-    rowAlign =
-        new GridItemAlignment.fromString(view.customStyle['grid-row-align']);
-    columnAlign =
-        new GridItemAlignment.fromString(view.customStyle['grid-column-align']);
-
     layer = StringUtils.parseInt(view.customStyle['grid-layer'], 0);
 
     rowSpan = StringUtils.parseInt(view.customStyle['grid-row-span']);
@@ -45,7 +42,7 @@
       row = line.start;
       if (line.length != null) {
         if (rowSpan != null) {
-          throw new UnsupportedError(
+          throw UnsupportedError(
               'grid-row-span cannot be with grid-row that defines an end');
         }
         rowSpan = line.length;
@@ -59,14 +56,14 @@
       column = line.start;
       if (line.length != null) {
         if (columnSpan != null) {
-          throw new UnsupportedError(
+          throw UnsupportedError(
               'grid-column-span cannot be with grid-column that defines an end');
         }
         columnSpan = line.length;
       }
     }
 
-    String cell = _GridTemplateParser.parseCell(view.customStyle['grid-cell']);
+    String? cell = _GridTemplateParser.parseCell(view.customStyle['grid-cell']);
     if (cell != null && cell != 'none') {
       // TODO(jmesserly): I didn't see anything spec'd about conflicts and
       // error handling. For now, throw an error on a misconfigured view.
@@ -76,16 +73,16 @@
           column != null ||
           rowSpan != null ||
           columnSpan != null) {
-        throw new UnsupportedError(
+        throw UnsupportedError(
             'grid-cell cannot be used with grid-row and grid-column');
       }
 
       if (layout.template == null) {
-        throw new UnsupportedError(
+        throw UnsupportedError(
             'grid-cell requires that grid-template is set on the parent');
       }
 
-      final rect = layout.template.lookupCell(cell);
+      final rect = layout.template!.lookupCell(cell);
       row = rect.row;
       column = rect.column;
       rowSpan = rect.rowSpan;
@@ -96,7 +93,7 @@
       if (columnSpan == null) columnSpan = 1;
 
       if (row == null && column == null) {
-        throw new UnsupportedError('grid-flow is not implemented' +
+        throw UnsupportedError('grid-flow is not implemented' +
             ' so at least one row or one column must be defined');
       }
 
@@ -104,6 +101,6 @@
       if (column == null) column = 1;
     }
 
-    assert(row > 0 && rowSpan > 0 && column > 0 && columnSpan > 0);
+    assert(row! > 0 && rowSpan! > 0 && column! > 0 && columnSpan! > 0);
   }
 }
diff --git a/samples-dev/swarm/swarm_ui_lib/layout/GridLayoutParser.dart b/samples-dev/swarm/swarm_ui_lib/layout/GridLayoutParser.dart
index 7cc87e8..009392a 100644
--- a/samples-dev/swarm/swarm_ui_lib/layout/GridLayoutParser.dart
+++ b/samples-dev/swarm/swarm_ui_lib/layout/GridLayoutParser.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 part of layout;
 
 /**
@@ -56,7 +54,7 @@
   }
 
   void _error(String msg) {
-    throw new SyntaxErrorException(msg, _src, _offset);
+    throw SyntaxErrorException(msg, _src, _offset);
   }
 
   int get length => _src.length;
@@ -132,7 +130,7 @@
     }
   }
 
-  String _maybeEatString() {
+  String? _maybeEatString() {
     // TODO(jmesserly): make this match CSS string parsing
     String quote = "'";
     if (!_maybeEat(quote)) {
@@ -171,7 +169,7 @@
   }
 
   /** Eats an integer. */
-  int _maybeEatInt() {
+  int? _maybeEatInt() {
     int start = _offset;
     bool dot = false;
     while (_offset < length && _isDigit(_peekChar())) {
@@ -186,8 +184,8 @@
   }
 
   /** Eats an integer. */
-  int _eatInt() {
-    int result = _maybeEatInt();
+  int? _eatInt() {
+    int? result = _maybeEatInt();
     if (result == null) {
       _error('expected positive integer');
     }
@@ -224,37 +222,37 @@
   _GridTemplateParser._internal(String src) : super(src);
 
   /** Parses the grid-rows and grid-columns CSS properties into object form. */
-  static GridTemplate parse(String str) {
+  static GridTemplate? parse(String? str) {
     if (str == null) return null;
-    final p = new _GridTemplateParser._internal(str);
+    final p = _GridTemplateParser._internal(str);
     final result = p._parseTemplate();
     p._eatEnd();
     return result;
   }
 
   /** Parses a grid-cell value. */
-  static String parseCell(String str) {
+  static String? parseCell(String? str) {
     if (str == null) return null;
-    final p = new _GridTemplateParser._internal(str);
+    final p = _GridTemplateParser._internal(str);
     final result = p._maybeEatString();
     p._eatEnd();
     return result;
   }
 
   // => <string>+ | 'none'
-  GridTemplate _parseTemplate() {
+  GridTemplate? _parseTemplate() {
     if (_maybeEat('none')) {
       return null;
     }
-    final rows = new List<String>();
-    String row;
+    final rows = <String?>[];
+    String? row;
     while ((row = _maybeEatString()) != null) {
       rows.add(row);
     }
     if (rows.length == 0) {
       _error('expected at least one cell, or "none"');
     }
-    return new GridTemplate(rows);
+    return GridTemplate(rows);
   }
 }
 
@@ -263,9 +261,9 @@
   _GridItemParser._internal(String src) : super(src);
 
   /** Parses the grid-rows and grid-columns CSS properties into object form. */
-  static _GridLocation parse(String cell, GridTrackList list) {
+  static _GridLocation? parse(String? cell, GridTrackList? list) {
     if (cell == null) return null;
-    final p = new _GridItemParser._internal(cell);
+    final p = _GridItemParser._internal(cell);
     final result = p._parseTrack(list);
     p._eatEnd();
     return result;
@@ -274,27 +272,27 @@
   // [ [ <integer> | <string> | 'start' | 'end' ]
   //   [ <integer> | <string> | 'start' | 'end' ]? ]
   // | 'auto'
-  _GridLocation _parseTrack(GridTrackList list) {
+  _GridLocation? _parseTrack(GridTrackList? list) {
     if (_maybeEat('auto')) {
       return null;
     }
-    int start = _maybeParseLine(list);
+    int? start = _maybeParseLine(list);
     if (start == null) {
       _error('expected row/column number or name');
     }
-    int end = _maybeParseLine(list);
-    int span = null;
+    int? end = _maybeParseLine(list);
+    int? span = null;
     if (end != null) {
-      span = end - start;
+      span = end - start!;
       if (span <= 0) {
         _error('expected row/column span to be a positive integer');
       }
     }
-    return new _GridLocation(start, span);
+    return _GridLocation(start, span);
   }
 
   // [ <integer> | <string> | 'start' | 'end' ]
-  int _maybeParseLine(GridTrackList list) {
+  int? _maybeParseLine(GridTrackList? list) {
     if (_maybeEat('start')) {
       return 1;
     } else if (_maybeEat('end')) {
@@ -303,14 +301,14 @@
       // TODO(jmesserly): this won't interact properly with implicit
       // rows/columns. Instead it will snap to the number of tracks at the point
       // where it is evaluated.
-      return list.tracks.length + 1;
+      return list!.tracks.length + 1;
     }
 
-    String name = _maybeEatString();
+    String? name = _maybeEatString();
     if (name == null) {
       return _maybeEatInt();
     } else {
-      int edge = list.lineNames[name];
+      int? edge = list!.lineNames[name];
       if (edge == null) {
         _error('row/column name "$name" not found in the parent\'s '
             ' grid-row/grid-columns properties');
@@ -329,17 +327,17 @@
 // CSS units, support for all escape sequences, etc.
 class _GridTrackParser extends _Parser {
   final List<GridTrack> _tracks;
-  final Map<String, int> _lineNames;
+  final Map<String?, int> _lineNames;
 
   _GridTrackParser._internal(String src)
-      : _tracks = new List<GridTrack>(),
-        _lineNames = new Map<String, int>(),
+      : _tracks = <GridTrack>[],
+        _lineNames = Map<String?, int>(),
         super(src);
 
   /** Parses the grid-rows and grid-columns CSS properties into object form. */
-  static GridTrackList parse(String str) {
+  static GridTrackList? parse(String? str) {
     if (str == null) return null;
-    final p = new _GridTrackParser._internal(str);
+    final p = _GridTrackParser._internal(str);
     final result = p._parseTrackList();
     p._eatEnd();
     return result;
@@ -349,28 +347,28 @@
    * Parses the grid-row-sizing and grid-column-sizing CSS properties into
    * object form.
    */
-  static TrackSizing parseTrackSizing(String str) {
+  static TrackSizing parseTrackSizing(String? str) {
     if (str == null) str = 'auto';
-    final p = new _GridTrackParser._internal(str);
+    final p = _GridTrackParser._internal(str);
     final result = p._parseTrackMinmax();
     p._eatEnd();
     return result;
   }
 
   // <track-list> => [ [ <string> ]* <track-group> [ <string> ]* ]+ | 'none'
-  GridTrackList _parseTrackList() {
+  GridTrackList? _parseTrackList() {
     if (_maybeEat('none')) {
       return null;
     }
     _parseTrackListHelper();
-    return new GridTrackList(_tracks, _lineNames);
+    return GridTrackList(_tracks, _lineNames);
   }
 
   /** Code shared by _parseTrackList and _parseTrackGroup */
-  void _parseTrackListHelper([List<GridTrack> resultTracks = null]) {
+  void _parseTrackListHelper([List<GridTrack>? resultTracks = null]) {
     _maybeEatWhitespace();
     while (!endOfInput) {
-      String name;
+      String? name;
       while ((name = _maybeEatString()) != null) {
         _lineNames[name] = _tracks.length + 1; // should be 1-based
       }
@@ -384,7 +382,7 @@
         if (_peekChar() == _Parser.R_PAREN) {
           return;
         }
-        resultTracks.add(new GridTrack(_parseTrackMinmax()));
+        resultTracks.add(GridTrack(_parseTrackMinmax()));
       } else {
         _parseTrackGroup();
       }
@@ -398,11 +396,11 @@
   //                  | <track-minmax>
   void _parseTrackGroup() {
     if (_maybeEat('(')) {
-      final tracks = new List<GridTrack>();
+      final tracks = <GridTrack>[];
       _parseTrackListHelper(tracks);
       _eat(')');
       if (_maybeEat('[')) {
-        num expand = _eatInt();
+        num expand = _eatInt()!;
         _eat(']');
 
         if (expand <= 0) {
@@ -419,7 +417,7 @@
         }
       }
     } else {
-      _tracks.add(new GridTrack(_parseTrackMinmax()));
+      _tracks.add(GridTrack(_parseTrackMinmax()));
     }
   }
 
@@ -434,10 +432,10 @@
       _eat(',');
       final max = _parseTrackBreadth();
       _eat(')');
-      return new TrackSizing(min, max);
+      return TrackSizing(min, max);
     } else {
       final breadth = _parseTrackBreadth();
-      return new TrackSizing(breadth, breadth);
+      return TrackSizing(breadth, breadth);
     }
   }
 
@@ -460,9 +458,9 @@
     }
 
     if (units == 'fr') {
-      return new FractionSizing(value);
+      return FractionSizing(value);
     } else {
-      return new FixedSizing(value, units);
+      return FixedSizing(value, units);
     }
   }
 }
diff --git a/samples-dev/swarm/swarm_ui_lib/layout/GridTracks.dart b/samples-dev/swarm/swarm_ui_lib/layout/GridTracks.dart
index 2fa6eb9..8baa1fb 100644
--- a/samples-dev/swarm/swarm_ui_lib/layout/GridTracks.dart
+++ b/samples-dev/swarm/swarm_ui_lib/layout/GridTracks.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 part of layout;
 
 // This file has classes representing the grid tracks and grid template
@@ -21,7 +19,7 @@
    * is used as a start or end, it might be interpreted exclusively or
    * inclusively.
    */
-  final Map<String, int> lineNames;
+  final Map<String?, int> lineNames;
 
   GridTrackList(this.tracks, this.lineNames) {}
 }
@@ -32,15 +30,15 @@
    * The start position of this track. Equal to the sum of previous track's
    * usedBreadth.
    */
-  num start;
+  late num start;
 
   /** The final computed breadth of this track. */
-  num usedBreadth;
+  late num usedBreadth;
 
   // Fields used internally by the sizing algorithm
-  num maxBreadth;
-  num updatedBreadth;
-  num tempBreadth;
+  late num maxBreadth;
+  late num updatedBreadth;
+  late num tempBreadth;
 
   final TrackSizing sizing;
 
@@ -50,7 +48,7 @@
    * Support for the feature that repeats rows and columns, e.g.
    * [:grid-columns: 10px ("content" 250px 10px)[4]:]
    */
-  GridTrack clone() => new GridTrack(sizing.clone());
+  GridTrack clone() => GridTrack(sizing.clone());
 
   /** The min sizing function for the track. */
   SizingFunction get minSizing => sizing.min;
@@ -69,7 +67,7 @@
   final String value;
 
   // 'start' | 'end' | 'center' | 'stretch'
-  GridItemAlignment.fromString(String value)
+  GridItemAlignment.fromString(String? value)
       : this.value = (value == null) ? 'stretch' : value {
     switch (this.value) {
       case 'start':
@@ -78,24 +76,25 @@
       case 'stretch':
         break;
       default:
-        throw new UnsupportedError('invalid row/column alignment "$value"');
+        throw UnsupportedError('invalid row/column alignment "$value"');
     }
   }
 
-  _GridLocation align(_GridLocation span, int size) {
+  _GridLocation align(_GridLocation span, int? size) {
     switch (value) {
       case 'start':
-        return new _GridLocation(span.start, size);
+        return _GridLocation(span.start, size);
       case 'end':
-        return new _GridLocation(span.end - size, size);
+        return _GridLocation(span.end - size!, size);
       case 'center':
-        size = Math.min(size, span.length);
-        num center = span.start + span.length / 2;
+        size = Math.min(size!, span.length!);
+        num center = span.start! + span.length! / 2;
         num left = center - size / 2;
-        return new _GridLocation(left.round(), size);
+        return _GridLocation(left.round(), size);
       case 'stretch':
         return span;
     }
+    throw UnsupportedError('invalid row/column alignment "$value"');
   }
 }
 
@@ -107,23 +106,23 @@
   final Map<int, _GridTemplateRect> _rects;
   final int _numRows;
 
-  GridTemplate(List<String> rows)
-      : _rects = new Map<int, _GridTemplateRect>(),
+  GridTemplate(List<String?> rows)
+      : _rects = <int, _GridTemplateRect>{},
         _numRows = rows.length {
     _buildRects(rows);
   }
 
   /** Scans the template strings and computes bounds for each one. */
-  void _buildRects(List<String> templateRows) {
+  void _buildRects(List<String?> templateRows) {
     for (int r = 0; r < templateRows.length; r++) {
-      String row = templateRows[r];
+      String row = templateRows[r]!;
       for (int c = 0; c < row.length; c++) {
         int cell = row.codeUnitAt(c);
         final rect = _rects[cell];
         if (rect != null) {
           rect.add(r + 1, c + 1);
         } else {
-          _rects[cell] = new _GridTemplateRect(cell, r + 1, c + 1);
+          _rects[cell] = _GridTemplateRect(cell, r + 1, c + 1);
         }
       }
     }
@@ -139,12 +138,12 @@
    */
   _GridTemplateRect lookupCell(String cell) {
     if (cell.length != 1) {
-      throw new UnsupportedError(
+      throw UnsupportedError(
           'grid-cell "$cell" must be a one character string');
     }
     final rect = _rects[cell.codeUnitAt(0)];
     if (rect == null) {
-      throw new UnsupportedError(
+      throw UnsupportedError(
           'grid-cell "$cell" not found in parent\'s grid-template');
     }
     return rect;
@@ -171,8 +170,8 @@
     if (expected != _count) {
       // TODO(jmesserly): not sure if we should throw here, due to CSS's
       // permissiveness. At the moment we're noisy about errors.
-      String cell = new String.fromCharCodes([_char]);
-      throw new UnsupportedError('grid-template "$cell"'
+      String cell = String.fromCharCodes([_char]);
+      throw UnsupportedError('grid-template "$cell"'
           ' is not square, expected $expected cells but got $_count');
     }
   }
@@ -183,8 +182,8 @@
  * grid-column during parsing.
  */
 class _GridLocation {
-  final int start, length;
+  final int? start, length;
   _GridLocation(this.start, this.length) {}
 
-  int get end => start + length;
+  int get end => start! + length!;
 }
diff --git a/samples-dev/swarm/swarm_ui_lib/layout/SizingFunctions.dart b/samples-dev/swarm/swarm_ui_lib/layout/SizingFunctions.dart
index 56e25b3..bc4258a 100644
--- a/samples-dev/swarm/swarm_ui_lib/layout/SizingFunctions.dart
+++ b/samples-dev/swarm/swarm_ui_lib/layout/SizingFunctions.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 part of layout;
 
 // This file has classes representing the grid sizing functions
@@ -20,7 +18,7 @@
   bool get isMaxContentSized => false;
   bool get isFraction => false;
 
-  num resolveLength(num gridSize) => 0;
+  num resolveLength(num? gridSize) => 0;
 
   num get fractionValue => 0;
 
@@ -46,16 +44,16 @@
   FixedSizing(this.length, [this.units = 'px']) : _contentSized = false {
     if (units != 'px' && units != '%') {
       // TODO(jmesserly): support other unit types
-      throw new UnsupportedError('Units other than px and %');
+      throw UnsupportedError('Units other than px and %');
     }
   }
 
   // TODO(jmesserly): this is only needed because of our mutable property
-  FixedSizing clone() => new FixedSizing(length, units);
+  FixedSizing clone() => FixedSizing(length, units);
 
   bool get isMinContentSized => _contentSized;
 
-  num resolveLength(num gridSize) {
+  num resolveLength(num? gridSize) {
     if (units == '%') {
       if (gridSize == null) {
         // Use content size when the grid doesn't have an absolute size in this
@@ -120,38 +118,38 @@
   TrackSizing(this.min, this.max) {}
 
   // TODO(jmesserly): this is only needed because FixedSizing is mutable
-  TrackSizing clone() => new TrackSizing(min.clone(), max.clone());
+  TrackSizing clone() => TrackSizing(min.clone(), max.clone());
 }
 
 /** Represents a GridTrack breadth property. */
 // TODO(jmesserly): these classes could be replaced with reflection/mirrors
 abstract class _BreadthAccumulator {
-  void setSize(GridTrack t, num value);
-  num getSize(GridTrack t);
+  void setSize(GridTrack? t, num value);
+  num? getSize(GridTrack? t);
 
-  SizingFunction getSizingFunction(GridTrack t);
+  SizingFunction getSizingFunction(GridTrack? t);
 }
 
 class _UsedBreadthAccumulator implements _BreadthAccumulator {
   const _UsedBreadthAccumulator();
 
-  void setSize(GridTrack t, num value) {
-    t.usedBreadth = value;
+  void setSize(GridTrack? t, num value) {
+    t!.usedBreadth = value;
   }
 
-  num getSize(GridTrack t) => t.usedBreadth;
+  num? getSize(GridTrack? t) => t!.usedBreadth;
 
-  SizingFunction getSizingFunction(GridTrack t) => t.minSizing;
+  SizingFunction getSizingFunction(GridTrack? t) => t!.minSizing;
 }
 
 class _MaxBreadthAccumulator implements _BreadthAccumulator {
   const _MaxBreadthAccumulator();
 
-  void setSize(GridTrack t, num value) {
-    t.maxBreadth = value;
+  void setSize(GridTrack? t, num value) {
+    t!.maxBreadth = value;
   }
 
-  num getSize(GridTrack t) => t.maxBreadth;
+  num? getSize(GridTrack? t) => t!.maxBreadth;
 
-  SizingFunction getSizingFunction(GridTrack t) => t.maxSizing;
+  SizingFunction getSizingFunction(GridTrack? t) => t!.maxSizing;
 }
diff --git a/samples-dev/swarm/swarm_ui_lib/layout/ViewLayout.dart b/samples-dev/swarm/swarm_ui_lib/layout/ViewLayout.dart
index aa0c3e9..5c284e1 100644
--- a/samples-dev/swarm/swarm_ui_lib/layout/ViewLayout.dart
+++ b/samples-dev/swarm/swarm_ui_lib/layout/ViewLayout.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 part of layout;
 
 /** The interface that the layout algorithms use to talk to the view. */
@@ -30,9 +28,9 @@
 class LayoutParams {
   // TODO(jmesserly): should be const, but there's a bug in DartC preventing us
   // from calling "window." in an initializer. See b/5332777
-  CssStyleDeclaration style;
+  CssStyleDeclaration? style;
 
-  int get layer => 0;
+  int? get layer => 0;
 
   LayoutParams(Element node) {
     style = node.getComputedStyle();
@@ -73,9 +71,9 @@
    * The layout parameters associated with this view and used by the parent
    * to determine how this view should be laid out.
    */
-  LayoutParams layoutParams;
-  int _offsetWidth;
-  int _offsetHeight;
+  LayoutParams? layoutParams;
+  int? _offsetWidth;
+  int? _offsetHeight;
 
   /** The view that this layout belongs to. */
   final Positionable view;
@@ -85,7 +83,7 @@
    * properties in the first pass while computing positions. Then we have a
    * second pass that actually moves everything.
    */
-  int _measuredLeft, _measuredTop, _measuredWidth, _measuredHeight;
+  int? _measuredLeft, _measuredTop, _measuredWidth, _measuredHeight;
 
   ViewLayout(this.view);
 
@@ -96,9 +94,9 @@
   // registered with a LayoutProvider.
   factory ViewLayout.fromView(Positionable view) {
     if (hasCustomLayout(view)) {
-      return new GridLayout(view);
+      return GridLayout(view);
     } else {
-      return new ViewLayout(view);
+      return ViewLayout(view);
     }
   }
 
@@ -106,36 +104,36 @@
     return view.customStyle['display'] == "-dart-grid";
   }
 
-  CssStyleDeclaration get _style => layoutParams.style;
+  CssStyleDeclaration? get _style => layoutParams!.style;
 
   void cacheExistingBrowserLayout() {
-    _offsetWidth = view.node.offset.width;
-    _offsetHeight = view.node.offset.height;
+    _offsetWidth = view.node.offset.width as int?;
+    _offsetHeight = view.node.offset.height as int?;
   }
 
-  int get currentWidth {
+  int? get currentWidth {
     return _offsetWidth;
   }
 
-  int get currentHeight {
+  int? get currentHeight {
     return _offsetHeight;
   }
 
-  int get borderLeftWidth => _toPixels(_style.borderLeftWidth);
-  int get borderTopWidth => _toPixels(_style.borderTopWidth);
-  int get borderRightWidth => _toPixels(_style.borderRightWidth);
-  int get borderBottomWidth => _toPixels(_style.borderBottomWidth);
+  int get borderLeftWidth => _toPixels(_style!.borderLeftWidth);
+  int get borderTopWidth => _toPixels(_style!.borderTopWidth);
+  int get borderRightWidth => _toPixels(_style!.borderRightWidth);
+  int get borderBottomWidth => _toPixels(_style!.borderBottomWidth);
   int get borderWidth => borderLeftWidth + borderRightWidth;
   int get borderHeight => borderTopWidth + borderBottomWidth;
 
   /** Implements the custom layout computation. */
-  void measureLayout(Future<Size> size, Completer<bool> changed) {}
+  void measureLayout(Future<Size> size, Completer<bool>? changed) {}
 
   /**
    * Positions the view within its parent container.
    * Also performs a layout of its children.
    */
-  void setBounds(int left, int top, int width, int height) {
+  void setBounds(int? left, int? top, int width, int height) {
     assert(width >= 0 && height >= 0);
 
     _measuredLeft = left;
@@ -144,8 +142,8 @@
     // Note: we need to save the client height
     _measuredWidth = width - borderWidth;
     _measuredHeight = height - borderHeight;
-    final completer = new Completer<Size>();
-    completer.complete(new Size(_measuredWidth, _measuredHeight));
+    final completer = Completer<Size>();
+    completer.complete(Size(_measuredWidth!, _measuredHeight!));
     measureLayout(completer.future, null);
   }
 
@@ -159,7 +157,7 @@
       style.top = '${_measuredTop}px';
       style.width = '${_measuredWidth}px';
       style.height = '${_measuredHeight}px';
-      style.zIndex = '${layoutParams.layer}';
+      style.zIndex = '${layoutParams!.layer}';
 
       _measuredLeft = null;
       _measuredTop = null;
@@ -181,8 +179,8 @@
     }
   }
 
-  int measureContent(ViewLayout parent, Dimension dimension,
-      [ContentSizeMode mode = null]) {
+  int? measureContent(ViewLayout parent, Dimension? dimension,
+      [ContentSizeMode? mode = null]) {
     if (dimension == Dimension.WIDTH) {
       return measureWidth(parent, mode);
     } else if (dimension == Dimension.HEIGHT) {
@@ -190,23 +188,23 @@
     }
   }
 
-  int measureWidth(ViewLayout parent, ContentSizeMode mode) {
-    final style = layoutParams.style;
+  int? measureWidth(ViewLayout parent, ContentSizeMode? mode) {
+    final style = layoutParams!.style;
     if (mode == ContentSizeMode.MIN) {
-      return _styleToPixels(style.minWidth, currentWidth, parent.currentWidth);
+      return _styleToPixels(style!.minWidth, currentWidth, parent.currentWidth);
     } else if (mode == ContentSizeMode.MAX) {
-      return _styleToPixels(style.maxWidth, currentWidth, parent.currentWidth);
+      return _styleToPixels(style!.maxWidth, currentWidth, parent.currentWidth);
     }
   }
 
-  int measureHeight(ViewLayout parent, ContentSizeMode mode) {
-    final style = layoutParams.style;
+  int? measureHeight(ViewLayout parent, ContentSizeMode? mode) {
+    final style = layoutParams!.style;
     if (mode == ContentSizeMode.MIN) {
       return _styleToPixels(
-          style.minHeight, currentHeight, parent.currentHeight);
+          style!.minHeight, currentHeight, parent.currentHeight);
     } else if (mode == ContentSizeMode.MAX) {
       return _styleToPixels(
-          style.maxHeight, currentHeight, parent.currentHeight);
+          style!.maxHeight, currentHeight, parent.currentHeight);
     }
   }
 
@@ -215,19 +213,18 @@
       return int.parse(style.substring(0, style.length - 2));
     } else {
       // TODO(jmesserly): other size units
-      throw new UnsupportedError(
-          'Unknown min/max content size format: "$style"');
+      throw UnsupportedError('Unknown min/max content size format: "$style"');
     }
   }
 
-  static int _styleToPixels(String style, num size, num parentSize) {
+  static int? _styleToPixels(String style, num? size, num? parentSize) {
     if (style == 'none') {
       // For an unset max-content size, use the actual size
-      return size;
+      return size as int?;
     }
     if (style.endsWith('%')) {
       num percent = double.parse(style.substring(0, style.length - 1));
-      return ((percent / 100) * parentSize).toInt();
+      return ((percent / 100) * parentSize!).toInt();
     }
     return _toPixels(style);
   }
diff --git a/samples-dev/swarm/swarm_ui_lib/layout/layout.dart b/samples-dev/swarm/swarm_ui_lib/layout/layout.dart
index ddc5bb1..b060c6e 100644
--- a/samples-dev/swarm/swarm_ui_lib/layout/layout.dart
+++ b/samples-dev/swarm/swarm_ui_lib/layout/layout.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 library layout;
 
 import 'dart:async';
diff --git a/samples-dev/swarm/swarm_ui_lib/util/CollectionUtils.dart b/samples-dev/swarm/swarm_ui_lib/util/CollectionUtils.dart
index 546d126..bba7cf2 100644
--- a/samples-dev/swarm/swarm_ui_lib/util/CollectionUtils.dart
+++ b/samples-dev/swarm/swarm_ui_lib/util/CollectionUtils.dart
@@ -80,9 +80,9 @@
   }
 
   /** Orders an iterable by its values, or by a key selector. */
-  static List orderBy(Iterable source,
+  static List<T> orderBy<T>(Iterable<T> source,
       [NumericValueSelector? selector = null]) {
-    final result = List.from(source);
+    final result = List<T>.from(source);
     sortBy(result, selector);
     return result;
   }