Version 2.13.0-211.0.dev

Merge commit '16687346977656e362bd607dc4b94053b11e12d9' into 'dev'
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart b/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart
index 0274d64..1402102 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart
@@ -1174,6 +1174,11 @@
   }
 
   @override
+  void handleConstFactory(Token constKeyword) {
+    listener?.handleConstFactory(constKeyword);
+  }
+
+  @override
   void handleContinueStatement(
       bool hasTarget, Token continueKeyword, Token endToken) {
     listener?.handleContinueStatement(hasTarget, continueKeyword, endToken);
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart b/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
index bb635b6..0e08a2e 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
@@ -1360,6 +1360,10 @@
     logEvent("ConstExpression");
   }
 
+  void handleConstFactory(Token constKeyword) {
+    logEvent("ConstFactory");
+  }
+
   /// Called before parsing a "for" control flow list, set, or map entry.
   /// Ended by either [endForControlFlow] or [endForInControlFlow].
   void beginForControlFlow(Token? awaitToken, Token forToken) {}
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
index 1fe9144..93d7a7b 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
@@ -4063,7 +4063,7 @@
     } else {
       if (varFinalOrConst != null && !optional('native', next)) {
         if (optional('const', varFinalOrConst)) {
-          reportRecoverableError(varFinalOrConst, codes.messageConstFactory);
+          listener.handleConstFactory(varFinalOrConst);
         }
       }
       token = parseFunctionBody(
diff --git a/pkg/analysis_server/benchmark/integration/driver.dart b/pkg/analysis_server/benchmark/integration/driver.dart
index 6e831aa..9f40d74 100644
--- a/pkg/analysis_server/benchmark/integration/driver.dart
+++ b/pkg/analysis_server/benchmark/integration/driver.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'dart:async';
 import 'dart:math' show max, sqrt;
 
@@ -42,13 +40,13 @@
   final Logger logger = Logger('Driver');
 
   /// The diagnostic port for Analysis Server or `null` if none.
-  final int diagnosticPort;
+  final int? diagnosticPort;
 
   /// A flag indicating whether the server is running.
   bool running = false;
 
   @override
-  Server server;
+  late Server server;
 
   /// The results collected while running analysis server.
   final Results results = Results();
@@ -65,7 +63,7 @@
   /// Perform the given operation.
   /// Return a [Future] that completes when the next operation can be performed,
   /// or `null` if the next operation can be performed immediately
-  Future perform(Operation op) {
+  Future<void>? perform(Operation op) {
     return op.perform(this);
   }
 
@@ -75,7 +73,7 @@
   /// normal (non-error) response, the future will be completed with the
   /// 'result' field from the response.  If the server acknowledges the command
   /// with an error response, the future will be completed with an error.
-  Future<Map<String, dynamic>> send(
+  Future<Map<String, Object?>?> send(
       String method, Map<String, dynamic> params) {
     return server.send(method, params);
   }
@@ -206,14 +204,17 @@
     print('');
     print('==================================================================');
     print('');
-    var keys = measurements.keys.toList()..sort();
-    var keyLen = keys.fold(0, (int len, String key) => max(len, key.length));
+    var sortedEntries = measurements.entries.toList();
+    sortedEntries.sort((a, b) => a.key.compareTo(b.key));
+    var keyLen = sortedEntries
+        .map((e) => e.key)
+        .fold(0, (int len, String key) => max(len, key.length));
     _printGroupHeader('Request/Response', keyLen);
     var totalCount = 0;
     var totalErrorCount = 0;
     var totalUnexpectedResultCount = 0;
-    for (var tag in keys) {
-      var m = measurements[tag];
+    for (var entry in sortedEntries) {
+      var m = entry.value;
       if (!m.notification) {
         m.printSummary(keyLen);
         totalCount += m.count;
@@ -225,8 +226,8 @@
         keyLen, totalCount, totalErrorCount, totalUnexpectedResultCount);
     print('');
     _printGroupHeader('Notifications', keyLen);
-    for (var tag in keys) {
-      var m = measurements[tag];
+    for (var entry in sortedEntries) {
+      var m = entry.value;
       if (m.notification) {
         m.printSummary(keyLen);
       }
@@ -252,7 +253,7 @@
   }
 
   void recordUnexpectedResults(String tag) {
-    measurements[tag].recordUnexpectedResults();
+    measurements[tag]!.recordUnexpectedResults();
   }
 
   void _printGroupHeader(String groupName, int keyLen) {
diff --git a/pkg/analysis_server/benchmark/integration/input_converter.dart b/pkg/analysis_server/benchmark/integration/input_converter.dart
index e128456..0f86919 100644
--- a/pkg/analysis_server/benchmark/integration/input_converter.dart
+++ b/pkg/analysis_server/benchmark/integration/input_converter.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'dart:async';
 import 'dart:convert';
 import 'dart:io';
@@ -20,14 +18,14 @@
 import 'operation.dart';
 
 /// Common input converter superclass for sharing implementation.
-abstract class CommonInputConverter extends Converter<String, Operation> {
+abstract class CommonInputConverter extends Converter<String, Operation?> {
   static final ERROR_PREFIX = 'Server responded with an error: ';
   final Logger logger = Logger('InstrumentationInputConverter');
   final Set<String> eventsSeen = <String>{};
 
   /// A mapping from request/response id to request json
   /// for those requests for which a response has not been processed.
-  final Map<String, dynamic> requestMap = {};
+  final Map<String, Object?> requestMap = {};
 
   /// A mapping from request/response id to a completer
   /// for those requests for which a response has not been processed.
@@ -37,7 +35,7 @@
 
   /// A mapping from request/response id to the actual response result
   /// for those responses that have not been processed.
-  final Map<String, dynamic> responseMap = {};
+  final Map<String, Object?> responseMap = {};
 
   /// A mapping of current overlay content
   /// parallel to what is in the analysis server
@@ -58,16 +56,18 @@
 
   CommonInputConverter(this.tmpSrcDirPath, this.srcPathMap);
 
-  Map<String, dynamic> asMap(dynamic value) => value as Map<String, dynamic>;
+  Map<String, Object?> asMap(dynamic value) => value as Map<String, Object?>;
+
+  Map<String, Object?>? asMap2(dynamic value) => value as Map<String, Object?>?;
 
   /// Return an operation for the notification or `null` if none.
-  Operation convertNotification(Map<String, dynamic> json) {
+  Operation? convertNotification(Map<String, dynamic> json) {
     String event = json['event'];
     if (event == SERVER_NOTIFICATION_STATUS) {
       // {"event":"server.status","params":{"analysis":{"isAnalyzing":false}}}
-      var params = asMap(json['params']);
+      var params = asMap2(json['params']);
       if (params != null) {
-        var analysis = asMap(params['analysis']);
+        var analysis = asMap2(params['analysis']);
         if (analysis != null && analysis['isAnalyzing'] == false) {
           return WaitForAnalysisCompleteOperation();
         }
@@ -84,23 +84,20 @@
   }
 
   /// Return an operation for the request or `null` if none.
-  Operation convertRequest(Map<String, dynamic> origJson) {
+  Operation convertRequest(Map<String, Object?> origJson) {
     var json = asMap(translateSrcPaths(origJson));
-    requestMap[json['id']] = json;
-    String method = json['method'];
+    requestMap[json['id'] as String] = json;
+    var method = json['method'] as String;
     // Sanity check operations that modify source
     // to ensure that the operation is on source in temp space
     if (method == ANALYSIS_REQUEST_UPDATE_CONTENT) {
       // Track overlays in parallel with the analysis server
       // so that when an overlay is removed, the file can be updated on disk
-      var request = Request.fromJson(json);
+      var request = Request.fromJson(json)!;
       var params = AnalysisUpdateContentParams.fromRequest(request);
       params.files.forEach((String filePath, change) {
         if (change is AddContentOverlay) {
           var content = change.content;
-          if (content == null) {
-            throw 'expected new overlay content\n$json';
-          }
           overlays[filePath] = content;
         } else if (change is ChangeContentOverlay) {
           var content = overlays[filePath];
@@ -172,8 +169,9 @@
   void processErrorResponse(String id, exception) {
     var result = exception;
     if (exception is UnimplementedError) {
-      if (exception.message.startsWith(ERROR_PREFIX)) {
-        result = json.decode(exception.message.substring(ERROR_PREFIX.length));
+      var message = exception.message;
+      if (message!.startsWith(ERROR_PREFIX)) {
+        result = json.decode(message.substring(ERROR_PREFIX.length));
       }
     }
     processResponseResult(id, result);
@@ -186,7 +184,7 @@
   /// Return a future that completes when the response is received
   /// or `null` if the response has already been received
   /// and the completer completed.
-  Future processExpectedResponse(String id, Completer completer) {
+  Future<void>? processExpectedResponse(String id, Completer completer) {
     if (responseMap.containsKey(id)) {
       logger.log(Level.INFO, 'processing cached response $id');
       completer.complete(responseMap.remove(id));
@@ -228,7 +226,7 @@
       return result;
     }
     if (json is Map) {
-      var result = <String, dynamic>{};
+      var result = <String, Object?>{};
       json.forEach((origKey, value) {
         result[translateSrcPaths(origKey)] = translateSrcPaths(value);
       });
@@ -241,7 +239,7 @@
 /// [InputConverter] converts an input stream
 /// into a series of operations to be sent to the analysis server.
 /// The input stream can be either an instrumentation or log file.
-class InputConverter extends Converter<String, Operation> {
+class InputConverter extends Converter<String, Operation?> {
   final Logger logger = Logger('InputConverter');
 
   /// A mapping of source path prefixes
@@ -259,7 +257,7 @@
 
   /// The underlying converter used to translate lines into operations
   /// or `null` if it has not yet been determined.
-  Converter<String, Operation> converter;
+  Converter<String, Operation?>? converter;
 
   /// [active] is `true` if converting lines to operations
   /// or `false` if an exception has occurred.
@@ -268,10 +266,11 @@
   InputConverter(this.tmpSrcDirPath, this.srcPathMap);
 
   @override
-  Operation convert(String line) {
+  Operation? convert(String line) {
     if (!active) {
       return null;
     }
+    var converter = this.converter;
     if (converter != null) {
       try {
         return converter.convert(line);
@@ -335,8 +334,8 @@
 }
 
 class _InputSink extends ChunkedConversionSink<String> {
-  final Converter<String, Operation> converter;
-  final Sink<Operation> outSink;
+  final Converter<String, Operation?> converter;
+  final Sink<Operation?> outSink;
 
   _InputSink(this.converter, this.outSink);
 
diff --git a/pkg/analysis_server/benchmark/integration/instrumentation_input_converter.dart b/pkg/analysis_server/benchmark/integration/instrumentation_input_converter.dart
index 2cd8783..037c9b0 100644
--- a/pkg/analysis_server/benchmark/integration/instrumentation_input_converter.dart
+++ b/pkg/analysis_server/benchmark/integration/instrumentation_input_converter.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'dart:convert';
 
 import 'package:analyzer/exception/exception.dart';
@@ -23,17 +21,18 @@
   /// [readBuffer] holds the contents of the file being read from disk
   /// as recorded in the instrumentation log
   /// or `null` if not converting a "Read" entry.
-  StringBuffer readBuffer;
+  StringBuffer? readBuffer;
 
   InstrumentationInputConverter(String tmpSrcDirPath, PathMap srcPathMap)
       : super(tmpSrcDirPath, srcPathMap);
 
   @override
-  Operation convert(String line) {
+  Operation? convert(String line) {
     List<String> fields;
     try {
       fields = _parseFields(line);
       if (fields.length < 2) {
+        var readBuffer = this.readBuffer;
         if (readBuffer != null) {
           readBuffer.writeln(fields.length == 1 ? fields[0] : '');
           return null;
@@ -78,7 +77,7 @@
     return null;
   }
 
-  Map<String, dynamic> decodeJson(String line, String text) {
+  Map<String, Object?> decodeJson(String line, String text) {
     try {
       return asMap(json.decode(text));
     } catch (e, s) {
diff --git a/pkg/analysis_server/benchmark/integration/local_runner.dart b/pkg/analysis_server/benchmark/integration/local_runner.dart
index e8353b2..f8a987a 100644
--- a/pkg/analysis_server/benchmark/integration/local_runner.dart
+++ b/pkg/analysis_server/benchmark/integration/local_runner.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'dart:io';
 
 import 'package:path/path.dart';
@@ -77,7 +75,7 @@
 }
 
 /// Print help and exit
-void printHelp([String errMsg]) {
+void printHelp([String? errMsg]) {
   if (errMsg != null) {
     print('');
     print('Error: $errMsg');
diff --git a/pkg/analysis_server/benchmark/integration/log_file_input_converter.dart b/pkg/analysis_server/benchmark/integration/log_file_input_converter.dart
index 238a1fa..bd87c70 100644
--- a/pkg/analysis_server/benchmark/integration/log_file_input_converter.dart
+++ b/pkg/analysis_server/benchmark/integration/log_file_input_converter.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'dart:convert';
 
 import 'package:analyzer/exception/exception.dart';
@@ -25,7 +23,7 @@
       : super(tmpSrcDirPath, srcPathMap);
 
   @override
-  Operation convert(String line) {
+  Operation? convert(String line) {
     try {
       var timeStampString = _parseTimeStamp(line);
       var data = line.substring(timeStampString.length);
diff --git a/pkg/analysis_server/benchmark/integration/main.dart b/pkg/analysis_server/benchmark/integration/main.dart
index c1c9911..8f0a438 100644
--- a/pkg/analysis_server/benchmark/integration/main.dart
+++ b/pkg/analysis_server/benchmark/integration/main.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'dart:async';
 import 'dart:convert';
 import 'dart:io';
@@ -26,9 +24,9 @@
 
   var driver = Driver(diagnosticPort: args.diagnosticPort);
   var stream = openInput(args);
-  StreamSubscription<Operation> subscription;
-  subscription = stream.listen((Operation op) {
-    var future = driver.perform(op);
+  late StreamSubscription<Operation?> subscription;
+  subscription = stream.listen((Operation? op) {
+    var future = driver.perform(op!);
     if (future != null) {
       logger.log(Level.FINE, 'pausing operations for ${op.runtimeType}');
       subscription.pause(future.then((_) {
@@ -63,17 +61,15 @@
 const VERBOSE_CMDLINE_OPTION = 'verbose';
 const VERY_VERBOSE_CMDLINE_OPTION = 'vv';
 
-ArgParser _argParser;
+late final ArgParser argParser = () {
+  var argParser = ArgParser();
 
-ArgParser get argParser {
-  _argParser = ArgParser();
-
-  _argParser.addOption(INPUT_CMDLINE_OPTION,
+  argParser.addOption(INPUT_CMDLINE_OPTION,
       abbr: 'i',
       help: '<filePath>\n'
           'The input file specifying how this client should interact with the server.\n'
           'If the input file name is "stdin", then the instructions are read from standard input.');
-  _argParser.addMultiOption(MAP_OPTION,
+  argParser.addMultiOption(MAP_OPTION,
       abbr: 'm',
       splitCommas: false,
       help: '<oldSrcPath>,<newSrcPath>\n'
@@ -82,26 +78,26 @@
           'to the target source directory <newSrcPath> used during performance testing.\n'
           'Multiple mappings can be specified.\n'
           'WARNING: The contents of the target directory will be modified');
-  _argParser.addOption(TMP_SRC_DIR_OPTION,
+  argParser.addOption(TMP_SRC_DIR_OPTION,
       abbr: 't',
       help: '<dirPath>\n'
           'The temporary directory containing source used during performance measurement.\n'
           'WARNING: The contents of the target directory will be modified');
-  _argParser.addOption(DIAGNOSTIC_PORT_OPTION,
+  argParser.addOption(DIAGNOSTIC_PORT_OPTION,
       abbr: 'd',
       help: 'localhost port on which server will provide diagnostic web pages');
-  _argParser.addFlag(VERBOSE_CMDLINE_OPTION,
+  argParser.addFlag(VERBOSE_CMDLINE_OPTION,
       abbr: 'v', help: 'Verbose logging', negatable: false);
-  _argParser.addFlag(VERY_VERBOSE_CMDLINE_OPTION,
+  argParser.addFlag(VERY_VERBOSE_CMDLINE_OPTION,
       help: 'Extra verbose logging', negatable: false);
-  _argParser.addFlag(HELP_CMDLINE_OPTION,
+  argParser.addFlag(HELP_CMDLINE_OPTION,
       abbr: 'h', help: 'Print this help information', negatable: false);
-  return _argParser;
-}
+  return argParser;
+}();
 
 /// Open and return the input stream specifying how this client
 /// should interact with the analysis server.
-Stream<Operation> openInput(PerfArgs args) {
+Stream<Operation?> openInput(PerfArgs args) {
   var logger = Logger('openInput');
   Stream<List<int>> inputRaw;
   if (args.inputPath == 'stdin') {
@@ -137,12 +133,12 @@
 
   var showHelp = args[HELP_CMDLINE_OPTION] || args.rest.isNotEmpty;
 
-  bool isMissing(key) => args[key] == null || args[key].isEmpty;
-
-  perfArgs.inputPath = args[INPUT_CMDLINE_OPTION];
-  if (isMissing(INPUT_CMDLINE_OPTION)) {
+  var inputArg = args[INPUT_CMDLINE_OPTION];
+  if (inputArg is! String || inputArg.isEmpty) {
     print('missing $INPUT_CMDLINE_OPTION argument');
     showHelp = true;
+  } else {
+    perfArgs.inputPath = inputArg;
   }
 
   for (String pair in args[MAP_OPTION]) {
@@ -157,18 +153,20 @@
         }
       }
     }
-    print('must specifiy $MAP_OPTION <oldSrcPath>,<newSrcPath>');
+    print('must specify $MAP_OPTION <oldSrcPath>,<newSrcPath>');
     showHelp = true;
   }
 
-  perfArgs.tmpSrcDirPath = _withTrailingSeparator(args[TMP_SRC_DIR_OPTION]);
-  if (isMissing(TMP_SRC_DIR_OPTION)) {
+  var tmpSrcDirPathArg = args[TMP_SRC_DIR_OPTION];
+  if (tmpSrcDirPathArg is! String || tmpSrcDirPathArg.isEmpty) {
     print('missing $TMP_SRC_DIR_OPTION argument');
     showHelp = true;
+  } else {
+    perfArgs.tmpSrcDirPath = _withTrailingSeparator(tmpSrcDirPathArg);
   }
 
-  String portText = args[DIAGNOSTIC_PORT_OPTION];
-  if (portText != null) {
+  var portText = args[DIAGNOSTIC_PORT_OPTION];
+  if (portText is String) {
     if (int.tryParse(portText) == null) {
       print('invalid $DIAGNOSTIC_PORT_OPTION: $portText');
       showHelp = true;
@@ -202,7 +200,7 @@
 
 /// Ensure that the given path has a trailing separator
 String _withTrailingSeparator(String dirPath) {
-  if (dirPath != null && dirPath.length > 4) {
+  if (dirPath.length > 4) {
     if (!dirPath.endsWith(path.separator)) {
       return '$dirPath${path.separator}';
     }
@@ -215,7 +213,7 @@
   /// The file path of the instrumentation or log file
   /// used to drive performance measurement,
   /// or 'stdin' if this information should be read from standard input.
-  String inputPath;
+  late String inputPath;
 
   /// A mapping from the original source directory
   /// when the instrumentation or log file was generated
@@ -224,8 +222,8 @@
 
   /// The temporary directory containing source used during performance
   /// measurement.
-  String tmpSrcDirPath;
+  late String tmpSrcDirPath;
 
   /// The diagnostic port for Analysis Server or `null` if none.
-  int diagnosticPort;
+  int? diagnosticPort;
 }
diff --git a/pkg/analysis_server/benchmark/integration/operation.dart b/pkg/analysis_server/benchmark/integration/operation.dart
index eb70f44..311e979 100644
--- a/pkg/analysis_server/benchmark/integration/operation.dart
+++ b/pkg/analysis_server/benchmark/integration/operation.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'dart:async';
 
 import 'package:analysis_server/protocol/protocol_generated.dart';
@@ -15,10 +13,10 @@
 /// A [CompletionRequestOperation] tracks response time along with
 /// the first and last completion notifications.
 class CompletionRequestOperation extends RequestOperation {
-  Driver driver;
-  StreamSubscription<CompletionResultsParams> subscription;
-  String notificationId;
-  Stopwatch stopwatch;
+  late Driver driver;
+  late StreamSubscription<CompletionResultsParams> subscription;
+  late String notificationId;
+  late Stopwatch stopwatch;
   bool firstNotification = true;
 
   CompletionRequestOperation(
@@ -26,7 +24,7 @@
       : super(converter, json);
 
   @override
-  Future perform(Driver driver) {
+  Future<void>? perform(Driver driver) {
     this.driver = driver;
     subscription = driver.onCompletionResults.listen(processNotification);
     return super.perform(driver);
@@ -50,8 +48,8 @@
 
   @override
   void processResult(
-      String id, Map<String, dynamic> result, Stopwatch stopwatch) {
-    notificationId = result['id'];
+      String id, Map<String, Object?> result, Stopwatch stopwatch) {
+    notificationId = result['id'] as String;
     this.stopwatch = stopwatch;
     super.processResult(id, result, stopwatch);
   }
@@ -59,7 +57,7 @@
 
 /// An [Operation] represents an action such as sending a request to the server.
 abstract class Operation {
-  Future perform(Driver driver);
+  Future<void>? perform(Driver driver);
 }
 
 /// A [RequestOperation] sends a [JSON] request to the server.
@@ -70,7 +68,7 @@
   RequestOperation(this.converter, this.json);
 
   @override
-  Future perform(Driver driver) {
+  Future<void>? perform(Driver driver) {
     var stopwatch = Stopwatch();
     String originalId = json['id'];
     String method = json['method'];
@@ -85,11 +83,9 @@
           .log(Level.FINE, 'Response received: $method : $elapsed\n  $result');
     }
 
-    driver
-        .send(method, converter.asMap(json['params']))
-        .then((Map<String, dynamic> result) {
+    driver.send(method, converter.asMap(json['params'])).then((result) {
       recordResult(true, result);
-      processResult(originalId, result, stopwatch);
+      processResult(originalId, result!, stopwatch);
     }).catchError((exception) {
       recordResult(false, exception);
       converter.processErrorResponse(originalId, exception);
@@ -98,7 +94,7 @@
   }
 
   void processResult(
-      String id, Map<String, dynamic> result, Stopwatch stopwatch) {
+      String id, Map<String, Object?> result, Stopwatch stopwatch) {
     converter.processResponseResult(id, result);
   }
 }
@@ -107,19 +103,20 @@
 class ResponseOperation extends Operation {
   static final Duration responseTimeout = Duration(seconds: 60);
   final CommonInputConverter converter;
-  final Map<String, dynamic> requestJson;
-  final Map<String, dynamic> responseJson;
+  final Map<String, Object?> requestJson;
+  final Map<String, Object?> responseJson;
   final Completer completer = Completer();
-  Driver driver;
+  late Driver driver;
 
   ResponseOperation(this.converter, this.requestJson, this.responseJson) {
     completer.future.then(_processResult).timeout(responseTimeout);
   }
 
   @override
-  Future perform(Driver driver) {
+  Future<void>? perform(Driver driver) {
     this.driver = driver;
-    return converter.processExpectedResponse(responseJson['id'], completer);
+    var id = responseJson['id'] as String;
+    return converter.processExpectedResponse(id, completer);
   }
 
   bool _equal(expectedResult, actualResult) {
@@ -161,7 +158,8 @@
           'expected result:${format(expectedResult)}\n'
           'expected error:${format(expectedError)}\n'
           'but received:${format(actualResult)}';
-      driver.results.recordUnexpectedResults(requestJson['method']);
+      var method = requestJson['method'] as String;
+      driver.results.recordUnexpectedResults(method);
       converter.logOverlayContent();
       if (expectedError == null) {
         converter.logger.log(Level.SEVERE, message);
@@ -184,13 +182,14 @@
   Future perform(Driver driver) {
     var start = DateTime.now();
     driver.logger.log(Level.FINE, 'waiting for analysis to complete');
-    StreamSubscription<ServerStatusParams> subscription;
-    Timer timer;
+    late StreamSubscription<ServerStatusParams> subscription;
+    late Timer timer;
     var completer = Completer();
     var isAnalyzing = false;
     subscription = driver.onServerStatus.listen((ServerStatusParams params) {
-      if (params.analysis != null) {
-        if (params.analysis.isAnalyzing) {
+      var analysisStatus = params.analysis;
+      if (analysisStatus != null) {
+        if (analysisStatus.isAnalyzing) {
           isAnalyzing = true;
         } else {
           subscription.cancel();
@@ -214,7 +213,7 @@
       }
       // Timeout if no communication received within the last 60 seconds.
       var currentTime = driver.server.currentElapseTime;
-      var lastTime = driver.server.lastCommunicationTime;
+      var lastTime = driver.server.lastCommunicationTime!;
       if (currentTime - lastTime > 60) {
         subscription.cancel();
         timer.cancel();
diff --git a/pkg/analyzer/lib/src/dart/micro/analysis_context.dart b/pkg/analyzer/lib/src/dart/micro/analysis_context.dart
index 97a397f..5e45d1e7 100644
--- a/pkg/analyzer/lib/src/dart/micro/analysis_context.dart
+++ b/pkg/analyzer/lib/src/dart/micro/analysis_context.dart
@@ -204,14 +204,7 @@
 
   @override
   Future<ResolvedLibraryResult> getResolvedLibrary(String path) async {
-    var resolvedUnit = await getResolvedUnit(path);
-    return ResolvedLibraryResultImpl(
-      this,
-      path,
-      resolvedUnit.uri,
-      resolvedUnit.libraryElement,
-      [resolvedUnit],
-    );
+    return analysisContext.fileResolver.resolveLibrary(path: path);
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
index 219aadc..03b5275 100644
--- a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
+++ b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
@@ -86,7 +86,7 @@
   /// It is used to allow assists and fixes without resolving the same file
   /// multiple times, as we compute more than one assist, or fixes when there
   /// are more than one error on a line.
-  final Map<String, ResolvedUnitResult> _cachedResults = {};
+  final Map<String, ResolvedLibraryResult> _cachedResults = {};
 
   FileResolver(
     PerformanceLog logger,
@@ -373,6 +373,48 @@
 
     performance ??= OperationPerformanceImpl('<default>');
 
+    return logger.run('Resolve $path', () {
+      var fileContext = getFileContext(
+        path: path,
+        performance: performance!,
+      );
+      var file = fileContext.file;
+
+      // If we have a `part of` directive, we want to analyze this library.
+      // But the library must include the file, so have its element.
+      var libraryFile = file;
+      var partOfLibrary = file.partOfLibrary;
+      if (partOfLibrary != null) {
+        if (partOfLibrary.libraryFiles.contains(file)) {
+          libraryFile = partOfLibrary;
+        }
+      }
+
+      var libraryUnit = resolveLibrary(
+        completionLine: completionLine,
+        completionColumn: completionColumn,
+        path: libraryFile.path,
+        completionPath: path,
+        performance: performance,
+      );
+      var result =
+          libraryUnit.units!.firstWhere((element) => element.path == path);
+      return result;
+    });
+  }
+
+  /// The [completionLine] and [completionColumn] are zero based.
+  ResolvedLibraryResult resolveLibrary({
+    int? completionLine,
+    int? completionColumn,
+    String? completionPath,
+    required String path,
+    OperationPerformanceImpl? performance,
+  }) {
+    _throwIfNotAbsoluteNormalizedPath(path);
+
+    performance ??= OperationPerformanceImpl('<default>');
+
     var cachedResult = _cachedResults[path];
     if (cachedResult != null) {
       return cachedResult;
@@ -410,10 +452,6 @@
 
       testView?.addResolvedFile(path);
 
-      var content = _getFileContent(path);
-      var errorListener = RecordingErrorListener();
-      var unit = file.parse(errorListener, content);
-
       late Map<FileState, UnitAnalysisResult> results;
 
       logger.run('Compute analysis results', () {
@@ -432,7 +470,7 @@
         try {
           results = performance!.run('analyze', (performance) {
             return libraryAnalyzer.analyzeSync(
-              completionPath: completionOffset != null ? path : null,
+              completionPath: completionOffset != null ? completionPath : null,
               completionOffset: completionOffset,
               performance: performance,
             );
@@ -450,19 +488,28 @@
           );
         }
       });
-      UnitAnalysisResult fileResult = results[file]!;
 
-      var result = ResolvedUnitResultImpl(
-        contextObjects!.analysisSession,
-        path,
-        file.uri,
-        file.exists,
-        content,
-        unit.lineInfo!,
-        false, // isPart
-        fileResult.unit,
-        fileResult.errors,
-      );
+      results.forEach((key, value) {
+        print('$key: $value');
+      });
+      var resolvedUnits = results.values.map((fileResult) {
+        var file = fileResult.file;
+        return ResolvedUnitResultImpl(
+          contextObjects!.analysisSession,
+          file.path,
+          file.uri,
+          file.exists,
+          file.getContent(),
+          file.lineInfo,
+          file.unlinked2.hasPartOfDirective,
+          fileResult.unit,
+          fileResult.errors,
+        );
+      }).toList();
+
+      var libraryUnit = resolvedUnits.first;
+      var result = ResolvedLibraryResultImpl(contextObjects!.analysisSession,
+          path, libraryUnit.uri, libraryUnit.libraryElement, resolvedUnits);
       _cachedResults[path] = result;
       return result;
     });
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index a43c330..0036512 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -11,6 +11,7 @@
         messageAbstractLateField,
         messageAbstractStaticField,
         messageConstConstructorWithBody,
+        messageConstFactory,
         messageConstructorWithTypeParameters,
         messageDirectiveAfterDeclaration,
         messageExpectedStatement,
@@ -2575,6 +2576,13 @@
   }
 
   @override
+  void handleConstFactory(Token constKeyword) {
+    debugEvent("ConstFactory");
+    // TODO(kallentu): Removal of const factory error for const function feature
+    handleRecoverableError(messageConstFactory, constKeyword, constKeyword);
+  }
+
+  @override
   void handleContinueStatement(
       bool hasTarget, Token continueKeyword, Token semicolon) {
     assert(optional('continue', continueKeyword));
diff --git a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
index 15b8ebd..aa6dfb3 100644
--- a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
+++ b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
@@ -679,6 +679,30 @@
     expect(result, isNot(same(result1)));
   }
 
+  test_resolveLibrary() async {
+    var aPath = convertPath('/workspace/dart/test/lib/a.dart');
+    newFile(aPath, content: r'''
+part 'test.dart';
+
+class A {
+  int m;
+}
+''');
+
+    newFile('/workspace/dart/test/lib/test.dart', content: r'''
+part of 'a.dart';
+
+void func() {
+  var a = A();
+  print(a.m);
+}
+''');
+
+    var result = fileResolver.resolveLibrary(path: aPath);
+    expect(result.path, aPath);
+    expect(result.units?.length, 2);
+  }
+
   test_reuse_compatibleOptions() async {
     newFile('/workspace/dart/aaa/BUILD', content: '');
     newFile('/workspace/dart/bbb/BUILD', content: '');
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 ccf323b..11692c2 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -4769,6 +4769,15 @@
   }
 
   @override
+  void handleConstFactory(Token constKeyword) {
+    debugEvent("ConstFactory");
+    if (!libraryBuilder.enableConstFunctionsInLibrary) {
+      handleRecoverableError(
+          fasta.messageConstFactory, constKeyword, constKeyword);
+    }
+  }
+
+  @override
   void beginIfControlFlow(Token ifToken) {
     // TODO(danrubel): consider removing this when control flow support is added
     // if the ifToken is not needed for error reporting
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 645bbd9..5178dfa 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -2783,6 +2783,11 @@
       } else {
         name = '${target.enclosingClass.name}.${name}';
       }
+
+      if (enableConstFunctions) {
+        return _handleFunctionInvocation(
+            node.target.function, typeArguments, positionals, named);
+      }
     }
     return createInvalidExpressionConstant(node, "Invocation of $name");
   }
diff --git a/pkg/front_end/lib/src/fasta/source/diet_listener.dart b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
index 3d05b76..c5664f8 100644
--- a/pkg/front_end/lib/src/fasta/source/diet_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
@@ -633,6 +633,11 @@
   }
 
   @override
+  void handleConstFactory(Token constKeyword) {
+    debugEvent("ConstFactory");
+  }
+
+  @override
   void handleNativeFunctionBody(Token nativeToken, Token semicolon) {
     debugEvent("NativeFunctionBody");
   }
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 96b6ff5..6e7b86a 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -2045,6 +2045,14 @@
   }
 
   @override
+  void handleConstFactory(Token constKeyword) {
+    debugEvent("ConstFactory");
+    if (!libraryBuilder.enableConstFunctionsInLibrary) {
+      handleRecoverableError(messageConstFactory, constKeyword, constKeyword);
+    }
+  }
+
+  @override
   void endFieldInitializer(Token assignmentOperator, Token token) {
     debugEvent("FieldInitializer");
     Token beforeLast = assignmentOperator.next;
diff --git a/pkg/front_end/lib/src/fasta/util/direct_parser_ast_helper.dart b/pkg/front_end/lib/src/fasta/util/direct_parser_ast_helper.dart
index cc76576..fe06b76 100644
--- a/pkg/front_end/lib/src/fasta/util/direct_parser_ast_helper.dart
+++ b/pkg/front_end/lib/src/fasta/util/direct_parser_ast_helper.dart
@@ -1970,6 +1970,13 @@
     seen(data);
   }
 
+  void handleConstFactory(Token constKeyword) {
+    DirectParserASTContentConstFactoryHandle data =
+        new DirectParserASTContentConstFactoryHandle(DirectParserASTType.HANDLE,
+            constKeyword: constKeyword);
+    seen(data);
+  }
+
   void beginForControlFlow(Token awaitToken, Token forToken) {
     DirectParserASTContentForControlFlowBegin data =
         new DirectParserASTContentForControlFlowBegin(DirectParserASTType.BEGIN,
@@ -5814,6 +5821,18 @@
       };
 }
 
+class DirectParserASTContentConstFactoryHandle extends DirectParserASTContent {
+  final Token constKeyword;
+
+  DirectParserASTContentConstFactoryHandle(DirectParserASTType type,
+      {this.constKeyword})
+      : super("ConstFactory", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "constKeyword": constKeyword,
+      };
+}
+
 class DirectParserASTContentForControlFlowBegin extends DirectParserASTContent {
   final Token awaitToken;
   final Token forToken;
diff --git a/pkg/front_end/test/parser_test_listener.dart b/pkg/front_end/test/parser_test_listener.dart
index fca16c8..8ffa24f 100644
--- a/pkg/front_end/test/parser_test_listener.dart
+++ b/pkg/front_end/test/parser_test_listener.dart
@@ -1765,6 +1765,11 @@
     doPrint('endConstExpression(' '$token)');
   }
 
+  void handleConstFactory(Token constKeyword) {
+    seen(constKeyword);
+    doPrint('handleConstFactory(' '$constKeyword)');
+  }
+
   void beginForControlFlow(Token? awaitToken, Token forToken) {
     seen(awaitToken);
     seen(forToken);
diff --git a/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart b/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart
new file mode 100644
index 0000000..08f2b76
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2021, 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.
+
+// Tests const factories with const functions.
+
+import "package:expect/expect.dart";
+
+const printConst = MessageType.parse("print");
+
+class MessageType {
+  static const print = MessageType._('print');
+
+  static const skip = MessageType._('skip');
+
+  final String name;
+
+  const factory MessageType.parse(String name) {
+    if (name == 'print') {
+      return MessageType.print;
+    }
+    return MessageType.skip;
+  }
+
+  const MessageType._(this.name);
+}
+
+void main() {
+  Expect.equals(printConst, MessageType.print);
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.strong.expect b/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.strong.expect
new file mode 100644
index 0000000..c9674e9
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.strong.expect
@@ -0,0 +1,38 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+class MessageType extends core::Object /*hasConstConstructor*/  {
+  static const field self::MessageType print = #C2;
+  static const field self::MessageType skip = #C4;
+  final field core::String name;
+  const constructor _(core::String name) → self::MessageType
+    : self::MessageType::name = name, super core::Object::•()
+    ;
+  static factory parse(core::String name) → self::MessageType {
+    if(name.{core::String::==}("print")) {
+      return #C2;
+    }
+    return #C4;
+  }
+}
+static const field self::MessageType printConst = #C2;
+static method main() → void {
+  exp::Expect::equals(#C2, #C2);
+}
+
+constants  {
+  #C1 = "print"
+  #C2 = self::MessageType {name:#C1}
+  #C3 = "skip"
+  #C4 = self::MessageType {name:#C3}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///const_functions_const_factory.dart:
+- MessageType._ (from org-dartlang-testcase:///const_functions_const_factory.dart:25:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.strong.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.strong.transformed.expect
new file mode 100644
index 0000000..c9674e9
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.strong.transformed.expect
@@ -0,0 +1,38 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+class MessageType extends core::Object /*hasConstConstructor*/  {
+  static const field self::MessageType print = #C2;
+  static const field self::MessageType skip = #C4;
+  final field core::String name;
+  const constructor _(core::String name) → self::MessageType
+    : self::MessageType::name = name, super core::Object::•()
+    ;
+  static factory parse(core::String name) → self::MessageType {
+    if(name.{core::String::==}("print")) {
+      return #C2;
+    }
+    return #C4;
+  }
+}
+static const field self::MessageType printConst = #C2;
+static method main() → void {
+  exp::Expect::equals(#C2, #C2);
+}
+
+constants  {
+  #C1 = "print"
+  #C2 = self::MessageType {name:#C1}
+  #C3 = "skip"
+  #C4 = self::MessageType {name:#C3}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///const_functions_const_factory.dart:
+- MessageType._ (from org-dartlang-testcase:///const_functions_const_factory.dart:25:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.textual_outline.expect b/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.textual_outline.expect
new file mode 100644
index 0000000..5caeeca
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+import "package:expect/expect.dart";
+const printConst = MessageType.parse("print");
+class MessageType {
+  static const print = MessageType._('print');
+  static const skip = MessageType._('skip');
+  final String name;
+  const factory MessageType.parse(String name) {}
+  const MessageType._(this.name);
+}
+void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cb1859d
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+import "package:expect/expect.dart";
+
+class MessageType {
+  const MessageType._(this.name);
+  const factory MessageType.parse(String name) {}
+  final String name;
+  static const print = MessageType._('print');
+  static const skip = MessageType._('skip');
+}
+
+const printConst = MessageType.parse("print");
+void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.weak.expect b/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.weak.expect
new file mode 100644
index 0000000..c9674e9
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.weak.expect
@@ -0,0 +1,38 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+class MessageType extends core::Object /*hasConstConstructor*/  {
+  static const field self::MessageType print = #C2;
+  static const field self::MessageType skip = #C4;
+  final field core::String name;
+  const constructor _(core::String name) → self::MessageType
+    : self::MessageType::name = name, super core::Object::•()
+    ;
+  static factory parse(core::String name) → self::MessageType {
+    if(name.{core::String::==}("print")) {
+      return #C2;
+    }
+    return #C4;
+  }
+}
+static const field self::MessageType printConst = #C2;
+static method main() → void {
+  exp::Expect::equals(#C2, #C2);
+}
+
+constants  {
+  #C1 = "print"
+  #C2 = self::MessageType {name:#C1}
+  #C3 = "skip"
+  #C4 = self::MessageType {name:#C3}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///const_functions_const_factory.dart:
+- MessageType._ (from org-dartlang-testcase:///const_functions_const_factory.dart:25:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.weak.outline.expect b/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.weak.outline.expect
new file mode 100644
index 0000000..fe4b863
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.weak.outline.expect
@@ -0,0 +1,25 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "package:expect/expect.dart";
+
+class MessageType extends core::Object /*hasConstConstructor*/  {
+  static const field self::MessageType print = const self::MessageType::_("print");
+  static const field self::MessageType skip = const self::MessageType::_("skip");
+  final field core::String name;
+  const constructor _(core::String name) → self::MessageType
+    : self::MessageType::name = name, super core::Object::•()
+    ;
+  static const factory parse(core::String name) → self::MessageType
+    ;
+}
+static const field self::MessageType printConst = const self::MessageType::parse("print");
+static method main() → void
+  ;
+
+
+Extra constant evaluation status:
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///const_functions_const_factory.dart:12:36 -> InstanceConstant(const MessageType{MessageType.name: "print"})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///const_functions_const_factory.dart:14:35 -> InstanceConstant(const MessageType{MessageType.name: "skip"})
+Extra constant evaluation: evaluated: 4, effectively constant: 2
diff --git a/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.weak.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.weak.transformed.expect
new file mode 100644
index 0000000..c9674e9
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.weak.transformed.expect
@@ -0,0 +1,38 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+class MessageType extends core::Object /*hasConstConstructor*/  {
+  static const field self::MessageType print = #C2;
+  static const field self::MessageType skip = #C4;
+  final field core::String name;
+  const constructor _(core::String name) → self::MessageType
+    : self::MessageType::name = name, super core::Object::•()
+    ;
+  static factory parse(core::String name) → self::MessageType {
+    if(name.{core::String::==}("print")) {
+      return #C2;
+    }
+    return #C4;
+  }
+}
+static const field self::MessageType printConst = #C2;
+static method main() → void {
+  exp::Expect::equals(#C2, #C2);
+}
+
+constants  {
+  #C1 = "print"
+  #C2 = self::MessageType {name:#C1}
+  #C3 = "skip"
+  #C4 = self::MessageType {name:#C3}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///const_functions_const_factory.dart:
+- MessageType._ (from org-dartlang-testcase:///const_functions_const_factory.dart:25:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/outline.status b/pkg/front_end/testcases/outline.status
index 8c4bb20..dc7cac2 100644
--- a/pkg/front_end/testcases/outline.status
+++ b/pkg/front_end/testcases/outline.status
@@ -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.md file.
 
+const_functions/const_functions_const_factory: VerificationError
 extension_types/simple: ExpectationFileMismatchSerialized
 extension_types/simple_getter_resolution: ExpectationFileMismatchSerialized
 extension_types/simple_method_resolution: ExpectationFileMismatchSerialized
diff --git a/pkg/front_end/testcases/textual_outline.status b/pkg/front_end/testcases/textual_outline.status
index 408c9ce..6dd5ffb 100644
--- a/pkg/front_end/testcases/textual_outline.status
+++ b/pkg/front_end/testcases/textual_outline.status
@@ -20,7 +20,7 @@
 regress/issue_39091_2: EmptyOutput
 regress/utf_16_le_content.crash: EmptyOutput
 
-
+const_functions/const_functions_const_factory: FormatterCrash
 extensions/extension_constructor: FormatterCrash
 extensions/extension_field_with_type_parameter_usage: FormatterCrash
 extensions/issue38600: FormatterCrash
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index 3d38bf7..0f193da 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -1332,6 +1332,16 @@
           body += FloatToDouble();
         }
         body += Box(kUnboxedDouble);
+      } else if (kind == MethodRecognizer::kFfiLoadInt8 ||
+                 kind == MethodRecognizer::kFfiLoadInt16 ||
+                 kind == MethodRecognizer::kFfiLoadUint8 ||
+                 kind == MethodRecognizer::kFfiLoadUint16) {
+        // LoadIndexed instruction with 8-bit and 16-bit elements
+        // results in value with kUnboxedIntPtr representation
+        // (see LoadIndexedInstr::representation).
+        // Avoid any unnecessary (and potentially deoptimizing) int
+        // conversions by using the correct representation at the first place.
+        body += Box(kUnboxedIntPtr);
       } else {
         body += Box(native_rep.AsRepresentationOverApprox(zone_));
         if (kind == MethodRecognizer::kFfiLoadPointer) {
@@ -1462,6 +1472,16 @@
             kind == MethodRecognizer::kFfiStoreFloatUnaligned) {
           body += DoubleToFloat();
         }
+      } else if (kind == MethodRecognizer::kFfiStoreInt8 ||
+                 kind == MethodRecognizer::kFfiStoreInt16 ||
+                 kind == MethodRecognizer::kFfiStoreUint8 ||
+                 kind == MethodRecognizer::kFfiStoreUint16) {
+        // StoreIndexed instruction with 8-bit and 16-bit elements
+        // takes value with kUnboxedIntPtr representation
+        // (see StoreIndexedInstr::RequiredInputRepresentation).
+        // Avoid any unnecessary (and potentially deoptimizing) int
+        // conversions by using the correct representation at the first place.
+        body += UnboxTruncate(kUnboxedIntPtr);
       } else {
         body += UnboxTruncate(native_rep.AsRepresentationOverApprox(zone_));
       }
diff --git a/tests/ffi/regress_flutter79441_test.dart b/tests/ffi/regress_flutter79441_test.dart
new file mode 100644
index 0000000..7f1336f
--- /dev/null
+++ b/tests/ffi/regress_flutter79441_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2021, 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.
+
+// Regression test for https://github.com/flutter/flutter/issues/79441.
+
+import 'dart:ffi';
+
+// FFI signature
+typedef _dart_memset = void Function(Pointer<Uint8>, int, int);
+typedef _c_memset = Void Function(Pointer<Uint8>, Int32, IntPtr);
+
+_dart_memset? fbMemset;
+
+void _fallbackMemset(Pointer<Uint8> ptr, int byte, int size) {
+  final bytes = ptr.cast<Uint8>();
+  for (var i = 0; i < size; i++) {
+    bytes[i] = byte;
+  }
+}
+
+void main() {
+  try {
+    fbMemset = DynamicLibrary.process()
+        .lookupFunction<_c_memset, _dart_memset>('memset');
+  } catch (_) {
+    // This works:
+    // fbMemset = _fallbackMemset;
+
+    // This doesn't: /aot/precompiler.cc: 2761: error: unreachable code
+    fbMemset = (Pointer<Uint8> ptr, int byte, int size) {
+      final bytes = ptr.cast<Uint8>();
+      for (var i = 0; i < size; i++) {
+        bytes[i] = byte;
+      }
+    };
+  }
+}
diff --git a/tests/ffi_2/regress_flutter79441_test.dart b/tests/ffi_2/regress_flutter79441_test.dart
new file mode 100644
index 0000000..a9b17de
--- /dev/null
+++ b/tests/ffi_2/regress_flutter79441_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2021, 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.
+
+// Regression test for https://github.com/flutter/flutter/issues/79441.
+
+import 'dart:ffi';
+
+// FFI signature
+typedef _dart_memset = void Function(Pointer<Uint8>, int, int);
+typedef _c_memset = Void Function(Pointer<Uint8>, Int32, IntPtr);
+
+_dart_memset fbMemset;
+
+void _fallbackMemset(Pointer<Uint8> ptr, int byte, int size) {
+  final bytes = ptr.cast<Uint8>();
+  for (var i = 0; i < size; i++) {
+    bytes[i] = byte;
+  }
+}
+
+void main() {
+  try {
+    fbMemset = DynamicLibrary.process()
+        .lookupFunction<_c_memset, _dart_memset>('memset');
+  } catch (_) {
+    // This works:
+    // fbMemset = _fallbackMemset;
+
+    // This doesn't: /aot/precompiler.cc: 2761: error: unreachable code
+    fbMemset = (Pointer<Uint8> ptr, int byte, int size) {
+      final bytes = ptr.cast<Uint8>();
+      for (var i = 0; i < size; i++) {
+        bytes[i] = byte;
+      }
+    };
+  }
+}
diff --git a/tests/language/const_functions/const_functions_const_factory_disabled_test.dart b/tests/language/const_functions/const_functions_const_factory_disabled_test.dart
new file mode 100644
index 0000000..e6bf9c6
--- /dev/null
+++ b/tests/language/const_functions/const_functions_const_factory_disabled_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2021, 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.
+
+// Tests const factories with const functions disabled.
+
+import "package:expect/expect.dart";
+
+const printConst = MessageType.parse("print");
+
+class MessageType {
+  static const print = MessageType._('print');
+
+  static const skip = MessageType._('skip');
+
+  final String name;
+
+  const factory MessageType.parse(String name) {
+//^^^^^
+// [analyzer] SYNTACTIC_ERROR.CONST_FACTORY
+// [cfe] Only redirecting factory constructors can be declared to be 'const'.
+    if (name == 'print') {
+      return MessageType.print;
+    }
+    return MessageType.skip;
+  }
+
+  const MessageType._(this.name);
+}
diff --git a/tests/language/const_functions/const_functions_const_factory_test.dart b/tests/language/const_functions/const_functions_const_factory_test.dart
new file mode 100644
index 0000000..2ff63bc
--- /dev/null
+++ b/tests/language/const_functions/const_functions_const_factory_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2021, 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.
+
+// Tests const factories with const functions.
+
+// SharedOptions=--enable-experiment=const-functions
+
+import "package:expect/expect.dart";
+
+const printConst = MessageType.parse("print");
+
+class MessageType {
+  static const print = MessageType._('print');
+
+  static const skip = MessageType._('skip');
+
+  final String name;
+
+  const factory MessageType.parse(String name) {
+//^^^^^
+// [analyzer] SYNTACTIC_ERROR.CONST_FACTORY
+    if (name == 'print') {
+      return MessageType.print;
+    }
+    return MessageType.skip;
+  }
+
+  const MessageType._(this.name);
+}
+
+void main() {
+  Expect.equals(printConst, MessageType.print);
+}
diff --git a/tools/VERSION b/tools/VERSION
index e5962f7d..f65d244 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 13
 PATCH 0
-PRERELEASE 210
+PRERELEASE 211
 PRERELEASE_PATCH 0
\ No newline at end of file