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

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

Issue 759083003: Allow the contents of the analysis cache to be inspected via html debugging. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years 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/analyzer/lib/src/generated/engine.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 get.handler; 5 library get.handler;
6 6
7 import 'dart:convert'; 7 import 'dart:convert';
8 import 'dart:io'; 8 import 'dart:io';
9 import 'dart:math'; 9 import 'dart:math';
10 10
(...skipping 10 matching lines...) Expand all
21 /** 21 /**
22 * Instances of the class [GetHandler] handle GET requests. 22 * Instances of the class [GetHandler] handle GET requests.
23 */ 23 */
24 class GetHandler { 24 class GetHandler {
25 /** 25 /**
26 * The path used to request the status of the analysis server as a whole. 26 * The path used to request the status of the analysis server as a whole.
27 */ 27 */
28 static const String STATUS_PATH = '/status'; 28 static const String STATUS_PATH = '/status';
29 29
30 /** 30 /**
31 * The path used to request code completion information. 31 * The path used to request information about the cache entry corresponding
32 * to a single file.
32 */ 33 */
33 static const String COMPLETION_PATH = '/completion'; 34 static const String CACHE_ENTRY_PATH = '/cache_entry';
34 35
35 /** 36 /**
36 * The path used to request the list of source files in a certain cache 37 * The path used to request the list of source files in a certain cache
37 * state. 38 * state.
38 */ 39 */
39 static const String CACHE_STATE_PATH = '/cache_state'; 40 static const String CACHE_STATE_PATH = '/cache_state';
40 41
41 /** 42 /**
43 * The path used to request code completion information.
44 */
45 static const String COMPLETION_PATH = '/completion';
46
47 /**
42 * Query parameter used to represent the cache state to search for, when 48 * Query parameter used to represent the cache state to search for, when
43 * accessing [CACHE_STATE_PATH]. 49 * accessing [CACHE_STATE_PATH].
44 */ 50 */
45 static const String STATE_QUERY_PARAM = 'state'; 51 static const String STATE_QUERY_PARAM = 'state';
46 52
47 /** 53 /**
48 * Query parameter used to represent the context to search for, when 54 * Query parameter used to represent the context to search for, when
49 * accessing [CACHE_STATE_PATH]. 55 * accessing [CACHE_ENTRY_PATH] or [CACHE_STATE_PATH].
50 */ 56 */
51 static const String CONTEXT_QUERY_PARAM = 'context'; 57 static const String CONTEXT_QUERY_PARAM = 'context';
52 58
53 /** 59 /**
54 * Query parameter used to represent the descriptor to search for, when 60 * Query parameter used to represent the descriptor to search for, when
55 * accessing [CACHE_STATE_PATH]. 61 * accessing [CACHE_STATE_PATH].
56 */ 62 */
57 static const String DESCRIPTOR_QUERY_PARAM = 'descriptor'; 63 static const String DESCRIPTOR_QUERY_PARAM = 'descriptor';
58 64
59 /** 65 /**
66 * Query parameter used to represent the source to search for, when accessing
67 * [CACHE_ENTRY_PATH].
68 */
69 static const String SOURCE_QUERY_PARAM = 'entry';
70
71 /**
60 * The socket server whose status is to be reported on. 72 * The socket server whose status is to be reported on.
61 */ 73 */
62 SocketServer _server; 74 SocketServer _server;
63 75
64 /** 76 /**
65 * Buffer containing strings printed by the analysis server. 77 * Buffer containing strings printed by the analysis server.
66 */ 78 */
67 List<String> _printBuffer; 79 List<String> _printBuffer;
68 80
69 /** 81 /**
70 * Initialize a newly created handler for GET requests. 82 * Initialize a newly created handler for GET requests.
71 */ 83 */
72 GetHandler(this._server, this._printBuffer); 84 GetHandler(this._server, this._printBuffer);
73 85
74 /** 86 /**
75 * Handle a GET request received by the HTTP server. 87 * Handle a GET request received by the HTTP server.
76 */ 88 */
77 void handleGetRequest(HttpRequest request) { 89 void handleGetRequest(HttpRequest request) {
78 String path = request.uri.path; 90 String path = request.uri.path;
79 if (path == STATUS_PATH) { 91 if (path == STATUS_PATH) {
80 _returnServerStatus(request); 92 _returnServerStatus(request);
81 } else if (path == CACHE_STATE_PATH) { 93 } else if (path == CACHE_STATE_PATH) {
82 _returnCacheState(request); 94 _returnCacheState(request);
95 } else if (path == CACHE_ENTRY_PATH) {
96 _returnCacheEntry(request);
83 } else if (path == COMPLETION_PATH) { 97 } else if (path == COMPLETION_PATH) {
84 _returnCompletionInfo(request); 98 _returnCompletionInfo(request);
85 } else { 99 } else {
86 _returnUnknownRequest(request); 100 _returnUnknownRequest(request);
87 } 101 }
88 } 102 }
89 103
90 /** 104 /**
91 * Create a link to [path] with query parameters [params], with inner HTML 105 * Create a link to [path] with query parameters [params], with inner HTML
92 * [innerHtml]. 106 * [innerHtml].
93 */ 107 */
94 String _makeLink(String path, Map<String, String> params, String innerHtml) { 108 String _makeLink(String path, Map<String, String> params, String innerHtml) {
95 Uri uri = new Uri(path: path, queryParameters: params); 109 Uri uri = new Uri(path: path, queryParameters: params);
96 return '<a href="${HTML_ESCAPE.convert(uri.toString())}">$innerHtml</a>'; 110 return '<a href="${HTML_ESCAPE.convert(uri.toString())}">$innerHtml</a>';
97 } 111 }
98 112
99 /** 113 /**
114 * Generate a table showing the cache values corresponding to the given
115 * [descriptors], using [getState] to get the cache state corresponding to
116 * each descriptor, and [getValue] to get the cached value corresponding to
117 * each descriptor. Append the resulting HTML to [response].
118 */
119 void _outputDescriptorTable(HttpResponse response,
120 List<DataDescriptor> descriptors, CacheState getState(DataDescriptor), dyn amic
121 getValue(DataDescriptor)) {
122 response.write('<dl>');
123 for (DataDescriptor descriptor in descriptors) {
124 String descriptorName = HTML_ESCAPE.convert(descriptor.toString());
125 String descriptorState =
126 HTML_ESCAPE.convert(getState(descriptor).toString());
127 response.write('<dt>$descriptorName ($descriptorState)</dt><dd>');
128 try {
129 _outputValueAsHtml(response, getValue(descriptor));
130 } catch (exception) {
131 response.write('(${HTML_ESCAPE.convert(exception.toString())})');
132 }
133 response.write('</dd>');
134 }
135 response.write('</dl>');
136 }
137
138 /**
139 * Render the given [value] as HTML and append it to [response].
140 */
141 void _outputValueAsHtml(HttpResponse response, dynamic value) {
142 if (value == null) {
143 response.write('<i>null</i>');
144 } else if (value is String) {
145 response.write('<pre>${HTML_ESCAPE.convert(value)}</pre>');
146 } else if (value is List) {
147 response.write('${value.length} entries');
148 response.write('<ul>');
149 for (var entry in value) {
150 response.write('<li>');
151 _outputValueAsHtml(response, entry);
152 response.write('</li>');
153 }
154 response.write('</ul>');
155 } else {
156 response.write(HTML_ESCAPE.convert(value.toString()));
157 response.write(
158 ' <i>(${HTML_ESCAPE.convert(value.runtimeType.toString())})</i>');
159 }
160 }
161
162 /**
163 * Return a response containing information about a single source file in the
164 * cache.
165 */
166 void _returnCacheEntry(HttpRequest request) {
167 // Figure out which context is being searched for.
168 String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
169 if (contextFilter == null) {
170 return _returnFailure(
171 request,
172 'Query parameter $CONTEXT_QUERY_PARAM required');
173 }
174
175 // Figure out which CacheEntry is being searched for.
176 String sourceUri = request.uri.queryParameters[SOURCE_QUERY_PARAM];
177 if (sourceUri == null) {
178 return _returnFailure(
179 request,
180 'Query parameter $SOURCE_QUERY_PARAM required');
181 }
182
183 AnalysisServer analysisServer = _server.analysisServer;
184 if (analysisServer == null) {
185 return _returnFailure(request, 'Analysis server not running');
186 }
187 HttpResponse response = request.response;
188 response.statusCode = HttpStatus.OK;
189 response.headers.add(HttpHeaders.CONTENT_TYPE, "text/html");
190 response.write('<html>');
191 response.write('<head>');
192 response.write('<title>Dart Analysis Server - Search result</title>');
193 response.write('</head>');
194 response.write('<body>');
195 response.write('<h1>');
196 response.write('File ${HTML_ESCAPE.convert(sourceUri)}');
197 response.write(' in context ${HTML_ESCAPE.convert(contextFilter)}');
198 response.write('</h1>');
199 analysisServer.folderMap.forEach(
200 (Folder folder, AnalysisContextImpl context) {
201 if (folder.path != contextFilter) {
202 return;
203 }
204 Source source = context.sourceFactory.forUri(sourceUri);
205 if (source == null) {
206 response.write('<p>Not found.</p>');
207 return;
208 }
209 SourceEntry entry = context.getReadableSourceEntryOrNull(source);
210 if (entry == null) {
211 response.write('<p>Not found.</p>');
212 return;
213 }
214 response.write('<h2>File info:</h2><dl>');
215 _outputDescriptorTable(
216 response,
217 entry.descriptors,
218 entry.getState,
219 entry.getValue);
220 if (entry is DartEntry) {
221 for (Source librarySource in entry.containingLibraries) {
222 String libraryName = HTML_ESCAPE.convert(librarySource.fullName);
223 response.write('<h2>In library $libraryName:</h2>');
224 _outputDescriptorTable(
225 response,
226 entry.libraryDescriptors,
227 (DataDescriptor descriptor) =>
228 entry.getStateInLibrary(descriptor, librarySource),
229 (DataDescriptor descriptor) =>
230 entry.getValueInLibrary(descriptor, librarySource));
231 }
232 }
233 });
234 response.write('</body>');
235 response.write('</html>');
236 response.close();
237 }
238
239 /**
100 * Return a response indicating the set of source files in a certain cache 240 * Return a response indicating the set of source files in a certain cache
101 * state. 241 * state.
102 */ 242 */
103 void _returnCacheState(HttpRequest request) { 243 void _returnCacheState(HttpRequest request) {
104 // Figure out what CacheState is being searched for. 244 // Figure out what CacheState is being searched for.
105 String stateQueryParam = request.uri.queryParameters[STATE_QUERY_PARAM]; 245 String stateQueryParam = request.uri.queryParameters[STATE_QUERY_PARAM];
106 if (stateQueryParam == null) { 246 if (stateQueryParam == null) {
107 return _returnFailure( 247 return _returnFailure(
108 request, 248 request,
109 'Query parameter $STATE_QUERY_PARAM required'); 249 'Query parameter $STATE_QUERY_PARAM required');
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 (Folder folder, AnalysisContextImpl context) { 300 (Folder folder, AnalysisContextImpl context) {
161 if (folder.path != contextFilter) { 301 if (folder.path != contextFilter) {
162 return; 302 return;
163 } 303 }
164 context.visitCacheItems( 304 context.visitCacheItems(
165 (Source source, SourceEntry dartEntry, DataDescriptor rowDesc, CacheSt ate state) 305 (Source source, SourceEntry dartEntry, DataDescriptor rowDesc, CacheSt ate state)
166 { 306 {
167 if (state != stateFilter || rowDesc.toString() != descriptorFilter) { 307 if (state != stateFilter || rowDesc.toString() != descriptorFilter) {
168 return; 308 return;
169 } 309 }
170 response.write('<li>${HTML_ESCAPE.convert(source.fullName)}</li>'); 310 String link = _makeLink(CACHE_ENTRY_PATH, {
311 CONTEXT_QUERY_PARAM: folder.path,
312 SOURCE_QUERY_PARAM: source.uri.toString()
313 }, HTML_ESCAPE.convert(source.fullName));
314 response.write('<li>$link</li>');
171 count++; 315 count++;
172 }); 316 });
173 }); 317 });
174 response.write('</ul>'); 318 response.write('</ul>');
175 response.write('<p>$count files found</p>'); 319 response.write('<p>$count files found</p>');
176 response.write('</body>'); 320 response.write('</body>');
177 response.write('</html>'); 321 response.write('</html>');
178 response.close(); 322 response.close();
179 } 323 }
180 324
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 if (header) { 547 if (header) {
404 response.write('</th>'); 548 response.write('</th>');
405 } else { 549 } else {
406 response.write('</td>'); 550 response.write('</td>');
407 } 551 }
408 } 552 }
409 553
410 response.write('</tr>'); 554 response.write('</tr>');
411 } 555 }
412 } 556 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/generated/engine.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698