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

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

Issue 340773005: Add support for adding/removing pubspec.yaml files. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: 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
« no previous file with comments | « no previous file | pkg/analysis_server/lib/src/resource.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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'; 7 import 'dart:async';
8 import 'dart:collection'; 8 import 'dart:collection';
9 9
10 import 'package:analysis_server/src/resource.dart'; 10 import 'package:analysis_server/src/resource.dart';
11 import 'package:analyzer/src/generated/engine.dart'; 11 import 'package:analyzer/src/generated/engine.dart';
12 import 'package:analyzer/src/generated/source.dart'; 12 import 'package:analyzer/src/generated/source.dart';
13 import 'package:watcher/watcher.dart'; 13 import 'package:watcher/watcher.dart';
14 14
15 /** 15 /**
16 * Information tracked by the [ContextDirectoryManager] for each context. 16 * Information tracked by the [ContextDirectoryManager] for each context.
17 */ 17 */
18 class _ContextDirectoryInfo { 18 class _ContextDirectoryInfo {
19 /** 19 /**
20 * Stream subscription we are using to watch the context's directory for 20 * Stream subscription we are using to watch the context's directory for
21 * changes. 21 * changes.
22 */ 22 */
23 StreamSubscription<WatchEvent> changeSubscription; 23 StreamSubscription<WatchEvent> changeSubscription;
24 24
25 /** 25 /**
26 * Map from full path to the [Source] object, for each source that has been 26 * Map from full path to the [Source] object, for each source that has been
27 * added to the context. 27 * added to the context.
28 */ 28 */
29 Map<String, Source> sources = new HashMap<String, Source>(); 29 Map<String, Source> sources = new HashMap<String, Source>();
30
31 /**
32 * Pubspec file for this context, if there is one. Otherwise null.
33 */
34 File pubspecFile = null;
scheglov 2014/06/18 18:32:04 Do we need "= null"?
Paul Berry 2014/06/19 14:55:15 Technically, it's redundant, since uninitialized v
35
36 /**
37 * Path to that the pubspec file for this context would have, if it has one.
38 * Otherwise path that the pubspec file would have.
39 */
40 String pubspecPath;
30 } 41 }
31 42
32 /** 43 /**
33 * Class that maintains a mapping from included/excluded paths to a set of 44 * Class that maintains a mapping from included/excluded paths to a set of
34 * folders that should correspond to analysis contexts. 45 * folders that should correspond to analysis contexts.
35 */ 46 */
36 abstract class ContextDirectoryManager { 47 abstract class ContextDirectoryManager {
37 /** 48 /**
49 * File name of pubspec files.
50 */
51 static String PUBSPEC_NAME = 'pubspec.yaml';
scheglov 2014/06/18 18:32:04 static const?
Paul Berry 2014/06/19 14:55:15 Done.
52
53 /**
38 * [_ContextDirectoryInfo] object for each included directory in the most 54 * [_ContextDirectoryInfo] object for each included directory in the most
39 * recent successful call to [setRoots]. 55 * recent successful call to [setRoots].
40 */ 56 */
41 Map<Folder, _ContextDirectoryInfo> _currentDirectoryInfo = 57 Map<Folder, _ContextDirectoryInfo> _currentDirectoryInfo =
42 new HashMap<Folder, _ContextDirectoryInfo>(); 58 new HashMap<Folder, _ContextDirectoryInfo>();
43 59
44 /** 60 /**
45 * The [ResourceProvider] using which paths are converted into [Resource]s. 61 * The [ResourceProvider] using which paths are converted into [Resource]s.
46 */ 62 */
47 final ResourceProvider resourceProvider; 63 final ResourceProvider resourceProvider;
(...skipping 24 matching lines...) Expand all
72 // TODO(scheglov) remove when implemented 88 // TODO(scheglov) remove when implemented
73 if (excludedPaths.isNotEmpty) { 89 if (excludedPaths.isNotEmpty) {
74 throw new UnimplementedError( 90 throw new UnimplementedError(
75 'Excluded paths are not supported yet'); 91 'Excluded paths are not supported yet');
76 } 92 }
77 Set<Folder> excludedFolders = new HashSet<Folder>(); 93 Set<Folder> excludedFolders = new HashSet<Folder>();
78 // diff 94 // diff
79 Set<Folder> currentFolders = _currentDirectoryInfo.keys.toSet(); 95 Set<Folder> currentFolders = _currentDirectoryInfo.keys.toSet();
80 Set<Folder> newFolders = includedFolders.difference(currentFolders); 96 Set<Folder> newFolders = includedFolders.difference(currentFolders);
81 Set<Folder> oldFolders = currentFolders.difference(includedFolders); 97 Set<Folder> oldFolders = currentFolders.difference(includedFolders);
82 // remove old contexts 98 // remove old contexts
scheglov 2014/06/18 18:32:04 "destroy old contexts" ?
Paul Berry 2014/06/19 14:55:15 Done.
83 for (Folder folder in oldFolders) { 99 for (Folder folder in oldFolders) {
84 _currentDirectoryInfo.remove(folder); 100 _destroyContext(folder);
85 removeContext(folder);
86 } 101 }
87 // add new contexts 102 // add new contexts
scheglov 2014/06/18 18:32:04 "create new contexts"?
Paul Berry 2014/06/19 14:55:15 Done.
88 for (Folder folder in newFolders) { 103 for (Folder folder in newFolders) {
89 _ContextDirectoryInfo info = new _ContextDirectoryInfo(); 104 _createContext(folder);
90 _currentDirectoryInfo[folder] = info;
91 info.changeSubscription = folder.changes.listen((WatchEvent event) {
92 _handleWatchEvent(folder, info, event);
93 });
94 File pubspecFile = folder.getChild('pubspec.yaml');
95 addContext(folder, pubspecFile.exists ? pubspecFile : null);
96 ChangeSet changeSet = new ChangeSet();
97 _addSourceFiles(changeSet, folder, info);
98 applyChangesToContext(folder, changeSet);
99 } 105 }
100 } 106 }
101 107
108 /**
109 * Create a new context associated with the given folder.
110 */
111 void _createContext(Folder folder) {
112 _ContextDirectoryInfo info = new _ContextDirectoryInfo();
113 _currentDirectoryInfo[folder] = info;
114 info.changeSubscription = folder.changes.listen((WatchEvent event) {
115 _handleWatchEvent(folder, info, event);
116 });
117 File pubspecFile = folder.getChild(PUBSPEC_NAME);
118 info.pubspecPath = pubspecFile.path;
119 if (pubspecFile.exists) {
120 info.pubspecFile = pubspecFile;
121 }
122 addContext(folder, info.pubspecFile);
123 ChangeSet changeSet = new ChangeSet();
124 _addSourceFiles(changeSet, folder, info);
125 applyChangesToContext(folder, changeSet);
126 }
127
128 /**
129 * Clean up and destroy the context associated with the given folder.
130 */
131 void _destroyContext(Folder folder) {
132 _currentDirectoryInfo[folder].changeSubscription.cancel();
133 _currentDirectoryInfo.remove(folder);
134 removeContext(folder);
135 }
136
102 void _handleWatchEvent(Folder folder, _ContextDirectoryInfo info, WatchEvent e vent) { 137 void _handleWatchEvent(Folder folder, _ContextDirectoryInfo info, WatchEvent e vent) {
103 switch (event.type) { 138 switch (event.type) {
104 case ChangeType.ADD: 139 case ChangeType.ADD:
105 if (_isInPackagesDir(event.path, folder)) { 140 if (_isInPackagesDir(event.path, folder)) {
106 // TODO(paulberry): perhaps we should only skip packages dirs if 141 // TODO(paulberry): perhaps we should only skip packages dirs if
107 // there is a pubspec.yaml? 142 // there is a pubspec.yaml?
108 break; 143 break;
109 } 144 }
110 // TODO(paulberry): handle adding pubspec.yaml 145 if (info.pubspecFile == null && event.path == info.pubspecPath) {
146 // Pubspec file added. This is likely to be such a rare event that
147 // there's no need to try to be clever. Just destroy the old context
148 // and create a new one.
149 _destroyContext(folder);
150 _createContext(folder);
151 return;
152 }
111 if (_shouldFileBeAnalyzed(event.path)) { 153 if (_shouldFileBeAnalyzed(event.path)) {
112 ChangeSet changeSet = new ChangeSet(); 154 ChangeSet changeSet = new ChangeSet();
113 Resource resource = resourceProvider.getResource(event.path); 155 Resource resource = resourceProvider.getResource(event.path);
114 // If the file went away and was replaced by a folder before we 156 // If the file went away and was replaced by a folder before we
115 // had a chance to process the event, resource might be a Folder. In 157 // had a chance to process the event, resource might be a Folder. In
116 // that case don't add it. 158 // that case don't add it.
117 if (resource is File) { 159 if (resource is File) {
118 File file = resource; 160 File file = resource;
119 Source source = file.createSource(UriKind.FILE_URI); 161 Source source = file.createSource(UriKind.FILE_URI);
120 changeSet.addedSource(source); 162 changeSet.addedSource(source);
121 applyChangesToContext(folder, changeSet); 163 applyChangesToContext(folder, changeSet);
122 info.sources[event.path]= source; 164 info.sources[event.path]= source;
123 } 165 }
124 } 166 }
125 break; 167 break;
126 case ChangeType.REMOVE: 168 case ChangeType.REMOVE:
169 if (info.pubspecFile != null && event.path == info.pubspecPath) {
170 // Pubspec file removed. This is likely to be such a rare event that
171 // there's no need to try to be clever. Just destroy the old context
172 // and create a new one.
173 _destroyContext(folder);
174 _createContext(folder);
175 return;
176 }
127 // TODO(paulberry): handle removing pubspec.yaml 177 // TODO(paulberry): handle removing pubspec.yaml
128 Source source = info.sources[event.path]; 178 Source source = info.sources[event.path];
129 if (source != null) { 179 if (source != null) {
130 ChangeSet changeSet = new ChangeSet(); 180 ChangeSet changeSet = new ChangeSet();
131 changeSet.removedSource(source); 181 changeSet.removedSource(source);
132 applyChangesToContext(folder, changeSet); 182 applyChangesToContext(folder, changeSet);
133 info.sources.remove(event.path); 183 info.sources.remove(event.path);
134 } 184 }
135 break; 185 break;
136 case ChangeType.MODIFY: 186 case ChangeType.MODIFY:
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 * some of those files have been modified). [changeSet] is the set of 249 * some of those files have been modified). [changeSet] is the set of
200 * changes that need to be applied to the context. 250 * changes that need to be applied to the context.
201 */ 251 */
202 void applyChangesToContext(Folder contextFolder, ChangeSet changeSet); 252 void applyChangesToContext(Folder contextFolder, ChangeSet changeSet);
203 253
204 /** 254 /**
205 * Remove the context associated with the given [folder]. 255 * Remove the context associated with the given [folder].
206 */ 256 */
207 void removeContext(Folder folder); 257 void removeContext(Folder folder);
208 } 258 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analysis_server/lib/src/resource.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698