Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(602)

Unified Diff: compiler/java/com/google/dart/compiler/SystemLibraryManager.java

Issue 9860009: Removes dartc reliance on its own libraries, now can be targeted at any implementation's libraries (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated 'configs' to be 'config' directory, updated addLib() to throw exception Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: compiler/java/com/google/dart/compiler/SystemLibraryManager.java
diff --git a/compiler/java/com/google/dart/compiler/SystemLibraryManager.java b/compiler/java/com/google/dart/compiler/SystemLibraryManager.java
index bab8b97444cda97da66d418f07705f9e0991a8b3..5857481cfc6bf793f43f9202fbde2d2776854e8e 100644
--- a/compiler/java/com/google/dart/compiler/SystemLibraryManager.java
+++ b/compiler/java/com/google/dart/compiler/SystemLibraryManager.java
@@ -4,109 +4,95 @@
package com.google.dart.compiler;
+import com.google.common.collect.Lists;
+
+import java.io.BufferedInputStream;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.IOException;
-import java.net.MalformedURLException;
+import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
-import java.net.URL;
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.jar.JarFile;
+import java.util.Map.Entry;
+import java.util.Properties;
/**
* Manages the collection of {@link SystemLibrary}s.
*/
public class SystemLibraryManager {
- private enum SystemLibraryPath {
- CORE("core", "core", "com/google/dart/corelib/", "corelib.dart", "corelib.jar", true),
- COREIMPL("core", "coreimpl", "com/google/dart/corelib/", "corelib_impl.dart", "corelib.jar",
- CORE, true),
- DOM("dom", "dom", "dom/", "dom.dart", "domlib.jar"),
- HTML("html", "html", "html/", "html.dart", "htmllib.jar"),
- JSON("json", "json", "json/", "json.dart", "jsonlib.jar"),
- ISOLATE("isolate", "isolate", "isolate/", "isolate_compiler.dart", "isolatelib.jar");
-
- final String hostName;
- final SystemLibraryPath base;
- final String shortName;
- final String jar;
- final String lib;
- final boolean failIfMissing;
-
- SystemLibraryPath(String hostName, String shortName, String path, String file, String jar,
- boolean failIfMissing) {
- this(hostName, shortName, path, file, jar, null, failIfMissing);
- }
-
- SystemLibraryPath(String hostName, String shortName, String path, String file, String jar) {
- this(hostName, shortName, path, file, jar, null, false);
+
+ public static class NotADartShortUriException extends RuntimeException {
+
+ public NotADartShortUriException(String uriString) {
+ super("Expected dart:<short name>, got: " + uriString);
}
-
- SystemLibraryPath(String hostName, String shortName, String path, String file, String jar,
- SystemLibraryPath base, boolean failIfMissing) {
- this.hostName = hostName;
- this.shortName = shortName;
- this.jar = jar;
- this.lib = path + file;
- this.base = base;
- this.failIfMissing = failIfMissing;
+
+ 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", "../"));
+
private static final String DART_SCHEME = "dart";
private static final String DART_SCHEME_SPEC = "dart:";
+ private static final String IMPORT_CONFIG = "import_%s.config";
- // executionFile is used to search for loose files on disk when the system libraries
- // are not on the classpath (e.g. Eclipse)
- private static final File executionFile = new File(SystemLibraryManager.class
- .getProtectionDomain().getCodeSource().getLocation().getPath());
-
+ /**
+ * 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());
+ }
+
private HashMap<String, String> expansionMap;
private Map<String, SystemLibrary> hostMap;
+ private final File sdkLibPath;
danrubel 2012/03/28 16:41:00 Perhaps rename to sdkLibDir? I saw the "Path" suff
zundel 2012/03/28 18:13:24 I've already committed it. Next time I'm in there
+ private final URI sdkLibPathUri;
+ private final String platformName;
+
+ private Map<URI, URI> longToShortUriMap;
- private SystemLibrary[] libraries;
+ private List<SystemLibrary> libraries;
public SystemLibraryManager() {
- setLibraries(getDefaultLibraries());
- }
-
- /**
- * Expand a relative or short URI (e.g. "dart:dom") which is implementation independent to its
- * full URI (e.g. "dart://dom/com/google/dart/domlib/dom.dart") and then translate that URI to
- * either a "file:" or "jar:" URI (e.g.
- * "jar:file:/some/install/director/dom.jar!/com/google/dart/domlib/dom.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));
+ this(DEFAULT_SDK_PATH, DEFAULT_PLATFORM);
}
- /**
- * Translate the URI from dart://[host]/[pathToLib] (e.g. dart://dom/dom.dart)
- * to either a "file:" or "jar:" URI (e.g. "jar:file:/some/install/director/dom.jar!/dom.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)) {
- String host = uri.getHost();
- SystemLibrary library = hostMap.get(host);
- if (library == null) {
- throw new RuntimeException("No system library defined for " + uri);
+ public SystemLibraryManager(File sdkPath, String platformName) {
+ this.sdkLibPath = new File(sdkPath, "lib").getAbsoluteFile();
+ try {
+ String path = this.sdkLibPath.toString();
+ if (!path.endsWith("/")) {
+ path += "/";
}
- return library.translateUri(uri);
+ this.sdkLibPathUri =
+ new URI("file", null, path, null, null);
+ } catch (URISyntaxException e) {
+ throw new InternalCompilerException(
+ "Error creating URI from " + sdkLibPath.toString() + "/lib", e);
}
-
- return uri;
+ this.platformName = platformName;
+ setLibraries(getDefaultLibraries());
}
/**
@@ -139,177 +125,202 @@ public class SystemLibraryManager {
}
/**
- * Answer <code>true</code> if the specified URI has a "dart" scheme
+ * Answer a collection of all bundled library URL specs (e.g. "dart:dom").
+ *
+ * @return a collection of specs (not <code>null</code>, contains no <code>null</code>s)
*/
- public static boolean isDartUri(URI uri) {
- return uri != null && DART_SCHEME.equals(uri.getScheme());
+ public Collection<String> getAllLibrarySpecs() {
+ Collection<String> result = new ArrayList<String>(libraries.size());
+ for (SystemLibrary lib : libraries) {
+ result.add("dart:" + lib.getShortName());
+ }
+ return result;
}
+ protected InputStream getImportConfigStream() {
+ File file = new File(new File(sdkLibPath, "config"),
+ String.format(IMPORT_CONFIG, platformName));
+ if (!file.exists()) {
+ throw new InternalCompilerException("Failed to find " + file.toString()
+ + ". Is dart-sdk path correct?");
+ }
+ try {
+ return new BufferedInputStream(new FileInputStream(file));
+ } catch (FileNotFoundException e) {
+ throw new InternalCompilerException("Failed to open " + file);
+ }
+ }
+
/**
- * Answer <code>true</code> if the string is a dart spec
+ * 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 static boolean isDartSpec(String spec) {
- return spec != null && spec.startsWith(DART_SCHEME_SPEC);
+ public URI getShortUri(URI uri) {
+ return longToShortUriMap.get(uri);
}
-
+
/**
- * Register system libraries for the "dart:" protocol such that dart:[shortLibName] (e.g.
- * "dart:dom") will automatically be expanded to dart://[host]/[pathToLib] (e.g.
- * dart://dom/dom.dart)
+ * Expand a relative or short URI (e.g. "dart:dom") which is implementation independent to its
+ * full URI (e.g. "dart://dom/com/google/dart/domlib/dom.dart") and then translate that URI to
+ * a "file:" URI (e.g.
+ * "file:/some/install/directory/com/google/dart/domlib/dom.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
*/
- private void setLibraries(SystemLibrary[] newLibraries) {
- libraries = newLibraries;
- hostMap = new HashMap<String, SystemLibrary>();
- expansionMap = new HashMap<String, String>();
- for (SystemLibrary library : libraries) {
- hostMap.put(library.getHost(), library);
- expansionMap.put(library.getShortName(),
- "//" + library.getHost() + "/" + library.getPathToLib());
- }
+ public URI resolveDartUri(URI uri) {
+ return translateDartUri(expandRelativeDartUri(uri));
}
- private File getResource(String name, boolean failOnMissing) {
- URL baseUrl = SystemLibraryManager.class.getClassLoader().getResource(name);
- if (baseUrl == null) {
- if (!failOnMissing) {
- return null;
+ /**
+ * Translate the URI from dart://[host]/[pathToLib] (e.g. dart://dom/dom.dart)
+ * to a "file:" URI (e.g. "file:/some/install/directory/dom.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)) {
+ String host = uri.getHost();
+ SystemLibrary library = hostMap.get(host);
+ if (library == null) {
+ throw new RuntimeException("No system library defined for " + uri);
}
- throw new RuntimeException("Failed to find the system library: " + name);
+ return library.translateUri(uri);
}
- return resolveResource(baseUrl, name);
- }
- static private File resolveResource(URL baseUrl, String name) {
- if (baseUrl == null) {
- return null;
- }
- File coreDirOrZip = null;
- String protocol = baseUrl.getProtocol();
- String path = baseUrl.getPath();
- if ("file".equals(protocol)) {
- coreDirOrZip = new File(path.substring(0, path.lastIndexOf(name)));
- } else if ("jar".equals(protocol)) {
- // jar:file://www.foo.com/bar/baz.jar!/com/google/some.class
- if (path.startsWith("file:")) {
- int index = path.indexOf('!');
- coreDirOrZip = new File(path.substring(5, index > 0 ? index : path.length()));
- }
- }
- if (coreDirOrZip == null) {
- throw new RuntimeException("Failed to find system library in " + baseUrl);
- }
- if (!coreDirOrZip.exists()) {
- throw new RuntimeException("System library container does not exist " + coreDirOrZip
- + "\n from " + baseUrl);
- }
- return coreDirOrZip;
+ return uri;
}
+
+ public File getSdkLibPath() {
+ return sdkLibPath;
+ }
+
+ /**
+ * Scan the directory returned by {@link #getLibrariesDir()} looking for libraries of the form
+ * libraries/<name>/<name>_<platform>.dart and libraries/<name>/<name>.dart where <platform> is
+ * the value initialized in the {@link SystemLibraryManager}.
+ */
+ protected SystemLibrary[] getDefaultLibraries() {
+ libraries = new ArrayList<SystemLibrary>();
+ longToShortUriMap = new HashMap<URI, URI>();
- private File searchForResource(String searchPath, String libraryName, boolean failOnMissing) {
- URL urlPath = null;
- File sourcePath = new File(searchPath);
+ // Cycle through the import.config, extracting explicit mappings and searching directories
+ URI base = this.sdkLibPathUri;
+ Properties importConfig = getImportConfig();
+ HashSet<String> explicitShortNames = new HashSet<String>();
+ for (Entry<Object, Object> entry : importConfig.entrySet()) {
+ String shortName = ((String) entry.getKey()).trim();
+ String path = ((String) entry.getValue()).trim();
- /* The source can be a directory or a jar file. Search both for our library. */
- if (sourcePath.isDirectory()) {
- File foundLibrary = new File(sourcePath.getPath() + File.separator + libraryName);
- if (!foundLibrary.exists()) {
- if (failOnMissing) {
- throw new RuntimeException("Failed to find system library " + libraryName + " with "
- + sourcePath.toString());
- }
- return null;
- }
+ File file;
try {
- urlPath = foundLibrary.toURI().toURL();
- } catch (MalformedURLException e) {
- throw new RuntimeException(e);
+ file = new File(base.resolve(new URI(null, null, path, null)).normalize());
+ } catch (URISyntaxException e) {
+ continue;
}
- } else if (sourcePath.isFile() && sourcePath.toString().endsWith(".jar")) {
- // Support for jar only right now...
- JarFile jarFile = null;
- try {
- jarFile = new JarFile(sourcePath);
- } catch (IOException e) {
- throw new RuntimeException(e);
+ if (!file.exists()) {
+ throw new InternalCompilerException("Can't find system library dart:" + shortName
+ + " at " + file);
}
- if (null != jarFile.getJarEntry(libraryName)) {
- String path = "jar:file:" + sourcePath.getPath() + "!/" + libraryName;
- try {
- urlPath = new URL(path);
- } catch (MalformedURLException e) {
- throw new RuntimeException(e);
+
+ // If the shortName ends with ":" then search the associated directory for libraries
+
+ if (shortName.endsWith(":")) {
+ if (!file.isDirectory()) {
+ continue;
+ }
+ for (File child : file.listFiles()) {
+ String host = child.getName();
+ // Do not overwrite explicit shortName to dart file mappings
+ if (explicitShortNames.contains(shortName + host)) {
+ continue;
+ }
+ if (!child.isDirectory()) {
+ continue;
+ }
+ File dartFile = new File(child, child.getName() + ".dart");
+ if (!dartFile.isFile()) {
+ // addLib() will throw an exception. In this case, we are just scanning
+ // for libraries and don't want the error to be fatal.
+ continue;
+ }
+ addLib(shortName, host, host, child, dartFile.getName());
}
} else {
- if (failOnMissing) {
- throw new RuntimeException("Failed to find system library " + libraryName + " with "
- + sourcePath.getPath());
+ // Otherwise treat the entry as an explicit shortName to dart file mapping
+ int index = shortName.indexOf(':');
+ if (index == -1) {
+ continue;
}
- return null;
+ explicitShortNames.add(shortName);
+ String scheme = shortName.substring(0, index + 1);
+ String host = shortName.substring(index + 1);
+ addLib(scheme, host, host, file.getParentFile(), file.getName());
}
}
-
- File foundLibrary = resolveResource(urlPath, libraryName);
- if (foundLibrary == null && failOnMissing) {
- throw new RuntimeException("Failed to find system library " + libraryName + " with "
- + sourcePath.getPath());
+ return libraries.toArray(new SystemLibrary[libraries.size()]);
+ }
+
+ /**
+ * Read the import.config content and return it as a collection of key/value pairs
+ */
+ protected Properties getImportConfig() {
+ Properties importConfig = new Properties();
+ InputStream stream = getImportConfigStream();
+ try {
+ importConfig.load(stream);
+ } catch (IOException ignored) {
+ } finally {
+ try {
+ stream.close();
+ } catch (IOException ignored) {
+ }
}
- return foundLibrary;
+ return importConfig;
}
- protected SystemLibrary locateSystemLibrary(SystemLibraryPath path) {
- // First, check for jars on the class path
- File libraryDirOrZip = getResource(path.lib, path.failIfMissing);
-
- // TODO(codefu): This is a hack. To keep Eclipse happy and to find the
- // sources, we hard code this path. In the future, when the libraries are
- // all gathered into a common "lib/" path, we can search from there.
- if (libraryDirOrZip == null) {
- // Eclipse's executionPath should be a directory, unless a jar file was included.
- String executionPath;
- if (executionFile.isDirectory()) {
- // Universal location of eclipse workspace to the dart source tree is
- // 'dart/compiler/eclipse.workspace/dartc/output'
- // and we need 'dart/client'
- executionPath =
- executionFile.getParent() + File.separator + ".." + File.separator + ".."
- + File.separator + ".." + File.separator + "client";
- } else {
- executionPath = executionFile.getParent() + File.separator + path.jar;
- }
- libraryDirOrZip = searchForResource(executionPath, path.lib, false);
- if (libraryDirOrZip == null && executionFile.isFile()) {
- // Last ditch; are the artifacts just in a flat file...
- libraryDirOrZip = searchForResource(executionFile.getParent(), path.lib, false);
- }
+ private boolean addLib(String scheme, String host, String name, File dir, String libFileName)
+ throws AssertionError {
+ File libFile = new File(dir, libFileName);
+ if (!libFile.isFile()) {
+ throw new InternalCompilerException("Error mapping dart:" + host + ", path "
+ + libFile.getAbsolutePath() + " is not a file.");
}
- if (libraryDirOrZip != null) {
- return new SystemLibrary(path.shortName, path.hostName, path.lib,
- libraryDirOrZip);
+ SystemLibrary lib = new SystemLibrary(name, host, libFileName, dir);
+ libraries.add(lib);
+ String libSpec = scheme + name;
+ URI libUri;
+ URI expandedUri;
+ try {
+ libUri = new URI(libSpec);
+ expandedUri = new URI("dart:" + "//" + host + "/" + libFileName);
+ } catch (URISyntaxException e) {
+ throw new AssertionError(e);
}
- return null;
+ URI resolvedUri = lib.translateUri(expandedUri);
+ longToShortUriMap.put(resolvedUri, libUri);
+ longToShortUriMap.put(expandedUri, libUri);
+ return true;
}
-
+
/**
- * Answer the libraries that are built into the compiler jar
+ * Register system libraries for the "dart:" protocol such that dart:[shortLibName] (e.g.
+ * "dart:dom") will automatically be expanded to dart://[host]/[pathToLib] (e.g.
+ * dart://dom/dom.dart)
*/
- protected SystemLibrary[] getDefaultLibraries() {
- ArrayList<SystemLibrary> defaultLibraries = new ArrayList<SystemLibrary>();
- File[] baseFiles = new File[SystemLibraryPath.values().length];
-
- for (SystemLibraryPath path : SystemLibraryPath.values()) {
- if (path.base != null) {
- defaultLibraries.add(new SystemLibrary(path.shortName, path.hostName, path.lib,
- baseFiles[path.base.ordinal()]));
- baseFiles[path.ordinal()] = baseFiles[path.base.ordinal()];
- } else {
- SystemLibrary library = locateSystemLibrary(path);
- if (library != null) {
- defaultLibraries.add(library);
- baseFiles[path.ordinal()] = library.getFile();
- }
- }
+ private void setLibraries(SystemLibrary[] newLibraries) {
+ libraries = Lists.newArrayList(newLibraries);
+ hostMap = new HashMap<String, SystemLibrary>();
+ expansionMap = new HashMap<String, String>();
+ for (SystemLibrary library : libraries) {
+ hostMap.put(library.getHost(), library);
+ expansionMap.put(library.getShortName(),
+ "//" + library.getHost() + "/" + library.getPathToLib());
}
-
- return defaultLibraries.toArray(new SystemLibrary[defaultLibraries.size()]);
}
}

Powered by Google App Engine
This is Rietveld 408576698