| Index: pkg/compiler/lib/src/platform_configuration.dart
|
| diff --git a/pkg/compiler/lib/src/platform_configuration.dart b/pkg/compiler/lib/src/platform_configuration.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..41da852868bfe3579e598475422b914864dad118
|
| --- /dev/null
|
| +++ b/pkg/compiler/lib/src/platform_configuration.dart
|
| @@ -0,0 +1,142 @@
|
| +// Copyright (c) 2015, the Fletch project authors. Please see the AUTHORS file
|
| +// for details. All rights reserved. Use of this source code is governed by a
|
| +// BSD-style license that can be found in the LICENSE.md file.
|
| +
|
| +/// Tools for loading and parsing platform-configuration files.
|
| +library plaform_configuration;
|
| +
|
| +import "dart:async";
|
| +import "package:charcode/ascii.dart";
|
| +import "../compiler_new.dart" as api;
|
| +
|
| +/// Parses an Ini-like format.
|
| +///
|
| +/// Sections are initialized with a name enclosed in brackets.
|
| +/// Each section contain zero or more properties of the form "name:value".
|
| +/// Empty lines are ignored.
|
| +/// Lines starting with # are ignored.
|
| +/// Duplicate names are not allowed.
|
| +/// All keys and values will be passed through [String.trim].
|
| +///
|
| +/// If an error is found, a [FormatException] is thrown, using [sourceUri] in
|
| +/// the error message.
|
| +///
|
| +/// Example
|
| +/// ```
|
| +/// [a]
|
| +/// b:c
|
| +///
|
| +/// [d]
|
| +/// e:file:///tmp/bla
|
| +/// ```
|
| +/// Will parse to {"a": {"b":"c"}, "d": {"e": "file:///tmp/bla"}}.
|
| +
|
| +Map<String, Map<String, String>> parseIni(List<int> source,
|
| + {Set<String> allowedSections, Uri sourceUri}) {
|
| + int startOfLine = 0;
|
| + int currentLine = 0;
|
| +
|
| + error(String message, int index) {
|
| + int column = index - startOfLine + 1;
|
| + throw new FormatException(
|
| + "$sourceUri:$currentLine:$column: $message", sourceUri, index);
|
| + }
|
| +
|
| + Map<String, Map<String, String>> result =
|
| + new Map<String, Map<String, String>>();
|
| + Map<String, String> currentSection = null;
|
| +
|
| + if (source.length == 0) return result;
|
| + bool endOfFile = false;
|
| +
|
| + // Iterate once per $lf in file.
|
| + while (!endOfFile) {
|
| + currentLine += 1;
|
| + int endOfLine = source.indexOf($lf, startOfLine);
|
| + if (endOfLine == -1) {
|
| + // The dart2js provider adds a final 0 to the file.
|
| + endOfLine = source.last == 0 ? source.length - 1 : source.length;
|
| + endOfFile = true;
|
| + }
|
| + if (startOfLine != endOfLine) {
|
| + int firstChar = source[startOfLine];
|
| + if (firstChar == $hash) {
|
| + // Comment, do nothing.
|
| + } else if (firstChar == $open_bracket) {
|
| + // Section header
|
| + int endOfHeader = source.indexOf($close_bracket, startOfLine);
|
| + if (endOfHeader == -1) {
|
| + error("'[' must be matched by ']' on the same line.", startOfLine);
|
| + }
|
| + if (endOfHeader == startOfLine + 1) {
|
| + error("Empty header name", startOfLine + 1);
|
| + }
|
| + if (endOfHeader != endOfLine - 1) {
|
| + error("Section heading lines must end with ']'", endOfHeader + 1);
|
| + }
|
| + int startOfSectionName = startOfLine + 1;
|
| + String sectionName = new String.fromCharCodes(
|
| + source, startOfSectionName, endOfHeader).trim();
|
| + currentSection = new Map<String, String>();
|
| + if (result.containsKey(sectionName)) {
|
| + error("Duplicate section name '$sectionName'", startOfSectionName);
|
| + }
|
| + if (allowedSections != null && !allowedSections.contains(sectionName)) {
|
| + error("Unrecognized section name '$sectionName'", startOfSectionName);
|
| + }
|
| + result[sectionName] = currentSection;
|
| + } else {
|
| + // Property line
|
| + if (currentSection == null) {
|
| + error("Property outside section", startOfLine);
|
| + }
|
| + int separator = source.indexOf($colon, startOfLine);
|
| + if (separator == startOfLine) {
|
| + error("Empty property name", startOfLine);
|
| + }
|
| + if (separator == -1 || separator > endOfLine) {
|
| + error("Property line without ':'", startOfLine);
|
| + }
|
| + String propertyName =
|
| + new String.fromCharCodes(source, startOfLine, separator).trim();
|
| + if (currentSection.containsKey(propertyName)) {
|
| + error("Duplicate property name '$propertyName'", startOfLine);
|
| + }
|
| + String propertyValue =
|
| + new String.fromCharCodes(source, separator + 1, endOfLine).trim();
|
| + currentSection[propertyName] = propertyValue;
|
| + }
|
| + }
|
| + startOfLine = endOfLine + 1;
|
| + }
|
| + return result;
|
| +}
|
| +
|
| +const String librariesSection = "libraries";
|
| +const String dartSpecSection = "dart-spec";
|
| +const String featuresSection = "features";
|
| +
|
| +Map<String, Uri> libraryMappings(
|
| + Map<String, Map<String, String>> sections, Uri baseLocation) {
|
| + assert(sections.containsKey(librariesSection));
|
| + Map<String, Uri> result = new Map<String, Uri>();
|
| + sections[librariesSection].forEach((String name, String value) {
|
| + result[name] = baseLocation.resolve(value);
|
| + });
|
| + return result;
|
| +}
|
| +
|
| +final Set<String> allowedSections =
|
| + new Set.from([librariesSection, dartSpecSection, featuresSection]);
|
| +
|
| +Future<Map<String, Uri>> load(Uri location, api.CompilerInput provider) {
|
| + return provider.readFromUri(location).then((contents) {
|
| + if (contents is String) {
|
| + contents = contents.codeUnits;
|
| + }
|
| + return libraryMappings(
|
| + parseIni(contents,
|
| + allowedSections: allowedSections, sourceUri: location),
|
| + location);
|
| + });
|
| +}
|
|
|