Index: sdk/lib/_internal/pub_generated/lib/src/preprocess.dart |
diff --git a/sdk/lib/_internal/pub_generated/lib/src/preprocess.dart b/sdk/lib/_internal/pub_generated/lib/src/preprocess.dart |
index 26b76d0da855c0b7309d0ba752d8ff4ad23a95b4..bf05f89fae1cdd0e320db0f7379a006b4987c423 100644 |
--- a/sdk/lib/_internal/pub_generated/lib/src/preprocess.dart |
+++ b/sdk/lib/_internal/pub_generated/lib/src/preprocess.dart |
@@ -1,16 +1,70 @@ |
+// Copyright (c) 2014, the Dart 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 file. |
+ |
library pub.preprocess; |
+ |
import 'package:pub_semver/pub_semver.dart'; |
import 'package:string_scanner/string_scanner.dart'; |
+ |
+/// Runs a simple preprocessor over [input] to remove sections that are |
+/// incompatible with the available barback version. |
+/// |
+/// [versions] are the available versions of each installed package, and |
+/// [sourceUrl] is a [String] or [Uri] indicating where [input] came from. It's |
+/// used for error reporting. |
+/// |
+/// For the most part, the preprocessor leaves text in the source document |
+/// alone. However, it handles two types of lines specially. Lines that begin |
+/// with `//>` are uncommented by the preprocessor, and lines that begin with |
+/// `//#` are operators. |
+/// |
+/// The preprocessor currently supports one top-level operator, "if": |
+/// |
+/// //# if barback >=0.14.1 |
+/// ... |
+/// //# else |
+/// ... |
+/// //# end |
+/// |
+/// If can check against any package installed in the current package. It can |
+/// check the version of the package, as above, or (if the version range is |
+/// omitted) whether the package exists at all. If the condition is true, |
+/// everything within the first block is included in the output and everything |
+/// within the second block is removed; otherwise, the first block is removed |
+/// and the second block is included. The `else` block is optional. |
+/// |
+/// It's important that the preprocessor syntax also be valid Dart code, because |
+/// pub loads the source files before preprocessing and runs them against the |
+/// version of barback that was compiled into pub. This is why the `//>` syntax |
+/// exists: so that code can be hidden from the running pub process but still be |
+/// visible to the barback isolate. For example: |
+/// |
+/// //# if barback >= 0.14.1 |
+/// ClassMirror get aggregateClass => reflectClass(AggregateTransformer); |
+/// //# else |
+/// //> ClassMirror get aggregateClass => null; |
+/// //# end |
String preprocess(String input, Map<String, Version> versions, sourceUrl) { |
+ // Short-circuit if there are no preprocessor directives in the file. |
if (!input.contains(new RegExp(r"^//[>#]", multiLine: true))) return input; |
return new _Preprocessor(input, versions, sourceUrl).run(); |
} |
+ |
+/// The preprocessor class. |
class _Preprocessor { |
+ /// The scanner over the input string. |
final StringScanner _scanner; |
+ |
final Map<String, Version> _versions; |
+ |
+ /// The buffer to which the output is written. |
final _buffer = new StringBuffer(); |
+ |
_Preprocessor(String input, this._versions, sourceUrl) |
: _scanner = new StringScanner(input, sourceUrl: sourceUrl); |
+ |
+ /// Run the preprocessor and return the processed output. |
String run() { |
while (!_scanner.isDone) { |
if (_scanner.scan(new RegExp(r"//#[ \t]*"))) { |
@@ -19,27 +73,38 @@ class _Preprocessor { |
_emitText(); |
} |
} |
+ |
_scanner.expectDone(); |
return _buffer.toString(); |
} |
+ |
+ /// Emit lines of the input document directly until an operator is |
+ /// encountered. |
void _emitText() { |
while (!_scanner.isDone && !_scanner.matches("//#")) { |
if (_scanner.scan("//>")) { |
if (!_scanner.matches("\n")) _scanner.expect(" "); |
} |
+ |
_scanner.scan(new RegExp(r"[^\n]*\n?")); |
_buffer.write(_scanner.lastMatch[0]); |
} |
} |
+ |
+ /// Move through lines of the input document without emitting them until an |
+ /// operator is encountered. |
void _ignoreText() { |
while (!_scanner.isDone && !_scanner.matches("//#")) { |
_scanner.scan(new RegExp(r"[^\n]*\n?")); |
} |
} |
+ |
+ /// Handle an `if` operator. |
void _if() { |
_scanner.expect(new RegExp(r"if[ \t]+"), name: "if statement"); |
_scanner.expect(new RegExp(r"[a-zA-Z0-9_]+"), name: "package name"); |
var package = _scanner.lastMatch[0]; |
+ |
_scanner.scan(new RegExp(r"[ \t]*")); |
var constraint = VersionConstraint.any; |
if (_scanner.scan(new RegExp(r"[^\n]+"))) { |
@@ -50,6 +115,7 @@ class _Preprocessor { |
} |
} |
_scanner.expect("\n"); |
+ |
var allowed = |
_versions.containsKey(package) && |
constraint.allows(_versions[package]); |
@@ -58,6 +124,7 @@ class _Preprocessor { |
} else { |
_ignoreText(); |
} |
+ |
_scanner.expect("//#"); |
_scanner.scan(new RegExp(r"[ \t]*")); |
if (_scanner.scan("else")) { |
@@ -70,6 +137,7 @@ class _Preprocessor { |
_scanner.expect("//#"); |
_scanner.scan(new RegExp(r"[ \t]*")); |
} |
+ |
_scanner.expect("end"); |
if (!_scanner.isDone) _scanner.expect("\n"); |
} |