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

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: 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';
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>{};
danrubel 2014/05/29 18:14:43 Do you need the extra type declaration here since
Paul Berry 2014/05/29 18:30:23 Heh, I was just talking about this yesterday with
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 String shortName = resourceProvider.pathContext.basename(event.path);
scheglov 2014/05/29 17:37:03 Should we hide using "path" package and just add s
Paul Berry 2014/05/29 17:57:21 That's not a bad idea--it would decrease our risk
105 if (_shouldFileBeAnalyzed(shortName)) {
106 ChangeSet changeSet = new ChangeSet();
107 Resource resource = resourceProvider.getResource(event.path);
108 // Only add the file if it didn't go away before we had a chance
109 // to process the event.
110 if (resource is File) {
scheglov 2014/05/29 17:37:03 AFAIK getResource() will always return a File, it
Paul Berry 2014/05/29 17:57:21 Ok, my comment is wrong, but I believe this if-tes
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 String fileName = child.shortName;
82 if (AnalysisEngine.isDartFileName(fileName) 143 if (_shouldFileBeAnalyzed(fileName)) {
83 || AnalysisEngine.isHtmlFileName(fileName)) {
84 Source source = child.createSource(UriKind.FILE_URI); 144 Source source = child.createSource(UriKind.FILE_URI);
85 changeSet.addedSource(source); 145 changeSet.addedSource(source);
146 // TODO(paulberry): this assumes child.fullName is synonymous with
147 // path. Can we rely on that? If so, maybe we should rename
148 // child.fullName to child.path.
scheglov 2014/05/29 17:37:03 SGTM
149 info.sources[child.fullName] = source;
86 } 150 }
87 } else if (child is Folder) { 151 } else if (child is Folder) {
88 _addSourceFiles(changeSet, child); 152 _addSourceFiles(changeSet, child, info);
89 } 153 }
90 } 154 }
91 } 155 }
92 156
157 static bool _shouldFileBeAnalyzed(String shortName) {
scheglov 2014/05/29 17:37:03 I don't think isDartFileName() cares if it is give
Paul Berry 2014/05/29 17:57:21 You're right. I'll rework this to remove the call
158 return AnalysisEngine.isDartFileName(shortName)
159 || AnalysisEngine.isHtmlFileName(shortName);
160 }
161
93 /** 162 /**
94 * Called when a new context needs to be created. If the context is 163 * 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]; 164 * associated with a pubspec file, that file is passed in [pubspecFile];
96 * otherwise it is null. 165 * otherwise it is null.
97 */ 166 */
98 void addContext(Folder folder, File pubspecFile); 167 void addContext(Folder folder, File pubspecFile);
99 168
100 /** 169 /**
101 * Called when the set of files associated with a context have changed (or 170 * 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 171 * some of those files have been modified). [changeSet] is the set of
103 * changes that need to be applied to the context. 172 * changes that need to be applied to the context.
104 */ 173 */
105 void applyChangesToContext(Folder contextFolder, ChangeSet changeSet); 174 void applyChangesToContext(Folder contextFolder, ChangeSet changeSet);
106 } 175 }
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