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

Side by Side Diff: lib/src/list_tree.dart

Issue 1491003002: Add a caseSensitive flag to new Glob(). (Closed) Base URL: git@github.com:dart-lang/glob@master
Patch Set: Code review changes Created 5 years 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 | « lib/src/ast.dart ('k') | lib/src/parser.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 library glob.list_tree; 5 library glob.list_tree;
6 6
7 import 'dart:io'; 7 import 'dart:io';
8 import 'dart:async'; 8 import 'dart:async';
9 9
10 import 'package:path/path.dart' as p; 10 import 'package:path/path.dart' as p;
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 /// 227 ///
228 /// This determines which entities will ultimately be emitted when [list] is 228 /// This determines which entities will ultimately be emitted when [list] is
229 /// called. 229 /// called.
230 OptionsNode _validator; 230 OptionsNode _validator;
231 231
232 /// Whether this node is recursive. 232 /// Whether this node is recursive.
233 /// 233 ///
234 /// A recursive node has no children and is listed recursively. 234 /// A recursive node has no children and is listed recursively.
235 bool get isRecursive => children == null; 235 bool get isRecursive => children == null;
236 236
237 bool get _caseSensitive {
238 if (_validator != null) return _validator.caseSensitive;
239 if (children == null) return true;
240 if (children.isEmpty) return true;
241 return children.keys.first.caseSensitive;
242 }
243
237 /// Whether this node doesn't itself need to be listed. 244 /// Whether this node doesn't itself need to be listed.
238 /// 245 ///
239 /// If a node has no validator and all of its children are literal filenames, 246 /// If a node has no validator and all of its children are literal filenames,
240 /// there's no need to list its contents. We can just directly traverse into 247 /// there's no need to list its contents. We can just directly traverse into
241 /// its children. 248 /// its children.
242 bool get _isIntermediate { 249 bool get _isIntermediate {
243 if (_validator != null) return false; 250 if (_validator != null) return false;
251 if (!_caseSensitive) return false;
244 return children.keys.every((sequence) => 252 return children.keys.every((sequence) =>
245 sequence.nodes.length == 1 && sequence.nodes.first is LiteralNode); 253 sequence.nodes.length == 1 && sequence.nodes.first is LiteralNode);
246 } 254 }
247 255
248 /// Returns whether listing this node might return overlapping results. 256 /// Returns whether listing this node might return overlapping results.
249 bool get canOverlap { 257 bool get canOverlap {
250 // A recusive node can never overlap with itself, because it will only ever 258 // A recusive node can never overlap with itself, because it will only ever
251 // involve a single call to [Directory.list] that's then filtered with 259 // involve a single call to [Directory.list] that's then filtered with
252 // [_validator]. 260 // [_validator].
253 if (isRecursive) return false; 261 if (isRecursive) return false;
254 262
255 // If there's more than one child node and at least one of the children is 263 // If there's more than one child node and at least one of the children is
256 // dynamic (that is, matches more than just a literal string), there may be 264 // dynamic (that is, matches more than just a literal string), there may be
257 // overlap. 265 // overlap.
258 if (children.length > 1 && children.keys.any((sequence) => 266 if (children.length > 1) {
267 // Case-insensitivity means that even literals may match multiple entries.
268 if (!_caseSensitive) return true;
269
270 if (children.keys.any((sequence) =>
259 sequence.nodes.length > 1 || sequence.nodes.single is! LiteralNode)) { 271 sequence.nodes.length > 1 || sequence.nodes.single is! LiteralNode)) {
260 return true; 272 return true;
273 }
261 } 274 }
262 275
263 return children.values.any((node) => node.canOverlap); 276 return children.values.any((node) => node.canOverlap);
264 } 277 }
265 278
266 /// Creates a node with no children and no validator. 279 /// Creates a node with no children and no validator.
267 _ListTreeNode() 280 _ListTreeNode()
268 : children = new Map<SequenceNode, _ListTreeNode>(), 281 : children = new Map<SequenceNode, _ListTreeNode>(),
269 _validator = null; 282 _validator = null;
270 283
271 /// Creates a recursive node the given [validator]. 284 /// Creates a recursive node the given [validator].
272 _ListTreeNode.recursive(SequenceNode validator) 285 _ListTreeNode.recursive(SequenceNode validator)
273 : children = null, 286 : children = null,
274 _validator = new OptionsNode([validator]); 287 _validator = new OptionsNode([validator],
288 caseSensitive: validator.caseSensitive);
275 289
276 /// Transforms this into recursive node, folding all its children into its 290 /// Transforms this into recursive node, folding all its children into its
277 /// validator. 291 /// validator.
278 void makeRecursive() { 292 void makeRecursive() {
279 if (isRecursive) return; 293 if (isRecursive) return;
280 _validator = new OptionsNode(children.keys.map((sequence) { 294 _validator = new OptionsNode(children.keys.map((sequence) {
281 var child = children[sequence]; 295 var child = children[sequence];
282 child.makeRecursive(); 296 child.makeRecursive();
283 return _join([sequence, child._validator]); 297 return _join([sequence, child._validator]);
284 })); 298 }), caseSensitive: _caseSensitive);
285 children = null; 299 children = null;
286 } 300 }
287 301
288 /// Adds [validator] to this node's existing validator. 302 /// Adds [validator] to this node's existing validator.
289 void addOption(SequenceNode validator) { 303 void addOption(SequenceNode validator) {
290 if (_validator == null) { 304 if (_validator == null) {
291 _validator = new OptionsNode([validator]); 305 _validator = new OptionsNode([validator],
306 caseSensitive: validator.caseSensitive);
292 } else { 307 } else {
293 _validator.options.add(validator); 308 _validator.options.add(validator);
294 } 309 }
295 } 310 }
296 311
297 /// Lists all entities within [dir] matching this node or its children. 312 /// Lists all entities within [dir] matching this node or its children.
298 /// 313 ///
299 /// This may return duplicate entities. These will be filtered out in 314 /// This may return duplicate entities. These will be filtered out in
300 /// [ListTree.list]. 315 /// [ListTree.list].
301 Stream<FileSystemEntity> list(String dir, {bool followLinks: true}) { 316 Stream<FileSystemEntity> list(String dir, {bool followLinks: true}) {
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 return _validator.matches(toPosixPath(p.context, path)); 419 return _validator.matches(toPosixPath(p.context, path));
405 } 420 }
406 421
407 String toString() => "($_validator) $children"; 422 String toString() => "($_validator) $children";
408 } 423 }
409 424
410 /// Joins each [components] into a new glob where each component is separated by 425 /// Joins each [components] into a new glob where each component is separated by
411 /// a path separator. 426 /// a path separator.
412 SequenceNode _join(Iterable<AstNode> components) { 427 SequenceNode _join(Iterable<AstNode> components) {
413 var componentsList = components.toList(); 428 var componentsList = components.toList();
414 var nodes = [componentsList.removeAt(0)]; 429 var first = componentsList.removeAt(0);
430 var nodes = [first];
415 for (var component in componentsList) { 431 for (var component in componentsList) {
416 nodes.add(new LiteralNode('/')); 432 nodes.add(new LiteralNode('/', caseSensitive: first.caseSensitive));
417 nodes.add(component); 433 nodes.add(component);
418 } 434 }
419 return new SequenceNode(nodes); 435 return new SequenceNode(nodes, caseSensitive: first.caseSensitive);
420 } 436 }
OLDNEW
« no previous file with comments | « lib/src/ast.dart ('k') | lib/src/parser.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698