Refer to correct locations in SDK (and other dill files)

Fixes https://github.com/dart-lang/sdk/issues/35559
Fixes https://github.com/dart-lang/sdk/issues/35558

Change-Id: I902273759c6d3076779ccf120a79fd972d939827
Reviewed-on: https://dart-review.googlesource.com/c/90181
Reviewed-by: Jens Johansen <jensj@google.com>
Commit-Queue: Peter von der Ahé <ahe@google.com>
diff --git a/pkg/front_end/lib/src/compute_platform_binaries_location.dart b/pkg/front_end/lib/src/compute_platform_binaries_location.dart
index a1d1cdb..9ac1f54 100644
--- a/pkg/front_end/lib/src/compute_platform_binaries_location.dart
+++ b/pkg/front_end/lib/src/compute_platform_binaries_location.dart
@@ -2,7 +2,13 @@
 // 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 "dart:io" show Platform;
+import "dart:io" show File, Platform;
+
+import 'package:kernel/ast.dart' show Source;
+
+import 'base/processed_options.dart' show ProcessedOptions;
+
+import 'fasta/compiler_context.dart' show CompilerContext;
 
 /// Computes the location of platform binaries, that is, compiled `.dill` files
 /// of the platform libraries that are used to avoid recompiling those
@@ -22,3 +28,62 @@
     return vmDirectory;
   }
 }
+
+/// Translates an SDK URI ("org-dartlang-sdk:///...") to a file URI.
+Uri translateSdk(Uri uri) {
+  if (CompilerContext.isActive) {
+    if (uri.scheme == "org-dartlang-sdk") {
+      String path = uri.path;
+      if (path.startsWith("/sdk/")) {
+        CompilerContext context = CompilerContext.current;
+        Uri sdkRoot = context.cachedSdkRoot;
+        if (sdkRoot == null) {
+          ProcessedOptions options = context.options;
+          sdkRoot = options.sdkRoot;
+          if (sdkRoot == null) {
+            sdkRoot = options.librariesSpecificationUri?.resolve("../");
+            if (sdkRoot != null) {
+              if (!isExistingFile(sdkRoot.resolve("lib/libraries.json"))) {
+                sdkRoot = null;
+              }
+            }
+          }
+          if (sdkRoot == null) {
+            sdkRoot = (options.sdkSummary ?? computePlatformBinariesLocation())
+                .resolve("../../");
+            if (sdkRoot != null) {
+              if (!isExistingFile(sdkRoot.resolve("lib/libraries.json"))) {
+                if (isExistingFile(sdkRoot.resolve("sdk/lib/libraries.json"))) {
+                  sdkRoot = sdkRoot.resolve("sdk/");
+                } else {
+                  sdkRoot = null;
+                }
+              }
+            }
+          }
+          sdkRoot ??= Uri.parse("org-dartlang-sdk:///sdk/");
+          context.cachedSdkRoot = sdkRoot;
+        }
+        Uri candidate = sdkRoot.resolve(path.substring(5));
+        if (isExistingFile(candidate)) {
+          Map<Uri, Source> uriToSource = CompilerContext.current.uriToSource;
+          Source source = uriToSource[uri];
+          if (source.source.isEmpty) {
+            uriToSource[uri] = new Source(source.lineStarts,
+                new File.fromUri(candidate).readAsBytesSync());
+          }
+        }
+        return candidate;
+      }
+    }
+  }
+  return uri;
+}
+
+bool isExistingFile(Uri uri) {
+  if (uri.scheme == "file") {
+    return new File.fromUri(uri).existsSync();
+  } else {
+    return false;
+  }
+}
diff --git a/pkg/front_end/lib/src/fasta/command_line_reporting.dart b/pkg/front_end/lib/src/fasta/command_line_reporting.dart
index c191dbb..fbfd9df 100644
--- a/pkg/front_end/lib/src/fasta/command_line_reporting.dart
+++ b/pkg/front_end/lib/src/fasta/command_line_reporting.dart
@@ -14,6 +14,8 @@
 
 import 'package:kernel/ast.dart' show Location;
 
+import '../compute_platform_binaries_location.dart' show translateSdk;
+
 import 'colors.dart' show green, magenta, red;
 
 import 'compiler_context.dart' show CompilerContext;
@@ -72,7 +74,7 @@
     }
 
     if (message.uri != null) {
-      String path = relativizeUri(message.uri);
+      String path = relativizeUri(translateSdk(message.uri));
       int offset = message.charOffset;
       location ??= (offset == -1 ? null : getLocation(message.uri, offset));
       String sourceLine = getSourceLine(location);
diff --git a/pkg/front_end/lib/src/fasta/compiler_context.dart b/pkg/front_end/lib/src/fasta/compiler_context.dart
index acb6637..c861e50 100644
--- a/pkg/front_end/lib/src/fasta/compiler_context.dart
+++ b/pkg/front_end/lib/src/fasta/compiler_context.dart
@@ -54,6 +54,8 @@
 
   bool enableColorsCached = null;
 
+  Uri cachedSdkRoot = null;
+
   CompilerContext(this.options);
 
   void disableColors() {
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
index bba4295..89fb431 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
@@ -41,6 +41,8 @@
             parent,
             cls.fileOffset);
 
+  Uri get fileUri => cls.fileUri;
+
   KernelTypeBuilder get supertype {
     KernelTypeBuilder supertype = super.supertype;
     if (supertype == null) {
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
index 4671069..92b5c40 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
@@ -51,22 +51,22 @@
 import 'dill_typedef_builder.dart' show DillFunctionTypeAliasBuilder;
 
 class DillLibraryBuilder extends LibraryBuilder<KernelTypeBuilder, Library> {
-  final Uri uri;
+  final Library library;
 
   final DillLoader loader;
 
-  Library library;
-
   /// Exports that can't be serialized.
   ///
   /// The elements of this map are documented in
   /// [../kernel/kernel_library_builder.dart].
   Map<String, String> unserializableExports;
 
-  DillLibraryBuilder(this.uri, this.loader)
-      : super(uri, new Scope.top(), new Scope.top());
+  DillLibraryBuilder(this.library, this.loader)
+      : super(library.fileUri, new Scope.top(), new Scope.top());
 
-  Uri get fileUri => uri;
+  Uri get uri => library.importUri;
+
+  Uri get fileUri => library.fileUri;
 
   @override
   String get name => library.name;
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_loader.dart b/pkg/front_end/lib/src/fasta/dill/dill_loader.dart
index 3df5940..ccda959 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_loader.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_loader.dart
@@ -18,7 +18,6 @@
         InterfaceType,
         InvalidType,
         Library,
-        Source,
         TypeParameter,
         TypeParameterType,
         TypedefType,
@@ -27,8 +26,6 @@
 import '../fasta_codes.dart'
     show SummaryTemplate, Template, templateDillOutlineSummary;
 
-import '../compiler_context.dart' show CompilerContext;
-
 import '../kernel/kernel_builder.dart'
     show
         DynamicTypeBuilder,
@@ -48,16 +45,10 @@
 
 import 'dill_library_builder.dart' show DillLibraryBuilder;
 
+import 'dill_target.dart' show DillTarget;
+
 class DillLoader extends Loader<Library> {
-  /// Source targets are compiled against these binary libraries.
-  final libraries = <Library>[];
-
-  /// Sources for all appended components.
-  final Map<Uri, Source> uriToSource;
-
-  DillLoader(TargetImplementation target)
-      : uriToSource = CompilerContext.current.uriToSource,
-        super(target);
+  DillLoader(TargetImplementation target) : super(target);
 
   Template<SummaryTemplate> get outlineSummaryTemplate =>
       templateDillOutlineSummary;
@@ -66,18 +57,25 @@
   /// provided, append only libraries whose [Uri] is accepted by the [filter].
   List<DillLibraryBuilder> appendLibraries(Component component,
       {bool filter(Uri uri), int byteCount: 0}) {
-    var builders = <DillLibraryBuilder>[];
-    for (Library library in component.libraries) {
+    List<Library> componentLibraries = component.libraries;
+    List<Uri> requestedLibraries = <Uri>[];
+    DillTarget target = this.target;
+    for (int i = 0; i < componentLibraries.length; i++) {
+      Library library = componentLibraries[i];
+      Uri uri = library.importUri;
       if (filter == null || filter(library.importUri)) {
         libraries.add(library);
-        DillLibraryBuilder builder = read(library.importUri, -1);
-        builder.library = library;
-        builders.add(builder);
+        target.addLibrary(library);
+        requestedLibraries.add(uri);
       }
     }
-    uriToSource.addAll(component.uriToSource);
+    List<DillLibraryBuilder> result = <DillLibraryBuilder>[];
+    for (int i = 0; i < requestedLibraries.length; i++) {
+      result.add(read(requestedLibraries[i], -1));
+    }
+    target.uriToSource.addAll(component.uriToSource);
     this.byteCount += byteCount;
-    return builders;
+    return result;
   }
 
   Future<Null> buildOutline(DillLibraryBuilder builder) async {
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_target.dart b/pkg/front_end/lib/src/fasta/dill/dill_target.dart
index 63348b0..4771d2c 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_target.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_target.dart
@@ -6,6 +6,8 @@
 
 import 'dart:async' show Future;
 
+import 'package:kernel/ast.dart' show Library;
+
 import 'package:kernel/target/targets.dart' show Target;
 
 import '../kernel/kernel_builder.dart' show ClassBuilder;
@@ -23,7 +25,11 @@
 import 'dill_loader.dart' show DillLoader;
 
 class DillTarget extends TargetImplementation {
+  final Map<Uri, DillLibraryBuilder> libraryBuilders =
+      <Uri, DillLibraryBuilder>{};
+
   bool isLoaded = false;
+
   DillLoader loader;
 
   DillTarget(Ticker ticker, UriTranslator uriTranslator, Target backendTarget)
@@ -54,9 +60,14 @@
   @override
   DillLibraryBuilder createLibraryBuilder(Uri uri, Uri fileUri, origin) {
     assert(origin == null);
-    return new DillLibraryBuilder(uri, loader);
+    return libraryBuilders.remove(uri);
   }
 
   @override
   void breakCycle(ClassBuilder cls) {}
+
+  void addLibrary(Library library) {
+    libraryBuilders[library.importUri] =
+        new DillLibraryBuilder(library, loader);
+  }
 }
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 9527bf3..fc4788c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -111,9 +111,6 @@
 
   final DillTarget dillTarget;
 
-  /// Shared with [CompilerContext].
-  final Map<Uri, Source> uriToSource;
-
   /// The [MetadataCollector] to write metadata to.
   final MetadataCollector metadataCollector;
 
@@ -138,7 +135,6 @@
       UriTranslator uriTranslator,
       {MetadataCollector metadataCollector})
       : dillTarget = dillTarget,
-        uriToSource = CompilerContext.current.uriToSource,
         metadataCollector = metadataCollector,
         super(dillTarget.ticker, uriTranslator, dillTarget.backendTarget) {
     loader = createLoader();
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 8679e5a..bc2812a 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -767,7 +767,7 @@
     List<Library> workList = <Library>[];
     builders.forEach((Uri uri, LibraryBuilder library) {
       if (!library.isPatch &&
-          (library.loader == this || library.fileUri.scheme == "dart")) {
+          (library.loader == this || library.uri.scheme == "dart")) {
         if (libraries.add(library.target)) {
           workList.add(library.target);
         }
diff --git a/pkg/front_end/lib/src/fasta/target_implementation.dart b/pkg/front_end/lib/src/fasta/target_implementation.dart
index f18563b..85a5843 100644
--- a/pkg/front_end/lib/src/fasta/target_implementation.dart
+++ b/pkg/front_end/lib/src/fasta/target_implementation.dart
@@ -4,6 +4,8 @@
 
 library fasta.target_implementation;
 
+import 'package:kernel/ast.dart' show Source;
+
 import 'package:kernel/target/targets.dart' as backend show Target;
 
 import '../base/processed_options.dart' show ProcessedOptions;
@@ -36,6 +38,9 @@
 
   final CompilerContext context = CompilerContext.current;
 
+  /// Shared with [CompilerContext].
+  final Map<Uri, Source> uriToSource = CompilerContext.current.uriToSource;
+
   Declaration cachedAbstractClassInstantiationError;
   Declaration cachedCompileTimeError;
   Declaration cachedDuplicatedFieldInitializerError;
diff --git a/pkg/front_end/lib/src/fasta/testing/kernel_chain.dart b/pkg/front_end/lib/src/fasta/testing/kernel_chain.dart
index 33a3b06..cd00cb1 100644
--- a/pkg/front_end/lib/src/fasta/testing/kernel_chain.dart
+++ b/pkg/front_end/lib/src/fasta/testing/kernel_chain.dart
@@ -40,6 +40,9 @@
 
 import '../../base/processed_options.dart' show ProcessedOptions;
 
+import '../../compute_platform_binaries_location.dart'
+    show computePlatformBinariesLocation;
+
 import '../compiler_context.dart' show CompilerContext;
 
 import '../kernel/verifier.dart' show verifyComponent;
@@ -49,6 +52,10 @@
 import '../fasta_codes.dart'
     show templateInternalProblemUnhandled, templateUnspecified;
 
+import '../util/relativize.dart' show relativizeUri;
+
+final Uri platformBinariesLocation = computePlatformBinariesLocation();
+
 abstract class MatchContext implements ChainContext {
   bool get updateExpectations;
 
@@ -218,7 +225,16 @@
     new Printer(buffer)
       ..writeProblemsAsJson("Problems in component", component.problemsAsJson)
       ..writeLibraryFile(library);
-    String actual = "$buffer".replaceAll("$base", "org-dartlang-testcase:///");
+    String actual = "$buffer";
+    String binariesPath = relativizeUri(platformBinariesLocation);
+    if (binariesPath.endsWith("/dart-sdk/lib/_internal/")) {
+      // We are running from the built SDK.
+      actual = actual.replaceAll(
+          binariesPath.substring(
+              0, binariesPath.length - "lib/_internal/".length),
+          "sdk/");
+    }
+    actual = actual.replaceAll("$base", "org-dartlang-testcase:///");
     actual = actual.replaceAll("$dartBase", "org-dartlang-testcase-sdk:///");
     actual = actual.replaceAll("\\n", "\n");
     return context.match<Component>(suffix, actual, uri, component);
diff --git a/pkg/front_end/testcases/sdk_diagnostic.dart.legacy.expect b/pkg/front_end/testcases/sdk_diagnostic.dart.legacy.expect
index f5f28d0..15c2801 100644
--- a/pkg/front_end/testcases/sdk_diagnostic.dart.legacy.expect
+++ b/pkg/front_end/testcases/sdk_diagnostic.dart.legacy.expect
@@ -12,12 +12,14 @@
 //
 // class C extends Iterable<Object> {
 //       ^
-// dart:core:1: Context: 'Iterable.iterator' is defined here.
+// sdk/lib/core/iterable.dart:154:19: Context: 'Iterable.iterator' is defined here.
+//   Iterator<E> get iterator;
+//                   ^^^^^^^^
 //
 // pkg/front_end/testcases/sdk_diagnostic.dart:12:8: Warning: Too few positional arguments: 1 required, 0 given.
 //   print(incorrectArgument: "fisk");
 //        ^
-// org-dartlang-sdk:///sdk/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match.
+// sdk/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match.
 // void print(Object object) {
 //      ^^^^^
 //
diff --git a/pkg/front_end/testcases/sdk_diagnostic.dart.legacy.transformed.expect b/pkg/front_end/testcases/sdk_diagnostic.dart.legacy.transformed.expect
index f5f28d0..15c2801 100644
--- a/pkg/front_end/testcases/sdk_diagnostic.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/sdk_diagnostic.dart.legacy.transformed.expect
@@ -12,12 +12,14 @@
 //
 // class C extends Iterable<Object> {
 //       ^
-// dart:core:1: Context: 'Iterable.iterator' is defined here.
+// sdk/lib/core/iterable.dart:154:19: Context: 'Iterable.iterator' is defined here.
+//   Iterator<E> get iterator;
+//                   ^^^^^^^^
 //
 // pkg/front_end/testcases/sdk_diagnostic.dart:12:8: Warning: Too few positional arguments: 1 required, 0 given.
 //   print(incorrectArgument: "fisk");
 //        ^
-// org-dartlang-sdk:///sdk/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match.
+// sdk/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match.
 // void print(Object object) {
 //      ^^^^^
 //
diff --git a/pkg/front_end/testcases/sdk_diagnostic.dart.outline.expect b/pkg/front_end/testcases/sdk_diagnostic.dart.outline.expect
index 9431005..a472835 100644
--- a/pkg/front_end/testcases/sdk_diagnostic.dart.outline.expect
+++ b/pkg/front_end/testcases/sdk_diagnostic.dart.outline.expect
@@ -12,7 +12,9 @@
 //
 // class C extends Iterable<Object> {
 //       ^
-// dart:core:1: Context: 'Iterable.iterator' is defined here.
+// sdk/lib/core/iterable.dart:154:19: Context: 'Iterable.iterator' is defined here.
+//   Iterator<E> get iterator;
+//                   ^^^^^^^^
 //
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/sdk_diagnostic.dart.strong.expect b/pkg/front_end/testcases/sdk_diagnostic.dart.strong.expect
index 957c7d9..eb45ae6 100644
--- a/pkg/front_end/testcases/sdk_diagnostic.dart.strong.expect
+++ b/pkg/front_end/testcases/sdk_diagnostic.dart.strong.expect
@@ -12,12 +12,16 @@
 //
 // class C extends Iterable<Object> {
 //       ^
-// dart:core:1: Context: 'Iterable.iterator' is defined here.
+// sdk/lib/core/iterable.dart:154:19: Context: 'Iterable.iterator' is defined here.
+//   Iterator<E> get iterator;
+//                   ^^^^^^^^
 //
 // pkg/front_end/testcases/sdk_diagnostic.dart:12:8: Error: Too few positional arguments: 1 required, 0 given.
 //   print(incorrectArgument: "fisk");
 //        ^
-// org-dartlang-sdk:///sdk/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match.
+// sdk/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match.
+// void print(Object object) {
+//      ^^^^^
 //
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/sdk_diagnostic.dart.strong.transformed.expect b/pkg/front_end/testcases/sdk_diagnostic.dart.strong.transformed.expect
index 957c7d9..eb45ae6 100644
--- a/pkg/front_end/testcases/sdk_diagnostic.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/sdk_diagnostic.dart.strong.transformed.expect
@@ -12,12 +12,16 @@
 //
 // class C extends Iterable<Object> {
 //       ^
-// dart:core:1: Context: 'Iterable.iterator' is defined here.
+// sdk/lib/core/iterable.dart:154:19: Context: 'Iterable.iterator' is defined here.
+//   Iterator<E> get iterator;
+//                   ^^^^^^^^
 //
 // pkg/front_end/testcases/sdk_diagnostic.dart:12:8: Error: Too few positional arguments: 1 required, 0 given.
 //   print(incorrectArgument: "fisk");
 //        ^
-// org-dartlang-sdk:///sdk/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match.
+// sdk/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match.
+// void print(Object object) {
+//      ^^^^^
 //
 import self as self;
 import "dart:core" as core;