Version 2.12.0-129.0.dev

Merge commit '1231658f99d29279210a87d6d3d38a21b6a9ca63' into 'dev'
diff --git a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
index 9752d91..7610ce4 100644
--- a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
@@ -2566,8 +2566,12 @@
   /// The type of the expression on the LHS of `==` or `!=`.
   final Type _leftOperandType;
 
-  _EqualityOpContext(
-      ExpressionInfo<Variable, Type> conditionInfo, this._leftOperandType)
+  /// If the LHS of `==` or `!=` is a variable reference, the variable.
+  /// Otherwise `null`.
+  final Variable _leftOperandVariable;
+
+  _EqualityOpContext(ExpressionInfo<Variable, Type> conditionInfo,
+      this._leftOperandType, this._leftOperandVariable)
       : super(conditionInfo);
 
   @override
@@ -2602,6 +2606,14 @@
   /// corresponding to it.  Otherwise `null`.
   ExpressionInfo<Variable, Type> _expressionInfo;
 
+  /// The most recently visited expression which was a variable reference, or
+  /// `null` if no expression has been visited that was a variable reference.
+  Expression _expressionWithVariable;
+
+  /// If [_expressionVariable] is not `null`, the variable corresponding to it.
+  /// Otherwise `null`.
+  Variable _expressionVariable;
+
   int _functionNestingLevel = 0;
 
   final AssignedVariables<Node, Variable> _assignedVariables;
@@ -2615,14 +2627,8 @@
 
   @override
   void asExpression_end(Expression subExpression, Type type) {
-    ExpressionInfo<Variable, Type> subExpressionInfo =
-        _getExpressionInfo(subExpression);
-    Variable variable;
-    if (subExpressionInfo is _VariableReadInfo<Variable, Type>) {
-      variable = subExpressionInfo._variable;
-    } else {
-      return;
-    }
+    Variable variable = _getExpressionVariable(subExpression);
+    if (variable == null) return;
     _current = _current.tryPromoteForTypeCast(typeOperations, variable, type);
   }
 
@@ -2730,8 +2736,10 @@
     _EqualityOpContext<Variable, Type> context =
         _stack.removeLast() as _EqualityOpContext<Variable, Type>;
     ExpressionInfo<Variable, Type> lhsInfo = context._conditionInfo;
+    Variable lhsVariable = context._leftOperandVariable;
     Type leftOperandType = context._leftOperandType;
     ExpressionInfo<Variable, Type> rhsInfo = _getExpressionInfo(rightOperand);
+    Variable rhsVariable = _getExpressionVariable(rightOperand);
     TypeClassification leftOperandTypeClassification =
         typeOperations.classifyType(leftOperandType);
     TypeClassification rightOperandTypeClassification =
@@ -2749,18 +2757,16 @@
       // but weak mode it might produce an "equal" result.  We don't want flow
       // analysis behavior to depend on mode, so we conservatively assume that
       // either result is possible.
-    } else if (lhsInfo is _NullInfo<Variable, Type> &&
-        rhsInfo is _VariableReadInfo<Variable, Type>) {
+    } else if (lhsInfo is _NullInfo<Variable, Type> && rhsVariable != null) {
       assert(
           leftOperandTypeClassification == TypeClassification.nullOrEquivalent);
       ExpressionInfo<Variable, Type> equalityInfo =
-          _current.tryMarkNonNullable(typeOperations, rhsInfo._variable);
+          _current.tryMarkNonNullable(typeOperations, rhsVariable);
       _storeExpressionInfo(wholeExpression,
           notEqual ? equalityInfo : ExpressionInfo.invert(equalityInfo));
-    } else if (rhsInfo is _NullInfo<Variable, Type> &&
-        lhsInfo is _VariableReadInfo<Variable, Type>) {
+    } else if (rhsInfo is _NullInfo<Variable, Type> && lhsVariable != null) {
       ExpressionInfo<Variable, Type> equalityInfo =
-          _current.tryMarkNonNullable(typeOperations, lhsInfo._variable);
+          _current.tryMarkNonNullable(typeOperations, lhsVariable);
       _storeExpressionInfo(wholeExpression,
           notEqual ? equalityInfo : ExpressionInfo.invert(equalityInfo));
     }
@@ -2769,7 +2775,9 @@
   @override
   void equalityOp_rightBegin(Expression leftOperand, Type leftOperandType) {
     _stack.add(new _EqualityOpContext<Variable, Type>(
-        _getExpressionInfo(leftOperand), leftOperandType));
+        _getExpressionInfo(leftOperand),
+        leftOperandType,
+        _getExpressionVariable(leftOperand)));
   }
 
   @override
@@ -2844,6 +2852,9 @@
     if (identical(_expressionWithInfo, oldExpression)) {
       _expressionWithInfo = newExpression;
     }
+    if (identical(_expressionWithVariable, oldExpression)) {
+      _expressionWithVariable = newExpression;
+    }
   }
 
   @override
@@ -2901,12 +2912,12 @@
   @override
   void ifNullExpression_rightBegin(
       Expression leftHandSide, Type leftHandSideType) {
-    ExpressionInfo<Variable, Type> lhsInfo = _getExpressionInfo(leftHandSide);
+    Variable lhsVariable = _getExpressionVariable(leftHandSide);
     FlowModel<Variable, Type> promoted;
     _current = _current.split();
-    if (lhsInfo is _VariableReadInfo<Variable, Type>) {
+    if (lhsVariable != null) {
       ExpressionInfo<Variable, Type> promotionInfo =
-          _current.tryMarkNonNullable(typeOperations, lhsInfo._variable);
+          _current.tryMarkNonNullable(typeOperations, lhsVariable);
       _current = promotionInfo.ifFalse;
       promoted = promotionInfo.ifTrue;
     } else {
@@ -2959,12 +2970,10 @@
   @override
   void isExpression_end(Expression isExpression, Expression subExpression,
       bool isNot, Type type) {
-    ExpressionInfo<Variable, Type> subExpressionInfo =
-        _getExpressionInfo(subExpression);
-    if (subExpressionInfo is _VariableReadInfo<Variable, Type>) {
-      ExpressionInfo<Variable, Type> expressionInfo =
-          _current.tryPromoteForTypeCheck(
-              typeOperations, subExpressionInfo._variable, type);
+    Variable subExpressionVariable = _getExpressionVariable(subExpression);
+    if (subExpressionVariable != null) {
+      ExpressionInfo<Variable, Type> expressionInfo = _current
+          .tryPromoteForTypeCheck(typeOperations, subExpressionVariable, type);
       _storeExpressionInfo(isExpression,
           isNot ? ExpressionInfo.invert(expressionInfo) : expressionInfo);
     }
@@ -3054,11 +3063,10 @@
 
   @override
   void nonNullAssert_end(Expression operand) {
-    ExpressionInfo<Variable, Type> operandInfo = _getExpressionInfo(operand);
-    if (operandInfo is _VariableReadInfo<Variable, Type>) {
-      _current = _current
-          .tryMarkNonNullable(typeOperations, operandInfo._variable)
-          .ifTrue;
+    Variable operandVariable = _getExpressionVariable(operand);
+    if (operandVariable != null) {
+      _current =
+          _current.tryMarkNonNullable(typeOperations, operandVariable).ifTrue;
     }
   }
 
@@ -3075,11 +3083,10 @@
     _current = _current.split();
     _stack.add(new _NullAwareAccessContext<Variable, Type>(_current));
     if (target != null) {
-      ExpressionInfo<Variable, Type> targetInfo = _getExpressionInfo(target);
-      if (targetInfo is _VariableReadInfo<Variable, Type>) {
-        _current = _current
-            .tryMarkNonNullable(typeOperations, targetInfo._variable)
-            .ifTrue;
+      Variable targetVariable = _getExpressionVariable(target);
+      if (targetVariable != null) {
+        _current =
+            _current.tryMarkNonNullable(typeOperations, targetVariable).ifTrue;
       }
     }
   }
@@ -3226,7 +3233,7 @@
 
   @override
   Type variableRead(Expression expression, Variable variable) {
-    _storeExpressionInfo(expression, new _VariableReadInfo(_current, variable));
+    _storeExpressionVariable(expression, variable);
     return _current.infoFor(variable).promotedTypes?.last;
   }
 
@@ -3273,6 +3280,8 @@
     print('  current: $_current');
     print('  expressionWithInfo: $_expressionWithInfo');
     print('  expressionInfo: $_expressionInfo');
+    print('  expressionWithVariable: $_expressionWithVariable');
+    print('  expressionVariable: $_expressionVariable');
     print('  stack:');
     for (_FlowContext stackEntry in _stack.reversed) {
       print('    $stackEntry');
@@ -3301,6 +3310,19 @@
     }
   }
 
+  /// Gets the [Variable] associated with the [expression] (which should be the
+  /// last expression that was traversed).  If there is no [Variable] associated
+  /// with the [expression], then `null` is returned.
+  Variable _getExpressionVariable(Expression expression) {
+    if (identical(expression, _expressionWithVariable)) {
+      Variable expressionVariable = _expressionVariable;
+      _expressionVariable = null;
+      return expressionVariable;
+    } else {
+      return null;
+    }
+  }
+
   FlowModel<Variable, Type> _join(
           FlowModel<Variable, Type> first, FlowModel<Variable, Type> second) =>
       FlowModel.join(typeOperations, first, second, _current._emptyVariableMap);
@@ -3319,6 +3341,14 @@
     _expressionInfo = expressionInfo;
     _current = expressionInfo.after;
   }
+
+  /// Associates [expression], which should be the most recently visited
+  /// expression, with the given [Variable] object.
+  void _storeExpressionVariable(
+      Expression expression, Variable expressionVariable) {
+    _expressionWithVariable = expression;
+    _expressionVariable = expressionVariable;
+  }
 }
 
 /// Base class for objects representing constructs in the Dart programming
@@ -3437,28 +3467,6 @@
       'afterBodyAndCatches: $_afterBodyAndCatches)';
 }
 
-/// [ExpressionInfo] representing an expression that reads the value of a
-/// variable.
-class _VariableReadInfo<Variable, Type>
-    implements ExpressionInfo<Variable, Type> {
-  @override
-  final FlowModel<Variable, Type> after;
-
-  /// The variable that is being read.
-  final Variable _variable;
-
-  _VariableReadInfo(this.after, this._variable);
-
-  @override
-  FlowModel<Variable, Type> get ifFalse => after;
-
-  @override
-  FlowModel<Variable, Type> get ifTrue => after;
-
-  @override
-  String toString() => '_VariableReadInfo(after: $after, variable: $_variable)';
-}
-
 /// [_FlowContext] representing a `while` loop (or a C-style `for` loop, which
 /// is functionally similar).
 class _WhileContext<Variable, Type>
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/quote.dart b/pkg/_fe_analyzer_shared/lib/src/parser/quote.dart
index d4928a5..a33410d 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/quote.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/quote.dart
@@ -184,7 +184,7 @@
 String unescapeCodeUnits(List<int> codeUnits, bool isRaw, Object location,
     UnescapeErrorListener listener) {
   // Can't use Uint8List or Uint16List here, the code units may be larger.
-  List<int> result = new List<int>(codeUnits.length);
+  List<int> result = new List<int>.filled(codeUnits.length, null);
   int resultOffset = 0;
 
   for (int i = 0; i < codeUnits.length; i++) {
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/stack_listener.dart b/pkg/_fe_analyzer_shared/lib/src/parser/stack_listener.dart
index e9d29da..6462add 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/stack_listener.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/stack_listener.dart
@@ -518,7 +518,7 @@
 }
 
 class StackImpl implements Stack {
-  List<Object> array = new List<Object>(/* length = */ 8);
+  List<Object> array = new List<Object>.filled(/* length = */ 8, null);
   int arrayLength = 0;
 
   bool get isNotEmpty => arrayLength > 0;
@@ -581,14 +581,14 @@
 
   List<Object> get values {
     final int length = arrayLength;
-    final List<Object> list = new List<Object>(length);
+    final List<Object> list = new List<Object>.filled(length, null);
     list.setRange(/* start = */ 0, length, array);
     return list;
   }
 
   void _grow() {
     final int length = array.length;
-    final List<Object> newArray = new List<Object>(length * 2);
+    final List<Object> newArray = new List<Object>.filled(length * 2, null);
     newArray.setRange(/* start = */ 0, length, array, /* skipCount = */ 0);
     array = newArray;
   }
@@ -597,7 +597,7 @@
 class DebugStack implements Stack {
   Stack realStack = new StackImpl();
   Stack stackTraceStack = new StackImpl();
-  List<StackTrace> latestStacktraces = new List<StackTrace>();
+  List<StackTrace> latestStacktraces = <StackTrace>[];
 
   @override
   Object operator [](int index) {
@@ -654,13 +654,14 @@
 
   List<T> pop(Stack stack, int count, [NullValue nullValue]) {
     if (count == 0) return null;
-    return stack.popList(count, new List<T>(count), nullValue);
+    return stack.popList(count, new List<T>.filled(count, null), nullValue);
   }
 
   List<T> popPadded(Stack stack, int count, int padding,
       [NullValue nullValue]) {
     if (count + padding == 0) return null;
-    return stack.popList(count, new List<T>(count + padding), nullValue);
+    return stack.popList(
+        count, new List<T>.filled(count + padding, null), nullValue);
   }
 }
 
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/token_stream_rewriter.dart b/pkg/_fe_analyzer_shared/lib/src/parser/token_stream_rewriter.dart
index df1e467..7868ae5 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/token_stream_rewriter.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/token_stream_rewriter.dart
@@ -331,7 +331,7 @@
 /// implementation does this by rewriting the previous token to point to the
 /// inserted token. It also allows to undo these changes.
 class UndoableTokenStreamRewriter extends TokenStreamRewriter {
-  List<TokenStreamChange> _changes = new List<TokenStreamChange>();
+  List<TokenStreamChange> _changes = <TokenStreamChange>[];
 
   void undo() {
     for (int i = _changes.length - 1; i >= 0; i--) {
diff --git a/pkg/_fe_analyzer_shared/lib/src/scanner/keyword_state.dart b/pkg/_fe_analyzer_shared/lib/src/scanner/keyword_state.dart
index b4620e3..05f07e0 100644
--- a/pkg/_fe_analyzer_shared/lib/src/scanner/keyword_state.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/scanner/keyword_state.dart
@@ -20,7 +20,8 @@
   static KeywordState _KEYWORD_STATE;
   static KeywordState get KEYWORD_STATE {
     if (_KEYWORD_STATE == null) {
-      List<String> strings = new List<String>(analyzer.Keyword.values.length);
+      List<String> strings =
+          new List<String>.filled(analyzer.Keyword.values.length, null);
       for (int i = 0; i < analyzer.Keyword.values.length; i++) {
         strings[i] = analyzer.Keyword.values[i].lexeme;
       }
@@ -38,7 +39,7 @@
       int start, List<String> strings, int offset, int length) {
     bool isLowercase = true;
 
-    List<KeywordState> table = new List<KeywordState>($z - $A + 1);
+    List<KeywordState> table = new List<KeywordState>.filled($z - $A + 1, null);
     assert(length != 0);
     int chunk = 0;
     int chunkStart = -1;
diff --git a/pkg/_fe_analyzer_shared/lib/src/scanner/string_canonicalizer.dart b/pkg/_fe_analyzer_shared/lib/src/scanner/string_canonicalizer.dart
index 2b127b7..7370bdf 100644
--- a/pkg/_fe_analyzer_shared/lib/src/scanner/string_canonicalizer.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/scanner/string_canonicalizer.dart
@@ -34,7 +34,7 @@
   int _count = 0;
 
   /// The table itself.
-  List<Node> _nodes = new List<Node>(INITIAL_SIZE);
+  List<Node> _nodes = new List<Node>.filled(INITIAL_SIZE, null);
 
   static String decode(List<int> data, int start, int end, bool asciiOnly) {
     String s;
@@ -64,7 +64,7 @@
 
   rehash() {
     int newSize = _size * 2;
-    List<Node> newNodes = new List<Node>(newSize);
+    List<Node> newNodes = new List<Node>.filled(newSize, null);
     for (int i = 0; i < _size; i++) {
       Node t = _nodes[i];
       while (t != null) {
@@ -117,7 +117,7 @@
 
   clear() {
     _size = INITIAL_SIZE;
-    _nodes = new List<Node>(_size);
+    _nodes = new List<Node>.filled(_size, null);
     _count = 0;
   }
 }
diff --git a/pkg/_fe_analyzer_shared/lib/src/util/link.dart b/pkg/_fe_analyzer_shared/lib/src/util/link.dart
index 8cb8dd0..2474f06 100644
--- a/pkg/_fe_analyzer_shared/lib/src/util/link.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/util/link.dart
@@ -24,9 +24,9 @@
   List<T> toList({bool growable: true}) {
     List<T> result;
     if (!growable) {
-      result = new List<T>(slowLength());
+      result = new List<T>.filled(slowLength(), null);
     } else {
-      result = new List<T>();
+      result = <T>[];
       result.length = slowLength();
     }
     int i = 0;
@@ -46,9 +46,9 @@
   List<E> mapToList<E>(E fn(T item), {bool growable: true}) {
     List<E> result;
     if (!growable) {
-      result = new List<E>(slowLength());
+      result = new List<E>.filled(slowLength(), null);
     } else {
-      result = new List<E>();
+      result = <E>[];
       result.length = slowLength();
     }
     int i = 0;
diff --git a/pkg/_fe_analyzer_shared/lib/src/util/link_implementation.dart b/pkg/_fe_analyzer_shared/lib/src/util/link_implementation.dart
index e9d97ec..7fced1a 100644
--- a/pkg/_fe_analyzer_shared/lib/src/util/link_implementation.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/util/link_implementation.dart
@@ -168,8 +168,8 @@
   }
 
   List<T> toList() {
-    if (length == 0) return new List<T>(0);
-    List<T> list = new List<T>(length);
+    if (length == 0) return new List<T>.filled(0, null);
+    List<T> list = new List<T>.filled(length, null);
     int index = 0;
     Link<T> link = head;
     while (link.isNotEmpty) {
diff --git a/pkg/_fe_analyzer_shared/tool/smoke_test_quick.dart b/pkg/_fe_analyzer_shared/tool/smoke_test_quick.dart
index e5c6d2b..2c7025c 100644
--- a/pkg/_fe_analyzer_shared/tool/smoke_test_quick.dart
+++ b/pkg/_fe_analyzer_shared/tool/smoke_test_quick.dart
@@ -10,7 +10,7 @@
 
 main(List<String> args) async {
   Stopwatch stopwatch = new Stopwatch()..start();
-  List<Future> futures = new List<Future>();
+  List<Future> futures = <Future>[];
   futures.add(run("pkg/front_end/test/spelling_test_src_suite.dart",
       ["--", "spelling_test_src/_fe_analyzer_shared/..."]));
   futures.add(run(
diff --git a/pkg/analysis_server/lib/src/services/completion/yaml/producer.dart b/pkg/analysis_server/lib/src/services/completion/yaml/producer.dart
index 67267f0..cc96113 100644
--- a/pkg/analysis_server/lib/src/services/completion/yaml/producer.dart
+++ b/pkg/analysis_server/lib/src/services/completion/yaml/producer.dart
@@ -4,6 +4,8 @@
 
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analyzer/file_system/file_system.dart';
+import 'package:meta/meta.dart';
+import 'package:path/path.dart' as path;
 
 /// An object that represents the location of a Boolean value.
 class BooleanProducer extends Producer {
@@ -51,22 +53,61 @@
 
 /// An object that represents the location of a possibly relative file path.
 class FilePathProducer extends Producer {
-  /// The resource provider used to access the content of the file in which
-  /// completion was requested.
-  final ResourceProvider provider;
-
-  /// Initialize a location whose valid values are file paths.
-  FilePathProducer(this.provider);
+  /// Initialize a producer whose valid values are file paths.
+  const FilePathProducer();
 
   @override
   Iterable<CompletionSuggestion> suggestions(
       YamlCompletionRequest request) sync* {
-    // TODO(brianwilkerson) Implement this.
+    // This currently assumes that all paths will be posix paths, but we might
+    // want to support platform-specific paths at some point, in which case we
+    // should add a flag to the constructor and use that to choose between the
+    // hard-coded `path.posix` and `provider.pathContext`;
+    var provider = request.resourceProvider;
+    var context = path.posix;
+    var separator = context.separator;
+    var precedingText = request.precedingText;
+
+    String parentDirectory;
+    if (precedingText.isEmpty || precedingText.endsWith(separator)) {
+      parentDirectory = precedingText;
+    } else {
+      parentDirectory = context.dirname(precedingText);
+    }
+    if (parentDirectory == '.') {
+      parentDirectory = '';
+    } else if (parentDirectory.endsWith(separator)) {
+      parentDirectory = parentDirectory.substring(
+          0, parentDirectory.length - separator.length);
+    }
+    if (context.isRelative(parentDirectory)) {
+      parentDirectory =
+          context.join(context.dirname(request.filePath), parentDirectory);
+    }
+    parentDirectory = context.normalize(parentDirectory);
+    var dir = provider.getResource(parentDirectory);
+    if (dir is Folder) {
+      try {
+        for (var child in dir.getChildren()) {
+          var name = child.shortName;
+          if (child is Folder) {
+            if (!name.startsWith('.')) {
+              yield identifier(name);
+            }
+          } else if (child is File) {
+            yield identifier(name);
+          }
+        }
+      } on FileSystemException {
+        // Guard against I/O exceptions.
+      }
+    }
   }
 }
 
 /// An object that represents the location of the keys/values in a map.
 abstract class KeyValueProducer extends Producer {
+  /// Initialize a producer representing a key/value pair in a map.
   const KeyValueProducer();
 
   /// Returns a producer for values of the given [key].
@@ -106,7 +147,6 @@
   /// by the map of [children].
   const MapProducer(this._children);
 
-  /// Returns a producer for values of the given [key].
   @override
   Producer producerForKey(String key) => _children[key];
 
@@ -144,8 +184,20 @@
   Iterable<CompletionSuggestion> suggestions(YamlCompletionRequest request);
 }
 
+/// The information provided to a [Producer] when requesting completions.
 class YamlCompletionRequest {
+  /// The resource provider used to access the file system.
   final ResourceProvider resourceProvider;
 
-  YamlCompletionRequest(this.resourceProvider);
+  /// The absolute path of the file in which completions are being requested.
+  final String filePath;
+
+  /// The text to the left of the cursor.
+  final String precedingText;
+
+  /// Initialize a newly created completion request.
+  YamlCompletionRequest(
+      {@required this.filePath,
+      @required this.precedingText,
+      @required this.resourceProvider});
 }
diff --git a/pkg/analysis_server/lib/src/services/completion/yaml/pubspec_generator.dart b/pkg/analysis_server/lib/src/services/completion/yaml/pubspec_generator.dart
index c616d58..2b3794f 100644
--- a/pkg/analysis_server/lib/src/services/completion/yaml/pubspec_generator.dart
+++ b/pkg/analysis_server/lib/src/services/completion/yaml/pubspec_generator.dart
@@ -30,7 +30,7 @@
     //  and 'dev_dependencies'.
     'dependency_overrides': EmptyProducer(),
     'flutter': MapProducer({
-      'assets': EmptyProducer(), // ListProducer(FilePathProducer()),
+      'assets': ListProducer(FilePathProducer()),
       'fonts': ListProducer(MapProducer({
         'family': EmptyProducer(),
         'fonts': ListProducer(MapProducer({
diff --git a/pkg/analysis_server/lib/src/services/completion/yaml/yaml_completion_generator.dart b/pkg/analysis_server/lib/src/services/completion/yaml/yaml_completion_generator.dart
index 561d209..2746a76 100644
--- a/pkg/analysis_server/lib/src/services/completion/yaml/yaml_completion_generator.dart
+++ b/pkg/analysis_server/lib/src/services/completion/yaml/yaml_completion_generator.dart
@@ -40,39 +40,43 @@
       // If the contents can't be parsed, then there are no suggestions.
       return const YamlCompletionResults.empty();
     }
-    var path = _pathToOffset(root, offset);
-    var completionNode = path.last;
+    var nodePath = _pathToOffset(root, offset);
+    var completionNode = nodePath.last;
+    var precedingText = '';
     if (completionNode is YamlScalar) {
       var value = completionNode.value;
-      if (value == null) {
-        return getSuggestionsForPath(path, offset);
-      } else if (value is String && completionNode.style == ScalarStyle.PLAIN) {
-        return getSuggestionsForPath(path, offset);
+      if (value is String && completionNode.style == ScalarStyle.PLAIN) {
+        precedingText =
+            value.substring(0, offset - completionNode.span.start.offset);
+      } else if (value != null) {
+        // There are no completions at the given location.
+        return const YamlCompletionResults.empty();
       }
-    } else {
-      return getSuggestionsForPath(path, offset);
     }
-    // There are no completions at the given location.
-    return const YamlCompletionResults.empty();
+    var request = YamlCompletionRequest(
+        filePath: filePath,
+        precedingText: precedingText,
+        resourceProvider: resourceProvider);
+    return getSuggestionsForPath(request, nodePath, offset);
   }
 
-  /// Given a [path] to the node in which completions are being requested and
-  /// the offset of the cursor, return the completions appropriate at that
-  /// location.
-  YamlCompletionResults getSuggestionsForPath(List<YamlNode> path, int offset) {
-    var request = YamlCompletionRequest(resourceProvider);
-    var producer = _producerForPath(path);
+  /// Given the [request] to pass to producers, a [nodePath] to the node in
+  /// which completions are being requested and the offset of the cursor, return
+  /// the completions appropriate at that location.
+  YamlCompletionResults getSuggestionsForPath(
+      YamlCompletionRequest request, List<YamlNode> nodePath, int offset) {
+    var producer = _producerForPath(nodePath);
     if (producer == null) {
       return const YamlCompletionResults.empty();
     }
-    var invalidSuggestions = _siblingsOnPath(path);
+    var invalidSuggestions = _siblingsOnPath(nodePath);
     var suggestions = <CompletionSuggestion>[];
     for (var suggestion in producer.suggestions(request)) {
       if (!invalidSuggestions.contains(suggestion.completion)) {
         suggestions.add(suggestion);
       }
     }
-    final node = path.isNotEmpty ? path.last : null;
+    final node = nodePath.isNotEmpty ? nodePath.last : null;
     final replaceNode = node is YamlScalar && node.containsOffset(offset);
     final replacementOffset = replaceNode ? node.span.start.offset : offset;
     final replacementLength = replaceNode ? node.span.length : 0;
diff --git a/pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart b/pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart
index c21363f..96e8e89 100644
--- a/pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart
+++ b/pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart
@@ -32,7 +32,7 @@
     }
     return tokens;
   } catch (e) {
-    return List<Token>(0);
+    return List<Token>.filled(0, null);
   }
 }
 
diff --git a/pkg/analysis_server/lib/src/services/correction/util.dart b/pkg/analysis_server/lib/src/services/correction/util.dart
index 59dca74..46b3f03 100644
--- a/pkg/analysis_server/lib/src/services/correction/util.dart
+++ b/pkg/analysis_server/lib/src/services/correction/util.dart
@@ -422,7 +422,7 @@
     }
   }
   // fill array of parents
-  var parents = List<AstNode>(numParents);
+  var parents = List<AstNode>.filled(numParents, null);
   var current = node.parent;
   var index = numParents;
   while (current != null) {
diff --git a/pkg/analysis_server/test/completion_test.dart b/pkg/analysis_server/test/completion_test.dart
index 3067b77..bb5fa96 100644
--- a/pkg/analysis_server/test/completion_test.dart
+++ b/pkg/analysis_server/test/completion_test.dart
@@ -181,7 +181,7 @@
 
     // Type propagation
     buildTests('testCommentSnippets035', '''
-class List{clear(){}length(){}}t3() {var x=new List(), y=x.!1length();x.!2clear();}''',
+class List{clear(){}length(){}}t3() {var x=[], y=x.!1length();x.!2clear();}''',
         <String>['1+length', '2+clear']);
 
     buildTests('testCommentSnippets036', '''
@@ -1829,7 +1829,7 @@
   var x = [Q.!2]
 }
 void c() {
-  var x = new List([Q.!3])
+  var x = new List.filled([Q.!3], null)
 }
 void d() {
   new Q.!4
diff --git a/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
index 1e7de2b..ff603a4 100644
--- a/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
@@ -3421,7 +3421,7 @@
     assertNotSuggested('_g');
     assertSuggestClass('bool');
     if (suggestConstructorsWithoutNew) {
-      assertSuggestConstructor('List');
+      assertSuggestConstructor('List.filled');
     }
   }
 
diff --git a/pkg/analysis_server/test/services/refactoring/extract_method_test.dart b/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
index 9db1931..ff277f5 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
@@ -1575,17 +1575,17 @@
   Future<void> test_singleExpression_returnTypeGeneric() async {
     await indexTestUnit('''
 main() {
-  var v = new List<String>();
+  var v = <String>[];
 }
 ''');
-    _createRefactoringForString('new List<String>()');
+    _createRefactoringForString('<String>[]');
     // apply refactoring
     return _assertSuccessfulRefactoring('''
 main() {
   var v = res();
 }
 
-List<String> res() => new List<String>();
+List<String> res() => <String>[];
 ''');
   }
 
diff --git a/pkg/analysis_server/test/src/services/completion/yaml/pubspec_generator_test.dart b/pkg/analysis_server/test/src/services/completion/yaml/pubspec_generator_test.dart
index 11430c5..b00f1d4 100644
--- a/pkg/analysis_server/test/src/services/completion/yaml/pubspec_generator_test.dart
+++ b/pkg/analysis_server/test/src/services/completion/yaml/pubspec_generator_test.dart
@@ -41,10 +41,70 @@
 flutter:
   ^
 ''');
-    assertSuggestion('assets: ');
+    assertSuggestion('assets:');
     assertSuggestion('plugin: ');
   }
 
+  void test_flutter_assets_invalidPath() {
+    newFile('/home/test/assets/img1.jpg');
+    getCompletions('''
+flutter:
+  assets:
+    - assets?im^
+''');
+    assertNoSuggestion('img1.jpg');
+  }
+
+  void test_flutter_assets_nonExistentPath() {
+    newFile('/home/test/assets/img1.jpg');
+    getCompletions('''
+flutter:
+  assets:
+    - asets/im^
+''');
+    assertNoSuggestion('img1.jpg');
+  }
+
+  void test_flutter_assets_noPath() {
+    newFile('/home/test/assets/img1.jpg');
+    getCompletions('''
+flutter:
+  assets:
+    - ^
+''');
+    assertSuggestion('assets');
+  }
+
+  void test_flutter_assets_partialPath() {
+    newFile('/home/test/assets/img1.jpg');
+    getCompletions('''
+flutter:
+  assets:
+    - assets/im^
+''');
+    assertSuggestion('img1.jpg');
+  }
+
+  void test_flutter_assets_path_withFollowing() {
+    newFile('/home/test/assets/img1.jpg');
+    getCompletions('''
+flutter:
+  assets:
+    - assets/^img
+''');
+    assertSuggestion('img1.jpg');
+  }
+
+  void test_flutter_assets_path_withoutFollowing() {
+    newFile('/home/test/assets/img1.jpg');
+    getCompletions('''
+flutter:
+  assets:
+    - assets/^
+''');
+    assertSuggestion('img1.jpg');
+  }
+
   void test_flutter_fonts() {
     getCompletions('''
 flutter:
diff --git a/pkg/analyzer/lib/src/dart/analysis/dependency/reference_collector.dart b/pkg/analyzer/lib/src/dart/analysis/dependency/reference_collector.dart
index 74a6b93..1314ccf 100644
--- a/pkg/analyzer/lib/src/dart/analysis/dependency/reference_collector.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/dependency/reference_collector.dart
@@ -121,8 +121,9 @@
       }
     }
 
-    var importPrefixes = List<String>(importPrefixCount);
-    var importPrefixedReferencedNames = List<List<String>>(importPrefixCount);
+    var importPrefixes = List<String>.filled(importPrefixCount, null);
+    var importPrefixedReferencedNames =
+        List<List<String>>.filled(importPrefixCount, null);
     var importIndex = 0;
     for (var i = 0; i < _importPrefixedReferences.length; i++) {
       var import = _importPrefixedReferences[i];
diff --git a/pkg/analyzer/lib/src/dart/analysis/unlinked_api_signature.dart b/pkg/analyzer/lib/src/dart/analysis/unlinked_api_signature.dart
index f916888..6968796 100644
--- a/pkg/analyzer/lib/src/dart/analysis/unlinked_api_signature.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/unlinked_api_signature.dart
@@ -28,15 +28,11 @@
     signature.addInt(node.members.length);
     for (var member in node.members) {
       if (member is ConstructorDeclaration) {
-        var lastInitializer = member.constKeyword != null &&
-                member.initializers != null &&
-                member.initializers.isNotEmpty
-            ? member.initializers.last
-            : null;
-        addTokens(
-          member.beginToken,
-          (lastInitializer ?? member.parameters ?? member.name).endToken,
-        );
+        addTokens(member.beginToken, member.parameters.endToken);
+        if (member.constKeyword != null) {
+          addNodeList(member.initializers);
+        }
+        addNode(member.redirectedConstructor);
       } else if (member is FieldDeclaration) {
         var variableList = member.fields;
         addVariables(
@@ -65,7 +61,15 @@
   }
 
   void addNode(AstNode node) {
-    addTokens(node.beginToken, node.endToken);
+    if (node != null) {
+      addTokens(node.beginToken, node.endToken);
+    }
+  }
+
+  void addNodeList(List<AstNode> nodes) {
+    for (var node in nodes) {
+      addNode(node);
+    }
   }
 
   void addToken(Token token) {
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index a948a39..59fd5c6 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -4475,7 +4475,7 @@
   @override
   List<ParameterElement> get parameterElements {
     int count = _parameters.length;
-    List<ParameterElement> types = List<ParameterElement>(count);
+    List<ParameterElement> types = List<ParameterElement>.filled(count, null);
     for (int i = 0; i < count; i++) {
       types[i] = _parameters[i].declaredElement;
     }
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index 33034f0..6c1f831 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -406,7 +406,7 @@
     }
 
     int argumentCount = arguments.length;
-    var argumentValues = List<DartObjectImpl>(argumentCount);
+    var argumentValues = List<DartObjectImpl>.filled(argumentCount, null);
     Map<String, NamedExpression> namedNodes;
     Map<String, DartObjectImpl> namedValues;
     for (int i = 0; i < argumentCount; i++) {
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index a41ae6b..faf322e 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -1019,7 +1019,7 @@
       int count = superParameters.length;
       if (count > 0) {
         List<ParameterElement> implicitParameters =
-            List<ParameterElement>(count);
+            List<ParameterElement>.filled(count, null);
         for (int i = 0; i < count; i++) {
           ParameterElement superParameter = superParameters[i];
           ParameterElementImpl implicitParameter;
@@ -3167,7 +3167,7 @@
       return const <ElementAnnotation>[];
     }
 
-    var annotations = List<ElementAnnotation>(length);
+    var annotations = List<ElementAnnotation>.filled(length, null);
     for (int i = 0; i < length; i++) {
       var ast = nodeList[i];
       annotations[i] = ElementAnnotationImpl(unit)
diff --git a/pkg/analyzer/lib/src/dart/element/least_upper_bound.dart b/pkg/analyzer/lib/src/dart/element/least_upper_bound.dart
index 941812a..d355eab 100644
--- a/pkg/analyzer/lib/src/dart/element/least_upper_bound.dart
+++ b/pkg/analyzer/lib/src/dart/element/least_upper_bound.dart
@@ -135,7 +135,7 @@
   List<InstantiatedClass> _toInstantiatedClasses(
     List<InterfaceType> interfaces,
   ) {
-    var result = List<InstantiatedClass>(interfaces.length);
+    var result = List<InstantiatedClass>.filled(interfaces.length, null);
     for (var i = 0; i < interfaces.length; i++) {
       var interface = interfaces[i];
       var substituted = _substitution.substituteType(interface);
@@ -196,7 +196,7 @@
       assert(args1.length == args2.length);
       assert(args1.length == params.length);
 
-      var args = List<DartType>(args1.length);
+      var args = List<DartType>.filled(args1.length, null);
       for (int i = 0; i < args1.length; i++) {
         // TODO (kallentu) : Clean up TypeParameterElementImpl casting once
         // variance is added to the interface.
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index 9816e56..f343aa1 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -1069,8 +1069,8 @@
 
     // Create type formals with specialized bounds.
     // For example `<U extends T>` where T comes from an outer scope.
-    var newElements = List<TypeParameterElement>(elements.length);
-    var newTypes = List<TypeParameterType>(elements.length);
+    var newElements = List<TypeParameterElement>.filled(elements.length, null);
+    var newTypes = List<TypeParameterType>.filled(elements.length, null);
     for (int i = 0; i < newElements.length; i++) {
       var element = elements[i];
       var newElement = TypeParameterElementImpl.synthetic(element.name);
diff --git a/pkg/analyzer/lib/src/dart/element/top_merge.dart b/pkg/analyzer/lib/src/dart/element/top_merge.dart
index 78714ea..8fb1327 100644
--- a/pkg/analyzer/lib/src/dart/element/top_merge.dart
+++ b/pkg/analyzer/lib/src/dart/element/top_merge.dart
@@ -212,7 +212,7 @@
       throw _TopMergeStateError(T, S, 'Different number of formal parameters');
     }
 
-    var R_parameters = List<ParameterElement>(T_parameters.length);
+    var R_parameters = List<ParameterElement>.filled(T_parameters.length, null);
     for (var i = 0; i < T_parameters.length; i++) {
       var T_parameter = T_parameters[i];
       var S_parameter = S_parameters[i];
@@ -278,7 +278,7 @@
     if (T_arguments.isEmpty) {
       return T;
     } else {
-      var arguments = List<DartType>(T_arguments.length);
+      var arguments = List<DartType>.filled(T_arguments.length, null);
       for (var i = 0; i < T_arguments.length; i++) {
         arguments[i] = topMerge(T_arguments[i], S_arguments[i]);
       }
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 20211b6..50953f8 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -644,7 +644,7 @@
     if (_accessors == null) {
       List<PropertyAccessorElement> accessors = element.accessors;
       List<PropertyAccessorElement> members =
-          List<PropertyAccessorElement>(accessors.length);
+          List<PropertyAccessorElement>.filled(accessors.length, null);
       for (int i = 0; i < accessors.length; i++) {
         members[i] = PropertyAccessorMember.from(accessors[i], this);
       }
@@ -666,7 +666,7 @@
     if (_constructors == null) {
       List<ConstructorElement> constructors = element.constructors;
       List<ConstructorElement> members =
-          List<ConstructorElement>(constructors.length);
+          List<ConstructorElement>.filled(constructors.length, null);
       for (int i = 0; i < constructors.length; i++) {
         members[i] = ConstructorMember.from(constructors[i], this);
       }
@@ -767,7 +767,8 @@
   List<MethodElement> get methods {
     if (_methods == null) {
       List<MethodElement> methods = element.methods;
-      List<MethodElement> members = List<MethodElement>(methods.length);
+      List<MethodElement> members =
+          List<MethodElement>.filled(methods.length, null);
       for (int i = 0; i < methods.length; i++) {
         members[i] = MethodMember.from(methods[i], this);
       }
@@ -1322,7 +1323,7 @@
     if (typeParameters.isEmpty) return defined;
 
     var substitution = Substitution.fromInterfaceType(this);
-    var result = List<InterfaceType>(defined.length);
+    var result = List<InterfaceType>.filled(defined.length, null);
     for (int i = 0; i < defined.length; i++) {
       result[i] = substitution.substituteType(defined[i]);
     }
@@ -1425,7 +1426,7 @@
     if (argumentCount == 0) {
       return firstType;
     }
-    List<DartType> lubArguments = List<DartType>(argumentCount);
+    List<DartType> lubArguments = List<DartType>.filled(argumentCount, null);
     for (int i = 0; i < argumentCount; i++) {
       //
       // Ideally we would take the least upper bound of the two argument types,
diff --git a/pkg/analyzer/lib/src/dart/element/type_algebra.dart b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
index 2854f7e..a6ca14b 100644
--- a/pkg/analyzer/lib/src/dart/element/type_algebra.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
@@ -239,7 +239,8 @@
       return const <TypeParameterElement>[];
     }
 
-    var freshElements = List<TypeParameterElement>(elements.length);
+    var freshElements =
+        List<TypeParameterElement>.filled(elements.length, null);
     for (var i = 0; i < elements.length; i++) {
       // TODO (kallentu) : Clean up TypeParameterElementImpl casting once
       // variance is added to the interface.
diff --git a/pkg/analyzer/lib/src/dart/resolver/type_name_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/type_name_resolver.dart
index 55967cb..c077118 100644
--- a/pkg/analyzer/lib/src/dart/resolver/type_name_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/type_name_resolver.dart
@@ -133,7 +133,7 @@
       return const <DartType>[];
     }
 
-    var typeArguments = List<DartType>(parameterCount);
+    var typeArguments = List<DartType>.filled(parameterCount, null);
     for (var i = 0; i < parameterCount; i++) {
       typeArguments[i] = arguments[i].type;
     }
diff --git a/pkg/analyzer/lib/src/dart/resolver/typed_literal_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/typed_literal_resolver.dart
index b36521c..e701244 100644
--- a/pkg/analyzer/lib/src/dart/resolver/typed_literal_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/typed_literal_resolver.dart
@@ -768,8 +768,9 @@
       nullabilitySuffix: _noneOrStarSuffix,
     );
 
-    var parameters = List<ParameterElement>(2 * inferredTypes.length);
-    var argumentTypes = List<DartType>(2 * inferredTypes.length);
+    var parameters =
+        List<ParameterElement>.filled(2 * inferredTypes.length, null);
+    var argumentTypes = List<DartType>.filled(2 * inferredTypes.length, null);
     for (var i = 0; i < inferredTypes.length; i++) {
       parameters[2 * i + 0] = ParameterElementImpl.synthetic(
           'key', genericKeyType, ParameterKind.POSITIONAL);
@@ -802,8 +803,8 @@
       nullabilitySuffix: _noneOrStarSuffix,
     );
 
-    var parameters = List<ParameterElement>(inferredTypes.length);
-    var argumentTypes = List<DartType>(inferredTypes.length);
+    var parameters = List<ParameterElement>.filled(inferredTypes.length, null);
+    var argumentTypes = List<DartType>.filled(inferredTypes.length, null);
     for (var i = 0; i < inferredTypes.length; i++) {
       parameters[i] = ParameterElementImpl.synthetic(
           'element', genericElementType, ParameterKind.POSITIONAL);
diff --git a/pkg/analyzer/lib/src/dart/sdk/sdk.dart b/pkg/analyzer/lib/src/dart/sdk/sdk.dart
index 5c3e5c9..0a0d0fa 100644
--- a/pkg/analyzer/lib/src/dart/sdk/sdk.dart
+++ b/pkg/analyzer/lib/src/dart/sdk/sdk.dart
@@ -142,7 +142,7 @@
   String _getPath(File file) {
     List<SdkLibrary> libraries = libraryMap.sdkLibraries;
     int length = libraries.length;
-    List<String> paths = List(length);
+    List<String> paths = List.filled(length, null);
     String filePath = getRelativePathFromFile(file);
     if (filePath == null) {
       return null;
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index fc6bb66..22fbfd8 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -8629,7 +8629,7 @@
    */
   static const CompileTimeErrorCode PRIVATE_OPTIONAL_PARAMETER =
       CompileTimeErrorCode('PRIVATE_OPTIONAL_PARAMETER',
-          "Named optional parameters can't start with an underscore.");
+          "Named parameters can't start with an underscore.");
 
   static const CompileTimeErrorCode PRIVATE_SETTER = CompileTimeErrorCode(
       'PRIVATE_SETTER',
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index 58ec08b..16eb67e 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -2087,10 +2087,10 @@
           member.labels.insert(0, pop());
           --labelCount;
         }
-        members = List<SwitchMember>(expressionCount + 1);
+        members = List<SwitchMember>.filled(expressionCount + 1, null);
         members[expressionCount] = member;
       } else {
-        members = List<SwitchMember>(expressionCount);
+        members = List<SwitchMember>.filled(expressionCount, null);
       }
       for (int index = expressionCount - 1; index >= 0; --index) {
         SwitchMember member = pop();
@@ -3476,7 +3476,7 @@
   void handleTypeVariablesDefined(Token token, int count) {
     debugEvent("handleTypeVariablesDefined");
     assert(count > 0);
-    push(popTypedList(count, List<TypeParameter>(count)));
+    push(popTypedList(count, List<TypeParameter>.filled(count, null)));
   }
 
   @override
@@ -3563,7 +3563,7 @@
   List<CommentReference> parseCommentReferences(Token dartdoc) {
     // Parse dartdoc into potential comment reference source/offset pairs
     int count = parser.parseCommentReferences(dartdoc);
-    List sourcesAndOffsets = List(count * 2);
+    List sourcesAndOffsets = List.filled(count * 2, null);
     popList(count * 2, sourcesAndOffsets);
 
     // Parse each of the source/offset pairs into actual comment references
@@ -3581,7 +3581,7 @@
       }
     }
 
-    final references = List<CommentReference>(count);
+    final references = List<CommentReference>.filled(count, null);
     popTypedList(count, references);
     return references;
   }
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index e7ba7d0..e54f009 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -1529,7 +1529,7 @@
       String name = element.displayName;
       List<Element> conflictingMembers = element.conflictingElements;
       int count = conflictingMembers.length;
-      List<String> libraryNames = List<String>(count);
+      List<String> libraryNames = List<String>.filled(count, null);
       for (int i = 0; i < count; i++) {
         libraryNames[i] = _getLibraryName(conflictingMembers[i]);
       }
@@ -3859,8 +3859,6 @@
   }
 
   /// Check that the given named optional [parameter] does not begin with '_'.
-  ///
-  /// See [CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER].
   void _checkForPrivateOptionalParameter(FormalParameter parameter) {
     // should be named parameter
     if (!parameter.isNamed) {
@@ -3873,7 +3871,7 @@
     }
 
     _errorReporter.reportErrorForNode(
-        CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, parameter);
+        CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, parameter.identifier);
   }
 
   /// Check whether the given constructor [declaration] is the redirecting
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 21b7d76..d44e6a0 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -2208,7 +2208,7 @@
     NodeList<Expression> arguments = argumentList.arguments;
     int argumentCount = arguments.length;
     List<ParameterElement> resolvedParameters =
-        List<ParameterElement>(argumentCount);
+        List<ParameterElement>.filled(argumentCount, null);
     int positionalArgumentCount = 0;
     HashSet<String> usedNames;
     bool noBlankArguments = true;
diff --git a/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart b/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
index 81d60f6..a76d625 100644
--- a/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
@@ -451,7 +451,7 @@
       String name, List<String> constantNames) {
     int count = constantNames.length;
     List<EnumConstantDeclaration> constants =
-        List<EnumConstantDeclaration>(count);
+        List<EnumConstantDeclaration>.filled(count, null);
     for (int i = 0; i < count; i++) {
       constants[i] = astFactory.enumConstantDeclaration(
           null, null, identifier3(constantNames[i]));
diff --git a/pkg/analyzer/lib/src/generated/testing/element_factory.dart b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
index afd513a..88250f8 100644
--- a/pkg/analyzer/lib/src/generated/testing/element_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
@@ -126,7 +126,8 @@
     constructor.isConst = isConst;
     if (argumentTypes != null) {
       int count = argumentTypes.length;
-      List<ParameterElement> parameters = List<ParameterElement>(count);
+      List<ParameterElement> parameters =
+          List<ParameterElement>.filled(count, null);
       for (int i = 0; i < count; i++) {
         ParameterElementImpl parameter = ParameterElementImpl("a$i", i);
         parameter.type = argumentTypes[i];
@@ -320,7 +321,8 @@
       method.parameters = const <ParameterElement>[];
     } else {
       int count = argumentTypes.length;
-      List<ParameterElement> parameters = List<ParameterElement>(count);
+      List<ParameterElement> parameters =
+          List<ParameterElement>.filled(count, null);
       for (int i = 0; i < count; i++) {
         ParameterElementImpl parameter = ParameterElementImpl("a$i", i);
         parameter.type = argumentTypes[i];
@@ -487,7 +489,7 @@
       return const <TypeParameterElement>[];
     }
     List<TypeParameterElementImpl> typeParameters =
-        List<TypeParameterElementImpl>(count);
+        List<TypeParameterElementImpl>.filled(count, null);
     for (int i = 0; i < count; i++) {
       typeParameters[i] = typeParameterWithType(names[i]);
     }
diff --git a/pkg/analyzer/lib/src/summary/flat_buffers.dart b/pkg/analyzer/lib/src/summary/flat_buffers.dart
index b939bb9..764ea95 100644
--- a/pkg/analyzer/lib/src/summary/flat_buffers.dart
+++ b/pkg/analyzer/lib/src/summary/flat_buffers.dart
@@ -737,7 +737,7 @@
 
   @override
   E operator [](int i) {
-    _items ??= List<E>(length);
+    _items ??= List<E>.filled(length, null);
     E item = _items[i];
     if (item == null) {
       item = elementReader.read(bc, offset + 4 + elementReader.size * i);
diff --git a/pkg/analyzer/lib/src/summary2/apply_resolution.dart b/pkg/analyzer/lib/src/summary2/apply_resolution.dart
index 62ecae0..1c0785b 100644
--- a/pkg/analyzer/lib/src/summary2/apply_resolution.dart
+++ b/pkg/analyzer/lib/src/summary2/apply_resolution.dart
@@ -901,7 +901,7 @@
       return const <ElementAnnotation>[];
     }
 
-    var annotations = List<ElementAnnotation>(length);
+    var annotations = List<ElementAnnotation>.filled(length, null);
     for (int i = 0; i < length; i++) {
       var ast = nodeList[i];
       annotations[i] = ElementAnnotationImpl(unit)
diff --git a/pkg/analyzer/lib/src/summary2/default_types_builder.dart b/pkg/analyzer/lib/src/summary2/default_types_builder.dart
index ad8c510..68cc053 100644
--- a/pkg/analyzer/lib/src/summary2/default_types_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/default_types_builder.dart
@@ -161,8 +161,8 @@
 
     var nodes = parameterList.typeParameters;
     var length = nodes.length;
-    var elements = List<TypeParameterElementImpl>(length);
-    var bounds = List<DartType>(length);
+    var elements = List<TypeParameterElementImpl>.filled(length, null);
+    var bounds = List<DartType>.filled(length, null);
     for (int i = 0; i < length; i++) {
       var node = nodes[i];
       elements[i] = node.declaredElement;
@@ -324,8 +324,8 @@
   ) {
     assert(parameters.length == bounds.length);
 
-    vertices = List<int>(parameters.length);
-    _edges = List<List<int>>(parameters.length);
+    vertices = List<int>.filled(parameters.length, null);
+    _edges = List<List<int>>.filled(parameters.length, null);
     for (int i = 0; i < vertices.length; i++) {
       vertices[i] = i;
       _edges[i] = <int>[];
diff --git a/pkg/analyzer/lib/src/summary2/named_type_builder.dart b/pkg/analyzer/lib/src/summary2/named_type_builder.dart
index a00dfb8..d67f186 100644
--- a/pkg/analyzer/lib/src/summary2/named_type_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/named_type_builder.dart
@@ -182,7 +182,7 @@
       return const <DartType>[];
     } else if (arguments.isNotEmpty) {
       if (arguments.length == parameters.length) {
-        var result = List<DartType>(parameters.length);
+        var result = List<DartType>.filled(parameters.length, null);
         for (int i = 0; i < result.length; ++i) {
           var type = arguments[i];
           result[i] = _buildType(type);
@@ -192,7 +192,7 @@
         return _listOfDynamic(parameters.length);
       }
     } else {
-      var result = List<DartType>(parameters.length);
+      var result = List<DartType>.filled(parameters.length, null);
       for (int i = 0; i < result.length; ++i) {
         TypeParameterElementImpl parameter = parameters[i];
         var defaultType = parameter.defaultType;
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
index cd29202..5007cde 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
@@ -253,7 +253,7 @@
 
 class ArgumentError extends Error {
   ArgumentError([message]);
-  
+
   static T checkNotNull<T>(T argument, [String, name]) => argument;
 }
 
diff --git a/pkg/analyzer/test/dart/ast/ast_test.dart b/pkg/analyzer/test/dart/ast/ast_test.dart
index 635d7ff..ba3b7ed 100644
--- a/pkg/analyzer/test/dart/ast/ast_test.dart
+++ b/pkg/analyzer/test/dart/ast/ast_test.dart
@@ -1693,7 +1693,8 @@
     VariableDeclaration varDecl = AstTestFactory.variableDeclaration("a");
     TopLevelVariableDeclaration decl =
         AstTestFactory.topLevelVariableDeclaration2(Keyword.VAR, [varDecl]);
-    Comment comment = astFactory.documentationComment(List<Token>(0));
+    Comment comment =
+        astFactory.documentationComment(List<Token>.filled(0, null));
     expect(varDecl.documentationComment, isNull);
     decl.documentationComment = comment;
     expect(varDecl.documentationComment, isNotNull);
@@ -1702,7 +1703,8 @@
 
   void test_getDocumentationComment_onNode() {
     VariableDeclaration decl = AstTestFactory.variableDeclaration("a");
-    Comment comment = astFactory.documentationComment(List<Token>(0));
+    Comment comment =
+        astFactory.documentationComment(List<Token>.filled(0, null));
     decl.documentationComment = comment;
     expect(decl.documentationComment, isNotNull);
   }
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index 95d7b3e..8bfa672 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -2045,7 +2045,7 @@
   List<E> m();
 }
 class B extends A<dynamic> {
-  List<dynamic> m() { return new List<dynamic>(); }
+  List<dynamic> m() { return <dynamic>[]; }
 }
 ''');
   }
diff --git a/pkg/analyzer/test/generated/non_hint_code_test.dart b/pkg/analyzer/test/generated/non_hint_code_test.dart
index bd32129..e283dd5 100644
--- a/pkg/analyzer/test/generated/non_hint_code_test.dart
+++ b/pkg/analyzer/test/generated/non_hint_code_test.dart
@@ -67,7 +67,7 @@
     await assertNoErrorsInCode(r'''
 class A { }
 class X<T> {
-  final x = new List<T>();
+  final x = <T>[];
 }
 class Z {
   final X<A> y = new X<A>();
diff --git a/pkg/analyzer/test/generated/utilities_test.dart b/pkg/analyzer/test/generated/utilities_test.dart
index 1bb1df6..9bf5576b 100644
--- a/pkg/analyzer/test/generated/utilities_test.dart
+++ b/pkg/analyzer/test/generated/utilities_test.dart
@@ -3808,7 +3808,7 @@
 
   void test_printListOfQuotedNames_empty() {
     expect(() {
-      StringUtilities.printListOfQuotedNames(List<String>(0));
+      StringUtilities.printListOfQuotedNames(List<String>.filled(0, null));
     }, throwsArgumentError);
   }
 
diff --git a/pkg/analyzer/test/src/dart/analysis/byte_store_test.dart b/pkg/analyzer/test/src/dart/analysis/byte_store_test.dart
index 38435ac..42bc17b 100644
--- a/pkg/analyzer/test/src/dart/analysis/byte_store_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/byte_store_test.dart
@@ -14,7 +14,7 @@
 }
 
 List<int> _b(int length) {
-  return List<int>(length);
+  return List<int>.filled(length, null);
 }
 
 @reflectiveTest
diff --git a/pkg/analyzer/test/src/dart/analysis/cache_test.dart b/pkg/analyzer/test/src/dart/analysis/cache_test.dart
index 67ec341..b966f63 100644
--- a/pkg/analyzer/test/src/dart/analysis/cache_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/cache_test.dart
@@ -13,7 +13,7 @@
 }
 
 List<int> _b(int length) {
-  return List<int>(length);
+  return List<int>.filled(length, null);
 }
 
 @reflectiveTest
diff --git a/pkg/analyzer/test/src/dart/analysis/unlinked_api_signature_test.dart b/pkg/analyzer/test/src/dart/analysis/unlinked_api_signature_test.dart
index 612a392..83e8192 100644
--- a/pkg/analyzer/test/src/dart/analysis/unlinked_api_signature_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/unlinked_api_signature_test.dart
@@ -192,6 +192,46 @@
 ''');
   }
 
+  test_class_constructor_redirectedConstructor_const() {
+    assertNotSameSignature(r'''
+class A {
+  const factory A() = B.foo;
+}
+class B implements A {
+  const B.foo();
+  const B.bar();
+}
+''', r'''
+class A {
+  const factory A() = B.bar;
+}
+class B implements A {
+  const B.foo();
+  const B.bar();
+}
+''');
+  }
+
+  test_class_constructor_redirectedConstructor_notConst() {
+    assertNotSameSignature(r'''
+class A {
+  factory A() = B.foo;
+}
+class B implements A {
+  B.foo();
+  B.bar();
+}
+''', r'''
+class A {
+  factory A() = B.bar;
+}
+class B implements A {
+  B.foo();
+  B.bar();
+}
+''');
+  }
+
   test_class_extends() {
     assertNotSameSignature(r'''
 class A {}
diff --git a/pkg/analyzer/test/src/diagnostics/private_optional_parameter_test.dart b/pkg/analyzer/test/src/diagnostics/private_optional_parameter_test.dart
index c8b9dbc..1fa9c76 100644
--- a/pkg/analyzer/test/src/diagnostics/private_optional_parameter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/private_optional_parameter_test.dart
@@ -23,7 +23,7 @@
 }
 ''', [
       error(HintCode.UNUSED_FIELD, 16, 2),
-      error(CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, 25, 7),
+      error(CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, 30, 2),
     ]);
   }
 
@@ -31,7 +31,7 @@
     await assertErrorsInCode('''
 f({var _p}) {}
 ''', [
-      error(CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, 3, 6),
+      error(CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, 7, 2),
     ]);
   }
 
diff --git a/pkg/analyzer/tool/messages/generate.dart b/pkg/analyzer/tool/messages/generate.dart
index e845177..fb3bfe7 100644
--- a/pkg/analyzer/tool/messages/generate.dart
+++ b/pkg/analyzer/tool/messages/generate.dart
@@ -187,7 +187,7 @@
   }
 
   void generateFastaAnalyzerErrorCodeList() {
-    final sorted = List<Map>(translatedEntries.length);
+    final sorted = List<Map>.filled(translatedEntries.length, null);
     for (var entry in translatedEntries) {
       var index = entry['index'];
       if (index is int && index >= 1 && index <= sorted.length) {
diff --git a/pkg/analyzer/tool/summary/mini_ast.dart b/pkg/analyzer/tool/summary/mini_ast.dart
index c8d5635..1993ae8 100644
--- a/pkg/analyzer/tool/summary/mini_ast.dart
+++ b/pkg/analyzer/tool/summary/mini_ast.dart
@@ -478,7 +478,7 @@
       int count, Token leftBracket, Token constKeyword, Token rightBracket) {
     debugEvent("LiteralList");
 
-    var elements = List<Object>(count);
+    var elements = List<Object>.filled(count, null);
     popList(count, elements);
     pop(); // type arguments
 
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index 60c4e1c..76191aa 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -117,7 +117,7 @@
   List<Uri> multiRoots;
   String multiRootScheme = 'org-dartlang-app';
   Uri packageConfig = null;
-  List<String> options = new List<String>();
+  List<String> options = <String>[];
   bool wantHelp = false;
   bool wantVersion = false;
   bool trustTypeAnnotations = false;
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index bc001f7..3e82de2 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -442,7 +442,7 @@
   void reportInlined(FunctionEntity element, MemberEntity inlinedFrom) {
     inlineCount.putIfAbsent(element, () => 0);
     inlineCount[element] += 1;
-    inlineMap.putIfAbsent(inlinedFrom, () => new List<Entity>());
+    inlineMap.putIfAbsent(inlinedFrom, () => <Entity>[]);
     inlineMap[inlinedFrom].add(element);
   }
 
@@ -486,9 +486,7 @@
   void registerEntityAst(Entity entity, jsAst.Node code,
       {LibraryEntity library}) {
     if (compiler.options.dumpInfo) {
-      _entityToNodes
-          .putIfAbsent(entity, () => new List<jsAst.Node>())
-          .add(code);
+      _entityToNodes.putIfAbsent(entity, () => <jsAst.Node>[]).add(code);
       _nodeData[code] ??= useBinaryFormat ? new CodeSpan() : new _CodeData();
     }
   }
diff --git a/pkg/compiler/lib/src/elements/types.dart b/pkg/compiler/lib/src/elements/types.dart
index 7cb8bc2..8a660e2 100644
--- a/pkg/compiler/lib/src/elements/types.dart
+++ b/pkg/compiler/lib/src/elements/types.dart
@@ -28,7 +28,7 @@
   List<DartType> _readDartTypes(
       List<FunctionTypeVariable> functionTypeVariables) {
     int count = readInt();
-    List<DartType> types = List<DartType>(count);
+    List<DartType> types = List<DartType>.filled(count, null);
     for (int index = 0; index < count; index++) {
       types[index] = DartType.readFromDataSource(this, functionTypeVariables);
     }
@@ -717,7 +717,8 @@
         source._readDartTypes(functionTypeVariables);
     List<DartType> namedParameterTypes =
         source._readDartTypes(functionTypeVariables);
-    List<String> namedParameters = List<String>(namedParameterTypes.length);
+    List<String> namedParameters =
+        List<String>.filled(namedParameterTypes.length, null);
     var requiredNamedParameters = <String>{};
     for (int i = 0; i < namedParameters.length; i++) {
       namedParameters[i] = source.readString();
@@ -1036,7 +1037,7 @@
     var length = oldTypeVariables.length;
 
     List<FunctionTypeVariable> typeVariables =
-        List<FunctionTypeVariable>(length);
+        List<FunctionTypeVariable>.filled(length, null);
     List<FunctionTypeVariable> erasableTypeVariables = [];
     List<FunctionTypeVariable> erasedTypeVariables = [];
     for (int i = 0; i < length; i++) {
diff --git a/pkg/compiler/lib/src/helpers/expensive_map.dart b/pkg/compiler/lib/src/helpers/expensive_map.dart
index 149e811..91098f5 100644
--- a/pkg/compiler/lib/src/helpers/expensive_map.dart
+++ b/pkg/compiler/lib/src/helpers/expensive_map.dart
@@ -10,7 +10,7 @@
 class ExpensiveMap<K, V> extends MapBase<K, V> {
   final List _maps;
 
-  ExpensiveMap([int copies = 10]) : _maps = new List(copies) {
+  ExpensiveMap([int copies = 10]) : _maps = new List.filled(copies, null) {
     assert(copies > 0);
     for (int i = 0; i < _maps.length; i++) {
       _maps[i] = new Map<K, V>();
diff --git a/pkg/compiler/lib/src/helpers/expensive_set.dart b/pkg/compiler/lib/src/helpers/expensive_set.dart
index 4c5101e..cc41f8b 100644
--- a/pkg/compiler/lib/src/helpers/expensive_set.dart
+++ b/pkg/compiler/lib/src/helpers/expensive_set.dart
@@ -10,7 +10,7 @@
 class ExpensiveSet<E> extends SetBase<E> {
   final List _sets;
 
-  ExpensiveSet([int copies = 10]) : _sets = new List(copies) {
+  ExpensiveSet([int copies = 10]) : _sets = new List.filled(copies, null) {
     assert(copies > 0);
     for (int i = 0; i < _sets.length; i++) {
       _sets[i] = new Set<E>();
diff --git a/pkg/compiler/lib/src/inferrer/builder_kernel.dart b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
index 55d7ab6..fdfd67e 100644
--- a/pkg/compiler/lib/src/inferrer/builder_kernel.dart
+++ b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
@@ -1243,15 +1243,15 @@
     var commonElements = _elementMap.commonElements;
 
     if (commonElements.isUnnamedListConstructor(constructor)) {
-      // We have `new List(...)`.
+      // We have `new List.filled(..., null)`.
       if (arguments.positional.isEmpty && arguments.named.isEmpty) {
-        // We have `new List()`.
+        // We have `[]`.
         return _inferrer.concreteTypes.putIfAbsent(
             node,
             () => _types.allocateList(_types.growableListType, node,
                 _analyzedMember, _types.nonNullEmpty(), 0));
       } else {
-        // We have `new List(len)`.
+        // We have `new List.filled(len, null)`.
         int length = _findLength(arguments);
         return _inferrer.concreteTypes.putIfAbsent(
             node,
diff --git a/pkg/compiler/lib/src/inferrer/closure_tracer.dart b/pkg/compiler/lib/src/inferrer/closure_tracer.dart
index 809b850..18eb0ca 100644
--- a/pkg/compiler/lib/src/inferrer/closure_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/closure_tracer.dart
@@ -15,7 +15,7 @@
 class ClosureTracerVisitor extends TracerVisitor {
   final Iterable<FunctionEntity> tracedElements;
   final List<CallSiteTypeInformation> _callsToAnalyze =
-      new List<CallSiteTypeInformation>();
+      <CallSiteTypeInformation>[];
 
   ClosureTracerVisitor(this.tracedElements, ApplyableTypeInformation tracedType,
       InferrerEngine inferrer)
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_dump.dart b/pkg/compiler/lib/src/inferrer/type_graph_dump.dart
index c215ca1..ac9c901 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_dump.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_dump.dart
@@ -136,7 +136,7 @@
 class _GraphGenerator extends TypeInformationVisitor {
   final TypeGraphDump global;
   final Set<TypeInformation> seen = new Set<TypeInformation>();
-  final List<TypeInformation> worklist = new List<TypeInformation>();
+  final List<TypeInformation> worklist = <TypeInformation>[];
   final Map<TypeInformation, int> nodeId = <TypeInformation, int>{};
   final String Function(AbstractValue) formatType;
   int usedIds = 0;
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
index 78664eb..f791743 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
@@ -115,7 +115,8 @@
 
   // The below is not a compile time constant to make it differentiable
   // from other empty lists of [TypeInformation].
-  static final STOP_TRACKING_INPUTS_MARKER = new List<TypeInformation>(0);
+  static final STOP_TRACKING_INPUTS_MARKER =
+      new List<TypeInformation>.filled(0, null);
 
   bool areInputsTracked() {
     return inputs != STOP_TRACKING_INPUTS_MARKER;
diff --git a/pkg/compiler/lib/src/io/source_map_builder.dart b/pkg/compiler/lib/src/io/source_map_builder.dart
index 654c87b..a630dd5 100644
--- a/pkg/compiler/lib/src/io/source_map_builder.dart
+++ b/pkg/compiler/lib/src/io/source_map_builder.dart
@@ -22,7 +22,7 @@
   final Uri targetFileUri;
 
   final LocationProvider locationProvider;
-  final List<SourceMapEntry> entries = new List<SourceMapEntry>();
+  final List<SourceMapEntry> entries = <SourceMapEntry>[];
 
   /// Extension used to deobfuscate minified names in error messages.
   final Map<String, String> minifiedGlobalNames;
diff --git a/pkg/compiler/lib/src/ir/static_type.dart b/pkg/compiler/lib/src/ir/static_type.dart
index 49f5eb2..9527cd2 100644
--- a/pkg/compiler/lib/src/ir/static_type.dart
+++ b/pkg/compiler/lib/src/ir/static_type.dart
@@ -644,7 +644,8 @@
     if (arguments.positional.isEmpty) {
       positional = const <ir.DartType>[];
     } else {
-      positional = new List<ir.DartType>(arguments.positional.length);
+      positional =
+          new List<ir.DartType>.filled(arguments.positional.length, null);
       int index = 0;
       for (ir.Expression argument in arguments.positional) {
         positional[index++] = visitNode(argument);
@@ -653,7 +654,7 @@
     if (arguments.named.isEmpty) {
       named = const <ir.DartType>[];
     } else {
-      named = new List<ir.DartType>(arguments.named.length);
+      named = new List<ir.DartType>.filled(arguments.named.length, null);
       int index = 0;
       for (ir.NamedExpression argument in arguments.named) {
         named[index++] = visitNode(argument);
diff --git a/pkg/compiler/lib/src/js/rewrite_async.dart b/pkg/compiler/lib/src/js/rewrite_async.dart
index 60e8c84..53e156a 100644
--- a/pkg/compiler/lib/src/js/rewrite_async.dart
+++ b/pkg/compiler/lib/src/js/rewrite_async.dart
@@ -1400,7 +1400,7 @@
     breakLabels[node] = after;
 
     beginLabel(before);
-    List<int> labels = new List<int>(node.cases.length);
+    List<int> labels = new List<int>.filled(node.cases.length, null);
 
     bool anyCaseExpressionTransformed = node.cases.any(
         (js.SwitchClause x) => x is js.Case && shouldTransform(x.expression));
diff --git a/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart b/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart
index a0fb0b3..3954c4c 100644
--- a/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart
+++ b/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart
@@ -48,7 +48,7 @@
 
   int globalCount = 0;
 
-  final List<jsAst.Name> nameStore = new List<jsAst.Name>();
+  final List<jsAst.Name> nameStore = <jsAst.Name>[];
 
   _FieldNamingRegistry(this.namer);
 
diff --git a/pkg/compiler/lib/src/js_backend/frequency_namer.dart b/pkg/compiler/lib/src/js_backend/frequency_namer.dart
index f929e7a..9d0eb71 100644
--- a/pkg/compiler/lib/src/js_backend/frequency_namer.dart
+++ b/pkg/compiler/lib/src/js_backend/frequency_namer.dart
@@ -9,7 +9,7 @@
     implements jsAst.TokenFinalizer {
   @override
   _FieldNamingRegistry fieldRegistry;
-  List<TokenName> tokens = new List<TokenName>();
+  List<TokenName> tokens = <TokenName>[];
 
   Map<NamingScope, TokenScope> _tokenScopes =
       new Maplet<NamingScope, TokenScope>();
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index c8084d5..2998012 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -994,7 +994,7 @@
   /// For instance `A` in:
   ///
   ///     class A {}
-  ///     main() => new List<A>() is List<String>;
+  ///     main() => <A>[] is List<String>;
   ///
   bool typeArgument = false;
 
@@ -1003,7 +1003,7 @@
   /// For instance `A` in:
   ///
   ///     class A {}
-  ///     main() => new List<String>() is List<A>;
+  ///     main() => <String>[] is List<A>;
   ///
   bool checkedTypeArgument = false;
 
diff --git a/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
index 1016f9a..cef6e37 100644
--- a/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
@@ -112,15 +112,17 @@
     String receiverArgumentName = r'$receiver';
 
     // The parameters that this stub takes.
-    List<jsAst.Parameter> stubParameters = new List<jsAst.Parameter>(
+    List<jsAst.Parameter> stubParameters = new List<jsAst.Parameter>.filled(
         extraArgumentCount +
             selector.argumentCount +
-            selector.typeArgumentCount);
+            selector.typeArgumentCount,
+        null);
     // The arguments that will be passed to the real method.
-    List<jsAst.Expression> targetArguments = new List<jsAst.Expression>(
+    List<jsAst.Expression> targetArguments = new List<jsAst.Expression>.filled(
         extraArgumentCount +
             parameterStructure.totalParameters +
-            parameterStructure.typeParameters);
+            parameterStructure.typeParameters,
+        null);
 
     int count = 0;
     if (isInterceptedMethod) {
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
index 0d0b438..351d6bc 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
@@ -250,7 +250,8 @@
     Iterable<Fragment> deferredFragments =
         _registry.deferredLibrariesMap.map(_buildDeferredFragment);
 
-    List<Fragment> fragments = new List<Fragment>(_registry.librariesMapCount);
+    List<Fragment> fragments =
+        new List<Fragment>.filled(_registry.librariesMapCount, null);
     fragments[0] = mainFragment;
     fragments.setAll(1, deferredFragments);
 
@@ -480,7 +481,8 @@
   }
 
   List<Library> _buildLibraries(LibrariesMap librariesMap) {
-    List<Library> libraries = new List<Library>(librariesMap.length);
+    List<Library> libraries =
+        new List<Library>.filled(librariesMap.length, null);
     int count = 0;
     librariesMap.forEach((LibraryEntity library, List<ClassEntity> classes,
         List<MemberEntity> members, List<ClassEntity> classTypeElements) {
diff --git a/pkg/compiler/lib/src/ordered_typeset.dart b/pkg/compiler/lib/src/ordered_typeset.dart
index dcbcf37..8be4970 100644
--- a/pkg/compiler/lib/src/ordered_typeset.dart
+++ b/pkg/compiler/lib/src/ordered_typeset.dart
@@ -55,7 +55,7 @@
 
     int levelCount = source.readInt();
     List<Link<InterfaceType>> levels =
-        new List<Link<InterfaceType>>(levelCount);
+        new List<Link<InterfaceType>>.filled(levelCount, null);
     for (int i = 0; i < levelCount; i++) {
       levels[i] = links[source.readInt()];
     }
@@ -90,7 +90,8 @@
   factory OrderedTypeSet.singleton(InterfaceType type) {
     Link<InterfaceType> types =
         new LinkEntry<InterfaceType>(type, const Link<InterfaceType>());
-    List<Link<InterfaceType>> list = new List<Link<InterfaceType>>(1);
+    List<Link<InterfaceType>> list =
+        new List<Link<InterfaceType>>.filled(1, null);
     list[0] = types;
     return new OrderedTypeSet.internal(list, types);
   }
@@ -107,7 +108,8 @@
             'OrderedTypeSet.extendClass'));
     Link<InterfaceType> extendedTypes =
         new LinkEntry<InterfaceType>(type, types);
-    List<Link<InterfaceType>> list = new List<Link<InterfaceType>>(levels + 1);
+    List<Link<InterfaceType>> list =
+        new List<Link<InterfaceType>>.filled(levels + 1, null);
     for (int i = 0; i < levels; i++) {
       list[i] = _levels[i];
     }
@@ -257,7 +259,7 @@
 
   OrderedTypeSet toTypeSet() {
     List<Link<InterfaceType>> levels =
-        new List<Link<InterfaceType>>(maxDepth + 1);
+        new List<Link<InterfaceType>>.filled(maxDepth + 1, null);
     if (maxDepth < 0) {
       return new OrderedTypeSet.internal(levels, const Link<InterfaceType>());
     }
diff --git a/pkg/compiler/lib/src/serialization/abstract_source.dart b/pkg/compiler/lib/src/serialization/abstract_source.dart
index b3ad306..c1e8ea1 100644
--- a/pkg/compiler/lib/src/serialization/abstract_source.dart
+++ b/pkg/compiler/lib/src/serialization/abstract_source.dart
@@ -143,7 +143,7 @@
   List<ir.DartType> _readDartTypeNodes(
       List<ir.TypeParameter> functionTypeVariables) {
     int count = readInt();
-    List<ir.DartType> types = new List<ir.DartType>(count);
+    List<ir.DartType> types = new List<ir.DartType>.filled(count, null);
     for (int index = 0; index < count; index++) {
       types[index] = _readDartTypeNode(functionTypeVariables);
     }
@@ -229,7 +229,7 @@
             _readDartTypeNodes(functionTypeVariables);
         int namedParameterCount = readInt();
         List<ir.NamedType> namedParameters =
-            new List<ir.NamedType>(namedParameterCount);
+            new List<ir.NamedType>.filled(namedParameterCount, null);
         for (int index = 0; index < namedParameterCount; index++) {
           String name = readString();
           bool isRequired = readBool();
@@ -427,7 +427,7 @@
       {bool emptyAsNull: false}) {
     int count = readInt();
     if (count == 0 && emptyAsNull) return null;
-    List<E> list = new List<E>(count);
+    List<E> list = new List<E>.filled(count, null);
     for (int i = 0; i < count; i++) {
       ir.TreeNode node = readTreeNodeInContextInternal(currentMemberData);
       list[i] = node;
diff --git a/pkg/compiler/lib/src/serialization/mixins.dart b/pkg/compiler/lib/src/serialization/mixins.dart
index 3718e25..d7d5d87 100644
--- a/pkg/compiler/lib/src/serialization/mixins.dart
+++ b/pkg/compiler/lib/src/serialization/mixins.dart
@@ -19,7 +19,7 @@
   List<E> readList<E>(E f(), {bool emptyAsNull: false}) {
     int count = readInt();
     if (count == 0 && emptyAsNull) return null;
-    List<E> list = new List<E>(count);
+    List<E> list = new List<E>.filled(count, null);
     for (int i = 0; i < count; i++) {
       list[i] = f();
     }
@@ -48,7 +48,7 @@
   List<String> readStrings({bool emptyAsNull: false}) {
     int count = readInt();
     if (count == 0 && emptyAsNull) return null;
-    List<String> list = new List<String>(count);
+    List<String> list = new List<String>.filled(count, null);
     for (int i = 0; i < count; i++) {
       list[i] = readString();
     }
@@ -59,7 +59,7 @@
   List<DartType> readDartTypes({bool emptyAsNull: false}) {
     int count = readInt();
     if (count == 0 && emptyAsNull) return null;
-    List<DartType> list = new List<DartType>(count);
+    List<DartType> list = new List<DartType>.filled(count, null);
     for (int i = 0; i < count; i++) {
       list[i] = readDartType();
     }
@@ -70,7 +70,8 @@
   List<ir.TypeParameter> readTypeParameterNodes({bool emptyAsNull: false}) {
     int count = readInt();
     if (count == 0 && emptyAsNull) return null;
-    List<ir.TypeParameter> list = new List<ir.TypeParameter>(count);
+    List<ir.TypeParameter> list =
+        new List<ir.TypeParameter>.filled(count, null);
     for (int i = 0; i < count; i++) {
       list[i] = readTypeParameterNode();
     }
@@ -81,7 +82,7 @@
   List<E> readMembers<E extends MemberEntity>({bool emptyAsNull: false}) {
     int count = readInt();
     if (count == 0 && emptyAsNull) return null;
-    List<E> list = new List<E>(count);
+    List<E> list = new List<E>.filled(count, null);
     for (int i = 0; i < count; i++) {
       MemberEntity member = readMember();
       list[i] = member;
@@ -93,7 +94,7 @@
   List<E> readMemberNodes<E extends ir.Member>({bool emptyAsNull: false}) {
     int count = readInt();
     if (count == 0 && emptyAsNull) return null;
-    List<E> list = new List<E>(count);
+    List<E> list = new List<E>.filled(count, null);
     for (int i = 0; i < count; i++) {
       ir.Member value = readMemberNode();
       list[i] = value;
@@ -105,7 +106,7 @@
   List<E> readClasses<E extends ClassEntity>({bool emptyAsNull: false}) {
     int count = readInt();
     if (count == 0 && emptyAsNull) return null;
-    List<E> list = new List<E>(count);
+    List<E> list = new List<E>.filled(count, null);
     for (int i = 0; i < count; i++) {
       ClassEntity cls = readClass();
       list[i] = cls;
@@ -187,7 +188,7 @@
   List<E> readLocals<E extends Local>({bool emptyAsNull: false}) {
     int count = readInt();
     if (count == 0 && emptyAsNull) return null;
-    List<E> list = new List<E>(count);
+    List<E> list = new List<E>.filled(count, null);
     for (int i = 0; i < count; i++) {
       Local local = readLocal();
       list[i] = local;
@@ -212,7 +213,7 @@
   List<E> readTreeNodes<E extends ir.TreeNode>({bool emptyAsNull: false}) {
     int count = readInt();
     if (count == 0 && emptyAsNull) return null;
-    List<E> list = new List<E>(count);
+    List<E> list = new List<E>.filled(count, null);
     for (int i = 0; i < count; i++) {
       ir.TreeNode node = readTreeNode();
       list[i] = node;
@@ -282,7 +283,7 @@
   List<E> readConstants<E extends ConstantValue>({bool emptyAsNull: false}) {
     int count = readInt();
     if (count == 0 && emptyAsNull) return null;
-    List<E> list = new List<E>(count);
+    List<E> list = new List<E>.filled(count, null);
     for (int i = 0; i < count; i++) {
       ConstantValue value = readConstant();
       list[i] = value;
@@ -326,7 +327,7 @@
   List<ImportEntity> readImports({bool emptyAsNull: false}) {
     int count = readInt();
     if (count == 0 && emptyAsNull) return null;
-    List<ImportEntity> list = new List<ImportEntity>(count);
+    List<ImportEntity> list = new List<ImportEntity>.filled(count, null);
     for (int i = 0; i < count; i++) {
       list[i] = readImport();
     }
@@ -350,7 +351,7 @@
   List<ir.DartType> readDartTypeNodes({bool emptyAsNull: false}) {
     int count = readInt();
     if (count == 0 && emptyAsNull) return null;
-    List<ir.DartType> list = new List<ir.DartType>(count);
+    List<ir.DartType> list = new List<ir.DartType>.filled(count, null);
     for (int i = 0; i < count; i++) {
       list[i] = readDartTypeNode();
     }
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index e1c0789..e81ca79 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -3816,12 +3816,12 @@
       return;
     }
 
-    // Recognize `List()` and `List(n)`.
+    // Recognize `[]` and `List.filled(n, null)`.
     if (_commonElements.isUnnamedListConstructor(function)) {
       if (invocation.arguments.named.isEmpty) {
         int argumentCount = invocation.arguments.positional.length;
         if (argumentCount == 0) {
-          // `List()` takes no arguments, `JSArray.list()` takes a sentinel.
+          // `[]` takes no arguments, `JSArray.list()` takes a sentinel.
           assert(arguments.length == 0 || arguments.length == 1,
               '\narguments: $arguments\n');
           _handleInvokeLegacyGrowableListFactoryConstructor(
@@ -3936,14 +3936,14 @@
     stack.add(_setListRuntimeTypeInfoIfNeeded(pop(), type, sourceInformation));
   }
 
-  /// Handle the legacy `List<T>()` constructor.
+  /// Handle the legacy `<T>[]` constructor.
   void _handleInvokeLegacyGrowableListFactoryConstructor(
       ir.StaticInvocation invocation,
       ConstructorEntity function,
       AbstractValue typeMask,
       List<HInstruction> arguments,
       SourceInformation sourceInformation) {
-    // `List<T>()` is essentially the same as `<T>[]`.
+    // `<T>[]` is essentially the same as `<T>[]`.
     push(_buildLiteralList(<HInstruction>[]));
     HInstruction allocation = pop();
     var inferredType = globalInferenceResults.typeOfNewList(invocation);
@@ -3956,7 +3956,7 @@
         _setListRuntimeTypeInfoIfNeeded(allocation, type, sourceInformation));
   }
 
-  /// Handle the `JSArray<T>.list(length)` and legacy `List<T>(length)`
+  /// Handle the `JSArray<T>.list(length)` and legacy `List<T>.filled(length, null)`
   /// constructors.
   void _handleInvokeLegacyFixedListFactoryConstructor(
       ir.StaticInvocation invocation,
@@ -5215,7 +5215,7 @@
     var argumentsInstruction = _buildLiteralList(arguments);
     add(argumentsInstruction);
 
-    var argumentNames = new List<HInstruction>();
+    var argumentNames = <HInstruction>[];
     for (String argumentName in selector.namedArguments) {
       ConstantValue argumentNameConstant =
           constant_system.createString(argumentName);
@@ -5865,10 +5865,11 @@
     ParameterStructure parameterStructure = function.parameterStructure;
     List<String> selectorArgumentNames =
         selector.callStructure.getOrderedNamedArguments();
-    List<HInstruction> compiledArguments = new List<HInstruction>(
+    List<HInstruction> compiledArguments = new List<HInstruction>.filled(
         parameterStructure.totalParameters +
             parameterStructure.typeParameters +
-            1); // Plus one for receiver.
+            1,
+        null); // Plus one for receiver.
 
     int compiledArgumentIndex = 0;
 
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index 7c50116..098531f 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -642,7 +642,7 @@
   List<js.Expression> visitArguments(List<HInstruction> inputs,
       {int start: HInvoke.ARGUMENTS_OFFSET}) {
     assert(inputs.length >= start);
-    List<js.Expression> result = new List<js.Expression>(inputs.length - start);
+    List<js.Expression> result = new List<js.Expression>.filled(inputs.length - start, null);
     for (int i = start; i < inputs.length; i++) {
       use(inputs[i]);
       result[i - start] = pop();
diff --git a/pkg/compiler/lib/src/ssa/codegen_helpers.dart b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
index 6aa5a3c..cb8a95e 100644
--- a/pkg/compiler/lib/src/ssa/codegen_helpers.dart
+++ b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
@@ -886,7 +886,7 @@
 
     // The expectedInputs list holds non-trivial instructions that may
     // be generated at their use site, if they occur in the correct order.
-    if (expectedInputs == null) expectedInputs = new List<HInstruction>();
+    if (expectedInputs == null) expectedInputs = <HInstruction>[];
     if (pureInputs == null) pureInputs = new Set<HInstruction>();
 
     // Pop instructions from expectedInputs until instruction is found.
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index 115e891..25b48a8 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -3789,8 +3789,8 @@
   HLoopBlockInformation loopBlockInformation;
 
   HLoopInformation(this.header, this.target, this.labels)
-      : blocks = new List<HBasicBlock>(),
-        backEdges = new List<HBasicBlock>();
+      : blocks = <HBasicBlock>[],
+        backEdges = <HBasicBlock>[];
 
   void addBackEdge(HBasicBlock predecessor) {
     backEdges.add(predecessor);
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index 5ea6c69..b855b90 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -2964,8 +2964,8 @@
     // loop changes flags list to zero so we can use bitwise or when
     // propagating loop changes upwards.
     final int length = graph.blocks.length;
-    blockChangesFlags = new List<int>(length);
-    loopChangesFlags = new List<int>(length);
+    blockChangesFlags = new List<int>.filled(length, null);
+    loopChangesFlags = new List<int>.filled(length, null);
     for (int i = 0; i < length; i++) loopChangesFlags[i] = 0;
 
     // Run through all the basic blocks in the graph and fill in the
@@ -3046,7 +3046,7 @@
 
   @override
   void visitGraph(HGraph graph) {
-    values = new List<ValueSet>(graph.blocks.length);
+    values = new List<ValueSet>.filled(graph.blocks.length, null);
     for (int i = 0; i < graph.blocks.length; i++) {
       values[graph.blocks[i].id] = new ValueSet();
     }
@@ -3315,7 +3315,7 @@
   @override
   void visitGraph(HGraph graph) {
     _graph = graph;
-    memories = new List<MemorySet>(graph.blocks.length);
+    memories = new List<MemorySet>.filled(graph.blocks.length, null);
     List<HBasicBlock> blocks = graph.blocks;
     for (int i = 0; i < blocks.length; i++) {
       HBasicBlock block = blocks[i];
diff --git a/pkg/compiler/lib/src/ssa/types_propagation.dart b/pkg/compiler/lib/src/ssa/types_propagation.dart
index 12fabcf..a5a1581 100644
--- a/pkg/compiler/lib/src/ssa/types_propagation.dart
+++ b/pkg/compiler/lib/src/ssa/types_propagation.dart
@@ -31,7 +31,7 @@
 // targeted conditioning checks.
 class SsaTypePropagator extends HBaseVisitor implements OptimizationPhase {
   final Map<int, HInstruction> workmap = new Map<int, HInstruction>();
-  final List<int> worklist = new List<int>();
+  final List<int> worklist = <int>[];
   final Map<HInstruction, Function> pendingOptimizations =
       new Map<HInstruction, Function>();
 
diff --git a/pkg/compiler/lib/src/ssa/value_set.dart b/pkg/compiler/lib/src/ssa/value_set.dart
index b24a560..f2a6148 100644
--- a/pkg/compiler/lib/src/ssa/value_set.dart
+++ b/pkg/compiler/lib/src/ssa/value_set.dart
@@ -9,7 +9,7 @@
   int size = 0;
   List<HInstruction> table;
   ValueSetNode collisions;
-  ValueSet() : table = new List<HInstruction>(8);
+  ValueSet() : table = new List<HInstruction>.filled(8, null);
 
   bool get isEmpty => size == 0;
   int get length => size;
@@ -138,7 +138,7 @@
     // Reset the table with a bigger capacity.
     assert(capacity > table.length);
     size = 0;
-    table = new List<HInstruction>(capacity);
+    table = new List<HInstruction>.filled(capacity, null);
     collisions = null;
     // Add the old instructions to the new table.
     copyTo(this, oldTable, oldCollisions);
diff --git a/pkg/compiler/lib/src/ssa/variable_allocator.dart b/pkg/compiler/lib/src/ssa/variable_allocator.dart
index 338204e..c279758 100644
--- a/pkg/compiler/lib/src/ssa/variable_allocator.dart
+++ b/pkg/compiler/lib/src/ssa/variable_allocator.dart
@@ -59,7 +59,7 @@
 
   @override
   String toString() {
-    List<String> res = new List<String>();
+    List<String> res = <String>[];
     for (final interval in ranges) res.add(interval.toString());
     return '(${res.join(", ")})';
   }
@@ -376,8 +376,8 @@
   final List<Copy<HInstruction>> assignments;
 
   CopyHandler()
-      : copies = new List<Copy<HInstruction>>(),
-        assignments = new List<Copy<HInstruction>>();
+      : copies = <Copy<HInstruction>>[],
+        assignments = <Copy<HInstruction>>[];
 
   void addCopy(HInstruction source, HInstruction destination) {
     copies.add(new Copy<HInstruction>(source, destination));
@@ -458,7 +458,7 @@
 
   VariableNamer(LiveEnvironment environment, this.names, this._namer)
       : usedNames = new Set<String>(),
-        freeTemporaryNames = new List<String>() {
+        freeTemporaryNames = <String>[] {
     // [VariableNames.swapTemp] is used when there is a cycle in a copy handler.
     // Therefore we make sure no one uses it.
     usedNames.add(names.swapTemp);
diff --git a/pkg/compiler/lib/src/util/maplet.dart b/pkg/compiler/lib/src/util/maplet.dart
index 329853c..6c46fed 100644
--- a/pkg/compiler/lib/src/util/maplet.dart
+++ b/pkg/compiler/lib/src/util/maplet.dart
@@ -99,7 +99,7 @@
       } else if (_key == key) {
         _value = value;
       } else {
-        List list = new List(CAPACITY * 2);
+        List list = new List.filled(CAPACITY * 2, null);
         list[0] = _key;
         list[1] = key;
         list[CAPACITY] = _value;
diff --git a/pkg/compiler/lib/src/util/setlet.dart b/pkg/compiler/lib/src/util/setlet.dart
index e35c12b..a2870a4 100644
--- a/pkg/compiler/lib/src/util/setlet.dart
+++ b/pkg/compiler/lib/src/util/setlet.dart
@@ -91,7 +91,7 @@
         // Do nothing.
         return false;
       } else {
-        List list = new List(CAPACITY);
+        List list = new List.filled(CAPACITY, null);
         list[0] = _contents;
         list[1] = element;
         _contents = list;
diff --git a/pkg/compiler/lib/src/util/util.dart b/pkg/compiler/lib/src/util/util.dart
index 423c0b2..7b5e9fd 100644
--- a/pkg/compiler/lib/src/util/util.dart
+++ b/pkg/compiler/lib/src/util/util.dart
@@ -88,7 +88,7 @@
   /// [existing].
   static int unorderedMapHash(Map map, [int existing = 0]) {
     if (map.length == 0) return existing;
-    List<int> hashCodes = List(map.length);
+    List<int> hashCodes = List.filled(map.length, null);
     int i = 0;
     for (var entry in map.entries) {
       hashCodes[i++] = objectHash(entry.key, objectHash(entry.value));
diff --git a/pkg/dds/test/web/sse_smoke_driver.dart.js b/pkg/dds/test/web/sse_smoke_driver.dart.js
index 1fc9758..bab6993 100644
--- a/pkg/dds/test/web/sse_smoke_driver.dart.js
+++ b/pkg/dds/test/web/sse_smoke_driver.dart.js
@@ -4479,7 +4479,7 @@
     },
     Iterator: function Iterator() {
     },
-    List: function List() {
+    List: function [] {
     },
     Map: function Map() {
     },
diff --git a/pkg/dev_compiler/doc/GENERIC_METHOD_COMMENTS.md b/pkg/dev_compiler/doc/GENERIC_METHOD_COMMENTS.md
index 9050eab..8f23657 100644
--- a/pkg/dev_compiler/doc/GENERIC_METHOD_COMMENTS.md
+++ b/pkg/dev_compiler/doc/GENERIC_METHOD_COMMENTS.md
@@ -139,7 +139,7 @@
 
 ```dart
 List/*<T>*/ makeList/*<T extends num>*/() {
-  return new List<num /*=T*/>();
+  return <num /*=T*/>[];
 }
 
 void main() {
@@ -174,7 +174,7 @@
    var l0 = <dynamic /*=S*/>[x];
 
    // as above, but with a regular constructor.
-   var l1 = new List<dynamic /*=S*/>();
+   var l1 = <dynamic /*=S*/>[];
    return l1;
 }
 ```
diff --git a/pkg/dev_compiler/lib/src/compiler/module_containers.dart b/pkg/dev_compiler/lib/src/compiler/module_containers.dart
index 82f06b4..6c76688 100644
--- a/pkg/dev_compiler/lib/src/compiler/module_containers.dart
+++ b/pkg/dev_compiler/lib/src/compiler/module_containers.dart
@@ -227,7 +227,7 @@
   @override
   List<js_ast.Statement> emit() {
     if (moduleItems.isEmpty) return [];
-    var properties = List<js_ast.Expression>(length);
+    var properties = List<js_ast.Expression>.filled(length, null);
 
     // If the entire array holds just one value, generate a short initializer.
     var valueSet = <js_ast.Expression>{};
diff --git a/pkg/dev_compiler/lib/src/js_ast/builder.dart b/pkg/dev_compiler/lib/src/js_ast/builder.dart
index ed3c8e3..42a4511 100644
--- a/pkg/dev_compiler/lib/src/js_ast/builder.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/builder.dart
@@ -1676,7 +1676,7 @@
     Expression key = parseExpression();
     expectCategory(RPAREN);
     expectCategory(LBRACE);
-    var clauses = List<SwitchCase>();
+    var clauses = <SwitchCase>[];
     while (lastCategory != RBRACE) {
       clauses.add(parseSwitchClause());
     }
@@ -1701,7 +1701,7 @@
       heritage = parseConditional();
     }
     expectCategory(LBRACE);
-    var methods = List<Method>();
+    var methods = <Method>[];
     while (lastCategory != RBRACE) {
       methods.add(parseMethodOrProperty(onlyMethods: true) as Method);
     }
diff --git a/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt b/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt
index 7803de7..0336282 100644
--- a/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt
+++ b/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt
@@ -1,11 +1,11 @@
 ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|3679|5|94|Const constructors can't throw exceptions.
-ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|7881|5|97|Const constructors can't throw exceptions.
+ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|7878|5|97|Const constructors can't throw exceptions.
 ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|893|5|95|Const constructors can't throw exceptions.
 ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|926|5|94|Const constructors can't throw exceptions.
 ERROR|COMPILE_TIME_ERROR|INVALID_ASSIGNMENT|lib/_internal/js_dev_runtime/private/interceptors.dart|1358|18|27|A value of type 'double' can't be assigned to a variable of type 'int'.
 ERROR|COMPILE_TIME_ERROR|RETURN_OF_INVALID_TYPE|lib/_internal/js_dev_runtime/private/interceptors.dart|1225|14|38|A value of type 'double' can't be returned from method '%' because it has a return type of 'JSNumber'.
 ERROR|COMPILE_TIME_ERROR|RETURN_OF_INVALID_TYPE|lib/_internal/js_dev_runtime/private/interceptors.dart|1227|14|38|A value of type 'double' can't be returned from method '%' because it has a return type of 'JSNumber'.
 ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|3677|3|5|Only redirecting factory constructors can be declared to be 'const'.
-ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|7879|3|5|Only redirecting factory constructors can be declared to be 'const'.
+ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|7876|3|5|Only redirecting factory constructors can be declared to be 'const'.
 ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|891|3|5|Only redirecting factory constructors can be declared to be 'const'.
 ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|924|3|5|Only redirecting factory constructors can be declared to be 'const'.
diff --git a/pkg/front_end/README.md b/pkg/front_end/README.md
index 6c4e0ed..c7be0eb 100644
--- a/pkg/front_end/README.md
+++ b/pkg/front_end/README.md
@@ -6,13 +6,12 @@
 with the analyzer package--this will be accomplished by having the analyzer
 package import (and re-export) parts of this package's private implementation.
 
-End-users should use the [dartanalyzer][analyzercli] command-line tool to
-analyze their Dart code.
+End-users should use the [`dart analyze`](https://dart.dev/tools/dart-tool)
+command-line tool to analyze their Dart code.
 
 Integrators that want to write tools that analyze Dart code should use the
-[analyzer] package.
+[analyzer](https://pub.dev/packages/analyzer) package.
 
-_Note:_ The APIs in this package are in an early state; developers should be
-careful about depending on this package.  In particular, there is no semver
-contract for release versions of this package.  Please depend directly on individual
-versions.
+_Note:_ A previous version of this package was published on pub.dev. It has now
+been marked DISCONTINUED as it is not intended for direct consumption, as per
+the notes above.
diff --git a/pkg/front_end/lib/src/api_unstable/bazel_worker.dart b/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
index d4445e4..48df5c9 100644
--- a/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
+++ b/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
@@ -77,7 +77,7 @@
     bool verbose: false,
     NnbdMode nnbdMode: NnbdMode.Weak}) async {
   List<Component> outputLoadedAdditionalDills =
-      new List<Component>(additionalDills.length);
+      new List<Component>.filled(additionalDills.length, null);
   Map<ExperimentalFlag, bool> experimentalFlags = parseExperimentalFlags(
       parseExperimentalArguments(experiments),
       onError: (e) => throw e);
diff --git a/pkg/front_end/lib/src/api_unstable/modular_incremental_compilation.dart b/pkg/front_end/lib/src/api_unstable/modular_incremental_compilation.dart
index 691483d..eb80f97 100644
--- a/pkg/front_end/lib/src/api_unstable/modular_incremental_compilation.dart
+++ b/pkg/front_end/lib/src/api_unstable/modular_incremental_compilation.dart
@@ -156,7 +156,7 @@
       if (trackNeededDillLibraries) {
         libraryToInputDill = new Map<Uri, Uri>();
       }
-      List<int> loadFromDillIndexes = new List<int>();
+      List<int> loadFromDillIndexes = <int>[];
 
       // Notice that the ordering of the input summaries matter, so we need to
       // keep them in order.
diff --git a/pkg/front_end/lib/src/base/processed_options.dart b/pkg/front_end/lib/src/base/processed_options.dart
index 9ab9035..7414b1c 100644
--- a/pkg/front_end/lib/src/base/processed_options.dart
+++ b/pkg/front_end/lib/src/base/processed_options.dart
@@ -216,7 +216,8 @@
         command_line_reporting.format(message, severity, location: location);
     List<FormattedMessage> formattedContext;
     if (context != null && context.isNotEmpty) {
-      formattedContext = new List<FormattedMessage>(context.length);
+      formattedContext =
+          new List<FormattedMessage>.filled(context.length, null);
       for (int i = 0; i < context.length; i++) {
         formattedContext[i] = format(context[i], Severity.context, null);
       }
diff --git a/pkg/front_end/lib/src/fasta/builder/constructor_builder.dart b/pkg/front_end/lib/src/fasta/builder/constructor_builder.dart
index 2c0f031..03f46c7 100644
--- a/pkg/front_end/lib/src/fasta/builder/constructor_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/constructor_builder.dart
@@ -263,7 +263,7 @@
     FunctionNode functionNode = super.buildFunction(library);
     ClassBuilder enclosingClassBuilder = parent;
     Class enclosingClass = enclosingClassBuilder.cls;
-    List<DartType> typeParameterTypes = new List<DartType>();
+    List<DartType> typeParameterTypes = <DartType>[];
     for (int i = 0; i < enclosingClass.typeParameters.length; i++) {
       TypeParameter typeParameter = enclosingClass.typeParameters[i];
       typeParameterTypes.add(
diff --git a/pkg/front_end/lib/src/fasta/builder/function_builder.dart b/pkg/front_end/lib/src/fasta/builder/function_builder.dart
index 2fea24a..129c01a 100644
--- a/pkg/front_end/lib/src/fasta/builder/function_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/function_builder.dart
@@ -461,7 +461,7 @@
       _extensionThis = result.positionalParameters.first;
       if (extensionBuilder.typeParameters != null) {
         int count = extensionBuilder.typeParameters.length;
-        _extensionTypeParameters = new List<TypeParameter>(count);
+        _extensionTypeParameters = new List<TypeParameter>.filled(count, null);
         for (int index = 0; index < count; index++) {
           _extensionTypeParameters[index] = result.typeParameters[index];
         }
diff --git a/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart b/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart
index b360b52..3143c2d 100644
--- a/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart
@@ -130,14 +130,16 @@
   FunctionTypeBuilder clone(List<TypeBuilder> newTypes) {
     List<TypeVariableBuilder> clonedTypeVariables;
     if (typeVariables != null) {
-      clonedTypeVariables = new List<TypeVariableBuilder>(typeVariables.length);
+      clonedTypeVariables =
+          new List<TypeVariableBuilder>.filled(typeVariables.length, null);
       for (int i = 0; i < clonedTypeVariables.length; i++) {
         clonedTypeVariables[i] = typeVariables[i].clone(newTypes);
       }
     }
     List<FormalParameterBuilder> clonedFormals;
     if (formals != null) {
-      clonedFormals = new List<FormalParameterBuilder>(formals.length);
+      clonedFormals =
+          new List<FormalParameterBuilder>.filled(formals.length, null);
       for (int i = 0; i < clonedFormals.length; i++) {
         FormalParameterBuilder formal = formals[i];
         clonedFormals[i] = formal.clone(newTypes);
diff --git a/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart b/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
index e09e091..54cd164 100644
--- a/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
@@ -399,7 +399,7 @@
   NamedTypeBuilder clone(List<TypeBuilder> newTypes) {
     List<TypeBuilder> clonedArguments;
     if (arguments != null) {
-      clonedArguments = new List<TypeBuilder>(arguments.length);
+      clonedArguments = new List<TypeBuilder>.filled(arguments.length, null);
       for (int i = 0; i < clonedArguments.length; i++) {
         clonedArguments[i] = arguments[i].clone(newTypes);
       }
diff --git a/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart b/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
index 18d69f7..f4962fb 100644
--- a/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
@@ -722,7 +722,7 @@
                   actualOrigin.function.typeParameters[i], library.library);
         }
         List<DartType> newTypeArguments =
-            new List<DartType>(typeArguments.length);
+            new List<DartType>.filled(typeArguments.length, null);
         for (int i = 0; i < newTypeArguments.length; i++) {
           newTypeArguments[i] = substitute(typeArguments[i], substitution);
         }
@@ -755,8 +755,8 @@
     }
     _procedure.isRedirectingFactoryConstructor = true;
     if (redirectionTarget.typeArguments != null) {
-      typeArguments =
-          new List<DartType>(redirectionTarget.typeArguments.length);
+      typeArguments = new List<DartType>.filled(
+          redirectionTarget.typeArguments.length, null);
       for (int i = 0; i < typeArguments.length; i++) {
         typeArguments[i] = redirectionTarget.typeArguments[i].build(library);
       }
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
index 73c8433..a548f80 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
@@ -149,7 +149,7 @@
     if (cls.implementedTypes.isEmpty) return null;
     if (super.interfaceBuilders == null) {
       List<TypeBuilder> result =
-          new List<TypeBuilder>(cls.implementedTypes.length);
+          new List<TypeBuilder>.filled(cls.implementedTypes.length, null);
       for (int i = 0; i < result.length; i++) {
         result[i] = computeTypeBuilder(library, cls.implementedTypes[i]);
       }
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index a354e88..35c074e 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -537,7 +537,7 @@
         }
       }
     } else {
-      outputLibraries = new List<Library>();
+      outputLibraries = <Library>[];
       allLibraries = computeTransitiveClosure(
               compiledLibraries,
               entryPoints,
@@ -895,7 +895,7 @@
       ExperimentalInvalidation experimentalInvalidation,
       ReusageResult reusedResult) {
     if (hierarchy != null) {
-      List<Library> removedLibraries = new List<Library>();
+      List<Library> removedLibraries = <Library>[];
       // TODO(jensj): For now remove all the original from the class hierarchy
       // to avoid the class hierarchy getting confused.
       if (experimentalInvalidation != null) {
@@ -1232,7 +1232,7 @@
     if (hierarchy is ClosedWorldClassHierarchy && !hierarchy.allBetsOff) {
       neededDillLibraries ??= new Set<Library>();
       Set<Class> classes = new Set<Class>();
-      List<Class> worklist = new List<Class>();
+      List<Class> worklist = <Class>[];
       // Get all classes touched by kernel class hierarchy.
       List<Class> usedClasses = hierarchy.getUsedClasses();
       worklist.addAll(usedClasses);
@@ -1447,7 +1447,7 @@
       UriTranslator uriTranslator,
       Map<Uri, Source> uriToSource,
       [List<Library> inputLibrariesFiltered]) {
-    List<Library> result = new List<Library>();
+    List<Library> result = <Library>[];
     Map<Uri, Library> libraryMap = <Uri, Library>{};
     Map<Uri, Library> potentiallyReferencedLibraries = <Uri, Library>{};
     Map<Uri, Library> potentiallyReferencedInputLibraries = <Uri, Library>{};
@@ -1462,7 +1462,7 @@
       }
     }
 
-    List<Uri> worklist = new List<Uri>();
+    List<Uri> worklist = <Uri>[];
     worklist.addAll(entries);
     for (LibraryBuilder libraryBuilder in reusedLibraries) {
       if (libraryBuilder.importUri.scheme == "dart" &&
@@ -1499,7 +1499,7 @@
       }
     }
 
-    List<Library> removedLibraries = new List<Library>();
+    List<Library> removedLibraries = <Library>[];
     bool removedDillBuilders = false;
     for (Uri uri in potentiallyReferencedLibraries.keys) {
       if (uri.scheme == "package") continue;
@@ -1690,7 +1690,7 @@
         if (message.uri != null) {
           List<DiagnosticMessageFromJson> messages =
               remainingComponentProblems[message.uri] ??=
-                  new List<DiagnosticMessageFromJson>();
+                  <DiagnosticMessageFromJson>[];
           messages.add(message);
         }
         if (message.involvedFiles != null) {
@@ -1701,7 +1701,7 @@
           for (Uri uri in message.involvedFiles) {
             List<DiagnosticMessageFromJson> messages =
                 remainingComponentProblems[uri] ??=
-                    new List<DiagnosticMessageFromJson>();
+                    <DiagnosticMessageFromJson>[];
             messages.add(message);
           }
         }
@@ -1915,7 +1915,7 @@
       return new ReusageResult({}, [], false, reusedLibraries);
     }
     bool invalidatedBecauseOfPackageUpdate = false;
-    List<LibraryBuilder> directlyInvalidated = new List<LibraryBuilder>();
+    List<LibraryBuilder> directlyInvalidated = <LibraryBuilder>[];
     Set<LibraryBuilder> notReusedLibraries = new Set<LibraryBuilder>();
 
     // Maps all non-platform LibraryBuilders from their import URI.
diff --git a/pkg/front_end/lib/src/fasta/incremental_serializer.dart b/pkg/front_end/lib/src/fasta/incremental_serializer.dart
index e22b912..4581f16 100644
--- a/pkg/front_end/lib/src/fasta/incremental_serializer.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_serializer.dart
@@ -62,7 +62,7 @@
     // Add groups. Wrap in try because an exception will be thrown if a group
     // has a dependency that isn't being met.
     try {
-      List<SerializationGroup> newGroups = new List<SerializationGroup>();
+      List<SerializationGroup> newGroups = <SerializationGroup>[];
       for (int i = 0; i < goodViews.length; i++) {
         SubComponentView view = goodViews[i];
         List<int> data = new Uint8List(view.componentFileSize);
@@ -113,8 +113,8 @@
     component.computeCanonicalNames();
 
     // Split into package and non-package libraries.
-    List<Library> packageLibraries = new List<Library>();
-    List<Library> nonPackageLibraries = new List<Library>();
+    List<Library> packageLibraries = <Library>[];
+    List<Library> nonPackageLibraries = <Library>[];
     for (Library lib in component.libraries) {
       Uri uri = lib.importUri;
       if (uri.scheme == "package") {
@@ -196,7 +196,7 @@
   void removeInvalidated() {
     // Remove all directly invalidated entries.
     Set<SerializationGroup> removed = new Set<SerializationGroup>();
-    List<SerializationGroup> workList = new List<SerializationGroup>();
+    List<SerializationGroup> workList = <SerializationGroup>[];
     for (Uri uri in invalidatedUris) {
       removeUriFromMap(uri, removed, workList);
     }
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 2efd369..8971d25 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -1389,8 +1389,8 @@
     List<FormalParameterBuilder> formals =
         parameters.positionalParameters.length == 0
             ? null
-            : new List<FormalParameterBuilder>(
-                parameters.positionalParameters.length);
+            : new List<FormalParameterBuilder>.filled(
+                parameters.positionalParameters.length, null);
     for (int i = 0; i < parameters.positionalParameters.length; i++) {
       VariableDeclaration formal = parameters.positionalParameters[i];
       formals[i] = new FormalParameterBuilder(
@@ -3133,7 +3133,8 @@
     if (isSet) {
       buildLiteralSet(typeArguments, constKeyword, leftBrace, setOrMapEntries);
     } else {
-      List<MapEntry> mapEntries = new List<MapEntry>(setOrMapEntries.length);
+      List<MapEntry> mapEntries =
+          new List<MapEntry>.filled(setOrMapEntries.length, null);
       for (int i = 0; i < setOrMapEntries.length; ++i) {
         if (setOrMapEntries[i] is MapEntry) {
           mapEntries[i] = setOrMapEntries[i];
@@ -5456,7 +5457,8 @@
     int count = labelCount + expressionCount;
     List<Object> labelsAndExpressions =
         const FixedNullableList<Object>().pop(stack, count);
-    List<Label> labels = labelCount == 0 ? null : new List<Label>(labelCount);
+    List<Label> labels =
+        labelCount == 0 ? null : new List<Label>.filled(labelCount, null);
     List<Expression> expressions =
         new List<Expression>.filled(expressionCount, null, growable: true);
     int labelIndex = 0;
diff --git a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
index d56fa0d..387a16c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
@@ -280,7 +280,7 @@
   if (typeParameterCount != bTypeParameters.length) return false;
   Substitution substitution;
   if (typeParameterCount != 0) {
-    List<DartType> types = new List<DartType>(typeParameterCount);
+    List<DartType> types = new List<DartType>.filled(typeParameterCount, null);
     for (int i = 0; i < typeParameterCount; i++) {
       types[i] = new TypeParameterType.forAlphaRenaming(
           bTypeParameters[i], aTypeParameters[i]);
@@ -790,7 +790,8 @@
           }
           Substitution methodSubstitution;
           if (typeParameterCount != 0) {
-            List<DartType> types = new List<DartType>(typeParameterCount);
+            List<DartType> types =
+                new List<DartType>.filled(typeParameterCount, null);
             for (int i = 0; i < typeParameterCount; i++) {
               types[i] = new TypeParameterType.forAlphaRenaming(
                   overriddenTypeParameters[i], declaredTypeParameters[i]);
@@ -1682,13 +1683,14 @@
     bool hasInterfaces = false;
     if (supernode == null) {
       // This should be Object.
-      superclasses = new List<Supertype>(0);
-      interfaces = new List<Supertype>(0);
+      superclasses = new List<Supertype>.filled(0, null);
+      interfaces = new List<Supertype>.filled(0, null);
       maxInheritancePath = 0;
     } else {
       maxInheritancePath = supernode.maxInheritancePath + 1;
 
-      superclasses = new List<Supertype>(supernode.superclasses.length + 1);
+      superclasses =
+          new List<Supertype>.filled(supernode.superclasses.length + 1, null);
       Supertype supertype = classBuilder.supertypeBuilder.buildSupertype(
           classBuilder.library, classBuilder.charOffset, classBuilder.fileUri);
       if (supertype == null) {
@@ -2328,9 +2330,10 @@
       substitutions[cls] = Substitution.empty;
     } else {
       List<DartType> arguments = supertype.typeArguments;
-      List<DartType> typeArguments = new List<DartType>(arguments.length);
+      List<DartType> typeArguments =
+          new List<DartType>.filled(arguments.length, null);
       List<TypeParameter> typeParameters =
-          new List<TypeParameter>(arguments.length);
+          new List<TypeParameter>.filled(arguments.length, null);
       for (int i = 0; i < arguments.length; i++) {
         typeParameters[i] = supertypeTypeParameters[i];
         typeArguments[i] = arguments[i];
@@ -2474,7 +2477,7 @@
                 mixedInType.classNode.typeParameters, cls.enclosingLibrary))
         .infer(cls);
     List<TypeBuilder> inferredArguments =
-        new List<TypeBuilder>(typeArguments.length);
+        new List<TypeBuilder>.filled(typeArguments.length, null);
     for (int i = 0; i < typeArguments.length; i++) {
       inferredArguments[i] =
           hierarchy.loader.computeTypeBuilder(typeArguments[i]);
@@ -2557,8 +2560,8 @@
   /// Returns a list of all supertypes of [classBuilder], including this node.
   List<ClassHierarchyNode> computeAllSuperNodes(
       ClassHierarchyBuilder hierarchy) {
-    List<ClassHierarchyNode> result = new List<ClassHierarchyNode>(
-        1 + superclasses.length + interfaces.length);
+    List<ClassHierarchyNode> result = new List<ClassHierarchyNode>.filled(
+        1 + superclasses.length + interfaces.length, null);
     for (int i = 0; i < superclasses.length; i++) {
       Supertype type = superclasses[i];
       result[i] = hierarchy.getNodeFromClass(type.classNode);
diff --git a/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart b/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart
index c97fc4e..c4ff40d 100644
--- a/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart
@@ -293,7 +293,7 @@
   /// Returns type of the [index]th member in [members] as inherited in
   /// [classBuilder].
   DartType getMemberType(int index) {
-    _memberTypes ??= new List<DartType>(members.length);
+    _memberTypes ??= new List<DartType>.filled(members.length, null);
     DartType candidateType = _memberTypes[index];
     if (candidateType == null) {
       Member target = _getMember(index);
@@ -412,7 +412,8 @@
       if (typeParameterCount == 0) {
         return type;
       }
-      List<DartType> types = new List<DartType>(typeParameterCount);
+      List<DartType> types =
+          new List<DartType>.filled(typeParameterCount, null);
       for (int i = 0; i < typeParameterCount; i++) {
         types[i] = new TypeParameterType.forAlphaRenaming(
             signatureTypeParameters[i], typeParameters[i]);
@@ -776,7 +777,7 @@
 
   @override
   Covariance _getMemberCovariance(int index) {
-    _memberCovariances ??= new List<Covariance>(members.length);
+    _memberCovariances ??= new List<Covariance>.filled(members.length, null);
     Covariance covariance = _memberCovariances[index];
     if (covariance == null) {
       _memberCovariances[index] = covariance =
diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_collection_builders.dart b/pkg/front_end/lib/src/fasta/kernel/constant_collection_builders.dart
index 8f0a84bb..8caaedc 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_collection_builders.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_collection_builders.dart
@@ -178,7 +178,7 @@
       SetConstant result = new SetConstant(elementType, entries);
       if (evaluator.desugarSets) {
         final List<ConstantMapEntry> mapEntries =
-            new List<ConstantMapEntry>(entries.length);
+            new List<ConstantMapEntry>.filled(entries.length, null);
         for (int i = 0; i < entries.length; ++i) {
           mapEntries[i] =
               new ConstantMapEntry(entries[i], evaluator.nullConstant);
diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
index ed46fca..c0c6a16 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -2182,7 +2182,7 @@
     }
     if (concatenated.length > 1) {
       final List<Expression> expressions =
-          new List<Expression>(concatenated.length);
+          new List<Expression>.filled(concatenated.length, null);
       for (int i = 0; i < concatenated.length; i++) {
         Object value = concatenated[i];
         if (value is StringBuffer) {
@@ -2754,9 +2754,9 @@
   Arguments unevaluatedArguments(List<Constant> positionalArgs,
       Map<String, Constant> namedArgs, List<DartType> types) {
     final List<Expression> positional =
-        new List<Expression>(positionalArgs.length);
+        new List<Expression>.filled(positionalArgs.length, null);
     final List<NamedExpression> named =
-        new List<NamedExpression>(namedArgs.length);
+        new List<NamedExpression>.filled(namedArgs.length, null);
     for (int i = 0; i < positionalArgs.length; ++i) {
       positional[i] = extract(positionalArgs[i]);
     }
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
index 06237ec..509c236 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -3036,7 +3036,7 @@
 
     List<TypeBuilder> argumentBuilders;
     if (arguments != null) {
-      argumentBuilders = new List<TypeBuilder>(arguments.length);
+      argumentBuilders = new List<TypeBuilder>.filled(arguments.length, null);
       for (int i = 0; i < argumentBuilders.length; i++) {
         argumentBuilders[i] = _helper
             .validateTypeUse(arguments[i],
diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
index e426f0b..89baa79 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -5114,7 +5114,7 @@
     List<TypeParameter> classTypeParameters =
         node.target.enclosingClass.typeParameters;
     List<DartType> typeArguments =
-        new List<DartType>(classTypeParameters.length);
+        new List<DartType>.filled(classTypeParameters.length, null);
     for (int i = 0; i < typeArguments.length; i++) {
       typeArguments[i] = new TypeParameterType.withDefaultNullabilityForLibrary(
           classTypeParameters[i], inferrer.library.library);
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 3a23482..de75625 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -198,7 +198,7 @@
 
   /// Return list of same size as input with possibly translated uris.
   List<Uri> setEntryPoints(List<Uri> entryPoints) {
-    List<Uri> result = new List<Uri>();
+    List<Uri> result = <Uri>[];
     for (Uri entryPoint in entryPoints) {
       Uri translatedEntryPoint =
           getEntryPointUri(entryPoint, issueProblem: true);
@@ -842,7 +842,7 @@
   }
 
   DartType makeConstructorReturnType(Class enclosingClass) {
-    List<DartType> typeParameterTypes = new List<DartType>();
+    List<DartType> typeParameterTypes = <DartType>[];
     for (int i = 0; i < enclosingClass.typeParameters.length; i++) {
       TypeParameter typeParameter = enclosingClass.typeParameters[i];
       typeParameterTypes.add(
diff --git a/pkg/front_end/lib/src/fasta/kernel/member_covariance.dart b/pkg/front_end/lib/src/fasta/kernel/member_covariance.dart
index 5d1d77f..6a5eaaf 100644
--- a/pkg/front_end/lib/src/fasta/kernel/member_covariance.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/member_covariance.dart
@@ -208,8 +208,9 @@
     } else if (other._positionalParameters == null) {
       positionalParameters = _positionalParameters;
     } else {
-      positionalParameters = new List<int>(max(
-          _positionalParameters.length, other._positionalParameters.length));
+      positionalParameters = new List<int>.filled(
+          max(_positionalParameters.length, other._positionalParameters.length),
+          null);
       for (int index = 0; index < positionalParameters.length; index++) {
         positionalParameters[index] =
             getPositionalVariance(index) | other.getPositionalVariance(index);
@@ -237,8 +238,8 @@
     } else if (other._typeParameters == null) {
       typeParameters = _typeParameters;
     } else {
-      typeParameters = new List<bool>(
-          max(_typeParameters.length, other._typeParameters.length));
+      typeParameters = new List<bool>.filled(
+          max(_typeParameters.length, other._typeParameters.length), null);
       for (int index = 0; index < typeParameters.length; index++) {
         typeParameters[index] = isTypeParameterGenericCovariantImpl(index) ||
             other.isTypeParameterGenericCovariantImpl(index);
diff --git a/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart b/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
index 1fd20cd..e93756e 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
@@ -293,11 +293,13 @@
   } else if (type is FunctionTypeBuilder) {
     List<TypeVariableBuilder> variables;
     if (type.typeVariables != null) {
-      variables = new List<TypeVariableBuilder>(type.typeVariables.length);
+      variables =
+          new List<TypeVariableBuilder>.filled(type.typeVariables.length, null);
     }
     List<FormalParameterBuilder> formals;
     if (type.formals != null) {
-      formals = new List<FormalParameterBuilder>(type.formals.length);
+      formals =
+          new List<FormalParameterBuilder>.filled(type.formals.length, null);
     }
     TypeBuilder returnType;
     bool changed = false;
@@ -391,7 +393,8 @@
 /// of the algorithm for details.
 List<TypeBuilder> calculateBounds(List<TypeVariableBuilder> variables,
     TypeBuilder dynamicType, TypeBuilder bottomType, ClassBuilder objectClass) {
-  List<TypeBuilder> bounds = new List<TypeBuilder>(variables.length);
+  List<TypeBuilder> bounds =
+      new List<TypeBuilder>.filled(variables.length, null);
 
   for (int i = 0; i < variables.length; i++) {
     bounds[i] = variables[i].bound ?? dynamicType;
@@ -449,10 +452,10 @@
   TypeVariablesGraph(this.variables, this.bounds) {
     assert(variables.length == bounds.length);
 
-    vertices = new List<int>(variables.length);
+    vertices = new List<int>.filled(variables.length, null);
     Map<TypeVariableBuilder, int> variableIndices =
         <TypeVariableBuilder, int>{};
-    edges = new List<List<int>>(variables.length);
+    edges = new List<List<int>>.filled(variables.length, null);
     for (int i = 0; i < vertices.length; i++) {
       vertices[i] = i;
       variableIndices[variables[i]] = i;
diff --git a/pkg/front_end/lib/src/fasta/kernel/type_builder_computer.dart b/pkg/front_end/lib/src/fasta/kernel/type_builder_computer.dart
index a02abb4..43402ad 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_builder_computer.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_builder_computer.dart
@@ -120,7 +120,7 @@
     List<TypeBuilder> arguments;
     List<DartType> kernelArguments = node.typeArguments;
     if (kernelArguments.isNotEmpty) {
-      arguments = new List<TypeBuilder>(kernelArguments.length);
+      arguments = new List<TypeBuilder>.filled(kernelArguments.length, null);
       for (int i = 0; i < kernelArguments.length; i++) {
         arguments[i] = kernelArguments[i].accept(this);
       }
@@ -154,8 +154,9 @@
     List<TypeVariableBuilder> typeVariables = null;
     List<DartType> positionalParameters = node.positionalParameters;
     List<NamedType> namedParameters = node.namedParameters;
-    List<FormalParameterBuilder> formals = new List<FormalParameterBuilder>(
-        positionalParameters.length + namedParameters.length);
+    List<FormalParameterBuilder> formals =
+        new List<FormalParameterBuilder>.filled(
+            positionalParameters.length + namedParameters.length, null);
     for (int i = 0; i < positionalParameters.length; i++) {
       TypeBuilder type = positionalParameters[i].accept(this);
       FormalParameterKind kind = FormalParameterKind.mandatory;
diff --git a/pkg/front_end/lib/src/fasta/source/outline_builder.dart b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
index 471859f..07a4d49 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -125,7 +125,7 @@
 
   List<String> popIdentifierList(int count) {
     if (count == 0) return null;
-    List<String> list = new List<String>(count);
+    List<String> list = new List<String>.filled(count, null);
     bool isParserRecovery = false;
     for (int i = count - 1; i >= 0; i--) {
       popCharOffset();
@@ -387,7 +387,7 @@
   @override
   void handleStringJuxtaposition(Token startToken, int literalCount) {
     debugEvent("StringJuxtaposition");
-    List<String> list = new List<String>(literalCount);
+    List<String> list = new List<String>.filled(literalCount, null);
     int charOffset = -1;
     for (int i = literalCount - 1; i >= 0; i--) {
       charOffset = pop();
@@ -1489,7 +1489,7 @@
         formals = last;
       } else if (last is! ParserRecovery) {
         assert(last != null);
-        formals = new List<FormalParameterBuilder>(1);
+        formals = new List<FormalParameterBuilder>.filled(1, null);
         formals[0] = last;
       }
     } else if (count > 1) {
@@ -1833,7 +1833,7 @@
 
   List<FieldInfo> popFieldInfos(int count) {
     if (count == 0) return null;
-    List<FieldInfo> fieldInfos = new List<FieldInfo>(count);
+    List<FieldInfo> fieldInfos = new List<FieldInfo>.filled(count, null);
     bool isParserRecovery = false;
     for (int i = count - 1; i != -1; i--) {
       int charEndOffset = pop();
@@ -1928,7 +1928,7 @@
           }
           if (bound == builder && bound.bound != null) {
             // Write out cycle.
-            List<String> via = new List<String>();
+            List<String> via = <String>[];
             bound = typeVariablesByName[builder.bound.name];
             while (bound != builder) {
               via.add(bound.name);
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index 4855bd5..3ee8253 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -248,8 +248,7 @@
   // default nullability of the corresponding type-parameter types.  This list
   // is used to collect such type-parameter types in order to set the
   // nullability after the bounds are built.
-  final List<TypeParameterType> pendingNullabilities =
-      new List<TypeParameterType>();
+  final List<TypeParameterType> pendingNullabilities = <TypeParameterType>[];
 
   // A library to use for Names generated when compiling code in this library.
   // This allows code generated in one library to use the private namespace of
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index e28997d..54420e8 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -1106,7 +1106,7 @@
     // TODO(ahe): Move this to [ClassHierarchyBuilder].
     if (!target.backendTarget.enableNoSuchMethodForwarders) return;
 
-    List<Class> changedClasses = new List<Class>();
+    List<Class> changedClasses = <Class>[];
     for (SourceClassBuilder builder in sourceClasses) {
       if (builder.library.loader == this && !builder.isPatch) {
         if (builder.addNoSuchMethodForwarders(target, hierarchy)) {
diff --git a/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart b/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
index 62d5564..4061bce 100644
--- a/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
@@ -84,7 +84,7 @@
     TypeBuilder type = this.type;
     if (type is FunctionTypeBuilder) {
       List<TypeParameter> typeParameters =
-          new List<TypeParameter>(type.typeVariables?.length ?? 0);
+          new List<TypeParameter>.filled(type.typeVariables?.length ?? 0, null);
       for (int i = 0; i < typeParameters.length; ++i) {
         TypeVariableBuilder typeVariable = type.typeVariables[i];
         typeParameters[i] = typeVariable.parameter;
diff --git a/pkg/front_end/lib/src/fasta/util/direct_parser_ast.dart b/pkg/front_end/lib/src/fasta/util/direct_parser_ast.dart
index 9f2c1ae..3331e01 100644
--- a/pkg/front_end/lib/src/fasta/util/direct_parser_ast.dart
+++ b/pkg/front_end/lib/src/fasta/util/direct_parser_ast.dart
@@ -708,7 +708,7 @@
     // of the fields.
     int countLeft = count;
     List<DirectParserASTContentIdentifierHandle> identifiers =
-        new List<DirectParserASTContentIdentifierHandle>(count);
+        new List<DirectParserASTContentIdentifierHandle>.filled(count, null);
     for (int i = children.length - 1; i >= 0; i--) {
       DirectParserASTContent child = children[i];
       if (child is DirectParserASTContentIdentifierHandle) {
diff --git a/pkg/front_end/lib/src/fasta/util/textual_outline.dart b/pkg/front_end/lib/src/fasta/util/textual_outline.dart
index 4b1f8cc..676582d 100644
--- a/pkg/front_end/lib/src/fasta/util/textual_outline.dart
+++ b/pkg/front_end/lib/src/fasta/util/textual_outline.dart
@@ -270,7 +270,7 @@
 }
 
 abstract class _ClassChunk extends _SortableChunk {
-  List<_Chunk> content = new List<_Chunk>();
+  List<_Chunk> content = <_Chunk>[];
   Token headerEnd;
   Token footerStart;
 
@@ -424,7 +424,7 @@
   Uint8List bytes = new Uint8List(rawBytes.length + 1);
   bytes.setRange(0, rawBytes.length, rawBytes);
 
-  List<_Chunk> parsedChunks = new List<_Chunk>();
+  List<_Chunk> parsedChunks = <_Chunk>[];
 
   BoxedInt originalPosition = new BoxedInt(0);
 
@@ -482,7 +482,7 @@
   StringBuffer sb = new StringBuffer();
   for (_Chunk chunk in chunks) {
     if (chunk is _MetadataChunk) {
-      metadataChunks ??= new List<_MetadataChunk>();
+      metadataChunks ??= <_MetadataChunk>[];
       metadataChunks.add(chunk);
     } else {
       chunk.metadata = metadataChunks;
@@ -491,7 +491,7 @@
       sb.clear();
 
       if (chunk is _SingleImportExportChunk) {
-        importExportChunks ??= new List<_SingleImportExportChunk>();
+        importExportChunks ??= <_SingleImportExportChunk>[];
         importExportChunks.add(chunk);
       } else {
         if (importExportChunks != null) {
diff --git a/pkg/front_end/lib/src/kernel_generator_impl.dart b/pkg/front_end/lib/src/kernel_generator_impl.dart
index 24b5b55..ae668cb 100644
--- a/pkg/front_end/lib/src/kernel_generator_impl.dart
+++ b/pkg/front_end/lib/src/kernel_generator_impl.dart
@@ -74,7 +74,7 @@
     DillTarget dillTarget =
         new DillTarget(options.ticker, uriTranslator, options.target);
 
-    List<Component> loadedComponents = new List<Component>();
+    List<Component> loadedComponents = <Component>[];
 
     Component sdkSummary = await options.loadSdkSummary(null);
     // By using the nameRoot of the the summary, we enable sharing the
diff --git a/pkg/front_end/test/ast_nodes_has_to_string_test.dart b/pkg/front_end/test/ast_nodes_has_to_string_test.dart
index 13d7120..9b0dc9f 100644
--- a/pkg/front_end/test/ast_nodes_has_to_string_test.dart
+++ b/pkg/front_end/test/ast_nodes_has_to_string_test.dart
@@ -56,13 +56,13 @@
               .toList();
           if (toStringList.length > 1) throw "What?";
           if (toStringList.length == 1) {
-            classMapWithOne[c.fileUri] ??= new List<Class>();
+            classMapWithOne[c.fileUri] ??= <Class>[];
             classMapWithOne[c.fileUri].add(c);
             continue;
           }
           toGo++;
 
-          classMap[c.fileUri] ??= new List<Class>();
+          classMap[c.fileUri] ??= <Class>[];
           classMap[c.fileUri].add(c);
         }
       }
diff --git a/pkg/front_end/test/binary_md_dill_reader.dart b/pkg/front_end/test/binary_md_dill_reader.dart
index c0a4b5b..271ffd8 100644
--- a/pkg/front_end/test/binary_md_dill_reader.dart
+++ b/pkg/front_end/test/binary_md_dill_reader.dart
@@ -517,7 +517,7 @@
 
         if (intCount >= 0) {
           readNothingIsOk = intCount == 0;
-          List<dynamic> value = new List(intCount);
+          List<dynamic> value = new List.filled(intCount, null);
           for (int i = 0; i < intCount; ++i) {
             int oldOffset2 = _binaryOffset;
             value[i] = _readBinary(type);
diff --git a/pkg/front_end/test/crashing_test_case_minimizer.dart b/pkg/front_end/test/crashing_test_case_minimizer.dart
index 3248a9d..8d0fcc6 100644
--- a/pkg/front_end/test/crashing_test_case_minimizer.dart
+++ b/pkg/front_end/test/crashing_test_case_minimizer.dart
@@ -959,7 +959,7 @@
   Uint8List data = fs.data[uri];
   Uint8List latestCrashData = data;
 
-  List<int> lineStarts = new List<int>();
+  List<int> lineStarts = <int>[];
 
   Token firstToken = parser_suite.scanRawBytes(data,
       nnbd ? scannerConfiguration : scannerConfigurationNonNNBD, lineStarts);
@@ -1697,7 +1697,7 @@
 }
 
 String getFileAsStringContent(Uint8List rawBytes, bool nnbd) {
-  List<int> lineStarts = new List<int>();
+  List<int> lineStarts = <int>[];
 
   Token firstToken = parser_suite.scanRawBytes(rawBytes,
       nnbd ? scannerConfiguration : scannerConfigurationNonNNBD, lineStarts);
diff --git a/pkg/front_end/test/dijkstras_sssp_algorithm.dart b/pkg/front_end/test/dijkstras_sssp_algorithm.dart
index c3079e9..b8f9789 100644
--- a/pkg/front_end/test/dijkstras_sssp_algorithm.dart
+++ b/pkg/front_end/test/dijkstras_sssp_algorithm.dart
@@ -79,7 +79,7 @@
   }
 
   List<E> getPathFromTarget(GraphNode<E> source, GraphNode<E> target) {
-    List<E> path = new List<E>();
+    List<E> path = <E>[];
     GraphNode<E> u = target;
     while (u == source || prev[u] != null) {
       path.add(u.node);
diff --git a/pkg/front_end/test/fasta/incremental_source_files.dart b/pkg/front_end/test/fasta/incremental_source_files.dart
index f830639..c6d6931 100644
--- a/pkg/front_end/test/fasta/incremental_source_files.dart
+++ b/pkg/front_end/test/fasta/incremental_source_files.dart
@@ -55,7 +55,7 @@
 ///   ["head v1 tail", "head v2 tail"]
 List<String> expandUpdates(List updates) {
   int outputCount = updates.firstWhere((e) => e is Iterable).length;
-  List<StringBuffer> result = new List<StringBuffer>(outputCount);
+  List<StringBuffer> result = new List<StringBuffer>.filled(outputCount, null);
   for (int i = 0; i < outputCount; i++) {
     result[i] = new StringBuffer();
   }
diff --git a/pkg/front_end/test/fasta/messages_suite.dart b/pkg/front_end/test/fasta/messages_suite.dart
index aa7aa4870..9a370f4 100644
--- a/pkg/front_end/test/fasta/messages_suite.dart
+++ b/pkg/front_end/test/fasta/messages_suite.dart
@@ -170,7 +170,7 @@
           int offset, String message, String messageForDenyListed) {
         if (source == null) {
           List<int> bytes = file.readAsBytesSync();
-          List<int> lineStarts = new List<int>();
+          List<int> lineStarts = <int>[];
           int indexOf = 0;
           while (indexOf >= 0) {
             lineStarts.add(indexOf);
@@ -179,7 +179,7 @@
           lineStarts.add(bytes.length);
           source = new Source(lineStarts, bytes, uri, uri);
         }
-        List<String> result = new List<String>();
+        List<String> result = <String>[];
         for (int i = 0; i < spellResult.misspelledWords.length; i++) {
           Location location = source.getLocation(
               uri, offset + spellResult.misspelledWordsOffset[i]);
@@ -217,7 +217,7 @@
                   spell.Dictionaries.cfeMessages
                 ]);
             if (spellingResult.misspelledWords != null) {
-              spellingMessages ??= new List<String>();
+              spellingMessages ??= <String>[];
               spellingMessages.addAll(formatSpellingMistakes(
                   spellingResult,
                   node.span.start.offset,
@@ -236,7 +236,7 @@
                   spell.Dictionaries.cfeMessages
                 ]);
             if (spellingResult.misspelledWords != null) {
-              spellingMessages ??= new List<String>();
+              spellingMessages ??= <String>[];
               spellingMessages.addAll(formatSpellingMistakes(
                   spellingResult,
                   node.span.start.offset,
@@ -741,7 +741,7 @@
 
     List<DiagnosticMessage> unexpectedMessages = <DiagnosticMessage>[];
     if (example.allowMoreCodes) {
-      List<DiagnosticMessage> messagesFiltered = new List<DiagnosticMessage>();
+      List<DiagnosticMessage> messagesFiltered = <DiagnosticMessage>[];
       for (DiagnosticMessage message in messages) {
         if (getMessageCodeObject(message).name == example.expectedCode) {
           messagesFiltered.add(message);
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index 6953580..64099f8 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -1065,7 +1065,7 @@
         }
 
         testOptions.component = p;
-        List<Library> keepLibraries = new List<Library>();
+        List<Library> keepLibraries = <Library>[];
         for (Library lib in p.libraries) {
           if (testOptions.linkDependencies.contains(lib.importUri)) {
             keepLibraries.add(lib);
diff --git a/pkg/front_end/test/fasta/type_inference/type_schema_environment_nnbd_test.dart b/pkg/front_end/test/fasta/type_inference/type_schema_environment_nnbd_test.dart
index 9e5df47..5818a50 100644
--- a/pkg/front_end/test/fasta/type_inference/type_schema_environment_nnbd_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_schema_environment_nnbd_test.dart
@@ -8,8 +8,6 @@
 import 'package:kernel/core_types.dart';
 import 'package:kernel/class_hierarchy.dart';
 import 'package:kernel/testing/type_parser_environment.dart';
-import 'package:kernel/testing/mock_sdk.dart';
-import 'package:kernel/type_environment.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -21,97 +19,90 @@
 
 @reflectiveTest
 class TypeSchemaEnvironmentTest {
-  Component component;
+  Env typeParserEnvironment;
+  TypeSchemaEnvironment typeSchemaEnvironment;
 
-  CoreTypes coreTypes;
+  final Map<String, DartType Function()> additionalTypes = {
+    "UNKNOWN": () => new UnknownType(),
+    "BOTTOM": () => new BottomType(),
+  };
 
-  TypeSchemaEnvironment env;
+  Library _coreLibrary;
+  Library _testLibrary;
 
-  TypeParserEnvironment typeParserEnvironment;
+  Library get coreLibrary => _coreLibrary;
+  Library get testLibrary => _testLibrary;
 
-  Library get testLib => component.libraries.single;
+  Component get component => typeParserEnvironment.component;
+  CoreTypes get coreTypes => typeParserEnvironment.coreTypes;
 
-  Class get iterableClass => coreTypes.iterableClass;
-
-  Class get listClass => coreTypes.listClass;
-
-  Class get mapClass => coreTypes.mapClass;
-
-  Class get objectClass => coreTypes.objectClass;
-
-  DartType get bottomType => const NeverType(Nullability.nonNullable);
-
-  DartType get topType => coreTypes.objectNullableRawType;
-
-  /// Converts the [text] representation of a type into a type.
-  ///
-  /// If [environment] is passed it's used to resolve the type terms in [text].
-  /// If [typeParameters] are passed, they are used to extend
-  /// [typeParserEnvironment] to resolve the type terms in [text].  Not more
-  /// than one of [environment] or [typeParameters] should be passed in.
-  DartType toType(String text,
-      {TypeParserEnvironment environment, String typeParameters}) {
-    assert(environment == null || typeParameters == null);
-    environment ??= extend(typeParameters);
-    return environment.parseType(text);
-  }
-
-  TypeParserEnvironment extend(String typeParameters) {
-    return typeParserEnvironment.extendWithTypeParameters(typeParameters);
+  void parseTestLibrary(String testLibraryText) {
+    typeParserEnvironment =
+        new Env(testLibraryText, isNonNullableByDefault: true);
+    typeSchemaEnvironment = new TypeSchemaEnvironment(
+        coreTypes, new ClassHierarchy(component, coreTypes));
+    assert(
+        typeParserEnvironment.component.libraries.length == 2,
+        "The tests are supposed to have exactly two libraries: "
+        "the core library and the test library.");
+    Library firstLibrary = typeParserEnvironment.component.libraries.first;
+    Library secondLibrary = typeParserEnvironment.component.libraries.last;
+    if (firstLibrary.importUri.scheme == "dart" &&
+        firstLibrary.importUri.path == "core") {
+      _coreLibrary = firstLibrary;
+      _testLibrary = secondLibrary;
+    } else {
+      assert(
+          secondLibrary.importUri.scheme == "dart" &&
+              secondLibrary.importUri.path == "core",
+          "One of the libraries is expected to be 'dart:core'.");
+      _coreLibrary == secondLibrary;
+      _testLibrary = firstLibrary;
+    }
   }
 
   void test_addLowerBound() {
-    const String testSdk = """
+    parseTestLibrary("""
       class A;
       class B extends A;
       class C extends A;
-    """;
-    _initialize(testSdk);
+    """);
 
     // TODO(dmitryas): Test for various nullabilities.
-    TypeConstraint typeConstraint = new TypeConstraint();
 
     // typeConstraint: EMPTY <: TYPE <: EMPTY
-    expect(typeConstraint.lower, new UnknownType());
+    checkConstraintLowerBound(constraint: "", bound: "UNKNOWN");
 
     // typeConstraint: B* <: TYPE <: EMPTY
-    env.addLowerBound(typeConstraint, toType("B*"), testLib);
-    testConstraint(typeConstraint, lowerExpected: toType("B*"));
+    checkConstraintLowerBound(constraint: ":> B*", bound: "B*");
 
     // typeConstraint: UP(B*, C*) <: TYPE <: EMPTY,
     //     where UP(B*, C*) = A*
-    env.addLowerBound(typeConstraint, toType("C*"), testLib);
-    testConstraint(typeConstraint, lowerExpected: toType("A*"));
+    checkConstraintLowerBound(constraint: ":> B* :> C*", bound: "A*");
   }
 
   void test_addUpperBound() {
-    const String testSdk = """
+    parseTestLibrary("""
       class A;
       class B extends A;
       class C extends A;
-    """;
-    _initialize(testSdk);
+    """);
 
     // TODO(dmitryas): Test for various nullabilities.
-    TypeConstraint typeConstraint = new TypeConstraint();
 
     // typeConstraint: EMPTY <: TYPE <: EMPTY
-    expect(typeConstraint.upper, new UnknownType());
+    checkConstraintUpperBound(constraint: "", bound: "UNKNOWN");
 
     // typeConstraint: EMPTY <: TYPE <: A*
-    env.addUpperBound(typeConstraint, toType("A*"), testLib);
-    testConstraint(typeConstraint, upperExpected: toType("A*"));
+    checkConstraintUpperBound(constraint: "<: A*", bound: "A*");
 
     // typeConstraint: EMPTY <: TYPE <: DOWN(A*, B*),
     //     where DOWN(A*, B*) = B*
-    env.addUpperBound(typeConstraint, toType("B*"), testLib);
-    testConstraint(typeConstraint, upperExpected: toType("B*"));
+    checkConstraintUpperBound(constraint: "<: A* <: B*", bound: "B*");
 
     // typeConstraint: EMPTY <: TYPE <: DOWN(B*, C*),
     //     where DOWN(B*, C*) = Never*
-    env.addUpperBound(typeConstraint, toType("C*"), testLib);
-    testConstraint(typeConstraint,
-        upperExpected: new NeverType(Nullability.legacy));
+    checkConstraintUpperBound(constraint: "<:A* <: B* <: C*", bound: "Never*");
   }
 
   /// Some of the types satisfying the TOP predicate.
@@ -272,53 +263,12 @@
     return "$typeParameters1, $typeParameters2";
   }
 
-  void testLower(String first, String second, String expected,
-      {String typeParameters}) {
-    TypeParserEnvironment environment = extend(typeParameters);
-    DartType firstType = toType(first, environment: environment);
-    DartType secondType = toType(second, environment: environment);
-    DartType expectedType = toType(expected, environment: environment);
-    DartType producedType =
-        env.getStandardLowerBound(firstType, secondType, testLib);
-    expect(producedType, expectedType,
-        reason: "DOWN(${firstType}, ${secondType}) produced '${producedType}', "
-            "but expected '${expectedType}'.");
-  }
-
-  void testUpper(String first, String second, String expected,
-      {String typeParameters}) {
-    TypeParserEnvironment environment = extend(typeParameters);
-    DartType firstType = toType(first, environment: environment);
-    DartType secondType = toType(second, environment: environment);
-    DartType expectedType = toType(expected, environment: environment);
-    DartType producedType =
-        env.getStandardUpperBound(firstType, secondType, testLib);
-    expect(producedType, expectedType,
-        reason: "UP(${firstType}, ${secondType}) produced '${producedType}', "
-            "but expected '${expectedType}'.");
-  }
-
-  void testConstraint(TypeConstraint typeConstraint,
-      {DartType lowerExpected, DartType upperExpected}) {
-    assert(lowerExpected != null || upperExpected != null);
-    if (lowerExpected != null) {
-      expect(typeConstraint.lower, lowerExpected,
-          reason: "Expected the lower bound to be '${lowerExpected}' "
-              "for the following type constraint: ${typeConstraint}");
-    }
-    if (upperExpected != null) {
-      expect(typeConstraint.upper, upperExpected,
-          reason: "Expected the upper bound to be '${upperExpected}' "
-              "for the following type constraint: ${typeConstraint}");
-    }
-  }
-
   void test_lower_bound_bottom() {
-    _initialize("class A;");
+    parseTestLibrary("class A;");
 
     for (String type in ["A*", "A?", "A"]) {
-      testLower("bottom", type, "bottom");
-      testLower(type, "bottom", "bottom");
+      checkLowerBound(type1: "bottom", type2: type, lowerBound: "bottom");
+      checkLowerBound(type1: type, type2: "bottom", lowerBound: "bottom");
     }
 
     // DOWN(T1, T2) where BOTTOM(T1) and BOTTOM(T2) =
@@ -328,26 +278,39 @@
       for (String t2 in bottomPredicateEnumeration.keys) {
         String typeParameters = joinTypeParameters(
             bottomPredicateEnumeration[t1], bottomPredicateEnumeration[t2]);
-        String expected = env.morebottom(
-                toType(t1, typeParameters: typeParameters),
-                toType(t2, typeParameters: typeParameters))
-            ? t1
-            : t2;
-        testLower(t1, t2, expected, typeParameters: typeParameters);
+        typeParserEnvironment.withTypeParameters(typeParameters, (_) {
+          String expected =
+              typeSchemaEnvironment.morebottom(parseType(t1), parseType(t2))
+                  ? t1
+                  : t2;
+          checkLowerBound(
+              type1: t1,
+              type2: t2,
+              lowerBound: expected,
+              typeParameters: typeParameters);
+        });
       }
     }
 
     // DOWN(T1, T2) = T2 if BOTTOM(T2)
     for (String type in ["A*", "A?", "A"]) {
       for (String t2 in bottomPredicateEnumeration.keys) {
-        testLower(type, t2, t2, typeParameters: bottomPredicateEnumeration[t2]);
+        checkLowerBound(
+            type1: type,
+            type2: t2,
+            lowerBound: t2,
+            typeParameters: bottomPredicateEnumeration[t2]);
       }
     }
 
     // DOWN(T1, T2) = T1 if BOTTOM(T1)
     for (String t1 in bottomPredicateEnumeration.keys) {
       for (String type in ["A*", "A?", "A"]) {
-        testLower(t1, type, t1, typeParameters: bottomPredicateEnumeration[t1]);
+        checkLowerBound(
+            type1: t1,
+            type2: type,
+            lowerBound: t1,
+            typeParameters: bottomPredicateEnumeration[t1]);
       }
     }
 
@@ -358,12 +321,17 @@
       for (String t2 in nullPredicateEnumeration.keys) {
         String typeParameters = joinTypeParameters(
             nullPredicateEnumeration[t1], nullPredicateEnumeration[t2]);
-        String expected = env.morebottom(
-                toType(t1, typeParameters: typeParameters),
-                toType(t2, typeParameters: typeParameters))
-            ? t1
-            : t2;
-        testLower(t1, t2, expected, typeParameters: typeParameters);
+        typeParserEnvironment.withTypeParameters(typeParameters, (_) {
+          String expected =
+              typeSchemaEnvironment.morebottom(parseType(t1), parseType(t2))
+                  ? t1
+                  : t2;
+          checkLowerBound(
+              type1: t1,
+              type2: t2,
+              lowerBound: expected,
+              typeParameters: typeParameters);
+        });
       }
     }
 
@@ -371,167 +339,264 @@
     //   Null if Null <: T2
     //   Never otherwise
     for (String t1 in nullPredicateEnumeration.keys) {
-      testLower(t1, "A*", t1, typeParameters: nullPredicateEnumeration[t1]);
-      testLower(t1, "A?", t1, typeParameters: nullPredicateEnumeration[t1]);
-      testLower(t1, "A", "Never", typeParameters: nullPredicateEnumeration[t1]);
+      checkLowerBound(
+          type1: t1,
+          type2: "A*",
+          lowerBound: t1,
+          typeParameters: nullPredicateEnumeration[t1]);
+      checkLowerBound(
+          type1: t1,
+          type2: "A?",
+          lowerBound: t1,
+          typeParameters: nullPredicateEnumeration[t1]);
+      checkLowerBound(
+          type1: t1,
+          type2: "A",
+          lowerBound: "Never",
+          typeParameters: nullPredicateEnumeration[t1]);
     }
 
     // DOWN(T1, Null) =
     //   Null if Null <: T1
     //   Never otherwise
     for (String t2 in nullPredicateEnumeration.keys) {
-      testLower("A*", t2, t2, typeParameters: nullPredicateEnumeration[t2]);
-      testLower("A?", t2, t2, typeParameters: nullPredicateEnumeration[t2]);
-      testLower("A", t2, "Never", typeParameters: nullPredicateEnumeration[t2]);
+      checkLowerBound(
+          type1: "A*",
+          type2: t2,
+          lowerBound: t2,
+          typeParameters: nullPredicateEnumeration[t2]);
+      checkLowerBound(
+          type1: "A?",
+          type2: t2,
+          lowerBound: t2,
+          typeParameters: nullPredicateEnumeration[t2]);
+      checkLowerBound(
+          type1: "A",
+          type2: t2,
+          lowerBound: "Never",
+          typeParameters: nullPredicateEnumeration[t2]);
     }
   }
 
   void test_lower_bound_object() {
-    _initialize("");
+    parseTestLibrary("");
 
-    testLower("Object", "FutureOr<Null>", "FutureOr<Never>");
-    testLower("FutureOr<Null>", "Object", "FutureOr<Never>");
+    checkLowerBound(
+        type1: "Object",
+        type2: "FutureOr<Null>",
+        lowerBound: "FutureOr<Never>");
+    checkLowerBound(
+        type1: "FutureOr<Null>",
+        type2: "Object",
+        lowerBound: "FutureOr<Never>");
 
     // FutureOr<dynamic> is top.
-    testLower("Object", "FutureOr<dynamic>", "Object");
-    testLower("FutureOr<dynamic>", "Object", "Object");
+    checkLowerBound(
+        type1: "Object", type2: "FutureOr<dynamic>", lowerBound: "Object");
+    checkLowerBound(
+        type1: "FutureOr<dynamic>", type2: "Object", lowerBound: "Object");
 
     // FutureOr<X> is not top and cannot be made non-nullable.
-    testLower("Object", "FutureOr<X>", "Never",
+    checkLowerBound(
+        type1: "Object",
+        type2: "FutureOr<X>",
+        lowerBound: "Never",
         typeParameters: 'X extends dynamic');
-    testLower("FutureOr<X>", "Object", "Never",
+    checkLowerBound(
+        type1: "FutureOr<X>",
+        type2: "Object",
+        lowerBound: "Never",
         typeParameters: 'X extends dynamic');
 
     // FutureOr<void> is top.
-    testLower("Object", "FutureOr<void>", "Object");
-    testLower("FutureOr<void>", "Object", "Object");
+    checkLowerBound(
+        type1: "Object", type2: "FutureOr<void>", lowerBound: "Object");
+    checkLowerBound(
+        type1: "FutureOr<void>", type2: "Object", lowerBound: "Object");
   }
 
   void test_lower_bound_function() {
-    const String testSdk = """
+    parseTestLibrary("""
       class A;
       class B extends A;
-    """;
-    _initialize(testSdk);
+    """);
 
     // TODO(dmitryas): Test for various nullabilities.
-    testLower("() ->* A*", "() ->* B*", "() ->* B*");
-    testLower("() ->* void", "(A*, B*) ->* void", "([A*, B*]) ->* void");
-    testLower("(A*, B*) ->* void", "() ->* void", "([A*, B*]) ->* void");
-    testLower("(A*) ->* void", "(B*) ->* void", "(A*) ->* void");
-    testLower("(B*) ->* void", "(A*) ->* void", "(A*) ->* void");
-    testLower(
-        "({A* a}) ->* void", "({B* b}) ->* void", "({A* a, B* b}) ->* void");
-    testLower(
-        "({B* b}) ->* void", "({A* a}) ->* void", "({A* a, B* b}) ->* void");
-    testLower("({A* a, A* c}) ->* void", "({B* b, B* d}) ->* void",
-        "({A* a, B* b, A* c, B* d}) ->* void");
-    testLower("({A* a, B* b}) ->* void", "({B* a, A* b}) ->* void",
-        "({A* a, A* b}) ->* void");
-    testLower("({B* a, A* b}) ->* void", "({A* a, B* b}) ->* void",
-        "({A* a, A* b}) ->* void");
-    testLower(
-        "(B*, {A* a}) ->* void", "(B*) ->* void", "(B*, {A* a}) ->* void");
-    testLower("({A* a}) -> void", "(B*) -> void", "Never");
-    testLower("({A* a}) -> void", "([B*]) ->* void", "Never");
-    testLower("<X>() -> void", "<Y>() -> void", "<Z>() -> void");
-    testLower("<X>(X) -> List<X>", "<Y>(Y) -> List<Y>", "<Z>(Z) -> List<Z>");
-    testLower(
-        "<X1, X2 extends List<X1>>(X1) -> X2",
-        "<Y1, Y2 extends List<Y1>>(Y1) -> Y2",
-        "<Z1, Z2 extends List<Z1>>(Z1) -> Z2");
-    testLower(
-        "<X extends int>(X) -> void", "<Y extends double>(Y) -> void", "Never");
+    checkLowerBound(
+        type1: "() ->* A*", type2: "() ->* B*", lowerBound: "() ->* B*");
+    checkLowerBound(
+        type1: "() ->* void",
+        type2: "(A*, B*) ->* void",
+        lowerBound: "([A*, B*]) ->* void");
+    checkLowerBound(
+        type1: "(A*, B*) ->* void",
+        type2: "() ->* void",
+        lowerBound: "([A*, B*]) ->* void");
+    checkLowerBound(
+        type1: "(A*) ->* void",
+        type2: "(B*) ->* void",
+        lowerBound: "(A*) ->* void");
+    checkLowerBound(
+        type1: "(B*) ->* void",
+        type2: "(A*) ->* void",
+        lowerBound: "(A*) ->* void");
+    checkLowerBound(
+        type1: "({A* a}) ->* void",
+        type2: "({B* b}) ->* void",
+        lowerBound: "({A* a, B* b}) ->* void");
+    checkLowerBound(
+        type1: "({B* b}) ->* void",
+        type2: "({A* a}) ->* void",
+        lowerBound: "({A* a, B* b}) ->* void");
+    checkLowerBound(
+        type1: "({A* a, A* c}) ->* void",
+        type2: "({B* b, B* d}) ->* void",
+        lowerBound: "({A* a, B* b, A* c, B* d}) ->* void");
+    checkLowerBound(
+        type1: "({A* a, B* b}) ->* void",
+        type2: "({B* a, A* b}) ->* void",
+        lowerBound: "({A* a, A* b}) ->* void");
+    checkLowerBound(
+        type1: "({B* a, A* b}) ->* void",
+        type2: "({A* a, B* b}) ->* void",
+        lowerBound: "({A* a, A* b}) ->* void");
+    checkLowerBound(
+        type1: "(B*, {A* a}) ->* void",
+        type2: "(B*) ->* void",
+        lowerBound: "(B*, {A* a}) ->* void");
+    checkLowerBound(
+        type1: "({A* a}) -> void", type2: "(B*) -> void", lowerBound: "Never");
+    checkLowerBound(
+        type1: "({A* a}) -> void",
+        type2: "([B*]) ->* void",
+        lowerBound: "Never");
+    checkLowerBound(
+        type1: "<X>() -> void",
+        type2: "<Y>() -> void",
+        lowerBound: "<Z>() -> void");
+    checkLowerBound(
+        type1: "<X>(X) -> List<X>",
+        type2: "<Y>(Y) -> List<Y>",
+        lowerBound: "<Z>(Z) -> List<Z>");
+    checkLowerBound(
+        type1: "<X1, X2 extends List<X1>>(X1) -> X2",
+        type2: "<Y1, Y2 extends List<Y1>>(Y1) -> Y2",
+        lowerBound: "<Z1, Z2 extends List<Z1>>(Z1) -> Z2");
+    checkLowerBound(
+        type1: "<X extends int>(X) -> void",
+        type2: "<Y extends double>(Y) -> void",
+        lowerBound: "Never");
 
-    testLower(
-        "({required A a, A b, required A c, A d, required A e}) -> A",
-        "({required B a, required B b, B c, B f, required B g}) -> B",
-        "({required A a, A b, A c, A d, A e, B f, B g}) -> B");
+    checkLowerBound(
+        type1: "({required A a, A b, required A c, A d, required A e}) -> A",
+        type2: "({required B a, required B b, B c, B f, required B g}) -> B",
+        lowerBound: "({required A a, A b, A c, A d, A e, B f, B g}) -> B");
 
-    testLower("<X extends dynamic>() -> void", "<Y extends Object?>() -> void",
-        "<Z extends dynamic>() -> void");
-    testLower("<X extends Null>() -> void", "<Y extends Never?>() -> void",
-        "<Z extends Null>() -> void");
-    testLower(
-        "<X extends FutureOr<dynamic>?>() -> void",
-        "<Y extends FutureOr<Object?>>() -> void",
-        "<Z extends FutureOr<dynamic>?>() -> void");
+    checkLowerBound(
+        type1: "<X extends dynamic>() -> void",
+        type2: "<Y extends Object?>() -> void",
+        lowerBound: "<Z extends dynamic>() -> void");
+    checkLowerBound(
+        type1: "<X extends Null>() -> void",
+        type2: "<Y extends Never?>() -> void",
+        lowerBound: "<Z extends Null>() -> void");
+    checkLowerBound(
+        type1: "<X extends FutureOr<dynamic>?>() -> void",
+        type2: "<Y extends FutureOr<Object?>>() -> void",
+        lowerBound: "<Z extends FutureOr<dynamic>?>() -> void");
   }
 
   void test_lower_bound_identical() {
-    _initialize("class A;");
+    parseTestLibrary("class A;");
 
-    testLower("A*", "A*", "A*");
-    testLower("A?", "A?", "A?");
-    testLower("A", "A", "A");
+    checkLowerBound(type1: "A*", type2: "A*", lowerBound: "A*");
+    checkLowerBound(type1: "A?", type2: "A?", lowerBound: "A?");
+    checkLowerBound(type1: "A", type2: "A", lowerBound: "A");
   }
 
   void test_lower_bound_subtype() {
-    const String testSdk = """
+    parseTestLibrary("""
       class A;
       class B extends A;
-    """;
-    _initialize(testSdk);
+    """);
 
-    testLower("A*", "B*", "B*");
-    testLower("A*", "B?", "B*");
-    testLower("A*", "B", "B");
+    checkLowerBound(type1: "A*", type2: "B*", lowerBound: "B*");
+    checkLowerBound(type1: "A*", type2: "B?", lowerBound: "B*");
+    checkLowerBound(type1: "A*", type2: "B", lowerBound: "B");
 
-    testLower("A?", "B*", "B*");
-    testLower("A?", "B?", "B?");
-    testLower("A?", "B", "B");
+    checkLowerBound(type1: "A?", type2: "B*", lowerBound: "B*");
+    checkLowerBound(type1: "A?", type2: "B?", lowerBound: "B?");
+    checkLowerBound(type1: "A?", type2: "B", lowerBound: "B");
 
-    testLower("A", "B*", "B");
-    testLower("A", "B?", "B");
-    testLower("A", "B", "B");
+    checkLowerBound(type1: "A", type2: "B*", lowerBound: "B");
+    checkLowerBound(type1: "A", type2: "B?", lowerBound: "B");
+    checkLowerBound(type1: "A", type2: "B", lowerBound: "B");
 
-    testLower("B*", "A*", "B*");
-    testLower("B?", "A*", "B*");
-    testLower("B", "A*", "B");
+    checkLowerBound(type1: "B*", type2: "A*", lowerBound: "B*");
+    checkLowerBound(type1: "B?", type2: "A*", lowerBound: "B*");
+    checkLowerBound(type1: "B", type2: "A*", lowerBound: "B");
 
-    testLower("B*", "A?", "B*");
-    testLower("B?", "A?", "B?");
-    testLower("B", "A?", "B");
+    checkLowerBound(type1: "B*", type2: "A?", lowerBound: "B*");
+    checkLowerBound(type1: "B?", type2: "A?", lowerBound: "B?");
+    checkLowerBound(type1: "B", type2: "A?", lowerBound: "B");
 
-    testLower("B*", "A", "B");
-    testLower("B?", "A", "B");
-    testLower("B", "A", "B");
+    checkLowerBound(type1: "B*", type2: "A", lowerBound: "B");
+    checkLowerBound(type1: "B?", type2: "A", lowerBound: "B");
+    checkLowerBound(type1: "B", type2: "A", lowerBound: "B");
 
-    testLower("Iterable<A>*", "List<B>*", "List<B>*");
-    testLower("Iterable<A>*", "List<B>?", "List<B>*");
-    testLower("Iterable<A>*", "List<B>", "List<B>");
+    checkLowerBound(
+        type1: "Iterable<A>*", type2: "List<B>*", lowerBound: "List<B>*");
+    checkLowerBound(
+        type1: "Iterable<A>*", type2: "List<B>?", lowerBound: "List<B>*");
+    checkLowerBound(
+        type1: "Iterable<A>*", type2: "List<B>", lowerBound: "List<B>");
 
-    testLower("Iterable<A>?", "List<B>*", "List<B>*");
-    testLower("Iterable<A>?", "List<B>?", "List<B>?");
-    testLower("Iterable<A>?", "List<B>", "List<B>");
+    checkLowerBound(
+        type1: "Iterable<A>?", type2: "List<B>*", lowerBound: "List<B>*");
+    checkLowerBound(
+        type1: "Iterable<A>?", type2: "List<B>?", lowerBound: "List<B>?");
+    checkLowerBound(
+        type1: "Iterable<A>?", type2: "List<B>", lowerBound: "List<B>");
 
-    testLower("Iterable<A>", "List<B>*", "List<B>");
-    testLower("Iterable<A>", "List<B>?", "List<B>");
-    testLower("Iterable<A>", "List<B>", "List<B>");
+    checkLowerBound(
+        type1: "Iterable<A>", type2: "List<B>*", lowerBound: "List<B>");
+    checkLowerBound(
+        type1: "Iterable<A>", type2: "List<B>?", lowerBound: "List<B>");
+    checkLowerBound(
+        type1: "Iterable<A>", type2: "List<B>", lowerBound: "List<B>");
 
-    testLower("List<B>*", "Iterable<A>*", "List<B>*");
-    testLower("List<B>?", "Iterable<A>*", "List<B>*");
-    testLower("List<B>", "Iterable<A>*", "List<B>");
+    checkLowerBound(
+        type1: "List<B>*", type2: "Iterable<A>*", lowerBound: "List<B>*");
+    checkLowerBound(
+        type1: "List<B>?", type2: "Iterable<A>*", lowerBound: "List<B>*");
+    checkLowerBound(
+        type1: "List<B>", type2: "Iterable<A>*", lowerBound: "List<B>");
 
-    testLower("List<B>*", "Iterable<A>?", "List<B>*");
-    testLower("List<B>?", "Iterable<A>?", "List<B>?");
-    testLower("List<B>", "Iterable<A>?", "List<B>");
+    checkLowerBound(
+        type1: "List<B>*", type2: "Iterable<A>?", lowerBound: "List<B>*");
+    checkLowerBound(
+        type1: "List<B>?", type2: "Iterable<A>?", lowerBound: "List<B>?");
+    checkLowerBound(
+        type1: "List<B>", type2: "Iterable<A>?", lowerBound: "List<B>");
 
-    testLower("List<B>*", "Iterable<A>", "List<B>");
-    testLower("List<B>?", "Iterable<A>", "List<B>");
-    testLower("List<B>", "Iterable<A>", "List<B>");
+    checkLowerBound(
+        type1: "List<B>*", type2: "Iterable<A>", lowerBound: "List<B>");
+    checkLowerBound(
+        type1: "List<B>?", type2: "Iterable<A>", lowerBound: "List<B>");
+    checkLowerBound(
+        type1: "List<B>", type2: "Iterable<A>", lowerBound: "List<B>");
   }
 
   void test_lower_bound_top() {
-    _initialize("class A;");
+    parseTestLibrary("class A;");
 
     // TODO(dmitryas): Test for various nullabilities.
-    testLower("dynamic", "A*", "A*");
-    testLower("A*", "dynamic", "A*");
-    testLower("Object?", "A*", "A*");
-    testLower("A*", "Object?", "A*");
-    testLower("void", "A*", "A*");
-    testLower("A*", "void", "A*");
+    checkLowerBound(type1: "dynamic", type2: "A*", lowerBound: "A*");
+    checkLowerBound(type1: "A*", type2: "dynamic", lowerBound: "A*");
+    checkLowerBound(type1: "Object?", type2: "A*", lowerBound: "A*");
+    checkLowerBound(type1: "A*", type2: "Object?", lowerBound: "A*");
+    checkLowerBound(type1: "void", type2: "A*", lowerBound: "A*");
+    checkLowerBound(type1: "A*", type2: "void", lowerBound: "A*");
 
     // DOWN(T1, T2) where TOP(T1) and TOP(T2) =
     //   T1 if MORETOP(T2, T1)
@@ -540,225 +605,208 @@
       for (String t2 in topPredicateEnumeration.keys) {
         String typeParameters = joinTypeParameters(
             topPredicateEnumeration[t1], topPredicateEnumeration[t2]);
-        String expected = env.moretop(
-                toType(t2, typeParameters: typeParameters),
-                toType(t1, typeParameters: typeParameters))
-            ? t1
-            : t2;
-        testLower(t1, t2, expected, typeParameters: typeParameters);
+        typeParserEnvironment.withTypeParameters(typeParameters, (_) {
+          String expected =
+              typeSchemaEnvironment.moretop(parseType(t2), parseType(t1))
+                  ? t1
+                  : t2;
+          checkLowerBound(
+              type1: t1,
+              type2: t2,
+              lowerBound: expected,
+              typeParameters: typeParameters);
+        });
       }
     }
 
     // DOWN(T1, T2) = T2 if TOP(T1)
     for (String t1 in topPredicateEnumeration.keys) {
-      testLower(t1, "A*", "A*", typeParameters: topPredicateEnumeration[t1]);
+      checkLowerBound(
+          type1: t1,
+          type2: "A*",
+          lowerBound: "A*",
+          typeParameters: topPredicateEnumeration[t1]);
     }
 
     // DOWN(T1, T2) = T1 if TOP(T2)
     for (String t2 in topPredicateEnumeration.keys) {
-      testLower("A*", t2, "A*", typeParameters: topPredicateEnumeration[t2]);
+      checkLowerBound(
+          type1: "A*",
+          type2: t2,
+          lowerBound: "A*",
+          typeParameters: topPredicateEnumeration[t2]);
     }
   }
 
   void test_lower_bound_unknown() {
-    _initialize("class A;");
+    parseTestLibrary("class A;");
 
-    testLower("A*", "unknown", "A*");
-    testLower("A?", "unknown", "A?");
-    testLower("A", "unknown", "A");
+    checkLowerBound(type1: "A*", type2: "UNKNOWN", lowerBound: "A*");
+    checkLowerBound(type1: "A?", type2: "UNKNOWN", lowerBound: "A?");
+    checkLowerBound(type1: "A", type2: "UNKNOWN", lowerBound: "A");
 
-    testLower("unknown", "A*", "A*");
-    testLower("unknown", "A?", "A?");
-    testLower("unknown", "A", "A");
+    checkLowerBound(type1: "UNKNOWN", type2: "A*", lowerBound: "A*");
+    checkLowerBound(type1: "UNKNOWN", type2: "A?", lowerBound: "A?");
+    checkLowerBound(type1: "UNKNOWN", type2: "A", lowerBound: "A");
   }
 
   void test_lower_bound_unrelated() {
-    const String testSdk = """
+    parseTestLibrary("""
       class A;
       class B;
-    """;
-    _initialize(testSdk);
+    """);
 
-    testLower("A*", "B*", "Never*");
-    testLower("A*", "B?", "Never*");
-    testLower("A*", "B", "Never");
+    checkLowerBound(type1: "A*", type2: "B*", lowerBound: "Never*");
+    checkLowerBound(type1: "A*", type2: "B?", lowerBound: "Never*");
+    checkLowerBound(type1: "A*", type2: "B", lowerBound: "Never");
 
-    testLower("A?", "B*", "Never*");
-    testLower("A?", "B?", "Never?");
-    testLower("A?", "B", "Never");
+    checkLowerBound(type1: "A?", type2: "B*", lowerBound: "Never*");
+    checkLowerBound(type1: "A?", type2: "B?", lowerBound: "Never?");
+    checkLowerBound(type1: "A?", type2: "B", lowerBound: "Never");
 
-    testLower("A", "B*", "Never");
-    testLower("A", "B?", "Never");
-    testLower("A", "B", "Never");
+    checkLowerBound(type1: "A", type2: "B*", lowerBound: "Never");
+    checkLowerBound(type1: "A", type2: "B?", lowerBound: "Never");
+    checkLowerBound(type1: "A", type2: "B", lowerBound: "Never");
   }
 
   void test_inferGenericFunctionOrType() {
-    _initialize("");
+    parseTestLibrary("");
 
     // TODO(dmitryas): Test for various nullabilities.
-    InterfaceType listClassThisType =
-        coreTypes.thisInterfaceType(listClass, testLib.nonNullable);
-    {
-      // Test an instantiation of [1, 2.0] with no context.  This should infer
-      // as List<?> during downwards inference.
-      List<DartType> inferredTypes = <DartType>[new UnknownType()];
-      TypeParameterType T = listClassThisType.typeArguments[0];
-      env.inferGenericFunctionOrType(listClassThisType, [T.parameter], null,
-          null, null, inferredTypes, testLib);
-      expect(inferredTypes[0], new UnknownType());
-      // And upwards inference should refine it to List<num>.
-      env.inferGenericFunctionOrType(
-          listClassThisType,
-          [T.parameter],
-          [T, T],
-          [coreTypes.intNonNullableRawType, coreTypes.doubleNonNullableRawType],
-          null,
-          inferredTypes,
-          testLib);
-      expect(inferredTypes[0], coreTypes.numNonNullableRawType);
-    }
-    {
-      // Test an instantiation of [1, 2.0] with a context of List<Object>.  This
-      // should infer as List<Object> during downwards inference.
-      List<DartType> inferredTypes = <DartType>[new UnknownType()];
-      TypeParameterType T = listClassThisType.typeArguments[0];
-      env.inferGenericFunctionOrType(
-          listClassThisType,
-          [T.parameter],
-          null,
-          null,
-          _list(coreTypes.objectNonNullableRawType),
-          inferredTypes,
-          testLib);
-      expect(inferredTypes[0], coreTypes.objectNonNullableRawType);
-      // And upwards inference should preserve the type.
-      env.inferGenericFunctionOrType(
-          listClassThisType,
-          [T.parameter],
-          [T, T],
-          [coreTypes.intNonNullableRawType, coreTypes.doubleNonNullableRawType],
-          _list(coreTypes.objectNonNullableRawType),
-          inferredTypes,
-          testLib);
-      expect(inferredTypes[0], coreTypes.objectNonNullableRawType);
-    }
-    {
-      // Test an instantiation of [1, 2.0, null] with no context.  This should
-      // infer as List<?> during downwards inference.
-      List<DartType> inferredTypes = <DartType>[new UnknownType()];
-      TypeParameterType T = listClassThisType.typeArguments[0];
-      env.inferGenericFunctionOrType(listClassThisType, [T.parameter], null,
-          null, null, inferredTypes, testLib);
-      expect(inferredTypes[0], new UnknownType());
-      // And upwards inference should refine it to List<num?>.
-      env.inferGenericFunctionOrType(
-          listClassThisType,
-          [T.parameter],
-          [T, T, T],
-          [
-            coreTypes.intNonNullableRawType,
-            coreTypes.doubleNonNullableRawType,
-            const NullType()
-          ],
-          null,
-          inferredTypes,
-          testLib);
-      expect(inferredTypes[0], coreTypes.numNullableRawType);
-    }
-    {
-      // Test an instantiation of legacy [1, 2.0] with no context.
-      // This should infer as List<?> during downwards inference.
-      List<DartType> inferredTypes = <DartType>[new UnknownType()];
-      TypeParameterType T = listClassThisType.typeArguments[0];
-      env.inferGenericFunctionOrType(listClassThisType, [T.parameter], null,
-          null, null, inferredTypes, testLib);
-      expect(inferredTypes[0], new UnknownType());
-      // And upwards inference should refine it to List<num!>.
-      env.inferGenericFunctionOrType(
-          listClassThisType,
-          [T.parameter],
-          [T, T],
-          [coreTypes.intLegacyRawType, coreTypes.doubleLegacyRawType],
-          null,
-          inferredTypes,
-          testLib);
-      expect(inferredTypes[0], coreTypes.numLegacyRawType);
-    }
+
+    // Test an instantiation of [1, 2.0] with no context.  This should infer
+    // as List<?> during downwards inference.
+    checkInference(
+        typeParametersToInfer: "T extends Object?",
+        functionType: "(T, T) -> List<T>",
+        actualParameterTypes: null,
+        returnContextType: null,
+        expectedTypes: "UNKNOWN");
+    // And upwards inference should refine it to List<num>.
+    checkInference(
+        typeParametersToInfer: "T extends Object?",
+        functionType: "(T, T) -> List<T>",
+        actualParameterTypes: "int, double",
+        returnContextType: null,
+        inferredTypesFromDownwardPhase: "UNKNOWN",
+        expectedTypes: "num");
+
+    // Test an instantiation of [1, 2.0] with a context of List<Object>.  This
+    // should infer as List<Object> during downwards inference.
+    checkInference(
+        typeParametersToInfer: "T extends Object?",
+        functionType: "(T, T) -> List<T>",
+        actualParameterTypes: null,
+        returnContextType: "List<Object>",
+        expectedTypes: "Object");
+    // And upwards inference should preserve the type.
+    checkInference(
+        typeParametersToInfer: "T extends Object?",
+        functionType: "(T, T) -> List<T>",
+        actualParameterTypes: "int, double",
+        returnContextType: "List<Object>",
+        inferredTypesFromDownwardPhase: "Object",
+        expectedTypes: "Object");
+
+    // Test an instantiation of [1, 2.0, null] with no context.  This should
+    // infer as List<?> during downwards inference.
+    checkInference(
+        typeParametersToInfer: "T extends Object?",
+        functionType: "(T, T, T) -> List<T>",
+        actualParameterTypes: null,
+        returnContextType: null,
+        expectedTypes: "UNKNOWN");
+    // And upwards inference should refine it to List<num?>.
+    checkInference(
+        typeParametersToInfer: "T extends Object?",
+        functionType: "(T, T, T) -> List<T>",
+        actualParameterTypes: "int, double, Null",
+        returnContextType: null,
+        inferredTypesFromDownwardPhase: "UNKNOWN",
+        expectedTypes: "num?");
+
+    // Test an instantiation of legacy [1, 2.0] with no context.
+    // This should infer as List<?> during downwards inference.
+    checkInference(
+        typeParametersToInfer: "T extends Object?",
+        functionType: "(T, T) -> List<T>",
+        actualParameterTypes: null,
+        returnContextType: null,
+        expectedTypes: "UNKNOWN");
+    checkInference(
+        typeParametersToInfer: "T extends Object?",
+        functionType: "(T, T) -> List<T>",
+        actualParameterTypes: "int*, double*",
+        returnContextType: null,
+        inferredTypesFromDownwardPhase: "UNKNOWN",
+        expectedTypes: "num");
   }
 
   void test_inferTypeFromConstraints_applyBound() {
-    _initialize("");
+    parseTestLibrary("");
 
-    // class A<T extends num*> {}
-    TypeParameter T = new TypeParameter("T", coreTypes.numLegacyRawType);
+    // Assuming: class A<T extends num*> {}
 
     // TODO(dmitryas): Test for various nullabilities.
-    {
-      // With no constraints:
-      Map<TypeParameter, TypeConstraint> constraints = {
-        T: new TypeConstraint()
-      };
 
-      // Downward inference should infer A<?>
-      List<DartType> inferredTypes = <DartType>[new UnknownType()];
-      env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib,
-          downwardsInferPhase: true);
-      expect(inferredTypes[0], new UnknownType());
+    // With no constraints:
+    // Downward inference should infer A<?>
+    checkInferenceFromConstraints(
+        typeParameter: "T extends num*",
+        constraints: "",
+        downwardsInferPhase: true,
+        expected: "UNKNOWN");
+    // Upward inference should infer A<num*>
+    checkInferenceFromConstraints(
+        typeParameter: "T extends num*",
+        constraints: "",
+        downwardsInferPhase: false,
+        inferredTypeFromDownwardPhase: "UNKNOWN",
+        expected: "num*");
 
-      // Upward inference should infer A<num*>
-      env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib);
-      expect(inferredTypes[0], coreTypes.numLegacyRawType);
-    }
-    {
-      // With an upper bound of Object*:
-      Map<TypeParameter, TypeConstraint> constraints = {
-        T: _makeConstraint(upper: coreTypes.objectLegacyRawType)
-      };
-
-      // Downward inference should infer A<num*>
-      List<DartType> inferredTypes = <DartType>[new UnknownType()];
-      env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib,
-          downwardsInferPhase: true);
-      expect(inferredTypes[0], coreTypes.numLegacyRawType);
-
-      // Upward inference should infer A<num*>
-      env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib);
-      expect(inferredTypes[0], coreTypes.numLegacyRawType);
-
-      // Upward inference should still infer A<num*> even if there are more
-      // constraints now, because num was finalized during downward inference.
-      constraints = {
-        T: _makeConstraint(
-            lower: coreTypes.intLegacyRawType,
-            upper: coreTypes.intLegacyRawType)
-      };
-      env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib);
-      expect(inferredTypes[0], coreTypes.numLegacyRawType);
-    }
+    // With an upper bound of Object*:
+    // Downward inference should infer A<num*>
+    checkInferenceFromConstraints(
+        typeParameter: "T extends num*",
+        constraints: "<: Object*",
+        downwardsInferPhase: true,
+        expected: "num*");
+    // Upward inference should infer A<num*>
+    checkInferenceFromConstraints(
+        typeParameter: "T extends num*",
+        constraints: "<: Object*",
+        downwardsInferPhase: false,
+        inferredTypeFromDownwardPhase: "num*",
+        expected: "num*");
+    // Upward inference should still infer A<num*> even if there are more
+    // constraints now, because num was finalized during downward inference.
+    checkInferenceFromConstraints(
+        typeParameter: "T extends num*",
+        constraints: ":> int* <: int*",
+        downwardsInferPhase: false,
+        inferredTypeFromDownwardPhase: "num*",
+        expected: "num*");
   }
 
   void test_inferTypeFromConstraints_simple() {
-    _initialize("");
-
-    TypeParameter T = listClass.typeParameters[0];
+    parseTestLibrary("");
 
     // TODO(dmitryas): Test for various nullabilities.
 
     // With an upper bound of List<?>*:
-    Map<TypeParameter, TypeConstraint> constraints = {
-      T: _makeConstraint(upper: _list(new UnknownType()))
-    };
-
     // Downwards inference should infer List<List<?>*>*
-    List<DartType> inferredTypes = <DartType>[new UnknownType()];
-    env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib,
-        downwardsInferPhase: true);
-    expect(inferredTypes[0], _list(new UnknownType()));
-
-    // Upwards inference should refine that to List<List<dynamic>*>*
-    env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib);
-    expect(inferredTypes[0],
-        _list(new InterfaceType(objectClass, Nullability.nullable)));
+    checkInferenceFromConstraints(
+        typeParameter: "T extends Object?",
+        constraints: "<: List<UNKNOWN>",
+        downwardsInferPhase: true,
+        expected: "List<UNKNOWN>");
+    // Upwards inference should refine that to List<List<Object?>*>*
+    checkInferenceFromConstraints(
+        typeParameter: "T extends Object?",
+        constraints: "<: List<UNKNOWN>",
+        downwardsInferPhase: false,
+        inferredTypeFromDownwardPhase: "List<UNKNOWN>",
+        expected: "List<Object?>");
   }
 
   void test_upper_bound_classic() {
@@ -771,7 +819,7 @@
     // B C K
     // |X| |
     // D E L
-    const String testSdk = """
+    parseTestLibrary("""
       class A;
       class B implements A;
       class C implements A;
@@ -779,180 +827,276 @@
       class D implements B, C;
       class E implements B, C;
       class L implements K;
-    """;
-    _initialize(testSdk);
+    """);
 
     // TODO(dmitryas): Test for various nullabilities.
-    testUpper("B*", "E*", "B*");
-    testUpper("D*", "C*", "C*");
-    testUpper("D*", "E*", "A*");
-    testUpper("D*", "A*", "A*");
-    testUpper("B*", "K*", "A*");
-    testUpper("B*", "L*", "A*");
+    checkUpperBound(type1: "B*", type2: "E*", upperBound: "B*");
+    checkUpperBound(type1: "D*", type2: "C*", upperBound: "C*");
+    checkUpperBound(type1: "D*", type2: "E*", upperBound: "A*");
+    checkUpperBound(type1: "D*", type2: "A*", upperBound: "A*");
+    checkUpperBound(type1: "B*", type2: "K*", upperBound: "A*");
+    checkUpperBound(type1: "B*", type2: "L*", upperBound: "A*");
   }
 
   void test_upper_bound_commonClass() {
-    _initialize("");
+    parseTestLibrary("");
 
-    testUpper("List<int*>", "List<double*>", "List<num*>");
-    testUpper("List<int?>", "List<double>", "List<num?>");
+    checkUpperBound(
+        type1: "List<int*>", type2: "List<double*>", upperBound: "List<num*>");
+    checkUpperBound(
+        type1: "List<int?>", type2: "List<double>", upperBound: "List<num?>");
   }
 
   void test_upper_bound_object() {
-    _initialize("");
+    parseTestLibrary("");
 
-    testUpper("Object", "FutureOr<Function?>", "Object?");
-    testUpper("FutureOr<Function?>", "Object", "Object?");
+    checkUpperBound(
+        type1: "Object", type2: "FutureOr<Function?>", upperBound: "Object?");
+    checkUpperBound(
+        type1: "FutureOr<Function?>", type2: "Object", upperBound: "Object?");
   }
 
   void test_upper_bound_function() {
-    const String testSdk = """
+    parseTestLibrary("""
       class A;
       class B extends A;
-    """;
-    _initialize(testSdk);
+    """);
 
-    testUpper("() ->? A", "() -> B?", "() ->? A?");
-    testUpper("([A*]) ->* void", "(A*) ->* void", "Function*");
-    testUpper("() ->* void", "(A*, B*) ->* void", "Function*");
-    testUpper("(A*, B*) ->* void", "() ->* void", "Function*");
-    testUpper("(A*) ->* void", "(B*) ->* void", "(B*) ->* void");
-    testUpper("(B*) ->* void", "(A*) ->* void", "(B*) ->* void");
-    testUpper("({A* a}) ->* void", "({B* b}) ->* void", "() ->* void");
-    testUpper("({B* b}) ->* void", "({A* a}) ->* void", "() ->* void");
-    testUpper(
-        "({A* a, A* c}) ->* void", "({B* b, B* d}) ->* void", "() ->* void");
-    testUpper("({A* a, B* b}) ->* void", "({B* a, A* b}) ->* void",
-        "({B* a, B* b}) ->* void");
-    testUpper("({B* a, A* b}) ->* void", "({A* a, B* b}) ->* void",
-        "({B* a, B* b}) ->* void");
-    testUpper("(B*, {A* a}) ->* void", "(B*) ->* void", "(B*) ->* void");
-    testUpper("({A* a}) ->* void", "(B*) ->* void", "Function*");
-    testUpper("() ->* void", "([B*]) ->* void", "() ->* void");
-    testUpper("<X>() -> void", "<Y>() -> void", "<Z>() -> void");
-    testUpper("<X>(X) -> List<X>", "<Y>(Y) -> List<Y>", "<Z>(Z) -> List<Z>");
-    testUpper(
-        "<X1, X2 extends List<X1>>(X1) -> X2",
-        "<Y1, Y2 extends List<Y1>>(Y1) -> Y2",
-        "<Z1, Z2 extends List<Z1>>(Z1) -> Z2");
-    testUpper("<X extends int>() -> void", "<Y extends double>() -> void",
-        "Function");
+    checkUpperBound(
+        type1: "() ->? A", type2: "() -> B?", upperBound: "() ->? A?");
+    checkUpperBound(
+        type1: "([A*]) ->* void",
+        type2: "(A*) ->* void",
+        upperBound: "Function*");
+    checkUpperBound(
+        type1: "() ->* void",
+        type2: "(A*, B*) ->* void",
+        upperBound: "Function*");
+    checkUpperBound(
+        type1: "(A*, B*) ->* void",
+        type2: "() ->* void",
+        upperBound: "Function*");
+    checkUpperBound(
+        type1: "(A*) ->* void",
+        type2: "(B*) ->* void",
+        upperBound: "(B*) ->* void");
+    checkUpperBound(
+        type1: "(B*) ->* void",
+        type2: "(A*) ->* void",
+        upperBound: "(B*) ->* void");
+    checkUpperBound(
+        type1: "({A* a}) ->* void",
+        type2: "({B* b}) ->* void",
+        upperBound: "() ->* void");
+    checkUpperBound(
+        type1: "({B* b}) ->* void",
+        type2: "({A* a}) ->* void",
+        upperBound: "() ->* void");
+    checkUpperBound(
+        type1: "({A* a, A* c}) ->* void",
+        type2: "({B* b, B* d}) ->* void",
+        upperBound: "() ->* void");
+    checkUpperBound(
+        type1: "({A* a, B* b}) ->* void",
+        type2: "({B* a, A* b}) ->* void",
+        upperBound: "({B* a, B* b}) ->* void");
+    checkUpperBound(
+        type1: "({B* a, A* b}) ->* void",
+        type2: "({A* a, B* b}) ->* void",
+        upperBound: "({B* a, B* b}) ->* void");
+    checkUpperBound(
+        type1: "(B*, {A* a}) ->* void",
+        type2: "(B*) ->* void",
+        upperBound: "(B*) ->* void");
+    checkUpperBound(
+        type1: "({A* a}) ->* void",
+        type2: "(B*) ->* void",
+        upperBound: "Function*");
+    checkUpperBound(
+        type1: "() ->* void",
+        type2: "([B*]) ->* void",
+        upperBound: "() ->* void");
+    checkUpperBound(
+        type1: "<X>() -> void",
+        type2: "<Y>() -> void",
+        upperBound: "<Z>() -> void");
+    checkUpperBound(
+        type1: "<X>(X) -> List<X>",
+        type2: "<Y>(Y) -> List<Y>",
+        upperBound: "<Z>(Z) -> List<Z>");
+    checkUpperBound(
+        type1: "<X1, X2 extends List<X1>>(X1) -> X2",
+        type2: "<Y1, Y2 extends List<Y1>>(Y1) -> Y2",
+        upperBound: "<Z1, Z2 extends List<Z1>>(Z1) -> Z2");
+    checkUpperBound(
+        type1: "<X extends int>() -> void",
+        type2: "<Y extends double>() -> void",
+        upperBound: "Function");
 
-    testUpper("({required A a, B b}) -> A", "({B a, required A b}) -> B",
-        "({required B a, required B b}) -> A");
+    checkUpperBound(
+        type1: "({required A a, B b}) -> A",
+        type2: "({B a, required A b}) -> B",
+        upperBound: "({required B a, required B b}) -> A");
 
-    testUpper("<X extends dynamic>() -> void", "<Y extends Object?>() -> void",
-        "<Z extends dynamic>() -> void");
-    testUpper("<X extends Null>() -> void", "<Y extends Never?>() -> void",
-        "<Z extends Null>() -> void");
-    testUpper(
-        "<X extends FutureOr<dynamic>?>() -> void",
-        "<Y extends FutureOr<Object?>>() -> void",
-        "<Z extends FutureOr<dynamic>?>() -> void");
+    checkUpperBound(
+        type1: "<X extends dynamic>() -> void",
+        type2: "<Y extends Object?>() -> void",
+        upperBound: "<Z extends dynamic>() -> void");
+    checkUpperBound(
+        type1: "<X extends Null>() -> void",
+        type2: "<Y extends Never?>() -> void",
+        upperBound: "<Z extends Null>() -> void");
+    checkUpperBound(
+        type1: "<X extends FutureOr<dynamic>?>() -> void",
+        type2: "<Y extends FutureOr<Object?>>() -> void",
+        upperBound: "<Z extends FutureOr<dynamic>?>() -> void");
 
-    testUpper("([dynamic]) -> dynamic", "([dynamic]) -> dynamic",
-        "([dynamic]) -> dynamic");
+    checkUpperBound(
+        type1: "([dynamic]) -> dynamic",
+        type2: "([dynamic]) -> dynamic",
+        upperBound: "([dynamic]) -> dynamic");
   }
 
   void test_upper_bound_identical() {
-    _initialize("class A;");
+    parseTestLibrary("class A;");
 
-    testUpper("A*", "A*", "A*");
-    testUpper("A*", "A?", "A?");
-    testUpper("A*", "A", "A*");
+    checkUpperBound(type1: "A*", type2: "A*", upperBound: "A*");
+    checkUpperBound(type1: "A*", type2: "A?", upperBound: "A?");
+    checkUpperBound(type1: "A*", type2: "A", upperBound: "A*");
 
-    testUpper("A?", "A*", "A?");
-    testUpper("A?", "A?", "A?");
-    testUpper("A?", "A", "A?");
+    checkUpperBound(type1: "A?", type2: "A*", upperBound: "A?");
+    checkUpperBound(type1: "A?", type2: "A?", upperBound: "A?");
+    checkUpperBound(type1: "A?", type2: "A", upperBound: "A?");
 
-    testUpper("A", "A*", "A*");
-    testUpper("A", "A?", "A?");
-    testUpper("A", "A", "A");
+    checkUpperBound(type1: "A", type2: "A*", upperBound: "A*");
+    checkUpperBound(type1: "A", type2: "A?", upperBound: "A?");
+    checkUpperBound(type1: "A", type2: "A", upperBound: "A");
   }
 
   void test_upper_bound_sameClass() {
-    const String testSdk = """
+    parseTestLibrary("""
       class A;
       class B extends A;
       class Pair<X, Y>;
-    """;
-    _initialize(testSdk);
+    """);
 
-    testUpper("Pair<A*, B*>", "Pair<B*, A*>", "Pair<A*, A*>");
-    testUpper("Pair<A*, B*>", "Pair<B?, A>", "Pair<A?, A*>");
-    testUpper("Pair<A?, B?>", "Pair<B, A>", "Pair<A?, A?>");
+    checkUpperBound(
+        type1: "Pair<A*, B*>",
+        type2: "Pair<B*, A*>",
+        upperBound: "Pair<A*, A*>");
+    checkUpperBound(
+        type1: "Pair<A*, B*>",
+        type2: "Pair<B?, A>",
+        upperBound: "Pair<A?, A*>");
+    checkUpperBound(
+        type1: "Pair<A?, B?>", type2: "Pair<B, A>", upperBound: "Pair<A?, A?>");
   }
 
   void test_upper_bound_subtype() {
-    const String testSdk = """
+    parseTestLibrary("""
       class A;
       class B extends A;
-    """;
-    _initialize(testSdk);
+    """);
 
     // UP(T1, T2) = T2 if T1 <: T2
     //   Note that both types must be class types at this point
-    testUpper("List<B*>", "Iterable<A*>", "Iterable<A*>");
-    testUpper("List<B*>", "Iterable<A?>", "Iterable<A?>");
-    testUpper("List<B*>", "Iterable<A>", "Iterable<A>");
-    testUpper("List<B>*", "Iterable<A>*", "Iterable<A>*");
-    testUpper("List<B>*", "Iterable<A>?", "Iterable<A>?");
-    testUpper("List<B>*", "Iterable<A>", "Iterable<A>*");
-    testUpper("List<B>?", "Iterable<A>*", "Iterable<A>?");
-    testUpper("List<B>?", "Iterable<A>?", "Iterable<A>?");
-    testUpper("List<B>?", "Iterable<A>", "Iterable<A>?");
+    checkUpperBound(
+        type1: "List<B*>", type2: "Iterable<A*>", upperBound: "Iterable<A*>");
+    checkUpperBound(
+        type1: "List<B*>", type2: "Iterable<A?>", upperBound: "Iterable<A?>");
+    checkUpperBound(
+        type1: "List<B*>", type2: "Iterable<A>", upperBound: "Iterable<A>");
+    checkUpperBound(
+        type1: "List<B>*", type2: "Iterable<A>*", upperBound: "Iterable<A>*");
+    checkUpperBound(
+        type1: "List<B>*", type2: "Iterable<A>?", upperBound: "Iterable<A>?");
+    checkUpperBound(
+        type1: "List<B>*", type2: "Iterable<A>", upperBound: "Iterable<A>*");
+    checkUpperBound(
+        type1: "List<B>?", type2: "Iterable<A>*", upperBound: "Iterable<A>?");
+    checkUpperBound(
+        type1: "List<B>?", type2: "Iterable<A>?", upperBound: "Iterable<A>?");
+    checkUpperBound(
+        type1: "List<B>?", type2: "Iterable<A>", upperBound: "Iterable<A>?");
 
     // UP(T1, T2) = T2 if T1 <: T2
     //   Note that both types must be class types at this point
-    testUpper("List<B?>", "Iterable<A*>", "Iterable<A*>");
-    testUpper("List<B?>", "Iterable<A?>", "Iterable<A?>");
-    testUpper("List<B>?", "Iterable<A>*", "Iterable<A>?");
-    testUpper("List<B>?", "Iterable<A>?", "Iterable<A>?");
-    testUpper("List<B>?", "Iterable<A>", "Iterable<A>?");
+    checkUpperBound(
+        type1: "List<B?>", type2: "Iterable<A*>", upperBound: "Iterable<A*>");
+    checkUpperBound(
+        type1: "List<B?>", type2: "Iterable<A?>", upperBound: "Iterable<A?>");
+    checkUpperBound(
+        type1: "List<B>?", type2: "Iterable<A>*", upperBound: "Iterable<A>?");
+    checkUpperBound(
+        type1: "List<B>?", type2: "Iterable<A>?", upperBound: "Iterable<A>?");
+    checkUpperBound(
+        type1: "List<B>?", type2: "Iterable<A>", upperBound: "Iterable<A>?");
     // UP(C0<T0, ..., Tn>, C1<S0, ..., Sk>)
     //     = least upper bound of two interfaces as in Dart 1.
-    testUpper("List<B?>", "Iterable<A>", "Object");
+    checkUpperBound(
+        type1: "List<B?>", type2: "Iterable<A>", upperBound: "Object");
 
     // UP(T1, T2) = T2 if T1 <: T2
     //   Note that both types must be class types at this point
-    testUpper("List<B>", "Iterable<A*>", "Iterable<A*>");
-    testUpper("List<B>", "Iterable<A?>", "Iterable<A?>");
-    testUpper("List<B>", "Iterable<A>", "Iterable<A>");
-    testUpper("List<B>", "Iterable<A>*", "Iterable<A>*");
-    testUpper("List<B>", "Iterable<A>?", "Iterable<A>?");
+    checkUpperBound(
+        type1: "List<B>", type2: "Iterable<A*>", upperBound: "Iterable<A*>");
+    checkUpperBound(
+        type1: "List<B>", type2: "Iterable<A?>", upperBound: "Iterable<A?>");
+    checkUpperBound(
+        type1: "List<B>", type2: "Iterable<A>", upperBound: "Iterable<A>");
+    checkUpperBound(
+        type1: "List<B>", type2: "Iterable<A>*", upperBound: "Iterable<A>*");
+    checkUpperBound(
+        type1: "List<B>", type2: "Iterable<A>?", upperBound: "Iterable<A>?");
 
     // UP(T1, T2) = T1 if T2 <: T1
     //   Note that both types must be class types at this point
-    testUpper("Iterable<A*>", "List<B*>", "Iterable<A*>");
-    testUpper("Iterable<A*>", "List<B?>", "Iterable<A*>");
-    testUpper("Iterable<A*>", "List<B>", "Iterable<A*>");
-    testUpper("Iterable<A>*", "List<B>*", "Iterable<A>*");
-    testUpper("Iterable<A>*", "List<B>?", "Iterable<A>?");
-    testUpper("Iterable<A>*", "List<B>", "Iterable<A>*");
+    checkUpperBound(
+        type1: "Iterable<A*>", type2: "List<B*>", upperBound: "Iterable<A*>");
+    checkUpperBound(
+        type1: "Iterable<A*>", type2: "List<B?>", upperBound: "Iterable<A*>");
+    checkUpperBound(
+        type1: "Iterable<A*>", type2: "List<B>", upperBound: "Iterable<A*>");
+    checkUpperBound(
+        type1: "Iterable<A>*", type2: "List<B>*", upperBound: "Iterable<A>*");
+    checkUpperBound(
+        type1: "Iterable<A>*", type2: "List<B>?", upperBound: "Iterable<A>?");
+    checkUpperBound(
+        type1: "Iterable<A>*", type2: "List<B>", upperBound: "Iterable<A>*");
 
     // UP(T1, T2) = T1 if T2 <: T1
     //   Note that both types must be class types at this point
-    testUpper("Iterable<A?>", "List<B*>", "Iterable<A?>");
-    testUpper("Iterable<A?>", "List<B?>", "Iterable<A?>");
-    testUpper("Iterable<A?>", "List<B>", "Iterable<A?>");
-    testUpper("Iterable<A>?", "List<B>*", "Iterable<A>?");
-    testUpper("Iterable<A>?", "List<B>?", "Iterable<A>?");
-    testUpper("Iterable<A>?", "List<B>", "Iterable<A>?");
+    checkUpperBound(
+        type1: "Iterable<A?>", type2: "List<B*>", upperBound: "Iterable<A?>");
+    checkUpperBound(
+        type1: "Iterable<A?>", type2: "List<B?>", upperBound: "Iterable<A?>");
+    checkUpperBound(
+        type1: "Iterable<A?>", type2: "List<B>", upperBound: "Iterable<A?>");
+    checkUpperBound(
+        type1: "Iterable<A>?", type2: "List<B>*", upperBound: "Iterable<A>?");
+    checkUpperBound(
+        type1: "Iterable<A>?", type2: "List<B>?", upperBound: "Iterable<A>?");
+    checkUpperBound(
+        type1: "Iterable<A>?", type2: "List<B>", upperBound: "Iterable<A>?");
 
     // UP(T1, T2) = T1 if T2 <: T1
     //   Note that both types must be class types at this point
-    testUpper("Iterable<A>", "List<B*>", "Iterable<A>");
-    testUpper("Iterable<A>", "List<B>*", "Iterable<A>*");
+    checkUpperBound(
+        type1: "Iterable<A>", type2: "List<B*>", upperBound: "Iterable<A>");
+    checkUpperBound(
+        type1: "Iterable<A>", type2: "List<B>*", upperBound: "Iterable<A>*");
     // UP(C0<T0, ..., Tn>, C1<S0, ..., Sk>)
     //     = least upper bound of two interfaces as in Dart 1.
-    testUpper("Iterable<A>", "List<B?>", "Object");
+    checkUpperBound(
+        type1: "Iterable<A>", type2: "List<B?>", upperBound: "Object");
     // UP(T1, T2) = T1 if T2 <: T1
     //   Note that both types must be class types at this point
-    testUpper("Iterable<A>", "List<B>", "Iterable<A>");
+    checkUpperBound(
+        type1: "Iterable<A>", type2: "List<B>", upperBound: "Iterable<A>");
   }
 
   void test_upper_bound_top() {
-    _initialize("class A;");
+    parseTestLibrary("class A;");
 
     // UP(T1, T2) where TOP(T1) and TOP(T2) =
     //   T1 if MORETOP(T1, T2)
@@ -961,26 +1105,39 @@
       for (String t2 in topPredicateEnumeration.keys) {
         String typeParameters = joinTypeParameters(
             topPredicateEnumeration[t1], topPredicateEnumeration[t2]);
-        String expected = env.moretop(
-                toType(t1, typeParameters: typeParameters),
-                toType(t2, typeParameters: typeParameters))
-            ? t1
-            : t2;
-        testUpper(t1, t2, expected, typeParameters: typeParameters);
+        typeParserEnvironment.withTypeParameters(typeParameters, (_) {
+          String expected =
+              typeSchemaEnvironment.moretop(parseType(t1), parseType(t2))
+                  ? t1
+                  : t2;
+          checkUpperBound(
+              type1: t1,
+              type2: t2,
+              upperBound: expected,
+              typeParameters: typeParameters);
+        });
       }
     }
 
     // UP(T1, T2) = T1 if TOP(T1)
     for (String t1 in topPredicateEnumeration.keys) {
       for (String t2 in ["A*", "A?", "A"]) {
-        testUpper(t1, t2, t1, typeParameters: topPredicateEnumeration[t1]);
+        checkUpperBound(
+            type1: t1,
+            type2: t2,
+            upperBound: t1,
+            typeParameters: topPredicateEnumeration[t1]);
       }
     }
 
     // UP(T1, T2) = T2 if TOP(T2)
     for (String t1 in ["A*", "A?", "A"]) {
       for (String t2 in topPredicateEnumeration.keys) {
-        testUpper(t1, t2, t2, typeParameters: topPredicateEnumeration[t2]);
+        checkUpperBound(
+            type1: t1,
+            type2: t2,
+            upperBound: t2,
+            typeParameters: topPredicateEnumeration[t2]);
       }
     }
 
@@ -991,12 +1148,17 @@
       for (String t2 in objectPredicateEnumeration.keys) {
         String typeParameters = joinTypeParameters(
             objectPredicateEnumeration[t1], objectPredicateEnumeration[t2]);
-        String expected = env.moretop(
-                toType(t1, typeParameters: typeParameters),
-                toType(t2, typeParameters: typeParameters))
-            ? t1
-            : t2;
-        testUpper(t1, t2, expected, typeParameters: typeParameters);
+        typeParserEnvironment.withTypeParameters(typeParameters, (_) {
+          String expected =
+              typeSchemaEnvironment.moretop(parseType(t1), parseType(t2))
+                  ? t1
+                  : t2;
+          checkUpperBound(
+              type1: t1,
+              type2: t2,
+              upperBound: expected,
+              typeParameters: typeParameters);
+        });
       }
     }
 
@@ -1004,25 +1166,31 @@
     //   T1 if T2 is non-nullable
     //   T1? otherwise
     for (String t1 in objectPredicateEnumeration.keys) {
-      testUpper(t1, "A*", "${t1}?",
+      checkUpperBound(
+          type1: t1,
+          type2: "A*",
+          upperBound: "${t1}?",
           typeParameters: objectPredicateEnumeration[t1]);
-      testUpper(t1, "A?", "${t1}?",
+      checkUpperBound(
+          type1: t1,
+          type2: "A?",
+          upperBound: "${t1}?",
           typeParameters: objectPredicateEnumeration[t1]);
-      testUpper(t1, "A", t1);
+      checkUpperBound(type1: t1, type2: "A", upperBound: t1);
     }
 
     // UP(T1, T2) where OBJECT(T2) =
     //   T2 if T1 is non-nullable
     //   T2? otherwise
     for (String t2 in objectPredicateEnumeration.keys) {
-      testUpper("A*", t2, "${t2}?");
-      testUpper("A?", t2, "${t2}?");
-      testUpper("A", t2, t2);
+      checkUpperBound(type1: "A*", type2: t2, upperBound: "${t2}?");
+      checkUpperBound(type1: "A?", type2: t2, upperBound: "${t2}?");
+      checkUpperBound(type1: "A", type2: t2, upperBound: t2);
     }
   }
 
   void test_upper_bound_bottom() {
-    _initialize("class A;");
+    parseTestLibrary("class A;");
 
     // UP(T1, T2) where BOTTOM(T1) and BOTTOM(T2) =
     //   T2 if MOREBOTTOM(T1, T2)
@@ -1031,26 +1199,39 @@
       for (String t2 in bottomPredicateEnumeration.keys) {
         String typeParameters = joinTypeParameters(
             bottomPredicateEnumeration[t1], bottomPredicateEnumeration[t2]);
-        String expected = env.morebottom(
-                toType(t1, typeParameters: typeParameters),
-                toType(t2, typeParameters: typeParameters))
-            ? t2
-            : t1;
-        testUpper(t1, t2, expected, typeParameters: typeParameters);
+        typeParserEnvironment.withTypeParameters(typeParameters, (_) {
+          String expected =
+              typeSchemaEnvironment.morebottom(parseType(t1), parseType(t2))
+                  ? t2
+                  : t1;
+          checkUpperBound(
+              type1: t1,
+              type2: t2,
+              upperBound: expected,
+              typeParameters: typeParameters);
+        });
       }
     }
 
     // UP(T1, T2) = T2 if BOTTOM(T1)
     for (String t1 in bottomPredicateEnumeration.keys) {
       for (String t2 in ["A*", "A?", "A"]) {
-        testUpper(t1, t2, t2, typeParameters: bottomPredicateEnumeration[t1]);
+        checkUpperBound(
+            type1: t1,
+            type2: t2,
+            upperBound: t2,
+            typeParameters: bottomPredicateEnumeration[t1]);
       }
     }
 
     // UP(T1, T2) = T1 if BOTTOM(T2)
     for (String t1 in ["A*", "A?", "A"]) {
       for (String t2 in bottomPredicateEnumeration.keys) {
-        testUpper(t1, t2, t1, typeParameters: bottomPredicateEnumeration[t2]);
+        checkUpperBound(
+            type1: t1,
+            type2: t2,
+            upperBound: t1,
+            typeParameters: bottomPredicateEnumeration[t2]);
       }
     }
 
@@ -1061,12 +1242,17 @@
       for (String t2 in nullPredicateEnumeration.keys) {
         String typeParameters = joinTypeParameters(
             nullPredicateEnumeration[t1], nullPredicateEnumeration[t2]);
-        String expected = env.morebottom(
-                toType(t1, typeParameters: typeParameters),
-                toType(t2, typeParameters: typeParameters))
-            ? t2
-            : t1;
-        testUpper(t1, t2, expected, typeParameters: typeParameters);
+        typeParserEnvironment.withTypeParameters(typeParameters, (_) {
+          String expected =
+              typeSchemaEnvironment.morebottom(parseType(t1), parseType(t2))
+                  ? t2
+                  : t1;
+          checkUpperBound(
+              type1: t1,
+              type2: t2,
+              upperBound: expected,
+              typeParameters: typeParameters);
+        });
       }
     }
 
@@ -1074,286 +1260,426 @@
     //   T2 if T2 is nullable
     //   T2? otherwise
     for (String t1 in nullPredicateEnumeration.keys) {
-      testUpper(t1, "A*", "A?", typeParameters: nullPredicateEnumeration[t1]);
-      testUpper(t1, "A?", "A?", typeParameters: nullPredicateEnumeration[t1]);
-      testUpper(t1, "A", "A?", typeParameters: nullPredicateEnumeration[t1]);
+      checkUpperBound(
+          type1: t1,
+          type2: "A*",
+          upperBound: "A?",
+          typeParameters: nullPredicateEnumeration[t1]);
+      checkUpperBound(
+          type1: t1,
+          type2: "A?",
+          upperBound: "A?",
+          typeParameters: nullPredicateEnumeration[t1]);
+      checkUpperBound(
+          type1: t1,
+          type2: "A",
+          upperBound: "A?",
+          typeParameters: nullPredicateEnumeration[t1]);
     }
 
     // UP(T1, T2) where NULL(T2) =
     //   T1 if T1 is nullable
     //   T1? otherwise
     for (String t2 in nullPredicateEnumeration.keys) {
-      testUpper("A*", t2, "A?", typeParameters: nullPredicateEnumeration[t2]);
-      testUpper("A?", t2, "A?", typeParameters: nullPredicateEnumeration[t2]);
-      testUpper("A", t2, "A?", typeParameters: nullPredicateEnumeration[t2]);
+      checkUpperBound(
+          type1: "A*",
+          type2: t2,
+          upperBound: "A?",
+          typeParameters: nullPredicateEnumeration[t2]);
+      checkUpperBound(
+          type1: "A?",
+          type2: t2,
+          upperBound: "A?",
+          typeParameters: nullPredicateEnumeration[t2]);
+      checkUpperBound(
+          type1: "A",
+          type2: t2,
+          upperBound: "A?",
+          typeParameters: nullPredicateEnumeration[t2]);
     }
   }
 
   void test_upper_bound_typeParameter() {
-    _initialize("");
+    parseTestLibrary("");
 
     // TODO(dmitryas): Test for various nullabilities.
-    testUpper("T", "T", "T", typeParameters: "T extends Object");
-    testUpper("T", "List<Never>", "List<Object?>",
+    checkUpperBound(
+        type1: "T",
+        type2: "T",
+        upperBound: "T",
+        typeParameters: "T extends Object");
+    checkUpperBound(
+        type1: "T",
+        type2: "List<Never>",
+        upperBound: "List<Object?>",
         typeParameters: "T extends List<T>");
-    testUpper("List<Never>", "T", "List<Object?>",
+    checkUpperBound(
+        type1: "List<Never>",
+        type2: "T",
+        upperBound: "List<Object?>",
         typeParameters: "T extends List<T>");
-    testUpper("T", "U", "List<Object?>",
+    checkUpperBound(
+        type1: "T",
+        type2: "U",
+        upperBound: "List<Object?>",
         typeParameters: "T extends List<T>, U extends List<Never>");
-    testUpper("U", "T", "List<Object?>",
+    checkUpperBound(
+        type1: "U",
+        type2: "T",
+        upperBound: "List<Object?>",
         typeParameters: "T extends List<T>, U extends List<Never>");
   }
 
   void test_upper_bound_unknown() {
-    _initialize("class A;");
+    parseTestLibrary("class A;");
 
-    testLower("A*", "unknown", "A*");
-    testLower("A?", "unknown", "A?");
-    testLower("A", "unknown", "A");
+    checkLowerBound(type1: "A*", type2: "UNKNOWN", lowerBound: "A*");
+    checkLowerBound(type1: "A?", type2: "UNKNOWN", lowerBound: "A?");
+    checkLowerBound(type1: "A", type2: "UNKNOWN", lowerBound: "A");
 
-    testLower("unknown", "A*", "A*");
-    testLower("unknown", "A?", "A?");
-    testLower("unknown", "A", "A");
+    checkLowerBound(type1: "UNKNOWN", type2: "A*", lowerBound: "A*");
+    checkLowerBound(type1: "UNKNOWN", type2: "A?", lowerBound: "A?");
+    checkLowerBound(type1: "UNKNOWN", type2: "A", lowerBound: "A");
   }
 
   void test_solveTypeConstraint() {
-    const String testSdk = """
+    parseTestLibrary("""
       class A<X>;
       class B<Y> extends A<Y>;
-    """;
-    _initialize(testSdk);
+    """);
 
     // TODO(dmitryas): Test for various nullabilities.
 
     // Solve(? <: T <: ?) => ?
-    expect(env.solveTypeConstraint(_makeConstraint(), topType, bottomType),
-        new UnknownType());
+    checkConstraintSolving("", "UNKNOWN", grounded: false);
 
     // Solve(? <: T <: ?, grounded) => dynamic
-    expect(
-        env.solveTypeConstraint(_makeConstraint(), topType, bottomType,
-            grounded: true),
-        new DynamicType());
+    checkConstraintSolving("", "dynamic", grounded: true);
 
     // Solve(A <: T <: ?) => A
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(lower: toType("A<dynamic>*")), topType, bottomType),
-        toType("A<dynamic>*"));
+    checkConstraintSolving(":> A<dynamic>*", "A<dynamic>*", grounded: false);
 
     // Solve(A <: T <: ?, grounded) => A
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(lower: toType("A<dynamic>*")), topType, bottomType,
-            grounded: true),
-        toType("A<dynamic>*"));
+    checkConstraintSolving(":> A<dynamic>*", "A<dynamic>*", grounded: true);
 
     // Solve(A<?>* <: T <: ?) => A<?>*
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(lower: toType("A<unknown>*")), topType, bottomType),
-        toType("A<unknown>*"));
+    checkConstraintSolving(":> A<UNKNOWN>*", "A<UNKNOWN>*", grounded: false);
 
     // Solve(A<?>* <: T <: ?, grounded) => A<Never>*
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(lower: toType("A<unknown>*")), topType, bottomType,
-            grounded: true),
-        toType("A<Never>*"));
+    checkConstraintSolving(":> A<UNKNOWN>*", "A<Never>*", grounded: true);
 
     // Solve(? <: T <: A*) => A*
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(upper: toType("A<dynamic>*")), topType, bottomType),
-        toType("A<dynamic>*"));
+    checkConstraintSolving("<: A<dynamic>*", "A<dynamic>*", grounded: false);
 
     // Solve(? <: T <: A*, grounded) => A*
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(upper: toType("A<dynamic>*")), topType, bottomType,
-            grounded: true),
-        toType("A<dynamic>*"));
+    checkConstraintSolving("<: A<dynamic>*", "A<dynamic>*", grounded: true);
 
     // Solve(? <: T <: A<?>*) => A<?>*
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(upper: toType("A<unknown>*")), topType, bottomType),
-        toType("A<unknown>*"));
+    checkConstraintSolving("<: A<UNKNOWN>*", "A<UNKNOWN>*", grounded: false);
 
     // Solve(? <: T <: A<?>*, grounded) => A<dynamic>*
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(upper: toType("A<unknown>*")), topType, bottomType,
-            grounded: true),
-        toType("A<Object?>*"));
+    checkConstraintSolving("<: A<UNKNOWN>*", "A<Object?>*", grounded: true);
 
     // Solve(B* <: T <: A*) => B*
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                lower: toType("B<dynamic>*"), upper: toType("A<dynamic>*")),
-            topType,
-            bottomType),
-        toType("B<dynamic>*"));
+    checkConstraintSolving(":> B<dynamic>* <: A<dynamic>*", "B<dynamic>*",
+        grounded: false);
 
     // Solve(B* <: T <: A*, grounded) => B*
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                lower: toType("B<dynamic>*"), upper: toType("A<dynamic>*")),
-            topType,
-            bottomType,
-            grounded: true),
-        toType("B<dynamic>*"));
+    checkConstraintSolving(":> B<dynamic>* <: A<dynamic>*", "B<dynamic>*",
+        grounded: true);
 
     // Solve(B<?>* <: T <: A*) => A*
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                lower: toType("B<unknown>*"), upper: toType("A<dynamic>*")),
-            topType,
-            bottomType),
-        toType("A<dynamic>*"));
+    checkConstraintSolving(":> B<UNKNOWN>* <: A<dynamic>*", "A<dynamic>*",
+        grounded: false);
 
     // Solve(B<?>* <: T <: A*, grounded) => A*
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                lower: toType("B<unknown>*"), upper: toType("A<dynamic>*")),
-            topType,
-            bottomType,
-            grounded: true),
-        toType("A<dynamic>*"));
+    checkConstraintSolving(":> B<UNKNOWN>* <: A<dynamic>*", "A<dynamic>*",
+        grounded: true);
 
     // Solve(B* <: T <: A<?>*) => B*
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                lower: toType("B<dynamic>*"), upper: toType("A<unknown>*")),
-            topType,
-            bottomType),
-        toType("B<dynamic>*"));
+    checkConstraintSolving(":> B<dynamic>* <: A<UNKNOWN>*", "B<dynamic>*",
+        grounded: false);
 
     // Solve(B* <: T <: A<?>*, grounded) => B*
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                lower: toType("B<dynamic>*"), upper: toType("A<unknown>*")),
-            topType,
-            bottomType,
-            grounded: true),
-        toType("B<dynamic>*"));
+    checkConstraintSolving(":> B<dynamic>* <: A<UNKNOWN>*", "B<dynamic>*",
+        grounded: true);
 
     // Solve(B<?>* <: T <: A<?>*) => B<?>*
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                lower: toType("B<unknown>*"), upper: toType("A<unknown>*")),
-            topType,
-            bottomType),
-        toType("B<unknown>*"));
+    checkConstraintSolving(":> B<UNKNOWN>* <: A<UNKNOWN>*", "B<UNKNOWN>*",
+        grounded: false);
 
     // Solve(B<?>* <: T <: A<?>*, grounded) => B<Never>*
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                lower: toType("B<unknown>*"), upper: toType("A<unknown>*")),
-            topType,
-            bottomType,
-            grounded: true),
-        toType("B<Never>*"));
+    checkConstraintSolving(":> B<UNKNOWN>* <: A<UNKNOWN>*", "B<Never>*",
+        grounded: true);
   }
 
   void test_typeConstraint_default() {
-    TypeConstraint typeConstraint = new TypeConstraint();
-    expect(typeConstraint.lower, new UnknownType());
-    expect(typeConstraint.upper, new UnknownType());
+    parseTestLibrary("");
+    checkConstraintLowerBound(constraint: "", bound: "UNKNOWN");
+    checkConstraintUpperBound(constraint: "", bound: "UNKNOWN");
   }
 
   void test_typeSatisfiesConstraint() {
-    const String testSdk = """
+    parseTestLibrary("""
       class A;
       class B extends A;
       class C extends B;
       class D extends C;
       class E extends D;
-    """;
-    _initialize(testSdk);
+    """);
 
-    // TODO(dmitryas): Test for various nullabilities.
-    TypeConstraint typeConstraint =
-        _makeConstraint(upper: toType("B*"), lower: toType("D*"));
-
-    expect(env.typeSatisfiesConstraint(toType("A*"), typeConstraint), isFalse);
-    expect(env.typeSatisfiesConstraint(toType("B*"), typeConstraint), isTrue);
-    expect(env.typeSatisfiesConstraint(toType("C*"), typeConstraint), isTrue);
-    expect(env.typeSatisfiesConstraint(toType("D*"), typeConstraint), isTrue);
-    expect(env.typeSatisfiesConstraint(toType("E*"), typeConstraint), isFalse);
+    checkTypeDoesntSatisfyConstraint("A*", ":> D* <: B*");
+    checkTypeSatisfiesConstraint("B*", ":> D* <: B*");
+    checkTypeSatisfiesConstraint("C*", ":> D* <: B*");
+    checkTypeSatisfiesConstraint("D*", ":> D* <: B*");
+    checkTypeDoesntSatisfyConstraint("E*", ":> D* <: B*");
   }
 
   void test_unknown_at_bottom() {
-    _initialize("class A;");
+    parseTestLibrary("class A;");
 
     // TODO(dmitryas): Test for various nullabilities.
-    expect(
-        env.isSubtypeOf(new UnknownType(), toType("A*"),
-            SubtypeCheckMode.ignoringNullabilities),
-        isTrue);
+    checkIsLegacySubtype("UNKNOWN", "A*");
   }
 
   void test_unknown_at_top() {
-    const String testSdk = """
+    parseTestLibrary("""
       class A;
       class Pair<X, Y>;
-    """;
-    _initialize(testSdk);
+    """);
 
+    checkIsLegacySubtype("A*", "UNKNOWN");
+    checkIsSubtype("Pair<A*, Null>*", "Pair<UNKNOWN, UNKNOWN>*");
+  }
+
+  void checkConstraintSolving(String constraint, String expected,
+      {bool grounded}) {
+    assert(grounded != null);
     expect(
-        env.isSubtypeOf(toType("A*"), new UnknownType(),
-            SubtypeCheckMode.ignoringNullabilities),
-        isTrue);
+        typeSchemaEnvironment.solveTypeConstraint(
+            parseConstraint(constraint),
+            coreTypes.objectNullableRawType,
+            new NeverType(Nullability.nonNullable),
+            grounded: grounded),
+        parseType(expected));
+  }
+
+  void checkConstraintUpperBound({String constraint, String bound}) {
+    assert(constraint != null);
+    assert(bound != null);
+
+    expect(parseConstraint(constraint).upper, parseType(bound));
+  }
+
+  void checkConstraintLowerBound({String constraint, String bound}) {
+    assert(constraint != null);
+    assert(bound != null);
+
+    expect(parseConstraint(constraint).lower, parseType(bound));
+  }
+
+  void checkTypeSatisfiesConstraint(String type, String constraint) {
     expect(
-        env.isSubtypeOf(
-            toType("Pair<A*, Null>*"),
-            toType("Pair<unknown, unknown>*"),
-            SubtypeCheckMode.withNullabilities),
+        typeSchemaEnvironment.typeSatisfiesConstraint(
+            parseType(type), parseConstraint(constraint)),
         isTrue);
   }
 
-  DartType _list(DartType elementType) {
-    return new InterfaceType(listClass, Nullability.nonNullable, [elementType]);
+  void checkTypeDoesntSatisfyConstraint(String type, String constraint) {
+    expect(
+        typeSchemaEnvironment.typeSatisfiesConstraint(
+            parseType(type), parseConstraint(constraint)),
+        isFalse);
   }
 
-  TypeConstraint _makeConstraint({DartType lower, DartType upper}) {
-    lower ??= new UnknownType();
-    upper ??= new UnknownType();
-    return new TypeConstraint()
-      ..lower = lower
-      ..upper = upper;
+  void checkIsSubtype(String subtype, String supertype) {
+    expect(
+        typeSchemaEnvironment
+            .performNullabilityAwareSubtypeCheck(
+                parseType(subtype), parseType(supertype))
+            .isSubtypeWhenUsingNullabilities(),
+        isTrue);
   }
 
-  void _initialize(String testSdk) {
-    Uri uri = Uri.parse("dart:core");
-    typeParserEnvironment = new TypeSchemaTypeParserEnvironment(uri);
-    Library library =
-        parseLibrary(uri, mockSdk + testSdk, environment: typeParserEnvironment)
-          ..isNonNullableByDefault = true;
-    component = new Component(libraries: <Library>[library]);
-    coreTypes = new CoreTypes(component);
-    env = new TypeSchemaEnvironment(
-        coreTypes, new ClassHierarchy(component, coreTypes));
+  void checkIsLegacySubtype(String subtype, String supertype) {
+    expect(
+        typeSchemaEnvironment
+            .performNullabilityAwareSubtypeCheck(
+                parseType(subtype), parseType(supertype))
+            .isSubtypeWhenIgnoringNullabilities(),
+        isTrue);
   }
-}
 
-class TypeSchemaTypeParserEnvironment extends TypeParserEnvironment {
-  TypeSchemaTypeParserEnvironment(Uri uri) : super(uri, uri);
+  void checkIsNotSubtype(String subtype, String supertype) {
+    expect(
+        typeSchemaEnvironment
+            .performNullabilityAwareSubtypeCheck(
+                parseType(subtype), parseType(supertype))
+            .isSubtypeWhenIgnoringNullabilities(),
+        isFalse);
+  }
 
-  DartType getPredefinedNamedType(String name) {
-    if (name == "unknown") {
-      // Don't return a const object to ensure we test implementations that use
-      // identical.
-      return new UnknownType();
+  void checkUpperBound(
+      {String type1, String type2, String upperBound, String typeParameters}) {
+    assert(type1 != null);
+    assert(type2 != null);
+    assert(upperBound != null);
+
+    typeParserEnvironment.withTypeParameters(typeParameters,
+        (List<TypeParameter> typeParameterNodes) {
+      expect(
+          typeSchemaEnvironment.getStandardUpperBound(
+              parseType(type1), parseType(type2), testLibrary),
+          parseType(upperBound));
+    });
+  }
+
+  void checkLowerBound(
+      {String type1, String type2, String lowerBound, String typeParameters}) {
+    assert(type1 != null);
+    assert(type2 != null);
+    assert(lowerBound != null);
+
+    typeParserEnvironment.withTypeParameters(typeParameters,
+        (List<TypeParameter> typeParameterNodes) {
+      expect(
+          typeSchemaEnvironment.getStandardLowerBound(
+              parseType(type1), parseType(type2), testLibrary),
+          parseType(lowerBound));
+    });
+  }
+
+  void checkInference(
+      {String typeParametersToInfer,
+      String functionType,
+      String actualParameterTypes,
+      String returnContextType,
+      String inferredTypesFromDownwardPhase,
+      String expectedTypes}) {
+    assert(typeParametersToInfer != null);
+    assert(functionType != null);
+    assert(expectedTypes != null);
+
+    typeParserEnvironment.withTypeParameters(typeParametersToInfer,
+        (List<TypeParameter> typeParameterNodesToInfer) {
+      FunctionType functionTypeNode = parseType(functionType);
+      DartType returnContextTypeNode =
+          returnContextType == null ? null : parseType(returnContextType);
+      List<DartType> actualTypeNodes = actualParameterTypes == null
+          ? null
+          : parseTypes(actualParameterTypes);
+      List<DartType> expectedTypeNodes =
+          expectedTypes == null ? null : parseTypes(expectedTypes);
+      DartType declaredReturnTypeNode = functionTypeNode.returnType;
+      List<DartType> formalTypeNodes = actualParameterTypes == null
+          ? null
+          : functionTypeNode.positionalParameters;
+
+      List<DartType> inferredTypeNodes;
+      if (inferredTypesFromDownwardPhase == null) {
+        inferredTypeNodes = new List<DartType>.generate(
+            typeParameterNodesToInfer.length, (_) => new UnknownType());
+      } else {
+        inferredTypeNodes = parseTypes(inferredTypesFromDownwardPhase);
+      }
+
+      typeSchemaEnvironment.inferGenericFunctionOrType(
+          declaredReturnTypeNode,
+          typeParameterNodesToInfer,
+          formalTypeNodes,
+          actualTypeNodes,
+          returnContextTypeNode,
+          inferredTypeNodes,
+          testLibrary);
+
+      assert(
+          inferredTypeNodes.length == expectedTypeNodes.length,
+          "The numbers of expected types and type parameters to infer "
+          "mismatch.");
+      for (int i = 0; i < inferredTypeNodes.length; ++i) {
+        expect(inferredTypeNodes[i], expectedTypeNodes[i]);
+      }
+    });
+  }
+
+  void checkInferenceFromConstraints(
+      {String typeParameter,
+      String constraints,
+      String inferredTypeFromDownwardPhase,
+      bool downwardsInferPhase,
+      String expected}) {
+    assert(typeParameter != null);
+    assert(expected != null);
+    assert(downwardsInferPhase != null);
+    assert(inferredTypeFromDownwardPhase == null || !downwardsInferPhase);
+
+    typeParserEnvironment.withTypeParameters(typeParameter,
+        (List<TypeParameter> typeParameterNodes) {
+      assert(typeParameterNodes.length == 1);
+
+      TypeConstraint typeConstraint = parseConstraint(constraints);
+      DartType expectedTypeNode = parseType(expected);
+      TypeParameter typeParameterNode = typeParameterNodes.single;
+      List<DartType> inferredTypeNodes = <DartType>[
+        inferredTypeFromDownwardPhase == null
+            ? new UnknownType()
+            : parseType(inferredTypeFromDownwardPhase)
+      ];
+
+      typeSchemaEnvironment.inferTypeFromConstraints(
+          {typeParameterNode: typeConstraint},
+          [typeParameterNode],
+          inferredTypeNodes,
+          testLibrary,
+          downwardsInferPhase: downwardsInferPhase);
+
+      expect(inferredTypeNodes.single, expectedTypeNode);
+    });
+  }
+
+  /// Parses a string like "<: T <: S >: R" into a [TypeConstraint].
+  ///
+  /// The [constraint] string is assumed to be a sequence of bounds added to the
+  /// constraint.  Each element of the sequence is either "<: T" or ":> T",
+  /// where the former adds an upper bound and the latter adds a lower bound.
+  /// The bounds are added to the constraint in the order they are mentioned in
+  /// the [constraint] string, from left to right.
+  TypeConstraint parseConstraint(String constraint) {
+    TypeConstraint result = new TypeConstraint();
+    List<String> upperBoundSegments = constraint.split("<:");
+    bool firstUpperBoundSegment = true;
+    for (String upperBoundSegment in upperBoundSegments) {
+      if (firstUpperBoundSegment) {
+        firstUpperBoundSegment = false;
+        if (upperBoundSegment.isEmpty) {
+          continue;
+        }
+      }
+      List<String> lowerBoundSegments = upperBoundSegment.split(":>");
+      bool firstLowerBoundSegment = true;
+      for (String segment in lowerBoundSegments) {
+        if (firstLowerBoundSegment) {
+          firstLowerBoundSegment = false;
+          if (segment.isNotEmpty) {
+            typeSchemaEnvironment.addUpperBound(
+                result, parseType(segment), testLibrary);
+          }
+        } else {
+          typeSchemaEnvironment.addLowerBound(
+              result, parseType(segment), testLibrary);
+        }
+      }
     }
-    return null;
+    return result;
+  }
+
+  DartType parseType(String type) {
+    return typeParserEnvironment.parseType(type,
+        additionalTypes: additionalTypes);
+  }
+
+  List<DartType> parseTypes(String types) {
+    return typeParserEnvironment.parseTypes(types,
+        additionalTypes: additionalTypes);
   }
 }
diff --git a/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart b/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart
index 24ef0a4..e57d799 100644
--- a/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart
@@ -7,8 +7,7 @@
 import 'package:kernel/ast.dart';
 import 'package:kernel/core_types.dart';
 import 'package:kernel/class_hierarchy.dart';
-import 'package:kernel/testing/mock_sdk_component.dart';
-import 'package:kernel/type_environment.dart';
+import 'package:kernel/testing/type_parser_environment.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -20,356 +19,273 @@
 
 @reflectiveTest
 class TypeSchemaEnvironmentTest {
-  static const UnknownType unknownType = const UnknownType();
+  Env typeParserEnvironment;
+  TypeSchemaEnvironment typeSchemaEnvironment;
 
-  static const DynamicType dynamicType = const DynamicType();
+  final Map<String, DartType Function()> additionalTypes = {
+    "UNKNOWN": () => new UnknownType(),
+    "BOTTOM": () => new BottomType(),
+  };
 
-  static const VoidType voidType = const VoidType();
+  Library _coreLibrary;
+  Library _testLibrary;
 
-  final testLib = new Library(Uri.parse('org-dartlang:///test.dart'));
+  Library get coreLibrary => _coreLibrary;
+  Library get testLibrary => _testLibrary;
 
-  Component component;
+  Component get component => typeParserEnvironment.component;
+  CoreTypes get coreTypes => typeParserEnvironment.coreTypes;
 
-  CoreTypes coreTypes;
-
-  TypeSchemaEnvironmentTest() {
-    component = createMockSdkComponent();
-    component.libraries.add(testLib..parent = component);
-    coreTypes = new CoreTypes(component);
+  void parseTestLibrary(String testLibraryText) {
+    typeParserEnvironment =
+        new Env(testLibraryText, isNonNullableByDefault: false);
+    typeSchemaEnvironment = new TypeSchemaEnvironment(
+        coreTypes, new ClassHierarchy(component, coreTypes));
+    assert(
+        typeParserEnvironment.component.libraries.length == 2,
+        "The tests are supposed to have exactly two libraries: "
+        "the core library and the test library.");
+    Library firstLibrary = typeParserEnvironment.component.libraries.first;
+    Library secondLibrary = typeParserEnvironment.component.libraries.last;
+    if (firstLibrary.importUri.scheme == "dart" &&
+        firstLibrary.importUri.path == "core") {
+      _coreLibrary = firstLibrary;
+      _testLibrary = secondLibrary;
+    } else {
+      assert(
+          secondLibrary.importUri.scheme == "dart" &&
+              secondLibrary.importUri.path == "core",
+          "One of the libraries is expected to be 'dart:core'.");
+      _coreLibrary == secondLibrary;
+      _testLibrary = firstLibrary;
+    }
   }
 
-  InterfaceType get doubleType => coreTypes.doubleLegacyRawType;
-
-  InterfaceType get functionType => coreTypes.functionLegacyRawType;
-
-  InterfaceType get intType => coreTypes.intLegacyRawType;
-
-  Class get iterableClass => coreTypes.iterableClass;
-
-  Class get listClass => coreTypes.listClass;
-
-  Class get mapClass => coreTypes.mapClass;
-
-  InterfaceType get numType => coreTypes.numLegacyRawType;
-
-  Class get objectClass => coreTypes.objectClass;
-
-  InterfaceType get objectType => coreTypes.objectLegacyRawType;
-
-  DartType get bottomType => const NullType();
-
-  DartType get topType => const DynamicType();
-
   void test_addLowerBound() {
-    var A = coreTypes.legacyRawType(_addClass(_class('A')));
-    var B = coreTypes.legacyRawType(
-        _addClass(_class('B', supertype: A.classNode.asThisSupertype)));
-    var C = coreTypes.legacyRawType(
-        _addClass(_class('C', supertype: A.classNode.asThisSupertype)));
-    var env = _makeEnv();
-    var typeConstraint = new TypeConstraint();
-    expect(typeConstraint.lower, same(unknownType));
-    env.addLowerBound(typeConstraint, B, testLib);
-    expect(typeConstraint.lower, same(B));
-    env.addLowerBound(typeConstraint, C, testLib);
-    expect(typeConstraint.lower, same(A));
+    parseTestLibrary("class A; class B extends A; class C extends A;");
+    checkConstraintLowerBound(constraint: "", bound: "UNKNOWN");
+    checkConstraintLowerBound(constraint: ":> B*", bound: "B*");
+    checkConstraintLowerBound(constraint: ":> B* :> C*", bound: "A*");
   }
 
   void test_addUpperBound() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var B = coreTypes.rawType(
-        _addClass(_class('B', supertype: A.classNode.asThisSupertype)),
-        Nullability.legacy);
-    var C = coreTypes.rawType(
-        _addClass(_class('C', supertype: A.classNode.asThisSupertype)),
-        Nullability.legacy);
-    var env = _makeEnv();
-    var typeConstraint = new TypeConstraint();
-    expect(typeConstraint.upper, same(unknownType));
-    env.addUpperBound(typeConstraint, A, testLib);
-    expect(typeConstraint.upper, same(A));
-    env.addUpperBound(typeConstraint, B, testLib);
-    expect(typeConstraint.upper, same(B));
-    env.addUpperBound(typeConstraint, C, testLib);
-    expect(typeConstraint.upper, new BottomType());
+    parseTestLibrary("class A; class B extends A; class C extends A;");
+    checkConstraintUpperBound(constraint: "", bound: "UNKNOWN");
+    checkConstraintUpperBound(constraint: "<: A*", bound: "A*");
+    checkConstraintUpperBound(constraint: "<: A* <: B*", bound: "B*");
+    checkConstraintUpperBound(constraint: "<: A* <: B* <: C*", bound: "BOTTOM");
   }
 
   void test_glb_bottom() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var env = _makeEnv();
-    expect(env.getStandardLowerBound(new BottomType(), A, testLib),
-        new BottomType());
-    expect(env.getStandardLowerBound(A, new BottomType(), testLib),
-        new BottomType());
+    parseTestLibrary("class A;");
+    checkLowerBound(type1: "Null", type2: "A*", lowerBound: "Null");
+    checkLowerBound(type1: "A*", type2: "Null", lowerBound: "Null");
   }
 
   void test_glb_function() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var B = coreTypes.rawType(
-        _addClass(_class('B', supertype: A.classNode.asThisSupertype)),
-        Nullability.legacy);
-    var env = _makeEnv();
+    parseTestLibrary("class A; class B extends A;");
+
     // GLB(() -> A, () -> B) = () -> B
-    expect(
-        env.getStandardLowerBound(new FunctionType([], A, Nullability.legacy),
-            new FunctionType([], B, Nullability.legacy), testLib),
-        new FunctionType([], B, Nullability.legacy));
+    checkLowerBound(
+        type1: "() ->* A*", type2: "() ->* B*", lowerBound: "() ->* B*");
+
     // GLB(() -> void, (A, B) -> void) = ([A, B]) -> void
-    expect(
-        env.getStandardLowerBound(
-            new FunctionType([], voidType, Nullability.legacy),
-            new FunctionType([A, B], voidType, Nullability.legacy),
-            testLib),
-        new FunctionType([A, B], voidType, Nullability.legacy,
-            requiredParameterCount: 0));
-    expect(
-        env.getStandardLowerBound(
-            new FunctionType([A, B], voidType, Nullability.legacy),
-            new FunctionType([], voidType, Nullability.legacy),
-            testLib),
-        new FunctionType([A, B], voidType, Nullability.legacy,
-            requiredParameterCount: 0));
+    checkLowerBound(
+        type1: "() ->* void",
+        type2: "(A*, B*) ->* void",
+        lowerBound: "([A*, B*]) ->* void");
+    checkLowerBound(
+        type1: "(A*, B*) ->* void",
+        type2: "() ->* void",
+        lowerBound: "([A*, B*]) ->* void");
+
     // GLB((A) -> void, (B) -> void) = (A) -> void
-    expect(
-        env.getStandardLowerBound(
-            new FunctionType([A], voidType, Nullability.legacy),
-            new FunctionType([B], voidType, Nullability.legacy),
-            testLib),
-        new FunctionType([A], voidType, Nullability.legacy));
-    expect(
-        env.getStandardLowerBound(
-            new FunctionType([B], voidType, Nullability.legacy),
-            new FunctionType([A], voidType, Nullability.legacy),
-            testLib),
-        new FunctionType([A], voidType, Nullability.legacy));
+    checkLowerBound(
+        type1: "(A*) ->* void",
+        type2: "(B*) ->* void",
+        lowerBound: "(A*) ->* void");
+    checkLowerBound(
+        type1: "(B*) ->* void",
+        type2: "(A*) ->* void",
+        lowerBound: "(A*) ->* void");
+
     // GLB(({a: A}) -> void, ({b: B}) -> void) = ({a: A, b: B}) -> void
-    expect(
-        env.getStandardLowerBound(
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [new NamedType('a', A)]),
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [new NamedType('b', B)]),
-            testLib),
-        new FunctionType([], voidType, Nullability.legacy,
-            namedParameters: [new NamedType('a', A), new NamedType('b', B)]));
-    expect(
-        env.getStandardLowerBound(
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [new NamedType('b', B)]),
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [new NamedType('a', A)]),
-            testLib),
-        new FunctionType([], voidType, Nullability.legacy,
-            namedParameters: [new NamedType('a', A), new NamedType('b', B)]));
+    checkLowerBound(
+        type1: "({A* a}) ->* void",
+        type2: "({B* b}) ->* void",
+        lowerBound: "({A* a, B* b}) ->* void");
+    checkLowerBound(
+        type1: "({B* b}) ->* void",
+        type2: "({A* a}) ->* void",
+        lowerBound: "({A* a, B* b}) ->* void");
+
     // GLB(({a: A, c: A}) -> void, ({b: B, d: B}) -> void)
     //     = ({a: A, b: B, c: A, d: B}) -> void
-    expect(
-        env.getStandardLowerBound(
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [
-                  new NamedType('a', A),
-                  new NamedType('c', A)
-                ]),
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [
-                  new NamedType('b', B),
-                  new NamedType('d', B)
-                ]),
-            testLib),
-        new FunctionType([], voidType, Nullability.legacy,
-            namedParameters: [
-              new NamedType('a', A),
-              new NamedType('b', B),
-              new NamedType('c', A),
-              new NamedType('d', B)
-            ]));
+    checkLowerBound(
+        type1: "({A* a, A* c}) ->* void",
+        type2: "({B* b, B* d}) ->* void",
+        lowerBound: "({A* a, B* b, A* c, B* d}) ->* void");
+
     // GLB(({a: A, b: B}) -> void, ({a: B, b: A}) -> void)
     //     = ({a: A, b: A}) -> void
-    expect(
-        env.getStandardLowerBound(
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [
-                  new NamedType('a', A),
-                  new NamedType('b', B)
-                ]),
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [
-                  new NamedType('a', B),
-                  new NamedType('b', A)
-                ]),
-            testLib),
-        new FunctionType([], voidType, Nullability.legacy,
-            namedParameters: [new NamedType('a', A), new NamedType('b', A)]));
-    expect(
-        env.getStandardLowerBound(
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [
-                  new NamedType('a', B),
-                  new NamedType('b', A)
-                ]),
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [
-                  new NamedType('a', A),
-                  new NamedType('b', B)
-                ]),
-            testLib),
-        new FunctionType([], voidType, Nullability.legacy,
-            namedParameters: [new NamedType('a', A), new NamedType('b', A)]));
+    checkLowerBound(
+        type1: "({A* a, B* b}) ->* void",
+        type2: "({B* a, A* b}) ->* void",
+        lowerBound: "({A* a, A* b}) ->* void");
+    checkLowerBound(
+        type1: "({B* a, A* b}) ->* void",
+        type2: "({A* a, B* b}) ->* void",
+        lowerBound: "({A* a, A* b}) ->* void");
+
     // GLB((B, {a: A}) -> void, (B) -> void) = (B, {a: A}) -> void
-    expect(
-        env.getStandardLowerBound(
-            new FunctionType([B], voidType, Nullability.legacy,
-                namedParameters: [new NamedType('a', A)]),
-            new FunctionType([B], voidType, Nullability.legacy),
-            testLib),
-        new FunctionType([B], voidType, Nullability.legacy,
-            namedParameters: [new NamedType('a', A)]));
+    checkLowerBound(
+        type1: "(B*, {A* a}) ->* void",
+        type2: "(B*) ->* void",
+        lowerBound: "(B*, {A* a}) ->* void");
+
     // GLB(({a: A}) -> void, (B) -> void) = bottom
-    expect(
-        env.getStandardLowerBound(
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [new NamedType('a', A)]),
-            new FunctionType([B], voidType, Nullability.legacy),
-            testLib),
-        new BottomType());
+    checkLowerBound(
+        type1: "({A* a}) ->* void",
+        type2: "(B*) ->* void",
+        lowerBound: "BOTTOM");
+
     // GLB(({a: A}) -> void, ([B]) -> void) = bottom
-    expect(
-        env.getStandardLowerBound(
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [new NamedType('a', A)]),
-            new FunctionType([B], voidType, Nullability.legacy,
-                requiredParameterCount: 0),
-            testLib),
-        new BottomType());
+    checkLowerBound(
+        type1: "({A* a}) ->* void",
+        type2: "([B*]) ->* void",
+        lowerBound: "BOTTOM");
   }
 
   void test_glb_identical() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var env = _makeEnv();
-    expect(env.getStandardLowerBound(A, A, testLib), same(A));
-    expect(
-        env.getStandardLowerBound(
-            new InterfaceType(A.classNode, Nullability.legacy), A, testLib),
-        A);
+    parseTestLibrary("class A;");
+    checkLowerBound(type1: "A*", type2: "A*", lowerBound: "A*");
   }
 
   void test_glb_subtype() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var B = coreTypes.rawType(
-        _addClass(_class('B', supertype: A.classNode.asThisSupertype)),
-        Nullability.legacy);
-    var env = _makeEnv();
-    expect(env.getStandardLowerBound(A, B, testLib), same(B));
-    expect(env.getStandardLowerBound(B, A, testLib), same(B));
+    parseTestLibrary("class A; class B extends A;");
+
+    checkLowerBound(type1: "A*", type2: "B*", lowerBound: "B*");
+    checkLowerBound(type1: "B*", type2: "A*", lowerBound: "B*");
   }
 
   void test_glb_top() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var env = _makeEnv();
-    expect(env.getStandardLowerBound(dynamicType, A, testLib), same(A));
-    expect(env.getStandardLowerBound(A, dynamicType, testLib), same(A));
-    expect(env.getStandardLowerBound(objectType, A, testLib), same(A));
-    expect(env.getStandardLowerBound(A, objectType, testLib), same(A));
-    expect(env.getStandardLowerBound(voidType, A, testLib), same(A));
-    expect(env.getStandardLowerBound(A, voidType, testLib), same(A));
+    parseTestLibrary("class A;");
+    checkLowerBound(type1: "dynamic", type2: "A*", lowerBound: "A*");
+    checkLowerBound(type1: "A*", type2: "dynamic", lowerBound: "A*");
+    checkLowerBound(type1: "Object*", type2: "A*", lowerBound: "A*");
+    checkLowerBound(type1: "A*", type2: "Object*", lowerBound: "A*");
+    checkLowerBound(type1: "void", type2: "A*", lowerBound: "A*");
+    checkLowerBound(type1: "A*", type2: "void", lowerBound: "A*");
   }
 
   void test_glb_unknown() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var env = _makeEnv();
-    expect(env.getStandardLowerBound(A, unknownType, testLib), same(A));
-    expect(env.getStandardLowerBound(unknownType, A, testLib), same(A));
+    parseTestLibrary("class A;");
+    checkLowerBound(type1: "A*", type2: "UNKNOWN", lowerBound: "A*");
+    checkLowerBound(type1: "UNKNOWN", type2: "A*", lowerBound: "A*");
   }
 
   void test_glb_unrelated() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var B = coreTypes.rawType(_addClass(_class('B')), Nullability.legacy);
-    var env = _makeEnv();
-    expect(env.getStandardLowerBound(A, B, testLib), new BottomType());
+    parseTestLibrary("class A; class B;");
+    checkLowerBound(type1: "A*", type2: "B*", lowerBound: "BOTTOM");
   }
 
   void test_inferGenericFunctionOrType() {
-    var env = _makeEnv();
-    InterfaceType listClassThisType =
-        coreTypes.thisInterfaceType(listClass, testLib.nonNullable);
-    {
-      // Test an instantiation of [1, 2.0] with no context.  This should infer
-      // as List<?> during downwards inference.
-      var inferredTypes = <DartType>[unknownType];
-      TypeParameterType T = listClassThisType.typeArguments[0];
-      env.inferGenericFunctionOrType(listClassThisType, [T.parameter], null,
-          null, null, inferredTypes, testLib);
-      expect(inferredTypes[0], unknownType);
-      // And upwards inference should refine it to List<num>.
-      env.inferGenericFunctionOrType(listClassThisType, [T.parameter], [T, T],
-          [intType, doubleType], null, inferredTypes, testLib);
-      expect(inferredTypes[0], numType);
-    }
-    {
-      // Test an instantiation of [1, 2.0] with a context of List<Object>.  This
-      // should infer as List<Object> during downwards inference.
-      var inferredTypes = <DartType>[unknownType];
-      TypeParameterType T = listClassThisType.typeArguments[0];
-      env.inferGenericFunctionOrType(listClassThisType, [T.parameter], null,
-          null, _list(objectType), inferredTypes, testLib);
-      expect(inferredTypes[0], objectType);
-      // And upwards inference should preserve the type.
-      env.inferGenericFunctionOrType(listClassThisType, [T.parameter], [T, T],
-          [intType, doubleType], _list(objectType), inferredTypes, testLib);
-      expect(inferredTypes[0], objectType);
-    }
+    parseTestLibrary("");
+
+    // Test an instantiation of [1, 2.0] with no context.  This should infer
+    // as List<?> during downwards inference.
+    checkInference(
+        typeParametersToInfer: "T extends Object*",
+        functionType: "() ->* List<T*>*",
+        actualParameterTypes: null,
+        returnContextType: null,
+        expectedTypes: "UNKNOWN");
+    // And upwards inference should refine it to List<num>.
+    checkInference(
+        typeParametersToInfer: "T extends Object*",
+        functionType: "(T*, T*) ->* List<T*>*",
+        actualParameterTypes: "int*, double*",
+        returnContextType: null,
+        inferredTypesFromDownwardPhase: "UNKNOWN",
+        expectedTypes: "num*");
+
+    // Test an instantiation of [1, 2.0] with a context of List<Object>.  This
+    // should infer as List<Object> during downwards inference.
+    checkInference(
+        typeParametersToInfer: "T extends Object*",
+        functionType: "() ->* List<T*>*",
+        actualParameterTypes: null,
+        returnContextType: "List<Object*>*",
+        expectedTypes: "Object*");
+    // And upwards inference should preserve the type.
+    checkInference(
+        typeParametersToInfer: "T extends Object*",
+        functionType: "(T*, T*) ->* List<T>",
+        actualParameterTypes: "int*, double*",
+        returnContextType: "List<Object*>*",
+        inferredTypesFromDownwardPhase: "Object*",
+        expectedTypes: "Object*");
   }
 
   void test_inferTypeFromConstraints_applyBound() {
-    // class A<T extends num> {}
-    var T = new TypeParameter('T', numType);
-    coreTypes.thisInterfaceType(
-        _addClass(_class('A', typeParameters: [T])), testLib.nonNullable);
-    var env = _makeEnv();
-    {
-      // With no constraints:
-      var constraints = {T: new TypeConstraint()};
-      // Downward inference should infer A<?>
-      var inferredTypes = <DartType>[unknownType];
-      env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib,
-          downwardsInferPhase: true);
-      expect(inferredTypes[0], unknownType);
-      // Upward inference should infer A<num>
-      env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib);
-      expect(inferredTypes[0], numType);
-    }
-    {
-      // With an upper bound of Object:
-      var constraints = {T: _makeConstraint(upper: objectType)};
-      // Downward inference should infer A<num>
-      var inferredTypes = <DartType>[unknownType];
-      env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib,
-          downwardsInferPhase: true);
-      expect(inferredTypes[0], numType);
-      // Upward inference should infer A<num>
-      env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib);
-      expect(inferredTypes[0], numType);
-      // Upward inference should still infer A<num> even if there are more
-      // constraints now, because num was finalized during downward inference.
-      constraints = {T: _makeConstraint(lower: intType, upper: intType)};
-      env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib);
-      expect(inferredTypes[0], numType);
-    }
+    parseTestLibrary("");
+
+    // With no constraints:
+    // Downward inference should infer '?'
+    checkInferenceFromConstraints(
+        typeParameter: "T extends num*",
+        constraints: "",
+        downwardsInferPhase: true,
+        expected: "UNKNOWN");
+    // Upward inference should infer num
+    checkInferenceFromConstraints(
+        typeParameter: "T extends num*",
+        constraints: "",
+        downwardsInferPhase: false,
+        inferredTypeFromDownwardPhase: "UNKNOWN",
+        expected: "num*");
+
+    // With an upper bound of Object:
+    // Downward inference should infer num.
+    checkInferenceFromConstraints(
+        typeParameter: "T extends num*",
+        constraints: "<: Object*",
+        downwardsInferPhase: true,
+        expected: "num*");
+    // Upward inference should infer num.
+    checkInferenceFromConstraints(
+        typeParameter: "T extends num*",
+        constraints: "<: Object*",
+        downwardsInferPhase: false,
+        inferredTypeFromDownwardPhase: "num*",
+        expected: "num*");
+    // Upward inference should still infer num even if there are more
+    // constraints now, because num was finalized during downward inference.
+    checkInferenceFromConstraints(
+        typeParameter: "T extends num*",
+        constraints: ":> int* <: int*",
+        downwardsInferPhase: false,
+        inferredTypeFromDownwardPhase: "num*",
+        expected: "num*");
   }
 
   void test_inferTypeFromConstraints_simple() {
-    var env = _makeEnv();
-    var T = listClass.typeParameters[0];
+    parseTestLibrary("");
+
     // With an upper bound of List<?>:
-    var constraints = {T: _makeConstraint(upper: _list(unknownType))};
     // Downwards inference should infer List<List<?>>
-    var inferredTypes = <DartType>[unknownType];
-    env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib,
-        downwardsInferPhase: true);
-    expect(inferredTypes[0], _list(unknownType));
+    checkInferenceFromConstraints(
+        typeParameter: "T extends Object*",
+        constraints: "<: List<UNKNOWN>*",
+        downwardsInferPhase: true,
+        expected: "List<UNKNOWN>*");
     // Upwards inference should refine that to List<List<dynamic>>
-    env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib);
-    expect(inferredTypes[0], _list(dynamicType));
+    checkInferenceFromConstraints(
+        typeParameter: "T extends Object*",
+        constraints: "<: List<UNKNOWN>*",
+        downwardsInferPhase: false,
+        inferredTypeFromDownwardPhase: "List<UNKNOWN>*",
+        expected: "List<dynamic>*");
   }
 
   void test_lub_classic() {
@@ -382,485 +298,517 @@
     // B C
     // |X|
     // D E
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var B = coreTypes.rawType(
-        _addClass(_class('B', supertype: A.classNode.asThisSupertype)),
-        Nullability.legacy);
-    var C = coreTypes.rawType(
-        _addClass(_class('C', supertype: A.classNode.asThisSupertype)),
-        Nullability.legacy);
-    var D = coreTypes.rawType(
-        _addClass(_class('D', implementedTypes: [
-          B.classNode.asThisSupertype,
-          C.classNode.asThisSupertype
-        ])),
-        Nullability.legacy);
-    var E = coreTypes.rawType(
-        _addClass(_class('E', implementedTypes: [
-          B.classNode.asThisSupertype,
-          C.classNode.asThisSupertype
-        ])),
-        Nullability.legacy);
-    var env = _makeEnv();
-    expect(env.getStandardUpperBound(D, E, testLib), A);
+    parseTestLibrary("""
+      class A;
+      class B extends A;
+      class C extends A;
+      class D implements B, C;
+      class E implements B, C;
+    """);
+
+    checkUpperBound(type1: "D*", type2: "E*", upperBound: "A*");
   }
 
   void test_lub_commonClass() {
-    var env = _makeEnv();
-    expect(
-        env.getStandardUpperBound(_list(intType), _list(doubleType), testLib),
-        _list(numType));
+    parseTestLibrary("");
+    checkUpperBound(
+        type1: "List<int*>*",
+        type2: "List<double*>*",
+        upperBound: "List<num*>*");
   }
 
   void test_lub_function() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var B = coreTypes.rawType(
-        _addClass(_class('B', supertype: A.classNode.asThisSupertype)),
-        Nullability.legacy);
-    var env = _makeEnv();
+    parseTestLibrary("class A; class B extends A;");
+
     // LUB(() -> A, () -> B) = () -> A
-    expect(
-        env.getStandardUpperBound(new FunctionType([], A, Nullability.legacy),
-            new FunctionType([], B, Nullability.legacy), testLib),
-        new FunctionType([], A, Nullability.legacy));
+    checkUpperBound(
+        type1: "() ->* A*", type2: "() ->* B*", upperBound: "() ->* A*");
+
     // LUB(([A]) -> void, (A) -> void) = Function
-    expect(
-        env.getStandardUpperBound(
-            new FunctionType([A], voidType, Nullability.legacy,
-                requiredParameterCount: 0),
-            new FunctionType([A], voidType, Nullability.legacy),
-            testLib),
-        functionType);
+    checkUpperBound(
+        type1: "([A*]) ->* void",
+        type2: "(A*) ->* void",
+        upperBound: "Function*");
+
     // LUB(() -> void, (A, B) -> void) = Function
-    expect(
-        env.getStandardUpperBound(
-            new FunctionType([], voidType, Nullability.legacy),
-            new FunctionType([A, B], voidType, Nullability.legacy),
-            testLib),
-        functionType);
-    expect(
-        env.getStandardUpperBound(
-            new FunctionType([A, B], voidType, Nullability.legacy),
-            new FunctionType([], voidType, Nullability.legacy),
-            testLib),
-        functionType);
+    checkUpperBound(
+        type1: "() ->* void",
+        type2: "(A*, B*) ->* void",
+        upperBound: "Function*");
+    checkUpperBound(
+        type1: "(A*, B*) ->* void",
+        type2: "() ->* void",
+        upperBound: "Function*");
+
     // LUB((A) -> void, (B) -> void) = (B) -> void
-    expect(
-        env.getStandardUpperBound(
-            new FunctionType([A], voidType, Nullability.legacy),
-            new FunctionType([B], voidType, Nullability.legacy),
-            testLib),
-        new FunctionType([B], voidType, Nullability.legacy));
-    expect(
-        env.getStandardUpperBound(
-            new FunctionType([B], voidType, Nullability.legacy),
-            new FunctionType([A], voidType, Nullability.legacy),
-            testLib),
-        new FunctionType([B], voidType, Nullability.legacy));
+    checkUpperBound(
+        type1: "(A*) ->* void",
+        type2: "(B*) ->* void",
+        upperBound: "(B*) ->* void");
+    checkUpperBound(
+        type1: "(B*) ->* void",
+        type2: "(A*) ->* void",
+        upperBound: "(B*) ->* void");
+
     // LUB(({a: A}) -> void, ({b: B}) -> void) = () -> void
-    expect(
-        env.getStandardUpperBound(
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [new NamedType('a', A)]),
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [new NamedType('b', B)]),
-            testLib),
-        new FunctionType([], voidType, Nullability.legacy));
-    expect(
-        env.getStandardUpperBound(
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [new NamedType('b', B)]),
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [new NamedType('a', A)]),
-            testLib),
-        new FunctionType([], voidType, Nullability.legacy));
+    checkUpperBound(
+        type1: "({A* a}) ->* void",
+        type2: "({B* b}) ->* void",
+        upperBound: "() ->* void");
+    checkUpperBound(
+        type1: "({B* b}) ->* void",
+        type2: "({A* a}) ->* void",
+        upperBound: "() ->* void");
+
     // LUB(({a: A, c: A}) -> void, ({b: B, d: B}) -> void) = () -> void
-    expect(
-        env.getStandardUpperBound(
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [
-                  new NamedType('a', A),
-                  new NamedType('c', A)
-                ]),
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [
-                  new NamedType('b', B),
-                  new NamedType('d', B)
-                ]),
-            testLib),
-        new FunctionType([], voidType, Nullability.legacy));
+    checkUpperBound(
+        type1: "({A* a, A* c}) ->* void",
+        type2: "({B* b, B* d}) ->* void",
+        upperBound: "() ->* void");
+
     // LUB(({a: A, b: B}) -> void, ({a: B, b: A}) -> void)
     //     = ({a: B, b: B}) -> void
-    expect(
-        env.getStandardUpperBound(
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [
-                  new NamedType('a', A),
-                  new NamedType('b', B)
-                ]),
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [
-                  new NamedType('a', B),
-                  new NamedType('b', A)
-                ]),
-            testLib),
-        new FunctionType([], voidType, Nullability.legacy,
-            namedParameters: [new NamedType('a', B), new NamedType('b', B)]));
-    expect(
-        env.getStandardUpperBound(
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [
-                  new NamedType('a', B),
-                  new NamedType('b', A)
-                ]),
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [
-                  new NamedType('a', A),
-                  new NamedType('b', B)
-                ]),
-            testLib),
-        new FunctionType([], voidType, Nullability.legacy,
-            namedParameters: [new NamedType('a', B), new NamedType('b', B)]));
+    checkUpperBound(
+        type1: "({A* a, B* b}) ->* void",
+        type2: "({B* a, A* b}) ->* void",
+        upperBound: "({B* a, B* b}) ->* void");
+    checkUpperBound(
+        type1: "({B* a, A* b}) ->* void",
+        type2: "({A* a, B* b}) ->* void",
+        upperBound: "({B* a, B* b}) ->* void");
+
     // LUB((B, {a: A}) -> void, (B) -> void) = (B) -> void
-    expect(
-        env.getStandardUpperBound(
-            new FunctionType([B], voidType, Nullability.legacy,
-                namedParameters: [new NamedType('a', A)]),
-            new FunctionType([B], voidType, Nullability.legacy),
-            testLib),
-        new FunctionType([B], voidType, Nullability.legacy));
+    checkUpperBound(
+        type1: "(B*, {A* a}) ->* void",
+        type2: "(B*) ->* void",
+        upperBound: "(B*) ->* void");
+
     // LUB(({a: A}) -> void, (B) -> void) = Function
-    expect(
-        env.getStandardUpperBound(
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [new NamedType('a', A)]),
-            new FunctionType([B], voidType, Nullability.legacy),
-            testLib),
-        functionType);
+    checkUpperBound(
+        type1: "({A* a}) ->* void",
+        type2: "(B*) ->* void",
+        upperBound: "Function*");
+
     // GLB(({a: A}) -> void, ([B]) -> void) = () -> void
-    expect(
-        env.getStandardUpperBound(
-            new FunctionType([], voidType, Nullability.legacy,
-                namedParameters: [new NamedType('a', A)]),
-            new FunctionType([B], voidType, Nullability.legacy,
-                requiredParameterCount: 0),
-            testLib),
-        new FunctionType([], voidType, Nullability.legacy));
+    checkUpperBound(
+        type1: "({A* a}) ->* void",
+        type2: "([B*]) ->* void",
+        upperBound: "() ->* void");
   }
 
   void test_lub_identical() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var env = _makeEnv();
-    expect(env.getStandardUpperBound(A, A, testLib), same(A));
-    expect(
-        env.getStandardUpperBound(
-            new InterfaceType(A.classNode, Nullability.legacy), A, testLib),
-        A);
+    parseTestLibrary("class A;");
+    checkUpperBound(type1: "A*", type2: "A*", upperBound: "A*");
   }
 
   void test_lub_sameClass() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var B = coreTypes.rawType(
-        _addClass(_class('B', supertype: A.classNode.asThisSupertype)),
-        Nullability.legacy);
-    var env = _makeEnv();
-    expect(
-        env.getStandardUpperBound(_map(A, B), _map(B, A), testLib), _map(A, A));
+    parseTestLibrary("class A; class B extends A; class Map<X, Y>;");
+    checkUpperBound(
+        type1: "Map<A*, B*>*",
+        type2: "Map<B*, A*>*",
+        upperBound: "Map<A*, A*>*");
   }
 
   void test_lub_subtype() {
-    var env = _makeEnv();
-    expect(
-        env.getStandardUpperBound(_list(intType), _iterable(numType), testLib),
-        _iterable(numType));
-    expect(
-        env.getStandardUpperBound(_iterable(numType), _list(intType), testLib),
-        _iterable(numType));
+    parseTestLibrary("");
+    checkUpperBound(
+        type1: "List<int*>*",
+        type2: "Iterable<num*>*",
+        upperBound: "Iterable<num*>*");
+    checkUpperBound(
+        type1: "Iterable<num*>*",
+        type2: "List<int*>*",
+        upperBound: "Iterable<num*>*");
   }
 
   void test_lub_top() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var env = _makeEnv();
-    expect(
-        env.getStandardUpperBound(dynamicType, A, testLib), same(dynamicType));
-    expect(
-        env.getStandardUpperBound(A, dynamicType, testLib), same(dynamicType));
-    expect(env.getStandardUpperBound(objectType, A, testLib), same(objectType));
-    expect(env.getStandardUpperBound(A, objectType, testLib), same(objectType));
-    expect(env.getStandardUpperBound(voidType, A, testLib), same(voidType));
-    expect(env.getStandardUpperBound(A, voidType, testLib), same(voidType));
-    expect(env.getStandardUpperBound(dynamicType, objectType, testLib),
-        same(dynamicType));
-    expect(env.getStandardUpperBound(objectType, dynamicType, testLib),
-        same(dynamicType));
-    expect(env.getStandardUpperBound(dynamicType, voidType, testLib),
-        same(voidType));
-    expect(env.getStandardUpperBound(voidType, dynamicType, testLib),
-        same(voidType));
-    expect(env.getStandardUpperBound(objectType, voidType, testLib),
-        same(voidType));
-    expect(env.getStandardUpperBound(voidType, objectType, testLib),
-        same(voidType));
+    parseTestLibrary("class A;");
+
+    checkUpperBound(type1: "dynamic", type2: "A*", upperBound: "dynamic");
+    checkUpperBound(type1: "A*", type2: "dynamic", upperBound: "dynamic");
+    checkUpperBound(type1: "Object*", type2: "A*", upperBound: "Object*");
+    checkUpperBound(type1: "A*", type2: "Object*", upperBound: "Object*");
+    checkUpperBound(type1: "void", type2: "A*", upperBound: "void");
+    checkUpperBound(type1: "A*", type2: "void", upperBound: "void");
+    checkUpperBound(type1: "dynamic", type2: "Object*", upperBound: "dynamic");
+    checkUpperBound(type1: "Object*", type2: "dynamic", upperBound: "dynamic");
+    checkUpperBound(type1: "dynamic", type2: "void", upperBound: "void");
+    checkUpperBound(type1: "void", type2: "dynamic", upperBound: "void");
+    checkUpperBound(type1: "Object*", type2: "void", upperBound: "void");
+    checkUpperBound(type1: "void", type2: "Object*", upperBound: "void");
   }
 
   void test_lub_typeParameter() {
-    var T = new TypeParameterType(new TypeParameter('T'), Nullability.legacy);
-    T.parameter.bound = _list(T);
-    var U = new TypeParameterType(new TypeParameter('U'), Nullability.legacy);
-    U.parameter.bound = _list(new BottomType());
-    var env = _makeEnv();
+    parseTestLibrary("");
+
     // LUB(T, T) = T
-    expect(env.getStandardUpperBound(T, T, testLib), same(T));
+    checkUpperBound(
+        type1: "T*",
+        type2: "T*",
+        upperBound: "T*",
+        typeParameters: "T extends List<T*>*");
+
     // LUB(T, List<Bottom>) = LUB(List<Object>, List<Bottom>) = List<Object>
-    expect(env.getStandardUpperBound(T, _list(new BottomType()), testLib),
-        _list(objectType));
-    expect(env.getStandardUpperBound(_list(new BottomType()), T, testLib),
-        _list(objectType));
+    checkUpperBound(
+        type1: "T*",
+        type2: "List<Null>*",
+        upperBound: "List<Object*>*",
+        typeParameters: "T extends List<T*>*");
+    checkUpperBound(
+        type1: "List<Null>*",
+        type2: "T*",
+        upperBound: "List<Object*>*",
+        typeParameters: "T extends List<T*>*");
+
     // LUB(T, U) = LUB(List<Object>, U) = LUB(List<Object>, List<Bottom>)
     // = List<Object>
-    expect(env.getStandardUpperBound(T, U, testLib), _list(objectType));
-    expect(env.getStandardUpperBound(U, T, testLib), _list(objectType));
+    checkUpperBound(
+        type1: "T*",
+        type2: "U*",
+        upperBound: "List<Object*>*",
+        typeParameters: "T extends List<T*>*, U extends List<Null>*");
+    checkUpperBound(
+        type1: "U*",
+        type2: "T*",
+        upperBound: "List<Object*>*",
+        typeParameters: "T extends List<T*>*, U extends List<Null>*");
   }
 
   void test_lub_unknown() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var env = _makeEnv();
-    expect(env.getStandardLowerBound(A, unknownType, testLib), same(A));
-    expect(env.getStandardLowerBound(unknownType, A, testLib), same(A));
+    parseTestLibrary("class A;");
+    checkUpperBound(type1: "A*", type2: "UNKNOWN", upperBound: "A*");
+    checkUpperBound(type1: "UNKNOWN", type2: "A*", upperBound: "A*");
   }
 
   void test_solveTypeConstraint() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var B = coreTypes.rawType(
-        _addClass(_class('B', supertype: A.classNode.asThisSupertype)),
-        Nullability.legacy);
-    var env = _makeEnv();
+    parseTestLibrary("""
+      class A;
+      class B extends A;
+      
+      class C<T extends Object*>;
+      class D<T extends Object*> extends C<T*>;
+    """);
+
     // Solve(? <: T <: ?) => ?
-    expect(env.solveTypeConstraint(_makeConstraint(), topType, bottomType),
-        same(unknownType));
+    checkConstraintSolving("", "UNKNOWN", grounded: false);
+
     // Solve(? <: T <: ?, grounded) => dynamic
-    expect(
-        env.solveTypeConstraint(_makeConstraint(), topType, bottomType,
-            grounded: true),
-        dynamicType);
+    checkConstraintSolving("", "dynamic", grounded: true);
+
     // Solve(A <: T <: ?) => A
-    expect(
-        env.solveTypeConstraint(_makeConstraint(lower: A), topType, bottomType),
-        A);
+    checkConstraintSolving(":> A*", "A*", grounded: false);
+
     // Solve(A <: T <: ?, grounded) => A
-    expect(
-        env.solveTypeConstraint(_makeConstraint(lower: A), topType, bottomType,
-            grounded: true),
-        A);
+    checkConstraintSolving(":> A*", "A*", grounded: true);
+
     // Solve(A<?> <: T <: ?) => A<?>
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                lower: new InterfaceType(
-                    A.classNode, Nullability.legacy, [unknownType])),
-            topType,
-            bottomType),
-        new InterfaceType(A.classNode, Nullability.legacy, [unknownType]));
+    checkConstraintSolving(":> C<UNKNOWN>*", "C<UNKNOWN>*", grounded: false);
+
     // Solve(A<?> <: T <: ?, grounded) => A<Null>
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                lower: new InterfaceType(
-                    A.classNode, Nullability.legacy, [unknownType])),
-            topType,
-            bottomType,
-            grounded: true),
-        new InterfaceType(A.classNode, Nullability.legacy, [const NullType()]));
+    checkConstraintSolving(":> C<UNKNOWN>*", "C<Null>*", grounded: true);
+
     // Solve(? <: T <: A) => A
-    expect(
-        env.solveTypeConstraint(_makeConstraint(upper: A), topType, bottomType),
-        A);
+    checkConstraintSolving("<: A*", "A*", grounded: false);
+
     // Solve(? <: T <: A, grounded) => A
-    expect(
-        env.solveTypeConstraint(_makeConstraint(upper: A), topType, bottomType,
-            grounded: true),
-        A);
+    checkConstraintSolving("<: A*", "A*", grounded: true);
+
     // Solve(? <: T <: A<?>) => A<?>
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                upper: new InterfaceType(
-                    A.classNode, Nullability.legacy, [unknownType])),
-            topType,
-            bottomType),
-        new InterfaceType(A.classNode, Nullability.legacy, [unknownType]));
+    checkConstraintSolving("<: C<UNKNOWN>*", "C<UNKNOWN>*", grounded: false);
+
     // Solve(? <: T <: A<?>, grounded) => A<dynamic>
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                upper: new InterfaceType(
-                    A.classNode, Nullability.legacy, [unknownType])),
-            topType,
-            bottomType,
-            grounded: true),
-        new InterfaceType(A.classNode, Nullability.legacy, [dynamicType]));
+    checkConstraintSolving("<: C<UNKNOWN>*", "C<dynamic>*", grounded: true);
+
     // Solve(B <: T <: A) => B
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(lower: B, upper: A), topType, bottomType),
-        B);
+    checkConstraintSolving(":> B* <: A*", "B*", grounded: false);
+
     // Solve(B <: T <: A, grounded) => B
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(lower: B, upper: A), topType, bottomType,
-            grounded: true),
-        B);
+    checkConstraintSolving(":> B* <: A*", "B*", grounded: true);
+
     // Solve(B<?> <: T <: A) => A
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                lower: new InterfaceType(
-                    B.classNode, Nullability.legacy, [unknownType]),
-                upper: A),
-            topType,
-            bottomType),
-        A);
+    checkConstraintSolving(":> D<UNKNOWN>* <: C<dynamic>*", "C<dynamic>*",
+        grounded: false);
+
     // Solve(B<?> <: T <: A, grounded) => A
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                lower: new InterfaceType(
-                    B.classNode, Nullability.legacy, [unknownType]),
-                upper: A),
-            topType,
-            bottomType,
-            grounded: true),
-        A);
+    checkConstraintSolving(":> D<UNKNOWN>* <: C<dynamic>*", "C<dynamic>*",
+        grounded: true);
+
     // Solve(B <: T <: A<?>) => B
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                lower: B,
-                upper: new InterfaceType(
-                    A.classNode, Nullability.legacy, [unknownType])),
-            topType,
-            bottomType),
-        B);
+    checkConstraintSolving(":> D<Null>* <: C<UNKNOWN>*", "D<Null>*",
+        grounded: false);
+
     // Solve(B <: T <: A<?>, grounded) => B
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                lower: B,
-                upper: new InterfaceType(
-                    A.classNode, Nullability.legacy, [unknownType])),
-            topType,
-            bottomType,
-            grounded: true),
-        B);
+    checkConstraintSolving(":> D<Null>* <: C<UNKNOWN>*", "D<Null>*",
+        grounded: true);
+
     // Solve(B<?> <: T <: A<?>) => B<?>
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                lower: new InterfaceType(
-                    B.classNode, Nullability.legacy, [unknownType]),
-                upper: new InterfaceType(
-                    A.classNode, Nullability.legacy, [unknownType])),
-            topType,
-            bottomType),
-        new InterfaceType(B.classNode, Nullability.legacy, [unknownType]));
+    checkConstraintSolving(":> D<UNKNOWN>* <: C<UNKNOWN>*", "D<UNKNOWN>*",
+        grounded: false);
+
     // Solve(B<?> <: T <: A<?>) => B<Null>
-    expect(
-        env.solveTypeConstraint(
-            _makeConstraint(
-                lower: new InterfaceType(
-                    B.classNode, Nullability.legacy, [unknownType]),
-                upper: new InterfaceType(
-                    A.classNode, Nullability.legacy, [unknownType])),
-            topType,
-            bottomType,
-            grounded: true),
-        new InterfaceType(B.classNode, Nullability.legacy, [const NullType()]));
+    checkConstraintSolving(":> D<UNKNOWN>* <: C<UNKNOWN>*", "D<Null>*",
+        grounded: true);
   }
 
   void test_typeConstraint_default() {
-    var typeConstraint = new TypeConstraint();
-    expect(typeConstraint.lower, same(unknownType));
-    expect(typeConstraint.upper, same(unknownType));
+    parseTestLibrary("");
+    checkConstraintUpperBound(constraint: "", bound: "UNKNOWN");
+    checkConstraintLowerBound(constraint: "", bound: "UNKNOWN");
   }
 
   void test_typeSatisfiesConstraint() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var B = coreTypes.rawType(
-        _addClass(_class('B', supertype: A.classNode.asThisSupertype)),
-        Nullability.legacy);
-    var C = coreTypes.rawType(
-        _addClass(_class('C', supertype: B.classNode.asThisSupertype)),
-        Nullability.legacy);
-    var D = coreTypes.rawType(
-        _addClass(_class('D', supertype: C.classNode.asThisSupertype)),
-        Nullability.legacy);
-    var E = coreTypes.rawType(
-        _addClass(_class('E', supertype: D.classNode.asThisSupertype)),
-        Nullability.legacy);
-    var env = _makeEnv();
-    var typeConstraint = _makeConstraint(upper: B, lower: D);
-    expect(env.typeSatisfiesConstraint(A, typeConstraint), isFalse);
-    expect(env.typeSatisfiesConstraint(B, typeConstraint), isTrue);
-    expect(env.typeSatisfiesConstraint(C, typeConstraint), isTrue);
-    expect(env.typeSatisfiesConstraint(D, typeConstraint), isTrue);
-    expect(env.typeSatisfiesConstraint(E, typeConstraint), isFalse);
+    parseTestLibrary("""
+      class A;
+      class B extends A;
+      class C extends B;
+      class D extends C;
+      class E extends D;
+    """);
+
+    checkTypeDoesntSatisfyConstraint("A*", ":> D* <: B*");
+    checkTypeSatisfiesConstraint("B*", ":> D* <: B*");
+    checkTypeSatisfiesConstraint("C*", ":> D* <: B*");
+    checkTypeSatisfiesConstraint("D*", ":> D* <: B*");
+    checkTypeDoesntSatisfyConstraint("E*", ":> D* <: B*");
   }
 
   void test_unknown_at_bottom() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var env = _makeEnv();
-    expect(
-        env.isSubtypeOf(unknownType, A, SubtypeCheckMode.ignoringNullabilities),
-        isTrue);
+    parseTestLibrary("class A;");
+    checkIsLegacySubtype("UNKNOWN", "A*");
   }
 
   void test_unknown_at_top() {
-    var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
-    var env = _makeEnv();
+    parseTestLibrary("class A; class Map<X, Y>;");
+    checkIsLegacySubtype("A*", "UNKNOWN");
+    checkIsLegacySubtype("Map<A*, A*>*", "Map<UNKNOWN, UNKNOWN>*");
+  }
+
+  void checkConstraintSolving(String constraint, String expected,
+      {bool grounded}) {
+    assert(grounded != null);
     expect(
-        env.isSubtypeOf(A, unknownType, SubtypeCheckMode.ignoringNullabilities),
-        isTrue);
+        typeSchemaEnvironment.solveTypeConstraint(
+            parseConstraint(constraint), new DynamicType(), new NullType(),
+            grounded: grounded),
+        parseType(expected));
+  }
+
+  void checkConstraintUpperBound({String constraint, String bound}) {
+    assert(constraint != null);
+    assert(bound != null);
+
+    expect(parseConstraint(constraint).upper, parseType(bound));
+  }
+
+  void checkConstraintLowerBound({String constraint, String bound}) {
+    assert(constraint != null);
+    assert(bound != null);
+
+    expect(parseConstraint(constraint).lower, parseType(bound));
+  }
+
+  void checkTypeSatisfiesConstraint(String type, String constraint) {
     expect(
-        env.isSubtypeOf(_map(A, A), _map(unknownType, unknownType),
-            SubtypeCheckMode.ignoringNullabilities),
+        typeSchemaEnvironment.typeSatisfiesConstraint(
+            parseType(type), parseConstraint(constraint)),
         isTrue);
   }
 
-  Class _addClass(Class c) {
-    testLib.addClass(c);
-    return c;
+  void checkTypeDoesntSatisfyConstraint(String type, String constraint) {
+    expect(
+        typeSchemaEnvironment.typeSatisfiesConstraint(
+            parseType(type), parseConstraint(constraint)),
+        isFalse);
   }
 
-  Class _class(String name,
-      {Supertype supertype,
-      List<TypeParameter> typeParameters,
-      List<Supertype> implementedTypes}) {
-    return new Class(
-        name: name,
-        supertype: supertype ?? objectClass.asThisSupertype,
-        typeParameters: typeParameters,
-        implementedTypes: implementedTypes);
+  void checkIsSubtype(String subtype, String supertype) {
+    expect(
+        typeSchemaEnvironment
+            .performNullabilityAwareSubtypeCheck(
+                parseType(subtype), parseType(supertype))
+            .isSubtypeWhenUsingNullabilities(),
+        isTrue);
   }
 
-  DartType _iterable(DartType elementType) =>
-      new InterfaceType(iterableClass, Nullability.legacy, [elementType]);
-
-  DartType _list(DartType elementType) =>
-      new InterfaceType(listClass, Nullability.legacy, [elementType]);
-
-  TypeConstraint _makeConstraint(
-      {DartType lower: const UnknownType(),
-      DartType upper: const UnknownType()}) {
-    return new TypeConstraint()
-      ..lower = lower
-      ..upper = upper;
+  void checkIsLegacySubtype(String subtype, String supertype) {
+    expect(
+        typeSchemaEnvironment
+            .performNullabilityAwareSubtypeCheck(
+                parseType(subtype), parseType(supertype))
+            .isSubtypeWhenIgnoringNullabilities(),
+        isTrue);
   }
 
-  TypeSchemaEnvironment _makeEnv() {
-    return new TypeSchemaEnvironment(
-        coreTypes, new ClassHierarchy(component, coreTypes));
+  void checkIsNotSubtype(String subtype, String supertype) {
+    expect(
+        typeSchemaEnvironment
+            .performNullabilityAwareSubtypeCheck(
+                parseType(subtype), parseType(supertype))
+            .isSubtypeWhenIgnoringNullabilities(),
+        isFalse);
   }
 
-  DartType _map(DartType key, DartType value) =>
-      new InterfaceType(mapClass, Nullability.legacy, [key, value]);
+  void checkUpperBound(
+      {String type1, String type2, String upperBound, String typeParameters}) {
+    assert(type1 != null);
+    assert(type2 != null);
+    assert(upperBound != null);
+
+    typeParserEnvironment.withTypeParameters(typeParameters,
+        (List<TypeParameter> typeParameterNodes) {
+      expect(
+          typeSchemaEnvironment.getStandardUpperBound(
+              parseType(type1), parseType(type2), testLibrary),
+          parseType(upperBound));
+    });
+  }
+
+  void checkLowerBound(
+      {String type1, String type2, String lowerBound, String typeParameters}) {
+    assert(type1 != null);
+    assert(type2 != null);
+    assert(lowerBound != null);
+
+    typeParserEnvironment.withTypeParameters(typeParameters,
+        (List<TypeParameter> typeParameterNodes) {
+      expect(
+          typeSchemaEnvironment.getStandardLowerBound(
+              parseType(type1), parseType(type2), testLibrary),
+          parseType(lowerBound));
+    });
+  }
+
+  void checkInference(
+      {String typeParametersToInfer,
+      String functionType,
+      String actualParameterTypes,
+      String returnContextType,
+      String inferredTypesFromDownwardPhase,
+      String expectedTypes}) {
+    assert(typeParametersToInfer != null);
+    assert(functionType != null);
+    assert(expectedTypes != null);
+
+    typeParserEnvironment.withTypeParameters(typeParametersToInfer,
+        (List<TypeParameter> typeParameterNodesToInfer) {
+      FunctionType functionTypeNode = parseType(functionType);
+      DartType returnContextTypeNode =
+          returnContextType == null ? null : parseType(returnContextType);
+      List<DartType> actualTypeNodes = actualParameterTypes == null
+          ? null
+          : parseTypes(actualParameterTypes);
+      List<DartType> expectedTypeNodes =
+          expectedTypes == null ? null : parseTypes(expectedTypes);
+      DartType declaredReturnTypeNode = functionTypeNode.returnType;
+      List<DartType> formalTypeNodes = actualParameterTypes == null
+          ? null
+          : functionTypeNode.positionalParameters;
+
+      List<DartType> inferredTypeNodes;
+      if (inferredTypesFromDownwardPhase == null) {
+        inferredTypeNodes = new List<DartType>.generate(
+            typeParameterNodesToInfer.length, (_) => new UnknownType());
+      } else {
+        inferredTypeNodes = parseTypes(inferredTypesFromDownwardPhase);
+      }
+
+      typeSchemaEnvironment.inferGenericFunctionOrType(
+          declaredReturnTypeNode,
+          typeParameterNodesToInfer,
+          formalTypeNodes,
+          actualTypeNodes,
+          returnContextTypeNode,
+          inferredTypeNodes,
+          testLibrary);
+
+      assert(
+          inferredTypeNodes.length == expectedTypeNodes.length,
+          "The numbers of expected types and type parameters to infer "
+          "mismatch.");
+      for (int i = 0; i < inferredTypeNodes.length; ++i) {
+        expect(inferredTypeNodes[i], expectedTypeNodes[i]);
+      }
+    });
+  }
+
+  void checkInferenceFromConstraints(
+      {String typeParameter,
+      String constraints,
+      String inferredTypeFromDownwardPhase,
+      bool downwardsInferPhase,
+      String expected}) {
+    assert(typeParameter != null);
+    assert(expected != null);
+    assert(downwardsInferPhase != null);
+    assert(inferredTypeFromDownwardPhase == null || !downwardsInferPhase);
+
+    typeParserEnvironment.withTypeParameters(typeParameter,
+        (List<TypeParameter> typeParameterNodes) {
+      assert(typeParameterNodes.length == 1);
+
+      TypeConstraint typeConstraint = parseConstraint(constraints);
+      DartType expectedTypeNode = parseType(expected);
+      TypeParameter typeParameterNode = typeParameterNodes.single;
+      List<DartType> inferredTypeNodes = <DartType>[
+        inferredTypeFromDownwardPhase == null
+            ? new UnknownType()
+            : parseType(inferredTypeFromDownwardPhase)
+      ];
+
+      typeSchemaEnvironment.inferTypeFromConstraints(
+          {typeParameterNode: typeConstraint},
+          [typeParameterNode],
+          inferredTypeNodes,
+          testLibrary,
+          downwardsInferPhase: downwardsInferPhase);
+
+      expect(inferredTypeNodes.single, expectedTypeNode);
+    });
+  }
+
+  /// Parses a string like "<: T <: S >: R" into a [TypeConstraint].
+  ///
+  /// The [constraint] string is assumed to be a sequence of bounds added to the
+  /// constraint.  Each element of the sequence is either "<: T" or ":> T",
+  /// where the former adds an upper bound and the latter adds a lower bound.
+  /// The bounds are added to the constraint in the order they are mentioned in
+  /// the [constraint] string, from left to right.
+  TypeConstraint parseConstraint(String constraint) {
+    TypeConstraint result = new TypeConstraint();
+    List<String> upperBoundSegments = constraint.split("<:");
+    bool firstUpperBoundSegment = true;
+    for (String upperBoundSegment in upperBoundSegments) {
+      if (firstUpperBoundSegment) {
+        firstUpperBoundSegment = false;
+        if (upperBoundSegment.isEmpty) {
+          continue;
+        }
+      }
+      List<String> lowerBoundSegments = upperBoundSegment.split(":>");
+      bool firstLowerBoundSegment = true;
+      for (String segment in lowerBoundSegments) {
+        if (firstLowerBoundSegment) {
+          firstLowerBoundSegment = false;
+          if (segment.isNotEmpty) {
+            typeSchemaEnvironment.addUpperBound(
+                result, parseType(segment), testLibrary);
+          }
+        } else {
+          typeSchemaEnvironment.addLowerBound(
+              result, parseType(segment), testLibrary);
+        }
+      }
+    }
+    return result;
+  }
+
+  DartType parseType(String type) {
+    return typeParserEnvironment.parseType(type,
+        additionalTypes: additionalTypes);
+  }
+
+  List<DartType> parseTypes(String types) {
+    return typeParserEnvironment.parseTypes(types,
+        additionalTypes: additionalTypes);
+  }
 }
diff --git a/pkg/front_end/test/flutter_gallery_leak_tester.dart b/pkg/front_end/test/flutter_gallery_leak_tester.dart
index f8f32f4..fa3a949 100644
--- a/pkg/front_end/test/flutter_gallery_leak_tester.dart
+++ b/pkg/front_end/test/flutter_gallery_leak_tester.dart
@@ -151,7 +151,7 @@
     throw "Didn't find $galleryDotPackages";
   }
 
-  List<helper.Interest> interests = new List<helper.Interest>();
+  List<helper.Interest> interests = <helper.Interest>[];
   interests.add(new helper.Interest(
       Uri.parse("package:kernel/ast.dart"), "Library", ["fileUri"]));
   helper.VMServiceHeapHelperSpecificExactLeakFinder heapHelper =
diff --git a/pkg/front_end/test/incremental_compiler_leak_test.dart b/pkg/front_end/test/incremental_compiler_leak_test.dart
index 7d3fcd7..9cefae5 100644
--- a/pkg/front_end/test/incremental_compiler_leak_test.dart
+++ b/pkg/front_end/test/incremental_compiler_leak_test.dart
@@ -143,8 +143,7 @@
           }
           List<int> listOfInstanceCounts = instanceCounts[member.classRef];
           if (listOfInstanceCounts == null) {
-            listOfInstanceCounts =
-                instanceCounts[member.classRef] = new List<int>();
+            listOfInstanceCounts = instanceCounts[member.classRef] = <int>[];
           }
           while (listOfInstanceCounts.length < iterationNumber - 2) {
             listOfInstanceCounts.add(0);
diff --git a/pkg/front_end/test/incremental_dart2js_tester.dart b/pkg/front_end/test/incremental_dart2js_tester.dart
index 59c95ee..05b5538 100644
--- a/pkg/front_end/test/incremental_dart2js_tester.dart
+++ b/pkg/front_end/test/incremental_dart2js_tester.dart
@@ -51,7 +51,7 @@
   Map<Uri, List<int>> libToData;
   List<Uri> uris;
 
-  List<Uri> diffs = new List<Uri>();
+  List<Uri> diffs = <Uri>[];
   Set<Uri> componentUris = new Set<Uri>();
 
   Dart2jsTester(this.useExperimentalInvalidation, this.fast,
@@ -63,7 +63,7 @@
       debugger();
     }
 
-    diffs = new List<Uri>();
+    diffs = <Uri>[];
     componentUris = new Set<Uri>();
 
     Stopwatch localStopwatch = new Stopwatch()..start();
diff --git a/pkg/front_end/test/incremental_flutter_tester.dart b/pkg/front_end/test/incremental_flutter_tester.dart
index ac3be91..4d2aa12 100644
--- a/pkg/front_end/test/incremental_flutter_tester.dart
+++ b/pkg/front_end/test/incremental_flutter_tester.dart
@@ -122,7 +122,7 @@
 
   c = null;
 
-  List<Uri> diffs = new List<Uri>();
+  List<Uri> diffs = <Uri>[];
   Set<Uri> componentUris = new Set<Uri>();
 
   Stopwatch localStopwatch = new Stopwatch()..start();
diff --git a/pkg/front_end/test/incremental_load_from_dill_suite.dart b/pkg/front_end/test/incremental_load_from_dill_suite.dart
index 45cc440..3a00d7e 100644
--- a/pkg/front_end/test/incremental_load_from_dill_suite.dart
+++ b/pkg/front_end/test/incremental_load_from_dill_suite.dart
@@ -316,7 +316,7 @@
   Map<String, List<int>> moduleResult = new Map<String, List<int>>();
 
   for (String moduleName in module.keys) {
-    List<Uri> moduleSources = new List<Uri>();
+    List<Uri> moduleSources = <Uri>[];
     Uri packagesUri;
     for (String filename in module[moduleName].keys) {
       Uri uri = base.resolve(filename);
@@ -343,7 +343,7 @@
         new TestIncrementalCompiler(options, moduleSources.first, null);
     Component c = await compiler.computeDelta(entryPoints: moduleSources);
     c.computeCanonicalNames();
-    List<Library> wantedLibs = new List<Library>();
+    List<Library> wantedLibs = <Library>[];
     for (Library lib in c.libraries) {
       if (moduleSources.contains(lib.importUri) ||
           moduleSources.contains(lib.fileUri)) {
@@ -451,7 +451,7 @@
           c.adoptChildren();
         }
 
-        modulesToUse = new List<Component>();
+        modulesToUse = <Component>[];
         for (String moduleName in world["modules"]) {
           Component moduleComponent = moduleComponents[moduleName];
           if (moduleComponent != null) {
@@ -594,7 +594,7 @@
       if (world["entry"] is String) {
         entries = [base.resolve(world["entry"])];
       } else {
-        entries = new List<Uri>();
+        entries = <Uri>[];
         List<dynamic> entryList = world["entry"];
         for (String entry in entryList) {
           entries.add(base.resolve(entry));
@@ -624,7 +624,7 @@
         }
       }
 
-      List<Uri> invalidated = new List<Uri>();
+      List<Uri> invalidated = <Uri>[];
       if (world["invalidate"] != null) {
         for (String filename in world["invalidate"]) {
           Uri uri = base.resolve(filename);
@@ -1535,13 +1535,13 @@
 Result<TestData> checkNeededDillLibraries(
     YamlMap world, TestData data, Set<Library> neededDillLibraries, Uri base) {
   if (world["neededDillLibraries"] != null) {
-    List<Uri> actualContent = new List<Uri>();
+    List<Uri> actualContent = <Uri>[];
     for (Library lib in neededDillLibraries) {
       if (lib.importUri.scheme == "dart") continue;
       actualContent.add(lib.importUri);
     }
 
-    List<Uri> expectedContent = new List<Uri>();
+    List<Uri> expectedContent = <Uri>[];
     for (String entry in world["neededDillLibraries"]) {
       expectedContent.add(base.resolve(entry));
     }
@@ -1580,7 +1580,7 @@
 
 String componentToStringSdkFiltered(Component component) {
   Component c = new Component();
-  List<Uri> dartUris = new List<Uri>();
+  List<Uri> dartUris = <Uri>[];
   for (Library lib in component.libraries) {
     if (lib.importUri.scheme == "dart") {
       dartUris.add(lib.importUri);
diff --git a/pkg/front_end/test/lint_suite.dart b/pkg/front_end/test/lint_suite.dart
index 938c1bf..8547196 100644
--- a/pkg/front_end/test/lint_suite.dart
+++ b/pkg/front_end/test/lint_suite.dart
@@ -194,7 +194,7 @@
 }
 
 class LintListener extends Listener {
-  List<String> problems = new List<String>();
+  List<String> problems = <String>[];
   LintTestDescription description;
   Uri uri;
 
@@ -204,7 +204,7 @@
 }
 
 class ExplicitTypeLintListener extends LintListener {
-  List<LatestType> _latestTypes = new List<LatestType>();
+  List<LatestType> _latestTypes = <LatestType>[];
 
   @override
   void beginVariablesDeclaration(
diff --git a/pkg/front_end/test/parser_suite.dart b/pkg/front_end/test/parser_suite.dart
index da464ac..8ef6ae8 100644
--- a/pkg/front_end/test/parser_suite.dart
+++ b/pkg/front_end/test/parser_suite.dart
@@ -171,7 +171,7 @@
 
   Future<Result<TestDescription>> run(
       TestDescription description, Context context) {
-    List<int> lineStarts = new List<int>();
+    List<int> lineStarts = <int>[];
 
     Token firstToken =
         scanUri(description.uri, description.shortName, lineStarts: lineStarts);
@@ -215,7 +215,7 @@
 
   Future<Result<TestDescription>> run(
       TestDescription description, Context context) {
-    List<int> lineStarts = new List<int>();
+    List<int> lineStarts = <int>[];
     Token firstToken =
         scanUri(description.uri, description.shortName, lineStarts: lineStarts);
 
@@ -251,7 +251,7 @@
 
   Future<Result<TestDescription>> run(
       TestDescription description, Context context) {
-    List<int> lineStarts = new List<int>();
+    List<int> lineStarts = <int>[];
     Token firstToken =
         scanUri(description.uri, description.shortName, lineStarts: lineStarts);
 
@@ -412,7 +412,7 @@
   final bool annotateLines;
   final Source source;
   final String shortName;
-  final List<String> errors = new List<String>();
+  final List<String> errors = <String>[];
   Location latestSeenLocation;
 
   ParserTestListenerWithMessageFormatting(
diff --git a/pkg/front_end/test/spell_checking_cleanup_lists.dart b/pkg/front_end/test/spell_checking_cleanup_lists.dart
index 3cca7cb..af7d5bd 100644
--- a/pkg/front_end/test/spell_checking_cleanup_lists.dart
+++ b/pkg/front_end/test/spell_checking_cleanup_lists.dart
@@ -14,7 +14,7 @@
     for (spell.Dictionaries dictionary in spell.Dictionaries.values) {
       if (dictionary == spell.Dictionaries.common) continue;
       Uri uri = spell.dictionaryToUri(dictionary);
-      List<String> keep = new List<String>();
+      List<String> keep = <String>[];
       for (String line in new File.fromUri(uri).readAsLinesSync()) {
         if (!commonWords.contains(line)) {
           keep.add(line);
@@ -30,7 +30,7 @@
     Set<String> codeWords =
         spell.loadedDictionaries[spell.Dictionaries.cfeCode];
     Uri uri = spell.dictionaryToUri(spell.Dictionaries.cfeTests);
-    List<String> keep = new List<String>();
+    List<String> keep = <String>[];
     for (String line in new File.fromUri(uri).readAsLinesSync()) {
       if (!codeWords.contains(line)) {
         keep.add(line);
diff --git a/pkg/front_end/test/spell_checking_utils.dart b/pkg/front_end/test/spell_checking_utils.dart
index 948ea88..b0f33a3 100644
--- a/pkg/front_end/test/spell_checking_utils.dart
+++ b/pkg/front_end/test/spell_checking_utils.dart
@@ -28,7 +28,7 @@
   List<List<String>> wrongWordsAlternatives;
   List<int> wrongWordsOffset;
   List<bool> wrongWordDenylisted;
-  List<int> wordOffsets = new List<int>();
+  List<int> wordOffsets = <int>[];
   List<String> words =
       splitStringIntoWords(s, wordOffsets, splitAsCode: splitAsCode);
   List<Set<String>> dictionariesUnpacked = [];
@@ -51,13 +51,13 @@
       }
     }
     if (!found) {
-      wrongWords ??= new List<String>();
+      wrongWords ??= <String>[];
       wrongWords.add(word);
-      wrongWordsAlternatives ??= new List<List<String>>();
+      wrongWordsAlternatives ??= <List<String>>[];
       wrongWordsAlternatives.add(findAlternatives(word, dictionariesUnpacked));
-      wrongWordsOffset ??= new List<int>();
+      wrongWordsOffset ??= <int>[];
       wrongWordsOffset.add(offset);
-      wrongWordDenylisted ??= new List<bool>();
+      wrongWordDenylisted ??= <bool>[];
       wrongWordDenylisted
           .add(loadedDictionaries[Dictionaries.denylist].contains(word));
     }
@@ -79,7 +79,7 @@
   }
 
   void ok(String w) {
-    result ??= new List<String>();
+    result ??= <String>[];
     result.add(w);
   }
 
@@ -185,7 +185,7 @@
 
 List<String> splitStringIntoWords(String s, List<int> splitOffsets,
     {bool splitAsCode: false}) {
-  List<String> result = new List<String>();
+  List<String> result = <String>[];
   // Match whitespace and the characters "-", "=", "|", "/", ",".
   String regExpStringInner = r"\s-=\|\/,";
   if (splitAsCode) {
@@ -204,8 +204,8 @@
   Iterator<RegExpMatch> matchesIterator =
       new RegExp(regExp).allMatches(s).iterator;
   int latestMatch = 0;
-  List<String> split = new List<String>();
-  List<int> splitOffset = new List<int>();
+  List<String> split = <String>[];
+  List<int> splitOffset = <int>[];
   while (matchesIterator.moveNext()) {
     RegExpMatch match = matchesIterator.current;
     if (match.start > latestMatch) {
@@ -385,7 +385,7 @@
     }
 
     if (interactive && dictionaryToUse != null) {
-      List<String> addedWords = new List<String>();
+      List<String> addedWords = <String>[];
       for (String s in reportedWords) {
         print("- $s");
         String answer;
@@ -420,8 +420,8 @@
         File dictionaryFile =
             new File.fromUri(dictionaryToUri(dictionaryToUse));
         List<String> lines = dictionaryFile.readAsLinesSync();
-        List<String> header = new List<String>();
-        List<String> sortThis = new List<String>();
+        List<String> header = <String>[];
+        List<String> sortThis = <String>[];
         for (String line in lines) {
           if (line.startsWith("#")) {
             header.add(line);
@@ -433,7 +433,7 @@
         }
         sortThis.addAll(addedWords);
         sortThis.sort();
-        lines = new List<String>();
+        lines = <String>[];
         lines.addAll(header);
         if (header.isEmpty || header.last.isNotEmpty) {
           lines.add("");
diff --git a/pkg/front_end/test/spell_checking_utils_test.dart b/pkg/front_end/test/spell_checking_utils_test.dart
index 3b5616e..658c88e 100644
--- a/pkg/front_end/test/spell_checking_utils_test.dart
+++ b/pkg/front_end/test/spell_checking_utils_test.dart
@@ -89,7 +89,7 @@
 
 void expectSplit(String s, bool splitAsCode, List<String> expectedWords,
     List<int> expectedOffsets) {
-  List<int> actualOffsets = new List<int>();
+  List<int> actualOffsets = <int>[];
   List<String> actualWords =
       splitStringIntoWords(s, actualOffsets, splitAsCode: splitAsCode);
   compareLists(actualWords, expectedWords);
diff --git a/pkg/front_end/test/spelling_test_base.dart b/pkg/front_end/test/spelling_test_base.dart
index 23d64a5..bd0ea9f 100644
--- a/pkg/front_end/test/spelling_test_base.dart
+++ b/pkg/front_end/test/spelling_test_base.dart
@@ -102,7 +102,7 @@
         scanner.lineStarts, rawBytes, description.uri, description.uri);
     void addErrorMessage(
         int offset, String word, bool denylisted, List<String> alternatives) {
-      errors ??= new List<String>();
+      errors ??= <String>[];
       String message;
       if (denylisted) {
         message = "Misspelled word: '$word' has explicitly been denylisted.";
diff --git a/pkg/front_end/test/split_dill_test.dart b/pkg/front_end/test/split_dill_test.dart
index 55f52ba..0ed6a0f 100644
--- a/pkg/front_end/test/split_dill_test.dart
+++ b/pkg/front_end/test/split_dill_test.dart
@@ -33,7 +33,7 @@
   component.computeCanonicalNames();
 
   stopwatch.reset();
-  List<List<int>> libComponents = new List<List<int>>();
+  List<List<int>> libComponents = <List<int>>[];
   for (Library lib in component.libraries) {
     Component libComponent = new Component(nameRoot: component.root);
     libComponent.libraries.add(lib);
diff --git a/pkg/front_end/test/test_generator_test.dart b/pkg/front_end/test/test_generator_test.dart
index a701999..2ad6f36 100644
--- a/pkg/front_end/test/test_generator_test.dart
+++ b/pkg/front_end/test/test_generator_test.dart
@@ -139,8 +139,8 @@
 
     final Set<String> formattedErrors = new Set<String>();
     final Set<String> formattedWarnings = new Set<String>();
-    final List<Code> formattedErrorsCodes = new List<Code>();
-    final List<Code> formattedWarningsCodes = new List<Code>();
+    final List<Code> formattedErrorsCodes = <Code>[];
+    final List<Code> formattedWarningsCodes = <Code>[];
 
     options.onDiagnostic = (DiagnosticMessage message) {
       String stringId = message.ansiFormatted.join("\n");
diff --git a/pkg/front_end/test/vm_service_coverage.dart b/pkg/front_end/test/vm_service_coverage.dart
index b144e3d..7c69754 100644
--- a/pkg/front_end/test/vm_service_coverage.dart
+++ b/pkg/front_end/test/vm_service_coverage.dart
@@ -5,7 +5,7 @@
 main(List<String> args) async {
   CoverageHelper coverageHelper = new CoverageHelper();
 
-  List<String> allArgs = new List<String>();
+  List<String> allArgs = <String>[];
   allArgs.addAll([
     "--disable-dart-dev",
     "--enable-asserts",
diff --git a/pkg/front_end/test/vm_service_coverage_constant_evaluator.dart b/pkg/front_end/test/vm_service_coverage_constant_evaluator.dart
index 4cab31b..d042077 100644
--- a/pkg/front_end/test/vm_service_coverage_constant_evaluator.dart
+++ b/pkg/front_end/test/vm_service_coverage_constant_evaluator.dart
@@ -3,7 +3,7 @@
 main(List<String> args) async {
   CoverageHelper coverageHelper = new CoverageHelper();
 
-  List<String> allArgs = new List<String>();
+  List<String> allArgs = <String>[];
   allArgs.addAll([
     "--disable-dart-dev",
     "--enable-asserts",
diff --git a/pkg/front_end/test/vm_service_for_leak_detection.dart b/pkg/front_end/test/vm_service_for_leak_detection.dart
index 9879b9c..748756e 100644
--- a/pkg/front_end/test/vm_service_for_leak_detection.dart
+++ b/pkg/front_end/test/vm_service_for_leak_detection.dart
@@ -3,7 +3,7 @@
 import "vm_service_heap_helper.dart" as helper;
 
 main(List<String> args) async {
-  List<helper.Interest> interests = new List<helper.Interest>();
+  List<helper.Interest> interests = <helper.Interest>[];
   interests.add(new helper.Interest(
       Uri.parse(
           "package:front_end/src/fasta/source/source_library_builder.dart"),
diff --git a/pkg/front_end/test/vm_service_heap_helper.dart b/pkg/front_end/test/vm_service_heap_helper.dart
index 497c0b3..f4841d0 100644
--- a/pkg/front_end/test/vm_service_heap_helper.dart
+++ b/pkg/front_end/test/vm_service_heap_helper.dart
@@ -28,7 +28,7 @@
       }
       List<String> fields = classToFields[interest.className];
       if (fields == null) {
-        fields = new List<String>();
+        fields = <String>[];
         classToFields[interest.className] = fields;
       }
       fields.addAll(interest.fieldNames);
@@ -41,7 +41,7 @@
       }
       List<String> fields = classToFields[interest.className];
       if (fields == null) {
-        fields = new List<String>();
+        fields = <String>[];
         classToFields[interest.className] = fields;
       }
       fields.addAll(interest.fieldNames);
@@ -421,7 +421,7 @@
 HeapGraph convertHeapGraph(vmService.HeapSnapshotGraph graph) {
   HeapGraphClassSentinel classSentinel = new HeapGraphClassSentinel();
   List<HeapGraphClassActual> classes =
-      new List<HeapGraphClassActual>(graph.classes.length);
+      new List<HeapGraphClassActual>.filled(graph.classes.length, null);
   for (int i = 0; i < graph.classes.length; i++) {
     vmService.HeapSnapshotClass c = graph.classes[i];
     classes[i] = new HeapGraphClassActual(c);
@@ -429,7 +429,7 @@
 
   HeapGraphElementSentinel elementSentinel = new HeapGraphElementSentinel();
   List<HeapGraphElementActual> elements =
-      new List<HeapGraphElementActual>(graph.objects.length);
+      new List<HeapGraphElementActual>.filled(graph.objects.length, null);
   for (int i = 0; i < graph.objects.length; i++) {
     vmService.HeapSnapshotObject o = graph.objects[i];
     elements[i] = new HeapGraphElementActual(o);
@@ -474,7 +474,7 @@
   void Function() referencesFiller;
   List<HeapGraphElement> get references {
     if (_references == null && referencesFiller != null) {
-      _references = new List<HeapGraphElement>();
+      _references = <HeapGraphElement>[];
       referencesFiller();
     }
     return _references;
@@ -552,7 +552,7 @@
   List<HeapGraphElement> _instances;
   List<HeapGraphElement> getInstances(HeapGraph graph) {
     if (_instances == null) {
-      _instances = new List<HeapGraphElement>();
+      _instances = <HeapGraphElement>[];
       for (int i = 0; i < graph.elements.length; i++) {
         HeapGraphElementActual converted = graph.elements[i];
         if (converted.class_ == this) {
diff --git a/pkg/front_end/testcases/general/expressions.dart b/pkg/front_end/testcases/general/expressions.dart
index 2cfc539..6cef03b 100644
--- a/pkg/front_end/testcases/general/expressions.dart
+++ b/pkg/front_end/testcases/general/expressions.dart
@@ -41,7 +41,7 @@
   print(i++);
   print(new Object());
   print(const Object());
-  print((new List<String>(2)).runtimeType);
+  print((new List<String>.filled(2, null)).runtimeType);
   foo(fisk: "Blorp gulp");
   f() {
     print("f was called");
diff --git a/pkg/front_end/testcases/general/expressions.dart.strong.expect b/pkg/front_end/testcases/general/expressions.dart.strong.expect
index 1c9f07b..90c7dca 100644
--- a/pkg/front_end/testcases/general/expressions.dart.strong.expect
+++ b/pkg/front_end/testcases/general/expressions.dart.strong.expect
@@ -49,7 +49,7 @@
   core::print(let final core::int* #t3 = i in let final core::int* #t4 = i = #t3.{core::num::+}(1) in #t3);
   core::print(new core::Object::•());
   core::print(#C2);
-  core::print(core::List::•<core::String*>(2).{core::Object::runtimeType});
+  core::print(core::List::filled<core::String*>(2, null).{core::Object::runtimeType});
   self::foo(fisk: "Blorp gulp");
   function f() → Null {
     core::print("f was called");
diff --git a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart
index aaa7e1c..7ea3518 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart
+++ b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart
@@ -12,17 +12,17 @@
 }
 
 Stream<List<int>> foo() async* {
-  yield new /*@ typeArgs=int* */ List();
+  yield /*@typeArgs=int**/ [];
   yield /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ MyStream();
-  yield* /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ List();
+  yield* /*error:YIELD_OF_INVALID_TYPE*/ /*@typeArgs=dynamic*/ [];
   yield* new /*@ typeArgs=List<int*>* */ MyStream();
 }
 
 Iterable<Map<int, int>> bar() sync* {
   yield new /*@ typeArgs=int*, int* */ Map();
-  yield /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ List();
+  yield /*error:YIELD_OF_INVALID_TYPE*/ /*@typeArgs=dynamic*/ [];
   yield* /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic, dynamic */ Map();
-  yield* new /*@ typeArgs=Map<int*, int*>* */ List();
+  yield* /*@typeArgs=Map<int*, int*>**/ [];
 }
 
 main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.expect
index 2514965..2420358 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.expect
@@ -8,17 +8,17 @@
 //   yield /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ MyStream();
 //                                                                     ^
 //
-// pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:17:70: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Stream<List<int>>'.
+// pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:17:64: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Stream<List<int>>'.
 //  - 'List' is from 'dart:core'.
 //  - 'Stream' is from 'dart:async'.
-//   yield* /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ List();
-//                                                                      ^
+//   yield* /*error:YIELD_OF_INVALID_TYPE*/ /*@typeArgs=dynamic*/ [];
+//                                                                ^
 //
-// pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:23:69: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Map<int, int>'.
+// pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:23:63: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Map<int, int>'.
 //  - 'List' is from 'dart:core'.
 //  - 'Map' is from 'dart:core'.
-//   yield /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ List();
-//                                                                     ^
+//   yield /*error:YIELD_OF_INVALID_TYPE*/ /*@typeArgs=dynamic*/ [];
+//                                                               ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:24:79: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'Iterable<Map<int, int>>'.
 //  - 'Map' is from 'dart:core'.
@@ -84,32 +84,32 @@
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
 }
 static method foo() → asy::Stream<core::List<core::int*>*>* async* {
-  yield core::List::•<core::int*>();
+  yield<core::int*>[];
   yield let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:16:69: Error: A value of type 'MyStream<dynamic>' can't be assigned to a variable of type 'List<int>'.
  - 'MyStream' is from 'pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart'.
  - 'List' is from 'dart:core'.
   yield /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ MyStream();
                                                                     ^" in self::MyStream::•<dynamic>() as{TypeError} core::List<core::int*>*;
-  yield* let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:17:70: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Stream<List<int>>'.
+  yield* let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:17:64: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Stream<List<int>>'.
  - 'List' is from 'dart:core'.
  - 'Stream' is from 'dart:async'.
-  yield* /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ List();
-                                                                     ^" in core::List::•<dynamic>() as{TypeError} asy::Stream<core::List<core::int*>*>*;
+  yield* /*error:YIELD_OF_INVALID_TYPE*/ /*@typeArgs=dynamic*/ [];
+                                                               ^" in <dynamic>[] as{TypeError} asy::Stream<core::List<core::int*>*>*;
   yield* self::MyStream::•<core::List<core::int*>*>();
 }
 static method bar() → core::Iterable<core::Map<core::int*, core::int*>*>* sync* {
   yield core::Map::•<core::int*, core::int*>();
-  yield let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:23:69: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Map<int, int>'.
+  yield let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:23:63: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Map<int, int>'.
  - 'List' is from 'dart:core'.
  - 'Map' is from 'dart:core'.
-  yield /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ List();
-                                                                    ^" in core::List::•<dynamic>() as{TypeError} core::Map<core::int*, core::int*>*;
+  yield /*error:YIELD_OF_INVALID_TYPE*/ /*@typeArgs=dynamic*/ [];
+                                                              ^" in <dynamic>[] as{TypeError} core::Map<core::int*, core::int*>*;
   yield* let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:24:79: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'Iterable<Map<int, int>>'.
  - 'Map' is from 'dart:core'.
  - 'Iterable' is from 'dart:core'.
   yield* /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic, dynamic */ Map();
                                                                               ^" in core::Map::•<dynamic, dynamic>() as{TypeError} core::Iterable<core::Map<core::int*, core::int*>*>*;
-  yield* core::List::•<core::Map<core::int*, core::int*>*>();
+  yield*<core::Map<core::int*, core::int*>*>[];
 }
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.transformed.expect
index 3f747b9..6772134 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.transformed.expect
@@ -8,17 +8,17 @@
 //   yield /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ MyStream();
 //                                                                     ^
 //
-// pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:17:70: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Stream<List<int>>'.
+// pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:17:64: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Stream<List<int>>'.
 //  - 'List' is from 'dart:core'.
 //  - 'Stream' is from 'dart:async'.
-//   yield* /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ List();
-//                                                                      ^
+//   yield* /*error:YIELD_OF_INVALID_TYPE*/ /*@typeArgs=dynamic*/ [];
+//                                                                ^
 //
-// pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:23:69: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Map<int, int>'.
+// pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:23:63: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Map<int, int>'.
 //  - 'List' is from 'dart:core'.
 //  - 'Map' is from 'dart:core'.
-//   yield /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ List();
-//                                                                     ^
+//   yield /*error:YIELD_OF_INVALID_TYPE*/ /*@typeArgs=dynamic*/ [];
+//                                                               ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:24:79: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'Iterable<Map<int, int>>'.
 //  - 'Map' is from 'dart:core'.
@@ -97,7 +97,7 @@
       try {
         #L1:
         {
-          if(:controller.{asy::_AsyncStarStreamController::add}(core::_GrowableList::•<core::int*>(0)))
+          if(:controller.{asy::_AsyncStarStreamController::add}(<core::int*>[]))
             return null;
           else
             [yield] null;
@@ -109,11 +109,11 @@
             return null;
           else
             [yield] null;
-          if(:controller.{asy::_AsyncStarStreamController::addStream}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:17:70: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Stream<List<int>>'.
+          if(:controller.{asy::_AsyncStarStreamController::addStream}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:17:64: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Stream<List<int>>'.
  - 'List' is from 'dart:core'.
  - 'Stream' is from 'dart:async'.
-  yield* /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ List();
-                                                                     ^" in core::_GrowableList::•<dynamic>(0) as{TypeError} asy::Stream<core::List<core::int*>*>*))
+  yield* /*error:YIELD_OF_INVALID_TYPE*/ /*@typeArgs=dynamic*/ [];
+                                                               ^" in <dynamic>[] as{TypeError} asy::Stream<core::List<core::int*>*>*))
             return null;
           else
             [yield] null;
@@ -147,11 +147,11 @@
           [yield] true;
         }
         {
-          :iterator.{core::_SyncIterator::_current} = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:23:69: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Map<int, int>'.
+          :iterator.{core::_SyncIterator::_current} = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:23:63: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Map<int, int>'.
  - 'List' is from 'dart:core'.
  - 'Map' is from 'dart:core'.
-  yield /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ List();
-                                                                    ^" in core::_GrowableList::•<dynamic>(0) as{TypeError} core::Map<core::int*, core::int*>*;
+  yield /*error:YIELD_OF_INVALID_TYPE*/ /*@typeArgs=dynamic*/ [];
+                                                              ^" in <dynamic>[] as{TypeError} core::Map<core::int*, core::int*>*;
           [yield] true;
         }
         {
@@ -163,7 +163,7 @@
           [yield] true;
         }
         {
-          :iterator.{core::_SyncIterator::_yieldEachIterable} = core::_GrowableList::•<core::Map<core::int*, core::int*>*>(0);
+          :iterator.{core::_SyncIterator::_yieldEachIterable} = <core::Map<core::int*, core::int*>*>[];
           [yield] true;
         }
       }
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart b/pkg/front_end/testcases/nnbd/issue41102.dart
index a237a56..47353c0 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart
@@ -14,7 +14,7 @@
 
 final s2 = s1?.length;
 
-final s3 = new List<int>(2);
+final s3 = new List<int>.filled(2, null);
 
 final s4 = () {
   var e = 0;
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.strong.expect
index 6c3640f..bd670ca 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.strong.expect
@@ -7,10 +7,9 @@
 // final s2 = s1?.length;
 //            ^
 //
-// pkg/front_end/testcases/nnbd/issue41102.dart:17:16: Error: Can't use the default List constructor.
-// Try using List.filled instead.
-// final s3 = new List<int>(2);
-//                ^
+// pkg/front_end/testcases/nnbd/issue41102.dart:17:36: Error: The value 'null' can't be assigned to the parameter type 'int' because 'int' is not nullable.
+// final s3 = new List<int>.filled(2, null);
+//                                    ^
 //
 // pkg/front_end/testcases/nnbd/issue41102.dart:22:5: Error: Switch case may fall through to the next case.
 //     case 0:
@@ -71,10 +70,9 @@
 static final field asy::StreamTransformer<core::Object?, core::Object?> t = new asy::_StreamHandlerTransformer::•<core::Object?, core::Object?>(handleData: (core::Object? data, asy::EventSink<core::Object?> sink) → void => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<core::Object?> sink) → void => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
 static final field core::List<dynamic> s1 = <dynamic>[];
 static final field core::int? s2 = let final core::List<dynamic> #t1 = self::s1 in #t1.{core::List::==}(null) ?{core::int?} null : #t1.{core::List::length};
-static final field core::List<core::int> s3 = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:17:16: Error: Can't use the default List constructor.
-Try using List.filled instead.
-final s3 = new List<int>(2);
-               ^" in core::List::•<core::int>(2);
+static final field core::List<core::int> s3 = core::List::filled<core::int>(2, let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:17:36: Error: The value 'null' can't be assigned to the parameter type 'int' because 'int' is not nullable.
+final s3 = new List<int>.filled(2, null);
+                                   ^" in null as{TypeError,ForNonNullableByDefault} core::int);
 static final field dynamic s4 = (() → Null {
   core::int e = 0;
   switch(e) {
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.strong.transformed.expect
index 55a469e..0ee6323 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.strong.transformed.expect
@@ -7,10 +7,9 @@
 // final s2 = s1?.length;
 //            ^
 //
-// pkg/front_end/testcases/nnbd/issue41102.dart:17:16: Error: Can't use the default List constructor.
-// Try using List.filled instead.
-// final s3 = new List<int>(2);
-//                ^
+// pkg/front_end/testcases/nnbd/issue41102.dart:17:36: Error: The value 'null' can't be assigned to the parameter type 'int' because 'int' is not nullable.
+// final s3 = new List<int>.filled(2, null);
+//                                    ^
 //
 // pkg/front_end/testcases/nnbd/issue41102.dart:22:5: Error: Switch case may fall through to the next case.
 //     case 0:
@@ -71,10 +70,9 @@
 static final field asy::StreamTransformer<core::Object?, core::Object?> t = new asy::_StreamHandlerTransformer::•<core::Object?, core::Object?>(handleData: (core::Object? data, asy::EventSink<core::Object?> sink) → void => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<core::Object?> sink) → void => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
 static final field core::List<dynamic> s1 = <dynamic>[];
 static final field core::int? s2 = let final core::List<dynamic> #t1 = self::s1 in #t1.{core::List::==}(null) ?{core::int?} null : #t1.{core::List::length};
-static final field core::List<core::int> s3 = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:17:16: Error: Can't use the default List constructor.
-Try using List.filled instead.
-final s3 = new List<int>(2);
-               ^" in core::_List::•<core::int>(2);
+static final field core::List<core::int> s3 = core::_List::filled<core::int>(2, let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:17:36: Error: The value 'null' can't be assigned to the parameter type 'int' because 'int' is not nullable.
+final s3 = new List<int>.filled(2, null);
+                                   ^" in let Null #t3 = null in #t3.==(null) ?{core::int} #t3 as{TypeError,ForNonNullableByDefault} core::int : #t3{core::int});
 static final field dynamic s4 = (() → Null {
   core::int e = 0;
   switch(e) {
@@ -90,33 +88,33 @@
   }
 }).call();
 static field core::int? s5;
-static final field core::num s6 = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:31:15: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+static final field core::num s6 = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:31:15: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
 final s6 = s5 + 0;
               ^" in self::s5.{core::num::+}(0);
 static field core::List<dynamic>? s7;
-static final field dynamic s8 = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:35:14: Error: Operator '[]' cannot be called on 'List<dynamic>?' because it is potentially null.
+static final field dynamic s8 = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:35:14: Error: Operator '[]' cannot be called on 'List<dynamic>?' because it is potentially null.
  - 'List' is from 'dart:core'.
 final s8 = s7[0];
              ^" in self::s7.{core::List::[]}(0);
-static final field core::int s9 = let final core::List<dynamic>? #t5 = self::s7 in let final core::int #t6 = 0 in let final core::int #t7 = 0 in let final void #t8 = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:37:14: Error: Operator '[]=' cannot be called on 'List<dynamic>?' because it is potentially null.
+static final field core::int s9 = let final core::List<dynamic>? #t6 = self::s7 in let final core::int #t7 = 0 in let final core::int #t8 = 0 in let final void #t9 = let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:37:14: Error: Operator '[]=' cannot be called on 'List<dynamic>?' because it is potentially null.
  - 'List' is from 'dart:core'.
 final s9 = s7[0] = 0;
-             ^" in #t5.{core::List::[]=}(#t6, #t7) in #t7;
-static final field core::int s10 = let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:39:16: Error: Property 'length' cannot be accessed on 'List<dynamic>?' because it is potentially null.
+             ^" in #t6.{core::List::[]=}(#t7, #t8) in #t8;
+static final field core::int s10 = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:39:16: Error: Property 'length' cannot be accessed on 'List<dynamic>?' because it is potentially null.
  - 'List' is from 'dart:core'.
 Try accessing using ?. instead.
 final s10 = s7.length;
                ^^^^^^" in self::s7.{core::List::length};
-static final field core::int s11 = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'List<dynamic>?' because it is potentially null.
+static final field core::int s11 = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:41:16: Error: Property 'length' cannot be accessed on 'List<dynamic>?' because it is potentially null.
  - 'List' is from 'dart:core'.
 Try accessing using ?. instead.
 final s11 = s7.length = 0;
                ^^^^^^" in self::s7.{core::List::length} = 0;
-static final field core::int s12 = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:43:13: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+static final field core::int s12 = let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:43:13: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
 final s12 = -s5;
             ^" in self::s5.{core::int::unary-}();
 static field () →? core::int s13;
-static final field core::int s14 = let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:47:18: Error: Can't use an expression of type 'int Function()?' as a function because it's potentially null.
+static final field core::int s14 = let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:47:18: Error: Can't use an expression of type 'int Function()?' as a function because it's potentially null.
 Try calling using ?.call instead.
 final s14 = (s13)();
                  ^" in self::s13.call();
@@ -132,7 +130,10 @@
 }
 
 Extra constant evaluation status:
+Evaluated: MethodInvocation @ org-dartlang-testcase:///issue41102.dart:17:36 -> BoolConstant(true)
+Evaluated: VariableGet @ org-dartlang-testcase:///issue41102.dart:17:36 -> NullConstant(null)
+Evaluated: VariableGet @ org-dartlang-testcase:///issue41102.dart:17:36 -> NullConstant(null)
 Evaluated: VariableGet @ org-dartlang-testcase:///issue41102.dart:37:15 -> IntConstant(0)
 Evaluated: VariableGet @ org-dartlang-testcase:///issue41102.dart:37:20 -> IntConstant(0)
 Evaluated: VariableGet @ org-dartlang-testcase:///issue41102.dart:37:20 -> IntConstant(0)
-Extra constant evaluation: evaluated: 55, effectively constant: 3
+Extra constant evaluation: evaluated: 61, effectively constant: 6
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.textual_outline.expect
index 841a03e..39804ba 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.textual_outline.expect
@@ -6,7 +6,7 @@
     handleDone: (sink) => Future.microtask(() => sink.close()));
 final s1 = [];
 final s2 = s1?.length;
-final s3 = new List<int>(2);
+final s3 = new List<int>.filled(2, null);
 final s4 = () {
   var e = 0;
   switch (e) {
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.textual_outline_modelled.expect
index 35fb63f..004471b 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.textual_outline_modelled.expect
@@ -8,7 +8,7 @@
 final s14 = (s13)();
 final s15 = throw null;
 final s2 = s1?.length;
-final s3 = new List<int>(2);
+final s3 = new List<int>.filled(2, null);
 final s4 = () {
   var e = 0;
   switch (e) {
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.weak.expect
index 6c3640f..bd670ca 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.weak.expect
@@ -7,10 +7,9 @@
 // final s2 = s1?.length;
 //            ^
 //
-// pkg/front_end/testcases/nnbd/issue41102.dart:17:16: Error: Can't use the default List constructor.
-// Try using List.filled instead.
-// final s3 = new List<int>(2);
-//                ^
+// pkg/front_end/testcases/nnbd/issue41102.dart:17:36: Error: The value 'null' can't be assigned to the parameter type 'int' because 'int' is not nullable.
+// final s3 = new List<int>.filled(2, null);
+//                                    ^
 //
 // pkg/front_end/testcases/nnbd/issue41102.dart:22:5: Error: Switch case may fall through to the next case.
 //     case 0:
@@ -71,10 +70,9 @@
 static final field asy::StreamTransformer<core::Object?, core::Object?> t = new asy::_StreamHandlerTransformer::•<core::Object?, core::Object?>(handleData: (core::Object? data, asy::EventSink<core::Object?> sink) → void => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<core::Object?> sink) → void => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
 static final field core::List<dynamic> s1 = <dynamic>[];
 static final field core::int? s2 = let final core::List<dynamic> #t1 = self::s1 in #t1.{core::List::==}(null) ?{core::int?} null : #t1.{core::List::length};
-static final field core::List<core::int> s3 = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:17:16: Error: Can't use the default List constructor.
-Try using List.filled instead.
-final s3 = new List<int>(2);
-               ^" in core::List::•<core::int>(2);
+static final field core::List<core::int> s3 = core::List::filled<core::int>(2, let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:17:36: Error: The value 'null' can't be assigned to the parameter type 'int' because 'int' is not nullable.
+final s3 = new List<int>.filled(2, null);
+                                   ^" in null as{TypeError,ForNonNullableByDefault} core::int);
 static final field dynamic s4 = (() → Null {
   core::int e = 0;
   switch(e) {
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.weak.transformed.expect
index 55a469e..61062c1 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.weak.transformed.expect
@@ -7,10 +7,9 @@
 // final s2 = s1?.length;
 //            ^
 //
-// pkg/front_end/testcases/nnbd/issue41102.dart:17:16: Error: Can't use the default List constructor.
-// Try using List.filled instead.
-// final s3 = new List<int>(2);
-//                ^
+// pkg/front_end/testcases/nnbd/issue41102.dart:17:36: Error: The value 'null' can't be assigned to the parameter type 'int' because 'int' is not nullable.
+// final s3 = new List<int>.filled(2, null);
+//                                    ^
 //
 // pkg/front_end/testcases/nnbd/issue41102.dart:22:5: Error: Switch case may fall through to the next case.
 //     case 0:
@@ -71,10 +70,9 @@
 static final field asy::StreamTransformer<core::Object?, core::Object?> t = new asy::_StreamHandlerTransformer::•<core::Object?, core::Object?>(handleData: (core::Object? data, asy::EventSink<core::Object?> sink) → void => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<core::Object?> sink) → void => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
 static final field core::List<dynamic> s1 = <dynamic>[];
 static final field core::int? s2 = let final core::List<dynamic> #t1 = self::s1 in #t1.{core::List::==}(null) ?{core::int?} null : #t1.{core::List::length};
-static final field core::List<core::int> s3 = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:17:16: Error: Can't use the default List constructor.
-Try using List.filled instead.
-final s3 = new List<int>(2);
-               ^" in core::_List::•<core::int>(2);
+static final field core::List<core::int> s3 = core::_List::filled<core::int>(2, let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:17:36: Error: The value 'null' can't be assigned to the parameter type 'int' because 'int' is not nullable.
+final s3 = new List<int>.filled(2, null);
+                                   ^" in null);
 static final field dynamic s4 = (() → Null {
   core::int e = 0;
   switch(e) {
diff --git a/pkg/front_end/testcases/rasta/issue_000070.dart b/pkg/front_end/testcases/rasta/issue_000070.dart
index 95a5b07..838bc59 100644
--- a/pkg/front_end/testcases/rasta/issue_000070.dart
+++ b/pkg/front_end/testcases/rasta/issue_000070.dart
@@ -7,7 +7,7 @@
 class A<N, S, U> {
   final List<U> field;
 
-  A(N n, S s) : field = new List<U>() {
+  A(N n, S s) : field = <U>[] {
     Expect.isTrue(n is N);
     Expect.isTrue(s is S);
   }
diff --git a/pkg/front_end/testcases/rasta/issue_000070.dart.strong.expect b/pkg/front_end/testcases/rasta/issue_000070.dart.strong.expect
index 2d43401..b0b26de 100644
--- a/pkg/front_end/testcases/rasta/issue_000070.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/issue_000070.dart.strong.expect
@@ -8,7 +8,7 @@
 class A<N extends core::Object* = dynamic, S extends core::Object* = dynamic, U extends core::Object* = dynamic> extends core::Object /*hasConstConstructor*/  {
   final field core::List<self::A::U*>* field;
   constructor •(self::A::N* n, self::A::S* s) → self::A<self::A::N*, self::A::S*, self::A::U*>*
-    : self::A::field = core::List::•<self::A::U*>(), super core::Object::•() {
+    : self::A::field = <self::A::U*>[], super core::Object::•() {
     exp::Expect::isTrue(n is self::A::N*);
     exp::Expect::isTrue(s is self::A::S*);
   }
diff --git a/pkg/front_end/testcases/rasta/issue_000070.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/issue_000070.dart.strong.transformed.expect
index b0d7301..b0b26de 100644
--- a/pkg/front_end/testcases/rasta/issue_000070.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000070.dart.strong.transformed.expect
@@ -8,7 +8,7 @@
 class A<N extends core::Object* = dynamic, S extends core::Object* = dynamic, U extends core::Object* = dynamic> extends core::Object /*hasConstConstructor*/  {
   final field core::List<self::A::U*>* field;
   constructor •(self::A::N* n, self::A::S* s) → self::A<self::A::N*, self::A::S*, self::A::U*>*
-    : self::A::field = core::_GrowableList::•<self::A::U*>(0), super core::Object::•() {
+    : self::A::field = <self::A::U*>[], super core::Object::•() {
     exp::Expect::isTrue(n is self::A::N*);
     exp::Expect::isTrue(s is self::A::S*);
   }
diff --git a/pkg/front_end/testcases/rasta/issue_000070.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000070.dart.textual_outline.expect
index 18be5ac..2184938 100644
--- a/pkg/front_end/testcases/rasta/issue_000070.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/rasta/issue_000070.dart.textual_outline.expect
@@ -2,7 +2,7 @@
 
 class A<N, S, U> {
   final List<U> field;
-  A(N n, S s) : field = new List<U>() {}
+  A(N n, S s) : field = <U>[] {}
   A.empty() : field = null {}
   factory A.f(S s) {}
   const A.c(U u, S s) : field = const [null];
diff --git a/pkg/front_end/testcases/rasta/issue_000070.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000070.dart.textual_outline_modelled.expect
index cefd17f..919600b 100644
--- a/pkg/front_end/testcases/rasta/issue_000070.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/rasta/issue_000070.dart.textual_outline_modelled.expect
@@ -5,7 +5,7 @@
 abstract class J<Aa, B> {}
 
 class A<N, S, U> {
-  A(N n, S s) : field = new List<U>() {}
+  A(N n, S s) : field = <U>[] {}
   A.empty() : field = null {}
   List<U> get getter {}
   const A.c(U u, S s) : field = const [null];
diff --git a/pkg/front_end/tool/_fasta/entry_points.dart b/pkg/front_end/tool/_fasta/entry_points.dart
index 03a5e96..1aa2265 100644
--- a/pkg/front_end/tool/_fasta/entry_points.dart
+++ b/pkg/front_end/tool/_fasta/entry_points.dart
@@ -485,7 +485,7 @@
   StringBuffer sb = new StringBuffer();
   sb.write(toRelativeFilePath(output));
   sb.write(":");
-  List<String> paths = new List<String>(allDependencies.length);
+  List<String> paths = new List<String>.filled(allDependencies.length, null);
   for (int i = 0; i < allDependencies.length; i++) {
     paths[i] = toRelativeFilePath(allDependencies[i]);
   }
diff --git a/pkg/front_end/tool/smoke_test_quick.dart b/pkg/front_end/tool/smoke_test_quick.dart
index 4956e04..03d3840 100644
--- a/pkg/front_end/tool/smoke_test_quick.dart
+++ b/pkg/front_end/tool/smoke_test_quick.dart
@@ -12,7 +12,7 @@
 
 main(List<String> args) async {
   Stopwatch stopwatch = new Stopwatch()..start();
-  List<Future> futures = new List<Future>();
+  List<Future> futures = <Future>[];
   futures.add(run(
       "pkg/front_end/test/explicit_creation_test.dart", ["--front-end-only"],
       filter: false));
diff --git a/pkg/frontend_server/lib/frontend_server.dart b/pkg/frontend_server/lib/frontend_server.dart
index 4867d3e..c1f089f 100644
--- a/pkg/frontend_server/lib/frontend_server.dart
+++ b/pkg/frontend_server/lib/frontend_server.dart
@@ -350,7 +350,7 @@
 
   final ProgramTransformer transformer;
 
-  final List<String> errors = List<String>();
+  final List<String> errors = <String>[];
 
   _onDiagnostic(DiagnosticMessage message) {
     bool printMessage;
@@ -888,8 +888,8 @@
       Component deltaProgram, Sink<List<int>> ioSink) {
     if (deltaProgram == null) return;
 
-    List<Library> packageLibraries = List<Library>();
-    List<Library> libraries = List<Library>();
+    List<Library> packageLibraries = <Library>[];
+    List<Library> libraries = <Library>[];
     deltaProgram.computeCanonicalNames();
 
     for (var lib in deltaProgram.libraries) {
diff --git a/pkg/frontend_server/test/frontend_server_flutter.dart b/pkg/frontend_server/test/frontend_server_flutter.dart
index 0137989..d238293 100644
--- a/pkg/frontend_server/test/frontend_server_flutter.dart
+++ b/pkg/frontend_server/test/frontend_server_flutter.dart
@@ -245,7 +245,7 @@
   String _boundaryKey;
   bool _readingSources;
 
-  List<String> allReceived = new List<String>();
+  List<String> allReceived = <String>[];
 
   void listener(String s) {
     allReceived.add(s);
@@ -331,7 +331,7 @@
 }
 
 class StdoutLogger extends Logger {
-  List<String> _log = new List<String>();
+  List<String> _log = <String>[];
 
   @override
   void logExpectedResult(String testName) {
diff --git a/pkg/frontend_server/test/frontend_server_flutter_suite.dart b/pkg/frontend_server/test/frontend_server_flutter_suite.dart
index 8028d59..d96ee6e 100644
--- a/pkg/frontend_server/test/frontend_server_flutter_suite.dart
+++ b/pkg/frontend_server/test/frontend_server_flutter_suite.dart
@@ -70,7 +70,7 @@
 class ResultLogger extends Logger {
   final SuiteConfiguration suiteConfiguration;
   final Map<String, Stopwatch> stopwatches = {};
-  List<String> _log = new List<String>();
+  List<String> _log = <String>[];
 
   ResultLogger(this.suiteConfiguration);
 
diff --git a/pkg/js_ast/lib/src/builder.dart b/pkg/js_ast/lib/src/builder.dart
index 9ec3bfe..2fee946 100644
--- a/pkg/js_ast/lib/src/builder.dart
+++ b/pkg/js_ast/lib/src/builder.dart
@@ -1522,7 +1522,7 @@
       }
       expectCategory(COLON);
     }
-    List statements = new List<Statement>();
+    List statements = <Statement>[];
     while (lastCategory != RBRACE &&
         lastToken != 'case' &&
         lastToken != 'default') {
@@ -1557,7 +1557,7 @@
     Expression key = parseExpression();
     expectCategory(RPAREN);
     expectCategory(LBRACE);
-    List<SwitchClause> clauses = new List<SwitchClause>();
+    List<SwitchClause> clauses = <SwitchClause>[];
     while (lastCategory != RBRACE) {
       clauses.add(parseSwitchClause());
     }
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index d91a3d1..f3d8ace 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -10341,7 +10341,7 @@
 
   static int combineMapHashUnordered(Map map, [int hash = 2]) {
     if (map == null || map.isEmpty) return hash;
-    List<int> entryHashes = List(map.length);
+    List<int> entryHashes = List.filled(map.length, null);
     int i = 0;
     for (core.MapEntry entry in map.entries) {
       entryHashes[i++] = combine(entry.key.hashCode, entry.value.hashCode);
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index 4730bc6..e4676d9 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -269,7 +269,7 @@
   void readStringTable(List<String> table) {
     // Read the table of end offsets.
     int length = readUInt30();
-    List<int> endOffsets = new List<int>(length);
+    List<int> endOffsets = new List<int>.filled(length, null);
     for (int i = 0; i < length; ++i) {
       endOffsets[i] = readUInt30();
     }
@@ -357,7 +357,7 @@
         final TearOffConstant tearOffConstant =
             readConstantReference() as TearOffConstant;
         final int length = readUInt30();
-        final List<DartType> types = new List<DartType>(length);
+        final List<DartType> types = new List<DartType>.filled(length, null);
         for (int i = 0; i < length; i++) {
           types[i] = readDartType();
         }
@@ -462,7 +462,7 @@
 
   void readLinkTable(CanonicalName linkRoot) {
     int length = readUInt30();
-    _linkTable = new List<CanonicalName>(length);
+    _linkTable = new List<CanonicalName>.filled(length, null);
     for (int i = 0; i < length; ++i) {
       int biasedParentIndex = readUInt30();
       String name = readStringReference();
@@ -543,7 +543,7 @@
       int componentFileIndex = 0;
       List<SubComponentView> views;
       if (createView) {
-        views = new List<SubComponentView>();
+        views = <SubComponentView>[];
       }
       while (_byteOffset < _bytes.length) {
         SubComponentView view = _readOneComponent(
@@ -672,7 +672,7 @@
     result.libraryCount = readUint32();
     // Library offsets are used for start and end offsets, so there is one extra
     // element that this the end offset of the last library
-    result.libraryOffsets = new List<int>(result.libraryCount + 1);
+    result.libraryOffsets = new List<int>.filled(result.libraryCount + 1, null);
     result.componentFileSizeInBytes = readUint32();
     if (result.componentFileSizeInBytes != componentFileSize) {
       throw "Malformed binary: This component file's component index indicates "
@@ -783,8 +783,10 @@
 
     SubComponentView result;
     if (createView) {
-      result = new SubComponentView(new List<Library>(numberOfLibraries),
-          _componentStartOffset, componentFileSize);
+      result = new SubComponentView(
+          new List<Library>.filled(numberOfLibraries, null),
+          _componentStartOffset,
+          componentFileSize);
     }
 
     for (int i = 0; i < numberOfLibraries; ++i) {
@@ -831,7 +833,7 @@
       _sourceUriTable[i] = uri;
       Uint8List sourceCode = readByteList();
       int lineCount = readUInt30();
-      List<int> lineStarts = new List<int>(lineCount);
+      List<int> lineStarts = new List<int>.filled(lineCount, null);
       int previousLineStart = 0;
       for (int j = 0; j < lineCount; ++j) {
         int lineStart = readUInt30() + previousLineStart;
@@ -977,7 +979,7 @@
     // There is a field for the procedure count.
     _byteOffset = endOffset - (1) * 4;
     int procedureCount = readUint32();
-    List<int> procedureOffsets = new List<int>(procedureCount + 1);
+    List<int> procedureOffsets = new List<int>.filled(procedureCount + 1, null);
 
     // There is a field for the procedure count, that number + 1 (for the end)
     // offsets, and then the class count (i.e. procedure count + 3 fields).
@@ -986,7 +988,7 @@
     for (int i = 0; i < procedureCount + 1; i++) {
       procedureOffsets[i] = _componentStartOffset + readUint32();
     }
-    List<int> classOffsets = new List<int>(classCount + 1);
+    List<int> classOffsets = new List<int>.filled(classCount + 1, null);
 
     // There is a field for the procedure count, that number + 1 (for the end)
     // offsets, then the class count and that number + 1 (for the end) offsets.
@@ -1173,7 +1175,7 @@
     // There is a field for the procedure count.
     _byteOffset = endOffset - (1) * 4;
     int procedureCount = readUint32();
-    List<int> procedureOffsets = new List<int>(procedureCount + 1);
+    List<int> procedureOffsets = new List<int>.filled(procedureCount + 1, null);
     // There is a field for the procedure count, that number + 1 (for the end)
     // offsets (i.e. procedure count + 2 fields).
     _byteOffset = endOffset - (procedureCount + 2) * 4;
@@ -1827,7 +1829,8 @@
           fieldValues[fieldRef] = value;
         }
         int assertCount = readUInt30();
-        List<AssertStatement> asserts = new List<AssertStatement>(assertCount);
+        List<AssertStatement> asserts =
+            new List<AssertStatement>.filled(assertCount, null);
         for (int i = 0; i < assertCount; i++) {
           asserts[i] = readStatement();
         }
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index 15f1a67..ca92ca9 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -26,8 +26,8 @@
   ConstantIndexer _constantIndexer;
   final UriIndexer _sourceUriIndexer = new UriIndexer();
   bool _currentlyInNonimplementation = false;
-  final List<bool> _sourcesFromRealImplementation = new List<bool>();
-  final List<bool> _sourcesUsedInLibrary = new List<bool>();
+  final List<bool> _sourcesFromRealImplementation = <bool>[];
+  final List<bool> _sourcesUsedInLibrary = <bool>[];
   Map<LibraryDependency, int> _libraryDependencyIndex =
       <LibraryDependency, int>{};
   NonNullableByDefaultCompiledMode compilationMode;
@@ -120,7 +120,7 @@
     _binaryOffsetForStringTable = getBufferOffset();
 
     // Containers for the WTF-8 encoded strings.
-    final List<Uint8List> data = new List<Uint8List>();
+    final List<Uint8List> data = <Uint8List>[];
     int totalLength = 0;
     const int minLength = 1 << 16;
     Uint8List buffer;
@@ -561,7 +561,7 @@
       writeConstantTable(_constantIndexer);
       List<Library> libraries = component.libraries;
       if (libraryFilter != null) {
-        List<Library> librariesNew = new List<Library>();
+        List<Library> librariesNew = <Library>[];
         for (int i = 0; i < libraries.length; i++) {
           Library library = libraries[i];
           if (libraryFilter(library)) librariesNew.add(library);
@@ -773,7 +773,7 @@
 
     int length = _sourceUriIndexer.index.length;
     writeUInt32(length);
-    List<int> index = new List<int>(length);
+    List<int> index = new List<int>.filled(length, null);
 
     // Write data.
     int i = 0;
@@ -994,12 +994,12 @@
     leaveScope(memberScope: true);
 
     writeTypedefNodeList(node.typedefs);
-    classOffsets = new List<int>();
+    classOffsets = <int>[];
     writeClassNodeList(node.classes);
     classOffsets.add(getBufferOffset());
     writeExtensionNodeList(node.extensions);
     writeFieldNodeList(node.fields);
-    procedureOffsets = new List<int>();
+    procedureOffsets = <int>[];
     writeProcedureNodeList(node.procedures);
     procedureOffsets.add(getBufferOffset());
 
@@ -2518,7 +2518,7 @@
   }
 
   void pushScope() {
-    scopes ??= new List<int>();
+    scopes ??= <int>[];
     scopes.add(stackHeight);
   }
 
diff --git a/pkg/kernel/lib/class_hierarchy.dart b/pkg/kernel/lib/class_hierarchy.dart
index fcec1e6..dbe15bd 100644
--- a/pkg/kernel/lib/class_hierarchy.dart
+++ b/pkg/kernel/lib/class_hierarchy.dart
@@ -369,7 +369,8 @@
   bool invalidated = false;
 
   _ClosedWorldClassHierarchySubtypes(this.hierarchy)
-      : _classesByTopDownIndex = new List<Class>(hierarchy._infoMap.length) {
+      : _classesByTopDownIndex =
+            new List<Class>.filled(hierarchy._infoMap.length, null) {
     hierarchy.allBetsOff = true;
     if (hierarchy._infoMap.isNotEmpty) {
       for (Class class_ in hierarchy._infoMap.keys) {
@@ -460,7 +461,7 @@
       onAmbiguousSupertypes(class_, a, b);
       List<Supertype> recorded = _recordedAmbiguousSupertypes[class_];
       if (recorded == null) {
-        recorded = new List<Supertype>();
+        recorded = <Supertype>[];
         _recordedAmbiguousSupertypes[class_] = recorded;
       }
       recorded.add(a);
@@ -473,7 +474,7 @@
       new LinkedHashMap<Class, _ClassInfo>();
 
   List<ForTestingClassInfo> getTestingClassInfo() {
-    List<ForTestingClassInfo> result = new List<ForTestingClassInfo>();
+    List<ForTestingClassInfo> result = <ForTestingClassInfo>[];
     for (_ClassInfo info in _infoMap.values) {
       result.add(new ForTestingClassInfo._(info));
     }
@@ -487,7 +488,7 @@
   }
 
   List<Class> getUsedClasses() {
-    List<Class> result = new List<Class>();
+    List<Class> result = <Class>[];
     for (_ClassInfo classInfo in _infoMap.values) {
       if (classInfo.used) {
         result.add(classInfo.classNode);
@@ -928,7 +929,7 @@
     }
 
     // Add the new classes.
-    List<Class> addedClassesSorted = new List<Class>();
+    List<Class> addedClassesSorted = <Class>[];
     int expectedStartIndex = _topSortIndex;
     for (Library lib in ensureKnownLibraries) {
       if (knownLibraries.contains(lib)) continue;
@@ -955,7 +956,7 @@
       {bool findDescendants: false}) {
     if (classes.isEmpty) return this;
 
-    List<_ClassInfo> infos = new List<_ClassInfo>();
+    List<_ClassInfo> infos = <_ClassInfo>[];
     if (findDescendants) {
       Set<_ClassInfo> processedClasses = new Set<_ClassInfo>();
       List<_ClassInfo> worklist = <_ClassInfo>[];
@@ -1214,7 +1215,7 @@
         }
       }
     } else {
-      members = new List<Member>();
+      members = <Member>[];
       for (Procedure procedure in classNode.procedures) {
         if (procedure.isStatic) continue;
         if (procedure.kind == ProcedureKind.Setter) {
diff --git a/pkg/kernel/lib/import_table.dart b/pkg/kernel/lib/import_table.dart
index 6450852..c85e9f3 100644
--- a/pkg/kernel/lib/import_table.dart
+++ b/pkg/kernel/lib/import_table.dart
@@ -144,7 +144,7 @@
     if (targetSegments.last == "") return ".";
     return targetSegments.last;
   }
-  List<String> path = new List<String>();
+  List<String> path = <String>[];
   int oked = same + 1;
   while (oked < refSegments.length - 1) {
     path.add("..");
diff --git a/pkg/kernel/lib/src/bounds_checks.dart b/pkg/kernel/lib/src/bounds_checks.dart
index c9aecc6..3e152d2 100644
--- a/pkg/kernel/lib/src/bounds_checks.dart
+++ b/pkg/kernel/lib/src/bounds_checks.dart
@@ -46,9 +46,9 @@
   TypeVariableGraph(this.typeParameters, this.bounds) {
     assert(typeParameters.length == bounds.length);
 
-    vertices = new List<int>(typeParameters.length);
+    vertices = new List<int>.filled(typeParameters.length, null);
     Map<TypeParameter, int> typeParameterIndices = <TypeParameter, int>{};
-    edges = new List<List<int>>(typeParameters.length);
+    edges = new List<List<int>>.filled(typeParameters.length, null);
     for (int i = 0; i < vertices.length; i++) {
       vertices[i] = i;
       typeParameterIndices[typeParameters[i]] = i;
@@ -161,7 +161,8 @@
 /// of the algorithm for details.
 List<DartType> calculateBounds(List<TypeParameter> typeParameters,
     Class objectClass, Library contextLibrary) {
-  List<DartType> bounds = new List<DartType>(typeParameters.length);
+  List<DartType> bounds =
+      new List<DartType>.filled(typeParameters.length, null);
   for (int i = 0; i < typeParameters.length; i++) {
     DartType bound = typeParameters[i].bound;
     if (bound == null) {
@@ -500,7 +501,7 @@
     return typeEnvironment.coreTypes.objectLegacyRawType;
   } else if (type is InterfaceType && type.classNode.typeParameters != null) {
     List<DartType> replacedTypeArguments =
-        new List<DartType>(type.typeArguments.length);
+        new List<DartType>.filled(type.typeArguments.length, null);
     for (int i = 0; i < replacedTypeArguments.length; i++) {
       replacedTypeArguments[i] = convertSuperBoundedToRegularBounded(
           clientLibrary, typeEnvironment, type.typeArguments[i], bottomType,
@@ -510,7 +511,7 @@
         type.classNode, type.nullability, replacedTypeArguments);
   } else if (type is TypedefType && type.typedefNode.typeParameters != null) {
     List<DartType> replacedTypeArguments =
-        new List<DartType>(type.typeArguments.length);
+        new List<DartType>.filled(type.typeArguments.length, null);
     for (int i = 0; i < replacedTypeArguments.length; i++) {
       replacedTypeArguments[i] = convertSuperBoundedToRegularBounded(
           clientLibrary, typeEnvironment, type.typeArguments[i], bottomType,
@@ -523,7 +524,7 @@
         clientLibrary, typeEnvironment, type.returnType, bottomType,
         isCovariant: isCovariant);
     List<DartType> replacedPositionalParameters =
-        new List<DartType>(type.positionalParameters.length);
+        new List<DartType>.filled(type.positionalParameters.length, null);
     for (int i = 0; i < replacedPositionalParameters.length; i++) {
       replacedPositionalParameters[i] = convertSuperBoundedToRegularBounded(
           clientLibrary,
@@ -533,7 +534,7 @@
           isCovariant: !isCovariant);
     }
     List<NamedType> replacedNamedParameters =
-        new List<NamedType>(type.namedParameters.length);
+        new List<NamedType>.filled(type.namedParameters.length, null);
     for (int i = 0; i < replacedNamedParameters.length; i++) {
       replacedNamedParameters[i] = new NamedType(
           type.namedParameters[i].name,
diff --git a/pkg/kernel/lib/src/merge_visitor.dart b/pkg/kernel/lib/src/merge_visitor.dart
index a3909da..62eb99a 100644
--- a/pkg/kernel/lib/src/merge_visitor.dart
+++ b/pkg/kernel/lib/src/merge_visitor.dart
@@ -35,7 +35,7 @@
     assert(a.namedParameters.length == b.namedParameters.length);
 
     List<TypeParameter> newTypeParameters =
-        new List<TypeParameter>(a.typeParameters.length);
+        new List<TypeParameter>.filled(a.typeParameters.length, null);
     for (int i = 0; i < a.typeParameters.length; i++) {
       TypeParameter aTypeParameter = a.typeParameters[i];
       TypeParameter bTypeParameter = b.typeParameters[i];
@@ -56,7 +56,7 @@
 
     if (newTypeParameters.isNotEmpty) {
       List<TypeParameterType> aTypeParameterTypes =
-          new List<TypeParameterType>(newTypeParameters.length);
+          new List<TypeParameterType>.filled(newTypeParameters.length, null);
       for (int i = 0; i < newTypeParameters.length; i++) {
         aTypeParameterTypes[i] = new TypeParameterType.forAlphaRenaming(
             a.typeParameters[i], newTypeParameters[i]);
@@ -64,7 +64,7 @@
       aSubstitution =
           Substitution.fromPairs(a.typeParameters, aTypeParameterTypes);
       List<TypeParameterType> bTypeParameterTypes =
-          new List<TypeParameterType>(newTypeParameters.length);
+          new List<TypeParameterType>.filled(newTypeParameters.length, null);
       for (int i = 0; i < newTypeParameters.length; i++) {
         bTypeParameterTypes[i] = new TypeParameterType.forAlphaRenaming(
             b.typeParameters[i], newTypeParameters[i]);
@@ -91,7 +91,7 @@
     DartType newReturnType = mergeTypes(a.returnType, b.returnType);
     if (newReturnType == null) return null;
     List<DartType> newPositionalParameters =
-        new List<DartType>(a.positionalParameters.length);
+        new List<DartType>.filled(a.positionalParameters.length, null);
     for (int i = 0; i < a.positionalParameters.length; i++) {
       DartType newType =
           mergeTypes(a.positionalParameters[i], b.positionalParameters[i]);
@@ -101,7 +101,7 @@
       newPositionalParameters[i] = newType;
     }
     List<NamedType> newNamedParameters =
-        new List<NamedType>(a.namedParameters.length);
+        new List<NamedType>.filled(a.namedParameters.length, null);
     for (int i = 0; i < a.namedParameters.length; i++) {
       DartType newType =
           mergeTypes(a.namedParameters[i].type, b.namedParameters[i].type);
@@ -157,7 +157,7 @@
       return new InterfaceType(a.classNode, nullability);
     }
     List<DartType> newTypeArguments =
-        new List<DartType>(a.typeArguments.length);
+        new List<DartType>.filled(a.typeArguments.length, null);
     for (int i = 0; i < a.typeArguments.length; i++) {
       DartType newType = a.typeArguments[i].accept1(this, b.typeArguments[i]);
       if (newType == null) {
@@ -287,7 +287,7 @@
       return new TypedefType(a.typedefNode, nullability);
     }
     List<DartType> newTypeArguments =
-        new List<DartType>(a.typeArguments.length);
+        new List<DartType>.filled(a.typeArguments.length, null);
     for (int i = 0; i < a.typeArguments.length; i++) {
       DartType newType = a.typeArguments[i].accept1(this, b.typeArguments[i]);
       if (newType == null) return null;
diff --git a/pkg/kernel/lib/src/nnbd_top_merge.dart b/pkg/kernel/lib/src/nnbd_top_merge.dart
index 5b3634a..9a56df4 100644
--- a/pkg/kernel/lib/src/nnbd_top_merge.dart
+++ b/pkg/kernel/lib/src/nnbd_top_merge.dart
@@ -14,7 +14,8 @@
   if (a.typeArguments.isEmpty) {
     return a;
   }
-  List<DartType> newTypeArguments = new List<DartType>(a.typeArguments.length);
+  List<DartType> newTypeArguments =
+      new List<DartType>.filled(a.typeArguments.length, null);
   for (int i = 0; i < a.typeArguments.length; i++) {
     DartType newTypeArgument =
         nnbdTopMerge(coreTypes, a.typeArguments[i], b.typeArguments[i]);
diff --git a/pkg/kernel/lib/src/replacement_visitor.dart b/pkg/kernel/lib/src/replacement_visitor.dart
index 5aea426..9550e18 100644
--- a/pkg/kernel/lib/src/replacement_visitor.dart
+++ b/pkg/kernel/lib/src/replacement_visitor.dart
@@ -35,7 +35,7 @@
     Substitution substitution;
     if (newTypeParameters != null) {
       List<TypeParameterType> typeParameterTypes =
-          new List<TypeParameterType>(newTypeParameters.length);
+          new List<TypeParameterType>.filled(newTypeParameters.length, null);
       for (int i = 0; i < newTypeParameters.length; i++) {
         typeParameterTypes[i] = new TypeParameterType.forAlphaRenaming(
             node.typeParameters[i], newTypeParameters[i]);
diff --git a/pkg/kernel/lib/src/standard_bounds.dart b/pkg/kernel/lib/src/standard_bounds.dart
index 92fb5ee..d622437 100644
--- a/pkg/kernel/lib/src/standard_bounds.dart
+++ b/pkg/kernel/lib/src/standard_bounds.dart
@@ -794,7 +794,7 @@
         int n = klass.typeParameters.length;
         List<DartType> leftArguments = type1.typeArguments;
         List<DartType> rightArguments = type2.typeArguments;
-        List<DartType> typeArguments = new List<DartType>(n);
+        List<DartType> typeArguments = new List<DartType>.filled(n, null);
         for (int i = 0; i < n; ++i) {
           int variance = klass.typeParameters[i].variance;
           if (variance == Variance.contravariant) {
@@ -1367,7 +1367,8 @@
     // Calculate the SUB of each corresponding pair of parameters.
     int totalPositional =
         math.max(f.positionalParameters.length, g.positionalParameters.length);
-    List<DartType> positionalParameters = new List<DartType>(totalPositional);
+    List<DartType> positionalParameters =
+        new List<DartType>.filled(totalPositional, null);
     for (int i = 0; i < totalPositional; i++) {
       if (i < f.positionalParameters.length) {
         DartType fType = f.positionalParameters[i];
@@ -1470,7 +1471,8 @@
     // other.
     int totalPositional =
         math.min(f.positionalParameters.length, g.positionalParameters.length);
-    List<DartType> positionalParameters = new List<DartType>(totalPositional);
+    List<DartType> positionalParameters =
+        new List<DartType>.filled(totalPositional, null);
     for (int i = 0; i < totalPositional; i++) {
       positionalParameters[i] = getStandardLowerBound(
           f.positionalParameters[i], g.positionalParameters[i], clientLibrary);
@@ -1549,7 +1551,7 @@
 
       assert(tArgs1.length == tArgs2.length);
       assert(tArgs1.length == tParams.length);
-      List<DartType> tArgs = new List(tArgs1.length);
+      List<DartType> tArgs = new List.filled(tArgs1.length, null);
       for (int i = 0; i < tArgs1.length; i++) {
         if (tParams[i].variance == Variance.contravariant) {
           tArgs[i] = getStandardLowerBound(tArgs1[i], tArgs2[i], clientLibrary);
diff --git a/pkg/kernel/lib/testing/type_parser_environment.dart b/pkg/kernel/lib/testing/type_parser_environment.dart
index 7388412..40484e6 100644
--- a/pkg/kernel/lib/testing/type_parser_environment.dart
+++ b/pkg/kernel/lib/testing/type_parser_environment.dart
@@ -125,6 +125,12 @@
         additionalTypes: additionalTypes);
   }
 
+  List<DartType> parseTypes(String text,
+      {Map<String, DartType Function()> additionalTypes}) {
+    return _libraryEnvironment.parseTypes(text,
+        additionalTypes: additionalTypes);
+  }
+
   List<TypeParameter> extendWithTypeParameters(String typeParameters) {
     if (typeParameters == null || typeParameters.isEmpty) {
       return <TypeParameter>[];
@@ -179,12 +185,21 @@
     return node;
   }
 
+  /// Parses a single type.
   DartType parseType(String text,
       {Map<String, DartType Function()> additionalTypes}) {
     return _kernelFromParsedType(type_parser.parse(text).single,
         additionalTypes: additionalTypes);
   }
 
+  /// Parses a list of types separated by commas.
+  List<DartType> parseTypes(String text,
+      {Map<String, DartType Function()> additionalTypes}) {
+    return (parseType("(${text}) -> void", additionalTypes: additionalTypes)
+            as FunctionType)
+        .positionalParameters;
+  }
+
   bool isObject(String name) => name == "Object" && "$uri" == "dart:core";
 
   Class get objectClass => lookupDeclaration("Object");
diff --git a/pkg/kernel/lib/text/serializer_combinators.dart b/pkg/kernel/lib/text/serializer_combinators.dart
index d25d6ae..dc8fe50 100644
--- a/pkg/kernel/lib/text/serializer_combinators.dart
+++ b/pkg/kernel/lib/text/serializer_combinators.dart
@@ -733,7 +733,7 @@
     Tuple2<List<T1>, List<T2>> toZip = lists.readFrom(stream, state);
     List<T1> firsts = toZip.first;
     List<T2> seconds = toZip.second;
-    List<T> zipped = new List<T>(toZip.first.length);
+    List<T> zipped = new List<T>.filled(toZip.first.length, null);
     for (int i = 0; i < zipped.length; ++i) {
       zipped[i] = zip(firsts[i], seconds[i]);
     }
@@ -741,8 +741,8 @@
   }
 
   void writeTo(StringBuffer buffer, List<T> zipped, SerializationState state) {
-    List<T1> firsts = new List<T1>(zipped.length);
-    List<T2> seconds = new List<T2>(zipped.length);
+    List<T1> firsts = new List<T1>.filled(zipped.length, null);
+    List<T2> seconds = new List<T2>.filled(zipped.length, null);
     for (int i = 0; i < zipped.length; ++i) {
       Tuple2<T1, T2> tuple = unzip(zipped[i]);
       firsts[i] = tuple.first;
diff --git a/pkg/kernel/lib/text/text_serializer.dart b/pkg/kernel/lib/text/text_serializer.dart
index 5ef2d8d..b94afb4 100644
--- a/pkg/kernel/lib/text/text_serializer.dart
+++ b/pkg/kernel/lib/text/text_serializer.dart
@@ -347,7 +347,8 @@
 
 Tuple3<DartType, DartType, List<Expression>> unwrapMapLiteral(
     MapLiteral expression) {
-  List<Expression> entries = new List(2 * expression.entries.length);
+  List<Expression> entries =
+      new List.filled(2 * expression.entries.length, null);
   for (int from = 0, to = 0; from < expression.entries.length; ++from) {
     MapEntry entry = expression.entries[from];
     entries[to++] = entry.key;
@@ -357,7 +358,7 @@
 }
 
 MapLiteral wrapMapLiteral(Tuple3<DartType, DartType, List<Expression>> tuple) {
-  List<MapEntry> entries = new List(tuple.third.length ~/ 2);
+  List<MapEntry> entries = new List.filled(tuple.third.length ~/ 2, null);
   for (int from = 0, to = 0; to < entries.length; ++to) {
     entries[to] = new MapEntry(tuple.third[from++], tuple.third[from++]);
   }
@@ -373,7 +374,7 @@
 
 MapLiteral wrapConstMapLiteral(
     Tuple3<DartType, DartType, List<Expression>> tuple) {
-  List<MapEntry> entries = new List(tuple.third.length ~/ 2);
+  List<MapEntry> entries = new List.filled(tuple.third.length ~/ 2, null);
   for (int from = 0, to = 0; to < entries.length; ++to) {
     entries[to] = new MapEntry(tuple.third[from++], tuple.third[from++]);
   }
diff --git a/pkg/kernel/lib/transformations/continuation.dart b/pkg/kernel/lib/transformations/continuation.dart
index 67dcc59..cf5e16f 100644
--- a/pkg/kernel/lib/transformations/continuation.dart
+++ b/pkg/kernel/lib/transformations/continuation.dart
@@ -818,7 +818,8 @@
     // with await in the loop's variable initializers or update expressions.
     bool isSimple = true;
     int length = stmt.variables.length;
-    List<List<Statement>> initEffects = new List<List<Statement>>(length);
+    List<List<Statement>> initEffects =
+        new List<List<Statement>>.filled(length, null);
     for (int i = 0; i < length; ++i) {
       VariableDeclaration decl = stmt.variables[i];
       initEffects[i] = <Statement>[];
@@ -831,7 +832,8 @@
     }
 
     length = stmt.updates.length;
-    List<List<Statement>> updateEffects = new List<List<Statement>>(length);
+    List<List<Statement>> updateEffects =
+        new List<List<Statement>>.filled(length, null);
     for (int i = 0; i < length; ++i) {
       updateEffects[i] = <Statement>[];
       stmt.updates[i] = expressionRewriter.rewrite(
diff --git a/pkg/kernel/lib/vm/constants_native_effects.dart b/pkg/kernel/lib/vm/constants_native_effects.dart
index 67b436b..444c44b 100644
--- a/pkg/kernel/lib/vm/constants_native_effects.dart
+++ b/pkg/kernel/lib/vm/constants_native_effects.dart
@@ -30,7 +30,7 @@
     // The _ImmutableMap class is implemented via one field pointing to a list
     // of key/value pairs -- see runtime/lib/immutable_map.dart!
     final List<Constant> kvListPairs =
-        new List<Constant>(2 * constant.entries.length);
+        new List<Constant>.filled(2 * constant.entries.length, null);
     for (int i = 0; i < constant.entries.length; i++) {
       final ConstantMapEntry entry = constant.entries[i];
       kvListPairs[2 * i] = entry.key;
diff --git a/pkg/kernel/test/binary_bench.dart b/pkg/kernel/test/binary_bench.dart
index 18c7610..a30296a 100644
--- a/pkg/kernel/test/binary_bench.dart
+++ b/pkg/kernel/test/binary_bench.dart
@@ -61,7 +61,7 @@
   }
   final warmupUs = sw.elapsedMicroseconds / warmupIterations;
 
-  final runsUs = new List<int>(benchmarkIterations);
+  final runsUs = new List<int>.filled(benchmarkIterations, null);
   for (var i = 0; i < benchmarkIterations; i++) {
     sw.reset();
     _fromBinary(bytes, eager: eager);
@@ -85,7 +85,7 @@
   }
   final warmupUs = sw.elapsedMicroseconds / warmupIterations;
 
-  final runsUs = new List<int>(benchmarkIterations);
+  final runsUs = new List<int>.filled(benchmarkIterations, null);
   for (var i = 0; i < benchmarkIterations; i++) {
     sw.reset();
     _toBinary(p);
diff --git a/pkg/kernel/test/class_hierarchy_bench.dart b/pkg/kernel/test/class_hierarchy_bench.dart
index 8168813..0026781 100644
--- a/pkg/kernel/test/class_hierarchy_bench.dart
+++ b/pkg/kernel/test/class_hierarchy_bench.dart
@@ -243,7 +243,7 @@
     classIds[class_] = classIds.length;
   }
 
-  List<int> depth = new List(classes.length);
+  List<int> depth = new List.filled(classes.length, null);
   for (int i = 0; i < depth.length; ++i) {
     int parentDepth = 0;
     var classNode = classes[i];
diff --git a/pkg/kernel/test/import_table_test.dart b/pkg/kernel/test/import_table_test.dart
index d02207f..daef20e 100644
--- a/pkg/kernel/test/import_table_test.dart
+++ b/pkg/kernel/test/import_table_test.dart
@@ -1,7 +1,7 @@
 import 'package:kernel/import_table.dart';
 
 main() {
-  List<String> paths = new List<String>();
+  List<String> paths = <String>[];
   paths.add("file://");
   paths.add("file:///a");
   paths.add("file:///a/b");
diff --git a/pkg/kernel/test/load_concat_dill_keeps_source_test.dart b/pkg/kernel/test/load_concat_dill_keeps_source_test.dart
index 05bbc05..a888455 100644
--- a/pkg/kernel/test/load_concat_dill_keeps_source_test.dart
+++ b/pkg/kernel/test/load_concat_dill_keeps_source_test.dart
@@ -53,7 +53,7 @@
   List<int> partial2Serialized = serialize(cPartial2);
   expectSource(partial2Serialized, false, true);
 
-  List<int> combined = new List<int>();
+  List<int> combined = <int>[];
   combined.addAll(partial1Serialized);
   combined.addAll(partial2Serialized);
   expectSource(combined, true, true);
@@ -83,7 +83,7 @@
   SimpleSink sink = new SimpleSink();
   BinaryPrinter printerWhole = new BinaryPrinter(sink);
   printerWhole.writeComponentFile(c);
-  List<int> result = new List<int>();
+  List<int> result = <int>[];
   for (List<int> chunk in sink.chunks) {
     result.addAll(chunk);
   }
diff --git a/pkg/kernel/tool/smoke_test_quick.dart b/pkg/kernel/tool/smoke_test_quick.dart
index bf32ec3..b5a0b9a 100644
--- a/pkg/kernel/tool/smoke_test_quick.dart
+++ b/pkg/kernel/tool/smoke_test_quick.dart
@@ -10,7 +10,7 @@
 
 main(List<String> args) async {
   Stopwatch stopwatch = new Stopwatch()..start();
-  List<Future> futures = new List<Future>();
+  List<Future> futures = <Future>[];
   futures.add(run("pkg/front_end/test/spelling_test_src_suite.dart",
       ["--", "spelling_test_src/kernel/..."]));
   await Future.wait(futures);
diff --git a/pkg/nnbd_migration/lib/src/front_end/info_builder.dart b/pkg/nnbd_migration/lib/src/front_end/info_builder.dart
index 7ee9977..2b8289c 100644
--- a/pkg/nnbd_migration/lib/src/front_end/info_builder.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/info_builder.dart
@@ -252,7 +252,8 @@
     var files = collector.files;
     var regions = collector.regions;
     var rawTargets = collector.targets;
-    var convertedTargets = List<NavigationTarget>(rawTargets.length);
+    var convertedTargets =
+        List<NavigationTarget>.filled(rawTargets.length, null);
     return regions.map((region) {
       var targets = region.targets;
       if (targets.isEmpty) {
diff --git a/pkg/sourcemap_testing/lib/src/stepping_helper.dart b/pkg/sourcemap_testing/lib/src/stepping_helper.dart
index b2c8c47..5468af7 100644
--- a/pkg/sourcemap_testing/lib/src/stepping_helper.dart
+++ b/pkg/sourcemap_testing/lib/src/stepping_helper.dart
@@ -248,7 +248,7 @@
   }
 
   List<String> sideBySide(List<String> a, List<String> b, int columns) {
-    List<String> result = new List<String>(a.length);
+    List<String> result = new List<String>.filled(a.length, null);
     for (int i = 0; i < a.length; ++i) {
       String left = a[i].padRight(columns).substring(0, columns);
       String right = b[i].padRight(columns).substring(0, columns);
diff --git a/pkg/status_file/lib/src/disjunctive.dart b/pkg/status_file/lib/src/disjunctive.dart
index 4c461b2..b94f17d 100644
--- a/pkg/status_file/lib/src/disjunctive.dart
+++ b/pkg/status_file/lib/src/disjunctive.dart
@@ -174,7 +174,7 @@
 /// finished the function returns all combined min sets.
 List<List<Expression>> _combineMinSets(
     List<List<Expression>> minSets, List<List<Expression>> primeImplicants) {
-  List<List<LogicExpression>> combined = new List<List<LogicExpression>>();
+  List<List<LogicExpression>> combined = <List<LogicExpression>>[];
   var addedInThisIteration = new Set<List<Expression>>();
   for (var i = 0; i < minSets.length; i++) {
     var minSet = minSets[i];
@@ -317,7 +317,7 @@
 // Computes the difference between two sets of expressions in disjunctive normal
 // form. if the difference is a negation, the difference is only counted once.
 List<Expression> _difference(List<Expression> As, List<Expression> Bs) {
-  var difference = new List<Expression>()
+  var difference = <Expression>[]
     ..addAll(As.where((a) => _findFirst(a, Bs) == null))
     ..addAll(Bs.where((b) => _findFirst(b, As) == null));
   for (var expression in difference.toList()) {
@@ -351,7 +351,7 @@
 /// were combined.
 List<List<LogicExpression>> _uniqueMinSets(
     List<List<LogicExpression>> minSets) {
-  var uniqueMinSets = new List<List<LogicExpression>>();
+  var uniqueMinSets = <List<LogicExpression>>[];
   for (int i = 0; i < minSets.length; i++) {
     bool foundEqual = false;
     for (var j = i - 1; j >= 0; j--) {
diff --git a/pkg/test_runner/lib/src/process_queue.dart b/pkg/test_runner/lib/src/process_queue.dart
index 947666f..7b29ea8 100644
--- a/pkg/test_runner/lib/src/process_queue.dart
+++ b/pkg/test_runner/lib/src/process_queue.dart
@@ -778,7 +778,7 @@
     // Start batch processes if needed.
     var runners = _batchProcesses[identifier];
     if (runners == null) {
-      runners = List<BatchRunnerProcess>(maxProcesses);
+      runners = List<BatchRunnerProcess>.filled(maxProcesses, null);
       for (var i = 0; i < maxProcesses; i++) {
         runners[i] = BatchRunnerProcess(useJson: identifier == "fasta");
       }
diff --git a/pkg/testing/lib/src/test_dart/path.dart b/pkg/testing/lib/src/test_dart/path.dart
index 5d22c0e..3c5fbea 100644
--- a/pkg/testing/lib/src/test_dart/path.dart
+++ b/pkg/testing/lib/src/test_dart/path.dart
@@ -121,7 +121,7 @@
     while (common < length && pathSegments[common] == baseSegments[common]) {
       common++;
     }
-    final segments = new List<String>();
+    final segments = <String>[];
 
     if (common < baseSegments.length && baseSegments[common] == '..') {
       throw new ArgumentError("Invalid case of Path.relativeTo(base):\n"
diff --git a/pkg/testing/lib/src/test_dart/status_expression.dart b/pkg/testing/lib/src/test_dart/status_expression.dart
index d1af0ba..200d241 100644
--- a/pkg/testing/lib/src/test_dart/status_expression.dart
+++ b/pkg/testing/lib/src/test_dart/status_expression.dart
@@ -53,7 +53,7 @@
   String expression;
   List<String> tokens;
 
-  Tokenizer(String this.expression) : tokens = new List<String>();
+  Tokenizer(String this.expression) : tokens = <String>[];
 
   // Tokens are : "(", ")", "$", ",", "&&", "||", "==", "!=", and (maximal) \w+.
   static final testRegexp =
diff --git a/pkg/testing/lib/src/test_dart/status_file_parser.dart b/pkg/testing/lib/src/test_dart/status_file_parser.dart
index 60c39f8..1ce711f 100644
--- a/pkg/testing/lib/src/test_dart/status_file_parser.dart
+++ b/pkg/testing/lib/src/test_dart/status_file_parser.dart
@@ -35,9 +35,9 @@
 
   Section.always(this.statusFile, this.lineNumber)
       : condition = null,
-        testRules = new List<TestRule>();
+        testRules = <TestRule>[];
   Section(this.statusFile, this.condition, this.lineNumber)
-      : testRules = new List<TestRule>();
+      : testRules = <TestRule>[];
 
   bool isEnabled(Map<String, String> environment) =>
       condition == null || condition.evaluate(environment);
@@ -58,7 +58,7 @@
 Future<void> ReadTestExpectationsInto(TestExpectations expectations,
     String statusFilePath, Map<String, String> environment) {
   var completer = new Completer();
-  List<Section> sections = new List<Section>();
+  List<Section> sections = <Section>[];
 
   void sectionsRead() {
     for (Section section in sections) {
@@ -233,7 +233,7 @@
     _map.forEach((key, expectations) {
       if (_keyToRegExps[key] != null) return;
       var splitKey = key.split('/');
-      var regExps = new List<RegExp>(splitKey.length);
+      var regExps = new List<RegExp>.filled(splitKey.length, null);
       for (var i = 0; i < splitKey.length; i++) {
         var component = splitKey[i];
         var regExp = _regExpCache[component];
diff --git a/pkg/vm/bin/kernel_service.dart b/pkg/vm/bin/kernel_service.dart
index fb5d3f1..13aa646 100644
--- a/pkg/vm/bin/kernel_service.dart
+++ b/pkg/vm/bin/kernel_service.dart
@@ -155,7 +155,7 @@
   final bool supportCodeCoverage;
   final bool supportHotReload;
 
-  final List<String> errors = new List<String>();
+  final List<String> errors = <String>[];
 
   CompilerOptions options;
 
@@ -621,7 +621,7 @@
 
 void _recordDependencies(
     int isolateId, Component component, Uri packageConfig) {
-  final dependencies = isolateDependencies[isolateId] ??= new List<Uri>();
+  final dependencies = isolateDependencies[isolateId] ??= <Uri>[];
 
   if (component != null) {
     for (var lib in component.libraries) {
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index c123f75..eb8f045 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -627,7 +627,7 @@
 /// The list of package names is written into a file '[outputFileName]-packages'.
 Future writeOutputSplitByPackages(Uri source, CompilerOptions compilerOptions,
     KernelCompilationResults compilationResults, String outputFileName) async {
-  final packages = new List<String>();
+  final packages = <String>[];
   await runWithFrontEndCompilerContext(
       source, compilerOptions, compilationResults.component, () async {
     // When loading a kernel file list, flutter_runner and dart_runner expect
@@ -692,11 +692,10 @@
   sortComponent(component);
 
   final packages = new Map<String, List<Library>>();
-  packages['main'] = new List<Library>(); // Always create 'main'.
+  packages['main'] = <Library>[]; // Always create 'main'.
   for (Library lib in component.libraries) {
     packages
-        .putIfAbsent(
-            packageFor(lib, loadedLibraries), () => new List<Library>())
+        .putIfAbsent(packageFor(lib, loadedLibraries), () => <Library>[])
         .add(lib);
   }
   packages.remove(null); // Ignore external libraries.
diff --git a/pkg/vm/lib/transformations/late_var_init_transformer.dart b/pkg/vm/lib/transformations/late_var_init_transformer.dart
index 1dc1a87..4acb7e4 100644
--- a/pkg/vm/lib/transformations/late_var_init_transformer.dart
+++ b/pkg/vm/lib/transformations/late_var_init_transformer.dart
@@ -49,7 +49,7 @@
 
   List<Statement> _transformStatements(List<Statement> statements) {
     if (!statements.any((s) => _shouldApplyTransform(s))) return null;
-    final List<Statement> newStatements = List<Statement>();
+    final List<Statement> newStatements = <Statement>[];
     for (Statement s in statements) {
       if (_shouldApplyTransform(s)) {
         newStatements.addAll(_transformVariableDeclaration(s));
diff --git a/pkg/vm/lib/transformations/type_flow/analysis.dart b/pkg/vm/lib/transformations/type_flow/analysis.dart
index 06490ea..b5c33f7 100644
--- a/pkg/vm/lib/transformations/type_flow/analysis.dart
+++ b/pkg/vm/lib/transformations/type_flow/analysis.dart
@@ -696,7 +696,7 @@
       assert(_type is ConcreteType);
       assert(_type != type);
 
-      _list = new List<ConcreteType>();
+      _list = <ConcreteType>[];
       _list.add(_type);
 
       _type = null;
@@ -966,7 +966,7 @@
     } else if (numSubTypes == 1) {
       return _allocatedSubtypes.single.concreteType;
     } else {
-      List<ConcreteType> types = new List<ConcreteType>();
+      List<ConcreteType> types = <ConcreteType>[];
       for (var sub in _allocatedSubtypes) {
         types.add(sub.concreteType);
       }
@@ -1052,7 +1052,7 @@
 
     List<DartType> flattenedTypeArgs =
         flattenedTypeArgumentsFor(klass, useCache: false);
-    result = new List<Type>(flattenedTypeArgs.length);
+    result = new List<Type>.filled(flattenedTypeArgs.length, null);
     for (int i = 0; i < flattenedTypeArgs.length; ++i) {
       final translated = closedTypeTranslator.translate(flattenedTypeArgs[i]);
       assert(translated is RuntimeType || translated is UnknownType);
diff --git a/pkg/vm/lib/transformations/type_flow/summary.dart b/pkg/vm/lib/transformations/type_flow/summary.dart
index d529e68..b009b27 100644
--- a/pkg/vm/lib/transformations/type_flow/summary.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary.dart
@@ -245,7 +245,7 @@
   @override
   Type apply(List<Type> computedTypes, TypeHierarchy typeHierarchy,
       CallHandler callHandler) {
-    final List<Type> argTypes = new List<Type>(args.values.length);
+    final List<Type> argTypes = new List<Type>.filled(args.values.length, null);
     for (int i = 0; i < args.values.length; i++) {
       final Type type = args.values[i].getComputedType(computedTypes);
       if (type == const EmptyType()) {
@@ -451,7 +451,7 @@
   Type apply(List<Type> computedTypes, TypeHierarchy typeHierarchy,
       CallHandler callHandler) {
     bool hasRuntimeType = false;
-    final types = new List<Type>(flattenedTypeArgs.length);
+    final types = new List<Type>.filled(flattenedTypeArgs.length, null);
     for (int i = 0; i < types.length; ++i) {
       final computed = flattenedTypeArgs[i].getComputedType(computedTypes);
       assert(computed is RuntimeType || computed is UnknownType);
@@ -483,7 +483,7 @@
   @override
   Type apply(List<Type> computedTypes, TypeHierarchy typeHierarchy,
       CallHandler callHandler) {
-    final types = new List<RuntimeType>(flattenedTypeArgs.length);
+    final types = new List<RuntimeType>.filled(flattenedTypeArgs.length, null);
     for (int i = 0; i < types.length; ++i) {
       final computed = flattenedTypeArgs[i].getComputedType(computedTypes);
       assert(computed is RuntimeType || computed is UnknownType);
@@ -637,7 +637,7 @@
     //
     // The first `parameterCount` statements are Parameters.
 
-    List<Type> types = new List<Type>(_statements.length);
+    List<Type> types = new List<Type>.filled(_statements.length, null);
 
     for (int i = 0; i < positionalArgCount; i++) {
       final Parameter param = _statements[i] as Parameter;
@@ -703,9 +703,9 @@
   }
 
   Args<Type> get argumentTypes {
-    final argTypes = new List<Type>(parameterCount);
-    final argNames =
-        new List<String>(parameterCount - positionalParameterCount);
+    final argTypes = new List<Type>.filled(parameterCount, null);
+    final argNames = new List<String>.filled(
+        parameterCount - positionalParameterCount, null);
     for (int i = 0; i < parameterCount; i++) {
       Parameter param = _statements[i] as Parameter;
       argTypes[i] = param.argumentType;
@@ -737,7 +737,7 @@
   }
 
   List<VariableDeclaration> get uncheckedParameters {
-    final params = List<VariableDeclaration>();
+    final params = <VariableDeclaration>[];
     for (Statement statement in _statements) {
       if (statement is TypeCheck &&
           statement.canAlwaysSkip &&
diff --git a/pkg/vm/lib/transformations/type_flow/summary_collector.dart b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
index 68162e7..51daa89 100644
--- a/pkg/vm/lib/transformations/type_flow/summary_collector.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
@@ -605,8 +605,9 @@
 
     _staticTypeContext = new StaticTypeContext(member, _environment);
     _variablesInfo = new _VariablesInfoCollector(member);
-    _variableValues = new List<TypeExpr>(_variablesInfo.numVariables);
-    _variableCells = new List<Join>(_variablesInfo.numVariables);
+    _variableValues =
+        new List<TypeExpr>.filled(_variablesInfo.numVariables, null);
+    _variableCells = new List<Join>.filled(_variablesInfo.numVariables, null);
     _variableVersions = new List<int>.filled(_variablesInfo.numVariables, 0);
     _variableValuesAfterLabeledStatements = null;
     _joinsAtSwitchCases = null;
@@ -943,7 +944,7 @@
       new List<TypeExpr>.from(values);
 
   List<TypeExpr> _makeEmptyVariableValues() {
-    final values = new List<TypeExpr>(_variablesInfo.numVariables);
+    final values = new List<TypeExpr>.filled(_variablesInfo.numVariables, null);
     for (int i = 0; i < values.length; ++i) {
       if (_variableCells[i] != null) {
         values[i] = _variableValues[i];
@@ -1008,7 +1009,8 @@
   }
 
   List<Join> _insertJoinsForModifiedVariables(TreeNode node, bool isTry) {
-    final List<Join> joins = new List<Join>(_variablesInfo.numVariables);
+    final List<Join> joins =
+        new List<Join>.filled(_variablesInfo.numVariables, null);
     for (var i in _variablesInfo.getModifiedVariables(node)) {
       if (_variableCells[i] != null) {
         assert(_variableCells[i] == _variableValues[i]);
@@ -2198,7 +2200,8 @@
     final substitution = Substitution.fromPairs(klass.typeParameters, typeArgs);
     final flattenedTypeArgs =
         genericInterfacesInfo.flattenedTypeArgumentsFor(klass);
-    final flattenedTypeExprs = new List<TypeExpr>(flattenedTypeArgs.length);
+    final flattenedTypeExprs =
+        new List<TypeExpr>.filled(flattenedTypeArgs.length, null);
 
     bool createConcreteType = true;
     bool allUnknown = true;
@@ -2269,7 +2272,8 @@
         type.classNode.typeParameters, type.typeArguments);
     final flattenedTypeArgs =
         genericInterfacesInfo.flattenedTypeArgumentsFor(type.classNode);
-    final flattenedTypeExprs = new List<TypeExpr>(flattenedTypeArgs.length);
+    final flattenedTypeExprs =
+        new List<TypeExpr>.filled(flattenedTypeArgs.length, null);
 
     bool createRuntimeType = true;
     for (var i = 0; i < flattenedTypeArgs.length; ++i) {
diff --git a/pkg/vm/lib/transformations/type_flow/table_selector_assigner.dart b/pkg/vm/lib/transformations/type_flow/table_selector_assigner.dart
index 1d78d39..2cfe329 100644
--- a/pkg/vm/lib/transformations/type_flow/table_selector_assigner.dart
+++ b/pkg/vm/lib/transformations/type_flow/table_selector_assigner.dart
@@ -25,7 +25,7 @@
         _memberIdsForClass(cls, getter: true);
       }
     }
-    _selectorIdForMemberId = List(_unionFind.size);
+    _selectorIdForMemberId = List.filled(_unionFind.size, null);
     // Assign all selector IDs eagerly to make them independent of how they are
     // queried in later phases. This makes TFA test expectation files (which
     // contain selector IDs) more stable under changes to how selector IDs are
diff --git a/pkg/vm/lib/transformations/type_flow/types.dart b/pkg/vm/lib/transformations/type_flow/types.dart
index c5754ed..4392865 100644
--- a/pkg/vm/lib/transformations/type_flow/types.dart
+++ b/pkg/vm/lib/transformations/type_flow/types.dart
@@ -858,7 +858,7 @@
       } else if (other.typeArgs == null) {
         mergedTypeArgs = typeArgs;
       } else {
-        mergedTypeArgs = new List<Type>(typeArgs.length);
+        mergedTypeArgs = new List<Type>.filled(typeArgs.length, null);
         bool hasRuntimeType = false;
         for (int i = 0; i < typeArgs.length; ++i) {
           final merged =
diff --git a/pkg/vm/test/incremental_compiler_test.dart b/pkg/vm/test/incremental_compiler_test.dart
index 52a98e6..00a1a1c 100644
--- a/pkg/vm/test/incremental_compiler_test.dart
+++ b/pkg/vm/test/incremental_compiler_test.dart
@@ -145,7 +145,7 @@
     }
 
     // Collect coverage for the two user scripts.
-    List<Map> sourceReports = new List<Map>();
+    List<Map> sourceReports = <Map>[];
     if (getAllSources) {
       Map sourceReport = await remoteVm.getSourceReport();
       sourceReports.add(sourceReport);
@@ -167,7 +167,7 @@
       }
     }
 
-    List<String> errorMessages = new List<String>();
+    List<String> errorMessages = <String>[];
     Set<int> hits = new Set<int>();
 
     // Ensure that we can get a line and column number for all reported
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/dynamic_list_access.dart b/pkg/vm/testcases/transformations/type_flow/transformer/dynamic_list_access.dart
index 560aabe..5f51fa3 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/dynamic_list_access.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/dynamic_list_access.dart
@@ -1,4 +1,4 @@
 main() {
-  dynamic x = List<int>(10);
+  dynamic x = List<int>.filled(10, null);
   x[0] + 10;
 }
diff --git a/pkg/vm_service/test/heap_snapshot_graph_test.dart b/pkg/vm_service/test/heap_snapshot_graph_test.dart
index 7bd4418..7b035cc 100644
--- a/pkg/vm_service/test/heap_snapshot_graph_test.dart
+++ b/pkg/vm_service/test/heap_snapshot_graph_test.dart
@@ -27,10 +27,10 @@
   r.right = b;
   a.left = b;
 
-  lst = List(2);
+  lst = List.filled(2, null);
   lst[0] = lst; // Self-loop.
   // Larger than any other fixed-size list in a fresh heap.
-  lst[1] = List(1234569);
+  lst[1] = List.filled(1234569, null);
 }
 
 var tests = <IsolateTest>[
diff --git a/pkg/vm_snapshot_analysis/lib/program_info.dart b/pkg/vm_snapshot_analysis/lib/program_info.dart
index c139f02..e243048 100644
--- a/pkg/vm_snapshot_analysis/lib/program_info.dart
+++ b/pkg/vm_snapshot_analysis/lib/program_info.dart
@@ -62,7 +62,7 @@
       void Function(
               String pkg, String lib, String cls, String fun, ProgramInfoNode n)
           callback) {
-    final context = List<String>(NodeType.values.length);
+    final context = List<String>.filled(NodeType.values.length, null);
 
     void recurse(ProgramInfoNode node) {
       final prevContext = context[node._type];
diff --git a/pkg/vm_snapshot_analysis/lib/treemap.dart b/pkg/vm_snapshot_analysis/lib/treemap.dart
index 36ce891..c0535e7 100644
--- a/pkg/vm_snapshot_analysis/lib/treemap.dart
+++ b/pkg/vm_snapshot_analysis/lib/treemap.dart
@@ -163,7 +163,8 @@
     return;
   }
 
-  final ownerPathCache = List<String>(info.snapshotInfo.infoNodes.length);
+  final ownerPathCache =
+      List<String>.filled(info.snapshotInfo.infoNodes.length, null);
   ownerPathCache[info.root.id] = info.root.name;
 
   String ownerPath(ProgramInfoNode n) {
diff --git a/runtime/bin/socket.cc b/runtime/bin/socket.cc
index 6881e59..6769a93 100644
--- a/runtime/bin/socket.cc
+++ b/runtime/bin/socket.cc
@@ -431,7 +431,8 @@
   RawAddr sourceAddr;
   address = Dart_GetNativeArgument(args, 2);
   if (Dart_IsNull(address)) {
-    Dart_SetReturnValue(args,
+    return Dart_SetReturnValue(
+        args,
         DartUtils::NewDartArgumentError("expect address to be of type String"));
   }
   result = SocketAddress::GetUnixDomainSockAddr(
@@ -462,7 +463,8 @@
   RawAddr addr;
   Dart_Handle address = Dart_GetNativeArgument(args, 1);
   if (Dart_IsNull(address)) {
-    Dart_SetReturnValue(args,
+    return Dart_SetReturnValue(
+        args,
         DartUtils::NewDartArgumentError("expect address to be of type String"));
   }
   Dart_Handle result = SocketAddress::GetUnixDomainSockAddr(
diff --git a/runtime/vm/compiler/recognized_methods_list.h b/runtime/vm/compiler/recognized_methods_list.h
index 88a8b64a..a78c350 100644
--- a/runtime/vm/compiler/recognized_methods_list.h
+++ b/runtime/vm/compiler/recognized_methods_list.h
@@ -15,7 +15,7 @@
   V(::, identical, ObjectIdentical, 0x19eb7f33)                                \
   V(ClassID, getID, ClassIDgetID, 0x4d140cb3)                                  \
   V(Object, Object., ObjectConstructor, 0x89c467da)                            \
-  V(List, ., ListFactory, 0x1892c890)                                          \
+  V(List, ., ListFactory, 0x1892cc51)                                          \
   V(_List, ., ObjectArrayAllocate, 0x4c9d39e2)                                 \
   V(_List, []=, ObjectArraySetIndexed, 0xe98d0a9e)                             \
   V(_GrowableList, []=, GrowableArraySetIndexed, 0xe98d0a9e)                   \
diff --git a/sdk/lib/_internal/vm/bin/socket_patch.dart b/sdk/lib/_internal/vm/bin/socket_patch.dart
index f2a91d8..0cb43ee 100644
--- a/sdk/lib/_internal/vm/bin/socket_patch.dart
+++ b/sdk/lib/_internal/vm/bin/socket_patch.dart
@@ -580,21 +580,22 @@
     // attempt isn't made until either a previous attempt has *failed*,
     // or the delay has passed.
     // This ensures that at most *n* uncompleted connections can be
-    // active after *n* &times; *delay* time has passed.
+    // active after *n* × *delay* time has passed.
     if (host is String) {
       host = escapeLinkLocalAddress(host);
     }
     _throwOnBadPort(port);
     _InternetAddress? source;
-    if (sourceAddress is _InternetAddress) {
-      source = sourceAddress;
-    } else if (sourceAddress is String) {
-      source = new _InternetAddress.fromString(sourceAddress);
+    if (sourceAddress != null) {
+      if (sourceAddress is _InternetAddress) {
+        source = sourceAddress;
+      } else if (sourceAddress is String) {
+        source = new _InternetAddress.fromString(sourceAddress);
+      } else {
+        throw ArgumentError.value(sourceAddress, "sourceAddress",
+            "Must be a string or native InternetAddress");
+      }
     }
-    // Should we throw if sourceAddress is not one of:
-    // null, _InternetAddress or String?
-    // Is it somehow ensured upstream
-    // that only those three types will reach here?
     return new Future.value(host).then<List<InternetAddress>>((host) {
       if (host is _InternetAddress) return [host];
       return lookup(host).then((addresses) {
@@ -606,7 +607,7 @@
     }).then((addresses) {
       assert(addresses.isNotEmpty);
       // Completer for result.
-      var completer = new Completer<_NativeSocket>();
+      var result = new Completer<_NativeSocket>();
       // Index of next address in [addresses] to try.
       var index = 0;
       // Error, set if an error occurs.
@@ -632,43 +633,55 @@
         if (index >= addresses.length) {
           if (connecting.isEmpty) {
             assert(error != null);
-            assert(!completer.isCompleted);
-            completer.completeError(error);
+            assert(!result.isCompleted);
+            result.completeError(error);
           }
           return;
         }
         final address = addresses[index++] as _InternetAddress;
         var socket = new _NativeSocket.normal(address);
-        var result;
-        if (source == null) {
-          if (address.type == InternetAddressType.unix) {
-            result = socket.nativeCreateUnixDomainConnect(
+        // Will contain values of various types representing the result
+        // of trying to create a connection.
+        // A value of `true` means success, everything else means failure.
+        Object? connectionResult;
+        if (address.type == InternetAddressType.unix) {
+          if (source == null) {
+            connectionResult = socket.nativeCreateUnixDomainConnect(
                 address.address, _Namespace._namespace);
           } else {
-            result = socket.nativeCreateConnect(
-                address._in_addr, port, address._scope_id);
-          }
-        } else {
-          if (address.type == InternetAddressType.unix) {
             assert(source.type == InternetAddressType.unix);
-            result = socket.nativeCreateUnixDomainBindConnect(
+            connectionResult = socket.nativeCreateUnixDomainBindConnect(
                 address.address, source.address, _Namespace._namespace);
+          }
+          assert(connectionResult == true ||
+              connectionResult is Error ||
+              connectionResult is OSError);
+        } else {
+          if (source == null) {
+            connectionResult = socket.nativeCreateConnect(
+                address._in_addr, port, address._scope_id);
           } else {
-            result = socket.nativeCreateBindConnect(
+            connectionResult = socket.nativeCreateBindConnect(
                 address._in_addr, port, source._in_addr, address._scope_id);
           }
+          assert(connectionResult == true || connectionResult is OSError);
         }
-        if (result is OSError) {
-          // Keep first error, if present.
-          if (error == null) {
-            int errorCode = result.errorCode;
+        if (connectionResult != true) {
+          // connectionResult was not a success.
+          if (connectionResult is OSError) {
+            int errorCode = connectionResult.errorCode;
             if (source != null &&
                 errorCode != null &&
                 socket.isBindError(errorCode)) {
-              error = createError(result, "Bind failed", source);
+              error = createError(connectionResult, "Bind failed", source);
             } else {
-              error = createError(result, "Connection failed", address, port);
+              error = createError(
+                  connectionResult, "Connection failed", address, port);
             }
+          } else if (connectionResult is Error) {
+            error = connectionResult;
+          } else {
+            error = createError(null, "Connection failed", address);
           }
           connectNext(); // Try again after failure to connect.
           return;
@@ -722,7 +735,7 @@
             s.setListening(read: false, write: false);
           }
           connecting.clear();
-          completer.complete(socket);
+          result.complete(socket);
         }, error: (e, st) {
           connecting.remove(socket);
           socket.close();
@@ -743,15 +756,15 @@
           s.setListening(read: false, write: false);
         }
         connecting.clear();
-        if (!completer.isCompleted) {
+        if (!result.isCompleted) {
           error ??= createError(null,
               "Connection attempt cancelled, host: ${host}, port: ${port}");
-          completer.completeError(error);
+          result.completeError(error);
         }
       }
 
       connectNext();
-      return new ConnectionTask<_NativeSocket>._(completer.future, onCancel);
+      return new ConnectionTask<_NativeSocket>._(result.future, onCancel);
     });
   }
 
diff --git a/sdk/lib/core/list.dart b/sdk/lib/core/list.dart
index 78575ba..e342bb7 100644
--- a/sdk/lib/core/list.dart
+++ b/sdk/lib/core/list.dart
@@ -27,7 +27,7 @@
  * The following code illustrates that some List implementations support
  * only a subset of the API.
  *
- *     List<int> fixedLengthList = new List(5);
+ *     List<int> fixedLengthList = new List.filled(5);
  *     fixedLengthList.length = 0;  // Error
  *     fixedLengthList.add(499);    // Error
  *     fixedLengthList[0] = 87;
@@ -55,13 +55,16 @@
   /**
    * Creates a list of the given length.
    *
-   * This constructor will throw an exception if [E] is not a nullable type.
-   * In this case, another constructor such as [List.filled] must be used
-   * instead.
+   * **NOTICE**: This constructor cannot be used in null-safe code.
+   * Use [List.filled] to create a non-empty list.
+   * This requires a fill value to initialize the list elements with.
+   * To create an empty list, use `[]` for a growable list or
+   * `List.empty` for a fixed length list (or where growability is determined
+   * at run-time).
    *
    * The created list is fixed-length if [length] is provided.
    *
-   *     List fixedLengthList = new List(3);
+   *     List fixedLengthList = new List.filled(3);
    *     fixedLengthList.length;     // 3
    *     fixedLengthList.length = 1; // Error
    *
@@ -84,14 +87,8 @@
    *
    * If the element type is not nullable, [length] must not be greater than
    * zero.
-   *
-   * This constructor cannot be used in null-safe code.
-   * Use [List.filled] to create a non-empty list.
-   * This requires a fill value to initialize the list elements with.
-   * To create an empty list, use `[]` for a growable list or
-   * `List.empty` for a fixed length list (or where growability is determined
-   * at run-time).
    */
+  @deprecated
   external factory List([int? length]);
 
   /**
@@ -705,7 +702,7 @@
    *
    * Example:
    * ```dart
-   *  List<int> list = new List(3);
+   *  List<int> list = new List.filled(3);
    *     list.fillRange(0, 2, 1);
    *     print(list); //  [1, 1, null]
    * ```
diff --git a/sdk/lib/internal/list.dart b/sdk/lib/internal/list.dart
index 0a8b6a9..fc24360 100644
--- a/sdk/lib/internal/list.dart
+++ b/sdk/lib/internal/list.dart
@@ -328,13 +328,15 @@
  * Converts a fixed-length list to an unmodifiable list.
  *
  * For internal use only.
- * Only works for core fixed-length lists as created by `new List(length)`,
+ *
+ * Only works for core fixed-length lists as created by
+ * `List.filled(length)`/`List.empty()`,
  * or as returned by [makeListFixedLength].
  *
  * The operation is efficient. It doesn't copy the elements, but converts
  * the existing list directly to a fixed length list.
  * That means that it is a destructive conversion.
- * The original list should not be used afterwards.
+ * The original list reference should not be used afterwards.
  *
  * The unmodifiable list type is similar to the one used by const lists.
  */
diff --git a/tests/language/parameter/initializer6_test.dart b/tests/language/parameter/initializer6_test.dart
index 9a5ebda..117a0c3 100644
--- a/tests/language/parameter/initializer6_test.dart
+++ b/tests/language/parameter/initializer6_test.dart
@@ -9,7 +9,7 @@
 class Foo {
   num _y;
   Foo.private({this._y: 77}) {}
-  //           ^^^^^^^
+  //                ^^
   // [analyzer] COMPILE_TIME_ERROR.PRIVATE_OPTIONAL_PARAMETER
   //                ^
   // [cfe] An optional named parameter can't start with '_'.
diff --git a/tests/language_2/parameter/initializer6_test.dart b/tests/language_2/parameter/initializer6_test.dart
index 9a5ebda..117a0c3 100644
--- a/tests/language_2/parameter/initializer6_test.dart
+++ b/tests/language_2/parameter/initializer6_test.dart
@@ -9,7 +9,7 @@
 class Foo {
   num _y;
   Foo.private({this._y: 77}) {}
-  //           ^^^^^^^
+  //                ^^
   // [analyzer] COMPILE_TIME_ERROR.PRIVATE_OPTIONAL_PARAMETER
   //                ^
   // [cfe] An optional named parameter can't start with '_'.
diff --git a/tools/VERSION b/tools/VERSION
index 91de3c0..2f20bdc 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 12
 PATCH 0
-PRERELEASE 128
+PRERELEASE 129
 PRERELEASE_PATCH 0
\ No newline at end of file