cbb4b0d59a
Review URL: https://codereview.chromium.org//12633010 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@19700 260f80e4-7a28-3924-810f-c04153c831b5
347 lines
11 KiB
Java
347 lines
11 KiB
Java
// Copyright (c) 2012, 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.
|
|
|
|
package com.google.dart.compiler;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.net.URI;
|
|
import java.net.URISyntaxException;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Collection;
|
|
import java.util.List;
|
|
|
|
|
|
/**
|
|
* Manages the collection of {@link SystemLibrary}s.
|
|
*/
|
|
public class PackageLibraryManager {
|
|
|
|
public static class NotADartShortUriException extends RuntimeException {
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
public NotADartShortUriException(String uriString) {
|
|
super("Expected dart:<short name>, got: " + uriString);
|
|
}
|
|
|
|
public NotADartShortUriException(URI uri) {
|
|
super("Expected dart:<short name>, got: " + uri.toString());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* The "any" platform is meant to have definitions for all known dart system libraries.
|
|
* Other implementations may only contain a subset.
|
|
*/
|
|
public static final String DEFAULT_PLATFORM = "any";
|
|
public static final File DEFAULT_SDK_PATH = new File(System.getProperty(
|
|
"com.google.dart.sdk", "../"));
|
|
|
|
public static final File DEFAULT_PACKAGE_ROOT = new File("packages");
|
|
public static final List<File> DEFAULT_PACKAGE_ROOTS = Arrays.asList(new File[] {DEFAULT_PACKAGE_ROOT});
|
|
|
|
public static final String PACKAGE_SCHEME = "package";
|
|
public static final String PACKAGE_SCHEME_SPEC = "package:";
|
|
|
|
public static final String DART_SCHEME = "dart";
|
|
public static final String DART_SCHEME_SPEC = "dart:";
|
|
|
|
|
|
/**
|
|
* Answer <code>true</code> if the string is a dart spec
|
|
*/
|
|
public static boolean isDartSpec(String spec) {
|
|
return spec != null && spec.startsWith(DART_SCHEME_SPEC);
|
|
}
|
|
|
|
/**
|
|
* Answer <code>true</code> if the specified URI has a "dart" scheme
|
|
*/
|
|
public static boolean isDartUri(URI uri) {
|
|
return uri != null && DART_SCHEME.equals(uri.getScheme());
|
|
}
|
|
|
|
/**
|
|
* Answer <code>true</code> if the string is a package spec
|
|
*/
|
|
public static boolean isPackageSpec(String spec) {
|
|
return spec != null && spec.startsWith(PACKAGE_SCHEME_SPEC);
|
|
}
|
|
|
|
/**
|
|
* Answer <code>true</code> if the specified URI has a "package" scheme
|
|
*/
|
|
public static boolean isPackageUri(URI uri) {
|
|
return uri != null && PACKAGE_SCHEME.equals(uri.getScheme());
|
|
}
|
|
|
|
private static SystemLibraryManager SDK_LIBRARY_MANAGER;
|
|
|
|
private List<File> packageRoots = new ArrayList<File>();
|
|
private List<URI> packageRootsUri = new ArrayList<URI>();
|
|
|
|
public PackageLibraryManager() {
|
|
this(DEFAULT_SDK_PATH, DEFAULT_PLATFORM);
|
|
}
|
|
|
|
public PackageLibraryManager(File sdkPath, String platformName) {
|
|
this(new FileBasedSystemLibraryProvider(sdkPath));
|
|
}
|
|
|
|
public PackageLibraryManager(SystemLibraryProvider libraryProvider) {
|
|
initLibraryManager(libraryProvider);
|
|
setPackageRoots(DEFAULT_PACKAGE_ROOTS);
|
|
}
|
|
|
|
protected void initLibraryManager(SystemLibraryProvider libraryProvider) {
|
|
if (SDK_LIBRARY_MANAGER == null) {
|
|
SDK_LIBRARY_MANAGER = new SystemLibraryManager(libraryProvider);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Expand a relative or short URI (e.g. "dart:html") which is implementation independent to its
|
|
* full URI (e.g. "dart://html/com/google/dart/htmllib/html.dart").
|
|
*
|
|
* @param uri the relative URI
|
|
* @return the expanded URI
|
|
* or the original URI if it could not be expanded
|
|
* or null if the uri is of the form "dart:<libname>" but does not correspond to a system library
|
|
*/
|
|
public URI expandRelativeDartUri(URI uri) throws AssertionError {
|
|
if (isDartUri(uri)) {
|
|
return SDK_LIBRARY_MANAGER.expandRelativeDartUri(uri);
|
|
}
|
|
if (isPackageUri(uri)){
|
|
String host = uri.getHost();
|
|
if (host == null) {
|
|
String spec = uri.getSchemeSpecificPart();
|
|
if (!spec.startsWith("//")){
|
|
try {
|
|
if (spec.startsWith("/")){
|
|
// TODO(keertip): fix to handle spaces
|
|
uri = new URI(PACKAGE_SCHEME + ":/" + spec);
|
|
} else {
|
|
uri = new URI(PACKAGE_SCHEME + "://" + spec);
|
|
}
|
|
} catch (URISyntaxException e) {
|
|
throw new AssertionError(e);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return uri;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Given an absolute file URI (e.g. "file:/some/install/directory/dart-sdk/lib/core/bool.dart"),
|
|
* answer the corresponding dart: URI (e.g. "dart://core/bool.dart") for that file URI,
|
|
* or <code>null</code> if the file URI does not map to a dart: URI
|
|
* @param fileUri the file URI
|
|
* @return the dart URI or <code>null</code>
|
|
*/
|
|
public URI getRelativeUri(URI fileUri) {
|
|
// TODO (danrubel): does not convert dart: libraries outside the dart-sdk/lib directory
|
|
if (fileUri == null || !fileUri.getScheme().equals("file")) {
|
|
return null;
|
|
}
|
|
|
|
URI relativeUri = SDK_LIBRARY_MANAGER.getRelativeUri(fileUri);
|
|
if (relativeUri != null){
|
|
return relativeUri;
|
|
}
|
|
|
|
for (URI rootUri : packageRootsUri){
|
|
relativeUri = rootUri.relativize(fileUri);
|
|
if (relativeUri.getScheme() == null) {
|
|
try {
|
|
return new URI(null, null, "package://" + relativeUri.getPath(), null, null);
|
|
} catch (URISyntaxException e) {
|
|
//$FALL-THROUGH$
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Given a package URI (package:foo/foo.dart), convert it into a file system URI.
|
|
*/
|
|
public URI resolvePackageUri(String packageUriRef) {
|
|
if (packageUriRef.startsWith(PACKAGE_SCHEME_SPEC)) {
|
|
String relPath = packageUriRef.substring(PACKAGE_SCHEME_SPEC.length());
|
|
if (relPath.startsWith("/")){
|
|
relPath = relPath.replaceAll("^\\/+", "");
|
|
}
|
|
for (URI rootUri : packageRootsUri){
|
|
URI fileUri = rootUri.resolve(relPath);
|
|
File file = new File(fileUri);
|
|
if (file.exists()){
|
|
try {
|
|
return file.getCanonicalFile().toURI();
|
|
} catch (IOException e) {
|
|
file.toURI();
|
|
}
|
|
}
|
|
}
|
|
// don't return null for package scheme
|
|
return packageRootsUri.get(0).resolve(relPath);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Answer the original "dart:<libname>" URI for the specified resolved URI or <code>null</code> if
|
|
* it does not map to a short URI.
|
|
*/
|
|
public URI getShortUri(URI uri) {
|
|
URI shortUri = SDK_LIBRARY_MANAGER.getShortUri(uri);
|
|
if (shortUri != null){
|
|
return shortUri;
|
|
}
|
|
shortUri = getRelativeUri(uri);
|
|
if (shortUri != null){
|
|
try {
|
|
if (shortUri.getHost() != null){
|
|
return new URI(null, null, shortUri.getScheme() + ":" + shortUri.getHost() + shortUri.getPath(),null, null);
|
|
}
|
|
else {
|
|
return new URI(null, null, shortUri.getScheme() + ":" + shortUri.getSchemeSpecificPart(), null, null);
|
|
}
|
|
} catch (URISyntaxException e) {
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Expand a relative or short URI (e.g. "dart:html") which is implementation independent to its
|
|
* full URI (e.g. "dart://html/com/google/dart/htmllib/html.dart") and then translate that URI to
|
|
* a "file:" URI (e.g.
|
|
* "file:/some/install/directory/com/google/dart/htmllib/html.dart").
|
|
*
|
|
* @param uri the original URI
|
|
* @return the expanded and translated URI, which may be <code>null</code> and may not exist
|
|
* @exception RuntimeException if the URI is a "dart" scheme, but does not map to a defined system
|
|
* library
|
|
*/
|
|
public URI resolveDartUri(URI uri) {
|
|
return translateDartUri(expandRelativeDartUri(uri));
|
|
}
|
|
|
|
|
|
public List<File> getPackageRoots(){
|
|
return packageRoots;
|
|
}
|
|
|
|
|
|
public void setPackageRoots(List<File> roots){
|
|
if (roots == null || roots.isEmpty()){
|
|
roots = DEFAULT_PACKAGE_ROOTS;
|
|
}
|
|
packageRoots.clear();
|
|
for (File file : roots){
|
|
packageRoots.add(file.getAbsoluteFile());
|
|
}
|
|
packageRootsUri.clear();
|
|
for (File file : roots){
|
|
packageRootsUri.add(file.toURI());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Translate the URI from dart://[host]/[pathToLib] (e.g. dart://html/html.dart)
|
|
* to a "file:" URI (e.g. "file:/some/install/directory/html.dart")
|
|
*
|
|
* @param uri the original URI
|
|
* @return the translated URI, which may be <code>null</code> and may not exist
|
|
* @exception RuntimeException if the URI is a "dart" scheme,
|
|
* but does not map to a defined system library
|
|
*/
|
|
public URI translateDartUri(URI uri) {
|
|
if (isDartUri(uri)) {
|
|
return SDK_LIBRARY_MANAGER.translateDartUri(uri);
|
|
}
|
|
if (isPackageUri(uri)){
|
|
URI fileUri;
|
|
for (URI rootUri : packageRootsUri){
|
|
fileUri = getResolvedPackageUri(uri, rootUri);
|
|
File file = new File(fileUri);
|
|
if (file.exists()){
|
|
try {
|
|
return file.getCanonicalFile().toURI();
|
|
} catch (IOException e) {
|
|
return file.toURI();
|
|
}
|
|
}
|
|
}
|
|
// resolve against first package root
|
|
fileUri = getResolvedPackageUri(uri, packageRootsUri.get(0));
|
|
return fileUri;
|
|
}
|
|
return uri;
|
|
}
|
|
|
|
|
|
/**
|
|
* Given a uri, resolve against the list of package roots, used to find generated files
|
|
* @return uri - resolved uri if file exists, else return given uri
|
|
*/
|
|
public URI findExistingFileInPackages(URI fileUri){
|
|
|
|
URI resolvedUri = getRelativeUri(fileUri);
|
|
if (isPackageUri(resolvedUri)){
|
|
resolvedUri = resolvePackageUri(resolvedUri.toString());
|
|
return resolvedUri;
|
|
}
|
|
return fileUri;
|
|
}
|
|
|
|
/**
|
|
* Resolves the given uri against the package root uri
|
|
*/
|
|
private URI getResolvedPackageUri(URI uri, URI packageRootUri) {
|
|
URI fileUri;
|
|
// TODO(keertip): Investigate further
|
|
// if uri.getHost() returns null, then it is resolved right
|
|
// so use uri.getAuthority to resolve
|
|
// package://third_party/dart_lang/lib/unittest/unittest.dart
|
|
if (uri.getHost() != null){
|
|
fileUri = packageRootUri.resolve(uri.getHost() + uri.getPath());
|
|
} else {
|
|
fileUri = packageRootUri.resolve(uri.getAuthority() + uri.getPath());
|
|
}
|
|
return fileUri;
|
|
}
|
|
|
|
/**
|
|
* Answer a collection of all bundled library URL specs (e.g. "dart:html").
|
|
*
|
|
* @return a collection of specs (not <code>null</code>, contains no <code>null</code>s)
|
|
*/
|
|
public Collection<String> getAllLibrarySpecs() {
|
|
return SDK_LIBRARY_MANAGER.getAllLibrarySpecs();
|
|
}
|
|
|
|
protected SystemLibrary[] getDefaultLibraries() {
|
|
return SDK_LIBRARY_MANAGER.getDefaultLibraries();
|
|
}
|
|
|
|
public Collection<SystemLibrary> getSystemLibraries(){
|
|
return SDK_LIBRARY_MANAGER.getAllSystemLibraries();
|
|
}
|
|
|
|
/**
|
|
* Check if this URI denotes a patch file.
|
|
*/
|
|
public static boolean isPatchFile(File file) {
|
|
return SDK_LIBRARY_MANAGER.isPatchFile(file.toURI());
|
|
}
|
|
|
|
}
|