Version 2.10.0-21.0.dev

Merge commit 'a3b15aefcaed10e62444d449394d561b3b12dcb4' into 'dev'
diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
index e2285a0..fb49ebe 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
@@ -3273,6 +3273,7 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageExternalLateField = const MessageCode(
     "ExternalLateField",
+    index: 109,
     message: r"""External fields cannot be late.""",
     tip: r"""Try removing the 'external' or 'late' keyword.""");
 
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 7d6d0e3..57b0902 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,3 +1,6 @@
+## 0.39.18-dev
+* Added `LibraryElement.featureSet`.
+
 ## 0.39.17
 * Depend on cli_util 0.2.0.
 
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index a2e9d64..8a4d9b9 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -34,6 +34,7 @@
 /// representation of the statements in a method body, but if one of those
 /// statements declares a local variable then the local variable will be
 /// represented by an element.
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/dart/constant/value.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
@@ -1317,6 +1318,13 @@
   /// Return a list containing all of the exports defined in this library.
   List<ExportElement> get exports;
 
+  /// The set of features available to this library.
+  ///
+  /// Determined by the combination of the language version for the enclosing
+  /// package, enabled experiments, and the presence of a `// @dart` language
+  /// version override comment at the top of the file.
+  FeatureSet get featureSet;
+
   /// Return `true` if the defining compilation unit of this library contains at
   /// least one import directive whose URI uses the "dart-ext" scheme.
   bool get hasExtUri;
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 9c7bfac..095f89c 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -172,6 +172,9 @@
   CompileTimeErrorCode.EXTENSION_OVERRIDE_ARGUMENT_NOT_ASSIGNABLE,
   CompileTimeErrorCode.EXTENSION_OVERRIDE_WITH_CASCADE,
   CompileTimeErrorCode.EXTENSION_OVERRIDE_WITHOUT_ACCESS,
+  CompileTimeErrorCode.EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER,
+  CompileTimeErrorCode.EXTERNAL_FIELD_INITIALIZER,
+  CompileTimeErrorCode.EXTERNAL_VARIABLE_INITIALIZER,
   CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS,
   CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED,
   CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS,
@@ -632,6 +635,7 @@
   ParserErrorCode.EXTERNAL_FACTORY_WITH_BODY,
   ParserErrorCode.EXTERNAL_FIELD,
   ParserErrorCode.EXTERNAL_GETTER_WITH_BODY,
+  ParserErrorCode.EXTERNAL_LATE_FIELD,
   ParserErrorCode.EXTERNAL_METHOD_WITH_BODY,
   ParserErrorCode.EXTERNAL_OPERATOR_WITH_BODY,
   ParserErrorCode.EXTERNAL_SETTER_WITH_BODY,
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 81e5485..94b9332 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -91,7 +91,7 @@
 /// TODO(scheglov) Clean up the list of implicitly analyzed files.
 class AnalysisDriver implements AnalysisDriverGeneric {
   /// The version of data format, should be incremented on every format change.
-  static const int DATA_VERSION = 108;
+  static const int DATA_VERSION = 109;
 
   /// The length of the list returned by [_computeDeclaredVariablesSignature].
   static const int _declaredVariablesSignatureLength = 4;
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 2456a92..f40eb69 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -4,6 +4,7 @@
 
 import 'dart:collection';
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
@@ -5369,6 +5370,9 @@
   }
 
   @override
+  FeatureSet get featureSet => (linkedNode as CompilationUnit).featureSet;
+
+  @override
   bool get hasExtUri {
     if (linkedNode != null) {
       var unit = linkedContext.unit_withDirectives;
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
index 57cc394..f55c540 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
@@ -303,6 +303,8 @@
       correction: "Try removing the body of the getter, or "
           "removing the keyword 'external'.");
 
+  static const ParserErrorCode EXTERNAL_LATE_FIELD = _EXTERNAL_LATE_FIELD;
+
   static const ParserErrorCode EXTERNAL_METHOD_WITH_BODY =
       _EXTERNAL_METHOD_WITH_BODY;
 
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
index 748f18c..8c50c14 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
@@ -116,6 +116,7 @@
   _EXTERNAL_CONSTRUCTOR_WITH_INITIALIZER,
   _ABSTRACT_STATIC_FIELD,
   _ABSTRACT_LATE_FIELD,
+  _EXTERNAL_LATE_FIELD,
 ];
 
 const ParserErrorCode _ABSTRACT_CLASS_MEMBER = ParserErrorCode(
@@ -315,6 +316,10 @@
     correction:
         "Try removing the keyword 'external', or replacing the field by an external getter and/or setter.");
 
+const ParserErrorCode _EXTERNAL_LATE_FIELD = ParserErrorCode(
+    'EXTERNAL_LATE_FIELD', r"External fields cannot be late.",
+    correction: "Try removing the 'external' or 'late' keyword.");
+
 const ParserErrorCode _EXTERNAL_METHOD_WITH_BODY = ParserErrorCode(
     'EXTERNAL_METHOD_WITH_BODY',
     r"An external or native method can't have a body.");
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index b126f7e..a0b721c 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -2980,6 +2980,25 @@
           correction: "Consider adding an access to an instance member.",
           hasPublishedDocs: true);
 
+  static const CompileTimeErrorCode EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER =
+      CompileTimeErrorCode('EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER',
+          'External fields cannot have initializers.',
+          correction:
+              "Try removing the field initializer or the 'external' keyword "
+              "from the field declaration.");
+
+  static const CompileTimeErrorCode EXTERNAL_FIELD_INITIALIZER =
+      CompileTimeErrorCode('EXTERNAL_FIELD_INITIALIZER',
+          'External fields cannot have initializers.',
+          correction:
+              "Try removing the initializer or the 'external' keyword.");
+
+  static const CompileTimeErrorCode EXTERNAL_VARIABLE_INITIALIZER =
+      CompileTimeErrorCode('EXTERNAL_VARIABLE_INITIALIZER',
+          'External variables cannot have initializers.',
+          correction:
+              "Try removing the initializer or the 'external' keyword.");
+
   /**
    * Parameters:
    * 0: the maximum number of positional arguments
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index 8ababeb..839f9a6 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -15,6 +15,7 @@
         messageDirectiveAfterDeclaration,
         messageExpectedStatement,
         messageExternalField,
+        messageExternalLateField,
         messageFieldInitializerOutsideConstructor,
         messageIllegalAssignmentToNonAssignable,
         messageInterpolationInUri,
@@ -866,9 +867,14 @@
         }
       }
     }
-    if (externalToken != null && !enableNonNullable) {
-      handleRecoverableError(
-          messageExternalField, externalToken, externalToken);
+    if (externalToken != null) {
+      if (!enableNonNullable) {
+        handleRecoverableError(
+            messageExternalField, externalToken, externalToken);
+      } else if (lateToken != null) {
+        handleRecoverableError(
+            messageExternalLateField, externalToken, externalToken);
+      }
     }
 
     List<VariableDeclaration> variables = popTypedList(count);
@@ -2153,9 +2159,14 @@
     assert(optional(';', semicolon));
     debugEvent("TopLevelFields");
 
-    if (externalToken != null && !enableNonNullable) {
-      handleRecoverableError(
-          messageExternalField, externalToken, externalToken);
+    if (externalToken != null) {
+      if (!enableNonNullable) {
+        handleRecoverableError(
+            messageExternalField, externalToken, externalToken);
+      } else if (lateToken != null) {
+        handleRecoverableError(
+            messageExternalLateField, externalToken, externalToken);
+      }
     }
 
     List<VariableDeclaration> variables = popTypedList(count);
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 91f08b0..1576546 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -491,7 +491,7 @@
       _checkForInvalidField(node, fieldName, staticElement);
       if (staticElement is FieldElement) {
         _checkForFieldInitializerNotAssignable(node, staticElement);
-        _checkForAbstractFieldConstructorInitializer(
+        _checkForAbstractOrExternalFieldConstructorInitializer(
             node.fieldName, staticElement);
       }
       super.visitConstructorFieldInitializer(node);
@@ -605,7 +605,7 @@
     if (element is FieldFormalParameterElement) {
       FieldElement fieldElement = element.field;
       if (fieldElement != null) {
-        _checkForAbstractFieldConstructorInitializer(
+        _checkForAbstractOrExternalFieldConstructorInitializer(
             node.identifier, fieldElement);
       }
     }
@@ -1200,7 +1200,7 @@
     // do checks
     _checkForInvalidAssignment(nameNode, initializerNode);
     _checkForImplicitDynamicIdentifier(node, nameNode);
-    _checkForAbstractFieldInitializer(node);
+    _checkForAbstractOrExternalVariableInitializer(node);
     // visit name
     nameNode.accept(this);
     // visit initializer
@@ -1294,21 +1294,37 @@
     }
   }
 
-  void _checkForAbstractFieldConstructorInitializer(
+  void _checkForAbstractOrExternalFieldConstructorInitializer(
       AstNode node, FieldElement fieldElement) {
     if (fieldElement.isAbstract) {
       _errorReporter.reportErrorForNode(
           CompileTimeErrorCode.ABSTRACT_FIELD_CONSTRUCTOR_INITIALIZER, node);
     }
+    if (fieldElement.isExternal) {
+      _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER, node);
+    }
   }
 
-  void _checkForAbstractFieldInitializer(VariableDeclaration node) {
+  void _checkForAbstractOrExternalVariableInitializer(
+      VariableDeclaration node) {
     var declaredElement = node.declaredElement;
-    if (declaredElement is FieldElement &&
-        declaredElement.isAbstract &&
-        node.initializer != null) {
-      _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.ABSTRACT_FIELD_INITIALIZER, node.name);
+    if (node.initializer != null) {
+      if (declaredElement is FieldElement) {
+        if (declaredElement.isAbstract) {
+          _errorReporter.reportErrorForNode(
+              CompileTimeErrorCode.ABSTRACT_FIELD_INITIALIZER, node.name);
+        }
+        if (declaredElement.isExternal) {
+          _errorReporter.reportErrorForNode(
+              CompileTimeErrorCode.EXTERNAL_FIELD_INITIALIZER, node.name);
+        }
+      } else if (declaredElement is TopLevelVariableElement) {
+        if (declaredElement.isExternal) {
+          _errorReporter.reportErrorForNode(
+              CompileTimeErrorCode.EXTERNAL_VARIABLE_INITIALIZER, node.name);
+        }
+      }
     }
   }
 
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index f7c6b21..ce3f18b 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -7028,11 +7028,22 @@
     return _variantField_33 ??= <String>[];
   }
 
+  @override
+  List<String> get compilationUnit_featureSetStrings {
+    assert(kind == idl.LinkedNodeKind.compilationUnit);
+    return _variantField_33 ??= <String>[];
+  }
+
   set comment_tokens(List<String> value) {
     assert(kind == idl.LinkedNodeKind.comment);
     _variantField_33 = value;
   }
 
+  set compilationUnit_featureSetStrings(List<String> value) {
+    assert(kind == idl.LinkedNodeKind.compilationUnit);
+    _variantField_33 = value;
+  }
+
   @override
   idl.LinkedNodeCommentType get comment_type {
     assert(kind == idl.LinkedNodeKind.comment);
@@ -7749,12 +7760,14 @@
   LinkedNodeBuilder.compilationUnit({
     List<LinkedNodeBuilder> compilationUnit_declarations,
     LinkedNodeBuilder compilationUnit_scriptTag,
+    List<String> compilationUnit_featureSetStrings,
     List<LinkedNodeBuilder> compilationUnit_directives,
     LinkedLibraryLanguageVersionBuilder compilationUnit_languageVersion,
     int informativeId,
   })  : _kind = idl.LinkedNodeKind.compilationUnit,
         _variantField_2 = compilationUnit_declarations,
         _variantField_6 = compilationUnit_scriptTag,
+        _variantField_33 = compilationUnit_featureSetStrings,
         _variantField_3 = compilationUnit_directives,
         _variantField_40 = compilationUnit_languageVersion,
         _variantField_36 = informativeId;
@@ -9378,6 +9391,14 @@
       signature.addBool(this.compilationUnit_scriptTag != null);
       this.compilationUnit_scriptTag?.collectApiSignature(signature);
       signature.addInt(this.flags ?? 0);
+      if (this.compilationUnit_featureSetStrings == null) {
+        signature.addInt(0);
+      } else {
+        signature.addInt(this.compilationUnit_featureSetStrings.length);
+        for (var x in this.compilationUnit_featureSetStrings) {
+          signature.addString(x);
+        }
+      }
       signature.addString(this.name ?? '');
       signature.addBool(this.compilationUnit_languageVersion != null);
       this.compilationUnit_languageVersion?.collectApiSignature(signature);
@@ -12866,6 +12887,14 @@
   }
 
   @override
+  List<String> get compilationUnit_featureSetStrings {
+    assert(kind == idl.LinkedNodeKind.compilationUnit);
+    _variantField_33 ??= const fb.ListReader<String>(fb.StringReader())
+        .vTableGet(_bc, _bcOffset, 33, const <String>[]);
+    return _variantField_33;
+  }
+
+  @override
   idl.LinkedNodeCommentType get comment_type {
     assert(kind == idl.LinkedNodeKind.comment);
     _variantField_29 ??= const _LinkedNodeCommentTypeReader()
@@ -13511,6 +13540,10 @@
         _result["compilationUnit_scriptTag"] =
             compilationUnit_scriptTag.toJson();
       }
+      if (compilationUnit_featureSetStrings.isNotEmpty) {
+        _result["compilationUnit_featureSetStrings"] =
+            compilationUnit_featureSetStrings;
+      }
       if (compilationUnit_directives.isNotEmpty) {
         _result["compilationUnit_directives"] = compilationUnit_directives
             .map((_value) => _value.toJson())
@@ -15050,6 +15083,7 @@
       return {
         "compilationUnit_declarations": compilationUnit_declarations,
         "compilationUnit_scriptTag": compilationUnit_scriptTag,
+        "compilationUnit_featureSetStrings": compilationUnit_featureSetStrings,
         "compilationUnit_directives": compilationUnit_directives,
         "compilationUnit_languageVersion": compilationUnit_languageVersion,
         "flags": flags,
@@ -17469,20 +17503,12 @@
 class LinkedNodeUnitBuilder extends Object
     with _LinkedNodeUnitMixin
     implements idl.LinkedNodeUnit {
-  bool _isNNBD;
   bool _isSynthetic;
   LinkedNodeBuilder _node;
   String _partUriStr;
   String _uriStr;
 
   @override
-  bool get isNNBD => _isNNBD ??= false;
-
-  set isNNBD(bool value) {
-    this._isNNBD = value;
-  }
-
-  @override
   bool get isSynthetic => _isSynthetic ??= false;
 
   set isSynthetic(bool value) {
@@ -17514,13 +17540,11 @@
   }
 
   LinkedNodeUnitBuilder(
-      {bool isNNBD,
-      bool isSynthetic,
+      {bool isSynthetic,
       LinkedNodeBuilder node,
       String partUriStr,
       String uriStr})
-      : _isNNBD = isNNBD,
-        _isSynthetic = isSynthetic,
+      : _isSynthetic = isSynthetic,
         _node = node,
         _partUriStr = partUriStr,
         _uriStr = uriStr;
@@ -17536,7 +17560,6 @@
     signature.addBool(this._node != null);
     this._node?.collectApiSignature(signature);
     signature.addBool(this._isSynthetic == true);
-    signature.addBool(this._isNNBD == true);
     signature.addString(this._partUriStr ?? '');
   }
 
@@ -17554,9 +17577,6 @@
       offset_uriStr = fbBuilder.writeString(_uriStr);
     }
     fbBuilder.startTable();
-    if (_isNNBD == true) {
-      fbBuilder.addBool(3, true);
-    }
     if (_isSynthetic == true) {
       fbBuilder.addBool(2, true);
     }
@@ -17564,7 +17584,7 @@
       fbBuilder.addOffset(1, offset_node);
     }
     if (offset_partUriStr != null) {
-      fbBuilder.addOffset(4, offset_partUriStr);
+      fbBuilder.addOffset(3, offset_partUriStr);
     }
     if (offset_uriStr != null) {
       fbBuilder.addOffset(0, offset_uriStr);
@@ -17589,19 +17609,12 @@
 
   _LinkedNodeUnitImpl(this._bc, this._bcOffset);
 
-  bool _isNNBD;
   bool _isSynthetic;
   idl.LinkedNode _node;
   String _partUriStr;
   String _uriStr;
 
   @override
-  bool get isNNBD {
-    _isNNBD ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 3, false);
-    return _isNNBD;
-  }
-
-  @override
   bool get isSynthetic {
     _isSynthetic ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 2, false);
     return _isSynthetic;
@@ -17615,7 +17628,7 @@
 
   @override
   String get partUriStr {
-    _partUriStr ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 4, '');
+    _partUriStr ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 3, '');
     return _partUriStr;
   }
 
@@ -17630,9 +17643,6 @@
   @override
   Map<String, Object> toJson() {
     Map<String, Object> _result = <String, Object>{};
-    if (isNNBD != false) {
-      _result["isNNBD"] = isNNBD;
-    }
     if (isSynthetic != false) {
       _result["isSynthetic"] = isSynthetic;
     }
@@ -17650,7 +17660,6 @@
 
   @override
   Map<String, Object> toMap() => {
-        "isNNBD": isNNBD,
         "isSynthetic": isSynthetic,
         "node": node,
         "partUriStr": partUriStr,
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index 211f5fb..5190610 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -1247,15 +1247,13 @@
 
 /// Information about a single library in a [LinkedNodeLibrary].
 table LinkedNodeUnit {
-  isNNBD:bool (id: 3);
-
   isSynthetic:bool (id: 2);
 
   node:LinkedNode (id: 1);
 
   /// If the unit is a part, the URI specified in the `part` directive.
   /// Otherwise empty.
-  partUriStr:string (id: 4);
+  partUriStr:string (id: 3);
 
   /// The absolute URI.
   uriStr:string (id: 0);
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index 8f6deea..bd5eac0 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -864,6 +864,9 @@
   @VariantId(3, variant: LinkedNodeKind.compilationUnit)
   List<LinkedNode> get compilationUnit_directives;
 
+  @VariantId(33, variant: LinkedNodeKind.compilationUnit)
+  List<String> get compilationUnit_featureSetStrings;
+
   /// The language version information.
   @VariantId(40, variant: LinkedNodeKind.compilationUnit)
   LinkedLibraryLanguageVersion get compilationUnit_languageVersion;
@@ -1873,9 +1876,6 @@
 
 /// Information about a single library in a [LinkedNodeLibrary].
 abstract class LinkedNodeUnit extends base.SummaryClass {
-  @Id(3)
-  bool get isNNBD;
-
   @Id(2)
   bool get isSynthetic;
 
@@ -1884,7 +1884,7 @@
 
   /// If the unit is a part, the URI specified in the `part` directive.
   /// Otherwise empty.
-  @Id(4)
+  @Id(3)
   String get partUriStr;
 
   /// The absolute URI.
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
index f79f45d..0a1f078 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
@@ -7,6 +7,7 @@
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/ast_factory.dart';
 import 'package:analyzer/src/dart/element/member.dart';
@@ -363,7 +364,9 @@
       directives: _readNodeList(data.compilationUnit_directives),
       declarations: _readNodeList(data.compilationUnit_declarations),
       endToken: null,
-      featureSet: null,
+      featureSet: ExperimentStatus.fromStrings(
+        data.compilationUnit_featureSetStrings,
+      ),
     );
     LazyCompilationUnit(node, data);
     return node;
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
index 7a71a14..8ec9dd4 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
@@ -7,6 +7,7 @@
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/summary/format.dart';
@@ -286,6 +287,8 @@
     var builder = LinkedNodeBuilder.compilationUnit(
       compilationUnit_declarations: _writeNodeList(node.declarations),
       compilationUnit_directives: _writeNodeList(node.directives),
+      compilationUnit_featureSetStrings:
+          (node.featureSet as ExperimentStatus).toStringList(),
       compilationUnit_languageVersion: LinkedLibraryLanguageVersionBuilder(
         package: LinkedLanguageVersionBuilder(
           major: nodeImpl.languageVersion.package.major,
diff --git a/pkg/analyzer/lib/src/summary2/link.dart b/pkg/analyzer/lib/src/summary2/link.dart
index 7f7118e..3f34f0d 100644
--- a/pkg/analyzer/lib/src/summary2/link.dart
+++ b/pkg/analyzer/lib/src/summary2/link.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/analysis/declared_variables.dart';
-import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart' show CompilationUnit;
 import 'package:analyzer/src/context/context.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
@@ -179,7 +178,6 @@
             partUriStr: unitContext.partUriStr,
             uriStr: unitContext.uriStr,
             node: unitLinkedNode,
-            isNNBD: unit.featureSet.isEnabled(Feature.non_nullable),
           ),
         );
       }
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index 527c5de..0058130 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -79,8 +79,8 @@
   /// Return `true` if this unit is a part of a bundle that is being linked.
   bool get isLinking => bundleContext.isLinking;
 
+  /// TODO(scheglov) remove it
   bool get isNNBD {
-    if (data != null) return data.isNNBD;
     return _unit.featureSet.isEnabled(Feature.non_nullable);
   }
 
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index be78fcc..92f288c 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 0.39.17
+version: 0.39.18-dev
 description: This package provides a library that performs static analysis of Dart code.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
 
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index 7a398a2..6f27e07 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -254,6 +254,40 @@
     expect(field.externalKeyword, isNotNull);
   }
 
+  void test_parseField_external_late() {
+    createParser('external late int? i;', featureSet: nonNullable);
+    ClassMember member = parser.parseClassMember('C');
+    expect(member, isNotNull);
+    assertErrors(errors: [
+      expectedError(ParserErrorCode.EXTERNAL_LATE_FIELD, 0, 8),
+    ]);
+    expect(member, isFieldDeclaration);
+    FieldDeclaration field = member;
+    expect(field.externalKeyword, isNotNull);
+  }
+
+  void test_parseField_external_late_final() {
+    createParser('external late final int? i;', featureSet: nonNullable);
+    ClassMember member = parser.parseClassMember('C');
+    expect(member, isNotNull);
+    assertErrors(errors: [
+      expectedError(ParserErrorCode.EXTERNAL_LATE_FIELD, 0, 8),
+    ]);
+    expect(member, isFieldDeclaration);
+    FieldDeclaration field = member;
+    expect(field.externalKeyword, isNotNull);
+  }
+
+  void test_parseField_external_static() {
+    createParser('external static int? i;', featureSet: nonNullable);
+    ClassMember member = parser.parseClassMember('C');
+    expect(member, isNotNull);
+    assertNoErrors();
+    expect(member, isFieldDeclaration);
+    FieldDeclaration field = member;
+    expect(field.externalKeyword, isNotNull);
+  }
+
   void test_parseField_final_late() {
     createParser('final late T f;', featureSet: nonNullable);
     ClassMember member = parser.parseClassMember('C');
@@ -4627,6 +4661,26 @@
     expect(declaration.externalKeyword, isNotNull);
   }
 
+  void test_parseTopLevelVariable_external_late() {
+    var unit = parseCompilationUnit('external late int? i;',
+        featureSet: nonNullable,
+        errors: [
+          expectedError(ParserErrorCode.EXTERNAL_LATE_FIELD, 0, 8),
+        ]);
+    var declaration = unit.declarations[0] as TopLevelVariableDeclaration;
+    expect(declaration.externalKeyword, isNotNull);
+  }
+
+  void test_parseTopLevelVariable_external_late_final() {
+    var unit = parseCompilationUnit('external late final int? i;',
+        featureSet: nonNullable,
+        errors: [
+          expectedError(ParserErrorCode.EXTERNAL_LATE_FIELD, 0, 8),
+        ]);
+    var declaration = unit.declarations[0] as TopLevelVariableDeclaration;
+    expect(declaration.externalKeyword, isNotNull);
+  }
+
   void test_parseTopLevelVariable_final_late() {
     var unit = parseCompilationUnit('final late a;',
         featureSet: nonNullable,
diff --git a/pkg/analyzer/test/src/dart/resolution/library_element_test.dart b/pkg/analyzer/test/src/dart/resolution/library_element_test.dart
index 3df95f6..1b4e874 100644
--- a/pkg/analyzer/test/src/dart/resolution/library_element_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/library_element_test.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:meta/meta.dart';
 import 'package:pub_semver/pub_semver.dart';
@@ -12,111 +13,284 @@
 
 main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(LibraryElementTest);
+    defineReflectiveTests(LibraryElementTest_featureSet);
+    defineReflectiveTests(LibraryElementTest_scope);
   });
 }
 
 @reflectiveTest
-class LibraryElementTest extends PubPackageResolutionTest {
-  test_languageVersion() async {
-    newFile('$testPackageRootPath/.dart_tool/package_config.json', content: '''
-{
-  "configVersion": 2,
-  "packages": [
-    {
-      "name": "test",
-      "rootUri": "../",
-      "packageUri": "lib/",
-      "languageVersion": "2.7"
-    },
-    {
-      "name": "aaa",
-      "rootUri": "${toUriStr('/aaa')}",
-      "packageUri": "lib/"
-    }
-  ]
-}
-''');
+class LibraryElementTest_featureSet extends PubPackageResolutionTest {
+  test_language205() async {
+    writeTestPackageConfig(
+      PackageConfigFileBuilder(),
+      languageVersion: '2.5',
+    );
 
-    newFile('$testPackageLibPath/a.dart', content: r'''
-class A {}
-''');
+    await resolveTestCode('');
 
-    newFile('$testPackageLibPath/b.dart', content: r'''
-// @dart = 2.6
-class A {}
-''');
-
-    newFile('$testPackageLibPath/c.dart', content: r'''
-// @dart = 2.9
-class A {}
-''');
-
-    newFile('$testPackageLibPath/d.dart', content: r'''
-// @dart = 2.99
-class A {}
-''');
-
-    newFile('$testPackageLibPath/e.dart', content: r'''
-// @dart = 3.0
-class A {}
-''');
-
-    newFile('$workspaceRootPath/aaa/lib/a.dart', content: r'''
-class A {}
-''');
-
-    newFile('$workspaceRootPath/aaa/lib/b.dart', content: r'''
-// @dart = 2.99
-class A {}
-''');
-
-    newFile('$workspaceRootPath/aaa/lib/c.dart', content: r'''
-// @dart = 3.0
-class A {}
-''');
-
-    // No override.
-    await _assertLanguageVersion(
-      path: '$testPackageLibPath/a.dart',
-      package: Version.parse('2.7.0'),
+    _assertLanguageVersion(
+      package: Version.parse('2.5.0'),
       override: null,
     );
 
-    // Valid override, less than the latest supported language version.
-    await _assertLanguageVersion(
-      path: '$testPackageLibPath/b.dart',
-      package: Version.parse('2.7.0'),
-      override: Version.parse('2.6.0'),
+    _assertFeatureSet([
+      Feature.constant_update_2018,
+      Feature.control_flow_collections,
+      Feature.set_literals,
+      Feature.spread_collections,
+    ]);
+  }
+
+  test_language208() async {
+    writeTestPackageConfig(
+      PackageConfigFileBuilder(),
+      languageVersion: '2.8',
     );
 
+    await resolveTestCode('');
+
+    _assertLanguageVersion(
+      package: Version.parse('2.8.0'),
+      override: null,
+    );
+
+    _assertFeatureSet([
+      Feature.constant_update_2018,
+      Feature.control_flow_collections,
+      Feature.extension_methods,
+      Feature.set_literals,
+      Feature.spread_collections,
+    ]);
+  }
+
+  test_language208_experimentNonNullable() async {
+    writeTestPackageConfig(
+      PackageConfigFileBuilder(),
+      languageVersion: '2.8',
+    );
+
+    writeTestPackageAnalysisOptionsFile(
+      AnalysisOptionsFileConfig(experiments: [
+        EnableString.non_nullable,
+      ]),
+    );
+
+    await resolveTestCode('');
+
+    _assertLanguageVersion(
+      package: Version.parse('2.8.0'),
+      override: null,
+    );
+
+    _assertFeatureSet([
+      Feature.constant_update_2018,
+      Feature.control_flow_collections,
+      Feature.extension_methods,
+      Feature.set_literals,
+      Feature.spread_collections,
+    ]);
+  }
+
+  test_language208_override205() async {
+    writeTestPackageConfig(
+      PackageConfigFileBuilder(),
+      languageVersion: '2.8',
+    );
+
+    await resolveTestCode('// @dart = 2.5');
+
+    // Valid override, less than the latest supported language version.
+    _assertLanguageVersion(
+      package: Version.parse('2.8.0'),
+      override: Version.parse('2.5.0'),
+    );
+
+    _assertFeatureSet([
+      Feature.constant_update_2018,
+      Feature.control_flow_collections,
+      Feature.set_literals,
+      Feature.spread_collections,
+    ]);
+  }
+
+  test_language209() async {
+    writeTestPackageConfig(
+      PackageConfigFileBuilder(),
+      languageVersion: '2.9',
+    );
+
+    await resolveTestCode('');
+
+    _assertLanguageVersion(
+      package: Version.parse('2.9.0'),
+      override: null,
+    );
+
+    _assertFeatureSet([
+      Feature.constant_update_2018,
+      Feature.control_flow_collections,
+      Feature.extension_methods,
+      Feature.set_literals,
+      Feature.spread_collections,
+    ]);
+  }
+
+  test_language209_experimentNonNullable_override210() async {
+    writeTestPackageConfig(
+      PackageConfigFileBuilder(),
+      languageVersion: '2.9',
+    );
+
+    writeTestPackageAnalysisOptionsFile(
+      AnalysisOptionsFileConfig(experiments: [
+        EnableString.non_nullable,
+      ]),
+    );
+
+    await resolveTestCode('// @dart = 2.10');
+
     // Valid override, even if greater than the package language version.
-    await _assertLanguageVersion(
-      path: '$testPackageLibPath/c.dart',
-      package: Version.parse('2.7.0'),
+    _assertLanguageVersion(
+      package: Version.parse('2.9.0'),
+      override: Version.parse('2.10.0'),
+    );
+
+    _assertFeatureSet([
+      Feature.constant_update_2018,
+      Feature.control_flow_collections,
+      Feature.extension_methods,
+      Feature.non_nullable,
+      Feature.set_literals,
+      Feature.spread_collections,
+    ]);
+  }
+
+  test_language209_override299() async {
+    writeTestPackageConfig(
+      PackageConfigFileBuilder(),
+      languageVersion: '2.9',
+    );
+
+    await resolveTestCode('// @dart = 2.99');
+
+    // Invalid override: minor is greater than the latest minor.
+    _assertLanguageVersion(
+      package: Version.parse('2.9.0'),
+      override: null,
+    );
+
+    _assertFeatureSet([
+      Feature.constant_update_2018,
+      Feature.control_flow_collections,
+      Feature.extension_methods,
+      Feature.set_literals,
+      Feature.spread_collections,
+    ]);
+  }
+
+  test_language209_override300() async {
+    writeTestPackageConfig(
+      PackageConfigFileBuilder(),
+      languageVersion: '2.9',
+    );
+
+    await resolveTestCode('// @dart = 3.00');
+
+    // Invalid override: major is greater than the latest major.
+    _assertLanguageVersion(
+      package: Version.parse('2.9.0'),
+      override: null,
+    );
+
+    _assertFeatureSet([
+      Feature.constant_update_2018,
+      Feature.control_flow_collections,
+      Feature.extension_methods,
+      Feature.set_literals,
+      Feature.spread_collections,
+    ]);
+  }
+
+  test_language210_experimentNonNullable() async {
+    writeTestPackageConfig(
+      PackageConfigFileBuilder(),
+      languageVersion: '2.10',
+    );
+
+    writeTestPackageAnalysisOptionsFile(
+      AnalysisOptionsFileConfig(experiments: [
+        EnableString.non_nullable,
+      ]),
+    );
+
+    await resolveTestCode('');
+
+    _assertLanguageVersion(
+      package: Version.parse('2.10.0'),
+      override: null,
+    );
+
+    _assertFeatureSet([
+      Feature.constant_update_2018,
+      Feature.control_flow_collections,
+      Feature.extension_methods,
+      Feature.non_nullable,
+      Feature.set_literals,
+      Feature.spread_collections,
+    ]);
+  }
+
+  test_language210_experimentNonNullable_override209() async {
+    writeTestPackageConfig(
+      PackageConfigFileBuilder(),
+      languageVersion: '2.10',
+    );
+
+    writeTestPackageAnalysisOptionsFile(
+      AnalysisOptionsFileConfig(experiments: [
+        EnableString.non_nullable,
+      ]),
+    );
+
+    await resolveTestCode('// @dart = 2.9');
+
+    _assertLanguageVersion(
+      package: Version.parse('2.10.0'),
       override: Version.parse('2.9.0'),
     );
 
-    // Invalid override: minor is greater than the latest minor.
-    await _assertLanguageVersion(
-      path: '$testPackageLibPath/d.dart',
-      package: Version.parse('2.7.0'),
-      override: null,
-    );
-
-    // Invalid override: major is greater than the latest major.
-    await _assertLanguageVersion(
-      path: '$testPackageLibPath/e.dart',
-      package: Version.parse('2.7.0'),
-      override: null,
-    );
-
-    await _assertLanguageVersionCurrent('$workspaceRootPath/aaa/lib/a.dart');
-    await _assertLanguageVersionCurrent('$workspaceRootPath/aaa/lib/b.dart');
-    await _assertLanguageVersionCurrent('$workspaceRootPath/aaa/lib/c.dart');
+    _assertFeatureSet([
+      Feature.constant_update_2018,
+      Feature.control_flow_collections,
+      Feature.extension_methods,
+      Feature.set_literals,
+      Feature.spread_collections,
+    ]);
   }
 
-  test_scope_lookup2() async {
+  void _assertFeatureSet(List<Feature> expected) {
+    var featureSet = result.libraryElement.featureSet;
+
+    var actual = ExperimentStatus.knownFeatures.values
+        .where(featureSet.isEnabled)
+        .toSet();
+
+    expect(actual, unorderedEquals(expected));
+  }
+
+  void _assertLanguageVersion({
+    @required Version package,
+    @required Version override,
+  }) async {
+    var element = result.libraryElement;
+    expect(element.languageVersion.package, package);
+    expect(element.languageVersion.override, override);
+  }
+}
+
+@reflectiveTest
+class LibraryElementTest_scope extends PubPackageResolutionTest {
+  test_lookup2() async {
     await assertNoErrorsInCode(r'''
 int foo;
 ''');
@@ -133,7 +307,7 @@
     );
   }
 
-  test_scope_lookup2_implicitCoreImport() async {
+  test_lookup2_implicitCoreImport() async {
     await assertNoErrorsInCode('');
 
     var scope = result.libraryElement.scope;
@@ -144,7 +318,7 @@
     );
   }
 
-  test_scope_lookup2_notFound() async {
+  test_lookup2_notFound() async {
     await assertNoErrorsInCode('');
 
     var scope = result.libraryElement.scope;
@@ -158,7 +332,7 @@
     );
   }
 
-  test_scope_lookup2_prefersLocal() async {
+  test_lookup2_prefersLocal() async {
     await assertNoErrorsInCode(r'''
 // ignore:unused_import
 import 'dart:math';
@@ -179,7 +353,7 @@
     );
   }
 
-  test_scope_lookup2_prefix() async {
+  test_lookup2_prefix() async {
     await assertNoErrorsInCode(r'''
 // ignore:unused_import
 import 'dart:math' as math;
@@ -193,7 +367,7 @@
     );
   }
 
-  test_scope_lookup2_respectsCombinator_hide() async {
+  test_lookup2_respectsCombinator_hide() async {
     await assertNoErrorsInCode(r'''
 // ignore:unused_import
 import 'dart:math' hide sin;
@@ -216,7 +390,7 @@
     );
   }
 
-  test_scope_lookup2_respectsCombinator_show() async {
+  test_lookup2_respectsCombinator_show() async {
     await assertNoErrorsInCode(r'''
 // ignore:unused_import
 import 'dart:math' show sin;
@@ -234,7 +408,7 @@
     );
   }
 
-  test_scope_lookup_implicitCoreImport() async {
+  test_lookup_implicitCoreImport() async {
     await assertNoErrorsInCode('');
 
     var scope = result.libraryElement.scope;
@@ -246,7 +420,7 @@
     );
   }
 
-  test_scope_lookup_lookup() async {
+  test_lookup_lookup() async {
     await assertNoErrorsInCode(r'''
 int foo;
 ''');
@@ -265,7 +439,7 @@
     );
   }
 
-  test_scope_lookup_notFound() async {
+  test_lookup_notFound() async {
     await assertNoErrorsInCode('');
 
     var scope = result.libraryElement.scope;
@@ -281,7 +455,7 @@
     );
   }
 
-  test_scope_lookup_prefersLocal() async {
+  test_lookup_prefersLocal() async {
     await assertNoErrorsInCode(r'''
 // ignore:unused_import
 import 'dart:math';
@@ -304,7 +478,7 @@
     );
   }
 
-  test_scope_lookup_prefix() async {
+  test_lookup_prefix() async {
     await assertNoErrorsInCode(r'''
 // ignore:unused_import
 import 'dart:math' as math;
@@ -319,7 +493,7 @@
     );
   }
 
-  test_scope_lookup_respectsCombinator_hide() async {
+  test_lookup_respectsCombinator_hide() async {
     await assertNoErrorsInCode(r'''
 // ignore:unused_import
 import 'dart:math' hide sin;
@@ -345,7 +519,7 @@
     );
   }
 
-  test_scope_lookup_respectsCombinator_show() async {
+  test_lookup_respectsCombinator_show() async {
     await assertNoErrorsInCode(r'''
 // ignore:unused_import
 import 'dart:math' show sin;
@@ -364,25 +538,4 @@
       scope.lookup(id: 'cos', setter: false),
     );
   }
-
-  Future<void> _assertLanguageVersion({
-    @required String path,
-    @required Version package,
-    @required Version override,
-  }) async {
-    path = convertPath(path);
-    var session = contextFor(path).currentSession;
-    var file = session.getFile(path);
-    var element = await session.getLibraryByUri('${file.uri}');
-    expect(element.languageVersion.package, package);
-    expect(element.languageVersion.override, override);
-  }
-
-  Future<void> _assertLanguageVersionCurrent(String path) async {
-    await _assertLanguageVersion(
-      path: path,
-      package: ExperimentStatus.currentVersion,
-      override: null,
-    );
-  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/external_field_constructor_initializer_test.dart b/pkg/analyzer/test/src/diagnostics/external_field_constructor_initializer_test.dart
new file mode 100644
index 0000000..f4939b0
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/external_field_constructor_initializer_test.dart
@@ -0,0 +1,80 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ExternalFieldConstructorInitializerTest);
+  });
+}
+
+@reflectiveTest
+class ExternalFieldConstructorInitializerTest extends PubPackageResolutionTest
+    with WithNullSafetyMixin {
+  test_external_field_constructor_initializer() async {
+    await assertErrorsInCode('''
+class A {
+  external int x;
+  A() : x = 0;
+}
+''', [
+      error(CompileTimeErrorCode.EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER, 36, 1),
+    ]);
+  }
+
+  test_external_field_final_constructor_initializer() async {
+    await assertErrorsInCode('''
+class A {
+  external final int x;
+  A() : x = 0;
+}
+''', [
+      error(CompileTimeErrorCode.EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER, 42, 1),
+    ]);
+  }
+
+  test_external_field_final_initializing_formal() async {
+    await assertErrorsInCode('''
+class A {
+  external final int x;
+  A(this.x);
+}
+''', [
+      error(CompileTimeErrorCode.EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER, 43, 1),
+    ]);
+  }
+
+  test_external_field_final_no_initialization() async {
+    await assertNoErrorsInCode('''
+class A {
+  external final int x;
+  A();
+}
+''');
+  }
+
+  test_external_field_initializing_formal() async {
+    await assertErrorsInCode('''
+class A {
+  external int x;
+  A(this.x);
+}
+''', [
+      error(CompileTimeErrorCode.EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER, 37, 1),
+    ]);
+  }
+
+  test_external_field_no_initialization() async {
+    await assertNoErrorsInCode('''
+class A {
+  external int x;
+  A();
+}
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/external_field_initializer_test.dart b/pkg/analyzer/test/src/diagnostics/external_field_initializer_test.dart
new file mode 100644
index 0000000..caa8ed8
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/external_field_initializer_test.dart
@@ -0,0 +1,90 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ExternalFieldInitializerTest);
+  });
+}
+
+@reflectiveTest
+class ExternalFieldInitializerTest extends PubPackageResolutionTest
+    with WithNullSafetyMixin {
+  test_external_field_final_initializer() async {
+    await assertErrorsInCode('''
+class A {
+  external final int x = 0;
+}
+''', [
+      error(CompileTimeErrorCode.EXTERNAL_FIELD_INITIALIZER, 31, 1),
+    ]);
+  }
+
+  test_external_field_final_no_initializer() async {
+    await assertNoErrorsInCode('''
+class A {
+  external final int x;
+}
+''');
+  }
+
+  test_external_field_initializer() async {
+    await assertErrorsInCode('''
+class A {
+  external int x = 0;
+}
+''', [
+      error(CompileTimeErrorCode.EXTERNAL_FIELD_INITIALIZER, 25, 1),
+    ]);
+  }
+
+  test_external_field_no_initializer() async {
+    await assertNoErrorsInCode('''
+class A {
+  external int x;
+}
+''');
+  }
+
+  test_external_static_field_final_initializer() async {
+    await assertErrorsInCode('''
+class A {
+  external static final int x = 0;
+}
+''', [
+      error(CompileTimeErrorCode.EXTERNAL_FIELD_INITIALIZER, 38, 1),
+    ]);
+  }
+
+  test_external_static_field_final_no_initializer() async {
+    await assertNoErrorsInCode('''
+class A {
+  external static final int x;
+}
+''');
+  }
+
+  test_external_static_field_initializer() async {
+    await assertErrorsInCode('''
+class A {
+  external static int x = 0;
+}
+''', [
+      error(CompileTimeErrorCode.EXTERNAL_FIELD_INITIALIZER, 32, 1),
+    ]);
+  }
+
+  test_external_static_field_no_initializer() async {
+    await assertNoErrorsInCode('''
+class A {
+  external static int x;
+}
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/external_variable_initializer_test.dart b/pkg/analyzer/test/src/diagnostics/external_variable_initializer_test.dart
new file mode 100644
index 0000000..54345c8
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/external_variable_initializer_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ExternalVariableInitializerTest);
+  });
+}
+
+@reflectiveTest
+class ExternalVariableInitializerTest extends PubPackageResolutionTest
+    with WithNullSafetyMixin {
+  test_external_variable_final_initializer() async {
+    await assertErrorsInCode('''
+external final int x = 0;
+''', [
+      error(CompileTimeErrorCode.EXTERNAL_VARIABLE_INITIALIZER, 19, 1),
+    ]);
+  }
+
+  test_external_variable_final_no_initializer() async {
+    await assertNoErrorsInCode('''
+external final int x;
+''');
+  }
+
+  test_external_variable_initializer() async {
+    await assertErrorsInCode('''
+external int x = 0;
+''', [
+      error(CompileTimeErrorCode.EXTERNAL_VARIABLE_INITIALIZER, 13, 1),
+    ]);
+  }
+
+  test_external_variable_no_initializer() async {
+    await assertNoErrorsInCode('''
+external int x;
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 5a35fa8..cbaddcb 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -169,6 +169,11 @@
     as extension_override_with_cascade;
 import 'extension_override_without_access_test.dart'
     as extension_override_without_access;
+import 'external_field_constructor_initializer_test.dart'
+    as external_field_constructor_initializer;
+import 'external_field_initializer_test.dart' as external_field_initializer;
+import 'external_variable_initializer_test.dart'
+    as external_variable_initializer;
 import 'extra_annotation_on_struct_field_test.dart'
     as extra_annotation_on_struct_field;
 import 'extra_positional_arguments_test.dart' as extra_positional_arguments;
@@ -745,6 +750,9 @@
     extension_override_argument_not_assignable.main();
     extension_override_with_cascade.main();
     extension_override_without_access.main();
+    external_field_constructor_initializer.main();
+    external_field_initializer.main();
+    external_variable_initializer.main();
     extra_annotation_on_struct_field.main();
     extra_positional_arguments.main();
     field_in_struct_with_initializer.main();
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index affbc2f..04ff108 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -261,7 +261,6 @@
 ExternalFactoryWithBody/script1: Fail
 ExternalFieldConstructorInitializer/analyzerCode: Fail
 ExternalFieldInitializer/analyzerCode: Fail
-ExternalLateField/analyzerCode: Fail
 ExtraneousModifier/part_wrapped_script1: Fail
 ExtraneousModifier/part_wrapped_script10: Fail
 ExtraneousModifier/part_wrapped_script11: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 084b7c1..d41b3ac 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -805,7 +805,9 @@
     - "abstract class C {external var f; C() : this.f = 0;}"
 
 ExternalLateField:
+  index: 109
   template: "External fields cannot be late."
+  analyzerCode: ParserErrorCode.EXTERNAL_LATE_FIELD
   tip: "Try removing the 'external' or 'late' keyword."
   configuration: nnbd-strong
   script:
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index 92bc408..8b3cc81 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -5528,7 +5528,6 @@
 
   DECLARE_INSTRUCTION(LoadIndexed)
   virtual CompileType ComputeType() const;
-  virtual bool RecomputeType();
 
   virtual Representation RequiredInputRepresentation(intptr_t idx) const {
     ASSERT(idx == 0 || idx == 1);
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc
index ba9529b..f3fcd25 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -1701,61 +1701,6 @@
   return CompileType::FromCid(definition_cid_);
 }
 
-static AbstractTypePtr ExtractElementTypeFromArrayType(
-    const AbstractType& array_type) {
-  if (array_type.IsTypeParameter()) {
-    return ExtractElementTypeFromArrayType(
-        AbstractType::Handle(TypeParameter::Cast(array_type).bound()));
-  }
-  if (!array_type.IsType()) {
-    return Object::dynamic_type().raw();
-  }
-  const intptr_t cid = array_type.type_class_id();
-  if (cid == kGrowableObjectArrayCid || cid == kArrayCid ||
-      cid == kImmutableArrayCid ||
-      array_type.type_class() ==
-          Isolate::Current()->object_store()->list_class()) {
-    const auto& type_args = TypeArguments::Handle(array_type.arguments());
-    return type_args.TypeAtNullSafe(Array::kElementTypeTypeArgPos);
-  }
-  return Object::dynamic_type().raw();
-}
-
-static AbstractTypePtr GetElementTypeFromArray(Value* array) {
-  return ExtractElementTypeFromArrayType(*(array->Type()->ToAbstractType()));
-}
-
-static CompileType ComputeArrayElementType(Value* array) {
-  // 1. Try to extract element type from array value.
-  auto& elem_type = AbstractType::Handle(GetElementTypeFromArray(array));
-  if (!elem_type.IsDynamicType()) {
-    return CompileType::FromAbstractType(elem_type);
-  }
-
-  // 2. Array value may be loaded from GrowableObjectArray.data.
-  // Unwrap and try again.
-  if (auto* load_field = array->definition()->AsLoadField()) {
-    if (load_field->slot().IsIdentical(Slot::GrowableObjectArray_data())) {
-      array = load_field->instance();
-      elem_type = GetElementTypeFromArray(array);
-      if (!elem_type.IsDynamicType()) {
-        return CompileType::FromAbstractType(elem_type);
-      }
-    }
-  }
-
-  // 3. If array was loaded from a Dart field, use field's static type.
-  // Unlike propagated type (which could be cid), static type may contain
-  // type arguments which can be used to figure out element type.
-  if (auto* load_field = array->definition()->AsLoadField()) {
-    if (load_field->slot().IsDartField()) {
-      elem_type =
-          ExtractElementTypeFromArrayType(load_field->slot().static_type());
-    }
-  }
-  return CompileType::FromAbstractType(elem_type);
-}
-
 CompileType LoadIndexedInstr::ComputeType() const {
   switch (class_id_) {
     case kArrayCid:
@@ -1764,7 +1709,7 @@
         // The original call knew something.
         return *result_type_;
       }
-      return ComputeArrayElementType(array());
+      return CompileType::Dynamic();
 
     case kTypedDataFloat32ArrayCid:
     case kTypedDataFloat64ArrayCid:
@@ -1806,13 +1751,4 @@
   }
 }
 
-bool LoadIndexedInstr::RecomputeType() {
-  if ((class_id_ == kArrayCid) || (class_id_ == kImmutableArrayCid)) {
-    // Array element type computation depends on computed
-    // types of other instructions and may change over time.
-    return UpdateType(ComputeType());
-  }
-  return false;
-}
-
 }  // namespace dart
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 2be3ae6..cc26637 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -9567,9 +9567,6 @@
 
   bool IsImmutable() const { return raw()->GetClassId() == kImmutableArrayCid; }
 
-  // Position of element type in type arguments.
-  static const intptr_t kElementTypeTypeArgPos = 0;
-
   virtual TypeArgumentsPtr GetTypeArguments() const {
     return raw_ptr()->type_arguments_;
   }
diff --git a/runtime/vm/object_store.cc b/runtime/vm/object_store.cc
index 26a5c3a..9683d81 100644
--- a/runtime/vm/object_store.cc
+++ b/runtime/vm/object_store.cc
@@ -335,15 +335,13 @@
 }
 
 void ObjectStore::LazyInitCoreTypes() {
-  if (list_class_ == Type::null()) {
-    ASSERT(non_nullable_list_rare_type_ == Type::null());
+  if (non_nullable_list_rare_type_ == Type::null()) {
     ASSERT(non_nullable_map_rare_type_ == Type::null());
     Thread* thread = Thread::Current();
     Zone* zone = thread->zone();
     const Library& core_lib = Library::Handle(zone, Library::CoreLibrary());
     Class& cls = Class::Handle(zone, core_lib.LookupClass(Symbols::List()));
     ASSERT(!cls.IsNull());
-    set_list_class(cls);
     Type& type = Type::Handle(zone);
     type ^= cls.RareType();
     set_non_nullable_list_rare_type(type);
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 169161f..7f3c93e 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -82,7 +82,6 @@
   RW(Type, string_type)                                                        \
   RW(Type, legacy_string_type)                                                 \
   RW(Type, non_nullable_string_type)                                           \
-  CW(Class, list_class)                    /* maybe be null, lazily built */   \
   CW(Type, non_nullable_list_rare_type)    /* maybe be null, lazily built */   \
   CW(Type, non_nullable_map_rare_type)     /* maybe be null, lazily built */   \
   FW(Type, non_nullable_future_rare_type)  /* maybe be null, lazily built */   \
diff --git a/tools/VERSION b/tools/VERSION
index cf7150f..10ca838 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 10
 PATCH 0
-PRERELEASE 20
+PRERELEASE 21
 PRERELEASE_PATCH 0
\ No newline at end of file