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

Side by Side Diff: packages/analyzer/lib/file_system/physical_file_system.dart

Issue 2990843002: Removed fixed dependencies (Closed)
Patch Set: Created 3 years, 4 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
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 physical_file_system; 5 library analyzer.file_system.physical_file_system;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:core' hide Resource; 8 import 'dart:core';
9 import 'dart:io' as io; 9 import 'dart:io' as io;
10 10
11 import 'package:analyzer/src/generated/java_io.dart'; 11 import 'package:analyzer/file_system/file_system.dart';
12 import 'package:analyzer/src/generated/source_io.dart'; 12 import 'package:analyzer/src/generated/source_io.dart';
13 import 'package:analyzer/src/source/source_resource.dart';
14 import 'package:analyzer/src/util/absolute_path.dart';
15 import 'package:isolate/isolate_runner.dart';
13 import 'package:path/path.dart'; 16 import 'package:path/path.dart';
14 import 'package:watcher/watcher.dart'; 17 import 'package:watcher/watcher.dart';
15 18
16 import 'file_system.dart'; 19 /**
20 * Return modification times for every file path in [paths].
21 *
22 * If a path is `null`, the modification time is also `null`.
23 *
24 * If any exception happens, the file is considered as a not existing and
25 * `-1` is its modification time.
26 */
27 List<int> _pathsToTimes(List<String> paths) {
28 return paths.map((path) {
29 if (path != null) {
30 try {
31 io.File file = new io.File(path);
32 return file.lastModifiedSync().millisecondsSinceEpoch;
33 } catch (_) {
34 return -1;
35 }
36 } else {
37 return null;
38 }
39 }).toList();
40 }
17 41
18 /** 42 /**
19 * A `dart:io` based implementation of [ResourceProvider]. 43 * A `dart:io` based implementation of [ResourceProvider].
20 */ 44 */
21 class PhysicalResourceProvider implements ResourceProvider { 45 class PhysicalResourceProvider implements ResourceProvider {
22 static final NORMALIZE_EOL_ALWAYS = (String string) => 46 static final FileReadMode NORMALIZE_EOL_ALWAYS =
23 string.replaceAll(new RegExp('\r\n?'), '\n'); 47 (String string) => string.replaceAll(new RegExp('\r\n?'), '\n');
24 48
25 static final PhysicalResourceProvider INSTANCE = 49 static final PhysicalResourceProvider INSTANCE =
26 new PhysicalResourceProvider(null); 50 new PhysicalResourceProvider(null);
27 51
28 /** 52 /**
29 * The name of the directory containing plugin specific subfolders used to 53 * The name of the directory containing plugin specific subfolders used to
30 * store data across sessions. 54 * store data across sessions.
31 */ 55 */
32 static final String SERVER_DIR = ".dartServer"; 56 static final String SERVER_DIR = ".dartServer";
33 57
34 PhysicalResourceProvider(String fileReadMode(String s)) { 58 static _SingleIsolateRunnerProvider pathsToTimesIsolateProvider =
59 new _SingleIsolateRunnerProvider();
60
61 @override
62 final AbsolutePathContext absolutePathContext =
63 new AbsolutePathContext(io.Platform.isWindows);
64
65 PhysicalResourceProvider(FileReadMode fileReadMode) {
35 if (fileReadMode != null) { 66 if (fileReadMode != null) {
36 FileBasedSource.fileReadMode = fileReadMode; 67 FileBasedSource.fileReadMode = fileReadMode;
37 } 68 }
38 } 69 }
39 70
40 @override 71 @override
41 Context get pathContext => io.Platform.isWindows ? windows : posix; 72 Context get pathContext => io.Platform.isWindows ? windows : posix;
42 73
43 @override 74 @override
44 File getFile(String path) => new _PhysicalFile(new io.File(path)); 75 File getFile(String path) {
76 path = normalize(path);
77 return new _PhysicalFile(new io.File(path));
78 }
45 79
46 @override 80 @override
47 Folder getFolder(String path) => new _PhysicalFolder(new io.Directory(path)); 81 Folder getFolder(String path) {
82 path = normalize(path);
83 return new _PhysicalFolder(new io.Directory(path));
84 }
85
86 @override
87 Future<List<int>> getModificationTimes(List<Source> sources) async {
88 List<String> paths = sources.map((source) => source.fullName).toList();
89 IsolateRunner runner = await pathsToTimesIsolateProvider.get();
90 return runner.run(_pathsToTimes, paths);
91 }
48 92
49 @override 93 @override
50 Resource getResource(String path) { 94 Resource getResource(String path) {
51 if (io.FileSystemEntity.isDirectorySync(path)) { 95 if (io.FileSystemEntity.isDirectorySync(path)) {
52 return getFolder(path); 96 return getFolder(path);
53 } else { 97 } else {
54 return getFile(path); 98 return getFile(path);
55 } 99 }
56 } 100 }
57 101
(...skipping 20 matching lines...) Expand all
78 */ 122 */
79 class _PhysicalFile extends _PhysicalResource implements File { 123 class _PhysicalFile extends _PhysicalResource implements File {
80 _PhysicalFile(io.File file) : super(file); 124 _PhysicalFile(io.File file) : super(file);
81 125
82 @override 126 @override
83 Stream<WatchEvent> get changes => new FileWatcher(_entry.path).events; 127 Stream<WatchEvent> get changes => new FileWatcher(_entry.path).events;
84 128
85 @override 129 @override
86 int get modificationStamp { 130 int get modificationStamp {
87 try { 131 try {
88 io.File file = _entry as io.File; 132 return _file.lastModifiedSync().millisecondsSinceEpoch;
89 return file.lastModifiedSync().millisecondsSinceEpoch;
90 } on io.FileSystemException catch (exception) { 133 } on io.FileSystemException catch (exception) {
91 throw new FileSystemException(exception.path, exception.message); 134 throw new FileSystemException(exception.path, exception.message);
92 } 135 }
93 } 136 }
94 137
138 /**
139 * Return the underlying file being represented by this wrapper.
140 */
141 io.File get _file => _entry as io.File;
142
95 @override 143 @override
96 Source createSource([Uri uri]) { 144 Source createSource([Uri uri]) {
97 io.File file = _entry as io.File; 145 return new FileSource(this, uri ?? pathContext.toUri(path));
98 JavaFile javaFile = new JavaFile(file.absolute.path);
99 if (uri == null) {
100 uri = javaFile.toURI();
101 }
102 return new FileBasedSource(javaFile, uri);
103 } 146 }
104 147
105 @override 148 @override
106 bool isOrContains(String path) { 149 bool isOrContains(String path) {
107 return path == this.path; 150 return path == this.path;
108 } 151 }
109 152
110 @override 153 @override
111 String readAsStringSync() { 154 List<int> readAsBytesSync() {
155 _throwIfWindowsDeviceDriver();
112 try { 156 try {
113 io.File file = _entry as io.File; 157 return _file.readAsBytesSync();
114 return file.readAsStringSync();
115 } on io.FileSystemException catch (exception) { 158 } on io.FileSystemException catch (exception) {
116 throw new FileSystemException(exception.path, exception.message); 159 throw new FileSystemException(exception.path, exception.message);
117 } 160 }
161 }
162
163 @override
164 String readAsStringSync() {
165 _throwIfWindowsDeviceDriver();
166 try {
167 return FileBasedSource.fileReadMode(_file.readAsStringSync());
168 } on io.FileSystemException catch (exception) {
169 throw new FileSystemException(exception.path, exception.message);
170 }
171 }
172
173 @override
174 File renameSync(String newPath) {
175 try {
176 return new _PhysicalFile(_file.renameSync(newPath));
177 } on io.FileSystemException catch (exception) {
178 throw new FileSystemException(exception.path, exception.message);
179 }
180 }
181
182 @override
183 File resolveSymbolicLinksSync() {
184 try {
185 return new _PhysicalFile(new io.File(_file.resolveSymbolicLinksSync()));
186 } on io.FileSystemException catch (exception) {
187 throw new FileSystemException(exception.path, exception.message);
188 }
189 }
190
191 @override
192 Uri toUri() => new Uri.file(path);
193
194 @override
195 void writeAsBytesSync(List<int> bytes) {
196 try {
197 _file.writeAsBytesSync(bytes);
198 } on io.FileSystemException catch (exception) {
199 throw new FileSystemException(exception.path, exception.message);
200 }
201 }
202
203 @override
204 void writeAsStringSync(String content) {
205 try {
206 _file.writeAsStringSync(content);
207 } on io.FileSystemException catch (exception) {
208 throw new FileSystemException(exception.path, exception.message);
209 }
118 } 210 }
119 } 211 }
120 212
121 /** 213 /**
122 * A `dart:io` based implementation of [Folder]. 214 * A `dart:io` based implementation of [Folder].
123 */ 215 */
124 class _PhysicalFolder extends _PhysicalResource implements Folder { 216 class _PhysicalFolder extends _PhysicalResource implements Folder {
125 _PhysicalFolder(io.Directory directory) : super(directory); 217 _PhysicalFolder(io.Directory directory) : super(directory);
126 218
127 @override 219 @override
128 Stream<WatchEvent> get changes => new DirectoryWatcher(_entry.path).events; 220 Stream<WatchEvent> get changes => new DirectoryWatcher(_entry.path).events;
129 221
222 /**
223 * Return the underlying file being represented by this wrapper.
224 */
225 io.Directory get _directory => _entry as io.Directory;
226
130 @override 227 @override
131 String canonicalizePath(String relPath) { 228 String canonicalizePath(String relPath) {
132 return normalize(join(_entry.absolute.path, relPath)); 229 return normalize(join(path, relPath));
133 } 230 }
134 231
135 @override 232 @override
136 bool contains(String path) { 233 bool contains(String path) {
137 return isWithin(this.path, path); 234 return absolutePathContext.isWithin(this.path, path);
138 } 235 }
139 236
140 @override 237 @override
141 Resource getChild(String relPath) { 238 Resource getChild(String relPath) {
142 String canonicalPath = canonicalizePath(relPath); 239 String canonicalPath = canonicalizePath(relPath);
143 return PhysicalResourceProvider.INSTANCE.getResource(canonicalPath); 240 return PhysicalResourceProvider.INSTANCE.getResource(canonicalPath);
144 } 241 }
145 242
146 @override 243 @override
244 _PhysicalFile getChildAssumingFile(String relPath) {
245 String canonicalPath = canonicalizePath(relPath);
246 io.File file = new io.File(canonicalPath);
247 return new _PhysicalFile(file);
248 }
249
250 @override
147 _PhysicalFolder getChildAssumingFolder(String relPath) { 251 _PhysicalFolder getChildAssumingFolder(String relPath) {
148 String canonicalPath = canonicalizePath(relPath); 252 String canonicalPath = canonicalizePath(relPath);
149 io.Directory directory = new io.Directory(canonicalPath); 253 io.Directory directory = new io.Directory(canonicalPath);
150 return new _PhysicalFolder(directory); 254 return new _PhysicalFolder(directory);
151 } 255 }
152 256
153 @override 257 @override
154 List<Resource> getChildren() { 258 List<Resource> getChildren() {
155 try { 259 try {
156 List<Resource> children = <Resource>[]; 260 List<Resource> children = <Resource>[];
(...skipping 14 matching lines...) Expand all
171 } 275 }
172 } 276 }
173 277
174 @override 278 @override
175 bool isOrContains(String path) { 279 bool isOrContains(String path) {
176 if (path == this.path) { 280 if (path == this.path) {
177 return true; 281 return true;
178 } 282 }
179 return contains(path); 283 return contains(path);
180 } 284 }
285
286 @override
287 Folder resolveSymbolicLinksSync() {
288 try {
289 return new _PhysicalFolder(
290 new io.Directory(_directory.resolveSymbolicLinksSync()));
291 } on io.FileSystemException catch (exception) {
292 throw new FileSystemException(exception.path, exception.message);
293 }
294 }
295
296 @override
297 Uri toUri() => new Uri.directory(path);
181 } 298 }
182 299
183 /** 300 /**
184 * A `dart:io` based implementation of [Resource]. 301 * A `dart:io` based implementation of [Resource].
185 */ 302 */
186 abstract class _PhysicalResource implements Resource { 303 abstract class _PhysicalResource implements Resource {
187 final io.FileSystemEntity _entry; 304 final io.FileSystemEntity _entry;
188 305
189 _PhysicalResource(this._entry); 306 _PhysicalResource(this._entry);
190 307
308 AbsolutePathContext get absolutePathContext =>
309 PhysicalResourceProvider.INSTANCE.absolutePathContext;
310
191 @override 311 @override
192 bool get exists => _entry.existsSync(); 312 bool get exists => _entry.existsSync();
193 313
194 @override 314 @override
195 get hashCode => path.hashCode; 315 get hashCode => path.hashCode;
196 316
197 @override 317 @override
198 Folder get parent { 318 Folder get parent {
199 String parentPath = dirname(path); 319 String parentPath = absolutePathContext.dirname(path);
200 if (parentPath == path) { 320 if (parentPath == path) {
201 return null; 321 return null;
202 } 322 }
203 return new _PhysicalFolder(new io.Directory(parentPath)); 323 return new _PhysicalFolder(new io.Directory(parentPath));
204 } 324 }
205 325
206 @override 326 @override
207 String get path => _entry.absolute.path; 327 String get path => _entry.absolute.path;
208 328
329 /**
330 * Return the path context used by this resource provider.
331 */
332 Context get pathContext => io.Platform.isWindows ? windows : posix;
333
209 @override 334 @override
210 String get shortName => basename(path); 335 String get shortName => absolutePathContext.basename(path);
211 336
212 @override 337 @override
213 bool operator ==(other) { 338 bool operator ==(other) {
214 if (runtimeType != other.runtimeType) { 339 if (runtimeType != other.runtimeType) {
215 return false; 340 return false;
216 } 341 }
217 return path == other.path; 342 return path == other.path;
218 } 343 }
219 344
220 @override 345 @override
346 void delete() {
347 try {
348 _entry.deleteSync(recursive: true);
349 } on io.FileSystemException catch (exception) {
350 throw new FileSystemException(exception.path, exception.message);
351 }
352 }
353
354 @override
221 String toString() => path; 355 String toString() => path;
356
357 /**
358 * If the operating system is Windows and the resource references one of the
359 * device drivers, throw a [FileSystemException].
360 *
361 * https://support.microsoft.com/en-us/kb/74496
362 */
363 void _throwIfWindowsDeviceDriver() {
364 if (io.Platform.isWindows) {
365 String shortName = this.shortName.toUpperCase();
366 if (shortName == r'CON' ||
367 shortName == r'PRN' ||
368 shortName == r'AUX' ||
369 shortName == r'CLOCK$' ||
370 shortName == r'NUL' ||
371 shortName == r'COM1' ||
372 shortName == r'LPT1' ||
373 shortName == r'LPT2' ||
374 shortName == r'LPT3' ||
375 shortName == r'COM2' ||
376 shortName == r'COM3' ||
377 shortName == r'COM4') {
378 throw new FileSystemException(
379 path, 'Windows device drivers cannot be read.');
380 }
381 }
382 }
222 } 383 }
384
385 /**
386 * This class encapsulates logic for creating a single [IsolateRunner].
387 */
388 class _SingleIsolateRunnerProvider {
389 bool _isSpawning = false;
390 IsolateRunner _runner;
391
392 /**
393 * Complete with the only [IsolateRunner] instance.
394 */
395 Future<IsolateRunner> get() async {
396 if (_runner != null) {
397 return _runner;
398 }
399 if (_isSpawning) {
400 Completer<IsolateRunner> completer = new Completer<IsolateRunner>();
401 new Timer.periodic(new Duration(milliseconds: 10), (Timer timer) {
402 if (_runner != null) {
403 completer.complete(_runner);
404 timer.cancel();
405 }
406 });
407 return completer.future;
408 }
409 _isSpawning = true;
410 _runner = await IsolateRunner.spawn();
411 return _runner;
412 }
413 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698