be83083ccd
More fixes in the service of supporting analysis of resources that are non-resident. Notably a pluggable UrlLibrarySource and a repurposable SystemLibrariesReader. NOTE (API Change): SystemLibraryProvider is now an abstract class, suitable for client customization. Review URL: https://codereview.chromium.org//11027006 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@13084 260f80e4-7a28-3924-810f-c04153c831b5
263 lines
8.4 KiB
Java
263 lines
8.4 KiB
Java
/*
|
|
* Copyright (c) 2012, the Dart project authors.
|
|
*
|
|
* Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
|
|
* in compliance with the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.eclipse.org/legal/epl-v10.html
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
* or implied. See the License for the specific language governing permissions and limitations under
|
|
* the License.
|
|
*/
|
|
package com.google.dart.compiler;
|
|
|
|
import com.google.common.io.CharStreams;
|
|
import com.google.common.io.Closeables;
|
|
import com.google.dart.compiler.CompilerConfiguration.ErrorFormat;
|
|
import com.google.dart.compiler.ast.ASTVisitor;
|
|
import com.google.dart.compiler.ast.DartBooleanLiteral;
|
|
import com.google.dart.compiler.ast.DartExpression;
|
|
import com.google.dart.compiler.ast.DartFieldDefinition;
|
|
import com.google.dart.compiler.ast.DartIdentifier;
|
|
import com.google.dart.compiler.ast.DartMapLiteralEntry;
|
|
import com.google.dart.compiler.ast.DartNamedExpression;
|
|
import com.google.dart.compiler.ast.DartNewExpression;
|
|
import com.google.dart.compiler.ast.DartNode;
|
|
import com.google.dart.compiler.ast.DartStringLiteral;
|
|
import com.google.dart.compiler.ast.DartUnit;
|
|
import com.google.dart.compiler.metrics.CompilerMetrics;
|
|
import com.google.dart.compiler.parser.DartParser;
|
|
import com.google.dart.compiler.util.DartSourceString;
|
|
|
|
import java.io.File;
|
|
import java.io.FileInputStream;
|
|
import java.io.IOException;
|
|
import java.io.InputStreamReader;
|
|
import java.io.Reader;
|
|
import java.net.URI;
|
|
import java.nio.charset.Charset;
|
|
import java.util.ArrayList;
|
|
import java.util.HashMap;
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
/**
|
|
* A reader that parses and reads the libraries dart-sdk/lib/_internal/libraries.dart file for
|
|
* system library information library information is in the format final Map<String, LibraryInfo>
|
|
* LIBRARIES = const <LibraryInfo> { // Used by VM applications "builtin": const LibraryInfo(
|
|
* "builtin/builtin_runtime.dart", category: "Server", platforms: VM_PLATFORM), "compiler": const
|
|
* LibraryInfo( "compiler/compiler.dart", category: "Tools", platforms: 0), };
|
|
*/
|
|
public class SystemLibrariesReader {
|
|
|
|
class DartLibrary {
|
|
|
|
private String shortName = null;
|
|
private String path = null;
|
|
private String category = "Shared";
|
|
private boolean documented = true;
|
|
private boolean implementation = false;
|
|
private int platforms = 0;
|
|
|
|
DartLibrary(String name) {
|
|
this.shortName = name;
|
|
}
|
|
|
|
public String getShortName() {
|
|
return shortName;
|
|
}
|
|
|
|
public String getPath() {
|
|
return path;
|
|
}
|
|
|
|
public void setPath(String path) {
|
|
this.path = path;
|
|
}
|
|
|
|
public String getCategory() {
|
|
return category;
|
|
}
|
|
|
|
public void setCategory(String category) {
|
|
this.category = category;
|
|
}
|
|
|
|
public boolean isDocumented() {
|
|
return documented;
|
|
}
|
|
|
|
public void setDocumented(boolean documented) {
|
|
this.documented = documented;
|
|
}
|
|
|
|
public boolean isImplementation() {
|
|
return implementation;
|
|
}
|
|
|
|
public void setImplementation(boolean implementation) {
|
|
this.implementation = implementation;
|
|
}
|
|
|
|
public boolean isDart2JsLibrary() {
|
|
return (platforms & DART2JS_PLATFORM) != 0;
|
|
}
|
|
|
|
public boolean isVmLibrary() {
|
|
return (platforms & VM_PLATFORM) != 0;
|
|
}
|
|
|
|
public void setPlatforms(int platforms) {
|
|
this.platforms = platforms;
|
|
}
|
|
}
|
|
|
|
class LibrariesFileAstVistor extends ASTVisitor<Void> {
|
|
|
|
@Override
|
|
public Void visitMapLiteralEntry(DartMapLiteralEntry node) {
|
|
|
|
String keyString = null;
|
|
DartExpression key = node.getKey();
|
|
if (key instanceof DartStringLiteral) {
|
|
keyString = "dart:" + ((DartStringLiteral) key).getValue();
|
|
}
|
|
DartExpression value = node.getValue();
|
|
if (value instanceof DartNewExpression) {
|
|
DartLibrary library = new DartLibrary(keyString);
|
|
List<DartExpression> args = ((DartNewExpression) value).getArguments();
|
|
for (DartExpression arg : args) {
|
|
if (arg instanceof DartStringLiteral) {
|
|
library.setPath(((DartStringLiteral) arg).getValue());
|
|
}
|
|
if (arg instanceof DartNamedExpression) {
|
|
String name = ((DartNamedExpression) arg).getName().getName();
|
|
DartExpression expression = ((DartNamedExpression) arg).getExpression();
|
|
if (name.equals(CATEGORY)) {
|
|
library.setCategory(((DartStringLiteral) expression).getValue());
|
|
} else if (name.equals(IMPLEMENTATION)) {
|
|
library.setImplementation(((DartBooleanLiteral) expression).getValue());
|
|
} else if (name.equals(DOCUMENTED)) {
|
|
library.setDocumented(((DartBooleanLiteral) expression).getValue());
|
|
} else if (name.equals(PATCH_PATH)) {
|
|
String path = ((DartStringLiteral) expression).getValue();
|
|
URI uri = sdkLibPath.resolve(URI.create(path));
|
|
patchPaths.add(uri);
|
|
} else if (name.equals(PLATFORMS)) {
|
|
if (expression instanceof DartIdentifier) {
|
|
String identifier = ((DartIdentifier) expression).getName();
|
|
if (identifier.equals("VM_PLATFORM")) {
|
|
library.setPlatforms(VM_PLATFORM);
|
|
} else {
|
|
library.setPlatforms(DART2JS_PLATFORM);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
librariesMap.put(keyString, library);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
}
|
|
|
|
public static final String LIBRARIES_FILE = "libraries.dart";
|
|
public static final String INTERNAL_DIR = "_internal";
|
|
|
|
private static final String IMPLEMENTATION = "implementation";
|
|
private static final String DOCUMENTED = "documented";
|
|
private static final String CATEGORY = "category";
|
|
private static final String PATCH_PATH = "dart2jsPatchPath";
|
|
private static final String PLATFORMS = "platforms";
|
|
|
|
private static final int DART2JS_PLATFORM = 1;
|
|
private static final int VM_PLATFORM = 2;
|
|
|
|
private final URI sdkLibPath;
|
|
private final Map<String, DartLibrary> librariesMap = new HashMap<String, DartLibrary>();
|
|
private final List<URI> patchPaths = new ArrayList<URI>();
|
|
|
|
public SystemLibrariesReader(URI sdkLibPath, Reader sdkFileReader) {
|
|
this.sdkLibPath = sdkLibPath;
|
|
loadLibraryInfo(sdkFileReader);
|
|
}
|
|
|
|
public SystemLibrariesReader(File sdkLibPath) throws IOException {
|
|
this(sdkLibPath.getAbsoluteFile().toURI(), new InputStreamReader(new FileInputStream(
|
|
getLibrariesFile(sdkLibPath)), Charset.forName("UTF8")));
|
|
}
|
|
|
|
public Map<String, DartLibrary> getLibrariesMap() {
|
|
return librariesMap;
|
|
}
|
|
|
|
public List<URI> getPatchPaths() {
|
|
return patchPaths;
|
|
}
|
|
|
|
private void loadLibraryInfo(Reader sdkFileReader) {
|
|
|
|
DartUnit unit = getDartUnit(sdkFileReader);
|
|
|
|
List<DartNode> nodes = unit.getTopLevelNodes();
|
|
for (DartNode node : nodes) {
|
|
if (node instanceof DartFieldDefinition) {
|
|
node.accept(new LibrariesFileAstVistor());
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Parse the given dart file and return the AST
|
|
*
|
|
* @param fileReader the dart file reader
|
|
* @return the parsed AST
|
|
*/
|
|
private DartUnit getDartUnit(Reader fileReader) {
|
|
|
|
String srcCode = getSource(fileReader);
|
|
DartSourceString dartSource = new DartSourceString(LIBRARIES_FILE, srcCode);
|
|
DefaultDartCompilerListener listener = new DefaultDartCompilerListener(ErrorFormat.NORMAL);
|
|
DartParser parser = new DartParser(
|
|
dartSource,
|
|
srcCode,
|
|
false,
|
|
new HashSet<String>(),
|
|
listener,
|
|
new CompilerMetrics());
|
|
return parser.parseUnit();
|
|
}
|
|
|
|
private String getSource(Reader reader) {
|
|
String srcCode = null;
|
|
boolean failed = true;
|
|
try {
|
|
srcCode = CharStreams.toString(reader);
|
|
failed = false;
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
} finally {
|
|
try {
|
|
Closeables.close(reader, failed);
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
return srcCode;
|
|
}
|
|
|
|
private static File getLibrariesFile(File sdkLibDir) {
|
|
File file = new File(new File(sdkLibDir, INTERNAL_DIR), LIBRARIES_FILE);
|
|
if (!file.exists()) {
|
|
throw new InternalCompilerException("Failed to find " + file.toString()
|
|
+ ". Is dart-sdk path correct?");
|
|
}
|
|
return file;
|
|
}
|
|
|
|
}
|