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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: observatory_pub_packages/analyzer/file_system/memory_file_system.dart
===================================================================
--- observatory_pub_packages/analyzer/file_system/memory_file_system.dart (revision 0)
+++ observatory_pub_packages/analyzer/file_system/memory_file_system.dart (working copy)
@@ -0,0 +1,383 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library memory_file_system;
+
+import 'dart:async';
+import 'dart:collection';
+
+import 'package:analyzer/src/generated/engine.dart' show TimestampedData;
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:path/path.dart';
+import 'package:watcher/watcher.dart';
+
+import 'file_system.dart';
+
+
+/**
+ * Exception thrown when a memory [Resource] file operation fails.
+ */
+class MemoryResourceException {
+ final path;
+ final message;
+
+ MemoryResourceException(this.path, this.message);
+
+ @override
+ String toString() {
+ return "MemoryResourceException(path=$path; message=$message)";
+ }
+}
+
+
+/**
+ * An in-memory implementation of [ResourceProvider].
+ * Use `/` as a path separator.
+ */
+class MemoryResourceProvider implements ResourceProvider {
+ final Map<String, _MemoryResource> _pathToResource =
+ new HashMap<String, _MemoryResource>();
+ final Map<String, String> _pathToContent = new HashMap<String, String>();
+ final Map<String, int> _pathToTimestamp = new HashMap<String, int>();
+ final Map<String, List<StreamController<WatchEvent>>> _pathToWatchers =
+ new HashMap<String, List<StreamController<WatchEvent>>>();
+ int nextStamp = 0;
+
+ @override
+ Context get pathContext => posix;
+
+ void deleteFile(String path) {
+ _checkFileAtPath(path);
+ _pathToResource.remove(path);
+ _pathToContent.remove(path);
+ _pathToTimestamp.remove(path);
+ _notifyWatchers(path, ChangeType.REMOVE);
+ }
+
+ @override
+ Resource getResource(String path) {
+ path = posix.normalize(path);
+ Resource resource = _pathToResource[path];
+ if (resource == null) {
+ resource = new _MemoryFile(this, path);
+ }
+ return resource;
+ }
+
+ void modifyFile(String path, String content) {
+ _checkFileAtPath(path);
+ _pathToContent[path] = content;
+ _pathToTimestamp[path] = nextStamp++;
+ _notifyWatchers(path, ChangeType.MODIFY);
+ }
+
+ /**
+ * Create a resource representing a dummy link (that is, a File object which
+ * appears in its parent directory, but whose `exists` property is false)
+ */
+ File newDummyLink(String path) {
+ path = posix.normalize(path);
+ newFolder(posix.dirname(path));
+ _MemoryDummyLink link = new _MemoryDummyLink(this, path);
+ _pathToResource[path] = link;
+ _pathToTimestamp[path] = nextStamp++;
+ _notifyWatchers(path, ChangeType.ADD);
+ return link;
+ }
+
+ File newFile(String path, String content) {
+ path = posix.normalize(path);
+ newFolder(posix.dirname(path));
+ _MemoryFile file = new _MemoryFile(this, path);
+ _pathToResource[path] = file;
+ _pathToContent[path] = content;
+ _pathToTimestamp[path] = nextStamp++;
+ _notifyWatchers(path, ChangeType.ADD);
+ return file;
+ }
+
+ Folder newFolder(String path) {
+ path = posix.normalize(path);
+ if (!path.startsWith('/')) {
+ throw new ArgumentError("Path must start with '/'");
+ }
+ _MemoryResource resource = _pathToResource[path];
+ if (resource == null) {
+ String parentPath = posix.dirname(path);
+ if (parentPath != path) {
+ newFolder(parentPath);
+ }
+ _MemoryFolder folder = new _MemoryFolder(this, path);
+ _pathToResource[path] = folder;
+ _pathToTimestamp[path] = nextStamp++;
+ return folder;
+ } else if (resource is _MemoryFolder) {
+ return resource;
+ } else {
+ String message =
+ 'Folder expected at ' "'$path'" 'but ${resource.runtimeType} found';
+ throw new ArgumentError(message);
+ }
+ }
+
+ void _checkFileAtPath(String path) {
+ _MemoryResource resource = _pathToResource[path];
+ if (resource is! _MemoryFile) {
+ throw new ArgumentError(
+ 'File expected at "$path" but ${resource.runtimeType} found');
+ }
+ }
+
+ void _notifyWatchers(String path, ChangeType changeType) {
+ _pathToWatchers.forEach(
+ (String watcherPath, List<StreamController<WatchEvent>> streamControllers) {
+ if (posix.isWithin(watcherPath, path)) {
+ for (StreamController<WatchEvent> streamController in streamControllers)
+ {
+ streamController.add(new WatchEvent(changeType, path));
+ }
+ }
+ });
+ }
+}
+
+
+/**
+ * An in-memory implementation of [File] which acts like a symbolic link to a
+ * non-existent file.
+ */
+class _MemoryDummyLink extends _MemoryResource implements File {
+ _MemoryDummyLink(MemoryResourceProvider provider, String path) : super(
+ provider,
+ path);
+
+ @override
+ bool get exists => false;
+
+ String get _content {
+ throw new MemoryResourceException(path, "File '$path' could not be read");
+ }
+
+ int get _timestamp => _provider._pathToTimestamp[path];
+
+ @override
+ Source createSource([Uri uri]) {
+ throw new MemoryResourceException(path, "File '$path' could not be read");
+ }
+
+ @override
+ bool isOrContains(String path) {
+ return path == this.path;
+ }
+}
+
+
+/**
+ * An in-memory implementation of [File].
+ */
+class _MemoryFile extends _MemoryResource implements File {
+ _MemoryFile(MemoryResourceProvider provider, String path) : super(
+ provider,
+ path);
+
+ String get _content {
+ String content = _provider._pathToContent[path];
+ if (content == null) {
+ throw new MemoryResourceException(path, "File '$path' does not exist");
+ }
+ return content;
+ }
+
+ int get _timestamp => _provider._pathToTimestamp[path];
+
+ @override
+ Source createSource([Uri uri]) {
+ if (uri == null) {
+ uri = posix.toUri(path);
+ }
+ return new _MemoryFileSource(this, uri);
+ }
+
+ @override
+ bool isOrContains(String path) {
+ return path == this.path;
+ }
+}
+
+
+/**
+ * An in-memory implementation of [Source].
+ */
+class _MemoryFileSource implements Source {
+ final _MemoryFile _file;
+
+ final Uri uri;
+
+ _MemoryFileSource(this._file, this.uri);
+
+ @override
+ TimestampedData<String> get contents {
+ return new TimestampedData<String>(modificationStamp, _file._content);
+ }
+
+ @override
+ String get encoding {
+ return uri.toString();
+ }
+
+ @override
+ String get fullName => _file.path;
+
+ @override
+ int get hashCode => _file.hashCode;
+
+ @override
+ bool get isInSystemLibrary => uriKind == UriKind.DART_URI;
+
+ @override
+ int get modificationStamp => _file._timestamp;
+
+ @override
+ String get shortName => _file.shortName;
+
+ @override
+ UriKind get uriKind {
+ String scheme = uri.scheme;
+ if (scheme == PackageUriResolver.PACKAGE_SCHEME) {
+ return UriKind.PACKAGE_URI;
+ } else if (scheme == DartUriResolver.DART_SCHEME) {
+ return UriKind.DART_URI;
+ } else if (scheme == FileUriResolver.FILE_SCHEME) {
+ return UriKind.FILE_URI;
+ }
+ return UriKind.FILE_URI;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is _MemoryFileSource) {
+ return other._file == _file;
+ }
+ return false;
+ }
+
+ @override
+ bool exists() => _file.exists;
+
+ @override
+ Uri resolveRelativeUri(Uri relativeUri) {
+ return uri.resolveUri(relativeUri);
+ }
+
+ @override
+ String toString() => _file.toString();
+}
+
+
+/**
+ * An in-memory implementation of [Folder].
+ */
+class _MemoryFolder extends _MemoryResource implements Folder {
+ _MemoryFolder(MemoryResourceProvider provider, String path) : super(
+ provider,
+ path);
+ @override
+ Stream<WatchEvent> get changes {
+ StreamController<WatchEvent> streamController =
+ new StreamController<WatchEvent>();
+ if (!_provider._pathToWatchers.containsKey(path)) {
+ _provider._pathToWatchers[path] = <StreamController<WatchEvent>>[];
+ }
+ _provider._pathToWatchers[path].add(streamController);
+ streamController.done.then((_) {
+ _provider._pathToWatchers[path].remove(streamController);
+ if (_provider._pathToWatchers[path].isEmpty) {
+ _provider._pathToWatchers.remove(path);
+ }
+ });
+ return streamController.stream;
+ }
+
+ @override
+ String canonicalizePath(String relPath) {
+ relPath = posix.normalize(relPath);
+ String childPath = posix.join(path, relPath);
+ childPath = posix.normalize(childPath);
+ return childPath;
+ }
+
+ @override
+ bool contains(String path) {
+ return posix.isWithin(this.path, path);
+ }
+
+ @override
+ Resource getChild(String relPath) {
+ String childPath = canonicalizePath(relPath);
+ _MemoryResource resource = _provider._pathToResource[childPath];
+ if (resource == null) {
+ resource = new _MemoryFile(_provider, childPath);
+ }
+ return resource;
+ }
+
+ @override
+ List<Resource> getChildren() {
+ List<Resource> children = <Resource>[];
+ _provider._pathToResource.forEach((resourcePath, resource) {
+ if (posix.dirname(resourcePath) == path) {
+ children.add(resource);
+ }
+ });
+ return children;
+ }
+
+ @override
+ bool isOrContains(String path) {
+ if (path == this.path) {
+ return true;
+ }
+ return contains(path);
+ }
+}
+
+
+/**
+ * An in-memory implementation of [Resource].
+ */
+abstract class _MemoryResource implements Resource {
+ final MemoryResourceProvider _provider;
+ final String path;
+
+ _MemoryResource(this._provider, this.path);
+
+ @override
+ bool get exists => _provider._pathToResource.containsKey(path);
+
+ @override
+ get hashCode => path.hashCode;
+
+ @override
+ Folder get parent {
+ String parentPath = posix.dirname(path);
+ if (parentPath == path) {
+ return null;
+ }
+ return _provider.getResource(parentPath);
+ }
+
+ @override
+ String get shortName => posix.basename(path);
+
+ @override
+ bool operator ==(other) {
+ if (runtimeType != other.runtimeType) {
+ return false;
+ }
+ return path == other.path;
+ }
+
+ @override
+ String toString() => path;
+}

Powered by Google App Engine
This is Rietveld 408576698