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

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

Issue 875663002: Clean up and add analyzing contexts (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | 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.src.get_handler; 5 library analysis_server.src.get_handler;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 import 'dart:convert'; 8 import 'dart:convert';
9 import 'dart:io'; 9 import 'dart:io';
10 import 'dart:math'; 10 import 'dart:math';
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 */ 49 */
50 static const String AST_PATH = '/ast'; 50 static const String AST_PATH = '/ast';
51 51
52 /** 52 /**
53 * The path used to request information about the cache entry corresponding 53 * The path used to request information about the cache entry corresponding
54 * to a single file. 54 * to a single file.
55 */ 55 */
56 static const String CACHE_ENTRY_PATH = '/cache_entry'; 56 static const String CACHE_ENTRY_PATH = '/cache_entry';
57 57
58 /** 58 /**
59 * The path used to request information about the cache entry corresponding
60 * to a single file.
61 */
62 static const String CACHE_ENTRY2_PATH = '/cache_entry2';
63
64 /**
65 * The path used to request the list of source files in a certain cache 59 * The path used to request the list of source files in a certain cache
66 * state. 60 * state.
67 */ 61 */
68 static const String CACHE_STATE_PATH = '/cache_state'; 62 static const String CACHE_STATE_PATH = '/cache_state';
69 63
70 /** 64 /**
71 * The path used to request code completion information. 65 * The path used to request code completion information.
72 */ 66 */
73 static const String COMPLETION_PATH = '/completion'; 67 static const String COMPLETION_PATH = '/completion';
74 68
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 orElse: () => null); 153 orElse: () => null);
160 } 154 }
161 155
162 /** 156 /**
163 * Handle a GET request received by the HTTP server. 157 * Handle a GET request received by the HTTP server.
164 */ 158 */
165 void handleGetRequest(HttpRequest request) { 159 void handleGetRequest(HttpRequest request) {
166 String path = request.uri.path; 160 String path = request.uri.path;
167 if (path == STATUS_PATH) { 161 if (path == STATUS_PATH) {
168 _returnServerStatus(request); 162 _returnServerStatus(request);
169 } else if (path == '/status2') {
170 _returnServerStatus2(request);
171 } else if (path == AST_PATH) { 163 } else if (path == AST_PATH) {
172 _returnAst(request); 164 _returnAst(request);
173 } else if (path == CACHE_STATE_PATH) { 165 } else if (path == CACHE_STATE_PATH) {
174 _returnCacheState(request); 166 _returnCacheState(request);
175 } else if (path == CACHE_ENTRY_PATH) { 167 } else if (path == CACHE_ENTRY_PATH) {
176 _returnCacheEntry(request); 168 _returnCacheEntry(request);
177 } else if (path == CACHE_ENTRY2_PATH) {
178 _returnCacheEntry2(request);
179 } else if (path == COMPLETION_PATH) { 169 } else if (path == COMPLETION_PATH) {
180 _returnCompletionInfo(request); 170 _returnCompletionInfo(request);
181 } else if (path == CONTEXT_PATH) { 171 } else if (path == CONTEXT_PATH) {
182 _returnContextInfo(request); 172 _returnContextInfo(request);
183 } else if (path == ELEMENT_PATH) { 173 } else if (path == ELEMENT_PATH) {
184 _returnElement(request); 174 _returnElement(request);
185 } else if (path == OVERLAY_PATH) { 175 } else if (path == OVERLAY_PATH) {
186 _returnOverlayContents(request); 176 _returnOverlayContents(request);
187 } else if (path == OVERLAYS_PATH) { 177 } else if (path == OVERLAYS_PATH) {
188 _returnOverlaysInfo(request); 178 _returnOverlaysInfo(request);
(...skipping 21 matching lines...) Expand all
210 context.visitCacheItems( 200 context.visitCacheItems(
211 (Source source, SourceEntry sourceEntry, DataDescriptor rowDesc, 201 (Source source, SourceEntry sourceEntry, DataDescriptor rowDesc,
212 CacheState state) { 202 CacheState state) {
213 if (sourceEntry.exception != null) { 203 if (sourceEntry.exception != null) {
214 hasException = true; 204 hasException = true;
215 } 205 }
216 }); 206 });
217 return hasException; 207 return hasException;
218 } 208 }
219 209
210 /**
211 * Return the folder in the [folderMap] with which the given [context] is
212 * associated.
213 */
220 Folder _keyForValue(Map<Folder, AnalysisContext> folderMap, 214 Folder _keyForValue(Map<Folder, AnalysisContext> folderMap,
221 AnalysisContext context) { 215 AnalysisContext context) {
222 for (Folder folder in folderMap.keys) { 216 for (Folder folder in folderMap.keys) {
223 if (folderMap[folder] == context) { 217 if (folderMap[folder] == context) {
224 return folder; 218 return folder;
225 } 219 }
226 } 220 }
227 return null; 221 return null;
228 } 222 }
229 223
230 /** 224 /**
231 * Create a link to [path] with query parameters [params], with inner HTML 225 * Create a link to [path] with query parameters [params], with inner HTML
232 * [innerHtml]. If [hasError] is `true`, then the link will have the class 226 * [innerHtml]. If [hasError] is `true`, then the link will have the class
233 * 'error'. 227 * 'error'.
234 */ 228 */
235 String _makeLink(String path, Map<String, String> params, String innerHtml, 229 String _makeLink(String path, Map<String, String> params, String innerHtml,
236 [bool hasError = false]) { 230 [bool hasError = false]) {
237 Uri uri = new Uri(path: path, queryParameters: params); 231 Uri uri = new Uri(path: path, queryParameters: params);
238 String href = HTML_ESCAPE.convert(uri.toString()); 232 String href = HTML_ESCAPE.convert(uri.toString());
239 String classAttribute = hasError ? ' class="error"' : ''; 233 String classAttribute = hasError ? ' class="error"' : '';
240 return '<a href="$href"$classAttribute>$innerHtml</a>'; 234 return '<a href="$href"$classAttribute>$innerHtml</a>';
241 } 235 }
242 236
243 /** 237 /**
244 * Generate a table showing the cache values corresponding to the given
245 * [descriptors], using [getState] to get the cache state corresponding to
246 * each descriptor, and [getValue] to get the cached value corresponding to
247 * each descriptor. Append the resulting HTML to [response].
248 */
249 void _outputDescriptorTable(HttpResponse response,
250 List<DataDescriptor> descriptors, CacheState getState(DataDescriptor), dyn amic
251 getValue(DataDescriptor)) {
252 response.write('<dl>');
253 for (DataDescriptor descriptor in descriptors) {
254 String descriptorName = HTML_ESCAPE.convert(descriptor.toString());
255 String descriptorState =
256 HTML_ESCAPE.convert(getState(descriptor).toString());
257 response.write('<dt>$descriptorName ($descriptorState)</dt><dd>');
258 try {
259 _outputValueAsHtml(response, getValue(descriptor));
260 } catch (exception) {
261 response.write('(${HTML_ESCAPE.convert(exception.toString())})');
262 }
263 response.write('</dd>');
264 }
265 response.write('</dl>');
266 }
267
268 /**
269 * Render the given [value] as HTML and append it to [response].
270 */
271 void _outputValueAsHtml(HttpResponse response, dynamic value) {
272 if (value == null) {
273 response.write('<i>null</i>');
274 } else if (value is String) {
275 response.write('<pre>${HTML_ESCAPE.convert(value)}</pre>');
276 } else if (value is List) {
277 response.write('${value.length} entries');
278 response.write('<ul>');
279 for (var entry in value) {
280 response.write('<li>');
281 _outputValueAsHtml(response, entry);
282 response.write('</li>');
283 }
284 response.write('</ul>');
285 } else {
286 response.write(HTML_ESCAPE.convert(value.toString()));
287 response.write(
288 ' <i>(${HTML_ESCAPE.convert(value.runtimeType.toString())})</i>');
289 }
290 }
291
292 /**
293 * Return a response containing information about an AST structure. 238 * Return a response containing information about an AST structure.
294 */ 239 */
295 void _returnAst(HttpRequest request) { 240 void _returnAst(HttpRequest request) {
296 AnalysisServer analysisServer = _server.analysisServer; 241 AnalysisServer analysisServer = _server.analysisServer;
297 if (analysisServer == null) { 242 if (analysisServer == null) {
298 return _returnFailure(request, 'Analysis server not running'); 243 return _returnFailure(request, 'Analysis server not running');
299 } 244 }
300 String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM]; 245 String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
301 if (contextFilter == null) { 246 if (contextFilter == null) {
302 return _returnFailure( 247 return _returnFailure(
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 ast.accept(new AstWriter(buffer)); 285 ast.accept(new AstWriter(buffer));
341 }); 286 });
342 }); 287 });
343 } 288 }
344 289
345 /** 290 /**
346 * Return a response containing information about a single source file in the 291 * Return a response containing information about a single source file in the
347 * cache. 292 * cache.
348 */ 293 */
349 void _returnCacheEntry(HttpRequest request) { 294 void _returnCacheEntry(HttpRequest request) {
350 // Figure out which context is being searched for.
351 String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
352 if (contextFilter == null) {
353 return _returnFailure(
354 request,
355 'Query parameter $CONTEXT_QUERY_PARAM required');
356 }
357
358 // Figure out which CacheEntry is being searched for.
359 String sourceUri = request.uri.queryParameters[SOURCE_QUERY_PARAM];
360 if (sourceUri == null) {
361 return _returnFailure(
362 request,
363 'Query parameter $SOURCE_QUERY_PARAM required');
364 }
365
366 AnalysisServer analysisServer = _server.analysisServer; 295 AnalysisServer analysisServer = _server.analysisServer;
367 if (analysisServer == null) { 296 if (analysisServer == null) {
368 return _returnFailure(request, 'Analysis server not running'); 297 return _returnFailure(request, 'Analysis server not running');
369 }
370
371 HttpResponse response = request.response;
372 response.statusCode = HttpStatus.OK;
373 response.headers.contentType = _htmlContent;
374 response.write('<html>');
375 response.write('<head>');
376 response.write('<title>Dart Analysis Server - Search result</title>');
377 response.write('</head>');
378 response.write('<body>');
379 response.write('<h1>');
380 response.write('File ${HTML_ESCAPE.convert(sourceUri)}');
381 response.write(' in context ${HTML_ESCAPE.convert(contextFilter)}');
382 response.write('</h1>');
383 analysisServer.folderMap.forEach(
384 (Folder folder, AnalysisContextImpl context) {
385 if (folder.path != contextFilter) {
386 return;
387 }
388 Source source = context.sourceFactory.forUri(sourceUri);
389 if (source == null) {
390 response.write('<p>Not found.</p>');
391 return;
392 }
393 SourceEntry entry = context.getReadableSourceEntryOrNull(source);
394 if (entry == null) {
395 response.write('<p>Not found.</p>');
396 return;
397 }
398 response.write('<h2>File info:</h2><dl>');
399 _outputDescriptorTable(
400 response,
401 entry.descriptors,
402 entry.getState,
403 entry.getValue);
404 if (entry is DartEntry) {
405 for (Source librarySource in entry.containingLibraries) {
406 String libraryName = HTML_ESCAPE.convert(librarySource.fullName);
407 response.write('<h2>In library $libraryName:</h2>');
408 _outputDescriptorTable(
409 response,
410 entry.libraryDescriptors,
411 (DataDescriptor descriptor) =>
412 entry.getStateInLibrary(descriptor, librarySource),
413 (DataDescriptor descriptor) =>
414 entry.getValueInLibrary(descriptor, librarySource));
415 }
416 }
417 });
418 response.write('</body>');
419 response.write('</html>');
420
421 response.close();
422 }
423
424 /**
425 * Return a response containing information about a single source file in the
426 * cache.
427 */
428 void _returnCacheEntry2(HttpRequest request) {
429 AnalysisServer analysisServer = _server.analysisServer;
430 if (analysisServer == null) {
431 return _returnFailure(request, 'Analysis server not running');
432 } 298 }
433 String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM]; 299 String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
434 if (contextFilter == null) { 300 if (contextFilter == null) {
435 return _returnFailure( 301 return _returnFailure(
436 request, 302 request,
437 'Query parameter $CONTEXT_QUERY_PARAM required'); 303 'Query parameter $CONTEXT_QUERY_PARAM required');
438 } 304 }
439 Folder folder = _findFolder(analysisServer, contextFilter); 305 Folder folder = _findFolder(analysisServer, contextFilter);
440 if (folder == null) { 306 if (folder == null) {
441 return _returnFailure(request, 'Invalid context: $contextFilter'); 307 return _returnFailure(request, 'Invalid context: $contextFilter');
442 } 308 }
443 String sourceUri = request.uri.queryParameters[SOURCE_QUERY_PARAM]; 309 String sourceUri = request.uri.queryParameters[SOURCE_QUERY_PARAM];
444 if (sourceUri == null) { 310 if (sourceUri == null) {
445 return _returnFailure( 311 return _returnFailure(
446 request, 312 request,
447 'Query parameter $SOURCE_QUERY_PARAM required'); 313 'Query parameter $SOURCE_QUERY_PARAM required');
448 } 314 }
449 315
316 List<Folder> allContexts = <Folder>[];
317 Map<Folder, SourceEntry> entryMap = new HashMap<Folder, SourceEntry>();
318 analysisServer.folderMap.forEach((Folder folder, AnalysisContextImpl context ) {
319 Source source = context.sourceFactory.forUri(sourceUri);
320 if (source != null) {
321 SourceEntry entry = context.getReadableSourceEntryOrNull(source);
322 if (entry != null) {
323 allContexts.add(folder);
324 entryMap[folder] = entry;
325 }
326 }
327 });
328 allContexts.sort((Folder firstFolder, Folder secondFolder) => firstFolder.pa th.compareTo(secondFolder.path));
450 AnalysisContextImpl context = analysisServer.folderMap[folder]; 329 AnalysisContextImpl context = analysisServer.folderMap[folder];
451 330
452 _writeResponse(request, (StringBuffer buffer) { 331 _writeResponse(request, (StringBuffer buffer) {
453 _writePage( 332 _writePage(
454 buffer, 333 buffer,
455 'Analysis Server - Cache Entry', 334 'Analysis Server - Cache Entry',
456 ['Context: $contextFilter', 'File: $sourceUri'], 335 ['Context: $contextFilter', 'File: $sourceUri'],
457 (HttpResponse) { 336 (HttpResponse) {
458 Source source = context.sourceFactory.forUri(sourceUri); 337 buffer.write('<h3>Analyzing Contexts</h3><p>');
459 if (source == null) { 338 bool first = true;
460 buffer.write('<p>Not found.</p>'); 339 allContexts.forEach((Folder folder) {
461 return; 340 if (first) {
462 } 341 first = false;
463 SourceEntry entry = context.getReadableSourceEntryOrNull(source); 342 } else {
343 buffer.write('<br>');
344 }
345 AnalysisContextImpl analyzingContext = analysisServer.folderMap[folder ];
346 if (analyzingContext == context) {
347 buffer.write(folder.path);
348 } else {
349 buffer.write(_makeLink(CACHE_ENTRY_PATH, {
350 CONTEXT_QUERY_PARAM: folder.path,
351 SOURCE_QUERY_PARAM: sourceUri
352 }, HTML_ESCAPE.convert(folder.path)));
353 }
354 if (entryMap[folder].explicitlyAdded) {
355 buffer.write(' (explicit)');
356 } else {
357 buffer.write(' (implicit)');
358 }
359 });
360 buffer.write('</p>');
361
362 SourceEntry entry = entryMap[folder];
464 if (entry == null) { 363 if (entry == null) {
465 buffer.write('<p>Not found.</p>'); 364 buffer.write('<p>Not being analyzed in this context.</p>');
466 return; 365 return;
467 } 366 }
468 Map<String, String> linkParameters = <String, String>{ 367 Map<String, String> linkParameters = <String, String>{
469 CONTEXT_QUERY_PARAM: folder.path, 368 CONTEXT_QUERY_PARAM: folder.path,
470 SOURCE_QUERY_PARAM: source.uri.toString() 369 SOURCE_QUERY_PARAM: sourceUri
471 }; 370 };
371
472 buffer.write('<h3>Library Independent</h3>'); 372 buffer.write('<h3>Library Independent</h3>');
473 _writeDescriptorTable( 373 _writeDescriptorTable(
474 buffer, 374 buffer,
475 entry.descriptors, 375 entry.descriptors,
476 entry.getState, 376 entry.getState,
477 entry.getValue, 377 entry.getValue,
478 linkParameters); 378 linkParameters);
479 if (entry is DartEntry) { 379 if (entry is DartEntry) {
480 for (Source librarySource in entry.containingLibraries) { 380 for (Source librarySource in entry.containingLibraries) {
481 String libraryName = HTML_ESCAPE.convert(librarySource.fullName); 381 String libraryName = HTML_ESCAPE.convert(librarySource.fullName);
(...skipping 14 matching lines...) Expand all
496 } 396 }
497 }); 397 });
498 }); 398 });
499 } 399 }
500 400
501 /** 401 /**
502 * Return a response indicating the set of source files in a certain cache 402 * Return a response indicating the set of source files in a certain cache
503 * state. 403 * state.
504 */ 404 */
505 void _returnCacheState(HttpRequest request) { 405 void _returnCacheState(HttpRequest request) {
406 AnalysisServer analysisServer = _server.analysisServer;
407 if (analysisServer == null) {
408 return _returnFailure(request, 'Analysis server not running');
409 }
410 // Figure out which context is being searched within.
411 String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
412 if (contextFilter == null) {
413 return _returnFailure(
414 request,
415 'Query parameter $CONTEXT_QUERY_PARAM required');
416 }
506 // Figure out what CacheState is being searched for. 417 // Figure out what CacheState is being searched for.
507 String stateQueryParam = request.uri.queryParameters[STATE_QUERY_PARAM]; 418 String stateQueryParam = request.uri.queryParameters[STATE_QUERY_PARAM];
508 if (stateQueryParam == null) { 419 if (stateQueryParam == null) {
509 return _returnFailure( 420 return _returnFailure(
510 request, 421 request,
511 'Query parameter $STATE_QUERY_PARAM required'); 422 'Query parameter $STATE_QUERY_PARAM required');
512 } 423 }
513 CacheState stateFilter = null; 424 CacheState stateFilter = null;
514 for (CacheState value in CacheState.values) { 425 for (CacheState value in CacheState.values) {
515 if (value.toString() == stateQueryParam) { 426 if (value.toString() == stateQueryParam) {
516 stateFilter = value; 427 stateFilter = value;
517 } 428 }
518 } 429 }
519 if (stateFilter == null) { 430 if (stateFilter == null) {
520 return _returnFailure( 431 return _returnFailure(
521 request, 432 request,
522 'Query parameter $STATE_QUERY_PARAM is invalid'); 433 'Query parameter $STATE_QUERY_PARAM is invalid');
523 } 434 }
524
525 // Figure out which context is being searched for.
526 String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
527 if (contextFilter == null) {
528 return _returnFailure(
529 request,
530 'Query parameter $CONTEXT_QUERY_PARAM required');
531 }
532
533 // Figure out which descriptor is being searched for. 435 // Figure out which descriptor is being searched for.
534 String descriptorFilter = 436 String descriptorFilter =
535 request.uri.queryParameters[DESCRIPTOR_QUERY_PARAM]; 437 request.uri.queryParameters[DESCRIPTOR_QUERY_PARAM];
536 if (descriptorFilter == null) { 438 if (descriptorFilter == null) {
537 return _returnFailure( 439 return _returnFailure(
538 request, 440 request,
539 'Query parameter $DESCRIPTOR_QUERY_PARAM required'); 441 'Query parameter $DESCRIPTOR_QUERY_PARAM required');
540 } 442 }
541 443
542 AnalysisServer analysisServer = _server.analysisServer; 444 Folder folder = _findFolder(analysisServer, contextFilter);
543 if (analysisServer == null) { 445 AnalysisContextImpl context = analysisServer.folderMap[folder];
544 return _returnFailure(request, 'Analysis server not running'); 446 List<String> links = <String>[];
545 } 447 context.visitCacheItems(
546 HttpResponse response = request.response; 448 (Source source, SourceEntry dartEntry, DataDescriptor rowDesc, CacheStat e state)
547 response.statusCode = HttpStatus.OK; 449 {
548 response.headers.contentType = _htmlContent; 450 if (state != stateFilter || rowDesc.toString() != descriptorFilter) {
549 response.write('<html>');
550 response.write('<head>');
551 response.write('<title>Dart Analysis Server - Search result</title>');
552 response.write('</head>');
553 response.write('<body>');
554 response.write('<h1>');
555 response.write('Files with state ${HTML_ESCAPE.convert(stateQueryParam)}');
556 response.write(' for descriptor ${HTML_ESCAPE.convert(descriptorFilter)}');
557 response.write(' in context ${HTML_ESCAPE.convert(contextFilter)}');
558 response.write('</h1>');
559 response.write('<ul>');
560 int count = 0;
561 analysisServer.folderMap.forEach(
562 (Folder folder, AnalysisContextImpl context) {
563 if (folder.path != contextFilter) {
564 return; 451 return;
565 } 452 }
566 context.visitCacheItems( 453 String link = _makeLink(CACHE_ENTRY_PATH, {
567 (Source source, SourceEntry dartEntry, DataDescriptor rowDesc, CacheSt ate state) 454 CONTEXT_QUERY_PARAM: folder.path,
568 { 455 SOURCE_QUERY_PARAM: source.uri.toString()
569 if (state != stateFilter || rowDesc.toString() != descriptorFilter) { 456 }, HTML_ESCAPE.convert(source.fullName));
570 return; 457 links.add(link);
571 } 458 });
572 String link = _makeLink(CACHE_ENTRY_PATH, { 459
573 CONTEXT_QUERY_PARAM: folder.path, 460 _writeResponse(request, (StringBuffer buffer) {
574 SOURCE_QUERY_PARAM: source.uri.toString() 461 _writePage(
575 }, HTML_ESCAPE.convert(source.fullName)); 462 buffer,
576 response.write('<li>$link</li>'); 463 'Analysis Server - Cache Search',
577 count++; 464 [
465 'Context: $contextFilter',
466 'Descriptor: ${HTML_ESCAPE.convert(descriptorFilter)}',
467 'State: ${HTML_ESCAPE.convert(stateQueryParam)}'],
468 (StringBuffer buffer) {
469 buffer.write('<p>${links.length} files found</p>');
470 buffer.write('<ul>');
471 links.forEach((String link) {
472 buffer.write('<li>$link</li>');
473 });
474 buffer.write('</ul>');
578 }); 475 });
579 }); 476 });
580 response.write('</ul>');
581 response.write('<p>$count files found</p>');
582 response.write('</body>');
583 response.write('</html>');
584 response.close();
585 } 477 }
586 478
587 /** 479 /**
588 * Return a response displaying code completion information. 480 * Return a response displaying code completion information.
589 */ 481 */
590 void _returnCompletionInfo(HttpRequest request) { 482 void _returnCompletionInfo(HttpRequest request) {
591 String value = request.requestedUri.queryParameters['index']; 483 String value = request.requestedUri.queryParameters['index'];
592 int index = value != null ? int.parse(value, onError: (_) => 0) : 0; 484 int index = value != null ? int.parse(value, onError: (_) => 0) : 0;
593 _writeResponse(request, (StringBuffer buffer) { 485 _writeResponse(request, (StringBuffer buffer) {
594 _writePage(buffer, 'Code Completion - Status', [], (StringBuffer buffer) { 486 _writePage(buffer, 'Analysis Server - Completion Stats', [], (StringBuffer buffer) {
595 _writeCompletionPerformanceDetail(buffer, index); 487 _writeCompletionPerformanceDetail(buffer, index);
596 _writeCompletionPerformanceList(buffer); 488 _writeCompletionPerformanceList(buffer);
597 }); 489 });
598 }); 490 });
599 } 491 }
600 492
601 /** 493 /**
602 * Return a response containing information about a single source file in the 494 * Return a response containing information about a single source file in the
603 * cache. 495 * cache.
604 */ 496 */
(...skipping 24 matching lines...) Expand all
629 context.prioritySources.map((Source source) => source.fullName).toList() ; 521 context.prioritySources.map((Source source) => source.fullName).toList() ;
630 context.visitCacheItems( 522 context.visitCacheItems(
631 (Source source, SourceEntry sourceEntry, DataDescriptor rowDesc, 523 (Source source, SourceEntry sourceEntry, DataDescriptor rowDesc,
632 CacheState state) { 524 CacheState state) {
633 String sourceName = source.fullName; 525 String sourceName = source.fullName;
634 if (!links.containsKey(sourceName)) { 526 if (!links.containsKey(sourceName)) {
635 CaughtException exception = sourceEntry.exception; 527 CaughtException exception = sourceEntry.exception;
636 if (exception != null) { 528 if (exception != null) {
637 exceptions.add(exception); 529 exceptions.add(exception);
638 } 530 }
639 String link = _makeLink(CACHE_ENTRY2_PATH, { 531 String link = _makeLink(CACHE_ENTRY_PATH, {
640 CONTEXT_QUERY_PARAM: folder.path, 532 CONTEXT_QUERY_PARAM: folder.path,
641 SOURCE_QUERY_PARAM: source.uri.toString() 533 SOURCE_QUERY_PARAM: source.uri.toString()
642 }, sourceName, exception != null); 534 }, sourceName, exception != null);
643 if (sourceEntry.explicitlyAdded) { 535 if (sourceEntry.explicitlyAdded) {
644 explicitNames.add(sourceName); 536 explicitNames.add(sourceName);
645 } else { 537 } else {
646 implicitNames.add(sourceName); 538 implicitNames.add(sourceName);
647 } 539 }
648 links[sourceName] = link; 540 links[sourceName] = link;
649 } 541 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 _writeResponse(request, (StringBuffer buffer) { 575 _writeResponse(request, (StringBuffer buffer) {
684 _writePage( 576 _writePage(
685 buffer, 577 buffer,
686 'Analysis Server - Context', 578 'Analysis Server - Context',
687 ['Context: $contextFilter'], 579 ['Context: $contextFilter'],
688 (StringBuffer buffer) { 580 (StringBuffer buffer) {
689 List headerRowText = ['Context']; 581 List headerRowText = ['Context'];
690 headerRowText.addAll(CacheState.values); 582 headerRowText.addAll(CacheState.values);
691 buffer.write('<h3>Summary</h3>'); 583 buffer.write('<h3>Summary</h3>');
692 buffer.write('<table>'); 584 buffer.write('<table>');
693 _writeRow2(buffer, headerRowText, header: true); 585 _writeRow(buffer, headerRowText, header: true);
694 AnalysisContextStatistics statistics = context.statistics; 586 AnalysisContextStatistics statistics = context.statistics;
695 statistics.cacheRows.forEach((AnalysisContextStatistics_CacheRow row) { 587 statistics.cacheRows.forEach((AnalysisContextStatistics_CacheRow row) {
696 List rowText = [row.name]; 588 List rowText = [row.name];
697 for (CacheState state in CacheState.values) { 589 for (CacheState state in CacheState.values) {
698 String text = row.getCount(state).toString(); 590 String text = row.getCount(state).toString();
699 Map<String, String> params = <String, String>{ 591 Map<String, String> params = <String, String>{
700 STATE_QUERY_PARAM: state.toString(), 592 STATE_QUERY_PARAM: state.toString(),
701 CONTEXT_QUERY_PARAM: folder.path, 593 CONTEXT_QUERY_PARAM: folder.path,
702 DESCRIPTOR_QUERY_PARAM: row.name 594 DESCRIPTOR_QUERY_PARAM: row.name
703 }; 595 };
704 rowText.add(_makeLink(CACHE_STATE_PATH, params, text)); 596 rowText.add(_makeLink(CACHE_STATE_PATH, params, text));
705 } 597 }
706 _writeRow2(buffer, rowText, classes: [null, "right"]); 598 _writeRow(buffer, rowText, classes: [null, "right"]);
707 }); 599 });
708 buffer.write('</table>'); 600 buffer.write('</table>');
709 601
710 _writeFiles(buffer, 'Priority Files', priorityNames); 602 _writeFiles(buffer, 'Priority Files', priorityNames);
711 _writeFiles(buffer, 'Explicitly Analyzed Files', explicitNames); 603 _writeFiles(buffer, 'Explicitly Analyzed Files', explicitNames);
712 _writeFiles(buffer, 'Implicitly Analyzed Files', implicitNames); 604 _writeFiles(buffer, 'Implicitly Analyzed Files', implicitNames);
713 605
714 buffer.write('<h3>Exceptions</h3>'); 606 buffer.write('<h3>Exceptions</h3>');
715 if (exceptions.isEmpty) { 607 if (exceptions.isEmpty) {
716 buffer.write('<p>None</p>'); 608 buffer.write('<p>None</p>');
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
748 'Query parameter $SOURCE_QUERY_PARAM required'); 640 'Query parameter $SOURCE_QUERY_PARAM required');
749 } 641 }
750 642
751 AnalysisContextImpl context = analysisServer.folderMap[folder]; 643 AnalysisContextImpl context = analysisServer.folderMap[folder];
752 644
753 _writeResponse(request, (StringBuffer buffer) { 645 _writeResponse(request, (StringBuffer buffer) {
754 _writePage( 646 _writePage(
755 buffer, 647 buffer,
756 'Analysis Server - Element Model', 648 'Analysis Server - Element Model',
757 ['Context: $contextFilter', 'File: $sourceUri'], 649 ['Context: $contextFilter', 'File: $sourceUri'],
758 (HttpResponse) { 650 (StringBuffer buffer) {
759 Source source = context.sourceFactory.forUri(sourceUri); 651 Source source = context.sourceFactory.forUri(sourceUri);
760 if (source == null) { 652 if (source == null) {
761 buffer.write('<p>Not found.</p>'); 653 buffer.write('<p>Not found.</p>');
762 return; 654 return;
763 } 655 }
764 SourceEntry entry = context.getReadableSourceEntryOrNull(source); 656 SourceEntry entry = context.getReadableSourceEntryOrNull(source);
765 if (entry == null) { 657 if (entry == null) {
766 buffer.write('<p>Not found.</p>'); 658 buffer.write('<p>Not found.</p>');
767 return; 659 return;
768 } 660 }
769 LibraryElement element = entry.getValue(DartEntry.ELEMENT); 661 LibraryElement element = entry.getValue(DartEntry.ELEMENT);
770 if (element == null) { 662 if (element == null) {
771 buffer.write('<p>null</p>'); 663 buffer.write('<p>null</p>');
772 return; 664 return;
773 } 665 }
774 element.accept(new ElementWriter(buffer)); 666 element.accept(new ElementWriter(buffer));
775 }); 667 });
776 }); 668 });
777 } 669 }
778 670
779 void _returnFailure(HttpRequest request, String message) { 671 void _returnFailure(HttpRequest request, String message) {
780 HttpResponse response = request.response; 672 _writeResponse(request, (StringBuffer buffer) {
781 response.statusCode = HttpStatus.OK; 673 _writePage(
782 response.headers.contentType = _htmlContent; 674 buffer,
783 response.write('<html>'); 675 'Analysis Server - Failure',
784 response.write('<head>'); 676 [],
785 response.write('<title>Dart Analysis Server - Failure</title>'); 677 (StringBuffer buffer) {
786 response.write('</head>'); 678 buffer.write(HTML_ESCAPE.convert(message));
787 response.write('<body>'); 679 });
788 response.write(HTML_ESCAPE.convert(message)); 680 });
789 response.write('</body>');
790 response.write('</html>');
791 response.close();
792 } 681 }
793 682
794 void _returnOverlayContents(HttpRequest request) { 683 void _returnOverlayContents(HttpRequest request) {
795 String idString = request.requestedUri.queryParameters[ID_PARAM]; 684 String idString = request.requestedUri.queryParameters[ID_PARAM];
685 if (idString == null) {
686 return _returnFailure(request, 'Query parameter $ID_PARAM required');
687 }
796 int id = int.parse(idString); 688 int id = int.parse(idString);
797 String contents = _overlayContents[id]; 689 String contents = _overlayContents[id];
798 HttpResponse response = request.response; 690
799 response.statusCode = HttpStatus.OK; 691 _writeResponse(request, (StringBuffer buffer) {
800 response.headers.contentType = _htmlContent; 692 _writePage(
801 response.write('<html>'); 693 buffer,
802 response.write('<head>'); 694 'Analysis Server - Overlay',
803 response.write('<title>Dart Analysis Server - Overlay</title>'); 695 [],
804 response.write('</head>'); 696 (StringBuffer buffer) {
805 response.write('<body>'); 697 buffer.write('<pre>${HTML_ESCAPE.convert(contents)}</pre>');
806 response.write('<pre>${HTML_ESCAPE.convert(contents)}</pre>'); 698 });
807 response.write('</body>'); 699 });
808 response.write('</html>');
809 response.close();
810 } 700 }
811 701
812 /** 702 /**
813 * Return a response displaying overlays information. 703 * Return a response displaying overlays information.
814 */ 704 */
815 void _returnOverlaysInfo(HttpRequest request) { 705 void _returnOverlaysInfo(HttpRequest request) {
816 AnalysisServer analysisServer = _server.analysisServer; 706 AnalysisServer analysisServer = _server.analysisServer;
817 if (analysisServer == null) { 707 if (analysisServer == null) {
818 return _returnFailure(request, 'Analysis server is not running'); 708 return _returnFailure(request, 'Analysis server is not running');
819 } 709 }
820 HttpResponse response = request.response; 710
821 response.statusCode = HttpStatus.OK; 711 _writeResponse(request, (StringBuffer buffer) {
822 response.headers.contentType = _htmlContent; 712 _writePage(
823 response.write('<html>'); 713 buffer,
824 response.write('<head>'); 714 'Analysis Server - Overlays',
825 response.write('<title>Dart Analysis Server - Overlays</title>'); 715 [],
826 response.write('</head>'); 716 (StringBuffer buffer) {
827 response.write('<body>'); 717 buffer.write('<table border="1">');
828 response.write('<h1>Dart Analysis Server - Overlays</h1>'); 718 int count = 0;
829 response.write('<table border="1">'); 719 _overlayContents.clear();
830 int count = 0; 720 analysisServer.folderMap.forEach((_, AnalysisContextImpl context) {
831 _overlayContents.clear(); 721 context.visitContentCache(
832 analysisServer.folderMap.forEach((_, AnalysisContextImpl context) { 722 (Source source, int stamp, String contents) {
833 context.visitContentCache((Source source, int stamp, String contents) { 723 count++;
834 count++; 724 buffer.write('<tr>');
835 response.write('<tr>'); 725 String linkRef = '$OVERLAY_PATH?id=$count';
836 String linkRef = '$OVERLAY_PATH?id=$count'; 726 String linkText = HTML_ESCAPE.convert(source.toString());
837 String linkText = HTML_ESCAPE.convert(source.toString()); 727 buffer.write('<td><a href="$linkRef">$linkText</a></td>');
838 response.write('<td><a href="$linkRef">$linkText</a></td>'); 728 buffer.write(
839 response.write( 729 '<td>${new DateTime.fromMillisecondsSinceEpoch(stamp)}</td>');
840 '<td>${new DateTime.fromMillisecondsSinceEpoch(stamp)}</td>'); 730 buffer.write('</tr>');
841 response.write('</tr>'); 731 _overlayContents[count] = contents;
842 _overlayContents[count] = contents; 732 });
733 });
734 buffer.write('<tr><td colspan="2">Total: $count entries.</td></tr>');
735 buffer.write('</table>');
843 }); 736 });
844 }); 737 });
845 response.write('<tr><td colspan="2">Total: $count entries.</td></tr>');
846 response.write('</table>');
847 response.write('</body>');
848 response.write('</html>');
849 response.close();
850 } 738 }
851 739
852 /** 740 /**
853 * Return a response indicating the status of the analysis server. 741 * Return a response indicating the status of the analysis server.
854 */ 742 */
855 void _returnServerStatus(HttpRequest request) { 743 void _returnServerStatus(HttpRequest request) {
856 HttpResponse response = request.response;
857 response.statusCode = HttpStatus.OK;
858 response.headers.contentType = _htmlContent;
859 response.write('<html>');
860 response.write('<head>');
861 response.write('<title>Dart Analysis Server - Status</title>');
862 response.write('<style>');
863 response.write('td.right {text-align: right;}');
864 response.write('</style>');
865 response.write('</head>');
866 response.write('<body>');
867 response.write('<h1>Analysis Server</h1>');
868 AnalysisServer analysisServer = _server.analysisServer;
869 if (analysisServer == null) {
870 response.write('<p>Not running</p>');
871 } else {
872 if (analysisServer.statusAnalyzing) {
873 response.write('<p>Running (analyzing)</p>');
874 } else {
875 response.write('<p>Running (not analyzing)</p>');
876 }
877 response.write('<p>Instrumentation status: ');
878 if (AnalysisEngine.instance.instrumentationService.isActive) {
879 response.write('<span style="color:red">active</span>');
880 } else {
881 response.write('inactive');
882 }
883 response.write('</p>');
884 response.write('<h1>Analysis Contexts</h1>');
885 response.write('<h2>Summary</h2>');
886 response.write('<table>');
887 List headerRowText = ['Context'];
888 headerRowText.addAll(CacheState.values);
889 _writeRow(response, headerRowText, header: true);
890 Map<Folder, AnalysisContext> folderMap = analysisServer.folderMap;
891 List<Folder> folders = folderMap.keys.toList();
892 folders.sort(
893 (Folder first, Folder second) => first.shortName.compareTo(second.shor tName));
894 folders.forEach((Folder folder) {
895 AnalysisContextImpl context = folderMap[folder];
896 String key = folder.shortName;
897 AnalysisContextStatistics statistics = context.statistics;
898 Map<CacheState, int> totals = <CacheState, int>{};
899 for (CacheState state in CacheState.values) {
900 totals[state] = 0;
901 }
902 statistics.cacheRows.forEach((AnalysisContextStatistics_CacheRow row) {
903 for (CacheState state in CacheState.values) {
904 totals[state] += row.getCount(state);
905 }
906 });
907 List rowText = [
908 '<a href="#context_${HTML_ESCAPE.convert(key)}">$key</a>'];
909 for (CacheState state in CacheState.values) {
910 rowText.add(totals[state]);
911 }
912 _writeRow(response, rowText, classes: [null, "right"]);
913 });
914 response.write('</table>');
915 folders.forEach((Folder folder) {
916 AnalysisContextImpl context = folderMap[folder];
917 String key = folder.shortName;
918 response.write(
919 '<h2><a name="context_${HTML_ESCAPE.convert(key)}">Analysis Context: $key</a></h2>');
920 AnalysisContextStatistics statistics = context.statistics;
921 response.write('<table>');
922 _writeRow(response, headerRowText, header: true);
923 statistics.cacheRows.forEach((AnalysisContextStatistics_CacheRow row) {
924 List rowText = [row.name];
925 for (CacheState state in CacheState.values) {
926 String text = row.getCount(state).toString();
927 Map<String, String> params = <String, String>{
928 STATE_QUERY_PARAM: state.toString(),
929 CONTEXT_QUERY_PARAM: folder.path,
930 DESCRIPTOR_QUERY_PARAM: row.name
931 };
932 rowText.add(_makeLink(CACHE_STATE_PATH, params, text));
933 }
934 _writeRow(response, rowText, classes: [null, "right"]);
935 });
936 response.write('</table>');
937 List<CaughtException> exceptions = statistics.exceptions;
938 if (!exceptions.isEmpty) {
939 response.write('<h2>Exceptions</h2>');
940 exceptions.forEach((CaughtException exception) {
941 StringBuffer buffer = new StringBuffer();
942 _writeException(buffer, exception);
943 response.write(buffer.toString());
944 });
945 }
946 });
947 }
948 response.write('<h1>Most recent strings printed by analysis server</h2>');
949 response.write('<pre>');
950 response.write(HTML_ESCAPE.convert(_printBuffer.join('\n')));
951 response.write('</pre>');
952 response.write('</body>');
953 response.write('</html>');
954 response.close();
955 }
956
957 /**
958 * Return a response indicating the status of the analysis server.
959 */
960 void _returnServerStatus2(HttpRequest request) {
961 _writeResponse(request, (StringBuffer buffer) { 744 _writeResponse(request, (StringBuffer buffer) {
962 _writePage(buffer, 'Analysis Server - Status', [], (StringBuffer buffer) { 745 _writePage(buffer, 'Analysis Server - Status', [], (StringBuffer buffer) {
963 if (_writeServerStatus(buffer)) { 746 if (_writeServerStatus(buffer)) {
964 _writeAnalysisStatus(buffer); 747 _writeAnalysisStatus(buffer);
965 _writeEditStatus(buffer); 748 _writeEditStatus(buffer);
966 _writeExecutionStatus(buffer); 749 _writeExecutionStatus(buffer);
967 _writeRecentOutput(buffer); 750 _writeRecentOutput(buffer);
968 } 751 }
969 }); 752 });
970 }); 753 });
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1096 } 879 }
1097 } 880 }
1098 if (performance == null) { 881 if (performance == null) {
1099 buffer.write('<h3>Completion Performance Detail</h3>'); 882 buffer.write('<h3>Completion Performance Detail</h3>');
1100 buffer.write('<p>No completions yet</p>'); 883 buffer.write('<p>No completions yet</p>');
1101 return; 884 return;
1102 } 885 }
1103 buffer.write( 886 buffer.write(
1104 '<h3>Completion Performance Detail - ${performance.startTimeAndMs}</h3>' ); 887 '<h3>Completion Performance Detail - ${performance.startTimeAndMs}</h3>' );
1105 buffer.write('<table>'); 888 buffer.write('<table>');
1106 _writeRow2(buffer, ['Elapsed', '', 'Operation'], header: true); 889 _writeRow(buffer, ['Elapsed', '', 'Operation'], header: true);
1107 performance.operations.forEach((OperationPerformance op) { 890 performance.operations.forEach((OperationPerformance op) {
1108 String elapsed = op.elapsed != null ? op.elapsed.toString() : '???'; 891 String elapsed = op.elapsed != null ? op.elapsed.toString() : '???';
1109 _writeRow2(buffer, [elapsed, '&nbsp;&nbsp;', op.name]); 892 _writeRow(buffer, [elapsed, '&nbsp;&nbsp;', op.name]);
1110 }); 893 });
1111 if (handler.priorityChangedPerformance == null) { 894 if (handler.priorityChangedPerformance == null) {
1112 buffer.write('<p>No priorityChanged caching</p>'); 895 buffer.write('<p>No priorityChanged caching</p>');
1113 } else { 896 } else {
1114 int len = handler.priorityChangedPerformance.operations.length; 897 int len = handler.priorityChangedPerformance.operations.length;
1115 if (len > 0) { 898 if (len > 0) {
1116 var op = handler.priorityChangedPerformance.operations[len - 1]; 899 var op = handler.priorityChangedPerformance.operations[len - 1];
1117 if (op != null) { 900 if (op != null) {
1118 _writeRow2(buffer, ['&nbsp;', '&nbsp;', '&nbsp;']); 901 _writeRow(buffer, ['&nbsp;', '&nbsp;', '&nbsp;']);
1119 String elapsed = op.elapsed != null ? op.elapsed.toString() : '???'; 902 String elapsed = op.elapsed != null ? op.elapsed.toString() : '???';
1120 _writeRow2(buffer, [elapsed, '&nbsp;&nbsp;', op.name]); 903 _writeRow(buffer, [elapsed, '&nbsp;&nbsp;', op.name]);
1121 } 904 }
1122 } 905 }
1123 } 906 }
1124 buffer.write('</table>'); 907 buffer.write('</table>');
1125 } 908 }
1126 909
1127 /** 910 /**
1128 * Write a table showing summary information for the last several 911 * Write a table showing summary information for the last several
1129 * completion requests to the given [buffer] object. 912 * completion requests to the given [buffer] object.
1130 */ 913 */
1131 void _writeCompletionPerformanceList(StringBuffer buffer) { 914 void _writeCompletionPerformanceList(StringBuffer buffer) {
1132 CompletionDomainHandler handler = _completionDomainHandler; 915 CompletionDomainHandler handler = _completionDomainHandler;
1133 buffer.write('<h3>Completion Performance</h3>'); 916 buffer.write('<h3>Completion Performance</h3>');
1134 if (handler == null) { 917 if (handler == null) {
1135 return; 918 return;
1136 } 919 }
1137 buffer.write('<table>'); 920 buffer.write('<table>');
1138 _writeRow2( 921 _writeRow(
1139 buffer, 922 buffer,
1140 [ 923 [
1141 'Start Time', 924 'Start Time',
1142 '', 925 '',
1143 'First (ms)', 926 'First (ms)',
1144 '', 927 '',
1145 'Complete (ms)', 928 'Complete (ms)',
1146 '', 929 '',
1147 '# Notifications', 930 '# Notifications',
1148 '', 931 '',
1149 '# Suggestions', 932 '# Suggestions',
1150 '', 933 '',
1151 'Snippet'], 934 'Snippet'],
1152 header: true); 935 header: true);
1153 int index = 0; 936 int index = 0;
1154 for (CompletionPerformance performance in handler.performanceList) { 937 for (CompletionPerformance performance in handler.performanceList) {
1155 String link = _makeLink(COMPLETION_PATH, { 938 String link = _makeLink(COMPLETION_PATH, {
1156 'index': '$index' 939 'index': '$index'
1157 }, '${performance.startTimeAndMs}'); 940 }, '${performance.startTimeAndMs}');
1158 _writeRow2( 941 _writeRow(
1159 buffer, 942 buffer,
1160 [ 943 [
1161 link, 944 link,
1162 '&nbsp;&nbsp;', 945 '&nbsp;&nbsp;',
1163 performance.firstNotificationInMilliseconds, 946 performance.firstNotificationInMilliseconds,
1164 '&nbsp;&nbsp;', 947 '&nbsp;&nbsp;',
1165 performance.elapsedInMilliseconds, 948 performance.elapsedInMilliseconds,
1166 '&nbsp;&nbsp;', 949 '&nbsp;&nbsp;',
1167 performance.notificationCount, 950 performance.notificationCount,
1168 '&nbsp;&nbsp;', 951 '&nbsp;&nbsp;',
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
1397 _writeException(buffer, new CaughtException(exception, stackTrace)); 1180 _writeException(buffer, new CaughtException(exception, stackTrace));
1398 }); 1181 });
1399 } 1182 }
1400 response.write(buffer.toString()); 1183 response.write(buffer.toString());
1401 } finally { 1184 } finally {
1402 response.close(); 1185 response.close();
1403 } 1186 }
1404 } 1187 }
1405 1188
1406 /** 1189 /**
1407 * Write a single row within a table to the given [response] object. The row
1408 * will have one cell for each of the [columns], and will be a header row if
1409 * [header] is `true`.
1410 */
1411 void _writeRow(HttpResponse response, List<Object> columns, {bool header:
1412 false, List<String> classes}) {
1413 response.write('<tr>');
1414 int count = columns.length;
1415 int maxClassIndex = classes == null ? 0 : classes.length - 1;
1416 for (int i = 0; i < count; i++) {
1417 String classAttribute = '';
1418 if (classes != null) {
1419 String className = classes[min(i, maxClassIndex)];
1420 if (className != null) {
1421 classAttribute = ' class="$className"';
1422 }
1423 }
1424 if (header) {
1425 response.write('<th$classAttribute>');
1426 } else {
1427 response.write('<td$classAttribute>');
1428 }
1429 response.write(columns[i]);
1430 if (header) {
1431 response.write('</th>');
1432 } else {
1433 response.write('</td>');
1434 }
1435 }
1436
1437 response.write('</tr>');
1438 }
1439
1440 /**
1441 * Write a single row within a table to the given [buffer]. The row will have 1190 * Write a single row within a table to the given [buffer]. The row will have
1442 * one cell for each of the [columns], and will be a header row if [header] is 1191 * one cell for each of the [columns], and will be a header row if [header] is
1443 * `true`. 1192 * `true`.
1444 */ 1193 */
1445 void _writeRow2(StringBuffer buffer, List<Object> columns, {bool header: 1194 void _writeRow(StringBuffer buffer, List<Object> columns, {bool header:
1446 false, List<String> classes}) { 1195 false, List<String> classes}) {
1447 buffer.write('<tr>'); 1196 buffer.write('<tr>');
1448 int count = columns.length; 1197 int count = columns.length;
1449 int maxClassIndex = classes == null ? 0 : classes.length - 1; 1198 int maxClassIndex = classes == null ? 0 : classes.length - 1;
1450 for (int i = 0; i < count; i++) { 1199 for (int i = 0; i < count; i++) {
1451 String classAttribute = ''; 1200 String classAttribute = '';
1452 if (classes != null) { 1201 if (classes != null) {
1453 String className = classes[min(i, maxClassIndex)]; 1202 String className = classes[min(i, maxClassIndex)];
1454 if (className != null) { 1203 if (className != null) {
1455 classAttribute = ' class="$className"'; 1204 classAttribute = ' class="$className"';
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
1628 } else if (value is Element) { 1377 } else if (value is Element) {
1629 String link = 1378 String link =
1630 _makeLink(ELEMENT_PATH, linkParameters, value.runtimeType.toString()); 1379 _makeLink(ELEMENT_PATH, linkParameters, value.runtimeType.toString());
1631 buffer.write('<i>$link</i>'); 1380 buffer.write('<i>$link</i>');
1632 } else { 1381 } else {
1633 buffer.write(HTML_ESCAPE.convert(value.toString())); 1382 buffer.write(HTML_ESCAPE.convert(value.toString()));
1634 buffer.write(' <i>(${value.runtimeType.toString()})</i>'); 1383 buffer.write(' <i>(${value.runtimeType.toString()})</i>');
1635 } 1384 }
1636 } 1385 }
1637 } 1386 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698