blob: 2f0e3b0c1fcb6ec133d079824f11626fe3fbb0da [file] [log] [blame]
// Copyright (c) 2016, 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.
library fasta.translate_uri;
import 'dart:async' show Future;
import 'dart:convert' show JSON;
import 'package:front_end/file_system.dart'
show FileSystem, FileSystemException;
import 'package:package_config/packages_file.dart' as packages_file show parse;
import 'deprecated_problems.dart' show deprecated_inputError;
class TranslateUri {
final Map<String, Uri> packages;
final Map<String, Uri> dartLibraries;
// TODO(ahe): We probably want this to be `Map<String, Uri>`, that is, just
// one patch library (with parts).
final Map<String, List<Uri>> patches;
TranslateUri(this.packages, this.dartLibraries, this.patches);
Uri translate(Uri uri) {
if (uri.scheme == "dart") return translateDartUri(uri);
if (uri.scheme == "package") return translatePackageUri(uri);
return null;
}
Uri translateDartUri(Uri uri) {
if (!uri.isScheme('dart')) return null;
String path = uri.path;
int index = path.indexOf('/');
if (index == -1) return dartLibraries[path];
String libraryName = path.substring(0, index);
String relativePath = path.substring(index + 1);
Uri libraryFileUri = dartLibraries[libraryName];
return libraryFileUri?.resolve(relativePath);
}
Uri translatePackageUri(Uri uri) {
int index = uri.path.indexOf("/");
if (index == -1) return null;
String name = uri.path.substring(0, index);
String path = uri.path.substring(index + 1);
Uri root = packages[name];
if (root == null) return null;
return root.resolve(path);
}
/// Returns true if [uri] is private to the platform libraries (and thus not
/// accessible from user code).
bool isPlatformImplementation(Uri uri) {
if (uri.scheme != "dart") return false;
String path = uri.path;
return dartLibraries[path] == null || path.startsWith("_");
}
static Future<TranslateUri> parse(FileSystem fileSystem, Uri sdk,
{Uri packages}) async {
Uri librariesJson = sdk?.resolve("lib/libraries.json");
// TODO(ahe): Provide a value for this file.
Uri patches = null;
packages ??= Uri.base.resolve(".packages");
List<int> bytes;
try {
bytes = await fileSystem.entityForUri(packages).readAsBytes();
} on FileSystemException catch (e) {
deprecated_inputError(packages, -1, e.message);
}
Map<String, Uri> parsedPackages;
try {
parsedPackages = packages_file.parse(bytes, packages);
} on FormatException catch (e) {
return deprecated_inputError(packages, e.offset, e.message);
}
return new TranslateUri(
parsedPackages,
await computeLibraries(fileSystem, librariesJson),
await computePatches(fileSystem, patches));
}
}
Future<Map<String, Uri>> computeLibraries(
FileSystem fileSystem, Uri uri) async {
if (uri == null) return const <String, Uri>{};
Map<String, String> libraries = JSON
.decode(await fileSystem.entityForUri(uri).readAsString())["libraries"];
Map<String, Uri> result = <String, Uri>{};
libraries.forEach((String name, String path) {
result[name] = uri.resolveUri(new Uri.file(path));
});
return result;
}
Future<Map<String, List<Uri>>> computePatches(
FileSystem fileSystem, Uri uri) async {
// TODO(ahe): Read patch information.
return const <String, List<Uri>>{};
}