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

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

Issue 544273003: Initial support for execution domain (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fixed formatting Created 6 years, 3 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
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 library domain.execution;
6
7 import 'package:analysis_server/src/analysis_server.dart';
8 import 'package:analysis_server/src/constants.dart';
9 import 'package:analysis_server/src/protocol.dart';
10 import 'dart:collection';
11 import 'package:analyzer/src/generated/engine.dart';
12 import 'package:analyzer/src/generated/source.dart';
13
14 /**
15 * Instances of the class [ExecutionDomainHandler] implement a [RequestHandler]
16 * that handles requests in the `execution` domain.
17 */
18 class ExecutionDomainHandler implements RequestHandler {
19 /**
20 * The analysis server that is using this handler to process requests.
21 */
22 final AnalysisServer server;
23
24 /**
25 * The next execution context identifier to be returned.
26 */
27 int nextContextId = 0;
28
29 /**
30 * A table mapping execution context id's to the root of the context.
31 */
32 Map<String, String> contextMap = new HashMap<String, String>();
33
34 /**
35 * The listener used to send notifications when
36 */
37 LaunchDataNotificationListener launchDataListener;
38
39 /**
40 * Initialize a newly created handler to handle requests for the given [server ].
41 */
42 ExecutionDomainHandler(this.server);
43
44 /**
45 * Implement the `execution.createContext` request.
46 */
47 Response createContext(Request request) {
48 String file =
49 new ExecutionCreateContextParams.fromRequest(request).contextRoot;
50 String contextId = (nextContextId++).toString();
51 contextMap[contextId] = file;
52 return new ExecutionCreateContextResult(contextId).toResponse(request.id);
53 }
54
55 /**
56 * Implement the `execution.deleteContext` request.
57 */
58 Response deleteContext(Request request) {
59 String contextId = new ExecutionDeleteContextParams.fromRequest(request).id;
60 contextMap.remove(contextId);
61 return new ExecutionDeleteContextResult().toResponse(request.id);
62 }
63
64 @override
65 Response handleRequest(Request request) {
66 try {
67 String requestName = request.method;
68 if (requestName == EXECUTION_CREATE_CONTEXT) {
69 return createContext(request);
70 } else if (requestName == EXECUTION_DELETE_CONTEXT) {
71 return deleteContext(request);
72 } else if (requestName == EXECUTION_MAP_URI) {
73 return mapUri(request);
74 } else if (requestName == EXECUTION_SET_SUBSCRIPTIONS) {
75 return setSubscriptions(request);
76 }
77 } on RequestFailure catch (exception) {
78 return exception.response;
79 }
80 return null;
81 }
82
83 /**
84 * Implement the 'execution.mapUri' request.
85 */
86 Response mapUri(Request request) {
87 ExecutionMapUriParams params =
88 new ExecutionMapUriParams.fromRequest(request);
89 String contextId = params.id;
90 String path = contextMap[contextId];
91 if (path == null) {
92 return new Response.invalidParameter(
93 request,
94 'id',
95 'There is no execution context with an id of $contextId');
96 }
97 AnalysisContext context = server.getAnalysisContext(path);
98 if (params.file != null) {
99 if (params.uri != null) {
100 return new Response.invalidParameter(
101 request,
102 'file',
103 'Either file or uri must be provided, but not both');
104 }
105 Source source = server.getSource(path);
106 // TODO(brianwilkerson) Figure out how to perform the mapping.
107 String uri = '';
108 return new ExecutionMapUriResult(uri: uri).toResponse(request.id);
109 } else if (params.uri != null) {
110 // TODO(brianwilkerson) Figure out how to perform the mapping.
111 String file = '';
112 return new ExecutionMapUriResult(file: file).toResponse(request.id);
113 }
114 return new Response.invalidParameter(
115 request,
116 'file',
117 'Either file or uri must be provided');
118 }
119
120 /**
121 * Implement the 'execution.setSubscriptions' request.
122 */
123 Response setSubscriptions(Request request) {
124 List<ExecutionService> subscriptions =
125 new ExecutionSetSubscriptionsParams.fromRequest(request).subscriptions;
126 if (subscriptions.contains(ExecutionService.LAUNCH_DATA)) {
127 if (launchDataListener == null) {
128 launchDataListener = new LaunchDataNotificationListener(server);
129 server.addAnalysisServerListener(launchDataListener);
130 if (server.isAnalysisComplete()) {
131 launchDataListener.analysisComplete();
132 }
133 }
134 } else {
135 if (launchDataListener != null) {
136 server.removeAnalysisServerListener(launchDataListener);
137 launchDataListener = null;
138 }
139 }
140 return new ExecutionSetSubscriptionsResult().toResponse(request.id);
141 }
142 }
143
144 /**
145 * Instances of the class [LaunchDataNotificationListener] listen for analysis
146 * to be complete and then notify the client of the launch data that has been
147 * computed.
148 */
149 class LaunchDataNotificationListener implements AnalysisServerListener {
150 /**
151 * The analysis server used to send notifications.
152 */
153 final AnalysisServer server;
154
155 /**
156 * Initialize a newly created listener to send notifications through the given
157 * [server] when analysis is complete.
158 */
159 LaunchDataNotificationListener(this.server);
160
161 @override
162 void analysisComplete() {
163 List<ExecutableFile> executables = [];
164 Map<String, List<String>> dartToHtml = new HashMap<String, List<String>>();
165 Map<String, List<String>> htmlToDart = new HashMap<String, List<String>>();
166 for (AnalysisContext context in server.getAnalysisContexts()) {
167 List<Source> clientSources = context.launchableClientLibrarySources;
168 List<Source> serverSources = context.launchableServerLibrarySources;
169 for (Source source in clientSources) {
170 ExecutableKind kind = ExecutableKind.CLIENT;
171 if (serverSources.remove(source)) {
172 kind = ExecutableKind.EITHER;
173 }
174 executables.add(new ExecutableFile(source.fullName, kind));
175 }
176 for (Source source in serverSources) {
177 executables.add(
178 new ExecutableFile(source.fullName, ExecutableKind.SERVER));
179 }
180
181 for (Source librarySource in context.librarySources) {
182 List<Source> files = context.getHtmlFilesReferencing(librarySource);
183 if (files.isNotEmpty) {
184 // TODO(brianwilkerson) Handle the case where the same library is
185 // being analyzed in multiple contexts.
186 dartToHtml[librarySource.fullName] = getFullNames(files);
187 }
188 }
189
190 for (Source htmlSource in context.htmlSources) {
191 List<Source> libraries =
192 context.getLibrariesReferencedFromHtml(htmlSource);
193 if (libraries.isNotEmpty) {
194 // TODO(brianwilkerson) Handle the case where the same HTML file is
195 // being analyzed in multiple contexts.
196 htmlToDart[htmlSource.fullName] = getFullNames(libraries);
197 }
198 }
199 }
200 server.sendNotification(
201 new ExecutionLaunchDataParams(
202 executables,
203 dartToHtml,
204 htmlToDart).toNotification());
205 }
206
207 List<String> getFullNames(List<Source> sources) {
208 return sources.map((Source source) => source.fullName).toList();
209 }
210 }
OLDNEW
« no previous file with comments | « pkg/analysis_server/lib/src/constants.dart ('k') | pkg/analysis_server/lib/src/generated_protocol.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698