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

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

Issue 298823007: add server.status notification (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: reduce variable scope 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/test/analysis_server_test.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 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/protocol.dart'; 11 import 'package:analysis_server/src/protocol.dart';
12 import 'package:analyzer/src/generated/engine.dart'; 12 import 'package:analyzer/src/generated/engine.dart';
13 import 'package:analyzer/src/generated/error.dart'; 13 import 'package:analyzer/src/generated/error.dart';
14 import 'package:analyzer/src/generated/java_core.dart'; 14 import 'package:analyzer/src/generated/java_core.dart';
15 import 'package:analyzer/src/generated/source.dart';
15 16
16 /** 17 /**
17 * Instances of the class [AnalysisServer] implement a server that listens on a 18 * Instances of the class [AnalysisServer] implement a server that listens on a
18 * [CommunicationChannel] for analysis requests and process them. 19 * [CommunicationChannel] for analysis requests and process them.
19 */ 20 */
20 class AnalysisServer { 21 class AnalysisServer {
21 /** 22 /**
22 * The name of the notification of new errors associated with a source. 23 * The name of the notification of new errors associated with a source.
23 */ 24 */
24 static const String ERROR_NOTIFICATION_NAME = 'context.errors'; 25 static const String ERROR_NOTIFICATION_NAME = 'context.errors';
(...skipping 12 matching lines...) Expand all
37 * The name of the parameter whose value is a source. 38 * The name of the parameter whose value is a source.
38 */ 39 */
39 static const String SOURCE_PARAM = 'source'; 40 static const String SOURCE_PARAM = 'source';
40 41
41 /** 42 /**
42 * The event name of the connected notification. 43 * The event name of the connected notification.
43 */ 44 */
44 static const String CONNECTED_NOTIFICATION = 'server.connected'; 45 static const String CONNECTED_NOTIFICATION = 'server.connected';
45 46
46 /** 47 /**
48 * The event name of the status notification.
49 */
50 static const String STATUS_NOTIFICATION = 'server.status';
51
52 /**
47 * The channel from which requests are received and to which responses should 53 * The channel from which requests are received and to which responses should
48 * be sent. 54 * be sent.
49 */ 55 */
50 final ServerCommunicationChannel channel; 56 final ServerCommunicationChannel channel;
51 57
52 /** 58 /**
53 * A flag indicating whether the server is running. When false, contexts 59 * A flag indicating whether the server is running. When false, contexts
54 * will no longer be added to [contextWorkQueue], and [performTask] will 60 * will no longer be added to [contextWorkQueue], and [performTask] will
55 * discard any tasks it finds on [contextWorkQueue]. 61 * discard any tasks it finds on [contextWorkQueue].
56 */ 62 */
57 bool running; 63 bool running;
58 64
59 /** 65 /**
60 * A list of the request handlers used to handle the requests sent to this 66 * A list of the request handlers used to handle the requests sent to this
61 * server. 67 * server.
62 */ 68 */
63 List<RequestHandler> handlers; 69 List<RequestHandler> handlers;
64 70
65 /** 71 /**
66 * A table mapping context id's to the analysis contexts associated with them. 72 * A table mapping context id's to the analysis contexts associated with them.
67 */ 73 */
68 final Map<String, AnalysisContext> contextMap = new Map<String, AnalysisContex t>(); 74 final Map<String, AnalysisContext> contextMap = new Map<String, AnalysisContex t>();
69 75
70 /** 76 /**
71 * A table mapping analysis contexts to the context id's associated with them. 77 * A table mapping analysis contexts to the context id's associated with them.
72 */ 78 */
73 final Map<AnalysisContext, String> contextIdMap = new Map<AnalysisContext, Str ing>(); 79 final Map<AnalysisContext, String> contextIdMap = new Map<AnalysisContext, Str ing>();
74 80
75 /** 81 /**
82 * The context identifier used in the last status notification.
83 */
84 String lastStatusNotificationContextId = null;
85
86 /**
76 * A list of the analysis contexts for which analysis work needs to be 87 * A list of the analysis contexts for which analysis work needs to be
77 * performed. 88 * performed.
78 * 89 *
79 * Invariant: when this list is non-empty, there is exactly one pending call 90 * Invariant: when this list is non-empty, there is exactly one pending call
80 * to [performTask] on the event queue. When this list is empty, there are 91 * to [performTask] on the event queue. When this list is empty, there are
81 * no calls to [performTask] on the event queue. 92 * no calls to [performTask] on the event queue.
82 */ 93 */
83 final List<AnalysisContext> contextWorkQueue = new List<AnalysisContext>(); 94 final List<AnalysisContext> contextWorkQueue = new List<AnalysisContext>();
84 95
85 /** 96 /**
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 return; 180 return;
170 } 181 }
171 // 182 //
172 // Look for a context that has work to be done and then perform one task. 183 // Look for a context that has work to be done and then perform one task.
173 // 184 //
174 List<ChangeNotice> notices = null; 185 List<ChangeNotice> notices = null;
175 String contextId; 186 String contextId;
176 try { 187 try {
177 AnalysisContext context = contextWorkQueue[0]; 188 AnalysisContext context = contextWorkQueue[0];
178 contextId = contextIdMap[context]; 189 contextId = contextIdMap[context];
179 AnalysisResult result = context.performAnalysisTask(); 190 AnalysisResult result = context.performAnalysisTask();
Paul Berry 2014/05/27 16:09:26 I think the call to sendStatusNotification(context
danrubel 2014/05/28 02:02:00 Good suggestion. Done.
180 notices = result.changeNotices; 191 notices = result.changeNotices;
181 } finally { 192 } finally {
182 if (notices == null) { 193 if (notices == null) {
183 // Either we have no more work to do for this context, or there was an 194 // Either we have no more work to do for this context, or there was an
184 // unhandled exception trying to perform the analysis. In either case, 195 // unhandled exception trying to perform the analysis. In either case,
185 // remove the context form the work queue so we won't try to do more 196 // remove the context form the work queue so we won't try to do more
186 // analysis on it. 197 // analysis on it.
187 contextWorkQueue.removeAt(0); 198 contextWorkQueue.removeAt(0);
188 } 199 }
189 // 200 //
190 // Schedule this method to be run again if there is any more work to be 201 // Schedule this method to be run again if there is any more work to be
191 // done. 202 // done.
192 // 203 //
193 if (!contextWorkQueue.isEmpty) { 204 if (!contextWorkQueue.isEmpty) {
194 _scheduleTask(); 205 _scheduleTask();
195 } 206 }
196 } 207 }
197 if (notices != null) { 208 if (notices != null) {
209 sendStatusNotification(contextId);
198 sendNotices(contextId, notices); 210 sendNotices(contextId, notices);
211 } else {
212 sendStatusNotification(null);
199 } 213 }
200 } 214 }
201 215
202 /** 216 /**
203 * Send the information in the given list of notices back to the client. 217 * Send the information in the given list of notices back to the client.
204 */ 218 */
205 void sendNotices(String contextId, List<ChangeNotice> notices) { 219 void sendNotices(String contextId, List<ChangeNotice> notices) {
206 for (int i = 0; i < notices.length; i++) { 220 for (int i = 0; i < notices.length; i++) {
207 ChangeNotice notice = notices[i]; 221 ChangeNotice notice = notices[i];
208 Notification notification = new Notification(ERROR_NOTIFICATION_NAME); 222 Notification notification = new Notification(ERROR_NOTIFICATION_NAME);
209 notification.setParameter(CONTEXT_ID_PARAM, contextId); 223 notification.setParameter(CONTEXT_ID_PARAM, contextId);
210 notification.setParameter(SOURCE_PARAM, notice.source.encoding); 224 notification.setParameter(SOURCE_PARAM, notice.source.encoding);
211 notification.setParameter(ERRORS_PARAM, notice.errors.map( 225 notification.setParameter(ERRORS_PARAM, notice.errors.map(
212 errorToJson).toList()); 226 errorToJson).toList());
213 sendNotification(notification); 227 sendNotification(notification);
214 } 228 }
215 } 229 }
216 230
231 /**
232 * Send status notification to the client. The `contextId` indicates
233 * the current context being analyzed or `null` if analysis is complete.
234 */
235 void sendStatusNotification(String contextId) {
236 if (contextId == lastStatusNotificationContextId) {
237 return;
238 }
239 lastStatusNotificationContextId = contextId;
240 Notification notification = new Notification(STATUS_NOTIFICATION);
241 Map<String, Object> analysis = new Map();
242 if (contextId != null) {
243 analysis['analyzing'] = true;
244 // TODO(danrubel): replace contextId with real analysisTarget
245 analysis['analysisTarget'] = contextId;
246 } else {
247 analysis['analyzing'] = false;
248 }
249 notification.params['analysis'] = analysis;
250 channel.sendNotification(notification);
251 }
252
217 static Map<String, Object> errorToJson(AnalysisError analysisError) { 253 static Map<String, Object> errorToJson(AnalysisError analysisError) {
218 // TODO(paulberry): move this function into the AnalysisError class. 254 // TODO(paulberry): move this function into the AnalysisError class.
219 255
220 // TODO(paulberry): we really shouldn't be exposing errorCode.ordinal 256 // TODO(paulberry): we really shouldn't be exposing errorCode.ordinal
221 // outside the analyzer, since the ordinal numbers change whenever we 257 // outside the analyzer, since the ordinal numbers change whenever we
222 // regenerate the analysis engine. 258 // regenerate the analysis engine.
223 Map<String, Object> result = { 259 Map<String, Object> result = {
224 'source': analysisError.source.encoding, 260 'source': analysisError.source.encoding,
225 'errorCode': (analysisError.errorCode as Enum).ordinal, 261 'errorCode': (analysisError.errorCode as Enum).ordinal,
226 'offset': analysisError.offset, 262 'offset': analysisError.offset,
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 /** 303 /**
268 * An enumeration of the services provided by the server domain. 304 * An enumeration of the services provided by the server domain.
269 */ 305 */
270 class ServerService extends Enum2<ServerService> { 306 class ServerService extends Enum2<ServerService> {
271 static const ServerService STATUS = const ServerService('STATUS', 0); 307 static const ServerService STATUS = const ServerService('STATUS', 0);
272 308
273 static const List<ServerService> VALUES = const [STATUS]; 309 static const List<ServerService> VALUES = const [STATUS];
274 310
275 const ServerService(String name, int ordinal) : super(name, ordinal); 311 const ServerService(String name, int ordinal) : super(name, ordinal);
276 } 312 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analysis_server/test/analysis_server_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698