blob: db469f0003df510d13a843e5714d15aa220f65be [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.
import 'package:path/path.dart' as p;
/// The class `UriResolver` implements the rules for resolving URIs to file
/// paths.
///
/// TODO(paulberry): Is it necessary to support the "http" scheme?
class UriResolver {
/// A map from package name to the file URI of the "lib" directory of the
/// corresponding package. This is equivalent to the format returned by
/// the "package_config" package's parse() function.
final Map<String, Uri> packages;
/// A map from SDK library name (e.g. `core` for `dart:core`) to the file URI
/// of the defining compilation unit of the SDK library.
final Map<String, Uri> sdkLibraries;
/// The path context which should be used to convert from file URIs to file
/// paths.
final p.Context pathContext;
/// The URI scheme used for "package" URIs.
static const PACKAGE_SCHEME = 'package';
/// The URI scheme used for "dart" URIs.
static const DART_SCHEME = 'dart';
/// The URI scheme used for "file" URIs.
static const FILE_SCHEME = 'file';
UriResolver(this.packages, this.sdkLibraries, this.pathContext);
/// Converts a URI to a file path.
///
/// If the given URI is valid, and of a recognized form, returns the file path
/// it corresponds to. Otherwise returns `null`. It is not necessary for the
/// URI to be absolute (relative URIs will be converted to relative file
/// paths).
///
/// Note that no I/O is performed; the file path that is returned will be
/// independent of whether or not any particular file exists on the file
/// system.
String resolve(Uri uri) {
Uri fileUri;
if (uri.scheme == FILE_SCHEME) {
fileUri = uri;
} else {
var path = uri.path;
var slashIndex = path.indexOf('/');
String prefix;
String rest;
if (slashIndex >= 0) {
prefix = path.substring(0, slashIndex);
rest = path.substring(slashIndex + 1);
} else {
prefix = path;
rest = '';
}
Uri libUri;
if (uri.scheme == PACKAGE_SCHEME) {
if (slashIndex < 0) return null;
libUri = packages[prefix];
} else if (uri.scheme == DART_SCHEME) {
libUri = sdkLibraries[prefix];
}
if (libUri == null) return null;
fileUri = libUri.resolve(rest);
if (fileUri.scheme != FILE_SCHEME) return null;
}
return pathContext.fromUri(fileUri);
}
}