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

Side by Side Diff: packages/glob/lib/src/ast.dart

Issue 3014633002: Roll to pickup pool changes (Closed)
Patch Set: Created 3 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 unified diff | Download patch
« no previous file with comments | « packages/glob/lib/glob.dart ('k') | packages/glob/lib/src/list_tree.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 import 'package:path/path.dart' as p; 5 import 'package:path/path.dart' as p;
6 import 'package:collection/collection.dart'; 6 import 'package:collection/collection.dart';
7 7
8 import 'utils.dart'; 8 import 'utils.dart';
9 9
10 const _SEPARATOR = 0x2F; // "/" 10 const _SEPARATOR = 0x2F; // "/"
(...skipping 20 matching lines...) Expand all
31 31
32 /// Returns a new glob with all the options bubbled to the top level. 32 /// Returns a new glob with all the options bubbled to the top level.
33 /// 33 ///
34 /// In particular, this returns a glob AST with two guarantees: 34 /// In particular, this returns a glob AST with two guarantees:
35 /// 35 ///
36 /// 1. There are no [OptionsNode]s other than the one at the top level. 36 /// 1. There are no [OptionsNode]s other than the one at the top level.
37 /// 2. It matches the same set of paths as [this]. 37 /// 2. It matches the same set of paths as [this].
38 /// 38 ///
39 /// For example, given the glob `{foo,bar}/{click/clack}`, this would return 39 /// For example, given the glob `{foo,bar}/{click/clack}`, this would return
40 /// `{foo/click,foo/clack,bar/click,bar/clack}`. 40 /// `{foo/click,foo/clack,bar/click,bar/clack}`.
41 OptionsNode flattenOptions() => new OptionsNode( 41 OptionsNode flattenOptions() => new OptionsNode([
42 [new SequenceNode([this], caseSensitive: caseSensitive)], 42 new SequenceNode([this], caseSensitive: caseSensitive)
43 caseSensitive: caseSensitive); 43 ], caseSensitive: caseSensitive);
44 44
45 /// Returns whether this glob matches [string]. 45 /// Returns whether this glob matches [string].
46 bool matches(String string) { 46 bool matches(String string) {
47 if (_regExp == null) { 47 if (_regExp == null) {
48 _regExp = new RegExp('^${_toRegExp()}\$', caseSensitive: caseSensitive); 48 _regExp = new RegExp('^${_toRegExp()}\$', caseSensitive: caseSensitive);
49 } 49 }
50 return _regExp.hasMatch(string); 50 return _regExp.hasMatch(string);
51 } 51 }
52 52
53 /// Subclasses should override this to return a regular expression component. 53 /// Subclasses should override this to return a regular expression component.
(...skipping 10 matching lines...) Expand all
64 64
65 SequenceNode(Iterable<AstNode> nodes, {bool caseSensitive: true}) 65 SequenceNode(Iterable<AstNode> nodes, {bool caseSensitive: true})
66 : nodes = nodes.toList(), 66 : nodes = nodes.toList(),
67 super._(caseSensitive); 67 super._(caseSensitive);
68 68
69 OptionsNode flattenOptions() { 69 OptionsNode flattenOptions() {
70 if (nodes.isEmpty) { 70 if (nodes.isEmpty) {
71 return new OptionsNode([this], caseSensitive: caseSensitive); 71 return new OptionsNode([this], caseSensitive: caseSensitive);
72 } 72 }
73 73
74 var sequences = nodes.first.flattenOptions().options 74 var sequences =
75 .map((sequence) => sequence.nodes); 75 nodes.first.flattenOptions().options.map((sequence) => sequence.nodes);
76 for (var node in nodes.skip(1)) { 76 for (var node in nodes.skip(1)) {
77 // Concatenate all sequences in the next options node ([nextSequences]) 77 // Concatenate all sequences in the next options node ([nextSequences])
78 // onto all previous sequences ([sequences]). 78 // onto all previous sequences ([sequences]).
79 var nextSequences = node.flattenOptions().options; 79 var nextSequences = node.flattenOptions().options;
80 sequences = sequences.expand((sequence) { 80 sequences = sequences.expand((sequence) {
81 return nextSequences.map((nextSequence) { 81 return nextSequences.map((nextSequence) {
82 return sequence.toList()..addAll(nextSequence.nodes); 82 return sequence.toList()..addAll(nextSequence.nodes);
83 }); 83 });
84 }); 84 });
85 } 85 }
86 86
87 return new OptionsNode(sequences.map((sequence) { 87 return new OptionsNode(sequences.map((sequence) {
88 // Combine any adjacent LiteralNodes in [sequence]. 88 // Combine any adjacent LiteralNodes in [sequence].
89 return new SequenceNode(sequence.fold/*<List<AstNode>>*/([], (combined, no de) { 89 return new SequenceNode(
90 if (combined.isEmpty || combined.last is! LiteralNode || 90 sequence.fold<List<AstNode>>([], (combined, node) {
91 node is! LiteralNode) { 91 if (combined.isEmpty ||
92 return combined..add(node); 92 combined.last is! LiteralNode ||
93 } 93 node is! LiteralNode) {
94 return combined..add(node);
95 }
94 96
95 combined[combined.length - 1] = new LiteralNode( 97 combined[combined.length - 1] = new LiteralNode(
96 // TODO(nweiz): Avoid casting when sdk#25565 is fixed. 98 // TODO(nweiz): Avoid casting when sdk#25565 is fixed.
97 (combined.last as LiteralNode).text + (node as LiteralNode).text, 99 (combined.last as LiteralNode).text +
98 caseSensitive: caseSensitive); 100 (node as LiteralNode).text,
99 return combined; 101 caseSensitive: caseSensitive);
100 }), caseSensitive: caseSensitive); 102 return combined;
103 }),
104 caseSensitive: caseSensitive);
101 }), caseSensitive: caseSensitive); 105 }), caseSensitive: caseSensitive);
102 } 106 }
103 107
104 /// Splits this glob into components along its path separators. 108 /// Splits this glob into components along its path separators.
105 /// 109 ///
106 /// For example, given the glob `foo/*/*.dart`, this would return three globs: 110 /// For example, given the glob `foo/*/*.dart`, this would return three globs:
107 /// `foo`, `*`, and `*.dart`. 111 /// `foo`, `*`, and `*.dart`.
108 /// 112 ///
109 /// Path separators within options nodes are not split. For example, 113 /// Path separators within options nodes are not split. For example,
110 /// `foo/{bar,baz/bang}/qux` will return three globs: `foo`, `{bar,baz/bang}`, 114 /// `foo/{bar,baz/bang}/qux` will return three globs: `foo`, `{bar,baz/bang}`,
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 addNode(new LiteralNode(components.last, caseSensitive: caseSensitive)); 182 addNode(new LiteralNode(components.last, caseSensitive: caseSensitive));
179 if (literal.text.endsWith('/')) finishComponent(); 183 if (literal.text.endsWith('/')) finishComponent();
180 } 184 }
181 185
182 finishComponent(); 186 finishComponent();
183 return componentsToReturn; 187 return componentsToReturn;
184 } 188 }
185 189
186 String _toRegExp() => nodes.map((node) => node._toRegExp()).join(); 190 String _toRegExp() => nodes.map((node) => node._toRegExp()).join();
187 191
188 bool operator==(Object other) => other is SequenceNode && 192 bool operator ==(Object other) =>
193 other is SequenceNode &&
189 const IterableEquality().equals(nodes, other.nodes); 194 const IterableEquality().equals(nodes, other.nodes);
190 195
191 int get hashCode => const IterableEquality().hash(nodes); 196 int get hashCode => const IterableEquality().hash(nodes);
192 197
193 String toString() => nodes.join(); 198 String toString() => nodes.join();
194 } 199 }
195 200
196 /// A node matching zero or more non-separator characters. 201 /// A node matching zero or more non-separator characters.
197 class StarNode extends AstNode { 202 class StarNode extends AstNode {
198 StarNode({bool caseSensitive: true}) : super._(caseSensitive); 203 StarNode({bool caseSensitive: true}) : super._(caseSensitive);
199 204
200 String _toRegExp() => '[^/]*'; 205 String _toRegExp() => '[^/]*';
201 206
202 bool operator==(Object other) => other is StarNode; 207 bool operator ==(Object other) => other is StarNode;
203 208
204 int get hashCode => 0; 209 int get hashCode => 0;
205 210
206 String toString() => '*'; 211 String toString() => '*';
207 } 212 }
208 213
209 /// A node matching zero or more characters that may be separators. 214 /// A node matching zero or more characters that may be separators.
210 class DoubleStarNode extends AstNode { 215 class DoubleStarNode extends AstNode {
211 /// The path context for the glob. 216 /// The path context for the glob.
212 /// 217 ///
(...skipping 21 matching lines...) Expand all
234 assert(_context.style == p.Style.url); 239 assert(_context.style == p.Style.url);
235 buffer.write(r'[a-zA-Z][-+.a-zA-Z\d]*://|/'); 240 buffer.write(r'[a-zA-Z][-+.a-zA-Z\d]*://|/');
236 } 241 }
237 242
238 // Use `[^]` rather than `.` so that it matches newlines as well. 243 // Use `[^]` rather than `.` so that it matches newlines as well.
239 buffer.write(r'))[^]*'); 244 buffer.write(r'))[^]*');
240 245
241 return buffer.toString(); 246 return buffer.toString();
242 } 247 }
243 248
244 bool operator==(Object other) => other is DoubleStarNode; 249 bool operator ==(Object other) => other is DoubleStarNode;
245 250
246 int get hashCode => 1; 251 int get hashCode => 1;
247 252
248 String toString() => '**'; 253 String toString() => '**';
249 } 254 }
250 255
251 /// A node matching a single non-separator character. 256 /// A node matching a single non-separator character.
252 class AnyCharNode extends AstNode { 257 class AnyCharNode extends AstNode {
253 AnyCharNode({bool caseSensitive: true}) : super._(caseSensitive); 258 AnyCharNode({bool caseSensitive: true}) : super._(caseSensitive);
254 259
255 String _toRegExp() => '[^/]'; 260 String _toRegExp() => '[^/]';
256 261
257 bool operator==(Object other) => other is AnyCharNode; 262 bool operator ==(Object other) => other is AnyCharNode;
258 263
259 int get hashCode => 2; 264 int get hashCode => 2;
260 265
261 String toString() => '?'; 266 String toString() => '?';
262 } 267 }
263 268
264 /// A node matching a single character in a range of options. 269 /// A node matching a single character in a range of options.
265 class RangeNode extends AstNode { 270 class RangeNode extends AstNode {
266 /// The ranges matched by this node. 271 /// The ranges matched by this node.
267 /// 272 ///
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 buffer.write(regExpQuote(start)); 317 buffer.write(regExpQuote(start));
313 if (range.isSingleton) continue; 318 if (range.isSingleton) continue;
314 buffer.write('-'); 319 buffer.write('-');
315 buffer.write(regExpQuote(new String.fromCharCodes([range.max]))); 320 buffer.write(regExpQuote(new String.fromCharCodes([range.max])));
316 } 321 }
317 322
318 buffer.write(']'); 323 buffer.write(']');
319 return buffer.toString(); 324 return buffer.toString();
320 } 325 }
321 326
322 bool operator==(Object other) { 327 bool operator ==(Object other) {
323 if (other is! RangeNode) return false; 328 if (other is! RangeNode) return false;
324 if ((other as RangeNode).negated != negated) return false; 329 if ((other as RangeNode).negated != negated) return false;
325 return const SetEquality().equals(ranges, (other as RangeNode).ranges); 330 return const SetEquality().equals(ranges, (other as RangeNode).ranges);
326 } 331 }
327 332
328 int get hashCode => (negated ? 1 : 3) * const SetEquality().hash(ranges); 333 int get hashCode => (negated ? 1 : 3) * const SetEquality().hash(ranges);
329 334
330 String toString() { 335 String toString() {
331 var buffer = new StringBuffer()..write('['); 336 var buffer = new StringBuffer()..write('[');
332 for (var range in ranges) { 337 for (var range in ranges) {
(...skipping 19 matching lines...) Expand all
352 : options = options.toList(), 357 : options = options.toList(),
353 super._(caseSensitive); 358 super._(caseSensitive);
354 359
355 OptionsNode flattenOptions() => new OptionsNode( 360 OptionsNode flattenOptions() => new OptionsNode(
356 options.expand((option) => option.flattenOptions().options), 361 options.expand((option) => option.flattenOptions().options),
357 caseSensitive: caseSensitive); 362 caseSensitive: caseSensitive);
358 363
359 String _toRegExp() => 364 String _toRegExp() =>
360 '(?:${options.map((option) => option._toRegExp()).join("|")})'; 365 '(?:${options.map((option) => option._toRegExp()).join("|")})';
361 366
362 bool operator==(Object other) => other is OptionsNode && 367 bool operator ==(Object other) =>
368 other is OptionsNode &&
363 const UnorderedIterableEquality().equals(options, other.options); 369 const UnorderedIterableEquality().equals(options, other.options);
364 370
365 int get hashCode => const UnorderedIterableEquality().hash(options); 371 int get hashCode => const UnorderedIterableEquality().hash(options);
366 372
367 String toString() => '{${options.join(',')}}'; 373 String toString() => '{${options.join(',')}}';
368 } 374 }
369 375
370 /// A node that matches a literal string. 376 /// A node that matches a literal string.
371 class LiteralNode extends AstNode { 377 class LiteralNode extends AstNode {
372 /// The string to match. 378 /// The string to match.
373 final String text; 379 final String text;
374 380
375 /// The path context for the glob. 381 /// The path context for the glob.
376 /// 382 ///
377 /// This is used to determine whether this could match an absolute path. 383 /// This is used to determine whether this could match an absolute path.
378 final p.Context _context; 384 final p.Context _context;
379 385
380 bool get canMatchAbsolute { 386 bool get canMatchAbsolute {
381 var nativeText = _context.style == p.Style.windows ? 387 var nativeText =
382 text.replaceAll('/', '\\') : text; 388 _context.style == p.Style.windows ? text.replaceAll('/', '\\') : text;
383 return _context.isAbsolute(nativeText); 389 return _context.isAbsolute(nativeText);
384 } 390 }
385 391
386 bool get canMatchRelative => !canMatchAbsolute; 392 bool get canMatchRelative => !canMatchAbsolute;
387 393
388 LiteralNode(this.text, {p.Context context, bool caseSensitive: true}) 394 LiteralNode(this.text, {p.Context context, bool caseSensitive: true})
389 : _context = context, 395 : _context = context,
390 super._(caseSensitive); 396 super._(caseSensitive);
391 397
392 String _toRegExp() => regExpQuote(text); 398 String _toRegExp() => regExpQuote(text);
393 399
394 bool operator==(Object other) => other is LiteralNode && other.text == text; 400 bool operator ==(Object other) => other is LiteralNode && other.text == text;
395 401
396 int get hashCode => text.hashCode; 402 int get hashCode => text.hashCode;
397 403
398 String toString() => text; 404 String toString() => text;
399 } 405 }
OLDNEW
« no previous file with comments | « packages/glob/lib/glob.dart ('k') | packages/glob/lib/src/list_tree.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698