blob: a86558ef4660cde66090403652308023eee14adc [file] [log] [blame]
// 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 com.google.dart.compiler.SystemLibrariesReader.DartLibrary;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
/**
* A Library manager that manages system libraries
*/
public class SystemLibraryManager {
private HashMap<String, String> expansionMap;
private Map<String, SystemLibrary> hostMap;
private final URI sdkLibPathUri;
private Map<URI, URI> longToShortUriMap;
private List<SystemLibrary> libraries;
private final SystemLibraryProvider libraryProvider;
public SystemLibraryManager(File sdkPath) {
this(new FileBasedSystemLibraryProvider(sdkPath));
}
public SystemLibraryManager(SystemLibraryProvider libraryProvider) {
this.libraryProvider = libraryProvider;
this.sdkLibPathUri = libraryProvider.getSdkLibPathUri();
setLibraries(getDefaultLibraries());
}
public URI expandRelativeDartUri(URI uri) throws AssertionError {
String host = uri.getHost();
if (host == null && uri.getAuthority() == null) {
String spec = uri.getSchemeSpecificPart();
String replacement = expansionMap.get(spec);
if (replacement != null) {
try {
uri = new URI(PackageLibraryManager.DART_SCHEME + ":" + replacement);
} catch (URISyntaxException e) {
throw new AssertionError();
}
} else {
return null;
}
}
return uri;
}
public URI getRelativeUri(URI fileUri) {
if (fileUri == null || !fileUri.getScheme().equals("file")){
return null;
}
URI relativeUri = sdkLibPathUri.relativize(fileUri);
if (relativeUri.getScheme() == null) {
try {
return new URI(null, null, "dart://" + relativeUri.getPath(), null, null);
} catch (URISyntaxException e) {
//$FALL-THROUGH$
}
}
return null;
}
public URI getShortUri(URI uri) {
URI shortUri = longToShortUriMap.get(uri);
if (shortUri != null){
return shortUri;
}
shortUri = getRelativeUri(uri);
if (shortUri != null){
try {
return new URI(null, null, shortUri.getScheme() + ":" + shortUri.getHost() + shortUri.getPath(),null, null);
} catch (URISyntaxException e) {
}
}
return null;
}
public URI translateDartUri(URI uri) {
String host = uri.getHost();
SystemLibrary library = hostMap.get(host);
if (library != null) {
return library.translateUri(uri);
}
if (host != null) {
return libraryProvider.resolveHost(host, uri);
}
String authorithy = uri.getAuthority();
if (authorithy != null){
return libraryProvider.resolveHost(authorithy, uri);
}
throw new RuntimeException("No system library defined for " + uri);
}
public Collection<String> getAllLibrarySpecs() {
Collection<String> result = new ArrayList<String>(libraries.size());
for (SystemLibrary lib : libraries) {
result.add("dart:" + lib.getShortName());
}
return result;
}
public Collection<SystemLibrary> getAllSystemLibraries(){
return libraries;
}
/**
* Load the libraries listed out in the libraries.dart files as read by the {@link SystemLibrariesReader}
*/
protected SystemLibrary[] getDefaultLibraries() {
libraries = new ArrayList<SystemLibrary>();
longToShortUriMap = new HashMap<URI, URI>();
// Cycle through the import.config, extracting explicit mappings and searching directories
URI base = this.sdkLibPathUri;
Map<String, DartLibrary> declaredLibraries = libraryProvider.getLibraryMap();
HashSet<String> explicitShortNames = new HashSet<String>();
for (Entry<String, DartLibrary> entry : declaredLibraries.entrySet()) {
if (entry.getValue().getCategory().equals("Internal")
// TODO(8365): the following line allows dart:_collection-dev to
// be imported even though it's a hidden library.
&& !entry.getKey().equals("dart:_collection-dev")) {
continue;
}
String shortName = entry.getKey().trim();
DartLibrary library = entry.getValue();
String path = library.getPath();
URI libFileUri;
try {
libFileUri = base.resolve(new URI(null, null, path, null, null)).normalize();
} catch (URISyntaxException e) {
continue;
}
if (!libraryProvider.exists(libFileUri)) {
throw new InternalCompilerException("Can't find system library dart:" + shortName
+ " at " + libFileUri);
}
int index = shortName.indexOf(':');
if (index == -1) {
continue;
}
explicitShortNames.add(shortName);
String scheme = shortName.substring(0, index + 1);
String name = shortName.substring(index + 1);
String relPath = sdkLibPathUri.relativize(libFileUri).getPath();
index = relPath.indexOf('/');
if (index == -1) {
continue;
}
String host = relPath.substring(0, index);
String pathToLib = relPath.substring(index + 1);
addLib(scheme,
host,
name,
pathToLib,
library.getCategory(),
library.isDocumented(),
library.isImplementation());
}
return libraries.toArray(new SystemLibrary[libraries.size()]);
}
protected boolean addLib(String scheme, String host, String name, String pathToLib,
String category, boolean documented, boolean implementation)
throws AssertionError {
SystemLibrary lib = libraryProvider.createSystemLibrary(name, host, pathToLib, category, documented, implementation);
libraries.add(lib);
String libSpec = scheme + name;
URI libUri;
URI expandedUri;
try {
libUri = new URI(libSpec);
expandedUri = new URI("dart:" + "//" + host + "/" + pathToLib);
} catch (URISyntaxException e) {
throw new AssertionError(e);
}
URI resolvedUri = lib.translateUri(expandedUri);
longToShortUriMap.put(resolvedUri, libUri);
longToShortUriMap.put(expandedUri, libUri);
return true;
}
/**
* Register system libraries for the "dart:" protocol such that dart:[shortLibName] (e.g.
* "dart:html") will automatically be expanded to dart://[host]/[pathToLib] (e.g.
* dart://html/html.dart)
*/
private void setLibraries(SystemLibrary[] newLibraries) {
libraries = new ArrayList<SystemLibrary>();
hostMap = new HashMap<String, SystemLibrary>();
expansionMap = new HashMap<String, String>();
for (SystemLibrary library : newLibraries) {
String host = library.getHost();
SystemLibrary existingLib = hostMap.get(host);
if (existingLib != null) {
libraries.remove(existingLib);
}
libraries.add(library);
hostMap.put(host, library);
expansionMap.put(library.getShortName(),
"//" + host + "/" + library.getPathToLib());
}
}
/**
* Check if this URI denotes a patch file.
*/
public boolean isPatchFile(URI uri) {
return libraryProvider.isPatchFile(uri);
}
}