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

Side by Side Diff: pkg/analysis_server/lib/src/context_directory_manager.dart

Issue 308713002: Handle file additions/removals in ContextDirectoryManager. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address Konstantin's comments Created 6 years, 6 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 context.directory.manager; 5 library context.directory.manager;
6 6
7 import 'dart:async';
8
7 import 'package:analysis_server/src/resource.dart'; 9 import 'package:analysis_server/src/resource.dart';
8 import 'package:analyzer/src/generated/engine.dart'; 10 import 'package:analyzer/src/generated/engine.dart';
9 import 'package:analyzer/src/generated/source.dart'; 11 import 'package:analyzer/src/generated/source.dart';
12 import 'package:watcher/watcher.dart';
13
14 /**
15 * Information tracked by the [ContextDirectoryManager] for each context.
16 */
17 class _ContextDirectoryInfo {
18 /**
19 * Stream subscription we are using to watch the context's directory for
20 * changes.
21 */
22 StreamSubscription<WatchEvent> changeSubscription;
23
24 /**
25 * Map from full path to the [Source] object, for each source that has been
26 * added to the context.
27 */
28 Map<String, Source> sources = <String, Source>{};
29 }
10 30
11 /** 31 /**
12 * Class that maintains a mapping from included/excluded paths to a set of 32 * Class that maintains a mapping from included/excluded paths to a set of
13 * folders that should correspond to analysis contexts. 33 * folders that should correspond to analysis contexts.
14 */ 34 */
15 abstract class ContextDirectoryManager { 35 abstract class ContextDirectoryManager {
16 /** 36 /**
17 * The set of included folders in the most recent successful call to 37 * [_ContextDirectoryInfo] object for each included directory in the most
18 * [setRoots]. 38 * recent successful call to [setRoots].
19 */ 39 */
20 Set<Folder> currentFolders = new Set<Folder>(); 40 Map<Folder, _ContextDirectoryInfo> _currentDirectoryInfo =
41 <Folder, _ContextDirectoryInfo>{};
21 42
22 /** 43 /**
23 * The [ResourceProvider] using which paths are converted into [Resource]s. 44 * The [ResourceProvider] using which paths are converted into [Resource]s.
24 */ 45 */
25 final ResourceProvider resourceProvider; 46 final ResourceProvider resourceProvider;
26 47
27 ContextDirectoryManager(this.resourceProvider); 48 ContextDirectoryManager(this.resourceProvider);
28 49
29 /** 50 /**
30 * Change the set of paths which should be used as starting points to 51 * Change the set of paths which should be used as starting points to
(...skipping 16 matching lines...) Expand all
47 } 68 }
48 } 69 }
49 // excluded 70 // excluded
50 // TODO(scheglov) remove when implemented 71 // TODO(scheglov) remove when implemented
51 if (excludedPaths.isNotEmpty) { 72 if (excludedPaths.isNotEmpty) {
52 throw new UnimplementedError( 73 throw new UnimplementedError(
53 'Excluded paths are not supported yet'); 74 'Excluded paths are not supported yet');
54 } 75 }
55 Set<Folder> excludedFolders = new Set<Folder>(); 76 Set<Folder> excludedFolders = new Set<Folder>();
56 // diff 77 // diff
78 Set<Folder> currentFolders = _currentDirectoryInfo.keys.toSet();
57 Set<Folder> newFolders = includedFolders.difference(currentFolders); 79 Set<Folder> newFolders = includedFolders.difference(currentFolders);
58 Set<Folder> oldFolders = currentFolders.difference(includedFolders); 80 Set<Folder> oldFolders = currentFolders.difference(includedFolders);
59 // remove old contexts 81 // remove old contexts
60 for (Folder folder in oldFolders) { 82 for (Folder folder in oldFolders) {
61 // TODO(scheglov) implement 83 // TODO(scheglov) implement
62 } 84 }
63 // add new contexts 85 // add new contexts
64 for (Folder folder in newFolders) { 86 for (Folder folder in newFolders) {
87 _ContextDirectoryInfo info = new _ContextDirectoryInfo();
88 _currentDirectoryInfo[folder] = info;
89 info.changeSubscription = folder.changes.listen((WatchEvent event) {
90 _handleWatchEvent(folder, info, event);
91 });
65 File pubspecFile = folder.getChild('pubspec.yaml'); 92 File pubspecFile = folder.getChild('pubspec.yaml');
66 addContext(folder, pubspecFile.exists ? pubspecFile : null); 93 addContext(folder, pubspecFile.exists ? pubspecFile : null);
67 ChangeSet changeSet = new ChangeSet(); 94 ChangeSet changeSet = new ChangeSet();
68 _addSourceFiles(changeSet, folder); 95 _addSourceFiles(changeSet, folder, info);
69 applyChangesToContext(folder, changeSet); 96 applyChangesToContext(folder, changeSet);
70 } 97 }
71 currentFolders = new Set<Folder>.from(includedFolders); 98 }
99
100 void _handleWatchEvent(Folder folder, _ContextDirectoryInfo info, WatchEvent e vent) {
101 switch (event.type) {
102 case ChangeType.ADD:
103 // TODO(paulberry): handle adding pubspec.yaml
104 if (_shouldFileBeAnalyzed(event.path)) {
105 ChangeSet changeSet = new ChangeSet();
106 Resource resource = resourceProvider.getResource(event.path);
107 // If the file went away and was replaced by a folder before we
108 // had a chance to process the event, resource might be a Folder. In
109 // that case don't add it.
110 if (resource is File) {
111 File file = resource;
112 Source source = file.createSource(UriKind.FILE_URI);
113 changeSet.addedSource(source);
114 applyChangesToContext(folder, changeSet);
115 info.sources[event.path]= source;
116 }
117 }
118 break;
119 case ChangeType.REMOVE:
120 // TODO(paulberry): handle removing pubspec.yaml
121 Source source = info.sources[event.path];
122 if (source != null) {
123 ChangeSet changeSet = new ChangeSet();
124 changeSet.removedSource(source);
125 applyChangesToContext(folder, changeSet);
126 info.sources.remove(event.path);
127 }
128 break;
129 case ChangeType.MODIFY:
130 // TODO(paulberry): handle modification events
131 break;
132 }
72 } 133 }
73 134
74 /** 135 /**
75 * Resursively adds all Dart and HTML files to the [changeSet]. 136 * Resursively adds all Dart and HTML files to the [changeSet].
76 */ 137 */
77 static void _addSourceFiles(ChangeSet changeSet, Folder folder) { 138 static void _addSourceFiles(ChangeSet changeSet, Folder folder, _ContextDirect oryInfo info) {
78 List<Resource> children = folder.getChildren(); 139 List<Resource> children = folder.getChildren();
79 for (Resource child in children) { 140 for (Resource child in children) {
80 if (child is File) { 141 if (child is File) {
81 String fileName = child.shortName; 142 if (_shouldFileBeAnalyzed(child.path)) {
82 if (AnalysisEngine.isDartFileName(fileName)
83 || AnalysisEngine.isHtmlFileName(fileName)) {
84 Source source = child.createSource(UriKind.FILE_URI); 143 Source source = child.createSource(UriKind.FILE_URI);
85 changeSet.addedSource(source); 144 changeSet.addedSource(source);
145 info.sources[child.path] = source;
86 } 146 }
87 } else if (child is Folder) { 147 } else if (child is Folder) {
88 _addSourceFiles(changeSet, child); 148 _addSourceFiles(changeSet, child, info);
89 } 149 }
90 } 150 }
91 } 151 }
92 152
153 static bool _shouldFileBeAnalyzed(String shortName) {
scheglov 2014/05/29 18:19:03 shortName -> path
154 return AnalysisEngine.isDartFileName(shortName)
155 || AnalysisEngine.isHtmlFileName(shortName);
156 }
157
93 /** 158 /**
94 * Called when a new context needs to be created. If the context is 159 * Called when a new context needs to be created. If the context is
95 * associated with a pubspec file, that file is passed in [pubspecFile]; 160 * associated with a pubspec file, that file is passed in [pubspecFile];
96 * otherwise it is null. 161 * otherwise it is null.
97 */ 162 */
98 void addContext(Folder folder, File pubspecFile); 163 void addContext(Folder folder, File pubspecFile);
99 164
100 /** 165 /**
101 * Called when the set of files associated with a context have changed (or 166 * Called when the set of files associated with a context have changed (or
102 * some of those files have been modified). [changeSet] is the set of 167 * some of those files have been modified). [changeSet] is the set of
103 * changes that need to be applied to the context. 168 * changes that need to be applied to the context.
104 */ 169 */
105 void applyChangesToContext(Folder contextFolder, ChangeSet changeSet); 170 void applyChangesToContext(Folder contextFolder, ChangeSet changeSet);
106 } 171 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698