blob: 10b66c1714d3c4530f0f31f03e88d88935631718 [file] [log] [blame]
/*
* 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;
}
}