| // Copyright (c) 2017, 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. |
| |
| /// Data structure storing an association between URI and file contents. |
| /// |
| /// Each URI is also associated with a unique arbitrary path ending in ".dart". |
| /// This allows interfacing with analyzer code that expects to manipulate paths |
| /// rather than URIs. |
| class FileRepository { |
| /// Regular expression matching the arbitrary file paths generated by |
| /// [_pathForIndex]. |
| static final _pathRegexp = new RegExp(r'^/[0-9]+\.dart$'); |
| |
| /// The URIs currently stored in the repository. |
| final _uris = <Uri>[]; |
| |
| /// Map from a URI to its index in [_uris]. |
| final _uriToIndexMap = <Uri, int>{}; |
| |
| /// The file contents associated with the URIs in [_uris]. |
| final _contents = <String>[]; |
| |
| /// Clear any contents stored in the file repository. The association between |
| /// URI and arbitrary path is preserved. |
| /// |
| /// Subsequent calls to [contentsForPath] will have undefined results until |
| /// new contents are stored using [store]. |
| void clearContents() { |
| for (var i = 0; i < _contents.length; i++) { |
| _contents[i] = null; |
| } |
| } |
| |
| /// Return the contents of the file whose arbitrary path is [path]. |
| /// |
| /// The path must have been returned by a previous call to [store] or |
| /// [pathForUri]. |
| String contentsForPath(String path) { |
| var contents = _contents[_indexForPath(path)]; |
| assert(contents != null); |
| return contents; |
| } |
| |
| /// For testing purposes, return the contents of all files stored in the file |
| /// repository, as a map from path to contents string. |
| Map<String, String> getContentsForTesting() { |
| var result = <String, String>{}; |
| for (var i = 0; i < _contents.length; i++) { |
| if (_contents[i] != null) result[_pathForIndex(i)] = _contents[i]; |
| } |
| return result; |
| } |
| |
| /// Return the arbitrary path associated with [uri]. |
| /// |
| /// If [allocate] is `false` (the default), the uri must have previously been |
| /// allocated a corresponding path, e.g. via a call to [store]. If [allocate] |
| /// is `true`, then a new path will be allocated if necessary. |
| String pathForUri(Uri uri, {bool allocate: false}) { |
| return _pathForIndex(_indexForUri(uri, allocate)); |
| } |
| |
| /// Associate the given [uri] with file [contents]. |
| /// |
| /// The arbitrary path associated with the file is returned. |
| String store(Uri uri, String contents) { |
| int index = _indexForUri(uri, true); |
| _contents[index] = contents; |
| return _pathForIndex(index); |
| } |
| |
| /// Return the URI for the file whose arbitrary path is [path]. |
| /// |
| /// The path must have been returned by a previous call to [store] or |
| /// [pathForUri]. |
| Uri uriForPath(String path) => _uris[_indexForPath(path)]; |
| |
| /// Return the index into [_uris] and [_contents] matching the arbitrary path |
| /// [path]. |
| int _indexForPath(String path) { |
| assert(_pathRegexp.hasMatch(path)); |
| return int.parse(path.substring(1, path.length - 5)); |
| } |
| |
| int _indexForUri(Uri uri, bool allocate) { |
| int index = _uriToIndexMap[uri]; |
| assert(allocate || index != null); |
| if (index == null) { |
| index = _uris.length; |
| _uris.add(uri); |
| _uriToIndexMap[uri] = index; |
| _contents.add(null); |
| } |
| return index; |
| } |
| |
| /// Return the arbitrary path associated with the given index. |
| String _pathForIndex(int index) => '/$index.dart'; |
| } |