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

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

Issue 9865025: Revert "Removes dartc reliance on its own libraries, now can be targeted at any implementation's li… (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: 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 5857481cfc6bf793f43f9202fbde2d2776854e8e..bab8b97444cda97da66d418f07705f9e0991a8b3 100644
--- a/compiler/java/com/google/dart/compiler/SystemLibraryManager.java
+++ b/compiler/java/com/google/dart/compiler/SystemLibraryManager.java
@@ -4,95 +4,109 @@
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.io.InputStream;
+import java.net.MalformedURLException;
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.Map.Entry;
-import java.util.Properties;
+import java.util.jar.JarFile;
/**
* Manages the collection of {@link SystemLibrary}s.
*/
public class SystemLibraryManager {
-
- public static class NotADartShortUriException extends RuntimeException {
-
- public NotADartShortUriException(String uriString) {
- super("Expected dart:<short name>, got: " + uriString);
+ 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 NotADartShortUriException(URI uri) {
- super("Expected dart:<short name>, got: " + uri.toString());
+
+ 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;
}
}
-
- /**
- * 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";
- /**
- * 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());
- }
-
+ // 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());
+
private HashMap<String, String> expansionMap;
private Map<String, SystemLibrary> hostMap;
- private final File sdkLibPath;
- private final URI sdkLibPathUri;
- private final String platformName;
-
- private Map<URI, URI> longToShortUriMap;
- private List<SystemLibrary> libraries;
+ private SystemLibrary[] libraries;
public SystemLibraryManager() {
- this(DEFAULT_SDK_PATH, DEFAULT_PLATFORM);
+ 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));
}
- public SystemLibraryManager(File sdkPath, String platformName) {
- this.sdkLibPath = new File(sdkPath, "lib").getAbsoluteFile();
- try {
- String path = this.sdkLibPath.toString();
- if (!path.endsWith("/")) {
- path += "/";
+ /**
+ * 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);
}
- this.sdkLibPathUri =
- new URI("file", null, path, null, null);
- } catch (URISyntaxException e) {
- throw new InternalCompilerException(
- "Error creating URI from " + sdkLibPath.toString() + "/lib", e);
+ return library.translateUri(uri);
}
- this.platformName = platformName;
- setLibraries(getDefaultLibraries());
+
+ return uri;
}
/**
@@ -125,202 +139,177 @@ public class SystemLibraryManager {
}
/**
- * 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)
+ * Answer <code>true</code> if the specified URI has a "dart" scheme
*/
- public Collection<String> getAllLibrarySpecs() {
- Collection<String> result = new ArrayList<String>(libraries.size());
- for (SystemLibrary lib : libraries) {
- result.add("dart:" + lib.getShortName());
- }
- return result;
+ public static boolean isDartUri(URI uri) {
+ return uri != null && DART_SCHEME.equals(uri.getScheme());
}
- 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 the original "dart:<libname>" URI for the specified resolved URI or <code>null</code> if
- * it does not map to a short URI.
+ * Answer <code>true</code> if the string is a dart spec
*/
- public URI getShortUri(URI uri) {
- return longToShortUriMap.get(uri);
+ public static boolean isDartSpec(String spec) {
+ return spec != null && spec.startsWith(DART_SCHEME_SPEC);
}
-
+
/**
- * 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
+ * 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)
*/
- public URI resolveDartUri(URI uri) {
- return translateDartUri(expandRelativeDartUri(uri));
+ 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());
+ }
}
- /**
- * 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);
+ private File getResource(String name, boolean failOnMissing) {
+ URL baseUrl = SystemLibraryManager.class.getClassLoader().getResource(name);
+ if (baseUrl == null) {
+ if (!failOnMissing) {
+ return null;
}
- return library.translateUri(uri);
+ throw new RuntimeException("Failed to find the system library: " + name);
}
-
- return uri;
+ return resolveResource(baseUrl, name);
}
-
- public File getSdkLibPath() {
- return sdkLibPath;
+
+ 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;
}
-
- /**
- * 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>();
- // 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();
+ private File searchForResource(String searchPath, String libraryName, boolean failOnMissing) {
+ URL urlPath = null;
+ File sourcePath = new File(searchPath);
- File file;
+ /* 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;
+ }
try {
- file = new File(base.resolve(new URI(null, null, path, null)).normalize());
- } catch (URISyntaxException e) {
- continue;
+ urlPath = foundLibrary.toURI().toURL();
+ } catch (MalformedURLException e) {
+ throw new RuntimeException(e);
}
- if (!file.exists()) {
- throw new InternalCompilerException("Can't find system library dart:" + shortName
- + " at " + file);
+ } 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 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());
+ if (null != jarFile.getJarEntry(libraryName)) {
+ String path = "jar:file:" + sourcePath.getPath() + "!/" + libraryName;
+ try {
+ urlPath = new URL(path);
+ } catch (MalformedURLException e) {
+ throw new RuntimeException(e);
}
} else {
- // Otherwise treat the entry as an explicit shortName to dart file mapping
- int index = shortName.indexOf(':');
- if (index == -1) {
- continue;
+ if (failOnMissing) {
+ throw new RuntimeException("Failed to find system library " + libraryName + " with "
+ + sourcePath.getPath());
}
- explicitShortNames.add(shortName);
- String scheme = shortName.substring(0, index + 1);
- String host = shortName.substring(index + 1);
- addLib(scheme, host, host, file.getParentFile(), file.getName());
+ return null;
}
}
- 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) {
- }
+
+ File foundLibrary = resolveResource(urlPath, libraryName);
+ if (foundLibrary == null && failOnMissing) {
+ throw new RuntimeException("Failed to find system library " + libraryName + " with "
+ + sourcePath.getPath());
}
- return importConfig;
+ return foundLibrary;
}
- 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.");
+ 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);
+ }
}
- 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);
+ if (libraryDirOrZip != null) {
+ return new SystemLibrary(path.shortName, path.hostName, path.lib,
+ libraryDirOrZip);
}
- URI resolvedUri = lib.translateUri(expandedUri);
- longToShortUriMap.put(resolvedUri, libUri);
- longToShortUriMap.put(expandedUri, libUri);
- return true;
+ return null;
}
-
+
/**
- * 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)
+ * Answer the libraries that are built into the compiler jar
*/
- 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());
+ 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();
+ }
+ }
}
+
+ return defaultLibraries.toArray(new SystemLibrary[defaultLibraries.size()]);
}
}

Powered by Google App Engine
This is Rietveld 408576698