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

Side by Side Diff: pkg/analyzer/lib/file_system/memory_file_system.dart

Issue 372763003: Move file_system libraries into 'analyzer'. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 5 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 | Annotate | Revision Log
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 resource; 5 library memory_file_system;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:collection'; 8 import 'dart:collection';
9 import 'dart:io' as io;
10 9
11 import 'package:analyzer/src/generated/engine.dart' show TimestampedData; 10 import 'package:analyzer/src/generated/engine.dart' show TimestampedData;
12 import 'package:analyzer/src/generated/java_io.dart';
13 import 'package:analyzer/src/generated/source_io.dart'; 11 import 'package:analyzer/src/generated/source_io.dart';
14 import 'package:path/path.dart'; 12 import 'package:path/path.dart';
15 import 'package:watcher/watcher.dart'; 13 import 'package:watcher/watcher.dart';
16 14
17 15 import 'file_system.dart';
18 /**
19 * [File]s are leaf [Resource]s which contain data.
20 */
21 abstract class File extends Resource {
22 /**
23 * Create a new [Source] instance that serves this file.
24 */
25 Source createSource(UriKind uriKind);
26 }
27
28
29 /**
30 * [Folder]s are [Resource]s which may contain files and/or other folders.
31 */
32 abstract class Folder extends Resource {
33 /**
34 * Return an existing child [Resource] with the given [relPath].
35 * Return a not existing [File] if no such child exist.
36 */
37 Resource getChild(String relPath);
38
39 /**
40 * Return a list of existing direct children [Resource]s (folders and files)
41 * in this folder, in no particular order.
42 */
43 List<Resource> getChildren();
44
45 /**
46 * Watch for changes to the files inside this folder (and in any nested
47 * folders, including folders reachable via links).
48 */
49 Stream<WatchEvent> get changes;
50
51 /**
52 * If the path [path] is a relative path, convert it to an absolute path
53 * by interpreting it relative to this folder. If it is already an aboslute
54 * path, then don't change it.
55 *
56 * However, regardless of whether [path] is relative or absolute, normalize
57 * it by removing path components of the form '.' or '..'.
58 */
59 String canonicalizePath(String path);
60 }
61
62
63 /**
64 * The abstract class [Resource] is an abstraction of file or folder.
65 */
66 abstract class Resource {
67 /**
68 * Return `true` if this resource exists.
69 */
70 bool get exists;
71
72 /**
73 * Return the full path to this resource.
74 */
75 String get path;
76
77 /**
78 * Return a short version of the name that can be displayed to the user to
79 * denote this resource.
80 */
81 String get shortName;
82
83 /**
84 * Return the [Folder] that contains this resource, or `null` if this resource
85 * is a root folder.
86 */
87 Folder get parent;
88 }
89
90
91 /**
92 * Instances of the class [ResourceProvider] convert [String] paths into
93 * [Resource]s.
94 */
95 abstract class ResourceProvider {
96 /**
97 * Return the [Resource] that corresponds to the given [path].
98 */
99 Resource getResource(String path);
100
101 /**
102 * Get the path context used by this resource provider.
103 */
104 Context get pathContext;
105 }
106
107
108 /**
109 * An in-memory implementation of [Resource].
110 */
111 abstract class _MemoryResource implements Resource {
112 final MemoryResourceProvider _provider;
113 final String path;
114
115 _MemoryResource(this._provider, this.path);
116
117 @override
118 bool operator ==(other) {
119 if (runtimeType != other.runtimeType) {
120 return false;
121 }
122 return path == other.path;
123 }
124
125 @override
126 bool get exists => _provider._pathToResource.containsKey(path);
127
128 @override
129 get hashCode => path.hashCode;
130
131 @override
132 String get shortName => posix.basename(path);
133
134 @override
135 String toString() => path;
136
137 @override
138 Folder get parent {
139 String parentPath = posix.dirname(path);
140 if (parentPath == path) {
141 return null;
142 }
143 return _provider.getResource(parentPath);
144 }
145 }
146
147
148 /**
149 * An in-memory implementation of [File].
150 */
151 class _MemoryFile extends _MemoryResource implements File {
152 _MemoryFile(MemoryResourceProvider provider, String path) :
153 super(provider, path);
154
155 @override
156 Source createSource(UriKind uriKind) {
157 return new _MemoryFileSource(this, uriKind);
158 }
159
160 String get _content {
161 String content = _provider._pathToContent[path];
162 if (content == null) {
163 throw new MemoryResourceException(path, "File '$path' does not exist");
164 }
165 return content;
166 }
167
168 int get _timestamp => _provider._pathToTimestamp[path];
169 }
170 16
171 17
172 /** 18 /**
173 * Exception thrown when a memory [Resource] file operation fails. 19 * Exception thrown when a memory [Resource] file operation fails.
174 */ 20 */
175 class MemoryResourceException { 21 class MemoryResourceException {
176 final path; 22 final path;
177 final message; 23 final message;
178 24
179 MemoryResourceException(this.path, this.message); 25 MemoryResourceException(this.path, this.message);
180 26
181 @override 27 @override
182 String toString() { 28 String toString() {
183 return "MemoryResourceException(path=$path; message=$message)"; 29 return "MemoryResourceException(path=$path; message=$message)";
184 } 30 }
185 } 31 }
186 32
187 33
188 /** 34 /**
35 * An in-memory implementation of [ResourceProvider].
36 * Use `/` as a path separator.
37 */
38 class MemoryResourceProvider implements ResourceProvider {
39 final Map<String, _MemoryResource> _pathToResource =
40 new HashMap<String, _MemoryResource>();
41 final Map<String, String> _pathToContent = new HashMap<String, String>();
42 final Map<String, int> _pathToTimestamp = new HashMap<String, int>();
43 final Map<String, List<StreamController<WatchEvent>>> _pathToWatchers =
44 new HashMap<String, List<StreamController<WatchEvent>>>();
45 int nextStamp = 0;
46
47 @override
48 Context get pathContext => posix;
49
50 void deleteFile(String path) {
51 _checkFileAtPath(path);
52 _pathToResource.remove(path);
53 _pathToContent.remove(path);
54 _pathToTimestamp.remove(path);
55 _notifyWatchers(path, ChangeType.REMOVE);
56 }
57
58 @override
59 Resource getResource(String path) {
60 path = posix.normalize(path);
61 Resource resource = _pathToResource[path];
62 if (resource == null) {
63 resource = new _MemoryFile(this, path);
64 }
65 return resource;
66 }
67
68 void modifyFile(String path, String content) {
69 _checkFileAtPath(path);
70 _pathToContent[path] = content;
71 _pathToTimestamp[path] = nextStamp++;
72 _notifyWatchers(path, ChangeType.MODIFY);
73 }
74
75 /**
76 * Create a resource representing a dummy link (that is, a File object which
77 * appears in its parent directory, but whose `exists` property is false)
78 */
79 File newDummyLink(String path) {
80 path = posix.normalize(path);
81 newFolder(posix.dirname(path));
82 _MemoryDummyLink link = new _MemoryDummyLink(this, path);
83 _pathToResource[path] = link;
84 _pathToTimestamp[path] = nextStamp++;
85 _notifyWatchers(path, ChangeType.ADD);
86 return link;
87 }
88
89 File newFile(String path, String content) {
90 path = posix.normalize(path);
91 newFolder(posix.dirname(path));
92 _MemoryFile file = new _MemoryFile(this, path);
93 _pathToResource[path] = file;
94 _pathToContent[path] = content;
95 _pathToTimestamp[path] = nextStamp++;
96 _notifyWatchers(path, ChangeType.ADD);
97 return file;
98 }
99
100 Folder newFolder(String path) {
101 path = posix.normalize(path);
102 if (!path.startsWith('/')) {
103 throw new ArgumentError("Path must start with '/'");
104 }
105 _MemoryResource resource = _pathToResource[path];
106 if (resource == null) {
107 String parentPath = posix.dirname(path);
108 if (parentPath != path) {
109 newFolder(parentPath);
110 }
111 _MemoryFolder folder = new _MemoryFolder(this, path);
112 _pathToResource[path] = folder;
113 _pathToTimestamp[path] = nextStamp++;
114 return folder;
115 } else if (resource is _MemoryFolder) {
116 return resource;
117 } else {
118 String message = 'Folder expected at '
119 "'$path'"
120 'but ${resource.runtimeType} found';
121 throw new ArgumentError(message);
122 }
123 }
124
125 void _checkFileAtPath(String path) {
126 _MemoryResource resource = _pathToResource[path];
127 if (resource is! _MemoryFile) {
128 throw new ArgumentError(
129 'File expected at "$path" but ${resource.runtimeType} found');
130 }
131 }
132
133 void _notifyWatchers(String path, ChangeType changeType) {
134 _pathToWatchers.forEach((String watcherPath, List<StreamController<WatchEven t>> streamControllers) {
135 if (posix.isWithin(watcherPath, path)) {
136 for (StreamController<WatchEvent> streamController in streamControllers) {
137 streamController.add(new WatchEvent(changeType, path));
138 }
139 }
140 });
141 }
142 }
143
144
145 /**
189 * An in-memory implementation of [File] which acts like a symbolic link to a 146 * An in-memory implementation of [File] which acts like a symbolic link to a
190 * non-existent file. 147 * non-existent file.
191 */ 148 */
192 class _MemoryDummyLink extends _MemoryResource implements File { 149 class _MemoryDummyLink extends _MemoryResource implements File {
193 _MemoryDummyLink(MemoryResourceProvider provider, String path) : 150 _MemoryDummyLink(MemoryResourceProvider provider, String path) :
194 super(provider, path); 151 super(provider, path);
195 152
196 @override 153 @override
197 Source createSource(UriKind uriKind) { 154 bool get exists => false;
198 throw new MemoryResourceException(path, "File '$path' could not be read");
199 }
200 155
201 String get _content { 156 String get _content {
202 throw new MemoryResourceException(path, "File '$path' could not be read"); 157 throw new MemoryResourceException(path, "File '$path' could not be read");
203 } 158 }
204 159
205 int get _timestamp => _provider._pathToTimestamp[path]; 160 int get _timestamp => _provider._pathToTimestamp[path];
206 161
207 @override 162 @override
208 bool get exists => false; 163 Source createSource(UriKind uriKind) {
164 throw new MemoryResourceException(path, "File '$path' could not be read");
165 }
209 } 166 }
210 167
211 168
169 /**
170 * An in-memory implementation of [File].
171 */
172 class _MemoryFile extends _MemoryResource implements File {
173 _MemoryFile(MemoryResourceProvider provider, String path) :
174 super(provider, path);
175
176 String get _content {
177 String content = _provider._pathToContent[path];
178 if (content == null) {
179 throw new MemoryResourceException(path, "File '$path' does not exist");
180 }
181 return content;
182 }
183
184 int get _timestamp => _provider._pathToTimestamp[path];
185
186 @override
187 Source createSource(UriKind uriKind) {
188 return new _MemoryFileSource(this, uriKind);
189 }
190 }
191
192
212 /** 193 /**
213 * An in-memory implementation of [Source]. 194 * An in-memory implementation of [Source].
214 */ 195 */
215 class _MemoryFileSource implements Source { 196 class _MemoryFileSource implements Source {
216 final _MemoryFile _file; 197 final _MemoryFile _file;
217 198
218 final UriKind uriKind; 199 final UriKind uriKind;
219 200
220 _MemoryFileSource(this._file, this.uriKind); 201 _MemoryFileSource(this._file, this.uriKind);
221 202
222 @override 203 @override
223 bool operator ==(other) {
224 if (other is _MemoryFileSource) {
225 return other._file == _file;
226 }
227 return false;
228 }
229
230 @override
231 TimestampedData<String> get contents { 204 TimestampedData<String> get contents {
232 return new TimestampedData<String>(modificationStamp, _file._content); 205 return new TimestampedData<String>(modificationStamp, _file._content);
233 } 206 }
234 207
235 @override 208 @override
236 String get encoding { 209 String get encoding {
237 return '${new String.fromCharCode(uriKind.encoding)}${_file.path}'; 210 return '${new String.fromCharCode(uriKind.encoding)}${_file.path}';
238 } 211 }
239 212
240 @override 213 @override
241 bool exists() => _file.exists;
242
243 @override
244 String get fullName => _file.path; 214 String get fullName => _file.path;
245 215
246 @override 216 @override
247 int get hashCode => _file.hashCode; 217 int get hashCode => _file.hashCode;
248 218
249 @override 219 @override
250 bool get isInSystemLibrary => false; 220 bool get isInSystemLibrary => false;
251 221
252 @override 222 @override
253 int get modificationStamp => _file._timestamp; 223 int get modificationStamp => _file._timestamp;
254 224
255 @override 225 @override
226 String get shortName => _file.shortName;
227
228 @override
229 bool operator ==(other) {
230 if (other is _MemoryFileSource) {
231 return other._file == _file;
232 }
233 return false;
234 }
235
236 @override
237 bool exists() => _file.exists;
238
239 @override
256 Source resolveRelative(Uri relativeUri) { 240 Source resolveRelative(Uri relativeUri) {
257 String relativePath = posix.fromUri(relativeUri); 241 String relativePath = posix.fromUri(relativeUri);
258 String folderPath = posix.dirname(_file.path); 242 String folderPath = posix.dirname(_file.path);
259 String path = posix.join(folderPath, relativePath); 243 String path = posix.join(folderPath, relativePath);
260 path = posix.normalize(path); 244 path = posix.normalize(path);
261 _MemoryFile file = new _MemoryFile(_file._provider, path); 245 _MemoryFile file = new _MemoryFile(_file._provider, path);
262 return new _MemoryFileSource(file, uriKind); 246 return new _MemoryFileSource(file, uriKind);
263 } 247 }
264
265 @override
266 String get shortName => _file.shortName;
267 } 248 }
268 249
269 250
270 /** 251 /**
271 * An in-memory implementation of [Folder]. 252 * An in-memory implementation of [Folder].
272 */ 253 */
273 class _MemoryFolder extends _MemoryResource implements Folder { 254 class _MemoryFolder extends _MemoryResource implements Folder {
274 _MemoryFolder(MemoryResourceProvider provider, String path) : 255 _MemoryFolder(MemoryResourceProvider provider, String path) :
275 super(provider, path); 256 super(provider, path);
276 @override 257 @override
277 Resource getChild(String relPath) {
278 String childPath = canonicalizePath(relPath);
279 _MemoryResource resource = _provider._pathToResource[childPath];
280 if (resource == null) {
281 resource = new _MemoryFile(_provider, childPath);
282 }
283 return resource;
284 }
285
286 @override
287 List<Resource> getChildren() {
288 List<Resource> children = <Resource>[];
289 _provider._pathToResource.forEach((resourcePath, resource) {
290 if (posix.dirname(resourcePath) == path) {
291 children.add(resource);
292 }
293 });
294 return children;
295 }
296
297 @override
298 Stream<WatchEvent> get changes { 258 Stream<WatchEvent> get changes {
299 StreamController<WatchEvent> streamController = new StreamController<WatchEv ent>(); 259 StreamController<WatchEvent> streamController = new StreamController<WatchEv ent>();
300 if (!_provider._pathToWatchers.containsKey(path)) { 260 if (!_provider._pathToWatchers.containsKey(path)) {
301 _provider._pathToWatchers[path] = <StreamController<WatchEvent>>[]; 261 _provider._pathToWatchers[path] = <StreamController<WatchEvent>>[];
302 } 262 }
303 _provider._pathToWatchers[path].add(streamController); 263 _provider._pathToWatchers[path].add(streamController);
304 streamController.done.then((_) { 264 streamController.done.then((_) {
305 _provider._pathToWatchers[path].remove(streamController); 265 _provider._pathToWatchers[path].remove(streamController);
306 if (_provider._pathToWatchers[path].isEmpty) { 266 if (_provider._pathToWatchers[path].isEmpty) {
307 _provider._pathToWatchers.remove(path); 267 _provider._pathToWatchers.remove(path);
308 } 268 }
309 }); 269 });
310 return streamController.stream; 270 return streamController.stream;
311 } 271 }
312 272
313 @override 273 @override
314 String canonicalizePath(String relPath) { 274 String canonicalizePath(String relPath) {
315 relPath = posix.normalize(relPath); 275 relPath = posix.normalize(relPath);
316 String childPath = posix.join(path, relPath); 276 String childPath = posix.join(path, relPath);
317 childPath = posix.normalize(childPath); 277 childPath = posix.normalize(childPath);
318 return childPath; 278 return childPath;
319 } 279 }
280
281 @override
282 Resource getChild(String relPath) {
283 String childPath = canonicalizePath(relPath);
284 _MemoryResource resource = _provider._pathToResource[childPath];
285 if (resource == null) {
286 resource = new _MemoryFile(_provider, childPath);
287 }
288 return resource;
289 }
290
291 @override
292 List<Resource> getChildren() {
293 List<Resource> children = <Resource>[];
294 _provider._pathToResource.forEach((resourcePath, resource) {
295 if (posix.dirname(resourcePath) == path) {
296 children.add(resource);
297 }
298 });
299 return children;
300 }
320 } 301 }
321 302
322 303
323 /** 304 /**
324 * An in-memory implementation of [ResourceProvider]. 305 * An in-memory implementation of [Resource].
325 * Use `/` as a path separator.
326 */ 306 */
327 class MemoryResourceProvider implements ResourceProvider { 307 abstract class _MemoryResource implements Resource {
328 final Map<String, _MemoryResource> _pathToResource = 308 final MemoryResourceProvider _provider;
329 new HashMap<String, _MemoryResource>(); 309 final String path;
330 final Map<String, String> _pathToContent = new HashMap<String, String>(); 310
331 final Map<String, int> _pathToTimestamp = new HashMap<String, int>(); 311 _MemoryResource(this._provider, this.path);
332 final Map<String, List<StreamController<WatchEvent>>> _pathToWatchers =
333 new HashMap<String, List<StreamController<WatchEvent>>>();
334 int nextStamp = 0;
335 312
336 @override 313 @override
337 Resource getResource(String path) { 314 bool get exists => _provider._pathToResource.containsKey(path);
338 path = posix.normalize(path);
339 Resource resource = _pathToResource[path];
340 if (resource == null) {
341 resource = new _MemoryFile(this, path);
342 }
343 return resource;
344 }
345
346 Folder newFolder(String path) {
347 path = posix.normalize(path);
348 if (!path.startsWith('/')) {
349 throw new ArgumentError("Path must start with '/'");
350 }
351 _MemoryResource resource = _pathToResource[path];
352 if (resource == null) {
353 String parentPath = posix.dirname(path);
354 if (parentPath != path) {
355 newFolder(parentPath);
356 }
357 _MemoryFolder folder = new _MemoryFolder(this, path);
358 _pathToResource[path] = folder;
359 _pathToTimestamp[path] = nextStamp++;
360 return folder;
361 } else if (resource is _MemoryFolder) {
362 return resource;
363 } else {
364 String message = 'Folder expected at '
365 "'$path'"
366 'but ${resource.runtimeType} found';
367 throw new ArgumentError(message);
368 }
369 }
370
371 File newFile(String path, String content) {
372 path = posix.normalize(path);
373 newFolder(posix.dirname(path));
374 _MemoryFile file = new _MemoryFile(this, path);
375 _pathToResource[path] = file;
376 _pathToContent[path] = content;
377 _pathToTimestamp[path] = nextStamp++;
378 _notifyWatchers(path, ChangeType.ADD);
379 return file;
380 }
381
382 /**
383 * Create a resource representing a dummy link (that is, a File object which
384 * appears in its parent directory, but whose `exists` property is false)
385 */
386 File newDummyLink(String path) {
387 path = posix.normalize(path);
388 newFolder(posix.dirname(path));
389 _MemoryDummyLink link = new _MemoryDummyLink(this, path);
390 _pathToResource[path] = link;
391 _pathToTimestamp[path] = nextStamp++;
392 _notifyWatchers(path, ChangeType.ADD);
393 return link;
394 }
395
396 void _notifyWatchers(String path, ChangeType changeType) {
397 _pathToWatchers.forEach((String watcherPath, List<StreamController<WatchEven t>> streamControllers) {
398 if (posix.isWithin(watcherPath, path)) {
399 for (StreamController<WatchEvent> streamController in streamControllers) {
400 streamController.add(new WatchEvent(changeType, path));
401 }
402 }
403 });
404 }
405
406 void modifyFile(String path, String content) {
407 _checkFileAtPath(path);
408 _pathToContent[path] = content;
409 _pathToTimestamp[path] = nextStamp++;
410 _notifyWatchers(path, ChangeType.MODIFY);
411 }
412
413 void _checkFileAtPath(String path) {
414 _MemoryResource resource = _pathToResource[path];
415 if (resource is! _MemoryFile) {
416 throw new ArgumentError(
417 'File expected at "$path" but ${resource.runtimeType} found');
418 }
419 }
420
421 void deleteFile(String path) {
422 _checkFileAtPath(path);
423 _pathToResource.remove(path);
424 _pathToContent.remove(path);
425 _pathToTimestamp.remove(path);
426 _notifyWatchers(path, ChangeType.REMOVE);
427 }
428
429 @override
430 Context get pathContext => posix;
431 }
432
433
434 /**
435 * A `dart:io` based implementation of [File].
436 */
437 class _PhysicalFile extends _PhysicalResource implements File {
438 _PhysicalFile(io.File file) : super(file);
439
440 @override
441 Source createSource(UriKind uriKind) {
442 io.File file = _entry as io.File;
443 JavaFile javaFile = new JavaFile(file.absolute.path);
444 return new FileBasedSource.con2(javaFile, uriKind);
445 }
446 }
447
448
449 /**
450 * A `dart:io` based implementation of [Folder].
451 */
452 class _PhysicalFolder extends _PhysicalResource implements Folder {
453 _PhysicalFolder(io.Directory directory) : super(directory);
454
455 @override
456 Resource getChild(String relPath) {
457 return PhysicalResourceProvider.INSTANCE.getResource(canonicalizePath(relPat h));
458 }
459
460 @override
461 List<Resource> getChildren() {
462 List<Resource> children = <Resource>[];
463 io.Directory directory = _entry as io.Directory;
464 List<io.FileSystemEntity> entries = directory.listSync(recursive: false);
465 int numEntries = entries.length;
466 for (int i = 0; i < numEntries; i++) {
467 io.FileSystemEntity entity = entries[i];
468 if (entity is io.Directory) {
469 children.add(new _PhysicalFolder(entity));
470 } else if (entity is io.File) {
471 children.add(new _PhysicalFile(entity));
472 }
473 }
474 return children;
475 }
476
477 @override
478 Stream<WatchEvent> get changes => new DirectoryWatcher(_entry.path).events;
479
480 @override
481 String canonicalizePath(String relPath) {
482 return normalize(join(_entry.absolute.path, relPath));
483 }
484 }
485
486
487 /**
488 * A `dart:io` based implementation of [Resource].
489 */
490 abstract class _PhysicalResource implements Resource {
491 final io.FileSystemEntity _entry;
492
493 _PhysicalResource(this._entry);
494
495 @override
496 bool get exists => _entry.existsSync();
497
498 @override
499 String get path => _entry.absolute.path;
500 315
501 @override 316 @override
502 get hashCode => path.hashCode; 317 get hashCode => path.hashCode;
503 318
504 @override 319 @override
505 bool operator==(other) { 320 Folder get parent {
321 String parentPath = posix.dirname(path);
322 if (parentPath == path) {
323 return null;
324 }
325 return _provider.getResource(parentPath);
326 }
327
328 @override
329 String get shortName => posix.basename(path);
330
331 @override
332 bool operator ==(other) {
506 if (runtimeType != other.runtimeType) { 333 if (runtimeType != other.runtimeType) {
507 return false; 334 return false;
508 } 335 }
509 return path == other.path; 336 return path == other.path;
510 } 337 }
511 338
512 @override 339 @override
513 String get shortName => basename(path);
514
515 @override
516 String toString() => path; 340 String toString() => path;
517
518 @override
519 Folder get parent {
520 String parentPath = dirname(path);
521 if (parentPath == path) {
522 return null;
523 }
524 return new _PhysicalFolder(new io.Directory(parentPath));
525 }
526 } 341 }
527
528
529 /**
530 * A `dart:io` based implementation of [ResourceProvider].
531 */
532 class PhysicalResourceProvider implements ResourceProvider {
533 static final PhysicalResourceProvider INSTANCE = new PhysicalResourceProvider. _();
534
535 PhysicalResourceProvider._();
536
537 @override
538 Resource getResource(String path) {
539 if (io.FileSystemEntity.isDirectorySync(path)) {
540 io.Directory directory = new io.Directory(path);
541 return new _PhysicalFolder(directory);
542 } else {
543 io.File file = new io.File(path);
544 return new _PhysicalFile(file);
545 }
546 }
547
548 @override
549 Context get pathContext => io.Platform.isWindows ? windows : posix;
550 }
551
552
553 /**
554 * A [UriResolver] for [Resource]s.
555 */
556 class ResourceUriResolver extends UriResolver {
557 /**
558 * The name of the `file` scheme.
559 */
560 static String _FILE_SCHEME = "file";
561
562 final ResourceProvider _provider;
563
564 ResourceUriResolver(this._provider);
565
566 @override
567 Source fromEncoding(UriKind kind, Uri uri) {
568 if (kind == UriKind.FILE_URI) {
569 Resource resource = _provider.getResource(uri.path);
570 if (resource is File) {
571 return resource.createSource(kind);
572 }
573 }
574 return null;
575 }
576
577 @override
578 Source resolveAbsolute(Uri uri) {
579 if (!_isFileUri(uri)) {
580 return null;
581 }
582 Resource resource = _provider.getResource(uri.path);
583 if (resource is File) {
584 return resource.createSource(UriKind.FILE_URI);
585 }
586 return null;
587 }
588
589 /**
590 * Return `true` if the given URI is a `file` URI.
591 *
592 * @param uri the URI being tested
593 * @return `true` if the given URI is a `file` URI
594 */
595 static bool _isFileUri(Uri uri) => uri.scheme == _FILE_SCHEME;
596 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/file_system/file_system.dart ('k') | pkg/analyzer/lib/file_system/physical_file_system.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698