| OLD | NEW |
| 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 analysis.server; | 5 library analysis.server; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import 'package:analysis_server/src/analysis_logger.dart'; | 9 import 'package:analysis_server/src/analysis_logger.dart'; |
| 10 import 'package:analysis_server/src/channel.dart'; | 10 import 'package:analysis_server/src/channel.dart'; |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 * no calls to [performTask] on the event queue. | 113 * no calls to [performTask] on the event queue. |
| 114 */ | 114 */ |
| 115 final List<AnalysisContext> contextWorkQueue = new List<AnalysisContext>(); | 115 final List<AnalysisContext> contextWorkQueue = new List<AnalysisContext>(); |
| 116 | 116 |
| 117 /** | 117 /** |
| 118 * A set of the [ServerService]s to send notifications for. | 118 * A set of the [ServerService]s to send notifications for. |
| 119 */ | 119 */ |
| 120 Set<ServerService> serverServices = new Set<ServerService>(); | 120 Set<ServerService> serverServices = new Set<ServerService>(); |
| 121 | 121 |
| 122 /** | 122 /** |
| 123 * A table mapping [AnalysisService]s to the file paths for which these |
| 124 * notifications should be sent. |
| 125 */ |
| 126 Map<AnalysisService, Set<String>> analysisServices = <AnalysisService, Set<Str
ing>>{}; |
| 127 |
| 128 /** |
| 123 * Initialize a newly created server to receive requests from and send | 129 * Initialize a newly created server to receive requests from and send |
| 124 * responses to the given [channel]. | 130 * responses to the given [channel]. |
| 125 */ | 131 */ |
| 126 AnalysisServer(this.channel, ResourceProvider resourceProvider) { | 132 AnalysisServer(this.channel, ResourceProvider resourceProvider) { |
| 127 contextDirectoryManager = new AnalysisServerContextDirectoryManager(this, re
sourceProvider); | 133 contextDirectoryManager = new AnalysisServerContextDirectoryManager(this, re
sourceProvider); |
| 128 AnalysisEngine.instance.logger = new AnalysisLogger(); | 134 AnalysisEngine.instance.logger = new AnalysisLogger(); |
| 129 running = true; | 135 running = true; |
| 130 Notification notification = new Notification(NOTIFICATION_CONNECTED); | 136 Notification notification = new Notification(NOTIFICATION_CONNECTED); |
| 131 channel.sendNotification(notification); | 137 channel.sendNotification(notification); |
| 132 channel.listen(handleRequest, onDone: done, onError: error); | 138 channel.listen(handleRequest, onDone: done, onError: error); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 237 } | 243 } |
| 238 | 244 |
| 239 /** | 245 /** |
| 240 * Send the information in the given list of notices back to the client. | 246 * Send the information in the given list of notices back to the client. |
| 241 */ | 247 */ |
| 242 void sendNotices(List<ChangeNotice> notices) { | 248 void sendNotices(List<ChangeNotice> notices) { |
| 243 for (int i = 0; i < notices.length; i++) { | 249 for (int i = 0; i < notices.length; i++) { |
| 244 ChangeNotice notice = notices[i]; | 250 ChangeNotice notice = notices[i]; |
| 245 Source source = notice.source; | 251 Source source = notice.source; |
| 246 CompilationUnit dartUnit = notice.compilationUnit; | 252 CompilationUnit dartUnit = notice.compilationUnit; |
| 247 // TODO(scheglov) use subscriptions to determine notifications to send | 253 // TODO(scheglov) use default subscriptions |
| 254 String file = source.fullName; |
| 255 if (dartUnit != null) { |
| 256 Set<String> files = analysisServices[AnalysisService.HIGHLIGHTS]; |
| 257 if (files != null && files.contains(file)) { |
| 258 sendAnalysisNotificationHighlights(file, dartUnit); |
| 259 } |
| 260 } |
| 248 if (!source.isInSystemLibrary) { | 261 if (!source.isInSystemLibrary) { |
| 249 // errors | 262 // errors |
| 250 { | 263 sendAnalysisNotificationErrors(file, notice.errors); |
| 251 Notification notification = new Notification(NOTIFICATION_ERRORS); | |
| 252 notification.setParameter(FILE, source.fullName); | |
| 253 notification.setParameter(ERRORS, notice.errors.map(errorToJson).toLis
t()); | |
| 254 sendNotification(notification); | |
| 255 } | |
| 256 // highlights | |
| 257 if (dartUnit != null) { | |
| 258 Notification notification = new Notification(NOTIFICATION_HIGHLIGHTS); | |
| 259 notification.setParameter(FILE, source.fullName); | |
| 260 notification.setParameter( | |
| 261 REGIONS, | |
| 262 new DartUnitHighlightsComputer(dartUnit).compute()); | |
| 263 sendNotification(notification); | |
| 264 } | |
| 265 } | 264 } |
| 266 } | 265 } |
| 267 } | 266 } |
| 268 | 267 |
| 268 void sendAnalysisNotificationErrors(String file, List<AnalysisError> errors) { |
| 269 Notification notification = new Notification(NOTIFICATION_ERRORS); |
| 270 notification.setParameter(FILE, file); |
| 271 notification.setParameter(ERRORS, errors.map(errorToJson).toList()); |
| 272 sendNotification(notification); |
| 273 } |
| 274 |
| 275 void sendAnalysisNotificationHighlights(String file, CompilationUnit dartUnit)
{ |
| 276 Notification notification = new Notification(NOTIFICATION_HIGHLIGHTS); |
| 277 notification.setParameter(FILE, file); |
| 278 notification.setParameter( |
| 279 REGIONS, |
| 280 new DartUnitHighlightsComputer(dartUnit).compute()); |
| 281 sendNotification(notification); |
| 282 } |
| 283 |
| 269 /** | 284 /** |
| 270 * Send status notification to the client. The `contextId` indicates | 285 * Send status notification to the client. The `contextId` indicates |
| 271 * the current context being analyzed or `null` if analysis is complete. | 286 * the current context being analyzed or `null` if analysis is complete. |
| 272 */ | 287 */ |
| 273 void sendStatusNotification(String contextId) { | 288 void sendStatusNotification(String contextId) { |
| 274 if (contextId == lastStatusNotificationContextId) { | 289 if (contextId == lastStatusNotificationContextId) { |
| 275 return; | 290 return; |
| 276 } | 291 } |
| 277 lastStatusNotificationContextId = contextId; | 292 lastStatusNotificationContextId = contextId; |
| 278 Notification notification = new Notification(NOTIFICATION_STATUS); | 293 Notification notification = new Notification(NOTIFICATION_STATUS); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 325 } else { | 340 } else { |
| 326 analysisContext.setChangedContents(source, change.content, | 341 analysisContext.setChangedContents(source, change.content, |
| 327 change.offset, change.oldLength, change.newLength); | 342 change.offset, change.oldLength, change.newLength); |
| 328 } | 343 } |
| 329 addContextToWorkQueue(analysisContext); | 344 addContextToWorkQueue(analysisContext); |
| 330 } | 345 } |
| 331 }); | 346 }); |
| 332 } | 347 } |
| 333 | 348 |
| 334 /** | 349 /** |
| 350 * Implementation for `analysis.setSubscriptions`. |
| 351 */ |
| 352 void setAnalysisSubscriptions(Map<AnalysisService, Set<String>> subscriptions)
{ |
| 353 // send notifications for already analyzed sources |
| 354 subscriptions.forEach((service, Set<String> newFiles) { |
| 355 Set<String> oldFiles = analysisServices[service]; |
| 356 Set<String> todoFiles = oldFiles != null ? newFiles.difference(oldFiles) :
newFiles; |
| 357 for (String file in todoFiles) { |
| 358 if (service == AnalysisService.ERRORS) { |
| 359 Source source = _getSource(file); |
| 360 AnalysisContext analysisContext = _getAnalysisContext(file); |
| 361 List<AnalysisError> errors = analysisContext.getErrors(source).errors; |
| 362 sendAnalysisNotificationErrors(file, errors); |
| 363 } |
| 364 if (service == AnalysisService.HIGHLIGHTS) { |
| 365 CompilationUnit dartUnit = test_getResolvedCompilationUnit(file); |
| 366 if (dartUnit != null) { |
| 367 sendAnalysisNotificationHighlights(file, dartUnit); |
| 368 } |
| 369 } |
| 370 } |
| 371 }); |
| 372 // remember new subscriptions |
| 373 this.analysisServices = subscriptions; |
| 374 } |
| 375 |
| 376 /** |
| 335 * Return the [AnalysisContext] that is used to analyze the given [path]. | 377 * Return the [AnalysisContext] that is used to analyze the given [path]. |
| 336 * Return `null` if there is no such context. | 378 * Return `null` if there is no such context. |
| 337 */ | 379 */ |
| 338 AnalysisContext _getAnalysisContext(String path) { | 380 AnalysisContext _getAnalysisContext(String path) { |
| 339 for (Folder folder in folderMap.keys) { | 381 for (Folder folder in folderMap.keys) { |
| 340 if (path.startsWith(folder.path)) { | 382 if (path.startsWith(folder.path)) { |
| 341 return folderMap[folder].context; | 383 return folderMap[folder].context; |
| 342 } | 384 } |
| 343 } | 385 } |
| 344 return null; | 386 return null; |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 /** | 516 /** |
| 475 * An enumeration of the services provided by the server domain. | 517 * An enumeration of the services provided by the server domain. |
| 476 */ | 518 */ |
| 477 class ServerService extends Enum2<ServerService> { | 519 class ServerService extends Enum2<ServerService> { |
| 478 static const ServerService STATUS = const ServerService('STATUS', 0); | 520 static const ServerService STATUS = const ServerService('STATUS', 0); |
| 479 | 521 |
| 480 static const List<ServerService> VALUES = const [STATUS]; | 522 static const List<ServerService> VALUES = const [STATUS]; |
| 481 | 523 |
| 482 const ServerService(String name, int ordinal) : super(name, ordinal); | 524 const ServerService(String name, int ordinal) : super(name, ordinal); |
| 483 } | 525 } |
| OLD | NEW |