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

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

Issue 1843173003: Fix strong mode warnings and errors. (Closed) Base URL: git@github.com:dart-lang/glob@master
Patch Set: Created 4 years, 8 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 | « 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 import 'dart:io'; 5 import 'dart:io';
6 import 'dart:async'; 6 import 'dart:async';
7 7
8 import 'package:async/async.dart';
8 import 'package:path/path.dart' as p; 9 import 'package:path/path.dart' as p;
9 10
10 import 'ast.dart'; 11 import 'ast.dart';
11 import 'stream_pool.dart';
12 import 'utils.dart'; 12 import 'utils.dart';
13 13
14 /// The errno for a file or directory not existing on Mac and Linux. 14 /// The errno for a file or directory not existing on Mac and Linux.
15 const _ENOENT = 2; 15 const _ENOENT = 2;
16 16
17 /// Another errno we see on Windows when trying to list a non-existent 17 /// Another errno we see on Windows when trying to list a non-existent
18 /// directory. 18 /// directory.
19 const _ENOENT_WIN = 3; 19 const _ENOENT_WIN = 3;
20 20
21 /// A structure built from a glob that efficiently lists filesystem entities 21 /// A structure built from a glob that efficiently lists filesystem entities
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 } 90 }
91 } 91 }
92 92
93 _addGlob(root, components); 93 _addGlob(root, components);
94 } 94 }
95 95
96 _canOverlap = _computeCanOverlap(); 96 _canOverlap = _computeCanOverlap();
97 } 97 }
98 98
99 /// Add the glob represented by [components] to the tree under [root]. 99 /// Add the glob represented by [components] to the tree under [root].
100 void _addGlob(String root, List<AstNode> components) { 100 void _addGlob(String root, List<SequenceNode> components) {
101 // The first [parent] represents the root directory itself. It may be null 101 // The first [parent] represents the root directory itself. It may be null
102 // here if this is the first option with this particular [root]. If so, 102 // here if this is the first option with this particular [root]. If so,
103 // we'll create it below. 103 // we'll create it below.
104 // 104 //
105 // As we iterate through [components], [parent] will be set to 105 // As we iterate through [components], [parent] will be set to
106 // progressively more nested nodes. 106 // progressively more nested nodes.
107 var parent = _trees[root]; 107 var parent = _trees[root];
108 for (var i = 0; i < components.length; i++) { 108 for (var i = 0; i < components.length; i++) {
109 var component = components[i]; 109 var component = components[i];
110 var recursive = component.nodes.any((node) => node is DoubleStarNode); 110 var recursive = component.nodes.any((node) => node is DoubleStarNode);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 if (_trees.length > 1 && _trees.containsKey('.')) return true; 163 if (_trees.length > 1 && _trees.containsKey('.')) return true;
164 164
165 // Otherwise, this can only overlap if the tree beneath any given root could 165 // Otherwise, this can only overlap if the tree beneath any given root could
166 // overlap internally. 166 // overlap internally.
167 return _trees.values.any((node) => node.canOverlap); 167 return _trees.values.any((node) => node.canOverlap);
168 } 168 }
169 169
170 /// List all entities that match this glob beneath [root]. 170 /// List all entities that match this glob beneath [root].
171 Stream<FileSystemEntity> list({String root, bool followLinks: true}) { 171 Stream<FileSystemEntity> list({String root, bool followLinks: true}) {
172 if (root == null) root = '.'; 172 if (root == null) root = '.';
173 var pool = new StreamPool(); 173 var group = new StreamGroup<FileSystemEntity>();
174 for (var rootDir in _trees.keys) { 174 for (var rootDir in _trees.keys) {
175 var dir = rootDir == '.' ? root : rootDir; 175 var dir = rootDir == '.' ? root : rootDir;
176 pool.add(_trees[rootDir].list(dir, followLinks: followLinks)); 176 group.add(_trees[rootDir].list(dir, followLinks: followLinks));
177 } 177 }
178 pool.closeWhenEmpty(); 178 group.close();
179 179
180 if (!_canOverlap) return pool.stream; 180 if (!_canOverlap) return group.stream;
181 181
182 // TODO(nweiz): Rather than filtering here, avoid double-listing directories 182 // TODO(nweiz): Rather than filtering here, avoid double-listing directories
183 // in the first place. 183 // in the first place.
184 var seen = new Set(); 184 var seen = new Set();
185 return pool.stream.where((entity) { 185 return group.stream.where((entity) {
186 if (seen.contains(entity.path)) return false; 186 if (seen.contains(entity.path)) return false;
187 seen.add(entity.path); 187 seen.add(entity.path);
188 return true; 188 return true;
189 }); 189 });
190 } 190 }
191 191
192 /// Synchronosuly list all entities that match this glob beneath [root]. 192 /// Synchronosuly list all entities that match this glob beneath [root].
193 List<FileSystemEntity> listSync({String root, bool followLinks: true}) { 193 List<FileSystemEntity> listSync({String root, bool followLinks: true}) {
194 if (root == null) root = '.'; 194 if (root == null) root = '.';
195 195
196 var result = _trees.keys.expand((rootDir) { 196 // TODO(nweiz): Remove the explicit annotation when sdk#26139 is fixed.
197 var result = _trees.keys.expand/*<FileSystemEntity>*/((rootDir) {
197 var dir = rootDir == '.' ? root : rootDir; 198 var dir = rootDir == '.' ? root : rootDir;
198 return _trees[rootDir].listSync(dir, followLinks: followLinks); 199 return _trees[rootDir].listSync(dir, followLinks: followLinks);
199 }); 200 });
200 201
201 if (!_canOverlap) return result.toList(); 202 if (!_canOverlap) return result.toList();
202 203
203 // TODO(nweiz): Rather than filtering here, avoid double-listing directories 204 // TODO(nweiz): Rather than filtering here, avoid double-listing directories
204 // in the first place. 205 // in the first place.
205 var seen = new Set(); 206 var seen = new Set<String>();
206 return result.where((entity) { 207 return result.where((entity) {
207 if (seen.contains(entity.path)) return false; 208 if (seen.contains(entity.path)) return false;
208 seen.add(entity.path); 209 seen.add(entity.path);
209 return true; 210 return true;
210 }).toList(); 211 }).toList();
211 } 212 }
212 } 213 }
213 214
214 /// A single node in a [ListTree]. 215 /// A single node in a [ListTree].
215 class _ListTreeNode { 216 class _ListTreeNode {
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 /// Lists all entities within [dir] matching this node or its children. 311 /// Lists all entities within [dir] matching this node or its children.
311 /// 312 ///
312 /// This may return duplicate entities. These will be filtered out in 313 /// This may return duplicate entities. These will be filtered out in
313 /// [ListTree.list]. 314 /// [ListTree.list].
314 Stream<FileSystemEntity> list(String dir, {bool followLinks: true}) { 315 Stream<FileSystemEntity> list(String dir, {bool followLinks: true}) {
315 if (isRecursive) { 316 if (isRecursive) {
316 return new Directory(dir).list(recursive: true, followLinks: followLinks) 317 return new Directory(dir).list(recursive: true, followLinks: followLinks)
317 .where((entity) => _matches(p.relative(entity.path, from: dir))); 318 .where((entity) => _matches(p.relative(entity.path, from: dir)));
318 } 319 }
319 320
320 var resultPool = new StreamPool(); 321 var resultGroup = new StreamGroup<FileSystemEntity>();
321 322
322 // Don't spawn extra [Directory.list] calls when we already know exactly 323 // Don't spawn extra [Directory.list] calls when we already know exactly
323 // which subdirectories we're interested in. 324 // which subdirectories we're interested in.
324 if (_isIntermediate) { 325 if (_isIntermediate) {
325 children.forEach((sequence, child) { 326 children.forEach((sequence, child) {
326 resultPool.add(child.list(p.join(dir, sequence.nodes.single.text), 327 resultGroup.add(child.list(
328 p.join(dir, (sequence.nodes.single as LiteralNode).text),
327 followLinks: followLinks)); 329 followLinks: followLinks));
328 }); 330 });
329 resultPool.closeWhenEmpty(); 331 resultGroup.close();
330 return resultPool.stream; 332 return resultGroup.stream;
331 } 333 }
332 334
333 var resultController = new StreamController(sync: true); 335 var resultController = new StreamController<FileSystemEntity>(sync: true);
334 resultPool.add(resultController.stream); 336 resultGroup.add(resultController.stream);
335 new Directory(dir).list(followLinks: followLinks).listen((entity) { 337 new Directory(dir).list(followLinks: followLinks).listen((entity) {
336 var basename = p.relative(entity.path, from: dir); 338 var basename = p.relative(entity.path, from: dir);
337 if (_matches(basename)) resultController.add(entity); 339 if (_matches(basename)) resultController.add(entity);
338 340
339 children.forEach((sequence, child) { 341 children.forEach((sequence, child) {
340 if (entity is! Directory) return; 342 if (entity is! Directory) return;
341 if (!sequence.matches(basename)) return; 343 if (!sequence.matches(basename)) return;
342 var stream = child.list(p.join(dir, basename), followLinks: followLinks) 344 var stream = child.list(p.join(dir, basename), followLinks: followLinks)
343 .handleError((_) {}, test: (error) { 345 .handleError((_) {}, test: (error) {
344 // Ignore errors from directories not existing. We do this here so 346 // Ignore errors from directories not existing. We do this here so
345 // that we only ignore warnings below wild cards. For example, the 347 // that we only ignore warnings below wild cards. For example, the
346 // glob "foo/bar/*/baz" should fail if "foo/bar" doesn't exist but 348 // glob "foo/bar/*/baz" should fail if "foo/bar" doesn't exist but
347 // succeed if "foo/bar/qux/baz" doesn't exist. 349 // succeed if "foo/bar/qux/baz" doesn't exist.
348 return error is FileSystemException && 350 return error is FileSystemException &&
349 (error.osError.errorCode == _ENOENT || 351 (error.osError.errorCode == _ENOENT ||
350 error.osError.errorCode == _ENOENT_WIN); 352 error.osError.errorCode == _ENOENT_WIN);
351 }); 353 });
352 resultPool.add(stream); 354 resultGroup.add(stream);
353 }); 355 });
354 }, 356 },
355 onError: resultController.addError, 357 onError: resultController.addError,
356 onDone: resultController.close); 358 onDone: () {
359 resultController.close();
360 resultGroup.close();
361 });
357 362
358 resultPool.closeWhenEmpty(); 363 return resultGroup.stream;
359 return resultPool.stream;
360 } 364 }
361 365
362 /// Synchronously lists all entities within [dir] matching this node or its 366 /// Synchronously lists all entities within [dir] matching this node or its
363 /// children. 367 /// children.
364 /// 368 ///
365 /// This may return duplicate entities. These will be filtered out in 369 /// This may return duplicate entities. These will be filtered out in
366 /// [ListTree.listSync]. 370 /// [ListTree.listSync].
367 Iterable<FileSystemEntity> listSync(String dir, {bool followLinks: true}) { 371 Iterable<FileSystemEntity> listSync(String dir, {bool followLinks: true}) {
368 if (isRecursive) { 372 if (isRecursive) {
369 return new Directory(dir) 373 return new Directory(dir)
370 .listSync(recursive: true, followLinks: followLinks) 374 .listSync(recursive: true, followLinks: followLinks)
371 .where((entity) => _matches(p.relative(entity.path, from: dir))); 375 .where((entity) => _matches(p.relative(entity.path, from: dir)));
372 } 376 }
373 377
374 // Don't spawn extra [Directory.listSync] calls when we already know exactly 378 // Don't spawn extra [Directory.listSync] calls when we already know exactly
375 // which subdirectories we're interested in. 379 // which subdirectories we're interested in.
376 if (_isIntermediate) { 380 if (_isIntermediate) {
377 return children.keys.expand((sequence) { 381 return children.keys.expand((sequence) {
378 return children[sequence].listSync( 382 return children[sequence].listSync(
379 p.join(dir, sequence.nodes.single.text), followLinks: followLinks); 383 p.join(dir, (sequence.nodes.single as LiteralNode).text),
384 followLinks: followLinks);
380 }); 385 });
381 } 386 }
382 387
383 return new Directory(dir).listSync(followLinks: followLinks) 388 return new Directory(dir).listSync(followLinks: followLinks)
384 .expand((entity) { 389 .expand((entity) {
385 var entities = []; 390 var entities = <FileSystemEntity>[];
386 var basename = p.relative(entity.path, from: dir); 391 var basename = p.relative(entity.path, from: dir);
387 if (_matches(basename)) entities.add(entity); 392 if (_matches(basename)) entities.add(entity);
388 if (entity is! Directory) return entities; 393 if (entity is! Directory) return entities;
389 394
390 entities.addAll(children.keys 395 entities.addAll(children.keys
391 .where((sequence) => sequence.matches(basename)) 396 .where((sequence) => sequence.matches(basename))
392 .expand((sequence) { 397 .expand((sequence) {
393 try { 398 try {
394 return children[sequence].listSync( 399 return children[sequence].listSync(
395 p.join(dir, basename), followLinks: followLinks).toList(); 400 p.join(dir, basename), followLinks: followLinks).toList();
(...skipping 29 matching lines...) Expand all
425 SequenceNode _join(Iterable<AstNode> components) { 430 SequenceNode _join(Iterable<AstNode> components) {
426 var componentsList = components.toList(); 431 var componentsList = components.toList();
427 var first = componentsList.removeAt(0); 432 var first = componentsList.removeAt(0);
428 var nodes = [first]; 433 var nodes = [first];
429 for (var component in componentsList) { 434 for (var component in componentsList) {
430 nodes.add(new LiteralNode('/', caseSensitive: first.caseSensitive)); 435 nodes.add(new LiteralNode('/', caseSensitive: first.caseSensitive));
431 nodes.add(component); 436 nodes.add(component);
432 } 437 }
433 return new SequenceNode(nodes, caseSensitive: first.caseSensitive); 438 return new SequenceNode(nodes, caseSensitive: first.caseSensitive);
434 } 439 }
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