Version 2.16.0-19.0.dev

Merge commit 'db642a008af38273faee13066f246f8659637673' into 'dev'
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
index 629101e..10e4cf9 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
@@ -482,7 +482,9 @@
     return (node is ast.InvocationExpression &&
             !node.argumentList.beginToken.isSynthetic) ||
         (node is ast.InstanceCreationExpression &&
-            !node.argumentList.beginToken.isSynthetic);
+            !node.argumentList.beginToken.isSynthetic) ||
+        // "ClassName.^()" will appear as accessing a property named '('.
+        (node is ast.PropertyAccess && node.propertyName.name.startsWith('('));
   }
 
   Iterable<CompletionItem> _pluginResultsToItems(
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion_resolve.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion_resolve.dart
index 30935d6..72903a8 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion_resolve.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion_resolve.dart
@@ -60,11 +60,12 @@
           'Requests not before server is initilized');
     }
 
-    final lineInfo = server.getLineInfo(data.file);
+    final file = data.file;
+    final lineInfo = server.getLineInfo(file);
     if (lineInfo == null) {
       return error(
         ErrorCodes.InternalError,
-        'Line info not available for ${data.file}',
+        'Line info not available for $file',
         null,
       );
     }
@@ -99,7 +100,7 @@
     _latestCompletionItem = item;
     while (item == _latestCompletionItem && timer.elapsed < timeout) {
       try {
-        final analysisDriver = server.getAnalysisDriver(data.file);
+        final analysisDriver = server.getAnalysisDriver(file);
         final session = analysisDriver?.currentSession;
 
         // We shouldn't not get a driver/session, but if we did perhaps the file
@@ -139,7 +140,7 @@
 
         var newInsertText = item.insertText ?? item.label;
         final builder = ChangeBuilder(session: session);
-        await builder.addDartFileEdit(data.file, (builder) {
+        await builder.addDartFileEdit(file, (builder) {
           final result = builder.importLibraryElement(library.uri);
           if (result.prefix != null) {
             newInsertText = '${result.prefix}.$newInsertText';
@@ -152,9 +153,9 @@
 
         final changes = builder.sourceChange;
         final thisFilesChanges =
-            changes.edits.where((e) => e.file == data.file).toList();
+            changes.edits.where((e) => e.file == file).toList();
         final otherFilesChanges =
-            changes.edits.where((e) => e.file != data.file).toList();
+            changes.edits.where((e) => e.file != file).toList();
 
         // If this completion involves editing other files, we'll need to build
         // a command that the client will call to apply those edits later.
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/import_library.dart b/pkg/analysis_server/lib/src/services/correction/dart/import_library.dart
index 415f155..4a949c4 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/import_library.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/import_library.dart
@@ -16,6 +16,7 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/source/source_range.dart';
 import 'package:analyzer_plugin/src/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/src/utilities/library.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:analyzer_plugin/utilities/range_factory.dart';
@@ -150,22 +151,6 @@
     return false;
   }
 
-  /// Returns the relative URI from the passed [library] to the given [path].
-  ///
-  /// If the [path] is not in the [library]'s directory, `null` is returned.
-  String? _getRelativeUriFromLibrary(LibraryElement library, String path) {
-    var librarySource = library.librarySource;
-    var pathContext = resourceProvider.pathContext;
-    var libraryDirectory = pathContext.dirname(librarySource.fullName);
-    var sourceDirectory = pathContext.dirname(path);
-    if (pathContext.isWithin(libraryDirectory, path) ||
-        pathContext.isWithin(sourceDirectory, libraryDirectory)) {
-      var relativeFile = pathContext.relative(path, from: libraryDirectory);
-      return pathContext.split(relativeFile).join('/');
-    }
-    return null;
-  }
-
   Iterable<CorrectionProducer> _importExtensionInLibrary(
       Uri uri, DartType targetType, String memberName) sync* {
     // Look to see whether the library at the [uri] is already imported. If it
@@ -207,25 +192,28 @@
 
   /// Returns a list of one or two import corrections.
   ///
-  /// If [relativeUri] is `null`, only one correction, with an absolute import
-  /// path, is returned. Otherwise, a correction with an absolute import path
-  /// and a correction with a relative path are returned. If the
+  /// If [includeRelativeFix] is `false`, only one correction, with an absolute
+  /// import path, is returned. Otherwise, a correction with an absolute import
+  /// path and a correction with a relative path are returned. If the
   /// `prefer_relative_imports` lint rule is enabled, the relative path is
   /// returned first.
-  Iterable<CorrectionProducer> _importLibrary(FixKind fixKind, Uri library,
-      [String? relativeUri]) {
-    if (relativeUri == null || relativeUri.isEmpty) {
+  Iterable<CorrectionProducer> _importLibrary(
+    FixKind fixKind,
+    Uri library, {
+    bool includeRelativeFix = false,
+  }) {
+    if (!includeRelativeFix) {
       return [_ImportAbsoluteLibrary(fixKind, library)];
     }
     if (isLintEnabled(LintNames.prefer_relative_imports)) {
       return [
-        _ImportRelativeLibrary(fixKind, relativeUri),
+        _ImportRelativeLibrary(fixKind, library),
         _ImportAbsoluteLibrary(fixKind, library),
       ];
     } else {
       return [
         _ImportAbsoluteLibrary(fixKind, library),
-        _ImportRelativeLibrary(fixKind, relativeUri),
+        _ImportRelativeLibrary(fixKind, library),
       ];
     }
   }
@@ -312,10 +300,13 @@
         // Good: direct declaration.
         fixKind = DartFixKind.IMPORT_LIBRARY_PROJECT1;
       }
-      // Add the fix.
-      var relativeUri =
-          _getRelativeUriFromLibrary(libraryElement, declaration.path);
-      yield* _importLibrary(fixKind, declaration.uri, relativeUri);
+      // If both files are in the same package's lib folder, also include a
+      // relative import.
+      var includeRelativeUri = canBeRelativeImport(
+          declaration.uri, libraryElement.librarySource.uri);
+      // Add the fix(es).
+      yield* _importLibrary(fixKind, declaration.uri,
+          includeRelativeFix: includeRelativeUri);
     }
   }
 
@@ -415,7 +406,9 @@
   @override
   Future<void> compute(ChangeBuilder builder) async {
     await builder.addDartFileEdit(file, (builder) {
-      _uriText = builder.importLibrary(_library);
+      if (builder is DartFileEditBuilderImpl) {
+        _uriText = builder.importLibraryWithAbsoluteUri(_library);
+      }
     });
   }
 }
@@ -532,12 +525,14 @@
 class _ImportRelativeLibrary extends CorrectionProducer {
   final FixKind _fixKind;
 
-  final String _relativeURI;
+  final Uri _library;
 
-  _ImportRelativeLibrary(this._fixKind, this._relativeURI);
+  String _uriText = '';
+
+  _ImportRelativeLibrary(this._fixKind, this._library);
 
   @override
-  List<Object> get fixArguments => [_relativeURI];
+  List<Object> get fixArguments => [_uriText];
 
   @override
   FixKind get fixKind => _fixKind;
@@ -546,7 +541,7 @@
   Future<void> compute(ChangeBuilder builder) async {
     await builder.addDartFileEdit(file, (builder) {
       if (builder is DartFileEditBuilderImpl) {
-        builder.importLibraryWithRelativeUri(_relativeURI);
+        _uriText = builder.importLibraryWithRelativeUri(_library);
       }
     });
   }
diff --git a/pkg/analysis_server/test/lsp/completion_dart_test.dart b/pkg/analysis_server/test/lsp/completion_dart_test.dart
index 9ccf020..cbacc55 100644
--- a/pkg/analysis_server/test/lsp/completion_dart_test.dart
+++ b/pkg/analysis_server/test/lsp/completion_dart_test.dart
@@ -4,9 +4,11 @@
 
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/src/lsp/constants.dart';
+import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' as plugin;
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
 import 'package:collection/collection.dart';
+import 'package:linter/src/rules.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -234,6 +236,21 @@
         insertText: 'myFunction',
       );
 
+  Future<void> test_completeFunctionCalls_existingArgList_member_noPrefix() =>
+      // https://github.com/Dart-Code/Dart-Code/issues/3672
+      checkCompleteFunctionCallInsertText(
+        '''
+        class Aaaaa {
+          static foo(int a) {}
+        }
+        void f() {
+          Aaaaa.[[^]]()
+        }
+        ''',
+        'foo(…)',
+        insertText: 'foo',
+      );
+
   Future<void> test_completeFunctionCalls_existingArgList_namedConstructor() =>
       checkCompleteFunctionCallInsertText(
         '''
@@ -1606,6 +1623,36 @@
     expect(resolved.detail, isNull);
   }
 
+  Future<void> test_suggestionSets_importsPackageUri() async {
+    newFile(
+      join(projectFolderPath, 'lib', 'my_class.dart'),
+      content: 'class MyClass {}',
+    );
+
+    final content = '''
+void f() {
+  MyClas^
+}
+    ''';
+
+    final expectedContent = '''
+import 'package:test/my_class.dart';
+
+void f() {
+  MyClass
+}
+    ''';
+
+    final completionLabel = 'MyClass';
+
+    await _checkCompletionEdits(
+      mainFileUri,
+      content,
+      completionLabel,
+      expectedContent,
+    );
+  }
+
   Future<void>
       test_suggestionSets_includesReexportedSymbolsForEachFile() async {
     newFile(
@@ -2003,6 +2050,78 @@
     '''));
   }
 
+  Future<void> test_suggestionSets_preferRelativeImportsLib_insideLib() async {
+    _enableLints([LintNames.prefer_relative_imports]);
+    final importingFilePath =
+        join(projectFolderPath, 'lib', 'nested1', 'main.dart');
+    final importingFileUri = Uri.file(importingFilePath);
+    final importedFilePath =
+        join(projectFolderPath, 'lib', 'nested2', 'imported.dart');
+
+    // Create a file that will be auto-imported from completion.
+    newFile(importedFilePath, content: 'class MyClass {}');
+
+    final content = '''
+void f() {
+  MyClas^
+}
+    ''';
+
+    final expectedContent = '''
+import '../nested2/imported.dart';
+
+void f() {
+  MyClass
+}
+    ''';
+
+    final completionLabel = 'MyClass';
+
+    await _checkCompletionEdits(
+      importingFileUri,
+      content,
+      completionLabel,
+      expectedContent,
+    );
+  }
+
+  Future<void> test_suggestionSets_preferRelativeImportsLib_outsideLib() async {
+    // Files outside of the lib folder should still get absolute imports to
+    // files inside lib, even with the lint enabled.
+    _enableLints([LintNames.prefer_relative_imports]);
+    final importingFilePath =
+        join(projectFolderPath, 'bin', 'nested1', 'main.dart');
+    final importingFileUri = Uri.file(importingFilePath);
+    final importedFilePath =
+        join(projectFolderPath, 'lib', 'nested2', 'imported.dart');
+
+    // Create a file that will be auto-imported from completion.
+    newFile(importedFilePath, content: 'class MyClass {}');
+
+    final content = '''
+void f() {
+  MyClas^
+}
+    ''';
+
+    final expectedContent = '''
+import 'package:test/nested2/imported.dart';
+
+void f() {
+  MyClass
+}
+    ''';
+
+    final completionLabel = 'MyClass';
+
+    await _checkCompletionEdits(
+      importingFileUri,
+      content,
+      completionLabel,
+      expectedContent,
+    );
+  }
+
   Future<void> test_suggestionSets_unavailableIfDisabled() async {
     newFile(
       join(projectFolderPath, 'other_file.dart'),
@@ -2085,6 +2204,39 @@
     expect(updated, contains('a.abcdefghij'));
   }
 
+  /// Sets up the server with a file containing [content] and checks that
+  /// accepting a specific completion produces [expectedContent].
+  ///
+  /// [content] should contain a `^` at the location where completion should be
+  /// invoked/accepted.
+  Future<void> _checkCompletionEdits(
+    Uri fileUri,
+    String content,
+    String completionLabel,
+    String expectedContent,
+  ) async {
+    final initialAnalysis = waitForAnalysisComplete();
+    await initialize(
+        workspaceCapabilities:
+            withApplyEditSupport(emptyWorkspaceClientCapabilities));
+    await openFile(fileUri, withoutMarkers(content));
+    await initialAnalysis;
+    final res = await getCompletion(fileUri, positionFromMarker(content));
+
+    final completion = res.where((c) => c.label == completionLabel).single;
+    final resolvedCompletion = await resolveCompletion(completion);
+
+    // Apply both the main completion edit and the additionalTextEdits atomically.
+    final newContent = applyTextEdits(
+      withoutMarkers(content),
+      [toTextEdit(resolvedCompletion.textEdit!)]
+          .followedBy(resolvedCompletion.additionalTextEdits!)
+          .toList(),
+    );
+
+    expect(newContent, equals(expectedContent));
+  }
+
   Future<void> _checkResultsForTriggerCharacters(String content,
       List<String> triggerCharacters, Matcher expectedResults) async {
     await initialize();
@@ -2099,6 +2251,16 @@
       expect(res, expectedResults);
     }
   }
+
+  void _enableLints(List<String> lintNames) {
+    registerLintRules();
+    final lintsYaml = lintNames.map((name) => '    - $name\n').join();
+    newFile(analysisOptionsPath, content: '''
+linter:
+  rules:
+$lintsYaml
+''');
+  }
 }
 
 @reflectiveTest
diff --git a/pkg/analysis_server/test/lsp/diagnostic_test.dart b/pkg/analysis_server/test/lsp/diagnostic_test.dart
index fc6dffe..3b7fc18 100644
--- a/pkg/analysis_server/test/lsp/diagnostic_test.dart
+++ b/pkg/analysis_server/test/lsp/diagnostic_test.dart
@@ -88,7 +88,7 @@
 linter:
   rules:
     - invalid_lint_rule_name
-''').path;
+''');
 
     final firstDiagnosticsUpdate = waitForDiagnostics(analysisOptionsUri);
     await initialize();
@@ -102,7 +102,7 @@
   Future<void> test_analysisOptionsFile_packageInclude() async {
     newFile(analysisOptionsPath, content: '''
 include: package:pedantic/analysis_options.yaml
-''').path;
+''');
 
     // Verify there's an error for the import.
     final firstDiagnosticsUpdate = waitForDiagnostics(analysisOptionsUri);
diff --git a/pkg/analyzer/lib/src/context/source.dart b/pkg/analyzer/lib/src/context/source.dart
index 554eb1a..f30c15c 100644
--- a/pkg/analyzer/lib/src/context/source.dart
+++ b/pkg/analyzer/lib/src/context/source.dart
@@ -11,6 +11,7 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart' as utils;
 import 'package:analyzer/src/source/package_map_resolver.dart';
+import 'package:analyzer/src/summary/package_bundle_reader.dart';
 import 'package:analyzer/src/util/file_paths.dart' as file_paths;
 import 'package:analyzer/src/workspace/package_build.dart';
 
@@ -137,6 +138,9 @@
 
   @override
   Uri? restoreUri(Source source) {
+    if (source is InSummarySource) {
+      return source.uri;
+    }
     for (UriResolver resolver in resolvers) {
       // First see if a resolver can restore the URI.
       Uri? uri = resolver.restoreAbsolute(source);
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index e74bf6d..97cac92 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -35,6 +35,7 @@
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
 import 'package:analyzer/src/summary2/informative_data.dart';
 import 'package:analyzer/src/util/either.dart';
+import 'package:analyzer/src/util/uri.dart';
 import 'package:analyzer/src/workspace/workspace.dart';
 import 'package:collection/collection.dart';
 import 'package:convert/convert.dart';
@@ -716,11 +717,8 @@
   /// Mapping from a path to the flag whether there is a URI for the path.
   final Map<String, bool> _hasUriForPath = {};
 
-  /// Mapping from a path to the corresponding [FileState]s, canonical or not.
-  final Map<String, List<FileState>> _pathToFiles = {};
-
-  /// Mapping from a path to the corresponding canonical [FileState].
-  final Map<String, FileState> _pathToCanonicalFile = {};
+  /// Mapping from a path to the corresponding [FileState].
+  final Map<String, FileState> _pathToFile = {};
 
   /// We don't read parts until requested, but if we need to know the
   /// library for a file, we need to read parts of every file to know
@@ -775,7 +773,8 @@
       }
     }
 
-    for (var file in _pathToFiles[path] ?? <FileState>[]) {
+    var file = _pathToFile[path];
+    if (file != null) {
       collectAffected(file);
     }
   }
@@ -808,25 +807,16 @@
     return featureSetProvider.getLanguageVersion(path, uri);
   }
 
-  /// Return the canonical [FileState] for the given absolute [path]. The
-  /// returned file has the last known state since if was last refreshed.
-  ///
-  /// Here "canonical" means that if the [path] is in a package `lib` then the
-  /// returned file will have the `package:` style URI.
+  /// Return the [FileState] for the given absolute [path]. The returned file
+  /// has the last known state since if was last refreshed.
   FileState getFileForPath(String path) {
-    FileState? file = _pathToCanonicalFile[path];
+    var file = _pathToFile[path];
     if (file == null) {
       File resource = _resourceProvider.getFile(path);
       Source fileSource = resource.createSource();
       Uri? uri = _sourceFactory.restoreUri(fileSource);
-      // Try to get the existing instance.
-      file = _uriToFile[uri];
-      // If we have a file, call it the canonical one and return it.
-      if (file != null) {
-        _pathToCanonicalFile[path] = file;
-        return file;
-      }
       // Create a new file.
+      // TODO(scheglov) this is duplicate
       FileSource uriSource = FileSource(resource, uri!);
       WorkspacePackage? workspacePackage = _workspace?.findPackageFor(path);
       FeatureSet featureSet = contextFeatureSet(path, uri, workspacePackage);
@@ -834,9 +824,9 @@
           contextLanguageVersion(path, uri, workspacePackage);
       file = FileState._(this, path, uri, uriSource, workspacePackage,
           featureSet, packageLanguageVersion);
+      _pathToFile[path] = file;
       _uriToFile[uri] = file;
       _addFileWithPath(path, file);
-      _pathToCanonicalFile[path] = file;
       file.refresh();
     }
     return file;
@@ -874,6 +864,13 @@
 
       String path = uriSource.fullName;
       File resource = _resourceProvider.getFile(path);
+
+      var rewrittenUri = rewriteFileToPackageUri(_sourceFactory, uri);
+      if (rewrittenUri == null) {
+        return Either2.t1(null);
+      }
+      uri = rewrittenUri;
+
       FileSource source = FileSource(resource, uri);
       WorkspacePackage? workspacePackage = _workspace?.findPackageFor(path);
       FeatureSet featureSet = contextFeatureSet(path, uri, workspacePackage);
@@ -881,6 +878,7 @@
           contextLanguageVersion(path, uri, workspacePackage);
       file = FileState._(this, path, uri, source, workspacePackage, featureSet,
           packageLanguageVersion);
+      _pathToFile[path] = file;
       _uriToFile[uri] = file;
       _addFileWithPath(path, file);
       file.refresh();
@@ -888,19 +886,6 @@
     return Either2.t1(file);
   }
 
-  /// Return the list of all [FileState]s corresponding to the given [path]. The
-  /// list has at least one item, and the first item is the canonical file.
-  List<FileState> getFilesForPath(String path) {
-    FileState canonicalFile = getFileForPath(path);
-    List<FileState> allFiles = _pathToFiles[path]!.toList();
-    if (allFiles.length == 1) {
-      return allFiles;
-    }
-    return allFiles
-      ..remove(canonicalFile)
-      ..insert(0, canonicalFile);
-  }
-
   /// Return files where the given [name] is subtyped, i.e. used in `extends`,
   /// `with` or `implements` clauses.
   Set<FileState>? getFilesSubtypingName(String name) {
@@ -951,15 +936,9 @@
   }
 
   void _addFileWithPath(String path, FileState file) {
-    var files = _pathToFiles[path];
-    if (files == null) {
-      knownFilePaths.add(path);
-      knownFiles.add(file);
-      files = <FileState>[];
-      _pathToFiles[path] = files;
-      fileStamp++;
-    }
-    files.add(file);
+    knownFilePaths.add(path);
+    knownFiles.add(file);
+    fileStamp++;
   }
 
   /// Clear all [FileState] data - all maps from path or URI, etc.
@@ -968,8 +947,7 @@
     knownFilePaths.clear();
     knownFiles.clear();
     _hasUriForPath.clear();
-    _pathToFiles.clear();
-    _pathToCanonicalFile.clear();
+    _pathToFile.clear();
     _librariesWithoutPartsRead.clear();
     _partToLibraries.clear();
     _subtypedNameToFiles.clear();
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_tracker.dart b/pkg/analyzer/lib/src/dart/analysis/file_tracker.dart
index d183ecc..887f450 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_tracker.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_tracker.dart
@@ -166,15 +166,9 @@
     return _logger.run('Verify API signature of $path', () {
       _logger.writeln('Work in ${_fsState.contextName}');
 
-      bool anyApiChanged = false;
-      List<FileState> files = _fsState.getFilesForPath(path);
-      for (FileState file in files) {
-        bool apiChanged = file.refresh();
-        if (apiChanged) {
-          anyApiChanged = true;
-        }
-      }
-      if (anyApiChanged) {
+      var file = _fsState.getFileForPath(path);
+      var apiChanged = file.refresh();
+      if (apiChanged) {
         _logger.writeln('API signatures mismatch found.');
         // TODO(scheglov) schedule analysis of only affected files
         var pendingChangedFiles = <String>{};
@@ -190,10 +184,8 @@
         // Add files that directly import the changed file.
         for (String addedPath in addedFiles) {
           FileState addedFile = _fsState.getFileForPath(addedPath);
-          for (FileState changedFile in files) {
-            if (addedFile.importedFiles.contains(changedFile)) {
-              pendingImportFiles.add(addedPath);
-            }
+          if (addedFile.importedFiles.contains(file)) {
+            pendingImportFiles.add(addedPath);
           }
         }
 
@@ -220,7 +212,7 @@
         _pendingErrorFiles = pendingErrorFiles;
         _pendingFiles = pendingFiles;
       }
-      return files[0];
+      return file;
     });
   }
 
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index 076e54f..1f513c1 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -41,6 +41,7 @@
 import 'package:analyzer/src/generated/ffi_verifier.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/hint/sdk_constraint_verifier.dart';
 import 'package:analyzer/src/ignore_comments/ignore_info.dart';
 import 'package:analyzer/src/lint/linter.dart';
@@ -49,6 +50,7 @@
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
 import 'package:analyzer/src/task/strong/checker.dart';
 import 'package:analyzer/src/util/performance/operation_performance.dart';
+import 'package:analyzer/src/util/uri.dart';
 import 'package:pub_semver/pub_semver.dart';
 
 var timerLibraryAnalyzer = Stopwatch();
@@ -772,6 +774,18 @@
         featureSet: unit.featureSet, flowAnalysisHelper: flowAnalysisHelper));
   }
 
+  Uri? _resolveRelativeUri(String relativeUriStr) {
+    Uri relativeUri;
+    try {
+      relativeUri = Uri.parse(relativeUriStr);
+    } on FormatException {
+      return null;
+    }
+
+    var absoluteUri = resolveRelativeUri(_library.uri, relativeUri);
+    return rewriteFileToPackageUri(_sourceFactory, absoluteUri);
+  }
+
   /// Return the result of resolve the given [uriContent], reporting errors
   /// against the [uriLiteral].
   Source? _resolveUri(FileState file, bool isImport, StringLiteral uriLiteral,
@@ -813,12 +827,12 @@
         directive.uriSource = defaultSource;
       }
       if (directive is NamespaceDirectiveImpl) {
-        var relativeUri = _selectRelativeUri(directive);
-        directive.selectedUriContent = relativeUri;
-        directive.selectedSource = _sourceFactory.resolveUri(
-          _library.source,
-          relativeUri,
-        );
+        var relativeUriStr = _selectRelativeUri(directive);
+        directive.selectedUriContent = relativeUriStr;
+        var absoluteUri = _resolveRelativeUri(relativeUriStr);
+        if (absoluteUri != null) {
+          directive.selectedSource = _sourceFactory.forUri2(absoluteUri);
+        }
         for (var configuration in directive.configurations) {
           configuration as ConfigurationImpl;
           var uriLiteral = configuration.uri;
diff --git a/pkg/analyzer/lib/src/summary2/element_builder.dart b/pkg/analyzer/lib/src/summary2/element_builder.dart
index 5d1e535..794ef17 100644
--- a/pkg/analyzer/lib/src/summary2/element_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/element_builder.dart
@@ -13,6 +13,7 @@
 import 'package:analyzer/src/summary2/link.dart';
 import 'package:analyzer/src/summary2/reference.dart';
 import 'package:analyzer/src/util/comment.dart';
+import 'package:analyzer/src/util/uri.dart';
 import 'package:collection/collection.dart';
 
 class ElementBuilder extends ThrowingAstVisitor<void> {
@@ -997,16 +998,24 @@
     if (relativeUriStr == null) {
       return null;
     }
-    var relativeUri = Uri.parse(relativeUriStr);
-    return resolveRelativeUri(_libraryBuilder.uri, relativeUri);
+
+    Uri relativeUri;
+    try {
+      relativeUri = Uri.parse(relativeUriStr);
+    } on FormatException {
+      return null;
+    }
+
+    var absoluteUri = resolveRelativeUri(_libraryBuilder.uri, relativeUri);
+
+    var sourceFactory = _linker.analysisContext.sourceFactory;
+    return rewriteFileToPackageUri(sourceFactory, absoluteUri);
   }
 
   LibraryElement? _selectLibrary(NamespaceDirective node) {
-    try {
-      var uri = _selectAbsoluteUri(node);
+    var uri = _selectAbsoluteUri(node);
+    if (uri != null) {
       return _linker.elementFactory.libraryOfUri('$uri');
-    } on FormatException {
-      return null;
     }
   }
 
diff --git a/pkg/analyzer/lib/src/util/uri.dart b/pkg/analyzer/lib/src/util/uri.dart
index 963dafc..4192e3f 100644
--- a/pkg/analyzer/lib/src/util/uri.dart
+++ b/pkg/analyzer/lib/src/util/uri.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:analyzer/src/generated/source.dart';
 import 'package:path/path.dart';
 
 String fileUriToNormalizedPath(Context context, Uri fileUri) {
@@ -10,3 +11,28 @@
   path = context.normalize(path);
   return path;
 }
+
+/// If the [absoluteUri] is a `file` URI that has corresponding `package` URI,
+/// return it. If the URI is not valid, e.g. has empty path segments, so
+/// does not represent a valid file path, return `null`.
+Uri? rewriteFileToPackageUri(SourceFactory sourceFactory, Uri absoluteUri) {
+  // Only file URIs get rewritten into package URIs.
+  if (!absoluteUri.isScheme('file')) {
+    return absoluteUri;
+  }
+
+  // It must be a valid URI, e.g. `file:///home/` is not.
+  var pathSegments = absoluteUri.pathSegments;
+  if (pathSegments.isEmpty || pathSegments.last.isEmpty) {
+    return null;
+  }
+
+  // We ask for Source only because `restoreUri` needs it.
+  // TODO(scheglov) Add more direct way to convert a path to URI.
+  var source = sourceFactory.forUri2(absoluteUri);
+  if (source == null) {
+    return null;
+  }
+
+  return sourceFactory.restoreUri(source);
+}
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index de37c97..35c3ab2 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -1952,16 +1952,13 @@
       expect(result.errors, isEmpty);
     }
 
-    // Analysis of my_pkg/bin/b.dart produces the error "A value of type
-    // 'String' can't be assigned to a variable of type 'int'", because
-    // file:///my_pkg/bin/b.dart imports file:///my_pkg/lib/c.dart, which
-    // successfully imports file:///my_pkg/test/d.dart, causing y to have an
-    // inferred type of String.
+    // Analysis of my_pkg/bin/a.dart produces no error because
+    // the import `../lib/c.dart` is resolved to package:my_pkg/c.dart, and
+    // package:my_pkg/c.dart's import is erroneous, causing y's reference to z
+    // to be unresolved (and therefore have type dynamic).
     {
       ResolvedUnitResult result = await driver.getResultValid(b);
-      List<AnalysisError> errors = result.errors;
-      expect(errors, hasLength(1));
-      expect(errors[0].errorCode, CompileTimeErrorCode.INVALID_ASSIGNMENT);
+      expect(result.errors, isEmpty);
     }
   }
 
@@ -2028,8 +2025,10 @@
 
     {
       ResolvedUnitResult result = await driver.getResultValid(b);
-      expect(_getImportSource(result.unit, 0).uri.toString(),
-          'package:test/a.dart');
+      expect(
+        _getImportSource(result.unit, 0).uri,
+        Uri.parse('package:test/a.dart'),
+      );
       _assertTopLevelVarType(result.unit, 'VB', 'A<int>');
     }
 
@@ -2037,7 +2036,7 @@
       ResolvedUnitResult result = await driver.getResultValid(c);
       expect(
         _getImportSource(result.unit, 0).uri,
-        toUri('/test/lib/a.dart'),
+        Uri.parse('package:test/a.dart'),
       );
       _assertTopLevelVarType(result.unit, 'VC', 'A<double>');
     }
diff --git a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
index b298989..6899a94 100644
--- a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
@@ -23,7 +23,6 @@
 import 'package:analyzer/src/source/package_map_resolver.dart';
 import 'package:analyzer/src/test_utilities/mock_sdk.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
-import 'package:analyzer/src/util/either.dart';
 import 'package:analyzer/src/workspace/basic.dart';
 import 'package:convert/convert.dart';
 import 'package:crypto/crypto.dart';
@@ -268,8 +267,6 @@
     expect(file.libraryFiles, [file, file.partedFiles[0]]);
 
     expect(_excludeSdk(file.directReferencedFiles), hasLength(5));
-
-    expect(fileSystemState.getFilesForPath(a1), [file]);
   }
 
   test_getFileForPath_onlyDartFiles() {
@@ -363,27 +360,6 @@
     );
   }
 
-  test_getFileForUri_packageVsFileUri() {
-    String path = convertPath('/aaa/lib/a.dart');
-    var packageUri = Uri.parse('package:aaa/a.dart');
-    var fileUri = toUri(path);
-
-    // The files with `package:` and `file:` URIs are different.
-    var filePackageUri = fileSystemState.getFileForUri(packageUri).asFileState;
-    var fileFileUri = fileSystemState.getFileForUri(fileUri).asFileState;
-    expect(filePackageUri, isNot(same(fileFileUri)));
-
-    expect(filePackageUri.path, path);
-    expect(filePackageUri.uri, packageUri);
-
-    expect(fileFileUri.path, path);
-    expect(fileFileUri.uri, fileUri);
-
-    // The file with the `package:` style URI is canonical, and is the first.
-    var files = fileSystemState.getFilesForPath(path);
-    expect(files, [filePackageUri, fileFileUri]);
-  }
-
   test_getFilesSubtypingName() {
     String a = convertPath('/a.dart');
     String b = convertPath('/b.dart');
@@ -783,12 +759,3 @@
     throw StateError('Unexpected invocation of ${invocation.memberName}');
   }
 }
-
-extension on Either2<FileState?, ExternalLibrary> {
-  FileState get asFileState {
-    return map(
-      (file) => file!,
-      (_) => fail('Expected a file'),
-    );
-  }
-}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
index 5a09829..e045770 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
@@ -13,11 +13,13 @@
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/summary2/bundle_reader.dart';
 import 'package:analyzer/src/summary2/informative_data.dart';
 import 'package:analyzer/src/summary2/link.dart';
 import 'package:analyzer/src/summary2/linked_element_factory.dart';
 import 'package:analyzer/src/summary2/reference.dart';
+import 'package:analyzer/src/util/uri.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'element_text.dart';
@@ -196,11 +198,9 @@
   void _addNonDartLibraries(
     Set<Source> addedLibraries,
     List<LinkInputLibrary> libraries,
-    Source? source,
+    Source source,
   ) {
-    if (source == null ||
-        source.uri.isScheme('dart') ||
-        !addedLibraries.add(source)) {
+    if (source.uri.isScheme('dart') || !addedLibraries.add(source)) {
       return;
     }
 
@@ -217,8 +217,29 @@
     );
 
     void addRelativeUriStr(StringLiteral uriNode) {
-      var uriStr = uriNode.stringValue;
-      var uriSource = sourceFactory.resolveUri(source, uriStr);
+      var relativeUriStr = uriNode.stringValue;
+      if (relativeUriStr == null) {
+        return;
+      }
+
+      Uri relativeUri;
+      try {
+        relativeUri = Uri.parse(relativeUriStr);
+      } on FormatException {
+        return;
+      }
+
+      var absoluteUri = resolveRelativeUri(source.uri, relativeUri);
+      var rewrittenUri = rewriteFileToPackageUri(sourceFactory, absoluteUri);
+      if (rewrittenUri == null) {
+        return;
+      }
+
+      var uriSource = sourceFactory.forUri2(rewrittenUri);
+      if (uriSource == null) {
+        return;
+      }
+
       _addNonDartLibraries(addedLibraries, libraries, uriSource);
     }
 
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index bb3c056..450bc47 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -18936,8 +18936,7 @@
   test_import_short_absolute() async {
     testFile = '/my/project/bin/test.dart';
     // Note: "/a.dart" resolves differently on Windows vs. Posix.
-    var destinationPath =
-        resourceProvider.pathContext.fromUri(Uri.parse('/a.dart'));
+    var destinationPath = convertPath('/a.dart');
     addLibrarySource(destinationPath, 'class C {}');
     var library = await checkLibrary('import "/a.dart"; C c;');
     checkElementText(library, r'''
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
index 9b0c895..104fc79 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
@@ -17,6 +17,7 @@
     hide Element, ElementKind;
 import 'package:analyzer_plugin/src/utilities/change_builder/change_builder_core.dart';
 import 'package:analyzer_plugin/src/utilities/charcodes.dart';
+import 'package:analyzer_plugin/src/utilities/library.dart';
 import 'package:analyzer_plugin/src/utilities/string_utilities.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
@@ -1337,11 +1338,6 @@
   /// the names used in generated code, to information about these imports.
   Map<Uri, _LibraryToImport> librariesToImport = {};
 
-  /// A mapping from libraries that need to be imported relatively in order to
-  /// make visible the names used in generated code, to information about these
-  /// imports.
-  Map<String, _LibraryToImport> librariesToRelativelyImport = {};
-
   /// Initialize a newly created builder to build a source file edit within the
   /// change being built by the given [changeBuilder]. The file being edited has
   /// the given [resolvedUnit] and [timeStamp].
@@ -1350,10 +1346,7 @@
       : super(changeBuilder, resolvedUnit.path, timeStamp);
 
   @override
-  bool get hasEdits =>
-      super.hasEdits ||
-      librariesToImport.isNotEmpty ||
-      librariesToRelativelyImport.isNotEmpty;
+  bool get hasEdits => super.hasEdits || librariesToImport.isNotEmpty;
 
   @override
   void addInsertion(
@@ -1402,9 +1395,6 @@
     for (var entry in librariesToImport.entries) {
       copy.librariesToImport[entry.key] = entry.value;
     }
-    for (var entry in librariesToRelativelyImport.entries) {
-      copy.librariesToRelativelyImport[entry.key] = entry.value;
-    }
     return copy;
   }
 
@@ -1418,9 +1408,6 @@
     if (librariesToImport.isNotEmpty) {
       _addLibraryImports(librariesToImport.values);
     }
-    if (librariesToRelativelyImport.isNotEmpty) {
-      _addLibraryImports(librariesToRelativelyImport.values);
-    }
   }
 
   @override
@@ -1480,8 +1467,12 @@
     return ImportLibraryElementResultImpl(null);
   }
 
-  String importLibraryWithRelativeUri(String uriText, [String? prefix]) {
-    return _importLibraryWithRelativeUri(uriText, prefix).uriText;
+  String importLibraryWithAbsoluteUri(Uri uri, [String? prefix]) {
+    return _importLibrary(uri, prefix: prefix, forceAbsolute: true).uriText;
+  }
+
+  String importLibraryWithRelativeUri(Uri uri, [String? prefix]) {
+    return _importLibrary(uri, prefix: prefix, forceRelative: true).uriText;
   }
 
   @override
@@ -1720,24 +1711,55 @@
   }
 
   /// Computes the best URI to import [uri] into the target library.
-  String _getLibraryUriText(Uri uri) {
-    if (uri.scheme == 'file') {
-      var pathContext = resolvedUnit.session.resourceProvider.pathContext;
-      var whatPath = pathContext.fromUri(uri);
+  ///
+  /// [uri] may be converted from an absolute URI to a relative URI depending on
+  /// user preferences/lints unless [forceAbsolute] or [forceRelative] are `true`.
+  String _getLibraryUriText(
+    Uri uri, {
+    bool forceAbsolute = false,
+    bool forceRelative = false,
+  }) {
+    var pathContext = resolvedUnit.session.resourceProvider.pathContext;
+
+    /// Returns the relative path to import [whatPath] into [resolvedUnit].
+    String getRelativePath(String whatPath) {
       var libraryPath = resolvedUnit.libraryElement.source.fullName;
       var libraryFolder = pathContext.dirname(libraryPath);
       var relativeFile = pathContext.relative(whatPath, from: libraryFolder);
       return pathContext.split(relativeFile).join('/');
     }
+
+    if (uri.isScheme('file')) {
+      var whatPath = pathContext.fromUri(uri);
+      return getRelativePath(whatPath);
+    }
+    var preferRelative = _isLintEnabled('prefer_relative_imports');
+    if (forceRelative || (preferRelative && !forceAbsolute)) {
+      if (canBeRelativeImport(uri, resolvedUnit.uri)) {
+        var whatPath = resolvedUnit.session.uriConverter.uriToPath(uri);
+        if (whatPath != null) {
+          return getRelativePath(whatPath);
+        }
+      }
+    }
     return uri.toString();
   }
 
   /// Arrange to have an import added for the library with the given [uri].
-  _LibraryToImport _importLibrary(Uri uri) {
+  ///
+  /// [uri] may be converted from an absolute URI to a relative URI depending on
+  /// user preferences/lints unless [forceAbsolute] or [forceRelative] are `true`.
+  _LibraryToImport _importLibrary(
+    Uri uri, {
+    String? prefix,
+    bool forceAbsolute = false,
+    bool forceRelative = false,
+  }) {
     var import = (libraryChangeBuilder ?? this).librariesToImport[uri];
     if (import == null) {
-      var uriText = _getLibraryUriText(uri);
-      var prefix =
+      var uriText = _getLibraryUriText(uri,
+          forceAbsolute: forceAbsolute, forceRelative: forceRelative);
+      prefix ??=
           importPrefixGenerator != null ? importPrefixGenerator!(uri) : null;
       import = _LibraryToImport(uriText, prefix);
       (libraryChangeBuilder ?? this).librariesToImport[uri] = import;
@@ -1745,23 +1767,17 @@
     return import;
   }
 
-  /// Arrange to have an import added for the library with the given relative
-  /// [uriText].
-  _LibraryToImport _importLibraryWithRelativeUri(String uriText,
-      [String? prefix]) {
-    var import = librariesToRelativelyImport[uriText];
-    if (import == null) {
-      import = _LibraryToImport(uriText, prefix);
-      librariesToRelativelyImport[uriText] = import;
-    }
-    return import;
-  }
-
   /// Return `true` if the [element] is defined in the target library.
   bool _isDefinedLocally(Element element) {
     return element.library == resolvedUnit.libraryElement;
   }
 
+  bool _isLintEnabled(String lintName) {
+    final analysisOptions =
+        resolvedUnit.session.analysisContext.analysisOptions;
+    return analysisOptions.isLintEnabled(lintName);
+  }
+
   /// Create an edit to replace the return type of the innermost function
   /// containing the given [node] with the type `Future`. The [typeProvider] is
   /// used to check the current return type, because if it is already `Future`
diff --git a/pkg/analyzer_plugin/lib/src/utilities/library.dart b/pkg/analyzer_plugin/lib/src/utilities/library.dart
new file mode 100644
index 0000000..8fa8383
--- /dev/null
+++ b/pkg/analyzer_plugin/lib/src/utilities/library.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Checks whether importing the library with URI [library2] into the
+/// library with URI [library1] could be a relative import.
+///
+/// Both URIs must be package: URIs and belong to the same package for this to
+/// be true.
+bool canBeRelativeImport(Uri library1, Uri library2) {
+  return library1.isScheme('package') &&
+      library2.isScheme('package') &&
+      library1.pathSegments.isNotEmpty &&
+      library2.pathSegments.isNotEmpty &&
+      library1.pathSegments.first == library2.pathSegments.first;
+}
diff --git a/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
index 6bd6c78..4eababe 100644
--- a/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
@@ -346,6 +346,9 @@
   ///
   /// Returns the text of the URI that will be used in the import directive.
   /// It can be different than the given [Uri].
+  ///
+  /// [uri] may be converted from an absolute URI to a relative URI depending on
+  /// user preferences/lints.
   String importLibrary(Uri uri);
 
   /// Ensure that the library with the given [uri] is imported.
diff --git a/pkg/dart2native/lib/dart2native.dart b/pkg/dart2native/lib/dart2native.dart
index f5f0dfe..be47b4c 100644
--- a/pkg/dart2native/lib/dart2native.dart
+++ b/pkg/dart2native/lib/dart2native.dart
@@ -6,8 +6,8 @@
 import 'dart:typed_data';
 
 // Maximum page size across all supported architectures (arm64 macOS has 16K
-// pages, the rest are all 4k pages).
-const elfPageSize = 16384;
+// pages, some arm64 Linux distributions have 64K pages).
+const elfPageSize = 65536;
 const appjitMagicNumber = <int>[0xdc, 0xdc, 0xf6, 0xf6, 0, 0, 0, 0];
 
 enum Kind { aot, exe }
diff --git a/pkg/dev_compiler/bin/dartdevc.dart b/pkg/dev_compiler/bin/dartdevc.dart
old mode 100755
new mode 100644
index 4d8d197..09d9ca8
--- a/pkg/dev_compiler/bin/dartdevc.dart
+++ b/pkg/dev_compiler/bin/dartdevc.dart
@@ -1,5 +1,5 @@
 #!/usr/bin/env dart
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
@@ -8,106 +8,14 @@
 /// Command line entry point for Dart Development Compiler (dartdevc), used to
 /// compile a collection of dart libraries into a single JS module
 
-import 'dart:async';
-import 'dart:convert';
-import 'dart:io';
 import 'dart:isolate';
-import 'package:bazel_worker/bazel_worker.dart';
-import 'package:dev_compiler/src/compiler/shared_command.dart';
-import 'package:dev_compiler/src/kernel/expression_compiler_worker.dart';
+
+import 'package:dev_compiler/ddc.dart' as ddc;
 
 /// The entry point for the Dart Dev Compiler.
 ///
 /// [sendPort] may be passed in when started in an isolate. If provided, it is
 /// used for bazel worker communication instead of stdin/stdout.
 Future main(List<String> args, [SendPort sendPort]) async {
-  // Always returns a new modifiable list.
-  var parsedArgs = ParsedArguments.from(args);
-
-  if (parsedArgs.isWorker) {
-    var workerConnection = sendPort == null
-        ? StdAsyncWorkerConnection()
-        : SendPortAsyncWorkerConnection(sendPort);
-    await _CompilerWorker(parsedArgs, workerConnection).run();
-  } else if (parsedArgs.isBatch) {
-    await runBatch(parsedArgs);
-  } else if (parsedArgs.isExpressionCompiler) {
-    await ExpressionCompilerWorker.createAndStart(parsedArgs.rest,
-        sendPort: sendPort);
-  } else {
-    var result = await compile(parsedArgs);
-    exitCode = result.exitCode;
-  }
-}
-
-/// Runs the compiler worker loop.
-class _CompilerWorker extends AsyncWorkerLoop {
-  /// The original args supplied to the executable.
-  final ParsedArguments _startupArgs;
-
-  _CompilerWorker(this._startupArgs, AsyncWorkerConnection workerConnection)
-      : super(connection: workerConnection);
-
-  /// Keeps track of our last compilation result so it can potentially be
-  /// re-used in a worker.
-  CompilerResult lastResult;
-
-  /// Performs each individual work request.
-  @override
-  Future<WorkResponse> performRequest(WorkRequest request) async {
-    var args = _startupArgs.merge(request.arguments);
-    var output = StringBuffer();
-    var context = args.reuseResult ? lastResult : null;
-
-    /// Build a map of uris to digests.
-    final inputDigests = <Uri, List<int>>{};
-    for (var input in request.inputs) {
-      inputDigests[sourcePathToUri(input.path)] = input.digest;
-    }
-
-    lastResult = await runZoned(
-        () =>
-            compile(args, previousResult: context, inputDigests: inputDigests),
-        zoneSpecification:
-            ZoneSpecification(print: (self, parent, zone, message) {
-      output.writeln(message.toString());
-    }));
-    return WorkResponse()
-      ..exitCode = lastResult.success ? 0 : 1
-      ..output = output.toString();
-  }
-}
-
-/// Runs DDC in Kernel batch mode for test.dart.
-Future runBatch(ParsedArguments batchArgs) async {
-  var totalTests = 0;
-  var failedTests = 0;
-  var watch = Stopwatch()..start();
-
-  print('>>> BATCH START');
-
-  String line;
-  CompilerResult result;
-
-  while ((line = stdin.readLineSync(encoding: utf8))?.isNotEmpty == true) {
-    totalTests++;
-    var args = batchArgs.merge(line.split(RegExp(r'\s+')));
-
-    String outcome;
-    try {
-      result = await compile(args, previousResult: result);
-      outcome = result.success ? 'PASS' : (result.crashed ? 'CRASH' : 'FAIL');
-    } catch (e, s) {
-      outcome = 'CRASH';
-      print('Unhandled exception:');
-      print(e);
-      print(s);
-    }
-
-    stderr.writeln('>>> EOF STDERR');
-    print('>>> TEST $outcome ${watch.elapsedMilliseconds}ms');
-  }
-
-  var time = watch.elapsedMilliseconds;
-  print('>>> BATCH END (${totalTests - failedTests})/$totalTests ${time}ms');
+  return ddc.internalMain(args, sendPort);
 }
diff --git a/pkg/dev_compiler/lib/ddc.dart b/pkg/dev_compiler/lib/ddc.dart
new file mode 100755
index 0000000..5911cd9
--- /dev/null
+++ b/pkg/dev_compiler/lib/ddc.dart
@@ -0,0 +1,113 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+/// Command line entry point for Dart Development Compiler (dartdevc), used to
+/// compile a collection of dart libraries into a single JS module
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+import 'dart:isolate';
+import 'package:bazel_worker/bazel_worker.dart';
+
+import 'src/compiler/shared_command.dart';
+import 'src/kernel/expression_compiler_worker.dart';
+
+/// The internal entry point for the Dart Dev Compiler.
+///
+/// [sendPort] may be passed in when started in an isolate. If provided, it is
+/// used for bazel worker communication instead of stdin/stdout.
+Future internalMain(List<String> args, [SendPort sendPort]) async {
+  // Always returns a new modifiable list.
+  var parsedArgs = ParsedArguments.from(args);
+
+  if (parsedArgs.isWorker) {
+    var workerConnection = sendPort == null
+        ? StdAsyncWorkerConnection()
+        : SendPortAsyncWorkerConnection(sendPort);
+    await _CompilerWorker(parsedArgs, workerConnection).run();
+  } else if (parsedArgs.isBatch) {
+    await runBatch(parsedArgs);
+  } else if (parsedArgs.isExpressionCompiler) {
+    await ExpressionCompilerWorker.createAndStart(parsedArgs.rest,
+        sendPort: sendPort);
+  } else {
+    var result = await compile(parsedArgs);
+    exitCode = result.exitCode;
+  }
+}
+
+/// Runs the compiler worker loop.
+class _CompilerWorker extends AsyncWorkerLoop {
+  /// The original args supplied to the executable.
+  final ParsedArguments _startupArgs;
+
+  _CompilerWorker(this._startupArgs, AsyncWorkerConnection workerConnection)
+      : super(connection: workerConnection);
+
+  /// Keeps track of our last compilation result so it can potentially be
+  /// re-used in a worker.
+  CompilerResult lastResult;
+
+  /// Performs each individual work request.
+  @override
+  Future<WorkResponse> performRequest(WorkRequest request) async {
+    var args = _startupArgs.merge(request.arguments);
+    var output = StringBuffer();
+    var context = args.reuseResult ? lastResult : null;
+
+    /// Build a map of uris to digests.
+    final inputDigests = <Uri, List<int>>{};
+    for (var input in request.inputs) {
+      inputDigests[sourcePathToUri(input.path)] = input.digest;
+    }
+
+    lastResult = await runZoned(
+        () =>
+            compile(args, previousResult: context, inputDigests: inputDigests),
+        zoneSpecification:
+            ZoneSpecification(print: (self, parent, zone, message) {
+      output.writeln(message.toString());
+    }));
+    return WorkResponse()
+      ..exitCode = lastResult.success ? 0 : 1
+      ..output = output.toString();
+  }
+}
+
+/// Runs DDC in Kernel batch mode for test.dart.
+Future runBatch(ParsedArguments batchArgs) async {
+  var totalTests = 0;
+  var failedTests = 0;
+  var watch = Stopwatch()..start();
+
+  print('>>> BATCH START');
+
+  String line;
+  CompilerResult result;
+
+  while ((line = stdin.readLineSync(encoding: utf8))?.isNotEmpty == true) {
+    totalTests++;
+    var args = batchArgs.merge(line.split(RegExp(r'\s+')));
+
+    String outcome;
+    try {
+      result = await compile(args, previousResult: result);
+      outcome = result.success ? 'PASS' : (result.crashed ? 'CRASH' : 'FAIL');
+    } catch (e, s) {
+      outcome = 'CRASH';
+      print('Unhandled exception:');
+      print(e);
+      print(s);
+    }
+
+    stderr.writeln('>>> EOF STDERR');
+    print('>>> TEST $outcome ${watch.elapsedMilliseconds}ms');
+  }
+
+  var time = watch.elapsedMilliseconds;
+  print('>>> BATCH END (${totalTests - failedTests})/$totalTests ${time}ms');
+}
diff --git a/runtime/include/dart_tools_api.h b/runtime/include/dart_tools_api.h
index 6d02750..1a2d9bb 100644
--- a/runtime/include/dart_tools_api.h
+++ b/runtime/include/dart_tools_api.h
@@ -222,25 +222,6 @@
     Dart_ServiceStreamCancelCallback cancel_callback);
 
 /**
- * A callback invoked when the VM service receives an event.
- */
-typedef void (*Dart_NativeStreamConsumer)(const uint8_t* event_json,
-                                          intptr_t event_json_length);
-
-/**
- * Sets the native VM service stream callbacks for a particular stream.
- * Note: The function may be called on multiple threads concurrently.
- *
- * \param consumer A function pointer to an event handler callback function.
- *   A NULL value removes the existing listen callback function if any.
- *
- * \param stream_id The ID of the stream on which to set the callback.
- */
-DART_EXPORT void Dart_SetNativeServiceStreamCallback(
-    Dart_NativeStreamConsumer consumer,
-    const char* stream_id);
-
-/**
  * Sends a data event to clients of the VM Service.
  *
  * A data event is used to pass an array of bytes to subscribed VM
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 00a1877..2dbd8d3 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -15,6 +15,9 @@
 #include "vm/dart_api_state.h"
 #include "vm/dart_entry.h"
 #include "vm/debugger.h"
+#if defined(DART_PRECOMPILED_RUNTIME) && defined(DART_TARGET_OS_LINUX)
+#include "vm/elf.h"
+#endif
 #include "vm/flags.h"
 #include "vm/handles.h"
 #include "vm/heap/become.h"
@@ -298,6 +301,16 @@
   }
   start_time_micros_ = OS::GetCurrentMonotonicMicros();
   VirtualMemory::Init();
+
+#if defined(DART_PRECOMPILED_RUNTIME) && defined(DART_TARGET_OS_LINUX)
+  if (VirtualMemory::PageSize() > kElfPageSize) {
+    return Utils::SCreate(
+        "Incompatible page size for AOT compiled ELF: expected at most %" Pd
+        ", got %" Pd "",
+        kElfPageSize, VirtualMemory::PageSize());
+  }
+#endif
+
   OSThread::Init();
   Zone::Init();
 #if defined(SUPPORT_TIMELINE)
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 437ce6f..082476f 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -6195,14 +6195,6 @@
 #endif
 }
 
-DART_EXPORT void Dart_SetNativeServiceStreamCallback(
-    Dart_NativeStreamConsumer consumer,
-    const char* stream_id) {
-#if !defined(PRODUCT)
-  Service::SetNativeServiceStreamCallback(consumer, stream_id);
-#endif
-}
-
 DART_EXPORT char* Dart_ServiceSendDataEvent(const char* stream_id,
                                             const char* event_kind,
                                             const uint8_t* bytes,
diff --git a/runtime/vm/elf.h b/runtime/vm/elf.h
index 579c49f..3bf980d 100644
--- a/runtime/vm/elf.h
+++ b/runtime/vm/elf.h
@@ -5,14 +5,30 @@
 #ifndef RUNTIME_VM_ELF_H_
 #define RUNTIME_VM_ELF_H_
 
+#include "platform/globals.h"
+
+#if defined(DART_PRECOMPILER)
 #include "vm/allocation.h"
 #include "vm/compiler/runtime_api.h"
 #include "vm/datastream.h"
 #include "vm/growable_array.h"
 #include "vm/zone.h"
+#endif
 
 namespace dart {
 
+// The max page size on all supported architectures. Used to determine
+// the alignment of load segments, so that they are guaranteed page-aligned,
+// and no ELF section or segment should have a larger alignment.
+#if defined(DART_TARGET_OS_LINUX) && defined(TARGET_ARCH_ARM64)
+// Some Linux distributions on ARM64 select 64 KB page size.
+// Follow LLVM (https://reviews.llvm.org/D25079) and set maximum page size
+// to 64 KB for ARM64 Linux builds.
+static constexpr intptr_t kElfPageSize = 64 * KB;
+#else
+static constexpr intptr_t kElfPageSize = 16 * KB;
+#endif
+
 #if defined(DART_PRECOMPILER)
 
 class Dwarf;
@@ -33,10 +49,7 @@
 
   Elf(Zone* zone, BaseWriteStream* stream, Type type, Dwarf* dwarf = nullptr);
 
-  // The max page size on all supported architectures. Used to determine
-  // the alignment of load segments, so that they are guaranteed page-aligned,
-  // and no ELF section or segment should have a larger alignment.
-  static constexpr intptr_t kPageSize = 16 * KB;
+  static constexpr intptr_t kPageSize = kElfPageSize;
 
   bool IsStripped() const { return dwarf_ == nullptr; }
 
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index b70dea0..b7576a4 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -1192,14 +1192,6 @@
   }
   PostEvent(event->isolate(), stream_id, event->KindAsCString(), &js,
             enter_safepoint);
-
-  // Post event to the native Service Stream handlers if set.
-  if (event->stream_info() != nullptr &&
-      event->stream_info()->consumer() != nullptr) {
-    auto length = js.buffer()->length();
-    event->stream_info()->consumer()(
-        reinterpret_cast<uint8_t*>(js.buffer()->buffer()), length);
-  }
 }
 
 void Service::PostEvent(Isolate* isolate,
@@ -1387,17 +1379,6 @@
   stream_cancel_callback_ = cancel_callback;
 }
 
-void Service::SetNativeServiceStreamCallback(Dart_NativeStreamConsumer consumer,
-                                             const char* stream_id) {
-  for (auto stream : streams_) {
-    if (stream->id() == stream_id) {
-      stream->set_consumer(consumer);
-    }
-  }
-  // Enable stream.
-  ListenStream(stream_id);
-}
-
 void Service::SetGetServiceAssetsCallback(
     Dart_GetVMServiceAssetsArchive get_service_assets) {
   get_service_assets_callback_ = get_service_assets;
diff --git a/runtime/vm/service.h b/runtime/vm/service.h
index f51eb10..d519124 100644
--- a/runtime/vm/service.h
+++ b/runtime/vm/service.h
@@ -75,15 +75,9 @@
   void set_enabled(bool value) { enabled_ = value; }
   bool enabled() const { return enabled_; }
 
-  void set_consumer(Dart_NativeStreamConsumer consumer) {
-    callback_ = consumer;
-  }
-  Dart_NativeStreamConsumer consumer() const { return callback_; }
-
  private:
   const char* id_;
   bool enabled_;
-  Dart_NativeStreamConsumer callback_;
 };
 
 class Service : public AllStatic {
@@ -116,9 +110,6 @@
       Dart_ServiceStreamListenCallback listen_callback,
       Dart_ServiceStreamCancelCallback cancel_callback);
 
-  static void SetNativeServiceStreamCallback(Dart_NativeStreamConsumer consumer,
-                                             const char* stream_id);
-
   static void SetGetServiceAssetsCallback(
       Dart_GetVMServiceAssetsArchive get_service_assets);
 
diff --git a/tools/VERSION b/tools/VERSION
index 7a5b83a..b08b806 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 16
 PATCH 0
-PRERELEASE 18
+PRERELEASE 19
 PRERELEASE_PATCH 0
\ No newline at end of file