Version 2.11.0-160.0.dev

Merge commit '75ffae6a5c523810989c929f0c4ba4aece8590bc' into 'dev'
diff --git a/pkg/analysis_server/analysis_options.yaml b/pkg/analysis_server/analysis_options.yaml
index dd243d9..5995e86 100644
--- a/pkg/analysis_server/analysis_options.yaml
+++ b/pkg/analysis_server/analysis_options.yaml
@@ -15,6 +15,7 @@
 
 linter:
   rules:
+    - await_only_futures
     - empty_statements
     - unnecessary_brace_in_string_interps
     #
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index 95ed5c8..570c266 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -561,7 +561,7 @@
     }
 
     // Prepare the file information.
-    var result = await server.getParsedUnit(file);
+    var result = server.getParsedUnit(file);
     if (result == null) {
       server.sendResponse(Response.fileNotAnalyzed(request, file));
       return;
diff --git a/pkg/analysis_server/lib/src/edit/fix/fix_code_task.dart b/pkg/analysis_server/lib/src/edit/fix/fix_code_task.dart
index fff1df7..a4243a9 100644
--- a/pkg/analysis_server/lib/src/edit/fix/fix_code_task.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/fix_code_task.dart
@@ -28,7 +28,7 @@
     }
   }
 
-  void processPackage(Folder pkgFolder) async {
+  Future<void> processPackage(Folder pkgFolder) async {
     for (var task in _codeTasks) {
       await task.processPackage(pkgFolder);
     }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_late.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_late.dart
index a8ec84f..93c14bd 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_late.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_late.dart
@@ -44,7 +44,7 @@
     }
   }
 
-  void _insertAt(ChangeBuilder builder, int offset) async {
+  Future<void> _insertAt(ChangeBuilder builder, int offset) async {
     await builder.addDartFileEdit(file, (builder) {
       builder.addSimpleInsertion(offset, 'late ');
     });
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/flutter_convert_to_children.dart b/pkg/analysis_server/lib/src/services/correction/dart/flutter_convert_to_children.dart
index 2025838..5bcc3fc 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/flutter_convert_to_children.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/flutter_convert_to_children.dart
@@ -60,7 +60,8 @@
       if (newlineLoc == childArgSrc.length) {
         newlineLoc -= 1;
       }
-      String indentOld = getLinePrefix(childArg.offset + 1 + newlineLoc);
+      String indentOld =
+          getLinePrefix(childArg.offset + eol.length + newlineLoc);
       var indentNew = '$indentOld${getIndent(1)}';
       // The separator includes 'child:' but that has no newlines.
       String separator =
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/flutter_wrap_generic.dart b/pkg/analysis_server/lib/src/services/correction/dart/flutter_wrap_generic.dart
index 6b0ac1a..5fcd235 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/flutter_wrap_generic.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/flutter_wrap_generic.dart
@@ -28,7 +28,7 @@
     if (newlineIdx < 0 || newlineIdx == literalSrc.length - 1) {
       return; // Lists need to be in multi-line format already.
     }
-    var indentOld = utils.getLinePrefix(node.offset + 1 + newlineIdx);
+    var indentOld = utils.getLinePrefix(node.offset + eol.length + newlineIdx);
     var indentArg = '$indentOld${utils.getIndent(1)}';
     var indentList = '$indentOld${utils.getIndent(2)}';
 
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_annotation.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_annotation.dart
index d40a8a5..6a6d159 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_annotation.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_annotation.dart
@@ -21,7 +21,7 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    void addFix(Annotation node) async {
+    Future<void> addFix(Annotation node) async {
       if (node == null) {
         return;
       }
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/analysis_options/fix_generator.dart b/pkg/analysis_server/lib/src/services/correction/fix/analysis_options/fix_generator.dart
index 32381fa..b176935 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/analysis_options/fix_generator.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/analysis_options/fix_generator.dart
@@ -87,7 +87,7 @@
     return fixes;
   }
 
-  void _addFix_removeSetting() async {
+  Future<void> _addFix_removeSetting() async {
     if (coveringNodePath[0] is YamlScalar) {
       SourceRange deletionRange;
       var index = 1;
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
index 886804c..d626bd2 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
@@ -754,7 +754,7 @@
   }
 
   Future<void> _initializeReturnType() async {
-    var typeProvider = await resolveResult.typeProvider;
+    var typeProvider = resolveResult.typeProvider;
     if (_selectionFunctionExpression != null) {
       variableType = '';
       returnType = '';
diff --git a/pkg/analysis_server/lib/src/status/diagnostics.dart b/pkg/analysis_server/lib/src/status/diagnostics.dart
index 540843b..bd39067 100644
--- a/pkg/analysis_server/lib/src/status/diagnostics.dart
+++ b/pkg/analysis_server/lib/src/status/diagnostics.dart
@@ -391,7 +391,7 @@
           raw: true);
       return;
     }
-    var file = await server.resourceProvider.getFile(filePath);
+    var file = server.resourceProvider.getFile(filePath);
     if (!file.exists) {
       p('The file <code>${escape(filePath)}</code> does not exist.', raw: true);
       return;
diff --git a/pkg/analysis_server/lib/src/utilities/flutter.dart b/pkg/analysis_server/lib/src/utilities/flutter.dart
index d5a48c5..9243a189 100644
--- a/pkg/analysis_server/lib/src/utilities/flutter.dart
+++ b/pkg/analysis_server/lib/src/utilities/flutter.dart
@@ -95,7 +95,8 @@
       if (newlineLoc == childArgSrc.length) {
         newlineLoc -= 1;
       }
-      String indentOld = getLinePrefix(childArg.offset + 1 + newlineLoc);
+      String indentOld =
+          getLinePrefix(childArg.offset + eol.length + newlineLoc);
       var indentNew = '$indentOld${getIndent(1)}';
       // The separator includes 'child:' but that has no newlines.
       String separator =
@@ -136,7 +137,8 @@
       if (newlineLoc == childArgSrc.length) {
         newlineLoc -= 1;
       }
-      String indentOld = getLinePrefix(childArg.offset + 1 + newlineLoc);
+      String indentOld =
+          getLinePrefix(childArg.offset + eol.length + newlineLoc);
       var indentNew = '$indentOld${getIndent(1)}';
       // The separator includes 'child:' but that has no newlines.
       String separator =
diff --git a/pkg/analysis_server/test/analysis/notification_errors_test.dart b/pkg/analysis_server/test/analysis/notification_errors_test.dart
index 540323d..5a67754 100644
--- a/pkg/analysis_server/test/analysis/notification_errors_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_errors_test.dart
@@ -203,7 +203,7 @@
 
     // Add to priority files and give chance for the file to be analyzed (if
     // it would).
-    await setPriorityFiles([brokenFile]);
+    setPriorityFiles([brokenFile]);
     await waitForTasksFinished();
     await pumpEventQueue(times: 5000);
 
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index 9bae3c4..c00d24e 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -866,12 +866,12 @@
     extends AbstractCompletionDomainTest {
   String testFileUri;
 
-  void expectTokens(String content, List<TokenDetails> expectedTokens) async {
+  Future<void> expectTokens(String content, List<TokenDetails> expected) async {
     newFile(testFile, content: content);
     var request = CompletionListTokenDetailsParams(testFile).toRequest('0');
     var response = await waitResponse(request);
     List<Map<String, dynamic>> tokens = response.result['tokens'];
-    _compareTokens(tokens, expectedTokens);
+    _compareTokens(tokens, expected);
   }
 
   @override
diff --git a/pkg/analysis_server/test/lsp/change_workspace_folders_test.dart b/pkg/analysis_server/test/lsp/change_workspace_folders_test.dart
index 95e11f4..414c52d 100644
--- a/pkg/analysis_server/test/lsp/change_workspace_folders_test.dart
+++ b/pkg/analysis_server/test/lsp/change_workspace_folders_test.dart
@@ -65,7 +65,7 @@
         join(workspaceFolder1Path, 'nested', 'deeply', 'in', 'folders');
     final nestedFilePath = join(nestedFolderPath, 'test.dart');
     final nestedFileUri = Uri.file(nestedFilePath);
-    await newFile(nestedFilePath);
+    newFile(nestedFilePath);
 
     await initialize(allowEmptyRootUri: true);
     await openFile(nestedFileUri, '');
@@ -98,7 +98,7 @@
         join(workspaceFolder1Path, 'nested', 'deeply', 'in', 'folders');
     final nestedFilePath = join(nestedFolderPath, 'test.dart');
     final nestedFileUri = Uri.file(nestedFilePath);
-    await newFile(nestedFilePath);
+    newFile(nestedFilePath);
 
     await initialize(allowEmptyRootUri: true);
     await openFile(nestedFileUri, '');
@@ -132,7 +132,7 @@
         join(workspaceFolder1Path, 'nested', 'deeply', 'in', 'folders');
     final nestedFilePath = join(nestedFolderPath, 'test.dart');
     final nestedFileUri = Uri.file(nestedFilePath);
-    await newFile(nestedFilePath);
+    newFile(nestedFilePath);
 
     await initialize(workspaceFolders: [workspaceFolder1Uri]);
 
@@ -164,7 +164,7 @@
         join(workspaceFolder1Path, 'nested', 'deeply', 'in', 'folders');
     final nestedFilePath = join(nestedFolderPath, 'test.dart');
     final nestedFileUri = Uri.file(nestedFilePath);
-    await newFile(nestedFilePath);
+    newFile(nestedFilePath);
 
     await initialize(workspaceFolders: [workspaceFolder1Uri]);
 
@@ -201,10 +201,10 @@
     // the pub cache folder being added as an analysis root, it should be analyzed
     // by the existing project's driver.
     final workspace1FilePath = join(workspaceFolder1Path, 'test.dart');
-    await newFile(workspace1FilePath);
+    newFile(workspace1FilePath);
     final workspace2FilePath = join(workspaceFolder2Path, 'test.dart');
     final workspace2FileUri = Uri.file(workspace2FilePath);
-    await newFile(workspace2FilePath);
+    newFile(workspace2FilePath);
 
     await initialize(workspaceFolders: [workspaceFolder1Uri]);
 
diff --git a/pkg/analysis_server/test/lsp/code_actions_assists_test.dart b/pkg/analysis_server/test/lsp/code_actions_assists_test.dart
index 0ed0c88..03def9f 100644
--- a/pkg/analysis_server/test/lsp/code_actions_assists_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_assists_test.dart
@@ -29,7 +29,7 @@
 
     Future f;
     ''';
-    await newFile(mainFilePath, content: withoutMarkers(content));
+    newFile(mainFilePath, content: withoutMarkers(content));
     await initialize(
       textDocumentCapabilities: withCodeActionKinds(
           emptyTextDocumentClientCapabilities, [CodeActionKind.Refactor]),
@@ -70,7 +70,7 @@
 
     Future f;
     ''';
-    await newFile(mainFilePath, content: withoutMarkers(content));
+    newFile(mainFilePath, content: withoutMarkers(content));
     await initialize(
       textDocumentCapabilities: withCodeActionKinds(
           emptyTextDocumentClientCapabilities, [CodeActionKind.Refactor]),
@@ -97,7 +97,7 @@
   }
 
   Future<void> test_nonDartFile() async {
-    await newFile(pubspecFilePath, content: simplePubspecContent);
+    newFile(pubspecFilePath, content: simplePubspecContent);
     await initialize(
       textDocumentCapabilities: withCodeActionKinds(
           emptyTextDocumentClientCapabilities, [CodeActionKind.Refactor]),
diff --git a/pkg/analysis_server/test/lsp/code_actions_fixes_test.dart b/pkg/analysis_server/test/lsp/code_actions_fixes_test.dart
index 0082910..c424137 100644
--- a/pkg/analysis_server/test/lsp/code_actions_fixes_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_fixes_test.dart
@@ -31,7 +31,7 @@
 
     Future foo;
     ''';
-    await newFile(mainFilePath, content: withoutMarkers(content));
+    newFile(mainFilePath, content: withoutMarkers(content));
     await initialize(
       textDocumentCapabilities: withCodeActionKinds(
           emptyTextDocumentClientCapabilities, [CodeActionKind.QuickFix]),
@@ -71,7 +71,7 @@
 
     Future foo;
     ''';
-    await newFile(mainFilePath, content: withoutMarkers(content));
+    newFile(mainFilePath, content: withoutMarkers(content));
     await initialize(
       textDocumentCapabilities: withCodeActionKinds(
           emptyTextDocumentClientCapabilities, [CodeActionKind.QuickFix]),
@@ -100,7 +100,7 @@
     var a = [Test, Test, Te[[]]st];
     ''';
 
-    await newFile(mainFilePath, content: withoutMarkers(content));
+    newFile(mainFilePath, content: withoutMarkers(content));
     await initialize(
       textDocumentCapabilities: withCodeActionKinds(
           emptyTextDocumentClientCapabilities, [CodeActionKind.QuickFix]),
@@ -120,7 +120,7 @@
     var a = [Test, Test, Te[[]]st];
     ''';
 
-    await newFile(mainFilePath, content: withoutMarkers(content));
+    newFile(mainFilePath, content: withoutMarkers(content));
     await initialize(
         textDocumentCapabilities: withCodeActionKinds(
             emptyTextDocumentClientCapabilities, [CodeActionKind.QuickFix]),
@@ -137,7 +137,7 @@
   }
 
   Future<void> test_nonDartFile() async {
-    await newFile(pubspecFilePath, content: simplePubspecContent);
+    newFile(pubspecFilePath, content: simplePubspecContent);
     await initialize(
       textDocumentCapabilities: withCodeActionKinds(
           emptyTextDocumentClientCapabilities, [CodeActionKind.QuickFix]),
@@ -172,7 +172,7 @@
 Completer a;
 ProcessInfo b;
     ''';
-    await newFile(mainFilePath, content: withoutMarkers(content));
+    newFile(mainFilePath, content: withoutMarkers(content));
     await initialize(
       textDocumentCapabilities: withCodeActionKinds(
           emptyTextDocumentClientCapabilities, [CodeActionKind.QuickFix]),
@@ -199,7 +199,7 @@
   Future<void> test_outsideRoot() async {
     final otherFilePath = '/home/otherProject/foo.dart';
     final otherFileUri = Uri.file(otherFilePath);
-    await newFile(otherFilePath, content: 'bad code to create error');
+    newFile(otherFilePath, content: 'bad code to create error');
     await initialize(
       textDocumentCapabilities: withCodeActionKinds(
           emptyTextDocumentClientCapabilities, [CodeActionKind.QuickFix]),
diff --git a/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart b/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
index b733be9..2701b41 100644
--- a/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
@@ -36,7 +36,7 @@
   print('Test!');
 }
     ''';
-    await newFile(mainFilePath, content: withoutMarkers(content));
+    newFile(mainFilePath, content: withoutMarkers(content));
     await initialize();
 
     final codeActions = await getCodeActions(mainFileUri.toString(),
@@ -55,7 +55,7 @@
 ^
 main() {}
     ''';
-    await newFile(mainFilePath, content: content);
+    newFile(mainFilePath, content: content);
     await initialize();
 
     final codeActions = await getCodeActions(mainFileUri.toString());
@@ -136,7 +136,7 @@
   }
 }
     ''';
-    await newFile(mainFilePath, content: withoutMarkers(content));
+    newFile(mainFilePath, content: withoutMarkers(content));
     await initialize();
 
     final codeActions = await getCodeActions(mainFileUri.toString(),
@@ -155,7 +155,7 @@
 ^
 main() {}
     ''';
-    await newFile(mainFilePath, content: content);
+    newFile(mainFilePath, content: content);
     await initialize();
 
     final codeActions = await getCodeActions(mainFileUri.toString());
diff --git a/pkg/analysis_server/test/lsp/code_actions_source_test.dart b/pkg/analysis_server/test/lsp/code_actions_source_test.dart
index 8f4e841..12838ed 100644
--- a/pkg/analysis_server/test/lsp/code_actions_source_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_source_test.dart
@@ -35,7 +35,7 @@
 Completer foo;
 int minified(int x, int y) => min(x, y);
     ''';
-    await newFile(mainFilePath, content: content);
+    newFile(mainFilePath, content: content);
     await initialize(
         workspaceCapabilities: withApplyEditSupport(
             withDocumentChangesSupport(emptyWorkspaceClientCapabilities)));
@@ -64,7 +64,7 @@
 Completer foo;
 int minified(int x, int y) => min(x, y);
     ''';
-    await newFile(mainFilePath, content: content);
+    newFile(mainFilePath, content: content);
     await initialize(
         workspaceCapabilities:
             withApplyEditSupport(emptyWorkspaceClientCapabilities));
@@ -77,7 +77,7 @@
   }
 
   Future<void> test_availableAsCodeActionLiteral() async {
-    await newFile(mainFilePath);
+    newFile(mainFilePath);
     await initialize(
         textDocumentCapabilities: withCodeActionKinds(
             emptyTextDocumentClientCapabilities, [CodeActionKind.Source]),
@@ -93,7 +93,7 @@
   }
 
   Future<void> test_availableAsCommand() async {
-    await newFile(mainFilePath);
+    newFile(mainFilePath);
     await initialize(
         workspaceCapabilities:
             withApplyEditSupport(emptyWorkspaceClientCapabilities));
@@ -108,7 +108,7 @@
 
   Future<void> test_failsSilentlyIfFileHasErrors() async {
     final content = 'invalid dart code';
-    await newFile(mainFilePath, content: content);
+    newFile(mainFilePath, content: content);
     await initialize(
         workspaceCapabilities:
             withApplyEditSupport(emptyWorkspaceClientCapabilities));
@@ -136,7 +136,7 @@
 Completer foo;
 int minified(int x, int y) => min(x, y);
     ''';
-    await newFile(mainFilePath, content: content);
+    newFile(mainFilePath, content: content);
     await initialize(
         workspaceCapabilities:
             withApplyEditSupport(emptyWorkspaceClientCapabilities));
@@ -158,7 +158,7 @@
   }
 
   Future<void> test_unavailableWhenNotRequested() async {
-    await newFile(mainFilePath);
+    newFile(mainFilePath);
     await initialize(
         textDocumentCapabilities: withCodeActionKinds(
             emptyTextDocumentClientCapabilities, [CodeActionKind.Refactor]),
@@ -171,7 +171,7 @@
   }
 
   Future<void> test_unavailableWithoutApplyEditSupport() async {
-    await newFile(mainFilePath);
+    newFile(mainFilePath);
     await initialize();
 
     final codeActions = await getCodeActions(mainFileUri.toString());
@@ -191,7 +191,7 @@
     String a;
     String b;
     ''';
-    await newFile(mainFilePath, content: content);
+    newFile(mainFilePath, content: content);
     await initialize(
         workspaceCapabilities: withApplyEditSupport(
             withDocumentChangesSupport(emptyWorkspaceClientCapabilities)));
@@ -213,7 +213,7 @@
     String a;
     String b;
     ''';
-    await newFile(mainFilePath, content: content);
+    newFile(mainFilePath, content: content);
     await initialize(
         workspaceCapabilities:
             withApplyEditSupport(emptyWorkspaceClientCapabilities));
@@ -226,7 +226,7 @@
   }
 
   Future<void> test_availableAsCodeActionLiteral() async {
-    await newFile(mainFilePath);
+    newFile(mainFilePath);
     await initialize(
         textDocumentCapabilities: withCodeActionKinds(
             emptyTextDocumentClientCapabilities, [CodeActionKind.Source]),
@@ -242,7 +242,7 @@
   }
 
   Future<void> test_availableAsCommand() async {
-    await newFile(mainFilePath);
+    newFile(mainFilePath);
     await initialize(
         workspaceCapabilities:
             withApplyEditSupport(emptyWorkspaceClientCapabilities));
@@ -260,7 +260,7 @@
     String b;
     String a;
     ''';
-    await newFile(mainFilePath, content: content);
+    newFile(mainFilePath, content: content);
     await initialize(
         workspaceCapabilities:
             withApplyEditSupport(emptyWorkspaceClientCapabilities));
@@ -294,7 +294,7 @@
 
   Future<void> test_failsIfFileHasErrors() async {
     final content = 'invalid dart code';
-    await newFile(mainFilePath, content: content);
+    newFile(mainFilePath, content: content);
     await initialize(
         workspaceCapabilities:
             withApplyEditSupport(emptyWorkspaceClientCapabilities));
@@ -315,7 +315,7 @@
   }
 
   Future<void> test_nonDartFile() async {
-    await newFile(pubspecFilePath, content: simplePubspecContent);
+    newFile(pubspecFilePath, content: simplePubspecContent);
     await initialize(
         textDocumentCapabilities: withCodeActionKinds(
             emptyTextDocumentClientCapabilities, [CodeActionKind.Source]),
@@ -328,7 +328,7 @@
   }
 
   Future<void> test_unavailableWhenNotRequested() async {
-    await newFile(mainFilePath);
+    newFile(mainFilePath);
     await initialize(
         textDocumentCapabilities: withCodeActionKinds(
             emptyTextDocumentClientCapabilities, [CodeActionKind.Refactor]),
@@ -341,7 +341,7 @@
   }
 
   Future<void> test_unavailableWithoutApplyEditSupport() async {
-    await newFile(mainFilePath);
+    newFile(mainFilePath);
     await initialize();
 
     final codeActions = await getCodeActions(mainFileUri.toString());
diff --git a/pkg/analysis_server/test/lsp/diagnostic_test.dart b/pkg/analysis_server/test/lsp/diagnostic_test.dart
index 565fd21..f88804e 100644
--- a/pkg/analysis_server/test/lsp/diagnostic_test.dart
+++ b/pkg/analysis_server/test/lsp/diagnostic_test.dart
@@ -171,7 +171,7 @@
 
     // Deleting the file should result in an update to remove the diagnostics.
     final secondDiagnosticsUpdate = waitForDiagnostics(mainFileUri);
-    await deleteFile(mainFilePath);
+    deleteFile(mainFilePath);
     final updatedDiagnostics = await secondDiagnosticsUpdate;
     expect(updatedDiagnostics, hasLength(0));
   }
diff --git a/pkg/analysis_server/test/lsp/initialization_test.dart b/pkg/analysis_server/test/lsp/initialization_test.dart
index 4bae1b9..43e9db8 100644
--- a/pkg/analysis_server/test/lsp/initialization_test.dart
+++ b/pkg/analysis_server/test/lsp/initialization_test.dart
@@ -262,12 +262,12 @@
   Future<void> test_emptyAnalysisRoots_multipleOpenFiles() async {
     final file1 = join(projectFolderPath, 'file1.dart');
     final file1Uri = Uri.file(file1);
-    await newFile(file1);
+    newFile(file1);
     final file2 = join(projectFolderPath, 'file2.dart');
     final file2Uri = Uri.file(file2);
-    await newFile(file2);
+    newFile(file2);
     final pubspecPath = join(projectFolderPath, 'pubspec.yaml');
-    await newFile(pubspecPath);
+    newFile(pubspecPath);
 
     await initialize(allowEmptyRootUri: true);
 
@@ -290,7 +290,7 @@
     final nestedFilePath = join(
         projectFolderPath, 'nested', 'deeply', 'in', 'folders', 'test.dart');
     final nestedFileUri = Uri.file(nestedFilePath);
-    await newFile(nestedFilePath);
+    newFile(nestedFilePath);
 
     // The project folder shouldn't be added to start with.
     await initialize(allowEmptyRootUri: true);
@@ -306,9 +306,9 @@
     final nestedFilePath = join(
         projectFolderPath, 'nested', 'deeply', 'in', 'folders', 'test.dart');
     final nestedFileUri = Uri.file(nestedFilePath);
-    await newFile(nestedFilePath);
+    newFile(nestedFilePath);
     final pubspecPath = join(projectFolderPath, 'pubspec.yaml');
-    await newFile(pubspecPath);
+    newFile(pubspecPath);
 
     // The project folder shouldn't be added to start with.
     await initialize(allowEmptyRootUri: true);
@@ -443,12 +443,12 @@
   Future<void> test_onlyAnalyzeProjectsWithOpenFiles_multipleFiles() async {
     final file1 = join(projectFolderPath, 'file1.dart');
     final file1Uri = Uri.file(file1);
-    await newFile(file1);
+    newFile(file1);
     final file2 = join(projectFolderPath, 'file2.dart');
     final file2Uri = Uri.file(file2);
-    await newFile(file2);
+    newFile(file2);
     final pubspecPath = join(projectFolderPath, 'pubspec.yaml');
-    await newFile(pubspecPath);
+    newFile(pubspecPath);
 
     await initialize(
       rootUri: projectFolderUri,
@@ -474,7 +474,7 @@
     final nestedFilePath = join(
         projectFolderPath, 'nested', 'deeply', 'in', 'folders', 'test.dart');
     final nestedFileUri = Uri.file(nestedFilePath);
-    await newFile(nestedFilePath);
+    newFile(nestedFilePath);
 
     // The project folder shouldn't be added to start with.
     await initialize(
@@ -493,9 +493,9 @@
     final nestedFilePath = join(
         projectFolderPath, 'nested', 'deeply', 'in', 'folders', 'test.dart');
     final nestedFileUri = Uri.file(nestedFilePath);
-    await newFile(nestedFilePath);
+    newFile(nestedFilePath);
     final pubspecPath = join(projectFolderPath, 'pubspec.yaml');
-    await newFile(pubspecPath);
+    newFile(pubspecPath);
 
     // The project folder shouldn't be added to start with.
     await initialize(
diff --git a/pkg/analysis_server/test/lsp/rename_test.dart b/pkg/analysis_server/test/lsp/rename_test.dart
index 0896bf2..41469c8 100644
--- a/pkg/analysis_server/test/lsp/rename_test.dart
+++ b/pkg/analysis_server/test/lsp/rename_test.dart
@@ -290,7 +290,7 @@
     final a = new [[Ob^ject]]();
     ''';
 
-    await newFile(mainFilePath, content: withoutMarkers(content));
+    newFile(mainFilePath, content: withoutMarkers(content));
     await initialize();
 
     final request = makeRequest(
diff --git a/pkg/analysis_server/test/src/lsp/lsp_packet_transformer_test.dart b/pkg/analysis_server/test/src/lsp/lsp_packet_transformer_test.dart
index a119979..614fe4f 100644
--- a/pkg/analysis_server/test/src/lsp/lsp_packet_transformer_test.dart
+++ b/pkg/analysis_server/test/src/lsp/lsp_packet_transformer_test.dart
@@ -74,10 +74,10 @@
       final payload = '{ json payload }';
       final lspPacket =
           makeLspPacket(payload, 'application/vscode-jsonrpc; charset=ascii');
-      final outputStream = await Stream.fromIterable([lspPacket])
-          .transform(LspPacketTransformer());
+      final outputStream =
+          Stream.fromIterable([lspPacket]).transform(LspPacketTransformer());
 
-      expectLater(outputStream.toList(),
+      await expectLater(outputStream.toList(),
           throwsA(const TypeMatcher<InvalidEncodingError>()));
     });
   });
diff --git a/pkg/analysis_server/test/src/services/correction/assist/add_type_annotation_test.dart b/pkg/analysis_server/test/src/services/correction/assist/add_type_annotation_test.dart
index 78926b0..d0d30dd 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/add_type_annotation_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/add_type_annotation_test.dart
@@ -50,7 +50,7 @@
   var f = 0;
 }
 ''');
-    await await assertHasAssistAt('var ', '''
+    await assertHasAssistAt('var ', '''
 class A {
   int f = 0;
 }
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_convert_to_children_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_convert_to_children_test.dart
index f2db30e..b34b23d 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_convert_to_children_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_convert_to_children_test.dart
@@ -19,13 +19,6 @@
   @override
   AssistKind get kind => DartAssistKind.FLUTTER_CONVERT_TO_CHILDREN;
 
-  @override
-  void setUp() {
-    super.setUp();
-    // TODO(dantup): Get these tests passing with either line ending.
-    useLineEndingsForPlatform = false;
-  }
-
   Future<void> test_childUnresolved() async {
     addFlutterPackage();
     verifyNoTestUnitErrors = false;
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_generic_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_generic_test.dart
index d53dda2..794cc11 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_generic_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_generic_test.dart
@@ -19,13 +19,6 @@
   @override
   AssistKind get kind => DartAssistKind.FLUTTER_WRAP_GENERIC;
 
-  @override
-  void setUp() {
-    super.setUp();
-    // TODO(dantup): Get these tests passing with either line ending.
-    useLineEndingsForPlatform = false;
-  }
-
   Future<void> test_minimal() async {
     addFlutterPackage();
     await resolveTestUnit('''
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_flutter_child_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_flutter_child_test.dart
index c4268d2..3e17f59 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_flutter_child_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_flutter_child_test.dart
@@ -19,13 +19,6 @@
   @override
   FixKind get kind => DartFixKind.CONVERT_FLUTTER_CHILD;
 
-  @override
-  void setUp() {
-    super.setUp();
-    // TODO(dantup): Get these tests passing with either line ending.
-    useLineEndingsForPlatform = false;
-  }
-
   Future<void> test_hasList() async {
     addFlutterPackage();
     await resolveTestUnit('''
diff --git a/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart b/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
index a7fb58c..ca983e6 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
@@ -110,7 +110,7 @@
     expect(resultCode, expected);
   }
 
-  void assertHasFixAllFix(ErrorCode errorCode, String expected,
+  Future<void> assertHasFixAllFix(ErrorCode errorCode, String expected,
       {String target}) async {
     if (useLineEndingsForPlatform) {
       expected = normalizeNewlinesForPlatform(expected);
diff --git a/pkg/analysis_server/tool/completion_metrics/code_metrics.dart b/pkg/analysis_server/tool/completion_metrics/code_metrics.dart
index 1ae1151..0876be9 100644
--- a/pkg/analysis_server/tool/completion_metrics/code_metrics.dart
+++ b/pkg/analysis_server/tool/completion_metrics/code_metrics.dart
@@ -1356,7 +1356,7 @@
   CodeShapeMetricsComputer();
 
   /// Compute the metrics for the file(s) in the [rootPath].
-  void compute(String rootPath) async {
+  Future<void> compute(String rootPath) async {
     final collection = AnalysisContextCollection(
       includedPaths: [rootPath],
       resourceProvider: PhysicalResourceProvider.INSTANCE,
@@ -1380,7 +1380,7 @@
   /// separate context collection to prevent accumulating memory. The metrics
   /// should be captured in the [collector]. Include additional details in the
   /// output if [verbose] is `true`.
-  void _computeInContext(
+  Future<void> _computeInContext(
       ContextRoot root, CodeShapeDataCollector collector) async {
     // Create a new collection to avoid consuming large quantities of memory.
     final collection = AnalysisContextCollection(
diff --git a/pkg/analysis_server/tool/completion_metrics/flutter_metrics.dart b/pkg/analysis_server/tool/completion_metrics/flutter_metrics.dart
index 8ff6195..dee0616 100644
--- a/pkg/analysis_server/tool/completion_metrics/flutter_metrics.dart
+++ b/pkg/analysis_server/tool/completion_metrics/flutter_metrics.dart
@@ -172,7 +172,7 @@
   FlutterMetricsComputer();
 
   /// Compute the metrics for the file(s) in the [rootPath].
-  void compute(String rootPath) async {
+  Future<void> compute(String rootPath) async {
     final collection = AnalysisContextCollection(
       includedPaths: [rootPath],
       resourceProvider: PhysicalResourceProvider.INSTANCE,
diff --git a/pkg/analysis_server/tool/completion_metrics/implicit_type_declarations.dart b/pkg/analysis_server/tool/completion_metrics/implicit_type_declarations.dart
index 4b9b1c0..c788082 100644
--- a/pkg/analysis_server/tool/completion_metrics/implicit_type_declarations.dart
+++ b/pkg/analysis_server/tool/completion_metrics/implicit_type_declarations.dart
@@ -139,7 +139,7 @@
   /// Compute the metrics for the file(s) in the [rootPath].
   /// If [corpus] is true, treat rootPath as a container of packages, creating
   /// a new context collection for each subdirectory.
-  void compute(String rootPath, {@required bool verbose}) async {
+  Future<void> compute(String rootPath, {@required bool verbose}) async {
     final collection = AnalysisContextCollection(
       includedPaths: [rootPath],
       resourceProvider: PhysicalResourceProvider.INSTANCE,
@@ -170,7 +170,8 @@
   /// separate context collection to prevent accumulating memory. The metrics
   /// should be captured in the [collector]. Include additional details in the
   /// output if [verbose] is `true`.
-  void _computeInContext(ContextRoot root, ImpliedTypeCollector collector,
+  Future<void> _computeInContext(
+      ContextRoot root, ImpliedTypeCollector collector,
       {@required bool verbose}) async {
     // Create a new collection to avoid consuming large quantities of memory.
     final collection = AnalysisContextCollection(
diff --git a/pkg/analysis_server/tool/completion_metrics/relevance_metrics.dart b/pkg/analysis_server/tool/completion_metrics/relevance_metrics.dart
index e043511..2664da1 100644
--- a/pkg/analysis_server/tool/completion_metrics/relevance_metrics.dart
+++ b/pkg/analysis_server/tool/completion_metrics/relevance_metrics.dart
@@ -1869,7 +1869,7 @@
   /// Compute the metrics for the file(s) in the [rootPath].
   /// If [corpus] is true, treat rootPath as a container of packages, creating
   /// a new context collection for each subdirectory.
-  void compute(String rootPath, {@required bool verbose}) async {
+  Future<void> compute(String rootPath, {@required bool verbose}) async {
     final collection = AnalysisContextCollection(
       includedPaths: [rootPath],
       resourceProvider: PhysicalResourceProvider.INSTANCE,
@@ -1929,7 +1929,8 @@
   /// separate context collection to prevent accumulating memory. The metrics
   /// should be captured in the [collector]. Include additional details in the
   /// output if [verbose] is `true`.
-  void _computeInContext(ContextRoot root, RelevanceDataCollector collector,
+  Future<void> _computeInContext(
+      ContextRoot root, RelevanceDataCollector collector,
       {@required bool verbose}) async {
     // Create a new collection to avoid consuming large quantities of memory.
     final collection = AnalysisContextCollection(
diff --git a/pkg/analysis_server/tool/completion_metrics/relevance_table_generator.dart b/pkg/analysis_server/tool/completion_metrics/relevance_table_generator.dart
index 846e22d..b746fb6 100644
--- a/pkg/analysis_server/tool/completion_metrics/relevance_table_generator.dart
+++ b/pkg/analysis_server/tool/completion_metrics/relevance_table_generator.dart
@@ -1350,7 +1350,7 @@
   /// Compute the metrics for the file(s) in the [rootPath].
   /// If [corpus] is true, treat rootPath as a container of packages, creating
   /// a new context collection for each subdirectory.
-  void compute(String rootPath, {@required bool verbose}) async {
+  Future<void> compute(String rootPath, {@required bool verbose}) async {
     final collection = AnalysisContextCollection(
       includedPaths: [rootPath],
       resourceProvider: PhysicalResourceProvider.INSTANCE,
@@ -1365,7 +1365,8 @@
   /// separate context collection to prevent accumulating memory. The metrics
   /// should be captured in the [collector]. Include additional details in the
   /// output if [verbose] is `true`.
-  void _computeInContext(ContextRoot root, RelevanceDataCollector collector,
+  Future<void> _computeInContext(
+      ContextRoot root, RelevanceDataCollector collector,
       {@required bool verbose}) async {
     // Create a new collection to avoid consuming large quantities of memory.
     final collection = AnalysisContextCollection(
diff --git a/pkg/analysis_server_client/analysis_options.yaml b/pkg/analysis_server_client/analysis_options.yaml
index fe1ff59..fd37fb4 100644
--- a/pkg/analysis_server_client/analysis_options.yaml
+++ b/pkg/analysis_server_client/analysis_options.yaml
@@ -4,6 +4,7 @@
 
 linter:
   rules:
+    - await_only_futures
     - empty_statements
     - unnecessary_brace_in_string_interps
     #
diff --git a/pkg/analyzer/analysis_options.yaml b/pkg/analyzer/analysis_options.yaml
index b269720..3f9b8e3 100644
--- a/pkg/analyzer/analysis_options.yaml
+++ b/pkg/analyzer/analysis_options.yaml
@@ -27,6 +27,7 @@
 linter:
   rules:
     - avoid_unused_constructor_parameters
+    - await_only_futures
     - empty_statements
     - iterable_contains_unrelated_type
     - list_remove_unrelated_type
diff --git a/pkg/analyzer/lib/src/dart/resolver/simple_identifier_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/simple_identifier_resolver.dart
new file mode 100644
index 0000000..c32b116
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/resolver/simple_identifier_resolver.dart
@@ -0,0 +1,336 @@
+// 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/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type_provider.dart';
+import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart';
+import 'package:analyzer/src/dart/resolver/invocation_inference_helper.dart';
+import 'package:analyzer/src/dart/resolver/property_element_resolver.dart';
+import 'package:analyzer/src/dart/resolver/scope.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+
+class SimpleIdentifierResolver {
+  final ResolverVisitor _resolver;
+  final FlowAnalysisHelper _flowAnalysis;
+
+  SimpleIdentifierResolver(this._resolver, this._flowAnalysis);
+
+  ErrorReporter get _errorReporter => _resolver.errorReporter;
+
+  InvocationInferenceHelper get _inferenceHelper => _resolver.inferenceHelper;
+
+  TypeProviderImpl get _typeProvider => _resolver.typeProvider;
+
+  void resolve(SimpleIdentifier node) {
+    if (node.inDeclarationContext()) {
+      return;
+    }
+
+    _resolver.checkUnreachableNode(node);
+
+    _resolver.checkReadOfNotAssignedLocalVariable(node, node.staticElement);
+
+    _resolve1(node);
+    _resolve2(node);
+  }
+
+  /// Return the type that should be recorded for a node that resolved to the given accessor.
+  ///
+  /// @param accessor the accessor that the node resolved to
+  /// @return the type that should be recorded for a node that resolved to the given accessor
+  ///
+  /// TODO(scheglov) this is duplicate
+  DartType _getTypeOfProperty(PropertyAccessorElement accessor) {
+    FunctionType functionType = accessor.type;
+    if (functionType == null) {
+      // TODO(brianwilkerson) Report this internal error. This happens when we
+      // are analyzing a reference to a property before we have analyzed the
+      // declaration of the property or when the property does not have a
+      // defined type.
+      return DynamicTypeImpl.instance;
+    }
+    if (accessor.isSetter) {
+      List<DartType> parameterTypes = functionType.normalParameterTypes;
+      if (parameterTypes != null && parameterTypes.isNotEmpty) {
+        return parameterTypes[0];
+      }
+      PropertyAccessorElement getter = accessor.variable.getter;
+      if (getter != null) {
+        functionType = getter.type;
+        if (functionType != null) {
+          return functionType.returnType;
+        }
+      }
+      return DynamicTypeImpl.instance;
+    }
+    return functionType.returnType;
+  }
+
+  /// Return `true` if the given [node] is not a type literal.
+  ///
+  /// TODO(scheglov) this is duplicate
+  bool _isExpressionIdentifier(Identifier node) {
+    var parent = node.parent;
+    if (node is SimpleIdentifier && node.inDeclarationContext()) {
+      return false;
+    }
+    if (parent is ConstructorDeclaration) {
+      if (parent.name == node || parent.returnType == node) {
+        return false;
+      }
+    }
+    if (parent is ConstructorName ||
+        parent is MethodInvocation ||
+        parent is PrefixedIdentifier && parent.prefix == node ||
+        parent is PropertyAccess ||
+        parent is TypeName) {
+      return false;
+    }
+    return true;
+  }
+
+  /// Return `true` if the given [node] can validly be resolved to a prefix:
+  /// * it is the prefix in an import directive, or
+  /// * it is the prefix in a prefixed identifier.
+  bool _isValidAsPrefix(SimpleIdentifier node) {
+    AstNode parent = node.parent;
+    if (parent is ImportDirective) {
+      return identical(parent.prefix, node);
+    } else if (parent is PrefixedIdentifier) {
+      return true;
+    } else if (parent is MethodInvocation) {
+      return identical(parent.target, node) &&
+          parent.operator?.type == TokenType.PERIOD;
+    }
+    return false;
+  }
+
+  /// Record that the static type of the given node is the given type.
+  ///
+  /// @param expression the node whose type is to be recorded
+  /// @param type the static type of the node
+  ///
+  /// TODO(scheglov) this is duplicate
+  void _recordStaticType(Expression expression, DartType type) {
+    if (_resolver.migrationResolutionHooks != null) {
+      // TODO(scheglov) type cannot be null
+      type = _resolver.migrationResolutionHooks.modifyExpressionType(
+        expression,
+        type ?? DynamicTypeImpl.instance,
+      );
+    }
+
+    // TODO(scheglov) type cannot be null
+    if (type == null) {
+      expression.staticType = DynamicTypeImpl.instance;
+    } else {
+      expression.staticType = type;
+      if (_resolver.typeSystem.isBottom(type)) {
+        _flowAnalysis?.flow?.handleExit();
+      }
+    }
+  }
+
+  void _resolve1(SimpleIdentifier node) {
+    //
+    // Synthetic identifiers have been already reported during parsing.
+    //
+    if (node.isSynthetic) {
+      return;
+    }
+
+    //
+    // Ignore nodes that should have been resolved before getting here.
+    //
+    if (node.inDeclarationContext()) {
+      return;
+    }
+    if (node.staticElement is LocalVariableElement ||
+        node.staticElement is ParameterElement) {
+      return;
+    }
+    AstNode parent = node.parent;
+    if (parent is FieldFormalParameter) {
+      return;
+    } else if (parent is ConstructorFieldInitializer &&
+        parent.fieldName == node) {
+      return;
+    } else if (parent is Annotation && parent.constructorName == node) {
+      return;
+    }
+
+    //
+    // Otherwise, the node should be resolved.
+    //
+
+    // TODO(scheglov) Special-case resolution of ForStatement, don't use this.
+    var hasRead = true;
+    var hasWrite = false;
+    {
+      var parent = node.parent;
+      if (parent is ForEachPartsWithIdentifier && parent.identifier == node) {
+        hasRead = false;
+        hasWrite = true;
+      }
+    }
+
+    var resolver = PropertyElementResolver(_resolver);
+    var result = resolver.resolveSimpleIdentifier(
+      node: node,
+      hasRead: hasRead,
+      hasWrite: hasWrite,
+    );
+
+    // Element element = _resolver.elementResolver.resolveSimpleIdentifier(node);
+    Element element = hasRead ? result.readElement : result.writeElement;
+
+    ClassElement enclosingClass = _resolver.enclosingClass;
+    if (_isFactoryConstructorReturnType(node) &&
+        !identical(element, enclosingClass)) {
+      _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLASS, node);
+    } else if (_isConstructorReturnType(node) &&
+        !identical(element, enclosingClass)) {
+      // This error is now reported by the parser.
+      element = null;
+    } else if (element == null ||
+        (element is PrefixElement && !_isValidAsPrefix(node))) {
+      // TODO(brianwilkerson) Recover from this error.
+      if (_isConstructorReturnType(node)) {
+        _errorReporter.reportErrorForNode(
+            CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, node);
+      } else if (parent is Annotation) {
+        _errorReporter.reportErrorForNode(
+            CompileTimeErrorCode.UNDEFINED_ANNOTATION, parent, [node.name]);
+      } else if (element != null) {
+        _errorReporter.reportErrorForNode(
+            CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
+            node,
+            [element.name]);
+      } else if (node.name == "await" && _resolver.enclosingFunction != null) {
+        _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.UNDEFINED_IDENTIFIER_AWAIT,
+          node,
+        );
+      } else if (!_resolver.nameScope.shouldIgnoreUndefined(node)) {
+        _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.UNDEFINED_IDENTIFIER,
+          node,
+          [node.name],
+        );
+      }
+    }
+    node.staticElement = element;
+  }
+
+  void _resolve2(SimpleIdentifier node) {
+    Element element = node.staticElement;
+
+    if (element is ExtensionElement) {
+      _setExtensionIdentifierType(node);
+      return;
+    }
+
+    DartType staticType = DynamicTypeImpl.instance;
+    if (element is ClassElement) {
+      if (_isExpressionIdentifier(node)) {
+        node.staticType = _typeProvider.typeType;
+      }
+      return;
+    } else if (element is FunctionTypeAliasElement) {
+      if (node.inDeclarationContext() || node.parent is TypeName) {
+        // no type
+      } else {
+        node.staticType = _typeProvider.typeType;
+      }
+      return;
+    } else if (element is MethodElement) {
+      staticType = element.type;
+    } else if (element is PropertyAccessorElement) {
+      staticType = _getTypeOfProperty(element);
+    } else if (element is ExecutableElement) {
+      staticType = element.type;
+    } else if (element is TypeParameterElement) {
+      staticType = _typeProvider.typeType;
+    } else if (element is VariableElement) {
+      staticType = _resolver.localVariableTypeProvider.getType(node);
+    } else if (element is PrefixElement) {
+      var parent = node.parent;
+      if (parent is PrefixedIdentifier && parent.prefix == node ||
+          parent is MethodInvocation && parent.target == node) {
+        return;
+      }
+      staticType = _typeProvider.dynamicType;
+    } else if (element is DynamicElementImpl) {
+      staticType = _typeProvider.typeType;
+    } else {
+      staticType = DynamicTypeImpl.instance;
+    }
+    staticType = _inferenceHelper.inferTearOff(node, node, staticType);
+    _recordStaticType(node, staticType);
+  }
+
+  /// TODO(scheglov) this is duplicate
+  void _setExtensionIdentifierType(Identifier node) {
+    if (node is SimpleIdentifier && node.inDeclarationContext()) {
+      return;
+    }
+
+    var parent = node.parent;
+
+    if (parent is PrefixedIdentifier && parent.identifier == node) {
+      node = parent;
+      parent = node.parent;
+    }
+
+    if (parent is CommentReference ||
+        parent is ExtensionOverride && parent.extensionName == node ||
+        parent is MethodInvocation && parent.target == node ||
+        parent is PrefixedIdentifier && parent.prefix == node ||
+        parent is PropertyAccess && parent.target == node) {
+      return;
+    }
+
+    _resolver.errorReporter.reportErrorForNode(
+      CompileTimeErrorCode.EXTENSION_AS_EXPRESSION,
+      node,
+      [node.name],
+    );
+
+    if (node is PrefixedIdentifier) {
+      node.identifier.staticType = DynamicTypeImpl.instance;
+      node.staticType = DynamicTypeImpl.instance;
+    } else if (node is SimpleIdentifier) {
+      node.staticType = DynamicTypeImpl.instance;
+    }
+  }
+
+  /// Return `true` if the given [identifier] is the return type of a
+  /// constructor declaration.
+  static bool _isConstructorReturnType(SimpleIdentifier identifier) {
+    AstNode parent = identifier.parent;
+    if (parent is ConstructorDeclaration) {
+      return identical(parent.returnType, identifier);
+    }
+    return false;
+  }
+
+  /// Return `true` if the given [identifier] is the return type of a factory
+  /// constructor.
+  static bool _isFactoryConstructorReturnType(SimpleIdentifier identifier) {
+    AstNode parent = identifier.parent;
+    if (parent is ConstructorDeclaration) {
+      return identical(parent.returnType, identifier) &&
+          parent.factoryKeyword != null;
+    }
+    return false;
+  }
+}
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index 20e0732..9939ed4 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
@@ -443,106 +442,6 @@
   }
 
   @override
-  void visitSimpleIdentifier(SimpleIdentifier node) {
-    //
-    // Synthetic identifiers have been already reported during parsing.
-    //
-    if (node.isSynthetic) {
-      return;
-    }
-    //
-    // Ignore nodes that should have been resolved before getting here.
-    //
-    if (node.inDeclarationContext()) {
-      return;
-    }
-    if (node.staticElement is LocalVariableElement ||
-        node.staticElement is ParameterElement) {
-      return;
-    }
-    AstNode parent = node.parent;
-    if (parent is FieldFormalParameter) {
-      return;
-    } else if (parent is ConstructorFieldInitializer &&
-        parent.fieldName == node) {
-      return;
-    } else if (parent is Annotation && parent.constructorName == node) {
-      return;
-    }
-    //
-    // Otherwise, the node should be resolved.
-    //
-    Element element = _resolveSimpleIdentifier(node);
-    ClassElement enclosingClass = _resolver.enclosingClass;
-    if (_isFactoryConstructorReturnType(node) &&
-        !identical(element, enclosingClass)) {
-      _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLASS, node);
-    } else if (_isConstructorReturnType(node) &&
-        !identical(element, enclosingClass)) {
-      // This error is now reported by the parser.
-      element = null;
-    } else if (element == null ||
-        (element is PrefixElement && !_isValidAsPrefix(node))) {
-      // TODO(brianwilkerson) Recover from this error.
-      if (_isConstructorReturnType(node)) {
-        _errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, node);
-      } else if (parent is Annotation) {
-        _errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.UNDEFINED_ANNOTATION, parent, [node.name]);
-      } else if (element != null) {
-        _errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
-            node,
-            [element.name]);
-      } else if (node.name == "await" && _resolver.enclosingFunction != null) {
-        _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.UNDEFINED_IDENTIFIER_AWAIT,
-          node,
-        );
-      } else if (!_resolver.nameScope.shouldIgnoreUndefined(node)) {
-        _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.UNDEFINED_IDENTIFIER,
-          node,
-          [node.name],
-        );
-      }
-    }
-    node.staticElement = element;
-
-    _resolver.setWriteElement(node, element);
-
-    Element getter;
-    var inGetterContext = node.inGetterContext();
-    if (inGetterContext) {
-      if (element is PropertyAccessorElement &&
-          element.enclosingElement is CompilationUnitElement) {
-        getter = element.variable.getter;
-      }
-    }
-
-    if (node.inSetterContext() && inGetterContext && enclosingClass != null) {
-      InterfaceType enclosingType = enclosingClass.thisType;
-      var result = _typePropertyResolver.resolve(
-        receiver: null,
-        receiverType: enclosingType,
-        name: node.name,
-        receiverErrorNode: node,
-        nameErrorEntity: node,
-      );
-      node.auxiliaryElements = AuxiliaryElements(
-        result.getter,
-      );
-      getter ??= result.getter;
-    }
-
-    if (inGetterContext) {
-      _resolver.setReadElement(node, getter);
-    }
-  }
-
-  @override
   void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
     ClassElementImpl enclosingClass = _resolver.enclosingClass;
     if (enclosingClass == null) {
@@ -630,22 +529,6 @@
     _resolveAnnotations(node.metadata);
   }
 
-  /// Return `true` if the given [node] can validly be resolved to a prefix:
-  /// * it is the prefix in an import directive, or
-  /// * it is the prefix in a prefixed identifier.
-  bool _isValidAsPrefix(SimpleIdentifier node) {
-    AstNode parent = node.parent;
-    if (parent is ImportDirective) {
-      return identical(parent.prefix, node);
-    } else if (parent is PrefixedIdentifier) {
-      return true;
-    } else if (parent is MethodInvocation) {
-      return identical(parent.target, node) &&
-          parent.operator?.type == TokenType.PERIOD;
-    }
-    return false;
-  }
-
   /// Return the target of a break or continue statement, and update the static
   /// element of its label (if any). The [parentNode] is the AST node of the
   /// break or continue statement. The [labelNode] is the label contained in
@@ -848,27 +731,6 @@
     return null;
   }
 
-  /// Return `true` if the given [identifier] is the return type of a
-  /// constructor declaration.
-  static bool _isConstructorReturnType(SimpleIdentifier identifier) {
-    AstNode parent = identifier.parent;
-    if (parent is ConstructorDeclaration) {
-      return identical(parent.returnType, identifier);
-    }
-    return false;
-  }
-
-  /// Return `true` if the given [identifier] is the return type of a factory
-  /// constructor.
-  static bool _isFactoryConstructorReturnType(SimpleIdentifier identifier) {
-    AstNode parent = identifier.parent;
-    if (parent is ConstructorDeclaration) {
-      return identical(parent.returnType, identifier) &&
-          parent.factoryKeyword != null;
-    }
-    return false;
-  }
-
   /// Resolve each of the annotations in the given list of [annotations].
   static void _resolveAnnotations(NodeList<Annotation> annotations) {
     for (Annotation annotation in annotations) {
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 3650e5b..f05f178 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -41,6 +41,7 @@
 import 'package:analyzer/src/dart/resolver/prefixed_identifier_resolver.dart';
 import 'package:analyzer/src/dart/resolver/property_element_resolver.dart';
 import 'package:analyzer/src/dart/resolver/scope.dart';
+import 'package:analyzer/src/dart/resolver/simple_identifier_resolver.dart';
 import 'package:analyzer/src/dart/resolver/type_property_resolver.dart';
 import 'package:analyzer/src/dart/resolver/typed_literal_resolver.dart';
 import 'package:analyzer/src/dart/resolver/variable_declaration_resolver.dart';
@@ -1832,13 +1833,7 @@
 
   @override
   void visitSimpleIdentifier(SimpleIdentifier node) {
-    if (node.inDeclarationContext()) {
-      return;
-    }
-
-    checkReadOfNotAssignedLocalVariable(node, node.staticElement);
-
-    super.visitSimpleIdentifier(node);
+    SimpleIdentifierResolver(this, _flowAnalysis).resolve(node);
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index 610860c..ecee766 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -9,17 +9,13 @@
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
-import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/member.dart' show ConstructorMember;
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_provider.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
 import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart';
-import 'package:analyzer/src/dart/resolver/invocation_inference_helper.dart';
-import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/migration.dart';
 import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/generated/variable_type_provider.dart';
 import 'package:analyzer/src/task/strong/checker.dart'
     show getExpressionType, getReadType;
 
@@ -48,9 +44,6 @@
   /// The type representing the type 'dynamic'.
   DartType _dynamicType;
 
-  /// The object providing promoted or declared types of variables.
-  LocalVariableTypeProvider _localVariableTypeProvider;
-
   final FlowAnalysisHelper _flowAnalysis;
 
   /// Initialize a newly created static type analyzer to analyze types for the
@@ -62,11 +55,8 @@
     _typeProvider = _resolver.typeProvider;
     _typeSystem = _resolver.typeSystem;
     _dynamicType = _typeProvider.dynamicType;
-    _localVariableTypeProvider = _resolver.localVariableTypeProvider;
   }
 
-  InvocationInferenceHelper get _inferenceHelper => _resolver.inferenceHelper;
-
   /// Is `true` if the library being analyzed is non-nullable by default.
   bool get _isNonNullableByDefault =>
       _featureSet.isEnabled(Feature.non_nullable);
@@ -300,90 +290,6 @@
     recordStaticType(node, _typeProvider.bottomType);
   }
 
-  /// The Dart Language Specification, 12.30: <blockquote>Evaluation of an identifier expression
-  /// <i>e</i> of the form <i>id</i> proceeds as follows:
-  ///
-  /// Let <i>d</i> be the innermost declaration in the enclosing lexical scope whose name is
-  /// <i>id</i>. If no such declaration exists in the lexical scope, let <i>d</i> be the declaration
-  /// of the inherited member named <i>id</i> if it exists.
-  /// * If <i>d</i> is a class or type alias <i>T</i>, the value of <i>e</i> is the unique instance
-  /// of class `Type` reifying <i>T</i>.
-  /// * If <i>d</i> is a type parameter <i>T</i>, then the value of <i>e</i> is the value of the
-  /// actual type argument corresponding to <i>T</i> that was passed to the generative constructor
-  /// that created the current binding of this. We are assured that this is well defined, because if
-  /// we were in a static member the reference to <i>T</i> would be a compile-time error.
-  /// * If <i>d</i> is a library variable then:
-  /// * If <i>d</i> is of one of the forms <i>var v = e<sub>i</sub>;</i>, <i>T v =
-  /// e<sub>i</sub>;</i>, <i>final v = e<sub>i</sub>;</i>, <i>final T v = e<sub>i</sub>;</i>, and no
-  /// value has yet been stored into <i>v</i> then the initializer expression <i>e<sub>i</sub></i> is
-  /// evaluated. If, during the evaluation of <i>e<sub>i</sub></i>, the getter for <i>v</i> is
-  /// referenced, a CyclicInitializationError is thrown. If the evaluation succeeded yielding an
-  /// object <i>o</i>, let <i>r = o</i>, otherwise let <i>r = null</i>. In any case, <i>r</i> is
-  /// stored into <i>v</i>. The value of <i>e</i> is <i>r</i>.
-  /// * If <i>d</i> is of one of the forms <i>const v = e;</i> or <i>const T v = e;</i> the result
-  /// of the getter is the value of the compile time constant <i>e</i>. Otherwise
-  /// * <i>e</i> evaluates to the current binding of <i>id</i>.
-  /// * If <i>d</i> is a local variable or formal parameter then <i>e</i> evaluates to the current
-  /// binding of <i>id</i>.
-  /// * If <i>d</i> is a static method, top level function or local function then <i>e</i>
-  /// evaluates to the function defined by <i>d</i>.
-  /// * If <i>d</i> is the declaration of a static variable or static getter declared in class
-  /// <i>C</i>, then <i>e</i> is equivalent to the getter invocation <i>C.id</i>.
-  /// * If <i>d</i> is the declaration of a top level getter, then <i>e</i> is equivalent to the
-  /// getter invocation <i>id</i>.
-  /// * Otherwise, if <i>e</i> occurs inside a top level or static function (be it function,
-  /// method, getter, or setter) or variable initializer, evaluation of e causes a NoSuchMethodError
-  /// to be thrown.
-  /// * Otherwise <i>e</i> is equivalent to the property extraction <i>this.id</i>.
-  /// </blockquote>
-  @override
-  void visitSimpleIdentifier(SimpleIdentifier node) {
-    Element element = node.staticElement;
-
-    if (element is ExtensionElement) {
-      _setExtensionIdentifierType(node);
-      return;
-    }
-
-    DartType staticType = _dynamicType;
-    if (element is ClassElement) {
-      if (_isExpressionIdentifier(node)) {
-        node.staticType = _nonNullable(_typeProvider.typeType);
-      }
-      return;
-    } else if (element is FunctionTypeAliasElement) {
-      if (node.inDeclarationContext() || node.parent is TypeName) {
-        // no type
-      } else {
-        node.staticType = _nonNullable(_typeProvider.typeType);
-      }
-      return;
-    } else if (element is MethodElement) {
-      staticType = element.type;
-    } else if (element is PropertyAccessorElement) {
-      staticType = _getTypeOfProperty(element);
-    } else if (element is ExecutableElement) {
-      staticType = element.type;
-    } else if (element is TypeParameterElement) {
-      staticType = _nonNullable(_typeProvider.typeType);
-    } else if (element is VariableElement) {
-      staticType = _localVariableTypeProvider.getType(node);
-    } else if (element is PrefixElement) {
-      var parent = node.parent;
-      if (parent is PrefixedIdentifier && parent.prefix == node ||
-          parent is MethodInvocation && parent.target == node) {
-        return;
-      }
-      staticType = _typeProvider.dynamicType;
-    } else if (element is DynamicElementImpl) {
-      staticType = _nonNullable(_typeProvider.typeType);
-    } else {
-      staticType = _dynamicType;
-    }
-    staticType = _inferenceHelper.inferTearOff(node, node, staticType);
-    recordStaticType(node, staticType);
-  }
-
   /// The Dart Language Specification, 12.5: <blockquote>The static type of a string literal is
   /// `String`.</blockquote>
   @override
@@ -511,36 +417,6 @@
     return type;
   }
 
-  /// Return the type that should be recorded for a node that resolved to the given accessor.
-  ///
-  /// @param accessor the accessor that the node resolved to
-  /// @return the type that should be recorded for a node that resolved to the given accessor
-  DartType _getTypeOfProperty(PropertyAccessorElement accessor) {
-    FunctionType functionType = accessor.type;
-    if (functionType == null) {
-      // TODO(brianwilkerson) Report this internal error. This happens when we
-      // are analyzing a reference to a property before we have analyzed the
-      // declaration of the property or when the property does not have a
-      // defined type.
-      return _dynamicType;
-    }
-    if (accessor.isSetter) {
-      List<DartType> parameterTypes = functionType.normalParameterTypes;
-      if (parameterTypes != null && parameterTypes.isNotEmpty) {
-        return parameterTypes[0];
-      }
-      PropertyAccessorElement getter = accessor.variable.getter;
-      if (getter != null) {
-        functionType = getter.type;
-        if (functionType != null) {
-          return functionType.returnType;
-        }
-      }
-      return _dynamicType;
-    }
-    return functionType.returnType;
-  }
-
   /// Given an instance creation of a possibly generic type, infer the type
   /// arguments using the current context type as well as the argument types.
   void _inferInstanceCreationExpression(InstanceCreationExpression node) {
@@ -598,27 +474,6 @@
     }
   }
 
-  /// Return `true` if the given [node] is not a type literal.
-  bool _isExpressionIdentifier(Identifier node) {
-    var parent = node.parent;
-    if (node is SimpleIdentifier && node.inDeclarationContext()) {
-      return false;
-    }
-    if (parent is ConstructorDeclaration) {
-      if (parent.name == node || parent.returnType == node) {
-        return false;
-      }
-    }
-    if (parent is ConstructorName ||
-        parent is MethodInvocation ||
-        parent is PrefixedIdentifier && parent.prefix == node ||
-        parent is PropertyAccess ||
-        parent is TypeName) {
-      return false;
-    }
-    return true;
-  }
-
   /// Return the non-nullable variant of the [type] if NNBD is enabled, otherwise
   /// return the type itself.
   DartType _nonNullable(DartType type) {
@@ -627,38 +482,4 @@
     }
     return type;
   }
-
-  void _setExtensionIdentifierType(Identifier node) {
-    if (node is SimpleIdentifier && node.inDeclarationContext()) {
-      return;
-    }
-
-    var parent = node.parent;
-
-    if (parent is PrefixedIdentifier && parent.identifier == node) {
-      node = parent;
-      parent = node.parent;
-    }
-
-    if (parent is CommentReference ||
-        parent is ExtensionOverride && parent.extensionName == node ||
-        parent is MethodInvocation && parent.target == node ||
-        parent is PrefixedIdentifier && parent.prefix == node ||
-        parent is PropertyAccess && parent.target == node) {
-      return;
-    }
-
-    _resolver.errorReporter.reportErrorForNode(
-      CompileTimeErrorCode.EXTENSION_AS_EXPRESSION,
-      node,
-      [node.name],
-    );
-
-    if (node is PrefixedIdentifier) {
-      node.identifier.staticType = _dynamicType;
-      node.staticType = _dynamicType;
-    } else if (node is SimpleIdentifier) {
-      node.staticType = _dynamicType;
-    }
-  }
 }
diff --git a/pkg/analyzer/lib/src/lint/project.dart b/pkg/analyzer/lib/src/lint/project.dart
index 18a944b..b3cc575 100644
--- a/pkg/analyzer/lib/src/lint/project.dart
+++ b/pkg/analyzer/lib/src/lint/project.dart
@@ -120,7 +120,7 @@
     return false;
   }
 
-  void _calculate() async {
+  Future<void> _calculate() async {
     if (sources == null || sources.isEmpty) {
       return;
     }
diff --git a/pkg/analyzer/test/generated/element_resolver_test.dart b/pkg/analyzer/test/generated/element_resolver_test.dart
index 35a067a..75588bf 100644
--- a/pkg/analyzer/test/generated/element_resolver_test.dart
+++ b/pkg/analyzer/test/generated/element_resolver_test.dart
@@ -664,40 +664,6 @@
     _listener.assertNoErrors();
   }
 
-  test_visitSimpleIdentifier_classScope() async {
-    InterfaceType doubleType = _typeProvider.doubleType;
-    String fieldName = 'nan';
-    SimpleIdentifier node = AstTestFactory.identifier3(fieldName);
-    _resolveInClass(node, doubleType.element);
-    expect(node.staticElement, doubleType.getGetter(fieldName));
-    _listener.assertNoErrors();
-  }
-
-  test_visitSimpleIdentifier_lexicalScope() async {
-    SimpleIdentifier node = AstTestFactory.identifier3("i");
-    VariableElementImpl element = ElementFactory.localVariableElement(node);
-    expect(_resolveIdentifier(node, [element]), same(element));
-    _listener.assertNoErrors();
-  }
-
-  test_visitSimpleIdentifier_lexicalScope_field_setter() async {
-    InterfaceType intType = _typeProvider.intType;
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    _encloseElement(classA);
-    String fieldName = "a";
-    FieldElement field =
-        ElementFactory.fieldElement(fieldName, false, false, false, intType);
-    classA.fields = <FieldElement>[field];
-    classA.accessors = <PropertyAccessorElement>[field.getter, field.setter];
-    SimpleIdentifier node = AstTestFactory.identifier3(fieldName);
-    AstTestFactory.assignmentExpression(
-        node, TokenType.EQ, AstTestFactory.integer(0));
-    _resolveInClass(node, classA);
-    PropertyAccessorElement element = node.staticElement;
-    expect(element.isSetter, isTrue);
-    _listener.assertNoErrors();
-  }
-
   test_visitSuperConstructorInvocation() async {
     ClassElementImpl superclass = ElementFactory.classElement2("A");
     _encloseElement(superclass);
@@ -811,18 +777,6 @@
   /// has resolved the identifier.
   ///
   /// @param node the expression to be resolved
-  /// @param definedElements the elements that are to be defined in the scope in
-  ///          which the element is being resolved
-  /// @return the element to which the expression was resolved
-  Element _resolveIdentifier(Identifier node, [List<Element> definedElements]) {
-    _resolveNode(node, definedElements);
-    return node.staticElement;
-  }
-
-  /// Return the element associated with the given identifier after the resolver
-  /// has resolved the identifier.
-  ///
-  /// @param node the expression to be resolved
   /// @param enclosingClass the element representing the class enclosing the
   ///          identifier
   /// @return the element to which the expression was resolved
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index 8c827ee..3046a23 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -2870,7 +2870,7 @@
 
   test_fuzz_38113() async {
     // https://github.com/dart-lang/sdk/issues/38113
-    await parseCompilationUnit(r'+t{{r?this}}', errors: [
+    parseCompilationUnit(r'+t{{r?this}}', errors: [
       expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 0, 1),
       expectedError(ParserErrorCode.MISSING_FUNCTION_PARAMETERS, 1, 1),
       expectedError(ParserErrorCode.MISSING_IDENTIFIER, 6, 4),
diff --git a/pkg/analyzer/test/src/dart/analysis/session_test.dart b/pkg/analyzer/test/src/dart/analysis/session_test.dart
index 5e5655f..ed80e60 100644
--- a/pkg/analyzer/test/src/dart/analysis/session_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/session_test.dart
@@ -124,7 +124,7 @@
     var typeProvider = resolvedUnit.typeProvider;
     var intClass = typeProvider.intType.element;
 
-    var parsedLibrary = await session.getParsedLibrary(testPath);
+    var parsedLibrary = session.getParsedLibrary(testPath);
 
     expect(() {
       parsedLibrary.getElementDeclaration(intClass);
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_internal_annotation_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_internal_annotation_test.dart
index 2dee934..7de20a1 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_internal_annotation_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_internal_annotation_test.dart
@@ -22,14 +22,14 @@
   void setUp() async {
     super.setUp();
     writeTestPackageConfigWithMeta();
-    await newFile('$testPackageRootPath/pubspec.yaml', content: r'''
+    newFile('$testPackageRootPath/pubspec.yaml', content: r'''
 name: test
 version: 0.0.1
 ''');
   }
 
   void test_annotationInLib() async {
-    await newFile('$testPackageLibPath/foo.dart', content: r'''
+    newFile('$testPackageLibPath/foo.dart', content: r'''
 import 'package:meta/meta.dart';
 @internal class One {}
 ''');
@@ -41,7 +41,7 @@
   }
 
   void test_annotationInLib_onLibrary() async {
-    await newFile('$testPackageLibPath/foo.dart', content: r'''
+    newFile('$testPackageLibPath/foo.dart', content: r'''
 @internal
 library foo;
 import 'package:meta/meta.dart';
@@ -54,7 +54,7 @@
   }
 
   void test_annotationInLibSrc() async {
-    await newFile('$testPackageLibPath/src/foo.dart', content: r'''
+    newFile('$testPackageLibPath/src/foo.dart', content: r'''
 import 'package:meta/meta.dart';
 @internal class One {}
 ''');
@@ -64,7 +64,7 @@
   }
 
   void test_annotationInLibSrcSubdirectory() async {
-    await newFile('$testPackageLibPath/src/foo/foo.dart', content: r'''
+    newFile('$testPackageLibPath/src/foo/foo.dart', content: r'''
 import 'package:meta/meta.dart';
 @internal class One {}
 ''');
@@ -74,7 +74,7 @@
   }
 
   void test_annotationInLibSubdirectory() async {
-    await newFile('$testPackageLibPath/foo/foo.dart', content: r'''
+    newFile('$testPackageLibPath/foo/foo.dart', content: r'''
 import 'package:meta/meta.dart';
 @internal class One {}
 ''');
@@ -86,7 +86,7 @@
   }
 
   void test_annotationInTest() async {
-    await newFile('$testPackageRootPath/test/foo_test.dart', content: r'''
+    newFile('$testPackageRootPath/test/foo_test.dart', content: r'''
 import 'package:meta/meta.dart';
 @internal class One {}
 ''');
@@ -96,7 +96,7 @@
   }
 
   void test_privateClass() async {
-    await newFile(testPackageImplementationFilePath, content: r'''
+    newFile(testPackageImplementationFilePath, content: r'''
 import 'package:meta/meta.dart';
 @internal class _One {}
 ''');
@@ -109,7 +109,7 @@
   }
 
   void test_privateClassConstructor_named() async {
-    await newFile(testPackageImplementationFilePath, content: r'''
+    newFile(testPackageImplementationFilePath, content: r'''
 import 'package:meta/meta.dart';
 class _C {
   @internal _C.named();
@@ -124,7 +124,7 @@
   }
 
   void test_privateClassConstructor_unnamed() async {
-    await newFile(testPackageImplementationFilePath, content: r'''
+    newFile(testPackageImplementationFilePath, content: r'''
 import 'package:meta/meta.dart';
 class _C {
   @internal _C();
@@ -139,7 +139,7 @@
   }
 
   void test_privateConstructor() async {
-    await newFile(testPackageImplementationFilePath, content: r'''
+    newFile(testPackageImplementationFilePath, content: r'''
 import 'package:meta/meta.dart';
 class C {
   @internal C._f();
@@ -153,7 +153,7 @@
   }
 
   void test_privateEnum() async {
-    await newFile(testPackageImplementationFilePath, content: r'''
+    newFile(testPackageImplementationFilePath, content: r'''
 import 'package:meta/meta.dart';
 @internal enum _E {one}
 ''');
@@ -167,7 +167,7 @@
   }
 
   void test_privateEnumValue() async {
-    await newFile(testPackageImplementationFilePath, content: r'''
+    newFile(testPackageImplementationFilePath, content: r'''
 import 'package:meta/meta.dart';
 enum E {@internal _one}
 ''');
@@ -180,7 +180,7 @@
   }
 
   void test_privateExtension() async {
-    await newFile(testPackageImplementationFilePath, content: r'''
+    newFile(testPackageImplementationFilePath, content: r'''
 import 'package:meta/meta.dart';
 @internal extension _One on String {}
 ''');
@@ -192,7 +192,7 @@
   }
 
   void test_privateExtension_unnamed() async {
-    await newFile(testPackageImplementationFilePath, content: r'''
+    newFile(testPackageImplementationFilePath, content: r'''
 import 'package:meta/meta.dart';
 @internal extension on String {}
 ''');
@@ -204,7 +204,7 @@
   }
 
   void test_privateField_instance() async {
-    await newFile(testPackageImplementationFilePath, content: r'''
+    newFile(testPackageImplementationFilePath, content: r'''
 import 'package:meta/meta.dart';
 class C {
   @internal int _i = 0;
@@ -219,7 +219,7 @@
   }
 
   void test_privateField_static() async {
-    await newFile(testPackageImplementationFilePath, content: r'''
+    newFile(testPackageImplementationFilePath, content: r'''
 import 'package:meta/meta.dart';
 class C {
   @internal static int _i = 0;
@@ -234,7 +234,7 @@
   }
 
   void test_privateGetter() async {
-    await newFile(testPackageImplementationFilePath, content: r'''
+    newFile(testPackageImplementationFilePath, content: r'''
 import 'package:meta/meta.dart';
 class C {
   @internal int get _i => 0;
@@ -249,7 +249,7 @@
   }
 
   void test_privateMethod_instance() async {
-    await newFile(testPackageImplementationFilePath, content: r'''
+    newFile(testPackageImplementationFilePath, content: r'''
 import 'package:meta/meta.dart';
 class C {
   @internal void _f() {}
@@ -264,7 +264,7 @@
   }
 
   void test_privateMethod_static() async {
-    await newFile('$testPackageLibPath/src/foo.dart', content: r'''
+    newFile('$testPackageLibPath/src/foo.dart', content: r'''
 import 'package:meta/meta.dart';
 class C {
   @internal static void _f() {}
@@ -279,7 +279,7 @@
   }
 
   void test_privateMixin() async {
-    await newFile('$testPackageLibPath/src/foo.dart', content: r'''
+    newFile('$testPackageLibPath/src/foo.dart', content: r'''
 import 'package:meta/meta.dart';
 @internal mixin _One {}
 ''');
@@ -292,7 +292,7 @@
   }
 
   void test_privateTopLevelFunction() async {
-    await newFile('$testPackageLibPath/src/foo.dart', content: r'''
+    newFile('$testPackageLibPath/src/foo.dart', content: r'''
 import 'package:meta/meta.dart';
 @internal void _f() {}
 ''');
@@ -305,7 +305,7 @@
   }
 
   void test_privateTopLevelVariable() async {
-    await newFile('$testPackageLibPath/src/foo.dart', content: r'''
+    newFile('$testPackageLibPath/src/foo.dart', content: r'''
 import 'package:meta/meta.dart';
 @internal int _i = 1;
 ''');
@@ -318,7 +318,7 @@
   }
 
   void test_privateTypedef() async {
-    await newFile('$testPackageLibPath/src/foo.dart', content: r'''
+    newFile('$testPackageLibPath/src/foo.dart', content: r'''
 import 'package:meta/meta.dart';
 @internal typedef _T = void Function();
 ''');
@@ -331,7 +331,7 @@
   }
 
   void test_publicMethod_privateClass() async {
-    await newFile('$testPackageLibPath/src/foo.dart', content: r'''
+    newFile('$testPackageLibPath/src/foo.dart', content: r'''
 import 'package:meta/meta.dart';
 class _C {
   @internal void f() {}
@@ -345,7 +345,7 @@
   }
 
   void test_publicMethod_privateClass_static() async {
-    await newFile('$testPackageLibPath/src/foo.dart', content: r'''
+    newFile('$testPackageLibPath/src/foo.dart', content: r'''
 import 'package:meta/meta.dart';
 class _C {
   @internal static void f() {}
diff --git a/pkg/analyzer/test/src/diagnostics/subtype_of_sealed_class_test.dart b/pkg/analyzer/test/src/diagnostics/subtype_of_sealed_class_test.dart
index 3b2acfa..9322aa2 100644
--- a/pkg/analyzer/test/src/diagnostics/subtype_of_sealed_class_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/subtype_of_sealed_class_test.dart
@@ -28,7 +28,7 @@
       meta: true,
     );
 
-    await newFile('$workspaceRootPath/foo/lib/foo.dart', content: r'''
+    newFile('$workspaceRootPath/foo/lib/foo.dart', content: r'''
 import 'package:meta/meta.dart';
 @sealed class Foo {}
 ''');
@@ -156,7 +156,7 @@
   }
 
   test_withinPackageLibDirectory_OK() async {
-    await newFile('$testPackageLibPath/a.dart', content: r'''
+    newFile('$testPackageLibPath/a.dart', content: r'''
 import 'package:meta/meta.dart';
 @sealed class Foo {}
 ''');
@@ -172,7 +172,7 @@
   }
 
   test_withinPackageTestDirectory_OK() async {
-    await newFile('$testPackageLibPath/a.dart', content: r'''
+    newFile('$testPackageLibPath/a.dart', content: r'''
 import 'package:meta/meta.dart';
 @sealed class Foo {}
 ''');
@@ -198,7 +198,7 @@
 @sealed class Foo {}
 ''');
 
-    await newFile(partPath, content: r'''
+    newFile(partPath, content: r'''
 part of 'a.dart';
 class Bar1 extends Foo {}
 class Bar2 implements Foo {}
diff --git a/pkg/analyzer/test/src/summary2/ast_text_printer_test.dart b/pkg/analyzer/test/src/summary2/ast_text_printer_test.dart
index 0c61468..4adaadd 100644
--- a/pkg/analyzer/test/src/summary2/ast_text_printer_test.dart
+++ b/pkg/analyzer/test/src/summary2/ast_text_printer_test.dart
@@ -61,7 +61,7 @@
   }
 
   test_extensionOverride() async {
-    await assertParseCodeAndPrintAst(this, '''
+    assertParseCodeAndPrintAst(this, '''
 extension E on Object {
   int f() => 0;
 }
diff --git a/pkg/analyzer/test/verify_docs_test.dart b/pkg/analyzer/test/verify_docs_test.dart
index 6e5236c..975bbf2 100644
--- a/pkg/analyzer/test/verify_docs_test.dart
+++ b/pkg/analyzer/test/verify_docs_test.dart
@@ -44,11 +44,11 @@
     snippetPath = provider.pathContext.join(snippetDirPath, 'snippet.dart');
   }
 
-  void verify() async {
+  Future<void> verify() async {
     await verifyFolder(docFolder);
   }
 
-  void verifyFile(File file) async {
+  Future<void> verifyFile(File file) async {
     String content = file.readAsStringSync();
     List<String> lines = const LineSplitter().convert(content);
     List<String> codeLines = [];
@@ -73,7 +73,7 @@
     }
   }
 
-  void verifyFolder(Folder folder) async {
+  Future<void> verifyFolder(Folder folder) async {
     for (Resource child in folder.getChildren()) {
       if (child is File) {
         if (child.shortName.endsWith('.md')) {
@@ -85,7 +85,7 @@
     }
   }
 
-  void verifySnippet(File file, String snippet) async {
+  Future<void> verifySnippet(File file, String snippet) async {
     // TODO(brianwilkerson) When the files outside of 'src' contain only public
     //  API, write code to compute the list of imports so that new public API
     //  will automatically be allowed.
diff --git a/pkg/analyzer_cli/analysis_options.yaml b/pkg/analyzer_cli/analysis_options.yaml
index a6ec312..ee6055a 100644
--- a/pkg/analyzer_cli/analysis_options.yaml
+++ b/pkg/analyzer_cli/analysis_options.yaml
@@ -14,6 +14,7 @@
   rules:
     - avoid_single_cascade_in_expression_statements
     - avoid_unused_constructor_parameters
+    - await_only_futures
     - empty_statements
     - iterable_contains_unrelated_type
     - list_remove_unrelated_type
diff --git a/pkg/analyzer_plugin/analysis_options.yaml b/pkg/analyzer_plugin/analysis_options.yaml
index 42406ef..ac616cb 100644
--- a/pkg/analyzer_plugin/analysis_options.yaml
+++ b/pkg/analyzer_plugin/analysis_options.yaml
@@ -3,6 +3,7 @@
     implicit-casts: false
 linter:
   rules:
+    - await_only_futures
     - empty_statements
     - unnecessary_brace_in_string_interps
     #
diff --git a/pkg/dartdev/pubspec.yaml b/pkg/dartdev/pubspec.yaml
index ecc93eb..511826b 100644
--- a/pkg/dartdev/pubspec.yaml
+++ b/pkg/dartdev/pubspec.yaml
@@ -26,5 +26,5 @@
   usage: ^3.4.0
 
 dev_dependencies:
-  test: ^1.0.0
   pedantic: ^1.9.0
+  test: ^1.0.0
diff --git a/pkg/dartfix/analysis_options.yaml b/pkg/dartfix/analysis_options.yaml
index bfb45bf..4be2194 100644
--- a/pkg/dartfix/analysis_options.yaml
+++ b/pkg/dartfix/analysis_options.yaml
@@ -16,6 +16,7 @@
 
 linter:
   rules:
+    - await_only_futures
     - directives_ordering
     - empty_statements
     - unnecessary_brace_in_string_interps
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 53d5493..375ac5c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -1128,7 +1128,7 @@
     if (loader.target.context.options
         .isExperimentEnabledGlobally(ExperimentalFlag.valueClass)) {
       valueClass.transformComponent(
-          component, loader.coreTypes, loader.hierarchy);
+          component, loader.coreTypes, loader.hierarchy, environment);
       ticker.logMs("Lowered value classes");
     }
 
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index 6c237da..660c22a 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -257,4 +257,5 @@
 set_literals/disambiguation_rule: RuntimeError
 value_class/simple: RuntimeError # Expected
 value_class/value_extends_non_value: RuntimeError # Expected
-value_class/value_implements_non_value: RuntimeError # Expected
\ No newline at end of file
+value_class/value_implements_non_value: RuntimeError # Expected
+value_class/copy_with_call_sites: RuntimeError # Expected
\ No newline at end of file
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 825cdf1..07eb30c 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -255,3 +255,4 @@
 value_class/simple: RuntimeError # Expected
 value_class/value_extends_non_value: RuntimeError # Expected
 value_class/value_implements_non_value: RuntimeError # Expected
+value_class/copy_with_call_sites: RuntimeError # Expected
\ No newline at end of file
diff --git a/pkg/front_end/testcases/value_class/copy_with_call_sites.dart b/pkg/front_end/testcases/value_class/copy_with_call_sites.dart
new file mode 100644
index 0000000..031deb0
--- /dev/null
+++ b/pkg/front_end/testcases/value_class/copy_with_call_sites.dart
@@ -0,0 +1,23 @@
+// 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 'value_class_support_lib.dart';
+
+class Animal {
+  final int numberOfLegs;
+  Animal({required this.numberOfLegs});
+}
+
+@valueClass
+class Cat extends Animal {
+  final int numberOfWhiskers;
+}
+
+main() {
+ Cat cat = new Cat(numberOfWhiskers: 20, numberOfLegs: 4);
+ (cat as dynamic).copyWith(numberOfWhiskers: 4);
+}
+
+
+
diff --git a/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.outline.expect b/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.outline.expect
new file mode 100644
index 0000000..0e4993f
--- /dev/null
+++ b/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.outline.expect
@@ -0,0 +1,34 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "value_class_support_lib.dart" as val;
+
+import "org-dartlang-testcase:///value_class_support_lib.dart";
+
+class Animal extends core::Object {
+  final field core::int numberOfLegs;
+  constructor •({required core::int numberOfLegs}) → self::Animal
+    ;
+}
+@val::valueClass
+class Cat extends self::Animal {
+  final field core::int numberOfWhiskers;
+  synthetic constructor •() → self::Cat
+    ;
+}
+static method main() → dynamic
+  ;
+
+library /*isNonNullableByDefault*/;
+import self as val;
+import "dart:core" as core;
+
+class JenkinsSmiHash extends core::Object {
+  synthetic constructor •() → val::JenkinsSmiHash
+    ;
+  static method combine(core::int hash, core::int value) → core::int
+    ;
+  static method finish(core::int hash) → core::int
+    ;
+}
+static const field core::String valueClass = "valueClass";
diff --git a/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.strong.expect b/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.strong.expect
new file mode 100644
index 0000000..dd3b9ec
--- /dev/null
+++ b/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.strong.expect
@@ -0,0 +1,72 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/value_class/copy_with_call_sites.dart:18:20: Error: No named parameter with the name 'numberOfWhiskers'.
+//  Cat cat = new Cat(numberOfWhiskers: 20, numberOfLegs: 4);
+//                    ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/value_class/copy_with_call_sites.dart:13:7: Context: The class 'Cat' has a constructor that takes no arguments.
+// class Cat extends Animal {
+//       ^
+//
+// pkg/front_end/testcases/value_class/copy_with_call_sites.dart:14:13: Error: Final field 'numberOfWhiskers' is not initialized.
+// Try to initialize the field in the declaration or in every constructor.
+//   final int numberOfWhiskers;
+//             ^^^^^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+import "value_class_support_lib.dart" as val;
+
+import "org-dartlang-testcase:///value_class_support_lib.dart";
+
+class Animal extends core::Object {
+  final field core::int numberOfLegs;
+  constructor •({required core::int numberOfLegs = #C1}) → self::Animal
+    : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
+    ;
+}
+class Cat extends self::Animal {
+  final field core::int numberOfWhiskers = null;
+  synthetic constructor •({required core::int numberOfWhiskers, core::int numberOfLegs}) → self::Cat
+    : self::Cat::numberOfWhiskers = numberOfWhiskers, super self::Animal::•(numberOfLegs)
+    ;
+  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+    return other is self::Cat && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Cat}.{self::Animal::numberOfLegs}) && this.{self::Cat::numberOfWhiskers}.{core::num::==}(other{self::Cat}.{self::Cat::numberOfWhiskers});
+  get /*isNullableByDefault*/ hashCode() → core::int
+    return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine(val::JenkinsSmiHash::combine("org-dartlang-testcase:///copy_with_call_sites.dartCat".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}), this.{self::Cat::numberOfWhiskers}.{core::num::hashCode}));
+  method /*isNullableByDefault*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
+    return new self::Cat::•(numberOfLegs: numberOfLegs, numberOfWhiskers: numberOfWhiskers);
+}
+static method main() → dynamic {
+  self::Cat cat = invalid-expression "pkg/front_end/testcases/value_class/copy_with_call_sites.dart:18:20: Error: No named parameter with the name 'numberOfWhiskers'.
+ Cat cat = new Cat(numberOfWhiskers: 20, numberOfLegs: 4);
+                   ^^^^^^^^^^^^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} self::Cat;
+  let final dynamic #t1 = cat as{ForNonNullableByDefault} dynamic in #t1.copyWith(numberOfWhiskers: 4, numberOfLegs: #t1.numberOfLegs);
+}
+
+library /*isNonNullableByDefault*/;
+import self as val;
+import "dart:core" as core;
+
+class JenkinsSmiHash extends core::Object {
+  synthetic constructor •() → val::JenkinsSmiHash
+    : super core::Object::•()
+    ;
+  static method combine(core::int hash, core::int value) → core::int {
+    hash = 536870911.{core::int::&}(hash.{core::num::+}(value));
+    hash = 536870911.{core::int::&}(hash.{core::num::+}(524287.{core::int::&}(hash).{core::int::<<}(10)));
+    return hash.{core::int::^}(hash.{core::int::>>}(6));
+  }
+  static method finish(core::int hash) → core::int {
+    hash = 536870911.{core::int::&}(hash.{core::num::+}(67108863.{core::int::&}(hash).{core::int::<<}(3)));
+    hash = hash.{core::int::^}(hash.{core::int::>>}(11));
+    return 536870911.{core::int::&}(hash.{core::num::+}(16383.{core::int::&}(hash).{core::int::<<}(15)));
+  }
+}
+static const field core::String valueClass = #C2;
+
+constants  {
+  #C1 = null
+  #C2 = "valueClass"
+}
diff --git a/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.strong.transformed.expect
new file mode 100644
index 0000000..f361669
--- /dev/null
+++ b/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.strong.transformed.expect
@@ -0,0 +1,72 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/value_class/copy_with_call_sites.dart:18:20: Error: No named parameter with the name 'numberOfWhiskers'.
+//  Cat cat = new Cat(numberOfWhiskers: 20, numberOfLegs: 4);
+//                    ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/value_class/copy_with_call_sites.dart:13:7: Context: The class 'Cat' has a constructor that takes no arguments.
+// class Cat extends Animal {
+//       ^
+//
+// pkg/front_end/testcases/value_class/copy_with_call_sites.dart:14:13: Error: Final field 'numberOfWhiskers' is not initialized.
+// Try to initialize the field in the declaration or in every constructor.
+//   final int numberOfWhiskers;
+//             ^^^^^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+import "value_class_support_lib.dart" as val;
+
+import "org-dartlang-testcase:///value_class_support_lib.dart";
+
+class Animal extends core::Object {
+  final field core::int numberOfLegs;
+  constructor •({required core::int numberOfLegs = #C1}) → self::Animal
+    : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
+    ;
+}
+class Cat extends self::Animal {
+  final field core::int numberOfWhiskers = null;
+  synthetic constructor •({required core::int numberOfWhiskers, core::int numberOfLegs}) → self::Cat
+    : self::Cat::numberOfWhiskers = numberOfWhiskers, super self::Animal::•(numberOfLegs)
+    ;
+  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+    return other is self::Cat && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Cat}.{self::Animal::numberOfLegs}) && this.{self::Cat::numberOfWhiskers}.{core::num::==}(other{self::Cat}.{self::Cat::numberOfWhiskers});
+  get /*isNullableByDefault*/ hashCode() → core::int
+    return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine(val::JenkinsSmiHash::combine("org-dartlang-testcase:///copy_with_call_sites.dartCat".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}), this.{self::Cat::numberOfWhiskers}.{core::num::hashCode}));
+  method /*isNullableByDefault*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
+    return new self::Cat::•(numberOfLegs: numberOfLegs, numberOfWhiskers: numberOfWhiskers);
+}
+static method main() → dynamic {
+  self::Cat cat = invalid-expression "pkg/front_end/testcases/value_class/copy_with_call_sites.dart:18:20: Error: No named parameter with the name 'numberOfWhiskers'.
+ Cat cat = new Cat(numberOfWhiskers: 20, numberOfLegs: 4);
+                   ^^^^^^^^^^^^^^^^";
+  let final dynamic #t1 = cat as{ForNonNullableByDefault} dynamic in #t1.copyWith(numberOfWhiskers: 4, numberOfLegs: #t1.numberOfLegs);
+}
+
+library /*isNonNullableByDefault*/;
+import self as val;
+import "dart:core" as core;
+
+class JenkinsSmiHash extends core::Object {
+  synthetic constructor •() → val::JenkinsSmiHash
+    : super core::Object::•()
+    ;
+  static method combine(core::int hash, core::int value) → core::int {
+    hash = 536870911.{core::int::&}(hash.{core::num::+}(value));
+    hash = 536870911.{core::int::&}(hash.{core::num::+}(524287.{core::int::&}(hash).{core::int::<<}(10)));
+    return hash.{core::int::^}(hash.{core::int::>>}(6));
+  }
+  static method finish(core::int hash) → core::int {
+    hash = 536870911.{core::int::&}(hash.{core::num::+}(67108863.{core::int::&}(hash).{core::int::<<}(3)));
+    hash = hash.{core::int::^}(hash.{core::int::>>}(11));
+    return 536870911.{core::int::&}(hash.{core::num::+}(16383.{core::int::&}(hash).{core::int::<<}(15)));
+  }
+}
+static const field core::String valueClass = #C2;
+
+constants  {
+  #C1 = null
+  #C2 = "valueClass"
+}
diff --git a/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.textual_outline.expect b/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.textual_outline.expect
new file mode 100644
index 0000000..93a182d
--- /dev/null
+++ b/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+import 'value_class_support_lib.dart';
+
+class Animal {
+  final int numberOfLegs;
+  Animal({required this.numberOfLegs});
+}
+
+@valueClass
+class Cat extends Animal {
+  final int numberOfWhiskers;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ce2b2e3
--- /dev/null
+++ b/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+import 'value_class_support_lib.dart';
+
+class Animal {
+  Animal({required this.numberOfLegs});
+  final int numberOfLegs;
+}
+
+@valueClass
+class Cat extends Animal {
+  final int numberOfWhiskers;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.weak.expect b/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.weak.expect
new file mode 100644
index 0000000..dd3b9ec
--- /dev/null
+++ b/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.weak.expect
@@ -0,0 +1,72 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/value_class/copy_with_call_sites.dart:18:20: Error: No named parameter with the name 'numberOfWhiskers'.
+//  Cat cat = new Cat(numberOfWhiskers: 20, numberOfLegs: 4);
+//                    ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/value_class/copy_with_call_sites.dart:13:7: Context: The class 'Cat' has a constructor that takes no arguments.
+// class Cat extends Animal {
+//       ^
+//
+// pkg/front_end/testcases/value_class/copy_with_call_sites.dart:14:13: Error: Final field 'numberOfWhiskers' is not initialized.
+// Try to initialize the field in the declaration or in every constructor.
+//   final int numberOfWhiskers;
+//             ^^^^^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+import "value_class_support_lib.dart" as val;
+
+import "org-dartlang-testcase:///value_class_support_lib.dart";
+
+class Animal extends core::Object {
+  final field core::int numberOfLegs;
+  constructor •({required core::int numberOfLegs = #C1}) → self::Animal
+    : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
+    ;
+}
+class Cat extends self::Animal {
+  final field core::int numberOfWhiskers = null;
+  synthetic constructor •({required core::int numberOfWhiskers, core::int numberOfLegs}) → self::Cat
+    : self::Cat::numberOfWhiskers = numberOfWhiskers, super self::Animal::•(numberOfLegs)
+    ;
+  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+    return other is self::Cat && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Cat}.{self::Animal::numberOfLegs}) && this.{self::Cat::numberOfWhiskers}.{core::num::==}(other{self::Cat}.{self::Cat::numberOfWhiskers});
+  get /*isNullableByDefault*/ hashCode() → core::int
+    return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine(val::JenkinsSmiHash::combine("org-dartlang-testcase:///copy_with_call_sites.dartCat".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}), this.{self::Cat::numberOfWhiskers}.{core::num::hashCode}));
+  method /*isNullableByDefault*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
+    return new self::Cat::•(numberOfLegs: numberOfLegs, numberOfWhiskers: numberOfWhiskers);
+}
+static method main() → dynamic {
+  self::Cat cat = invalid-expression "pkg/front_end/testcases/value_class/copy_with_call_sites.dart:18:20: Error: No named parameter with the name 'numberOfWhiskers'.
+ Cat cat = new Cat(numberOfWhiskers: 20, numberOfLegs: 4);
+                   ^^^^^^^^^^^^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} self::Cat;
+  let final dynamic #t1 = cat as{ForNonNullableByDefault} dynamic in #t1.copyWith(numberOfWhiskers: 4, numberOfLegs: #t1.numberOfLegs);
+}
+
+library /*isNonNullableByDefault*/;
+import self as val;
+import "dart:core" as core;
+
+class JenkinsSmiHash extends core::Object {
+  synthetic constructor •() → val::JenkinsSmiHash
+    : super core::Object::•()
+    ;
+  static method combine(core::int hash, core::int value) → core::int {
+    hash = 536870911.{core::int::&}(hash.{core::num::+}(value));
+    hash = 536870911.{core::int::&}(hash.{core::num::+}(524287.{core::int::&}(hash).{core::int::<<}(10)));
+    return hash.{core::int::^}(hash.{core::int::>>}(6));
+  }
+  static method finish(core::int hash) → core::int {
+    hash = 536870911.{core::int::&}(hash.{core::num::+}(67108863.{core::int::&}(hash).{core::int::<<}(3)));
+    hash = hash.{core::int::^}(hash.{core::int::>>}(11));
+    return 536870911.{core::int::&}(hash.{core::num::+}(16383.{core::int::&}(hash).{core::int::<<}(15)));
+  }
+}
+static const field core::String valueClass = #C2;
+
+constants  {
+  #C1 = null
+  #C2 = "valueClass"
+}
diff --git a/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.weak.transformed.expect
new file mode 100644
index 0000000..f361669
--- /dev/null
+++ b/pkg/front_end/testcases/value_class/copy_with_call_sites.dart.weak.transformed.expect
@@ -0,0 +1,72 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/value_class/copy_with_call_sites.dart:18:20: Error: No named parameter with the name 'numberOfWhiskers'.
+//  Cat cat = new Cat(numberOfWhiskers: 20, numberOfLegs: 4);
+//                    ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/value_class/copy_with_call_sites.dart:13:7: Context: The class 'Cat' has a constructor that takes no arguments.
+// class Cat extends Animal {
+//       ^
+//
+// pkg/front_end/testcases/value_class/copy_with_call_sites.dart:14:13: Error: Final field 'numberOfWhiskers' is not initialized.
+// Try to initialize the field in the declaration or in every constructor.
+//   final int numberOfWhiskers;
+//             ^^^^^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+import "value_class_support_lib.dart" as val;
+
+import "org-dartlang-testcase:///value_class_support_lib.dart";
+
+class Animal extends core::Object {
+  final field core::int numberOfLegs;
+  constructor •({required core::int numberOfLegs = #C1}) → self::Animal
+    : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
+    ;
+}
+class Cat extends self::Animal {
+  final field core::int numberOfWhiskers = null;
+  synthetic constructor •({required core::int numberOfWhiskers, core::int numberOfLegs}) → self::Cat
+    : self::Cat::numberOfWhiskers = numberOfWhiskers, super self::Animal::•(numberOfLegs)
+    ;
+  operator /*isNullableByDefault*/ ==(core::Object other) → core::bool
+    return other is self::Cat && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Cat}.{self::Animal::numberOfLegs}) && this.{self::Cat::numberOfWhiskers}.{core::num::==}(other{self::Cat}.{self::Cat::numberOfWhiskers});
+  get /*isNullableByDefault*/ hashCode() → core::int
+    return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine(val::JenkinsSmiHash::combine("org-dartlang-testcase:///copy_with_call_sites.dartCat".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}), this.{self::Cat::numberOfWhiskers}.{core::num::hashCode}));
+  method /*isNullableByDefault*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
+    return new self::Cat::•(numberOfLegs: numberOfLegs, numberOfWhiskers: numberOfWhiskers);
+}
+static method main() → dynamic {
+  self::Cat cat = invalid-expression "pkg/front_end/testcases/value_class/copy_with_call_sites.dart:18:20: Error: No named parameter with the name 'numberOfWhiskers'.
+ Cat cat = new Cat(numberOfWhiskers: 20, numberOfLegs: 4);
+                   ^^^^^^^^^^^^^^^^";
+  let final dynamic #t1 = cat as{ForNonNullableByDefault} dynamic in #t1.copyWith(numberOfWhiskers: 4, numberOfLegs: #t1.numberOfLegs);
+}
+
+library /*isNonNullableByDefault*/;
+import self as val;
+import "dart:core" as core;
+
+class JenkinsSmiHash extends core::Object {
+  synthetic constructor •() → val::JenkinsSmiHash
+    : super core::Object::•()
+    ;
+  static method combine(core::int hash, core::int value) → core::int {
+    hash = 536870911.{core::int::&}(hash.{core::num::+}(value));
+    hash = 536870911.{core::int::&}(hash.{core::num::+}(524287.{core::int::&}(hash).{core::int::<<}(10)));
+    return hash.{core::int::^}(hash.{core::int::>>}(6));
+  }
+  static method finish(core::int hash) → core::int {
+    hash = 536870911.{core::int::&}(hash.{core::num::+}(67108863.{core::int::&}(hash).{core::int::<<}(3)));
+    hash = hash.{core::int::^}(hash.{core::int::>>}(11));
+    return 536870911.{core::int::&}(hash.{core::num::+}(16383.{core::int::&}(hash).{core::int::<<}(15)));
+  }
+}
+static const field core::String valueClass = #C2;
+
+constants  {
+  #C1 = null
+  #C2 = "valueClass"
+}
diff --git a/pkg/front_end/testcases/weak.status b/pkg/front_end/testcases/weak.status
index fee0310..eae95b4 100644
--- a/pkg/front_end/testcases/weak.status
+++ b/pkg/front_end/testcases/weak.status
@@ -75,4 +75,5 @@
 nnbd_mixed/never_opt_out: TypeCheckError
 value_class/simple: RuntimeError # Expected
 value_class/value_extends_non_value: RuntimeError # Expected
-value_class/value_implements_non_value: RuntimeError # Expected
\ No newline at end of file
+value_class/value_implements_non_value: RuntimeError # Expected
+value_class/copy_with_call_sites: RuntimeError # Expected
\ No newline at end of file
diff --git a/pkg/kernel/lib/transformations/scanner.dart b/pkg/kernel/lib/transformations/scanner.dart
index 6d4a690..ce4b9fc 100644
--- a/pkg/kernel/lib/transformations/scanner.dart
+++ b/pkg/kernel/lib/transformations/scanner.dart
@@ -11,7 +11,7 @@
 }
 
 class ScanResult<X extends TreeNode, Y extends TreeNode> {
-  Map<X, ScanResult<Y, TreeNode>> targets;
+  Map<X, ScanResult<Y, TreeNode>> targets = new Map();
   Map<X, ScanError> errors;
 }
 
@@ -26,11 +26,12 @@
 
   ScanResult<Class, Y> scan(TreeNode node) {
     ScanResult<Class, Y> result = new ScanResult();
-    result.targets = new Map();
 
     if (node is Class) {
       if (predicate(node)) {
         result.targets[node] = next?.scan(node);
+        // TODO(dmitryas): set result.errors when specification is landed,
+        //  same with all other places where targets is set
       }
     } else if (node is Library) {
       _scanLibrary(node, result);
@@ -65,12 +66,9 @@
 
   ScanResult<Field, Y> scan(TreeNode node) {
     ScanResult<Field, Y> result = new ScanResult();
-    result.targets = new Map();
 
     if (node is Field) {
-      if (predicate(node)) {
-        result.targets[node] = next?.scan(node);
-      }
+      _scanField(node, result);
     } else if (node is Class) {
       _scanClass(node, result);
     } else if (node is Library) {
@@ -82,11 +80,15 @@
     return result;
   }
 
+  void _scanField(Field field, ScanResult<Field, Y> result) {
+    if (predicate(field)) {
+      result.targets[field] = next?.scan(field);
+    }
+  }
+
   void _scanClass(Class cls, ScanResult<Field, Y> result) {
     for (Field field in cls.fields) {
-      if (predicate(field)) {
-        result.targets[field] = next?.scan(field);
-      }
+      _scanField(field, result);
     }
   }
 
@@ -95,9 +97,7 @@
       _scanClass(cls, result);
     }
     for (Field field in library.fields) {
-      if (predicate(field)) {
-        result.targets[field] = next?.scan(field);
-      }
+      _scanField(field, result);
     }
   }
 
@@ -108,6 +108,57 @@
   }
 }
 
+abstract class MemberScanner<Y extends TreeNode> implements Scanner<Member, Y> {
+  final Scanner<Y, TreeNode> next;
+
+  MemberScanner(this.next);
+
+  bool predicate(Member node);
+
+  ScanResult<Member, Y> scan(TreeNode node) {
+    ScanResult<Member, Y> result = new ScanResult();
+
+    if (node is Member) {
+      _scanMember(node, result);
+    } else if (node is Class) {
+      _scanClass(node, result);
+    } else if (node is Library) {
+      _scanLibrary(node, result);
+    } else if (node is Component) {
+      _scanComponent(node, result);
+    }
+
+    return result;
+  }
+
+  void _scanMember(Member member, ScanResult<Member, Y> result) {
+    if (predicate(member)) {
+      result.targets[member] = next?.scan(member);
+    }
+  }
+
+  void _scanClass(Class cls, ScanResult<Member, Y> result) {
+    for (Member member in cls.members) {
+      _scanMember(member, result);
+    }
+  }
+
+  void _scanLibrary(Library library, ScanResult<Member, Y> result) {
+    for (Class cls in library.classes) {
+      _scanClass(cls, result);
+    }
+    for (Member member in library.members) {
+      _scanMember(member, result);
+    }
+  }
+
+  void _scanComponent(Component component, ScanResult<Member, Y> result) {
+    for (Library library in component.libraries) {
+      _scanLibrary(library, result);
+    }
+  }
+}
+
 abstract class ProcedureScanner<Y extends TreeNode>
     implements Scanner<Procedure, Y> {
   final Scanner<Y, TreeNode> next;
@@ -118,12 +169,9 @@
 
   ScanResult<Procedure, Y> scan(TreeNode node) {
     ScanResult<Procedure, Y> result = new ScanResult();
-    result.targets = new Map();
 
     if (node is Procedure) {
-      if (predicate(node)) {
-        result.targets[node] = next?.scan(node);
-      }
+      _scanProcedure(node, result);
     } else if (node is Class) {
       _scanClass(node, result);
     } else if (node is Library) {
@@ -135,11 +183,15 @@
     return result;
   }
 
+  void _scanProcedure(Procedure procedure, ScanResult<Procedure, Y> result) {
+    if (predicate(procedure)) {
+      result.targets[procedure] = next?.scan(procedure);
+    }
+  }
+
   void _scanClass(Class cls, ScanResult<Procedure, Y> result) {
     for (Procedure procedure in cls.procedures) {
-      if (predicate(procedure)) {
-        result.targets[procedure] = next?.scan(procedure);
-      }
+      _scanProcedure(procedure, result);
     }
   }
 
@@ -148,9 +200,7 @@
       _scanClass(cls, result);
     }
     for (Procedure procedure in library.procedures) {
-      if (predicate(procedure)) {
-        result.targets[procedure] = next?.scan(procedure);
-      }
+      _scanProcedure(procedure, result);
     }
   }
 
@@ -160,3 +210,51 @@
     }
   }
 }
+
+abstract class ExpressionScanner<Y extends TreeNode>
+    extends RecursiveVisitor<void> implements Scanner<Expression, Y> {
+  final Scanner<Y, TreeNode> next;
+  ScanResult<Expression, Y> _result;
+
+  ExpressionScanner(this.next);
+
+  bool predicate(Expression node);
+
+  ScanResult<Expression, Y> scan(TreeNode node) {
+    ScanResult<Expression, Y> result = _result = new ScanResult();
+    node.accept(this);
+    _result = null;
+    return result;
+  }
+
+  void visitExpression(Expression node) {
+    if (predicate(node)) {
+      _result.targets[node] = next?.scan(node);
+      // TODO: Update result.errors.
+    }
+  }
+}
+
+abstract class MethodInvocationScanner<Y extends TreeNode>
+    extends RecursiveVisitor<void> implements Scanner<MethodInvocation, Y> {
+  final Scanner<Y, TreeNode> next;
+  ScanResult<MethodInvocation, Y> _result;
+
+  MethodInvocationScanner(this.next);
+
+  bool predicate(MethodInvocation node);
+
+  ScanResult<MethodInvocation, Y> scan(TreeNode node) {
+    ScanResult<MethodInvocation, Y> result = _result = new ScanResult();
+    node.accept(this);
+    _result = null;
+    return result;
+  }
+
+  void visitMethodInvocation(MethodInvocation node) {
+    if (predicate(node)) {
+      _result.targets[node] = next?.scan(node);
+      // TODO: Update result.errors.
+    }
+  }
+}
diff --git a/pkg/kernel/lib/transformations/value_class.dart b/pkg/kernel/lib/transformations/value_class.dart
index c760a89..c616cea 100644
--- a/pkg/kernel/lib/transformations/value_class.dart
+++ b/pkg/kernel/lib/transformations/value_class.dart
@@ -4,6 +4,8 @@
 
 library kernel.transformations.value_class;
 
+import 'package:kernel/type_environment.dart';
+
 import '../ast.dart';
 import '../kernel.dart';
 import '../core_types.dart' show CoreTypes;
@@ -13,18 +15,7 @@
 class ValueClassScanner extends ClassScanner<Null> {
   ValueClassScanner() : super(null);
 
-  bool predicate(Class node) {
-    for (Expression annotation in node.annotations) {
-      if (annotation is ConstantExpression &&
-          annotation.constant is StringConstant) {
-        StringConstant constant = annotation.constant;
-        if (constant.value == 'valueClass') {
-          return true;
-        }
-      }
-    }
-    return false;
-  }
+  bool predicate(Class node) => isValueClass(node);
 }
 
 class JenkinsClassScanner extends ClassScanner<Procedure> {
@@ -43,17 +34,48 @@
   }
 }
 
-void transformComponent(
-    Component node, CoreTypes coreTypes, ClassHierarchy hierarchy) {
-  ValueClassScanner scanner = new ValueClassScanner();
-  ScanResult<Class, Null> valueClasses = scanner.scan(node);
-  for (Class valueClass in valueClasses.targets.keys) {
-    transformValueClass(valueClass, coreTypes, hierarchy);
+class AllMemberScanner extends MemberScanner<MethodInvocation> {
+  AllMemberScanner(Scanner<MethodInvocation, TreeNode> next) : super(next);
+
+  bool predicate(Member member) => true;
+}
+
+// Scans and matches all copyWith invocations were the reciever is _ as dynamic
+// It will filter out the results that are not value classes afterwards
+class ValueClassCopyWithScanner extends MethodInvocationScanner<Null> {
+  ValueClassCopyWithScanner() : super(null);
+
+  // The matching construct followed in unit-tests is:
+  // @valueClass V {}
+  // V v;
+  // (v as dynamic).copyWith() as V
+  bool predicate(MethodInvocation node) {
+    return node.name.name == "copyWith" &&
+        _isValueClassAsConstruct(node.receiver);
+  }
+
+  bool _isValueClassAsConstruct(Expression node) {
+    return node is AsExpression && node.type is DynamicType;
   }
 }
 
-void transformValueClass(
-    Class cls, CoreTypes coreTypes, ClassHierarchy hierarchy) {
+void transformComponent(Component node, CoreTypes coreTypes,
+    ClassHierarchy hierarchy, TypeEnvironment typeEnvironment) {
+  ValueClassScanner scanner = new ValueClassScanner();
+  ScanResult<Class, Null> valueClasses = scanner.scan(node);
+  for (Class valueClass in valueClasses.targets.keys) {
+    transformValueClass(valueClass, coreTypes, hierarchy, typeEnvironment);
+  }
+
+  treatCopyWithCallSites(node, coreTypes, typeEnvironment, hierarchy);
+
+  for (Class valueClass in valueClasses.targets.keys) {
+    removeValueClassAnnotation(valueClass);
+  }
+}
+
+void transformValueClass(Class cls, CoreTypes coreTypes,
+    ClassHierarchy hierarchy, TypeEnvironment typeEnvironment) {
   List<VariableDeclaration> allVariables = queryAllInstanceVariables(cls);
   Constructor syntheticConstructor = null;
   for (Constructor constructor in cls.constructors) {
@@ -65,8 +87,8 @@
   addConstructor(cls, coreTypes, syntheticConstructor);
   addEqualsOperator(cls, coreTypes, hierarchy, allVariables.toList());
   addHashCode(cls, coreTypes, hierarchy, allVariables.toList());
-  addCopyWith(
-      cls, coreTypes, hierarchy, allVariables.toList(), syntheticConstructor);
+  addCopyWith(cls, coreTypes, hierarchy, allVariables.toList(),
+      syntheticConstructor, typeEnvironment);
 }
 
 void addConstructor(
@@ -103,21 +125,6 @@
     ..addAll(ownFields.values)
     ..addAll(superParameters);
   syntheticConstructor.initializers = initializersConstructor;
-
-  int valueClassAnnotationIndex;
-  for (int annotationIndex = 0;
-      annotationIndex < cls.annotations.length;
-      annotationIndex++) {
-    Expression annotation = cls.annotations[annotationIndex];
-    if (annotation is ConstantExpression &&
-        annotation.constant is StringConstant) {
-      StringConstant constant = annotation.constant;
-      if (constant.value == 'valueClass') {
-        valueClassAnnotationIndex = annotationIndex;
-      }
-    }
-  }
-  cls.annotations.removeAt(valueClassAnnotationIndex);
 }
 
 void addEqualsOperator(Class cls, CoreTypes coreTypes, ClassHierarchy hierarchy,
@@ -245,8 +252,13 @@
     ..fileOffset = cls.fileOffset);
 }
 
-void addCopyWith(Class cls, CoreTypes coreTypes, ClassHierarchy hierarchy,
-    List<VariableDeclaration> allVariables, Constructor syntheticConstructor) {
+void addCopyWith(
+    Class cls,
+    CoreTypes coreTypes,
+    ClassHierarchy hierarchy,
+    List<VariableDeclaration> allVariables,
+    Constructor syntheticConstructor,
+    TypeEnvironment typeEnvironment) {
   Map<VariableDeclaration, Member> targetsEquals = new Map();
   Map<VariableDeclaration, Member> targets = new Map();
   for (VariableDeclaration variable in allVariables) {
@@ -291,3 +303,98 @@
         ..addAll(cls.fields.map<VariableDeclaration>(
             (f) => VariableDeclaration(f.name.text, type: f.type)));
 }
+
+void removeValueClassAnnotation(Class cls) {
+  int valueClassAnnotationIndex;
+  for (int annotationIndex = 0;
+      annotationIndex < cls.annotations.length;
+      annotationIndex++) {
+    Expression annotation = cls.annotations[annotationIndex];
+    if (annotation is ConstantExpression &&
+        annotation.constant is StringConstant) {
+      StringConstant constant = annotation.constant;
+      if (constant.value == 'valueClass') {
+        valueClassAnnotationIndex = annotationIndex;
+      }
+    }
+  }
+  cls.annotations.removeAt(valueClassAnnotationIndex);
+}
+
+void treatCopyWithCallSites(Component component, CoreTypes coreTypes,
+    TypeEnvironment typeEnvironment, ClassHierarchy hierarchy) {
+  ValueClassCopyWithScanner valueCopyWithScanner =
+      new ValueClassCopyWithScanner();
+  AllMemberScanner copyWithScanner = AllMemberScanner(valueCopyWithScanner);
+  ScanResult<Member, MethodInvocation> copyWithCallSites =
+      copyWithScanner.scan(component);
+  for (Member memberWithCopyWith in copyWithCallSites.targets.keys) {
+    if (copyWithCallSites.targets[memberWithCopyWith].targets != null) {
+      StaticTypeContext staticTypeContext =
+          StaticTypeContext(memberWithCopyWith, typeEnvironment);
+      for (MethodInvocation copyWithCall
+          in copyWithCallSites.targets[memberWithCopyWith].targets.keys) {
+        AsExpression receiver = copyWithCall.receiver as AsExpression;
+
+        Expression valueClassInstance = receiver.operand;
+        DartType valueClassType =
+            valueClassInstance.getStaticType(staticTypeContext);
+        if (valueClassType is InterfaceType) {
+          Class valueClass = valueClassType.classNode;
+          if (isValueClass(valueClass)) {
+            treatCopyWithCallSite(
+                valueClass, copyWithCall, coreTypes, hierarchy);
+          }
+        }
+      }
+    }
+  }
+}
+
+void treatCopyWithCallSite(Class valueClass, MethodInvocation copyWithCall,
+    CoreTypes coreTypes, ClassHierarchy hierarchy) {
+  Map<String, Expression> preTransformationArguments = new Map();
+  for (NamedExpression argument in copyWithCall.arguments.named) {
+    preTransformationArguments[argument.name] = argument.value;
+  }
+  Constructor syntheticConstructor;
+  for (Constructor constructor in valueClass.constructors) {
+    if (constructor.isSynthetic) {
+      syntheticConstructor = constructor;
+    }
+  }
+  List<VariableDeclaration> allArguments =
+      syntheticConstructor.function.namedParameters;
+
+  VariableDeclaration letVariable =
+      VariableDeclaration.forValue(copyWithCall.receiver);
+  Arguments postTransformationArguments = Arguments.empty();
+  for (VariableDeclaration argument in allArguments) {
+    if (preTransformationArguments.containsKey(argument.name)) {
+      postTransformationArguments.named.add(NamedExpression(
+          argument.name, preTransformationArguments[argument.name])
+        ..parent = postTransformationArguments);
+    } else {
+      postTransformationArguments.named.add(NamedExpression(argument.name,
+          PropertyGet(VariableGet(letVariable), Name(argument.name)))
+        ..parent = postTransformationArguments);
+    }
+  }
+  copyWithCall.replaceWith(Let(
+      letVariable,
+      MethodInvocation(VariableGet(letVariable), Name("copyWith"),
+          postTransformationArguments)));
+}
+
+bool isValueClass(Class node) {
+  for (Expression annotation in node.annotations) {
+    if (annotation is ConstantExpression &&
+        annotation.constant is StringConstant) {
+      StringConstant constant = annotation.constant;
+      if (constant.value == "valueClass") {
+        return true;
+      }
+    }
+  }
+  return false;
+}
diff --git a/pkg/nnbd_migration/analysis_options.yaml b/pkg/nnbd_migration/analysis_options.yaml
index be53569..d38c130 100644
--- a/pkg/nnbd_migration/analysis_options.yaml
+++ b/pkg/nnbd_migration/analysis_options.yaml
@@ -16,6 +16,7 @@
 
 linter:
   rules:
+    - await_only_futures
     - empty_constructor_bodies
     - empty_statements
     - unnecessary_brace_in_string_interps
diff --git a/pkg/nnbd_migration/test/api_test.dart b/pkg/nnbd_migration/test/api_test.dart
index a54bf55..34fd139 100644
--- a/pkg/nnbd_migration/test/api_test.dart
+++ b/pkg/nnbd_migration/test/api_test.dart
@@ -55,7 +55,7 @@
         removeViaComments: removeViaComments,
         warnOnWeakCode: warnOnWeakCode);
     for (var path in input.keys) {
-      if (!(await session.getFile(path)).isPart) {
+      if (!(session.getFile(path)).isPart) {
         for (var unit in (await session.getResolvedLibrary(path)).units) {
           migration.prepareInput(unit);
         }
@@ -63,7 +63,7 @@
     }
     _betweenStages();
     for (var path in input.keys) {
-      if (!(await session.getFile(path)).isPart) {
+      if (!(session.getFile(path)).isPart) {
         for (var unit in (await session.getResolvedLibrary(path)).units) {
           migration.processInput(unit);
         }
@@ -71,7 +71,7 @@
     }
     _betweenStages();
     for (var path in input.keys) {
-      if (!(await session.getFile(path)).isPart) {
+      if (!(session.getFile(path)).isPart) {
         for (var unit in (await session.getResolvedLibrary(path)).units) {
           migration.finalizeInput(unit);
         }
diff --git a/pkg/nnbd_migration/test/migration_cli_test.dart b/pkg/nnbd_migration/test/migration_cli_test.dart
index 0d98a16..e9393df 100644
--- a/pkg/nnbd_migration/test/migration_cli_test.dart
+++ b/pkg/nnbd_migration/test/migration_cli_test.dart
@@ -444,7 +444,7 @@
         'external bool operator ==(dynamic other)');
     expect(newCoreLibText, isNot(oldCoreLibText));
     coreLib.writeAsStringSync(newCoreLibText);
-    var projectDir = await createProjectDir(simpleProject());
+    var projectDir = createProjectDir(simpleProject());
     await assertRunFailure([projectDir], cli: cli);
     var output = logger.stdoutBuffer.toString();
     expect(output, contains(messages.sdkNnbdOff));
@@ -464,7 +464,7 @@
         'external bool operator ==(dynamic other)');
     expect(newCoreLibText, isNot(oldCoreLibText));
     coreLib.writeAsStringSync(newCoreLibText);
-    var projectDir = await createProjectDir(simpleProject());
+    var projectDir = createProjectDir(simpleProject());
     await assertRunFailure([projectDir], cli: cli);
     var output = logger.stdoutBuffer.toString();
     expect(output, contains(messages.sdkNnbdOff));
@@ -564,7 +564,7 @@
 
   test_lifecycle_apply_changes() async {
     var projectContents = simpleProject();
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var cli = _createCli();
     var cliRunner = cli.decodeCommandLineArgs(
         _parseArgs(['--no-web-preview', '--apply-changes', projectDir]));
@@ -602,7 +602,7 @@
     - empty_constructor_bodies
 ''';
 
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var cliRunner = _createCli()
         .decodeCommandLineArgs(_parseArgs(['--no-web-preview', projectDir]));
     await cliRunner.run();
@@ -615,7 +615,7 @@
 
   test_lifecycle_contextdiscovery_handles_single() async {
     var projectContents = simpleProject();
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var cliRunner = _createCli()
         .decodeCommandLineArgs(_parseArgs(['--no-web-preview', projectDir]));
     await cliRunner.run();
@@ -626,7 +626,7 @@
 
   test_lifecycle_exception_handling() async {
     var projectContents = simpleProject(sourceText: 'main() { print(0); }');
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     injectArtificialException = true;
     await assertRunFailure([projectDir]);
     var errorOutput = logger.stderrBuffer.toString();
@@ -638,7 +638,7 @@
 
   test_lifecycle_exception_handling_ignore() async {
     var projectContents = simpleProject(sourceText: 'main() { print(0); }');
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     injectArtificialException = true;
     var cli = _createCli();
     await runWithPreviewServer(cli, ['--ignore-exceptions', projectDir],
@@ -659,7 +659,7 @@
   test_lifecycle_exception_handling_multiple() async {
     var projectContents =
         simpleProject(sourceText: 'main() { print(0); print(1); }');
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     injectArtificialException = true;
     await assertRunFailure([projectDir]);
     var errorOutput = logger.stderrBuffer.toString();
@@ -673,7 +673,7 @@
   test_lifecycle_exception_handling_with_error() async {
     var projectContents =
         simpleProject(sourceText: 'main() { print(0); unresolved; }');
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     injectArtificialException = true;
     await assertRunFailure(['--ignore-errors', projectDir]);
     var errorOutput = logger.stderrBuffer.toString();
@@ -686,7 +686,7 @@
     var projectContents = simpleProject(sourceText: '''
 int f() => null
 ''');
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     await assertRunFailure([projectDir]);
     var output = logger.stdoutBuffer.toString();
     expect(output, contains('1 analysis issue found'));
@@ -706,7 +706,7 @@
     var projectContents = simpleProject(sourceText: '''
 int? f() => null
 ''');
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var cli = _createCli();
     await runWithPreviewServer(cli, ['--ignore-errors', projectDir],
         (url) async {
@@ -722,7 +722,7 @@
 
   test_lifecycle_no_preview() async {
     var projectContents = simpleProject();
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var cliRunner = _createCli()
         .decodeCommandLineArgs(_parseArgs(['--no-web-preview', projectDir]));
     await cliRunner.run();
@@ -764,7 +764,7 @@
     }
 
     var projectContents = makeProject();
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var testPath =
         resourceProvider.pathContext.join(projectDir, 'lib', 'test.dart');
     var analyzeButDoNotMigratePath = resourceProvider.pathContext
@@ -789,7 +789,7 @@
 
   test_lifecycle_preview() async {
     var projectContents = simpleProject();
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var cli = _createCli();
     await runWithPreviewServer(cli, [projectDir], (url) async {
       var localhostAddressText = Platform.environment.containsKey('FORCE_IPV6')
@@ -806,7 +806,7 @@
 
   test_lifecycle_preview_add_hint() async {
     var projectContents = simpleProject(sourceText: 'int x;');
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var cli = _createCli();
     await runWithPreviewServer(cli, [projectDir], (url) async {
       expect(
@@ -835,7 +835,7 @@
 
   test_lifecycle_preview_apply_changes() async {
     var projectContents = simpleProject();
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var cli = _createCli();
     bool applyHookCalled = false;
     cli._onApplyHook = () {
@@ -861,7 +861,7 @@
   }
 
   test_lifecycle_preview_extra_forward_slash() async {
-    var projectDir = await createProjectDir(simpleProject());
+    var projectDir = createProjectDir(simpleProject());
     var cli = _createCli();
     await runWithPreviewServer(cli, [projectDir], (url) async {
       var uri = Uri.parse(url);
@@ -873,7 +873,7 @@
   test_lifecycle_preview_navigation_links() async {
     var projectContents = simpleProject(sourceText: 'int x;');
     projectContents['lib/src/test.dart'] = 'import "../test.dart"; int y = x;';
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var cli = _createCli();
     await runWithPreviewServer(cli, [projectDir], (url) async {
       expect(
@@ -907,7 +907,7 @@
 
   test_lifecycle_preview_navigation_tree() async {
     var projectContents = simpleProject(sourceText: 'int x;');
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var cli = _createCli();
     await runWithPreviewServer(cli, [projectDir], (url) async {
       expect(
@@ -940,7 +940,7 @@
 
   test_lifecycle_preview_on_host_any() async {
     var projectContents = simpleProject();
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var cli = _createCli()
       ..decodeCommandLineArgs(_parseArgs(['--preview-hostname=any']));
     await runWithPreviewServer(cli, [projectDir], (url) async {
@@ -953,7 +953,7 @@
 
   test_lifecycle_preview_region_link() async {
     var projectContents = simpleProject(sourceText: 'int x;');
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var cli = _createCli();
     await runWithPreviewServer(cli, [projectDir], (url) async {
       expect(
@@ -994,7 +994,7 @@
 
   test_lifecycle_preview_region_table_path() async {
     var projectContents = simpleProject(sourceText: 'int x;');
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var cli = _createCli();
     await runWithPreviewServer(cli, [projectDir], (url) async {
       expect(
@@ -1027,7 +1027,7 @@
   test_lifecycle_preview_rerun() async {
     var origSourceText = 'void f() {}';
     var projectContents = simpleProject(sourceText: origSourceText);
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var cli = _createCli();
     await runWithPreviewServer(cli, [projectDir], (url) async {
       await assertPreviewServerResponsive(url);
@@ -1049,7 +1049,7 @@
 
   test_lifecycle_preview_rerun_added_file() async {
     var projectContents = simpleProject();
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var cli = _createCli();
     await runWithPreviewServer(cli, [projectDir], (url) async {
       await assertPreviewServerResponsive(url);
@@ -1072,7 +1072,7 @@
 
   test_lifecycle_preview_rerun_deleted_file() async {
     var projectContents = simpleProject();
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var cli = _createCli();
     // Note: we use the summary to verify that the deletion was noticed
     var summaryPath = resourceProvider.convertPath('/summary.json');
@@ -1109,7 +1109,7 @@
   test_lifecycle_preview_rerun_with_new_analysis_errors() async {
     var origSourceText = 'void f(int i) {}';
     var projectContents = simpleProject(sourceText: origSourceText);
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var cli = _createCli();
     await runWithPreviewServer(cli, [projectDir], (url) async {
       await assertPreviewServerResponsive(url);
@@ -1143,9 +1143,9 @@
     var crazyFunctionName = 'crazyFunctionNameThatHasNeverBeenSeenBefore';
     var projectContents =
         simpleProject(sourceText: 'void $crazyFunctionName() {}');
-    var mainProjectDir = await createProjectDir(projectContents);
-    var otherProjectDir = await createProjectDir(projectContents,
-        posixPath: '/other_project_dir');
+    var mainProjectDir = createProjectDir(projectContents);
+    var otherProjectDir =
+        createProjectDir(projectContents, posixPath: '/other_project_dir');
     var cli = _createCli();
     await runWithPreviewServer(cli, [mainProjectDir], (url) async {
       await assertPreviewServerResponsive(url);
@@ -1174,7 +1174,7 @@
 
   test_lifecycle_preview_stack_hint_action() async {
     var projectContents = simpleProject(sourceText: 'int x;');
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var cli = _createCli();
     await runWithPreviewServer(cli, [projectDir], (url) async {
       expect(
@@ -1209,7 +1209,7 @@
 
   test_lifecycle_preview_stacktrace_link() async {
     var projectContents = simpleProject(sourceText: 'int x;');
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var cli = _createCli();
     await runWithPreviewServer(cli, [projectDir], (url) async {
       expect(
@@ -1246,7 +1246,7 @@
     var projectContents = simpleProject(sourceText: '''
 int f() => null;
 ''');
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     processManager._mockResult = ProcessResult(
         123 /* pid */,
         0 /* exitCode */,
@@ -1266,7 +1266,7 @@
     var projectContents = simpleProject(sourceText: '''
 int f() => null;
 ''');
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     processManager._mockResult = ProcessResult(
         123 /* pid */,
         0 /* exitCode */,
@@ -1287,7 +1287,7 @@
 
   test_lifecycle_summary() async {
     var projectContents = simpleProject();
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var summaryPath = resourceProvider.convertPath('/summary.json');
     var cliRunner = _createCli().decodeCommandLineArgs(
         _parseArgs(['--no-web-preview', '--summary', summaryPath, projectDir]));
@@ -1301,7 +1301,7 @@
 
   test_lifecycle_summary_does_not_double_count_hint_removals() async {
     var projectContents = simpleProject(sourceText: 'int/*?*/ x;');
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var summaryPath = resourceProvider.convertPath('/summary.json');
     var cliRunner = _createCli().decodeCommandLineArgs(
         _parseArgs(['--no-web-preview', '--summary', summaryPath, projectDir]));
@@ -1316,7 +1316,7 @@
 
   test_lifecycle_summary_rewritten_upon_rerun() async {
     var projectContents = simpleProject(sourceText: 'int f(int/*?*/ i) => i;');
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var cli = _createCli();
     var summaryPath = resourceProvider.convertPath('/summary.json');
     await runWithPreviewServer(cli, ['--summary', summaryPath, projectDir],
@@ -1351,7 +1351,7 @@
 import 'package:does_not/exist.dart';
 int f() => null;
 ''');
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     await assertRunFailure([projectDir]);
     var output = logger.stdoutBuffer.toString();
     expect(output, contains('1 analysis issue found'));
@@ -1464,7 +1464,7 @@
   test_package_config_does_not_exist() async {
     var projectContents = simpleProject()
       ..remove('.dart_tool/package_config.json');
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var cliRunner = _createCli().decodeCommandLineArgs(
         _parseArgs(['--no-web-preview', '--apply-changes', projectDir]));
     await cliRunner.run();
@@ -1489,7 +1489,7 @@
 }
 ''';
     var projectContents = simpleProject(packageConfigText: packageConfigText);
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var cliRunner = _createCli().decodeCommandLineArgs(
         _parseArgs(['--no-web-preview', '--apply-changes', projectDir]));
     await cliRunner.run();
@@ -1507,7 +1507,7 @@
 }
 ''';
     var projectContents = simpleProject(packageConfigText: packageConfigText);
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var cliRunner = _createCli().decodeCommandLineArgs(
         _parseArgs(['--no-web-preview', '--apply-changes', projectDir]));
     await cliRunner.run();
@@ -1531,7 +1531,7 @@
 }
 ''';
     var projectContents = simpleProject(packageConfigText: packageConfigText);
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var cliRunner = _createCli().decodeCommandLineArgs(
         _parseArgs(['--no-web-preview', '--apply-changes', projectDir]));
     await cliRunner.run();
@@ -1672,7 +1672,7 @@
     var projectContents = simpleProject()
       ..remove('pubspec.yaml')
       ..remove('.dart_tool/package_config.json');
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var cliRunner = _createCli().decodeCommandLineArgs(
         _parseArgs(['--no-web-preview', '--apply-changes', projectDir]));
     await cliRunner.run();
@@ -1690,7 +1690,7 @@
 environment:
   foo: 1
 ''');
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var cliRunner = _createCli().decodeCommandLineArgs(
         _parseArgs(['--no-web-preview', '--apply-changes', projectDir]));
     await cliRunner.run();
@@ -1710,7 +1710,7 @@
 environment: 1
 ''';
     var projectContents = simpleProject(pubspecText: pubspecText);
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var cliRunner = _createCli().decodeCommandLineArgs(
         _parseArgs(['--no-web-preview', '--apply-changes', projectDir]));
     await cliRunner.run();
@@ -1727,7 +1727,7 @@
 ''';
     var projectContents = simpleProject(pubspecText: pubspecText)
       ..remove('.dart_tool/package_config.json');
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var cliRunner = _createCli().decodeCommandLineArgs(
         _parseArgs(['--no-web-preview', '--apply-changes', projectDir]));
     await cliRunner.run();
@@ -1742,7 +1742,7 @@
     var projectContents = simpleProject(pubspecText: '''
 name: test
 ''');
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var cliRunner = _createCli().decodeCommandLineArgs(
         _parseArgs(['--no-web-preview', '--apply-changes', projectDir]));
     await cliRunner.run();
@@ -1759,7 +1759,7 @@
 
   test_pubspec_is_not_a_map() async {
     var projectContents = simpleProject(pubspecText: 'not-a-map');
-    var projectDir = await createProjectDir(projectContents);
+    var projectDir = createProjectDir(projectContents);
     var cliRunner = _createCli().decodeCommandLineArgs(
         _parseArgs(['--no-web-preview', '--apply-changes', projectDir]));
     expect(() async => await cliRunner.run(), throwsUnsupportedError);
@@ -1883,6 +1883,11 @@
   }
 
   @override
+  void trace(String message) {
+    throw UnimplementedError('TODO(paulberry)');
+  }
+
+  @override
   void write(String message) {
     stdoutBuffer.write(message);
   }
@@ -1891,9 +1896,4 @@
   void writeCharCode(int charCode) {
     stdoutBuffer.writeCharCode(charCode);
   }
-
-  @override
-  void trace(String message) {
-    throw UnimplementedError('TODO(paulberry)');
-  }
 }
diff --git a/pkg/nnbd_migration/tool/codegen/generate_resources.dart b/pkg/nnbd_migration/tool/codegen/generate_resources.dart
index e1a9c86..43c9356 100644
--- a/pkg/nnbd_migration/tool/codegen/generate_resources.dart
+++ b/pkg/nnbd_migration/tool/codegen/generate_resources.dart
@@ -88,7 +88,7 @@
   return lines.join('\n');
 }
 
-void compileWebFrontEnd({bool devMode = false}) async {
+Future<void> compileWebFrontEnd({bool devMode = false}) async {
   var sdkBinDir = path.dirname(Platform.resolvedExecutable);
   var dart2jsBinary = Platform.isWindows ? 'dart2js.bat' : 'dart2js';
   var dart2jsPath = path.join(sdkBinDir, dart2jsBinary);
diff --git a/runtime/bin/file_system_watcher_win.cc b/runtime/bin/file_system_watcher_win.cc
index 33654c4..b371363 100644
--- a/runtime/bin/file_system_watcher_win.cc
+++ b/runtime/bin/file_system_watcher_win.cc
@@ -80,6 +80,9 @@
   const intptr_t kEventSize = sizeof(FILE_NOTIFY_INFORMATION);
   DirectoryWatchHandle* dir = reinterpret_cast<DirectoryWatchHandle*>(path_id);
   intptr_t available = dir->Available();
+  if (available <= 0) {
+    return Dart_NewList(0);
+  }
   intptr_t max_count = available / kEventSize + 1;
   Dart_Handle events = Dart_NewList(max_count);
   uint8_t* buffer = Dart_ScopeAllocate(available);
diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h
index 5ec71e8..da31762 100644
--- a/runtime/vm/compiler/runtime_api.h
+++ b/runtime/vm/compiler/runtime_api.h
@@ -280,6 +280,9 @@
 #endif
 static constexpr int kWordSize = 1 << kWordSizeLog2;
 static_assert(kWordSize == sizeof(word), "kWordSize should match sizeof(word)");
+// Our compiler code currently assumes this, so formally check it.
+static_assert(dart::kWordSize >= kWordSize,
+              "Host word size smaller than target word size");
 
 static constexpr word kBitsPerWordLog2 = kWordSizeLog2 + kBitsPerByteLog2;
 static constexpr word kBitsPerWord = 1 << kBitsPerWordLog2;
diff --git a/runtime/vm/datastream.h b/runtime/vm/datastream.h
index 39acb48..03fac70 100644
--- a/runtime/vm/datastream.h
+++ b/runtime/vm/datastream.h
@@ -332,7 +332,7 @@
   class Raw<1, T> {
    public:
     static void Write(BaseWriteStream* st, T value) {
-      st->WriteByte(bit_cast<int8_t>(value));
+      st->WriteByte(bit_cast<uint8_t>(value));
     }
   };
 
@@ -390,33 +390,25 @@
     current_ += len;
   }
 
-  void WriteWord(uword value) {
-    const intptr_t len = sizeof(uword);
-    EnsureSpace(len);
-    *reinterpret_cast<uword*>(current_) = value;
-    current_ += len;
-  }
+  void WriteWord(uword value) { WriteFixed(value); }
 
   void WriteTargetWord(uword value) {
 #if defined(IS_SIMARM_X64)
     RELEASE_ASSERT(Utils::IsInt(32, static_cast<word>(value)));
-    const intptr_t len = sizeof(uint32_t);
-    EnsureSpace(len);
-    *reinterpret_cast<uint32_t*>(current_) = static_cast<uint32_t>(value);
-    current_ += len;
-#else   // defined(IS_SIMARM_X64)
-    WriteWord(value);
-#endif  // defined(IS_SIMARM_X64)
+    WriteFixed(static_cast<uint32_t>(value));
+#else
+    WriteFixed(value);
+#endif
   }
 
-  void Print(const char* format, ...) {
+  void Printf(const char* format, ...) PRINTF_ATTRIBUTE(2, 3) {
     va_list args;
     va_start(args, format);
-    VPrint(format, args);
+    VPrintf(format, args);
     va_end(args);
   }
 
-  void VPrint(const char* format, va_list args) {
+  void VPrintf(const char* format, va_list args) {
     // Measure.
     va_list measure_args;
     va_copy(measure_args, args);
@@ -447,18 +439,17 @@
 
   template <typename T>
   void WriteFixed(T value) {
-    const intptr_t len = sizeof(T);
-    EnsureSpace(len);
-    *reinterpret_cast<T*>(current_) = static_cast<T>(value);
-    current_ += len;
+    WriteBytes(&value, sizeof(value));
   }
 
- protected:
   DART_FORCE_INLINE void WriteByte(uint8_t value) {
     EnsureSpace(1);
     *current_++ = value;
   }
 
+  void WriteString(const char* cstr) { WriteBytes(cstr, strlen(cstr)); }
+
+ protected:
   void EnsureSpace(intptr_t size_needed) {
     if (Remaining() >= size_needed) return;
     intptr_t increment_size = capacity_;
diff --git a/runtime/vm/elf.cc b/runtime/vm/elf.cc
index 9d08ce5..30c25bf 100644
--- a/runtime/vm/elf.cc
+++ b/runtime/vm/elf.cc
@@ -21,7 +21,7 @@
   explicit ElfWriteStream(BaseWriteStream* stream)
       : stream_(ASSERT_NOTNULL(stream)) {}
 
-  intptr_t position() const { return stream_->Position(); }
+  intptr_t Position() const { return stream_->Position(); }
   void Align(const intptr_t alignment) {
     ASSERT(Utils::IsPowerOfTwo(alignment));
     stream_->Align(alignment);
@@ -29,25 +29,13 @@
   void WriteBytes(const uint8_t* b, intptr_t size) {
     stream_->WriteBytes(b, size);
   }
-  void WriteByte(uint8_t value) {
-    stream_->WriteBytes(reinterpret_cast<uint8_t*>(&value), sizeof(value));
-  }
-  void WriteHalf(uint16_t value) {
-    stream_->WriteBytes(reinterpret_cast<uint8_t*>(&value), sizeof(value));
-  }
-  void WriteWord(uint32_t value) {
-    stream_->WriteBytes(reinterpret_cast<uint8_t*>(&value), sizeof(value));
-  }
-  void WriteAddr(compiler::target::uword value) {
-    stream_->WriteBytes(reinterpret_cast<uint8_t*>(&value), sizeof(value));
-  }
-  void WriteOff(compiler::target::uword value) {
-    stream_->WriteBytes(reinterpret_cast<uint8_t*>(&value), sizeof(value));
-  }
+  void WriteByte(uint8_t value) { stream_->WriteByte(value); }
+  void WriteHalf(uint16_t value) { stream_->WriteFixed(value); }
+  void WriteWord(uint32_t value) { stream_->WriteFixed(value); }
+  void WriteAddr(compiler::target::uword value) { stream_->WriteFixed(value); }
+  void WriteOff(compiler::target::uword value) { stream_->WriteFixed(value); }
 #if defined(TARGET_ARCH_IS_64_BIT)
-  void WriteXWord(uint64_t value) {
-    stream_->WriteBytes(reinterpret_cast<uint8_t*>(&value), sizeof(value));
-  }
+  void WriteXWord(uint64_t value) { stream_->WriteFixed(value); }
 #endif
 
  private:
@@ -602,7 +590,7 @@
         cstr_(cstr) {}
 
   void Write(ElfWriteStream* stream) const {
-    const intptr_t start = stream->position();
+    const intptr_t start = stream->Position();
     stream->WriteWord(name_index);
 #if defined(TARGET_ARCH_IS_32_BIT)
     stream->WriteAddr(offset);
@@ -617,7 +605,7 @@
     stream->WriteAddr(offset);
     stream->WriteXWord(size);
 #endif
-    ASSERT_EQUAL(stream->position() - start, sizeof(elf::Symbol));
+    ASSERT_EQUAL(stream->Position() - start, sizeof(elf::Symbol));
   }
 
   const intptr_t name_index;
@@ -655,9 +643,9 @@
   void Write(ElfWriteStream* stream) {
     for (intptr_t i = 0; i < Length(); i++) {
       auto const symbol = At(i);
-      const intptr_t start = stream->position();
+      const intptr_t start = stream->Position();
       symbol->Write(stream);
-      ASSERT_EQUAL(stream->position() - start, entry_size);
+      ASSERT_EQUAL(stream->Position() - start, entry_size);
     }
   }
 
@@ -777,7 +765,7 @@
     Entry(elf::DynamicEntryType tag, intptr_t value) : tag(tag), value(value) {}
 
     void Write(ElfWriteStream* stream) {
-      const intptr_t start = stream->position();
+      const intptr_t start = stream->Position();
 #if defined(TARGET_ARCH_IS_32_BIT)
       stream->WriteWord(static_cast<uint32_t>(tag));
       stream->WriteAddr(value);
@@ -785,7 +773,7 @@
       stream->WriteXWord(static_cast<uint64_t>(tag));
       stream->WriteAddr(value);
 #endif
-      ASSERT_EQUAL(stream->position() - start, sizeof(elf::DynamicEntry));
+      ASSERT_EQUAL(stream->Position() - start, sizeof(elf::DynamicEntry));
     }
 
     elf::DynamicEntryType tag;
@@ -1039,7 +1027,7 @@
       } else {
         part |= 0x80;
       }
-      stream_->WriteFixed(part);
+      stream_->WriteByte(part);
     }
   }
 
@@ -1053,35 +1041,32 @@
       } else {
         part |= 0x80;
       }
-      stream_->WriteFixed(part);
+      stream_->WriteByte(part);
     }
   }
 
-  void u1(uint8_t value) { stream_->WriteFixed(value); }
-  // Can't use WriteFixed for these, as we may not be at aligned positions.
-  void u2(uint16_t value) { stream_->WriteBytes(&value, sizeof(value)); }
-  void u4(uint32_t value) { stream_->WriteBytes(&value, sizeof(value)); }
-  void u8(uint64_t value) { stream_->WriteBytes(&value, sizeof(value)); }
+  void u1(uint8_t value) { stream_->WriteByte(value); }
+  void u2(uint16_t value) { stream_->WriteFixed(value); }
+  void u4(uint32_t value) { stream_->WriteFixed(value); }
+  void u8(uint64_t value) { stream_->WriteFixed(value); }
   void string(const char* cstr) {  // NOLINT
-    stream_->WriteBytes(reinterpret_cast<const uint8_t*>(cstr),
-                        strlen(cstr) + 1);
+    // Unlike stream_->WriteString(), we want the null terminator written.
+    stream_->WriteBytes(cstr, strlen(cstr) + 1);
   }
-  intptr_t position() { return stream_->Position(); }
   intptr_t ReserveSize(const char* prefix, intptr_t* start) {
     ASSERT(start != nullptr);
-    intptr_t fixup = position();
+    intptr_t fixup = stream_->Position();
     // We assume DWARF v2, so all sizes are 32-bit.
     u4(0);
     // All sizes for DWARF sections measure the size of the section data _after_
     // the size value.
-    *start = position();
+    *start = stream_->Position();
     return fixup;
   }
   void SetSize(intptr_t fixup, const char* prefix, intptr_t start) {
-    const intptr_t old_position = position();
+    const intptr_t old_position = stream_->Position();
     stream_->SetPosition(fixup);
-    const uint32_t value = old_position - start;
-    stream_->WriteBytes(&value, sizeof(value));
+    stream_->WriteFixed(static_cast<uint32_t>(old_position - start));
     stream_->SetPosition(old_position);
   }
   void OffsetFromSymbol(const char* symbol, intptr_t offset) {
@@ -1108,7 +1093,7 @@
   void RegisterAbstractOrigin(intptr_t index) {
     ASSERT(abstract_origins_ != nullptr);
     ASSERT(index < abstract_origins_size_);
-    abstract_origins_[index] = position();
+    abstract_origins_[index] = stream_->Position();
   }
   void AbstractOrigin(intptr_t index) { u4(abstract_origins_[index]); }
 
@@ -1532,12 +1517,12 @@
   stream->WriteHalf(sections_.length());
   stream->WriteHalf(shstrtab_->index());
 
-  ASSERT_EQUAL(stream->position(), sizeof(elf::ElfHeader));
+  ASSERT_EQUAL(stream->Position(), sizeof(elf::ElfHeader));
 }
 
 void Elf::WriteProgramTable(ElfWriteStream* stream) {
   ASSERT(program_table_file_size_ >= 0);  // Check for finalization.
-  ASSERT(stream->position() == program_table_file_offset_);
+  ASSERT(stream->Position() == program_table_file_offset_);
 #if defined(DEBUG)
   // Here, we count the number of times that a PT_LOAD writable segment is
   // followed by a non-writable segment. We initialize last_writable to true so
@@ -1554,9 +1539,9 @@
       last_writable = segment->IsWritable();
     }
 #endif
-    const intptr_t start = stream->position();
+    const intptr_t start = stream->Position();
     segment->WriteProgramHeader(stream);
-    const intptr_t end = stream->position();
+    const intptr_t end = stream->Position();
     ASSERT_EQUAL(end - start, sizeof(elf::ProgramHeader));
   }
 #if defined(DEBUG)
@@ -1570,12 +1555,12 @@
 void Elf::WriteSectionTable(ElfWriteStream* stream) {
   ASSERT(section_table_file_size_ >= 0);  // Check for finalization.
   stream->Align(kElfSectionTableAlignment);
-  ASSERT_EQUAL(stream->position(), section_table_file_offset_);
+  ASSERT_EQUAL(stream->Position(), section_table_file_offset_);
 
   for (auto const section : sections_) {
-    const intptr_t start = stream->position();
+    const intptr_t start = stream->Position();
     section->WriteSectionHeader(stream);
-    const intptr_t end = stream->position();
+    const intptr_t end = stream->Position();
     ASSERT_EQUAL(end - start, sizeof(elf::SectionHeader));
   }
 }
@@ -1598,9 +1583,9 @@
       stream->Align(load_align);
       current_segment = section->load_segment;
     }
-    ASSERT_EQUAL(stream->position(), section->file_offset());
+    ASSERT_EQUAL(stream->Position(), section->file_offset());
     section->Write(stream);
-    ASSERT_EQUAL(stream->position(),
+    ASSERT_EQUAL(stream->Position(),
                  section->file_offset() + section->FileSize());
   }
 }
diff --git a/runtime/vm/image_snapshot.cc b/runtime/vm/image_snapshot.cc
index 8ed1d98..ae8efbe 100644
--- a/runtime/vm/image_snapshot.cc
+++ b/runtime/vm/image_snapshot.cc
@@ -622,27 +622,30 @@
   explicit DwarfAssemblyStream(BaseWriteStream* stream)
       : stream_(ASSERT_NOTNULL(stream)) {}
 
-  void sleb128(intptr_t value) { Print(".sleb128 %" Pd "\n", value); }
-  void uleb128(uintptr_t value) { Print(".uleb128 %" Pd "\n", value); }
-  void u1(uint8_t value) { Print(".byte %u\n", value); }
-  void u2(uint16_t value) { Print(".2byte %u\n", value); }
-  void u4(uint32_t value) { Print(".4byte %" Pu32 "\n", value); }
-  void u8(uint64_t value) { Print(".8byte %" Pu64 "\n", value); }
+  void sleb128(intptr_t value) { stream_->Printf(".sleb128 %" Pd "\n", value); }
+  void uleb128(uintptr_t value) {
+    stream_->Printf(".uleb128 %" Pd "\n", value);
+  }
+  void u1(uint8_t value) { stream_->Printf(".byte %u\n", value); }
+  void u2(uint16_t value) { stream_->Printf(".2byte %u\n", value); }
+  void u4(uint32_t value) { stream_->Printf(".4byte %" Pu32 "\n", value); }
+  void u8(uint64_t value) { stream_->Printf(".8byte %" Pu64 "\n", value); }
   void string(const char* cstr) {     // NOLINT
-    Print(".string \"%s\"\n", cstr);  // NOLINT
+    stream_->Printf(".string \"%s\"\n", cstr);  // NOLINT
   }
   // Uses labels, so doesn't output to start or return a useful fixup position.
   intptr_t ReserveSize(const char* prefix, intptr_t* start) {
     // Assignment to temp works around buggy Mac assembler.
-    Print("L%s_size = .L%s_end - .L%s_start\n", prefix, prefix, prefix);
-    Print(".4byte L%s_size\n", prefix);
-    Print(".L%s_start:\n", prefix);
+    stream_->Printf("L%s_size = .L%s_end - .L%s_start\n", prefix, prefix,
+                    prefix);
+    stream_->Printf(".4byte L%s_size\n", prefix);
+    stream_->Printf(".L%s_start:\n", prefix);
     return -1;
   }
   // Just need to label the end so the assembler can calculate the size, so
   // start and the fixup position is unused.
   void SetSize(intptr_t fixup, const char* prefix, intptr_t start) {
-    Print(".L%s_end:\n", prefix);
+    stream_->Printf(".L%s_end:\n", prefix);
   }
   void OffsetFromSymbol(const char* symbol, intptr_t offset) {
     if (offset == 0) {
@@ -655,51 +658,53 @@
                                     intptr_t offset1,
                                     const char* symbol2,
                                     intptr_t offset2) {
-    Print(".uleb128 %s - %s + %" Pd "\n", symbol1, symbol2, offset1 - offset2);
+    stream_->Printf(".uleb128 %s - %s + %" Pd "\n", symbol1, symbol2,
+                    offset1 - offset2);
   }
 
   // No-op, we'll be using labels.
   void InitializeAbstractOrigins(intptr_t size) {}
   void RegisterAbstractOrigin(intptr_t index) {
     // Label for DW_AT_abstract_origin references
-    Print(".Lfunc%" Pd ":\n", index);
+    stream_->Printf(".Lfunc%" Pd ":\n", index);
   }
   void AbstractOrigin(intptr_t index) {
     // Assignment to temp works around buggy Mac assembler.
-    Print("Ltemp%" Pd " = .Lfunc%" Pd " - %s\n", temp_, index, kDebugInfoLabel);
-    Print(".4byte Ltemp%" Pd "\n", temp_);
+    stream_->Printf("Ltemp%" Pd " = .Lfunc%" Pd " - %s\n", temp_, index,
+                    kDebugInfoLabel);
+    stream_->Printf(".4byte Ltemp%" Pd "\n", temp_);
     temp_++;
   }
 
   // Methods for writing the assembly prologues for various DWARF sections.
   void AbbreviationsPrologue() {
 #if defined(TARGET_OS_MACOS) || defined(TARGET_OS_MACOS_IOS)
-    Print(".section __DWARF,__debug_abbrev,regular,debug\n");
+    stream_->WriteString(".section __DWARF,__debug_abbrev,regular,debug\n");
 #elif defined(TARGET_OS_LINUX) || defined(TARGET_OS_ANDROID) ||                \
     defined(TARGET_OS_FUCHSIA)
-    Print(".section .debug_abbrev,\"\"\n");
+    stream_->WriteString(".section .debug_abbrev,\"\"\n");
 #else
     UNIMPLEMENTED();
 #endif
   }
   void DebugInfoPrologue() {
 #if defined(TARGET_OS_MACOS) || defined(TARGET_OS_MACOS_IOS)
-    Print(".section __DWARF,__debug_info,regular,debug\n");
+    stream_->WriteString(".section __DWARF,__debug_info,regular,debug\n");
 #elif defined(TARGET_OS_LINUX) || defined(TARGET_OS_ANDROID) ||                \
     defined(TARGET_OS_FUCHSIA)
-    Print(".section .debug_info,\"\"\n");
+    stream_->WriteString(".section .debug_info,\"\"\n");
 #else
     UNIMPLEMENTED();
 #endif
     // Used to calculate abstract origin values.
-    Print("%s:\n", kDebugInfoLabel);
+    stream_->Printf("%s:\n", kDebugInfoLabel);
   }
   void LineNumberProgramPrologue() {
 #if defined(TARGET_OS_MACOS) || defined(TARGET_OS_MACOS_IOS)
-    Print(".section __DWARF,__debug_line,regular,debug\n");
+    stream_->WriteString(".section __DWARF,__debug_line,regular,debug\n");
 #elif defined(TARGET_OS_LINUX) || defined(TARGET_OS_ANDROID) ||                \
     defined(TARGET_OS_FUCHSIA)
-    Print(".section .debug_line,\"\"\n");
+    stream_->WriteString(".section .debug_line,\"\"\n");
 #else
     UNIMPLEMENTED();
 #endif
@@ -708,22 +713,17 @@
  private:
   static constexpr const char* kDebugInfoLabel = ".Ldebug_info";
 
-  void Print(const char* format, ...) PRINTF_ATTRIBUTE(2, 3) {
-    va_list args;
-    va_start(args, format);
-    stream_->VPrint(format, args);
-    va_end(args);
-  }
-
 #if defined(TARGET_ARCH_IS_32_BIT)
 #define FORM_ADDR ".4byte"
 #elif defined(TARGET_ARCH_IS_64_BIT)
 #define FORM_ADDR ".8byte"
 #endif
 
-  void PrintNamedAddress(const char* name) { Print(FORM_ADDR " %s\n", name); }
+  void PrintNamedAddress(const char* name) {
+    stream_->Printf(FORM_ADDR " %s\n", name);
+  }
   void PrintNamedAddressWithOffset(const char* name, intptr_t offset) {
-    Print(FORM_ADDR " %s + %" Pd "\n", name, offset);
+    stream_->Printf(FORM_ADDR " %s + %" Pd "\n", name, offset);
   }
 
 #undef FORM_ADDR
@@ -840,10 +840,10 @@
 #if defined(DART_PRECOMPILER)
   auto const bss_symbol =
       vm ? kVmSnapshotBssAsmSymbol : kIsolateSnapshotBssAsmSymbol;
-  assembly_stream_->Print(".bss\n");
+  assembly_stream_->WriteString(".bss\n");
   // Align the BSS contents as expected by the Image class.
   Align(ImageWriter::kBssAlignment);
-  assembly_stream_->Print("%s:\n", bss_symbol);
+  assembly_stream_->Printf("%s:\n", bss_symbol);
 
   auto const entry_count = vm ? BSS::kVmEntryCount : BSS::kIsolateEntryCount;
   for (intptr_t i = 0; i < entry_count; i++) {
@@ -860,18 +860,18 @@
 #else
 #if defined(TARGET_OS_LINUX) || defined(TARGET_OS_ANDROID) ||                  \
     defined(TARGET_OS_FUCHSIA)
-  assembly_stream_->Print(".section .rodata\n");
+  assembly_stream_->WriteString(".section .rodata\n");
 #elif defined(TARGET_OS_MACOS) || defined(TARGET_OS_MACOS_IOS)
-  assembly_stream_->Print(".const\n");
+  assembly_stream_->WriteString(".const\n");
 #else
   UNIMPLEMENTED();
 #endif
 
   const char* data_symbol =
       vm ? kVmSnapshotDataAsmSymbol : kIsolateSnapshotDataAsmSymbol;
-  assembly_stream_->Print(".globl %s\n", data_symbol);
+  assembly_stream_->Printf(".globl %s\n", data_symbol);
   Align(ImageWriter::kRODataAlignment);
-  assembly_stream_->Print("%s:\n", data_symbol);
+  assembly_stream_->Printf("%s:\n", data_symbol);
   const uword buffer = reinterpret_cast<uword>(clustered_stream->buffer());
   const intptr_t length = clustered_stream->bytes_written();
   WriteByteSequence(buffer, buffer + length);
@@ -895,13 +895,13 @@
 
   const char* instructions_symbol = vm ? kVmSnapshotInstructionsAsmSymbol
                                        : kIsolateSnapshotInstructionsAsmSymbol;
-  assembly_stream_->Print(".text\n");
-  assembly_stream_->Print(".globl %s\n", instructions_symbol);
+  assembly_stream_->WriteString(".text\n");
+  assembly_stream_->Printf(".globl %s\n", instructions_symbol);
 
   // Start snapshot at page boundary.
   ASSERT(ImageWriter::kTextAlignment >= VirtualMemory::PageSize());
   Align(ImageWriter::kTextAlignment);
-  assembly_stream_->Print("%s:\n", instructions_symbol);
+  assembly_stream_->Printf("%s:\n", instructions_symbol);
 
 #if defined(DART_PRECOMPILER)
   auto const bss_symbol =
@@ -976,8 +976,8 @@
 
     // An ImageHeader has four fields:
     // 1) The BSS offset from this section.
-    assembly_stream_->Print("%s %s - %s\n", kLiteralPrefix, bss_symbol,
-                            instructions_symbol);
+    assembly_stream_->Printf("%s %s - %s\n", kLiteralPrefix, bss_symbol,
+                             instructions_symbol);
     text_offset += compiler::target::kWordSize;
     // 2) The relocated address of the instructions.
     //
@@ -1133,7 +1133,7 @@
 #endif
     // 2. Write a label at the entry point.
     // Linux's perf uses these labels.
-    assembly_stream_->Print("%s:\n", object_name);
+    assembly_stream_->Printf("%s:\n", object_name);
 
     {
       // 3. Write from the payload start to payload end. For AOT snapshots
@@ -1160,11 +1160,10 @@
           Utils::RoundDown(payload_end, sizeof(compiler::target::uword));
       for (uword cursor = payload_start; cursor < possible_relocations_end;
            cursor += sizeof(compiler::target::uword)) {
-        compiler::target::uword data =
-            *reinterpret_cast<compiler::target::uword*>(cursor);
+        uword data = *reinterpret_cast<compiler::target::uword*>(cursor);
         if ((cursor - payload_start) == next_reloc_offset) {
-          assembly_stream_->Print("%s %s - (.) + %" Pd "\n", kLiteralPrefix,
-                                  bss_symbol, /*addend=*/data);
+          assembly_stream_->Printf("%s %s - (.) + %" Pu "\n", kLiteralPrefix,
+                                   bss_symbol, /*addend=*/data);
           text_offset += compiler::target::kWordSize;
           next_reloc_offset = iterator.MoveNext() ? iterator.PcOffset() : -1;
         } else {
@@ -1243,12 +1242,14 @@
   // Creates DWARF's .debug_frame
   // CFI = Call frame information
   // CFA = Canonical frame address
-  assembly_stream_->Print(".cfi_startproc\n");
+  assembly_stream_->WriteString(".cfi_startproc\n");
 
 #if defined(TARGET_ARCH_X64)
-  assembly_stream_->Print(".cfi_def_cfa rbp, 0\n");  // CFA is fp+0
-  assembly_stream_->Print(".cfi_offset rbp, 0\n");   // saved fp is *(CFA+0)
-  assembly_stream_->Print(".cfi_offset rip, 8\n");   // saved pc is *(CFA+8)
+  assembly_stream_->WriteString(".cfi_def_cfa rbp, 0\n");  // CFA is fp+0
+  assembly_stream_->WriteString(
+      ".cfi_offset rbp, 0\n");  // saved fp is *(CFA+0)
+  assembly_stream_->WriteString(
+      ".cfi_offset rip, 8\n");  // saved pc is *(CFA+8)
   // saved sp is CFA+16
   // Should be ".cfi_value_offset rsp, 16", but requires gcc newer than late
   // 2016 and not supported by Android's libunwind.
@@ -1257,14 +1258,16 @@
   // uleb128 size of operation     2
   // DW_OP_plus_uconst          0x23
   // uleb128 addend               16
-  assembly_stream_->Print(".cfi_escape 0x10, 31, 2, 0x23, 16\n");
+  assembly_stream_->WriteString(".cfi_escape 0x10, 31, 2, 0x23, 16\n");
 
 #elif defined(TARGET_ARCH_ARM64)
   COMPILE_ASSERT(FP == R29);
   COMPILE_ASSERT(LR == R30);
-  assembly_stream_->Print(".cfi_def_cfa x29, 0\n");  // CFA is fp+0
-  assembly_stream_->Print(".cfi_offset x29, 0\n");   // saved fp is *(CFA+0)
-  assembly_stream_->Print(".cfi_offset x30, 8\n");   // saved pc is *(CFA+8)
+  assembly_stream_->WriteString(".cfi_def_cfa x29, 0\n");  // CFA is fp+0
+  assembly_stream_->WriteString(
+      ".cfi_offset x29, 0\n");  // saved fp is *(CFA+0)
+  assembly_stream_->WriteString(
+      ".cfi_offset x30, 8\n");  // saved pc is *(CFA+8)
   // saved sp is CFA+16
   // Should be ".cfi_value_offset sp, 16", but requires gcc newer than late
   // 2016 and not supported by Android's libunwind.
@@ -1273,19 +1276,20 @@
   // uleb128 size of operation     2
   // DW_OP_plus_uconst          0x23
   // uleb128 addend               16
-  assembly_stream_->Print(".cfi_escape 0x10, 31, 2, 0x23, 16\n");
+  assembly_stream_->WriteString(".cfi_escape 0x10, 31, 2, 0x23, 16\n");
 
 #elif defined(TARGET_ARCH_ARM)
 #if defined(TARGET_OS_MACOS) || defined(TARGET_OS_MACOS_IOS)
   COMPILE_ASSERT(FP == R7);
-  assembly_stream_->Print(".cfi_def_cfa r7, 0\n");  // CFA is fp+j0
-  assembly_stream_->Print(".cfi_offset r7, 0\n");   // saved fp is *(CFA+0)
+  assembly_stream_->WriteString(".cfi_def_cfa r7, 0\n");  // CFA is fp+j0
+  assembly_stream_->WriteString(".cfi_offset r7, 0\n");  // saved fp is *(CFA+0)
 #else
   COMPILE_ASSERT(FP == R11);
-  assembly_stream_->Print(".cfi_def_cfa r11, 0\n");  // CFA is fp+0
-  assembly_stream_->Print(".cfi_offset r11, 0\n");   // saved fp is *(CFA+0)
+  assembly_stream_->WriteString(".cfi_def_cfa r11, 0\n");  // CFA is fp+0
+  assembly_stream_->WriteString(
+      ".cfi_offset r11, 0\n");  // saved fp is *(CFA+0)
 #endif
-  assembly_stream_->Print(".cfi_offset lr, 4\n");   // saved pc is *(CFA+4)
+  assembly_stream_->WriteString(".cfi_offset lr, 4\n");  // saved pc is *(CFA+4)
   // saved sp is CFA+8
   // Should be ".cfi_value_offset sp, 8", but requires gcc newer than late
   // 2016 and not supported by Android's libunwind.
@@ -1294,14 +1298,14 @@
   // uleb128 size of operation     2
   // DW_OP_plus_uconst          0x23
   // uleb128 addend                8
-  assembly_stream_->Print(".cfi_escape 0x10, 13, 2, 0x23, 8\n");
+  assembly_stream_->WriteString(".cfi_escape 0x10, 13, 2, 0x23, 8\n");
 
 // libunwind on ARM may use .ARM.exidx instead of .debug_frame
 #if !defined(TARGET_OS_MACOS) && !defined(TARGET_OS_MACOS_IOS)
   COMPILE_ASSERT(FP == R11);
-  assembly_stream_->Print(".fnstart\n");
-  assembly_stream_->Print(".save {r11, lr}\n");
-  assembly_stream_->Print(".setfp r11, sp, #0\n");
+  assembly_stream_->WriteString(".fnstart\n");
+  assembly_stream_->WriteString(".save {r11, lr}\n");
+  assembly_stream_->WriteString(".setfp r11, sp, #0\n");
 #endif
 
 #endif
@@ -1310,10 +1314,10 @@
 void AssemblyImageWriter::FrameUnwindEpilogue() {
 #if defined(TARGET_ARCH_ARM)
 #if !defined(TARGET_OS_MACOS) && !defined(TARGET_OS_MACOS_IOS)
-  assembly_stream_->Print(".fnend\n");
+  assembly_stream_->WriteString(".fnend\n");
 #endif
 #endif
-  assembly_stream_->Print(".cfi_endproc\n");
+  assembly_stream_->WriteString(".cfi_endproc\n");
 }
 
 intptr_t AssemblyImageWriter::WriteByteSequence(uword start, uword end) {
@@ -1327,20 +1331,22 @@
   }
   if (end != end_of_words) {
     auto start_of_rest = reinterpret_cast<const uint8_t*>(end_of_words);
-    assembly_stream_->Print(".byte ");
+    assembly_stream_->WriteString(".byte ");
     for (auto cursor = start_of_rest;
          cursor < reinterpret_cast<const uint8_t*>(end); cursor++) {
-      if (cursor != start_of_rest) assembly_stream_->Print(", ");
-      assembly_stream_->Print("0x%0.2" Px "", *cursor);
+      if (cursor != start_of_rest) {
+        assembly_stream_->WriteString(", ");
+      }
+      assembly_stream_->Printf("0x%0.2x", *cursor);
     }
-    assembly_stream_->Print("\n");
+    assembly_stream_->WriteString("\n");
   }
   return end - start;
 }
 
 intptr_t AssemblyImageWriter::Align(intptr_t alignment, uword position) {
   const uword next_position = Utils::RoundUp(position, alignment);
-  assembly_stream_->Print(".balign %" Pd ", 0\n", alignment);
+  assembly_stream_->Printf(".balign %" Pd ", 0\n", alignment);
   return next_position - position;
 }
 
diff --git a/runtime/vm/image_snapshot.h b/runtime/vm/image_snapshot.h
index a75871b..44673a3 100644
--- a/runtime/vm/image_snapshot.h
+++ b/runtime/vm/image_snapshot.h
@@ -484,12 +484,15 @@
   const char* kLiteralPrefix = ".long";
 #endif
 
-  intptr_t WriteWordLiteralText(compiler::target::uword value) {
+  intptr_t WriteWordLiteralText(uword value) {
+#if defined(IS_SIMARM_X64)
+    ASSERT(value <= kMaxUint32);
+#endif
     // Padding is helpful for comparing the .S with --disassemble.
 #if defined(TARGET_ARCH_IS_64_BIT)
-    assembly_stream_->Print(".quad 0x%0.16" Px "\n", value);
+    assembly_stream_->Printf(".quad 0x%0.16" Px "\n", value);
 #else
-    assembly_stream_->Print(".long 0x%0.8" Px "\n", value);
+    assembly_stream_->Printf(".long 0x%0.8" Px "\n", value);
 #endif
     return compiler::target::kWordSize;
   }
diff --git a/tools/VERSION b/tools/VERSION
index 452c461..77e4c0e 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 11
 PATCH 0
-PRERELEASE 159
+PRERELEASE 160
 PRERELEASE_PATCH 0
\ No newline at end of file