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

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

Issue 311653002: Extract analysis/notifications into a separate operation/file. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Tweak for the test method name. 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 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';
11 import 'package:analysis_server/src/constants.dart'; 11 import 'package:analysis_server/src/constants.dart';
12 import 'package:analysis_server/src/context_directory_manager.dart'; 12 import 'package:analysis_server/src/context_directory_manager.dart';
13 import 'package:analysis_server/src/domain_analysis.dart'; 13 import 'package:analysis_server/src/domain_analysis.dart';
14 import 'package:analysis_server/src/operation/operation_analysis.dart';
14 import 'package:analysis_server/src/operation/operation.dart'; 15 import 'package:analysis_server/src/operation/operation.dart';
15 import 'package:analysis_server/src/operation/operation_queue.dart'; 16 import 'package:analysis_server/src/operation/operation_queue.dart';
16 import 'package:analysis_server/src/protocol.dart'; 17 import 'package:analysis_server/src/protocol.dart';
17 import 'package:analysis_server/src/resource.dart'; 18 import 'package:analysis_server/src/resource.dart';
18 import 'package:analyzer/src/generated/ast.dart'; 19 import 'package:analyzer/src/generated/ast.dart';
19 import 'package:analyzer/src/generated/engine.dart'; 20 import 'package:analyzer/src/generated/engine.dart';
20 import 'package:analyzer/src/generated/error.dart'; 21 import 'package:analyzer/src/generated/error.dart';
21 import 'package:analyzer/src/generated/java_core.dart';
22 import 'package:analyzer/src/generated/source.dart'; 22 import 'package:analyzer/src/generated/source.dart';
23 import 'package:analyzer/src/generated/sdk.dart'; 23 import 'package:analyzer/src/generated/sdk.dart';
24 import 'package:analyzer/src/generated/sdk_io.dart'; 24 import 'package:analyzer/src/generated/sdk_io.dart';
25 import 'package:analyzer/src/generated/source_io.dart'; 25 import 'package:analyzer/src/generated/source_io.dart';
26 import 'package:analysis_server/src/computers.dart'; 26 import 'package:analysis_server/src/computers.dart';
27 27
28 28
29 /** 29 /**
30 * An instance of [DirectoryBasedDartSdk] that is shared between 30 * An instance of [DirectoryBasedDartSdk] that is shared between
31 * [AnalysisServer] instances to improve performance. 31 * [AnalysisServer] instances to improve performance.
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 */ 129 */
130 void schedulePerformAnalysisOperation(AnalysisContext context) { 130 void schedulePerformAnalysisOperation(AnalysisContext context) {
131 scheduleOperation(new PerformAnalysisOperation(context, false)); 131 scheduleOperation(new PerformAnalysisOperation(context, false));
132 } 132 }
133 133
134 /** 134 /**
135 * Schedules execution of the given [ServerOperation]. 135 * Schedules execution of the given [ServerOperation].
136 */ 136 */
137 void scheduleOperation(ServerOperation operation) { 137 void scheduleOperation(ServerOperation operation) {
138 bool wasEmpty = operationQueue.isEmpty; 138 bool wasEmpty = operationQueue.isEmpty;
139 operationQueue.add(operation); 139 addOperation(operation);
140 if (wasEmpty) { 140 if (wasEmpty) {
141 _schedulePerformOperation(); 141 _schedulePerformOperation();
142 } 142 }
143 } 143 }
144 144
145 /** 145 /**
146 * Adds the given [ServerOperation] to the queue, but does not schedule
147 * operations execution.
148 */
149 void addOperation(ServerOperation operation) {
150 operationQueue.add(operation);
151 }
152
153 /**
146 * The socket from which requests are being read has been closed. 154 * The socket from which requests are being read has been closed.
147 */ 155 */
148 void done() { 156 void done() {
149 running = false; 157 running = false;
150 } 158 }
151 159
152 /** 160 /**
153 * There was an error related to the socket from which requests are being 161 * There was an error related to the socket from which requests are being
154 * read. 162 * read.
155 */ 163 */
(...skipping 15 matching lines...) Expand all
171 } 179 }
172 } on RequestFailure catch (exception) { 180 } on RequestFailure catch (exception) {
173 channel.sendResponse(exception.response); 181 channel.sendResponse(exception.response);
174 return; 182 return;
175 } 183 }
176 } 184 }
177 channel.sendResponse(new Response.unknownRequest(request)); 185 channel.sendResponse(new Response.unknownRequest(request));
178 } 186 }
179 187
180 /** 188 /**
189 * Returns `true` if there is a subscription for the given [server] and [file] .
190 */
191 bool hasAnalysisSubscription(AnalysisService service, String file) {
192 Set<String> files = analysisServices[service];
193 return files != null && files.contains(file);
194 }
195
196 /**
181 * Returns `true` if the given [AnalysisContext] is a priority one. 197 * Returns `true` if the given [AnalysisContext] is a priority one.
182 */ 198 */
183 bool isPriorityContext(AnalysisContext context) { 199 bool isPriorityContext(AnalysisContext context) {
184 // TODO(scheglov) implement support for priority sources/contexts 200 // TODO(scheglov) implement support for priority sources/contexts
185 return false; 201 return false;
186 } 202 }
187 203
188 /** 204 /**
189 * Perform the next available [ServerOperation]. 205 * Perform the next available [ServerOperation].
190 */ 206 */
(...skipping 15 matching lines...) Expand all
206 } finally { 222 } finally {
207 if (!operationQueue.isEmpty) { 223 if (!operationQueue.isEmpty) {
208 _schedulePerformOperation(); 224 _schedulePerformOperation();
209 } else { 225 } else {
210 sendStatusNotification(null); 226 sendStatusNotification(null);
211 } 227 }
212 } 228 }
213 } 229 }
214 230
215 /** 231 /**
216 * Perform analysis in the given [AnalysisContext].
217 */
218 void internalPerformAnalysis(AnalysisContext context) {
219 //
220 // TODO(brianwilkerson) Add an optional function-valued parameter to
221 // performAnalysisTask that will be called when the task has been computed
222 // but before it is performed and send notification in the function:
223 //
224 // AnalysisResult result = context.performAnalysisTask((taskDescription) {
225 // sendStatusNotification(context.toString(), taskDescription);
226 // });
227 // prepare results
228 AnalysisResult result = context.performAnalysisTask();
229 List<ChangeNotice> notices = result.changeNotices;
230 if (notices == null) {
231 return;
232 }
233 // TODO(scheglov) remember known sources
234 // TODO(scheglov) index units
235 // TODO(scheglov) schedule notifications
236 sendNotices(notices);
237 // continue analysis
238 operationQueue.add(new PerformAnalysisOperation(context, true));
239 }
240
241 /**
242 * Send the information in the given list of notices back to the client.
243 */
244 void sendNotices(List<ChangeNotice> notices) {
245 for (int i = 0; i < notices.length; i++) {
246 ChangeNotice notice = notices[i];
247 Source source = notice.source;
248 CompilationUnit dartUnit = notice.compilationUnit;
249 // TODO(scheglov) use default subscriptions
250 String file = source.fullName;
251 if (dartUnit != null) {
252 Set<String> files = analysisServices[AnalysisService.HIGHLIGHTS];
253 if (files != null && files.contains(file)) {
254 sendAnalysisNotificationHighlights(file, dartUnit);
255 }
256 }
257 if (!source.isInSystemLibrary) {
258 // errors
259 sendAnalysisNotificationErrors(file, notice.errors);
260 }
261 }
262 }
263
264 void sendAnalysisNotificationErrors(String file, List<AnalysisError> errors) {
265 Notification notification = new Notification(NOTIFICATION_ERRORS);
266 notification.setParameter(FILE, file);
267 notification.setParameter(ERRORS, errors.map(errorToJson).toList());
268 sendNotification(notification);
269 }
270
271 void sendAnalysisNotificationHighlights(String file, CompilationUnit dartUnit) {
272 Notification notification = new Notification(NOTIFICATION_HIGHLIGHTS);
273 notification.setParameter(FILE, file);
274 notification.setParameter(
275 REGIONS,
276 new DartUnitHighlightsComputer(dartUnit).compute());
277 sendNotification(notification);
278 }
279
280 /**
281 * Send status notification to the client. The `contextId` indicates 232 * Send status notification to the client. The `contextId` indicates
282 * the current context being analyzed or `null` if analysis is complete. 233 * the current context being analyzed or `null` if analysis is complete.
283 */ 234 */
284 void sendStatusNotification(String contextId) { 235 void sendStatusNotification(String contextId) {
285 // if (contextId == lastStatusNotificationContextId) { 236 // if (contextId == lastStatusNotificationContextId) {
286 // return; 237 // return;
287 // } 238 // }
288 // lastStatusNotificationContextId = contextId; 239 // lastStatusNotificationContextId = contextId;
289 Notification notification = new Notification(NOTIFICATION_STATUS); 240 Notification notification = new Notification(NOTIFICATION_STATUS);
290 Map<String, Object> analysis = new Map(); 241 Map<String, Object> analysis = new Map();
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 void setAnalysisSubscriptions(Map<AnalysisService, Set<String>> subscriptions) { 299 void setAnalysisSubscriptions(Map<AnalysisService, Set<String>> subscriptions) {
349 // send notifications for already analyzed sources 300 // send notifications for already analyzed sources
350 subscriptions.forEach((service, Set<String> newFiles) { 301 subscriptions.forEach((service, Set<String> newFiles) {
351 Set<String> oldFiles = analysisServices[service]; 302 Set<String> oldFiles = analysisServices[service];
352 Set<String> todoFiles = oldFiles != null ? newFiles.difference(oldFiles) : newFiles; 303 Set<String> todoFiles = oldFiles != null ? newFiles.difference(oldFiles) : newFiles;
353 for (String file in todoFiles) { 304 for (String file in todoFiles) {
354 if (service == AnalysisService.ERRORS) { 305 if (service == AnalysisService.ERRORS) {
355 Source source = _getSource(file); 306 Source source = _getSource(file);
356 AnalysisContext analysisContext = _getAnalysisContext(file); 307 AnalysisContext analysisContext = _getAnalysisContext(file);
357 List<AnalysisError> errors = analysisContext.getErrors(source).errors; 308 List<AnalysisError> errors = analysisContext.getErrors(source).errors;
358 sendAnalysisNotificationErrors(file, errors); 309 sendAnalysisNotificationErrors(this, file, errors);
359 } 310 }
360 if (service == AnalysisService.HIGHLIGHTS) { 311 if (service == AnalysisService.HIGHLIGHTS) {
361 CompilationUnit dartUnit = test_getResolvedCompilationUnit(file); 312 CompilationUnit dartUnit = test_getResolvedCompilationUnit(file);
362 if (dartUnit != null) { 313 if (dartUnit != null) {
363 sendAnalysisNotificationHighlights(file, dartUnit); 314 sendAnalysisNotificationHighlights(this, file, dartUnit);
364 } 315 }
365 } 316 }
366 } 317 }
367 }); 318 });
368 // remember new subscriptions 319 // remember new subscriptions
369 this.analysisServices = subscriptions; 320 this.analysisServices = subscriptions;
370 } 321 }
371 322
372 /** 323 /**
373 * Return the [AnalysisContext] that is used to analyze the given [path]. 324 * Return the [AnalysisContext] that is used to analyze the given [path].
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 return context.getResolvedCompilationUnit2(unitSource, librarySources[0]); 361 return context.getResolvedCompilationUnit2(unitSource, librarySources[0]);
411 } 362 }
412 363
413 /** 364 /**
414 * Return `true` if all operations have been performed in this [AnalysisServer ]. 365 * Return `true` if all operations have been performed in this [AnalysisServer ].
415 */ 366 */
416 bool test_areOperationsFinished() { 367 bool test_areOperationsFinished() {
417 return operationQueue.isEmpty; 368 return operationQueue.isEmpty;
418 } 369 }
419 370
420 static Map<String, Object> errorToJson(AnalysisError analysisError) {
421 // TODO(paulberry): move this function into the AnalysisError class.
422 ErrorCode errorCode = analysisError.errorCode;
423 Map<String, Object> result = {
424 'file': analysisError.source.fullName,
425 // TODO(scheglov) add Enum.fullName ?
426 'errorCode': '${errorCode.runtimeType}.${(errorCode as Enum).name}',
427 'offset': analysisError.offset,
428 'length': analysisError.length,
429 'message': analysisError.message
430 };
431 if (analysisError.correction != null) {
432 result['correction'] = analysisError.correction;
433 }
434 return result;
435 }
436
437 /** 371 /**
438 * Send the given [notification] to the client. 372 * Send the given [notification] to the client.
439 */ 373 */
440 void sendNotification(Notification notification) { 374 void sendNotification(Notification notification) {
441 channel.sendNotification(notification); 375 channel.sendNotification(notification);
442 } 376 }
443 377
444 /** 378 /**
445 * Schedules [performOperation] exection. 379 * Schedules [performOperation] exection.
446 */ 380 */
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 /** 449 /**
516 * An enumeration of the services provided by the server domain. 450 * An enumeration of the services provided by the server domain.
517 */ 451 */
518 class ServerService extends Enum2<ServerService> { 452 class ServerService extends Enum2<ServerService> {
519 static const ServerService STATUS = const ServerService('STATUS', 0); 453 static const ServerService STATUS = const ServerService('STATUS', 0);
520 454
521 static const List<ServerService> VALUES = const [STATUS]; 455 static const List<ServerService> VALUES = const [STATUS];
522 456
523 const ServerService(String name, int ordinal) : super(name, ordinal); 457 const ServerService(String name, int ordinal) : super(name, ordinal);
524 } 458 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698