| /* |
| * 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; |
| } |
| |
| } |