Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(847)

Unified Diff: glob/lib/src/ast.dart

Issue 1400473008: Roll Observatory packages and add a roll script (Closed) Base URL: git@github.com:dart-lang/observatory_pub_packages.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « glob/lib/glob.dart ('k') | glob/lib/src/list_tree.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: glob/lib/src/ast.dart
diff --git a/glob/lib/src/ast.dart b/glob/lib/src/ast.dart
deleted file mode 100644
index 191347734238d536fa50ae04940b5447e7029f75..0000000000000000000000000000000000000000
--- a/glob/lib/src/ast.dart
+++ /dev/null
@@ -1,372 +0,0 @@
-// 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 glob.ast;
-
-import 'package:path/path.dart' as p;
-import 'package:collection/collection.dart';
-
-import 'utils.dart';
-
-const _SEPARATOR = 0x2F; // "/"
-
-/// A node in the abstract syntax tree for a glob.
-abstract class AstNode {
- /// The cached regular expression that this AST was compiled into.
- RegExp _regExp;
-
- /// Whether this glob could match an absolute path.
- ///
- /// Either this or [canMatchRelative] or both will be true.
- final bool canMatchAbsolute = false;
-
- /// Whether this glob could match a relative path.
- ///
- /// Either this or [canMatchRelative] or both will be true.
- final bool canMatchRelative = true;
-
- /// Returns a new glob with all the options bubbled to the top level.
- ///
- /// In particular, this returns a glob AST with two guarantees:
- ///
- /// 1. There are no [OptionsNode]s other than the one at the top level.
- /// 2. It matches the same set of paths as [this].
- ///
- /// For example, given the glob `{foo,bar}/{click/clack}`, this would return
- /// `{foo/click,foo/clack,bar/click,bar/clack}`.
- OptionsNode flattenOptions() => new OptionsNode([new SequenceNode([this])]);
-
- /// Returns whether this glob matches [string].
- bool matches(String string) {
- if (_regExp == null) _regExp = new RegExp('^${_toRegExp()}\$');
- return _regExp.hasMatch(string);
- }
-
- /// Subclasses should override this to return a regular expression component.
- String _toRegExp();
-}
-
-/// A sequence of adjacent AST nodes.
-class SequenceNode extends AstNode {
- /// The nodes in the sequence.
- final List<AstNode> nodes;
-
- bool get canMatchAbsolute => nodes.first.canMatchAbsolute;
- bool get canMatchRelative => nodes.first.canMatchRelative;
-
- SequenceNode(Iterable<AstNode> nodes)
- : nodes = nodes.toList();
-
- OptionsNode flattenOptions() {
- if (nodes.isEmpty) return new OptionsNode([this]);
-
- var sequences = nodes.first.flattenOptions().options
- .map((sequence) => sequence.nodes);
- for (var node in nodes.skip(1)) {
- // Concatenate all sequences in the next options node ([nextSequences])
- // onto all previous sequences ([sequences]).
- var nextSequences = node.flattenOptions().options;
- sequences = sequences.expand((sequence) {
- return nextSequences.map((nextSequence) {
- return sequence.toList()..addAll(nextSequence.nodes);
- });
- });
- }
-
- return new OptionsNode(sequences.map((sequence) {
- // Combine any adjacent LiteralNodes in [sequence].
- return new SequenceNode(sequence.fold([], (combined, node) {
- if (combined.isEmpty || combined.last is! LiteralNode ||
- node is! LiteralNode) {
- return combined..add(node);
- }
-
- combined[combined.length - 1] =
- new LiteralNode(combined.last.text + node.text);
- return combined;
- }));
- }));
- }
-
- /// Splits this glob into components along its path separators.
- ///
- /// For example, given the glob `foo/*/*.dart`, this would return three globs:
- /// `foo`, `*`, and `*.dart`.
- ///
- /// Path separators within options nodes are not split. For example,
- /// `foo/{bar,baz/bang}/qux` will return three globs: `foo`, `{bar,baz/bang}`,
- /// and `qux`.
- ///
- /// [context] is used to determine what absolute roots look like for this
- /// glob.
- List<SequenceNode> split(p.Context context) {
- var componentsToReturn = [];
- var currentComponent;
-
- addNode(node) {
- if (currentComponent == null) currentComponent = [];
- currentComponent.add(node);
- }
-
- finishComponent() {
- if (currentComponent == null) return;
- componentsToReturn.add(new SequenceNode(currentComponent));
- currentComponent = null;
- }
-
- for (var node in nodes) {
- if (node is! LiteralNode || !node.text.contains('/')) {
- addNode(node);
- continue;
- }
-
- var text = node.text;
- if (context.style == p.Style.windows) text = text.replaceAll("/", "\\");
- var components = context.split(text);
-
- // If the first component is absolute, that means it's a separator (on
- // Windows some non-separator things are also absolute, but it's invalid
- // to have "C:" show up in the middle of a path anyway).
- if (context.isAbsolute(components.first)) {
- // If this is the first component, it's the root.
- if (componentsToReturn.isEmpty && currentComponent == null) {
- var root = components.first;
- if (context.style == p.Style.windows) {
- // Above, we switched to backslashes to make [context.split] handle
- // roots properly. That means that if there is a root, it'll still
- // have backslashes, where forward slashes are required for globs.
- // So we switch it back here.
- root = root.replaceAll("\\", "/");
- }
- addNode(new LiteralNode(root));
- }
- finishComponent();
- components = components.skip(1);
- if (components.isEmpty) continue;
- }
-
- // For each component except the last one, add a separate sequence to
- // [sequences] containing only that component.
- for (var component in components.take(components.length - 1)) {
- addNode(new LiteralNode(component));
- finishComponent();
- }
-
- // For the final component, only end its sequence (by adding a new empty
- // sequence) if it ends with a separator.
- addNode(new LiteralNode(components.last));
- if (node.text.endsWith('/')) finishComponent();
- }
-
- finishComponent();
- return componentsToReturn;
- }
-
- String _toRegExp() => nodes.map((node) => node._toRegExp()).join();
-
- bool operator==(Object other) => other is SequenceNode &&
- const IterableEquality().equals(nodes, other.nodes);
-
- int get hashCode => const IterableEquality().hash(nodes);
-
- String toString() => nodes.join();
-}
-
-/// A node matching zero or more non-separator characters.
-class StarNode extends AstNode {
- StarNode();
-
- String _toRegExp() => '[^/]*';
-
- bool operator==(Object other) => other is StarNode;
-
- int get hashCode => 0;
-
- String toString() => '*';
-}
-
-/// A node matching zero or more characters that may be separators.
-class DoubleStarNode extends AstNode {
- /// The path context for the glob.
- ///
- /// This is used to determine what absolute paths look like.
- final p.Context _context;
-
- DoubleStarNode(this._context);
-
- String _toRegExp() {
- // Double star shouldn't match paths with a leading "../", since these paths
- // wouldn't be listed with this glob. We only check for "../" at the
- // beginning since the paths are normalized before being checked against the
- // glob.
- var buffer = new StringBuffer()..write(r'(?!^(?:\.\./|');
-
- // A double star at the beginning of the glob also shouldn't match absolute
- // paths, since those also wouldn't be listed. Which root patterns we look
- // for depends on the style of path we're matching.
- if (_context.style == p.Style.posix) {
- buffer.write(r'/');
- } else if (_context.style == p.Style.windows) {
- buffer.write(r'//|[A-Za-z]:/');
- } else {
- assert(_context.style == p.Style.url);
- buffer.write(r'[a-zA-Z][-+.a-zA-Z\d]*://|/');
- }
-
- // Use `[^]` rather than `.` so that it matches newlines as well.
- buffer.write(r'))[^]*');
-
- return buffer.toString();
- }
-
- bool operator==(Object other) => other is DoubleStarNode;
-
- int get hashCode => 1;
-
- String toString() => '**';
-}
-
-/// A node matching a single non-separator character.
-class AnyCharNode extends AstNode {
- AnyCharNode();
-
- String _toRegExp() => '[^/]';
-
- bool operator==(Object other) => other is AnyCharNode;
-
- int get hashCode => 2;
-
- String toString() => '?';
-}
-
-/// A node matching a single character in a range of options.
-class RangeNode extends AstNode {
- /// The ranges matched by this node.
- ///
- /// The ends of the ranges are unicode code points.
- final Set<Range> ranges;
-
- /// Whether this range was negated.
- final bool negated;
-
- RangeNode(Iterable<Range> ranges, {this.negated})
- : ranges = ranges.toSet();
-
- OptionsNode flattenOptions() {
- if (negated || ranges.any((range) => !range.isSingleton)) {
- return super.flattenOptions();
- }
-
- // If a range explicitly lists a set of characters, return each character as
- // a separate expansion.
- return new OptionsNode(ranges.map((range) {
- return new SequenceNode([
- new LiteralNode(new String.fromCharCodes([range.min]))
- ]);
- }));
- }
-
- String _toRegExp() {
- var buffer = new StringBuffer();
-
- var containsSeparator = ranges.any((range) => range.contains(_SEPARATOR));
- if (!negated && containsSeparator) {
- // Add `(?!/)` because ranges are never allowed to match separators.
- buffer.write('(?!/)');
- }
-
- buffer.write('[');
- if (negated) {
- buffer.write('^');
- // If the range doesn't itself exclude separators, exclude them ourselves,
- // since ranges are never allowed to match them.
- if (!containsSeparator) buffer.write('/');
- }
-
- for (var range in ranges) {
- var start = new String.fromCharCodes([range.min]);
- buffer.write(regExpQuote(start));
- if (range.isSingleton) continue;
- buffer.write('-');
- buffer.write(regExpQuote(new String.fromCharCodes([range.max])));
- }
-
- buffer.write(']');
- return buffer.toString();
- }
-
- bool operator==(Object other) {
- if (other is! RangeNode) return false;
- if ((other as RangeNode).negated != negated) return false;
- return const SetEquality().equals(ranges, (other as RangeNode).ranges);
- }
-
- int get hashCode => (negated ? 1 : 3) * const SetEquality().hash(ranges);
-
- String toString() {
- var buffer = new StringBuffer()..write('[');
- for (var range in ranges) {
- buffer.writeCharCode(range.min);
- if (range.isSingleton) continue;
- buffer.write('-');
- buffer.writeCharCode(range.max);
- }
- buffer.write(']');
- return buffer.toString();
- }
-}
-
-/// A node that matches one of several options.
-class OptionsNode extends AstNode {
- /// The options to match.
- final List<SequenceNode> options;
-
- bool get canMatchAbsolute => options.any((node) => node.canMatchAbsolute);
- bool get canMatchRelative => options.any((node) => node.canMatchRelative);
-
- OptionsNode(Iterable<SequenceNode> options)
- : options = options.toList();
-
- OptionsNode flattenOptions() => new OptionsNode(
- options.expand((option) => option.flattenOptions().options));
-
- String _toRegExp() =>
- '(?:${options.map((option) => option._toRegExp()).join("|")})';
-
- bool operator==(Object other) => other is OptionsNode &&
- const UnorderedIterableEquality().equals(options, other.options);
-
- int get hashCode => const UnorderedIterableEquality().hash(options);
-
- String toString() => '{${options.join(',')}}';
-}
-
-/// A node that matches a literal string.
-class LiteralNode extends AstNode {
- /// The string to match.
- final String text;
-
- /// The path context for the glob.
- ///
- /// This is used to determine whether this could match an absolute path.
- final p.Context _context;
-
- bool get canMatchAbsolute {
- var nativeText = _context.style == p.Style.windows ?
- text.replaceAll('/', '\\') : text;
- return _context.isAbsolute(nativeText);
- }
-
- bool get canMatchRelative => !canMatchAbsolute;
-
- LiteralNode(this.text, [this._context]);
-
- String _toRegExp() => regExpQuote(text);
-
- bool operator==(Object other) => other is LiteralNode && other.text == text;
-
- int get hashCode => text.hashCode;
-
- String toString() => text;
-}
« no previous file with comments | « glob/lib/glob.dart ('k') | glob/lib/src/list_tree.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698