Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 resource; | 5 library resource; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:io' as io; | 8 import 'dart:io' as io; |
| 9 | 9 |
| 10 import 'package:analyzer/src/generated/engine.dart' show TimestampedData; | 10 import 'package:analyzer/src/generated/engine.dart' show TimestampedData; |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 237 _provider._pathToResource.forEach((path, resource) { | 237 _provider._pathToResource.forEach((path, resource) { |
| 238 if (posix.dirname(path) == _path) { | 238 if (posix.dirname(path) == _path) { |
| 239 children.add(resource); | 239 children.add(resource); |
| 240 } | 240 } |
| 241 }); | 241 }); |
| 242 return children; | 242 return children; |
| 243 } | 243 } |
| 244 | 244 |
| 245 @override | 245 @override |
| 246 Stream<WatchEvent> get changes { | 246 Stream<WatchEvent> get changes { |
| 247 // TODO(paulberry): implement. | 247 if (_provider._pathToWatcher.containsKey(_path)) { |
| 248 return new StreamController<WatchEvent>().stream; | 248 // Two clients watching the same path is not yet supported. |
| 249 // TODO(paulberry): add support for this if needed. | |
| 250 throw new StateError('Path "$_path" is already being watched for changes') ; | |
| 251 } | |
| 252 var streamController = new StreamController<WatchEvent>(); | |
|
scheglov
2014/05/28 18:22:28
AFAIK we use type annotations.
Paul Berry
2014/05/28 20:16:22
Done.
| |
| 253 _provider._pathToWatcher[_path] = streamController; | |
| 254 streamController.done.then((_) { | |
| 255 _provider._pathToWatcher.remove(_path); | |
| 256 }); | |
| 257 return streamController.stream; | |
| 249 } | 258 } |
| 250 } | 259 } |
| 251 | 260 |
| 252 | 261 |
| 253 /** | 262 /** |
| 254 * An in-memory implementation of [ResourceProvider]. | 263 * An in-memory implementation of [ResourceProvider]. |
| 255 * Use `/` as a path separator. | 264 * Use `/` as a path separator. |
| 256 */ | 265 */ |
| 257 class MemoryResourceProvider implements ResourceProvider { | 266 class MemoryResourceProvider implements ResourceProvider { |
| 258 final Map<String, _MemoryResource> _pathToResource = <String, _MemoryResource> {}; | 267 final Map<String, _MemoryResource> _pathToResource = <String, _MemoryResource> {}; |
| 259 final Map<String, String> _pathToContent = <String, String>{}; | 268 final Map<String, String> _pathToContent = <String, String>{}; |
| 260 final Map<String, int> _pathToTimestamp = <String, int>{}; | 269 final Map<String, int> _pathToTimestamp = <String, int>{}; |
| 270 final Map<String, StreamController<WatchEvent>> _pathToWatcher = | |
| 271 <String, StreamController<WatchEvent>>{}; | |
| 261 int nextStamp = 0; | 272 int nextStamp = 0; |
| 262 | 273 |
| 263 @override | 274 @override |
| 264 Resource getResource(String path) { | 275 Resource getResource(String path) { |
| 265 path = posix.normalize(path); | 276 path = posix.normalize(path); |
| 266 Resource resource = _pathToResource[path]; | 277 Resource resource = _pathToResource[path]; |
| 267 if (resource == null) { | 278 if (resource == null) { |
| 268 resource = new _MemoryFile(this, path); | 279 resource = new _MemoryFile(this, path); |
| 269 } | 280 } |
| 270 return resource; | 281 return resource; |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 299 return folder; | 310 return folder; |
| 300 } | 311 } |
| 301 | 312 |
| 302 File newFile(String path, String content) { | 313 File newFile(String path, String content) { |
| 303 path = posix.normalize(path); | 314 path = posix.normalize(path); |
| 304 newFolder(posix.dirname(path)); | 315 newFolder(posix.dirname(path)); |
| 305 _MemoryFile file = new _MemoryFile(this, path); | 316 _MemoryFile file = new _MemoryFile(this, path); |
| 306 _pathToResource[path] = file; | 317 _pathToResource[path] = file; |
| 307 _pathToContent[path] = content; | 318 _pathToContent[path] = content; |
| 308 _pathToTimestamp[path] = nextStamp++; | 319 _pathToTimestamp[path] = nextStamp++; |
| 320 _notifyWatchers(path, ChangeType.ADD); | |
| 309 return file; | 321 return file; |
| 310 } | 322 } |
| 323 | |
| 324 void _notifyWatchers(String path, changeType) { | |
|
scheglov
2014/05/28 18:22:28
Type annotation for "changeType".
Paul Berry
2014/05/28 20:16:22
Done.
| |
| 325 _pathToWatcher.forEach((watcherPath, streamController) { | |
|
scheglov
2014/05/28 18:22:28
I'm not 100% sure, but AFAIK we should put type an
Paul Berry
2014/05/28 20:16:22
Done.
| |
| 326 if (posix.isWithin(watcherPath, path)) { | |
| 327 streamController.add(new WatchEvent(changeType, path)); | |
| 328 } | |
| 329 }); | |
| 330 } | |
| 331 | |
| 332 void modifyFile(String path, String content) { | |
| 333 _checkFileAtPath(path); | |
| 334 _pathToContent[path] = content; | |
| 335 _pathToTimestamp[path] = nextStamp++; | |
| 336 _notifyWatchers(path, ChangeType.MODIFY); | |
| 337 } | |
| 338 | |
| 339 void _checkFileAtPath(String path) { | |
| 340 var resource = _pathToResource[path]; | |
| 341 if (resource is! _MemoryFile) { | |
| 342 throw new ArgumentError( | |
| 343 'File expected at "$path" but ${resource.runtimeType} found'); | |
| 344 } | |
| 345 } | |
| 346 | |
| 347 void deleteFile(String path) { | |
| 348 _checkFileAtPath(path); | |
| 349 _pathToResource.remove(path); | |
| 350 _pathToContent.remove(path); | |
| 351 _pathToTimestamp.remove(path); | |
| 352 _notifyWatchers(path, ChangeType.REMOVE); | |
| 353 } | |
| 311 } | 354 } |
| 312 | 355 |
| 313 | 356 |
| 314 /** | 357 /** |
| 315 * A `dart:io` based implementation of [File]. | 358 * A `dart:io` based implementation of [File]. |
| 316 */ | 359 */ |
| 317 class _PhysicalFile extends _PhysicalResource implements File { | 360 class _PhysicalFile extends _PhysicalResource implements File { |
| 318 _PhysicalFile(io.File file) : super(file); | 361 _PhysicalFile(io.File file) : super(file); |
| 319 | 362 |
| 320 @override | 363 @override |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 397 Resource getResource(String path) { | 440 Resource getResource(String path) { |
| 398 if (io.FileSystemEntity.isDirectorySync(path)) { | 441 if (io.FileSystemEntity.isDirectorySync(path)) { |
| 399 io.Directory directory = new io.Directory(path); | 442 io.Directory directory = new io.Directory(path); |
| 400 return new _PhysicalFolder(directory); | 443 return new _PhysicalFolder(directory); |
| 401 } else { | 444 } else { |
| 402 io.File file = new io.File(path); | 445 io.File file = new io.File(path); |
| 403 return new _PhysicalFile(file); | 446 return new _PhysicalFile(file); |
| 404 } | 447 } |
| 405 } | 448 } |
| 406 } | 449 } |
| OLD | NEW |