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

Side by Side Diff: observatory_pub_packages/analyzer/file_system/memory_file_system.dart

Issue 816693004: Add observatory_pub_packages snapshot to third_party (Closed) Base URL: http://dart.googlecode.com/svn/third_party/
Patch Set: Created 6 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 | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 library memory_file_system;
6
7 import 'dart:async';
8 import 'dart:collection';
9
10 import 'package:analyzer/src/generated/engine.dart' show TimestampedData;
11 import 'package:analyzer/src/generated/source_io.dart';
12 import 'package:path/path.dart';
13 import 'package:watcher/watcher.dart';
14
15 import 'file_system.dart';
16
17
18 /**
19 * Exception thrown when a memory [Resource] file operation fails.
20 */
21 class MemoryResourceException {
22 final path;
23 final message;
24
25 MemoryResourceException(this.path, this.message);
26
27 @override
28 String toString() {
29 return "MemoryResourceException(path=$path; message=$message)";
30 }
31 }
32
33
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 =
119 'Folder expected at ' "'$path'" 'but ${resource.runtimeType} found';
120 throw new ArgumentError(message);
121 }
122 }
123
124 void _checkFileAtPath(String path) {
125 _MemoryResource resource = _pathToResource[path];
126 if (resource is! _MemoryFile) {
127 throw new ArgumentError(
128 'File expected at "$path" but ${resource.runtimeType} found');
129 }
130 }
131
132 void _notifyWatchers(String path, ChangeType changeType) {
133 _pathToWatchers.forEach(
134 (String watcherPath, List<StreamController<WatchEvent>> streamController s) {
135 if (posix.isWithin(watcherPath, path)) {
136 for (StreamController<WatchEvent> streamController in streamControllers)
137 {
138 streamController.add(new WatchEvent(changeType, path));
139 }
140 }
141 });
142 }
143 }
144
145
146 /**
147 * An in-memory implementation of [File] which acts like a symbolic link to a
148 * non-existent file.
149 */
150 class _MemoryDummyLink extends _MemoryResource implements File {
151 _MemoryDummyLink(MemoryResourceProvider provider, String path) : super(
152 provider,
153 path);
154
155 @override
156 bool get exists => false;
157
158 String get _content {
159 throw new MemoryResourceException(path, "File '$path' could not be read");
160 }
161
162 int get _timestamp => _provider._pathToTimestamp[path];
163
164 @override
165 Source createSource([Uri uri]) {
166 throw new MemoryResourceException(path, "File '$path' could not be read");
167 }
168
169 @override
170 bool isOrContains(String path) {
171 return path == this.path;
172 }
173 }
174
175
176 /**
177 * An in-memory implementation of [File].
178 */
179 class _MemoryFile extends _MemoryResource implements File {
180 _MemoryFile(MemoryResourceProvider provider, String path) : super(
181 provider,
182 path);
183
184 String get _content {
185 String content = _provider._pathToContent[path];
186 if (content == null) {
187 throw new MemoryResourceException(path, "File '$path' does not exist");
188 }
189 return content;
190 }
191
192 int get _timestamp => _provider._pathToTimestamp[path];
193
194 @override
195 Source createSource([Uri uri]) {
196 if (uri == null) {
197 uri = posix.toUri(path);
198 }
199 return new _MemoryFileSource(this, uri);
200 }
201
202 @override
203 bool isOrContains(String path) {
204 return path == this.path;
205 }
206 }
207
208
209 /**
210 * An in-memory implementation of [Source].
211 */
212 class _MemoryFileSource implements Source {
213 final _MemoryFile _file;
214
215 final Uri uri;
216
217 _MemoryFileSource(this._file, this.uri);
218
219 @override
220 TimestampedData<String> get contents {
221 return new TimestampedData<String>(modificationStamp, _file._content);
222 }
223
224 @override
225 String get encoding {
226 return uri.toString();
227 }
228
229 @override
230 String get fullName => _file.path;
231
232 @override
233 int get hashCode => _file.hashCode;
234
235 @override
236 bool get isInSystemLibrary => uriKind == UriKind.DART_URI;
237
238 @override
239 int get modificationStamp => _file._timestamp;
240
241 @override
242 String get shortName => _file.shortName;
243
244 @override
245 UriKind get uriKind {
246 String scheme = uri.scheme;
247 if (scheme == PackageUriResolver.PACKAGE_SCHEME) {
248 return UriKind.PACKAGE_URI;
249 } else if (scheme == DartUriResolver.DART_SCHEME) {
250 return UriKind.DART_URI;
251 } else if (scheme == FileUriResolver.FILE_SCHEME) {
252 return UriKind.FILE_URI;
253 }
254 return UriKind.FILE_URI;
255 }
256
257 @override
258 bool operator ==(other) {
259 if (other is _MemoryFileSource) {
260 return other._file == _file;
261 }
262 return false;
263 }
264
265 @override
266 bool exists() => _file.exists;
267
268 @override
269 Uri resolveRelativeUri(Uri relativeUri) {
270 return uri.resolveUri(relativeUri);
271 }
272
273 @override
274 String toString() => _file.toString();
275 }
276
277
278 /**
279 * An in-memory implementation of [Folder].
280 */
281 class _MemoryFolder extends _MemoryResource implements Folder {
282 _MemoryFolder(MemoryResourceProvider provider, String path) : super(
283 provider,
284 path);
285 @override
286 Stream<WatchEvent> get changes {
287 StreamController<WatchEvent> streamController =
288 new StreamController<WatchEvent>();
289 if (!_provider._pathToWatchers.containsKey(path)) {
290 _provider._pathToWatchers[path] = <StreamController<WatchEvent>>[];
291 }
292 _provider._pathToWatchers[path].add(streamController);
293 streamController.done.then((_) {
294 _provider._pathToWatchers[path].remove(streamController);
295 if (_provider._pathToWatchers[path].isEmpty) {
296 _provider._pathToWatchers.remove(path);
297 }
298 });
299 return streamController.stream;
300 }
301
302 @override
303 String canonicalizePath(String relPath) {
304 relPath = posix.normalize(relPath);
305 String childPath = posix.join(path, relPath);
306 childPath = posix.normalize(childPath);
307 return childPath;
308 }
309
310 @override
311 bool contains(String path) {
312 return posix.isWithin(this.path, path);
313 }
314
315 @override
316 Resource getChild(String relPath) {
317 String childPath = canonicalizePath(relPath);
318 _MemoryResource resource = _provider._pathToResource[childPath];
319 if (resource == null) {
320 resource = new _MemoryFile(_provider, childPath);
321 }
322 return resource;
323 }
324
325 @override
326 List<Resource> getChildren() {
327 List<Resource> children = <Resource>[];
328 _provider._pathToResource.forEach((resourcePath, resource) {
329 if (posix.dirname(resourcePath) == path) {
330 children.add(resource);
331 }
332 });
333 return children;
334 }
335
336 @override
337 bool isOrContains(String path) {
338 if (path == this.path) {
339 return true;
340 }
341 return contains(path);
342 }
343 }
344
345
346 /**
347 * An in-memory implementation of [Resource].
348 */
349 abstract class _MemoryResource implements Resource {
350 final MemoryResourceProvider _provider;
351 final String path;
352
353 _MemoryResource(this._provider, this.path);
354
355 @override
356 bool get exists => _provider._pathToResource.containsKey(path);
357
358 @override
359 get hashCode => path.hashCode;
360
361 @override
362 Folder get parent {
363 String parentPath = posix.dirname(path);
364 if (parentPath == path) {
365 return null;
366 }
367 return _provider.getResource(parentPath);
368 }
369
370 @override
371 String get shortName => posix.basename(path);
372
373 @override
374 bool operator ==(other) {
375 if (runtimeType != other.runtimeType) {
376 return false;
377 }
378 return path == other.path;
379 }
380
381 @override
382 String toString() => path;
383 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698