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

Unified Diff: pkg/analysis_server/lib/src/analysis_server.dart

Issue 137703010: Add server and request handlers (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 11 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 side-by-side diff with in-line comments
Download patch
Index: pkg/analysis_server/lib/src/analysis_server.dart
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
new file mode 100644
index 0000000000000000000000000000000000000000..7fd84f4f019d64a765b37e10b6b646ccf7f0b38f
--- /dev/null
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -0,0 +1,178 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analysis.server;
+
+import 'dart:async';
+
+import 'package:analyzer/src/generated/engine.dart';
+
+import 'analysis_logger.dart';
+import 'channel.dart';
+import 'protocol.dart';
+
+/**
+ * Instances of the class [AnalysisServer] implement a server that listens on a
+ * [CommunicationChannel] for analysis requests and process them.
+ */
+class AnalysisServer {
+ /**
+ * The name of the notification of new errors associated with a source.
+ */
+ static const String ERROR_NOTIFICATION_NAME = 'context.errors';
+
+ /**
+ * The name of the parameter whose value is a list of errors.
+ */
+ static const String ERRORS_PARAM = 'errors';
+
+ /**
+ * The name of the parameter whose value is a source.
+ */
+ static const String SOURCE_PARAM = 'source';
+
+ /**
+ * The channel from which requests are received and to which responses should
+ * be sent.
+ */
+ CommunicationChannel channel;
+
+ /**
+ * A flag indicating whether the server is running.
+ */
+ bool running;
+
+ /**
+ * A list of the request handlers used to handle the requests sent to this
+ * server.
+ */
+ List<RequestHandler> handlers;
+
+ /**
+ * A table mapping context id's to the analysis contexts associated with them.
+ */
+ final Map<String, AnalysisContext> contextMap = new Map<String, AnalysisContext>();
+
+ /**
+ * A list of the analysis contexts for which analysis work needs to be
+ * performed.
+ */
+ final List<AnalysisContext> contextWorkQueue = new List<AnalysisContext>();
+
+ /**
+ * Initialize a newly created server to receive requests from and send
+ * responses to the given [channel].
+ */
+ AnalysisServer(CommunicationChannel channel) {
+ AnalysisEngine.instance.logger = new AnalysisLogger();
+ running = true;
+ this.channel = channel;
+ this.channel.listen(handleRequest, onError: error, onDone: done);
+ }
+
+ /**
+ * Add the given [context] to the list of analysis contexts for which analysis
+ * work needs to be performed. Ensure that the work will be performed.
+ */
+ void addContextToWorkQueue(AnalysisContext context) {
+ if (!contextWorkQueue.contains(context)) {
+ contextWorkQueue.add(context);
+ run();
+ }
+ }
+
+ /**
+ * The socket from which requests are being read has been closed.
+ */
+ void done() {
+ running = false;
+ }
+
+ /**
+ * There was an error related to the socket from which requests are being
+ * read.
+ */
+ void error() {
+ running = false;
+ }
+
+ /**
+ * Handle a [request] that was read from the communication channel.
+ */
+ void handleRequest(Request request) {
+ int count = handlers.length;
+ for (int i = 0; i < count; i++) {
+ Response response = handlers[i].handleRequest(request);
+ if (response != null) {
+ channel.sendResponse(response);
+ return;
+ }
+ }
+ channel.sendResponse(new Response.unknownRequest(request));
+ }
+
+ /**
+ * Perform the next available task. If a request was received that has not yet
+ * been performed, perform it next. Otherwise, look for some analysis that
+ * needs to be done and do that. Otherwise, do nothing.
+ */
+ void performTask() {
+ //
+ // Look for a context that has work to be done and then perform one task.
+ //
+ if (!contextWorkQueue.isEmpty) {
+ AnalysisContext context = contextWorkQueue[0];
+ AnalysisResult result = context.performAnalysisTask();
+ List<ChangeNotice> notices = result.changeNotices;
+ if (notices == null) {
+ contextWorkQueue.removeAt(0);
+ } else { //if (context.analysisOptions.provideErrors) {
+ sendNotices(notices);
+ }
+ }
+ //
+ // Schedule this method to be run again if there is any more work to be done.
+ //
+ if (contextWorkQueue.isEmpty) {
+ running = false;
+ } else {
+ Timer.run(() {
+ performTask();
+ });
+ }
+ }
+
+ /**
+ * Send the information in the given list of notices back to the client.
+ */
+ void sendNotices(List<ChangeNotice> notices) {
+ for (int i = 0; i < notices.length; i++) {
+ ChangeNotice notice = notices[i];
+ Notification notification = new Notification(ERROR_NOTIFICATION_NAME);
+ notification.setParameter(SOURCE_PARAM, notice.source.encoding);
+ notification.setParameter(ERRORS_PARAM, notice.errors);
+ sendNotification(notification);
+ }
+ }
+
+ /**
+ * Perform the tasks that are waiting for execution until the server is shut
+ * down.
+ */
+ void run() {
+ if (!running) {
+ running = true;
+ Timer.run(() {
+ performTask();
+ });
+ }
+ }
+
+ /**
+ * Send the given [notification] to the client.
+ */
+ void sendNotification(Notification notification) {
+ channel.sendNotification(notification);
+ }
+}
« no previous file with comments | « no previous file | pkg/analysis_server/lib/src/domain_context.dart » ('j') | pkg/analysis_server/lib/src/domain_context.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698