Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 import 'package:analyzer/file_system/file_system.dart'; | 5 import 'package:analyzer/file_system/file_system.dart'; |
| 6 import 'package:analyzer/src/dart/analysis/byte_store.dart'; | 6 import 'package:analyzer/src/dart/analysis/byte_store.dart'; |
| 7 import 'package:analyzer/src/dart/analysis/driver.dart' | 7 import 'package:analyzer/src/dart/analysis/driver.dart' |
| 8 show AnalysisDriverGeneric, AnalysisDriverScheduler, PerformanceLog; | 8 show AnalysisDriverGeneric, AnalysisDriverScheduler, PerformanceLog; |
| 9 import 'package:analyzer/src/dart/analysis/file_byte_store.dart'; | 9 import 'package:analyzer/src/dart/analysis/file_byte_store.dart'; |
| 10 import 'package:analyzer/src/dart/analysis/file_state.dart'; | 10 import 'package:analyzer/src/dart/analysis/file_state.dart'; |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 171 /** | 171 /** |
| 172 * Create an analysis driver that can analyze the files within the given | 172 * Create an analysis driver that can analyze the files within the given |
| 173 * [contextRoot]. | 173 * [contextRoot]. |
| 174 */ | 174 */ |
| 175 AnalysisDriverGeneric createAnalysisDriver(ContextRoot contextRoot); | 175 AnalysisDriverGeneric createAnalysisDriver(ContextRoot contextRoot); |
| 176 | 176 |
| 177 /** | 177 /** |
| 178 * Handle an 'analysis.handleWatchEvents' request. | 178 * Handle an 'analysis.handleWatchEvents' request. |
| 179 */ | 179 */ |
| 180 AnalysisHandleWatchEventsResult handleAnalysisHandleWatchEvents( | 180 AnalysisHandleWatchEventsResult handleAnalysisHandleWatchEvents( |
| 181 AnalysisHandleWatchEventsParams parameters) => | 181 AnalysisHandleWatchEventsParams parameters) { |
| 182 null; | 182 for (WatchEvent event in parameters.events) { |
| 183 switch (event.type) { | |
| 184 case WatchEventType.ADD: | |
| 185 // TODO(brianwilkerson) Handle the event. | |
| 186 break; | |
| 187 case WatchEventType.MODIFY: | |
| 188 contentChanged(event.path); | |
| 189 break; | |
| 190 case WatchEventType.REMOVE: | |
| 191 // TODO(brianwilkerson) Handle the event. | |
| 192 break; | |
| 193 default: | |
| 194 // Ignore unhandled watch event types. | |
| 195 break; | |
| 196 } | |
| 197 } | |
| 198 return new AnalysisHandleWatchEventsResult(); | |
| 199 } | |
| 183 | 200 |
| 184 /** | 201 /** |
| 185 * Handle an 'analysis.reanalyze' request. | 202 * Handle an 'analysis.reanalyze' request. |
| 186 */ | 203 */ |
| 187 AnalysisReanalyzeResult handleAnalysisReanalyze( | 204 AnalysisReanalyzeResult handleAnalysisReanalyze( |
| 188 AnalysisReanalyzeParams parameters) => | 205 AnalysisReanalyzeParams parameters) { |
| 189 null; | 206 var rootPaths = parameters.roots; |
| 207 if (rootPaths == null) { | |
| 208 // | |
| 209 // Reanalyze everything. | |
| 210 // | |
| 211 List<ContextRoot> roots = driverMap.keys.toList(); | |
| 212 for (ContextRoot contextRoot in roots) { | |
|
scheglov
2017/05/08 16:45:43
Do we want to handle this as "reanalyze contexts"
Brian Wilkerson
2017/05/08 17:01:10
Interesting question. My intuition is that (a) cha
| |
| 213 AnalysisDriverGeneric driver = driverMap[contextRoot]; | |
| 214 driver.dispose(); | |
| 215 driver = createAnalysisDriver(contextRoot); | |
| 216 driverMap[contextRoot] = driver; | |
| 217 } | |
| 218 return new AnalysisReanalyzeResult(); | |
| 219 } else { | |
| 220 // | |
| 221 // Reanalyze a specific set of files. | |
| 222 // | |
| 223 // TODO(brianwilkerson) There is no API for telling a driver that we need | |
| 224 // to have some files reanalyzed. | |
| 225 // for (String rootPath in rootPaths) { | |
| 226 // ContextRoot contextRoot = contextRootContaining(rootPath); | |
| 227 // AnalysisDriverGeneric driver = driverMap[contextRoot]; | |
| 228 // driver.reanalyze(rootPath); | |
| 229 // } | |
| 230 return null; | |
| 231 } | |
| 232 } | |
| 190 | 233 |
| 191 /** | 234 /** |
| 192 * Handle an 'analysis.setContextBuilderOptions' request. | 235 * Handle an 'analysis.setContextBuilderOptions' request. |
| 193 */ | 236 */ |
| 194 AnalysisSetContextBuilderOptionsResult handleAnalysisSetContextBuilderOptions( | 237 AnalysisSetContextBuilderOptionsResult handleAnalysisSetContextBuilderOptions( |
| 195 AnalysisSetContextBuilderOptionsParams parameters) => | 238 AnalysisSetContextBuilderOptionsParams parameters) => |
| 196 null; | 239 null; |
| 197 | 240 |
| 198 /** | 241 /** |
| 199 * Handle an 'analysis.setContextRoots' request. | 242 * Handle an 'analysis.setContextRoots' request. |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 243 } | 286 } |
| 244 | 287 |
| 245 /** | 288 /** |
| 246 * Handle an 'analysis.setSubscriptions' request. Most subclasses should not | 289 * Handle an 'analysis.setSubscriptions' request. Most subclasses should not |
| 247 * override this method, but should instead use the [subscriptionManager] to | 290 * override this method, but should instead use the [subscriptionManager] to |
| 248 * access the list of subscriptions for any given file. | 291 * access the list of subscriptions for any given file. |
| 249 */ | 292 */ |
| 250 AnalysisSetSubscriptionsResult handleAnalysisSetSubscriptions( | 293 AnalysisSetSubscriptionsResult handleAnalysisSetSubscriptions( |
| 251 AnalysisSetSubscriptionsParams parameters) { | 294 AnalysisSetSubscriptionsParams parameters) { |
| 252 Map<AnalysisService, List<String>> subscriptions = parameters.subscriptions; | 295 Map<AnalysisService, List<String>> subscriptions = parameters.subscriptions; |
| 253 subscriptionManager.setSubscriptions(subscriptions); | 296 Map<String, List<AnalysisService>> newSubscriptions = |
| 254 // TODO(brianwilkerson) Cause any newly subscribed for notifications to be s ent. | 297 subscriptionManager.setSubscriptions(subscriptions); |
| 298 sendNotificationsForSubscriptions(newSubscriptions); | |
| 255 return new AnalysisSetSubscriptionsResult(); | 299 return new AnalysisSetSubscriptionsResult(); |
| 256 } | 300 } |
| 257 | 301 |
| 258 /** | 302 /** |
| 259 * Handle an 'analysis.updateContent' request. Most subclasses should not | 303 * Handle an 'analysis.updateContent' request. Most subclasses should not |
| 260 * override this method, but should instead use the [contentCache] to access | 304 * override this method, but should instead use the [contentCache] to access |
| 261 * the current content of overlaid files. | 305 * the current content of overlaid files. |
| 262 */ | 306 */ |
| 263 AnalysisUpdateContentResult handleAnalysisUpdateContent( | 307 AnalysisUpdateContentResult handleAnalysisUpdateContent( |
| 264 AnalysisUpdateContentParams parameters) { | 308 AnalysisUpdateContentParams parameters) { |
| 265 Map<String, Object> files = parameters.files; | 309 Map<String, Object> files = parameters.files; |
| 266 files.forEach((String filePath, Object overlay) { | 310 files.forEach((String filePath, Object overlay) { |
| 267 // We don't need to get the correct URI because only the full path is | 311 // We don't need to get the correct URI because only the full path is |
| 268 // used by the contentCache. | 312 // used by the contentCache. |
| 269 Source source = resourceProvider.getFile(filePath).createSource(); | 313 Source source = resourceProvider.getFile(filePath).createSource(); |
| 270 if (overlay is AddContentOverlay) { | 314 if (overlay is AddContentOverlay) { |
| 271 fileContentOverlay[source.fullName] = overlay.content; | 315 fileContentOverlay[source.fullName] = overlay.content; |
| 272 } else if (overlay is ChangeContentOverlay) { | 316 } else if (overlay is ChangeContentOverlay) { |
| 273 String fileName = source.fullName; | 317 String fileName = source.fullName; |
| 274 String oldContents = fileContentOverlay[fileName]; | 318 String oldContents = fileContentOverlay[fileName]; |
| 275 String newContents; | 319 String newContents; |
| 276 if (oldContents == null) { | 320 if (oldContents == null) { |
| 277 // The server should only send a ChangeContentOverlay if there is | 321 // The server should only send a ChangeContentOverlay if there is |
| 278 // already an existing overlay for the source. | 322 // already an existing overlay for the source. |
| 279 throw new RequestFailure(new RequestError( | 323 throw new RequestFailure( |
| 280 RequestErrorCode.INVALID_OVERLAY_CHANGE, | 324 RequestErrorFactory.invalidOverlayChangeNoContent()); |
| 281 'Invalid overlay change: no content to change')); | |
| 282 } | 325 } |
| 283 try { | 326 try { |
| 284 newContents = SourceEdit.applySequence(oldContents, overlay.edits); | 327 newContents = SourceEdit.applySequence(oldContents, overlay.edits); |
| 285 } on RangeError { | 328 } on RangeError { |
| 286 throw new RequestFailure(new RequestError( | 329 throw new RequestFailure( |
| 287 RequestErrorCode.INVALID_OVERLAY_CHANGE, | 330 RequestErrorFactory.invalidOverlayChangeInvalidEdit()); |
| 288 'Invalid overlay change: invalid edit')); | |
| 289 } | 331 } |
| 290 fileContentOverlay[fileName] = newContents; | 332 fileContentOverlay[fileName] = newContents; |
| 291 } else if (overlay is RemoveContentOverlay) { | 333 } else if (overlay is RemoveContentOverlay) { |
| 292 fileContentOverlay[source.fullName] = null; | 334 fileContentOverlay[source.fullName] = null; |
| 293 } | 335 } |
| 294 contentChanged(filePath); | 336 contentChanged(filePath); |
| 295 }); | 337 }); |
| 296 return new AnalysisUpdateContentResult(); | 338 return new AnalysisUpdateContentResult(); |
| 297 } | 339 } |
| 298 | 340 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 370 */ | 412 */ |
| 371 void onDone() {} | 413 void onDone() {} |
| 372 | 414 |
| 373 /** | 415 /** |
| 374 * The method that is called when an error has occurred in the analysis | 416 * The method that is called when an error has occurred in the analysis |
| 375 * server. This method will not be invoked under normal conditions. | 417 * server. This method will not be invoked under normal conditions. |
| 376 */ | 418 */ |
| 377 void onError(Object exception, StackTrace stackTrace) {} | 419 void onError(Object exception, StackTrace stackTrace) {} |
| 378 | 420 |
| 379 /** | 421 /** |
| 422 * Send notifications corresponding to the given description of subscriptions. | |
| 423 * The map is keyed by the path of each file for which notifications should be | |
| 424 * send and has values representing the list of services associated with the | |
| 425 * notifications to send. | |
| 426 */ | |
| 427 void sendNotificationsForSubscriptions( | |
| 428 Map<String, List<AnalysisService>> subscriptions); | |
| 429 | |
| 430 /** | |
| 380 * Start this plugin by listening to the given communication [channel]. | 431 * Start this plugin by listening to the given communication [channel]. |
| 381 */ | 432 */ |
| 382 void start(PluginCommunicationChannel channel) { | 433 void start(PluginCommunicationChannel channel) { |
| 383 _channel = channel; | 434 _channel = channel; |
| 384 _channel.listen(_onRequest, onError: onError, onDone: onDone); | 435 _channel.listen(_onRequest, onError: onError, onDone: onDone); |
| 385 } | 436 } |
| 386 | 437 |
| 387 /** | 438 /** |
| 388 * Compute the response that should be returned for the given [request], or | 439 * Compute the response that should be returned for the given [request], or |
| 389 * `null` if the response has already been sent. | 440 * `null` if the response has already been sent. |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 474 response = new Response(id, | 525 response = new Response(id, |
| 475 error: new RequestError( | 526 error: new RequestError( |
| 476 RequestErrorCode.PLUGIN_ERROR, exception.toString(), | 527 RequestErrorCode.PLUGIN_ERROR, exception.toString(), |
| 477 stackTrace: stackTrace.toString())); | 528 stackTrace: stackTrace.toString())); |
| 478 } | 529 } |
| 479 if (response != null) { | 530 if (response != null) { |
| 480 _channel.sendResponse(response); | 531 _channel.sendResponse(response); |
| 481 } | 532 } |
| 482 } | 533 } |
| 483 } | 534 } |
| OLD | NEW |