OLD | NEW |
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.status.get_handler; | 5 library analysis_server.src.status.get_handler; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:collection'; | 8 import 'dart:collection'; |
9 import 'dart:convert'; | 9 import 'dart:convert'; |
10 import 'dart:io'; | 10 import 'dart:io'; |
(...skipping 10 matching lines...) Expand all Loading... |
21 import 'package:analysis_server/src/services/index/local_index.dart'; | 21 import 'package:analysis_server/src/services/index/local_index.dart'; |
22 import 'package:analysis_server/src/services/index/store/split_store.dart'; | 22 import 'package:analysis_server/src/services/index/store/split_store.dart'; |
23 import 'package:analysis_server/src/socket_server.dart'; | 23 import 'package:analysis_server/src/socket_server.dart'; |
24 import 'package:analysis_server/src/status/ast_writer.dart'; | 24 import 'package:analysis_server/src/status/ast_writer.dart'; |
25 import 'package:analysis_server/src/status/element_writer.dart'; | 25 import 'package:analysis_server/src/status/element_writer.dart'; |
26 import 'package:analyzer/file_system/file_system.dart'; | 26 import 'package:analyzer/file_system/file_system.dart'; |
27 import 'package:analyzer/src/context/cache.dart'; | 27 import 'package:analyzer/src/context/cache.dart'; |
28 import 'package:analyzer/src/generated/ast.dart'; | 28 import 'package:analyzer/src/generated/ast.dart'; |
29 import 'package:analyzer/src/generated/element.dart'; | 29 import 'package:analyzer/src/generated/element.dart'; |
30 import 'package:analyzer/src/generated/engine.dart' | 30 import 'package:analyzer/src/generated/engine.dart' |
31 hide AnalysisContextImpl, AnalysisTask; | 31 hide AnalysisCache, AnalysisContextImpl, AnalysisTask; |
32 import 'package:analyzer/src/generated/java_engine.dart'; | 32 import 'package:analyzer/src/generated/java_engine.dart'; |
33 import 'package:analyzer/src/generated/source.dart'; | 33 import 'package:analyzer/src/generated/source.dart'; |
34 import 'package:analyzer/src/generated/utilities_collection.dart'; | 34 import 'package:analyzer/src/generated/utilities_collection.dart'; |
35 import 'package:analyzer/src/generated/utilities_general.dart'; | 35 import 'package:analyzer/src/generated/utilities_general.dart'; |
36 import 'package:analyzer/src/task/dart.dart'; | 36 import 'package:analyzer/src/task/dart.dart'; |
| 37 import 'package:analyzer/src/task/html.dart'; |
37 import 'package:analyzer/task/dart.dart'; | 38 import 'package:analyzer/task/dart.dart'; |
| 39 import 'package:analyzer/task/general.dart'; |
| 40 import 'package:analyzer/task/html.dart'; |
38 import 'package:analyzer/task/model.dart'; | 41 import 'package:analyzer/task/model.dart'; |
39 import 'package:plugin/plugin.dart'; | 42 import 'package:plugin/plugin.dart'; |
40 | 43 |
41 /** | 44 /** |
42 * A function that can be used to generate HTML output into the given [buffer]. | 45 * A function that can be used to generate HTML output into the given [buffer]. |
43 * The HTML that is generated must be valid (special characters must already be | 46 * The HTML that is generated must be valid (special characters must already be |
44 * encoded). | 47 * encoded). |
45 */ | 48 */ |
46 typedef void HtmlGenerator(StringBuffer buffer); | 49 typedef void HtmlGenerator(StringBuffer buffer); |
47 | 50 |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 return unit; | 267 return unit; |
265 } | 268 } |
266 unit = entry.getValue(RESOLVED_UNIT8); | 269 unit = entry.getValue(RESOLVED_UNIT8); |
267 if (unit != null) { | 270 if (unit != null) { |
268 return unit; | 271 return unit; |
269 } | 272 } |
270 return entry.getValue(RESOLVED_UNIT); | 273 return entry.getValue(RESOLVED_UNIT); |
271 } | 274 } |
272 | 275 |
273 /** | 276 /** |
| 277 * Return a list of the result descriptors whose state should be displayed for |
| 278 * the given cache [entry]. |
| 279 */ |
| 280 List<ResultDescriptor> _getExpectedResults(CacheEntry entry) { |
| 281 AnalysisTarget target = entry.target; |
| 282 Set<ResultDescriptor> results = entry.nonInvalidResults.toSet(); |
| 283 if (target is Source) { |
| 284 String name = target.shortName; |
| 285 results.add(CONTENT); |
| 286 results.add(LINE_INFO); |
| 287 results.add(MODIFICATION_TIME); |
| 288 if (AnalysisEngine.isDartFileName(name)) { |
| 289 results.add(BUILD_DIRECTIVES_ERRORS); |
| 290 results.add(BUILD_LIBRARY_ERRORS); |
| 291 results.add(CONTAINING_LIBRARIES); |
| 292 results.add(DART_ERRORS); |
| 293 results.add(EXPLICITLY_IMPORTED_LIBRARIES); |
| 294 results.add(EXPORT_SOURCE_CLOSURE); |
| 295 results.add(EXPORTED_LIBRARIES); |
| 296 results.add(IMPORT_EXPORT_SOURCE_CLOSURE); |
| 297 results.add(IMPORTED_LIBRARIES); |
| 298 results.add(INCLUDED_PARTS); |
| 299 results.add(IS_CLIENT); |
| 300 results.add(IS_LAUNCHABLE); |
| 301 results.add(LIBRARY_ELEMENT1); |
| 302 results.add(LIBRARY_ELEMENT2); |
| 303 results.add(LIBRARY_ELEMENT3); |
| 304 results.add(LIBRARY_ELEMENT4); |
| 305 results.add(LIBRARY_ELEMENT5); |
| 306 results.add(LIBRARY_ELEMENT); |
| 307 results.add(LIBRARY_ERRORS_READY); |
| 308 results.add(PARSE_ERRORS); |
| 309 results.add(PARSED_UNIT); |
| 310 results.add(REFERENCED_NAMES); |
| 311 results.add(SCAN_ERRORS); |
| 312 results.add(SOURCE_KIND); |
| 313 results.add(TOKEN_STREAM); |
| 314 results.add(UNITS); |
| 315 } else if (AnalysisEngine.isHtmlFileName(name)) { |
| 316 results.add(DART_SCRIPTS); |
| 317 results.add(HTML_DOCUMENT); |
| 318 results.add(HTML_DOCUMENT_ERRORS); |
| 319 results.add(HTML_ERRORS); |
| 320 results.add(REFERENCED_LIBRARIES); |
| 321 } |
| 322 } else if (target is LibrarySpecificUnit) { |
| 323 results.add(COMPILATION_UNIT_CONSTANTS); |
| 324 results.add(COMPILATION_UNIT_ELEMENT); |
| 325 results.add(HINTS); |
| 326 results.add(INFER_STATIC_VARIABLE_TYPES_ERRORS); |
| 327 results.add(INFERABLE_STATIC_VARIABLES_IN_UNIT); |
| 328 results.add(LIBRARY_UNIT_ERRORS); |
| 329 results.add(PARTIALLY_RESOLVE_REFERENCES_ERRORS); |
| 330 results.add(RESOLVE_FUNCTION_BODIES_ERRORS); |
| 331 results.add(RESOLVE_TYPE_NAMES_ERRORS); |
| 332 results.add(RESOLVED_UNIT1); |
| 333 results.add(RESOLVED_UNIT2); |
| 334 results.add(RESOLVED_UNIT3); |
| 335 results.add(RESOLVED_UNIT4); |
| 336 results.add(RESOLVED_UNIT5); |
| 337 results.add(RESOLVED_UNIT6); |
| 338 results.add(RESOLVED_UNIT7); |
| 339 results.add(RESOLVED_UNIT8); |
| 340 results.add(RESOLVED_UNIT); |
| 341 results.add(USED_IMPORTED_ELEMENTS); |
| 342 results.add(USED_LOCAL_ELEMENTS); |
| 343 results.add(VARIABLE_REFERENCE_ERRORS); |
| 344 results.add(VERIFY_ERRORS); |
| 345 } else if (target is ConstantEvaluationTarget) { |
| 346 results.add(CONSTANT_DEPENDENCIES); |
| 347 results.add(CONSTANT_VALUE); |
| 348 if (target is VariableElement) { |
| 349 results.add(INFER_STATIC_VARIABLE_ERRORS); |
| 350 results.add(INFERABLE_STATIC_VARIABLE_DEPENDENCIES); |
| 351 results.add(INFERRED_STATIC_VARIABLE); |
| 352 } |
| 353 } else if (target is AnalysisContextTarget) { |
| 354 results.add(TYPE_PROVIDER); |
| 355 } |
| 356 return results.toList(); |
| 357 } |
| 358 |
| 359 /** |
274 * Return `true` if the given analysis [context] has at least one entry with | 360 * Return `true` if the given analysis [context] has at least one entry with |
275 * an exception. | 361 * an exception. |
276 */ | 362 */ |
277 bool _hasException(InternalAnalysisContext context) { | 363 bool _hasException(InternalAnalysisContext context) { |
278 MapIterator<AnalysisTarget, CacheEntry> iterator = | 364 MapIterator<AnalysisTarget, CacheEntry> iterator = |
279 context.analysisCache.iterator(); | 365 context.analysisCache.iterator(); |
280 while (iterator.moveNext()) { | 366 while (iterator.moveNext()) { |
281 if (iterator.value.exception != null) { | 367 if (iterator.value.exception != null) { |
282 return true; | 368 return true; |
283 } | 369 } |
(...skipping 20 matching lines...) Expand all Loading... |
304 */ | 390 */ |
305 void _returnAnalysisPerformance(HttpRequest request) { | 391 void _returnAnalysisPerformance(HttpRequest request) { |
306 AnalysisServer analysisServer = _server.analysisServer; | 392 AnalysisServer analysisServer = _server.analysisServer; |
307 if (analysisServer == null) { | 393 if (analysisServer == null) { |
308 return _returnFailure(request, 'Analysis server is not running'); | 394 return _returnFailure(request, 'Analysis server is not running'); |
309 } | 395 } |
310 _writeResponse(request, (StringBuffer buffer) { | 396 _writeResponse(request, (StringBuffer buffer) { |
311 _writePage(buffer, 'Analysis Server - Analysis Performance', [], | 397 _writePage(buffer, 'Analysis Server - Analysis Performance', [], |
312 (StringBuffer buffer) { | 398 (StringBuffer buffer) { |
313 buffer.write('<h3>Analysis Performance</h3>'); | 399 buffer.write('<h3>Analysis Performance</h3>'); |
314 // | 400 _writeTwoColumns(buffer, (StringBuffer buffer) { |
315 // Write performance tags. | 401 // |
316 // | 402 // Write performance tags. |
317 buffer.write('<p><b>Performance tag data</b></p>'); | 403 // |
318 buffer.write( | 404 buffer.write('<p><b>Performance tag data</b></p>'); |
319 '<table style="border-collapse: separate; border-spacing: 10px 5px;"
>'); | 405 buffer.write( |
320 _writeRow(buffer, ['Time (in ms)', 'Percent', 'Tag name'], | 406 '<table style="border-collapse: separate; border-spacing: 10px 5px
;">'); |
321 header: true); | 407 _writeRow(buffer, ['Time (in ms)', 'Percent', 'Tag name'], |
322 // prepare sorted tags | 408 header: true); |
323 List<PerformanceTag> tags = PerformanceTag.all.toList(); | 409 // prepare sorted tags |
324 tags.remove(ServerPerformanceStatistics.idle); | 410 List<PerformanceTag> tags = PerformanceTag.all.toList(); |
325 tags.sort((a, b) => b.elapsedMs - a.elapsedMs); | 411 tags.remove(ServerPerformanceStatistics.idle); |
326 // prepare total time | 412 tags.sort((a, b) => b.elapsedMs - a.elapsedMs); |
327 int totalTagTime = 0; | 413 // prepare total time |
328 tags.forEach((PerformanceTag tag) { | 414 int totalTagTime = 0; |
329 totalTagTime += tag.elapsedMs; | 415 tags.forEach((PerformanceTag tag) { |
| 416 totalTagTime += tag.elapsedMs; |
| 417 }); |
| 418 // write rows |
| 419 void writeRow(PerformanceTag tag) { |
| 420 double percent = (tag.elapsedMs * 100) / totalTagTime; |
| 421 String percentStr = '${percent.toStringAsFixed(2)}%'; |
| 422 _writeRow(buffer, [tag.elapsedMs, percentStr, tag.label], |
| 423 classes: ["right", "right", null]); |
| 424 } |
| 425 tags.forEach(writeRow); |
| 426 buffer.write('</table>'); |
| 427 // |
| 428 // Write target counts. |
| 429 // |
| 430 void incrementCount(Map<String, int> counts, String key) { |
| 431 int count = counts[key]; |
| 432 if (count == null) { |
| 433 count = 1; |
| 434 } else { |
| 435 count++; |
| 436 } |
| 437 counts[key] = count; |
| 438 } |
| 439 Set<AnalysisTarget> countedTargets = new HashSet<AnalysisTarget>(); |
| 440 Map<String, int> sourceTypeCounts = new HashMap<String, int>(); |
| 441 Map<String, int> typeCounts = new HashMap<String, int>(); |
| 442 analysisServer.folderMap |
| 443 .forEach((Folder folder, InternalAnalysisContext context) { |
| 444 AnalysisCache cache = context.analysisCache; |
| 445 MapIterator<AnalysisTarget, CacheEntry> iterator = cache.iterator(); |
| 446 while (iterator.moveNext()) { |
| 447 AnalysisTarget target = iterator.key; |
| 448 if (countedTargets.add(target)) { |
| 449 if (target is Source) { |
| 450 String name = target.fullName; |
| 451 String sourceName; |
| 452 if (AnalysisEngine.isDartFileName(name)) { |
| 453 if (iterator.value.explicitlyAdded) { |
| 454 sourceName = 'Dart file (explicit)'; |
| 455 } else { |
| 456 sourceName = 'Dart file (implicit)'; |
| 457 } |
| 458 } else if (AnalysisEngine.isHtmlFileName(name)) { |
| 459 if (iterator.value.explicitlyAdded) { |
| 460 sourceName = 'Html file (explicit)'; |
| 461 } else { |
| 462 sourceName = 'Html file (implicit)'; |
| 463 } |
| 464 } else { |
| 465 if (iterator.value.explicitlyAdded) { |
| 466 sourceName = 'Unknown file (explicit)'; |
| 467 } else { |
| 468 sourceName = 'Unknown file (implicit)'; |
| 469 } |
| 470 } |
| 471 incrementCount(sourceTypeCounts, sourceName); |
| 472 } else if (target is ConstantEvaluationTarget) { |
| 473 incrementCount(typeCounts, 'ConstantEvaluationTarget'); |
| 474 } else { |
| 475 String typeName = target.runtimeType.toString(); |
| 476 incrementCount(typeCounts, typeName); |
| 477 } |
| 478 } |
| 479 } |
| 480 }); |
| 481 List<String> sourceTypeNames = sourceTypeCounts.keys.toList(); |
| 482 sourceTypeNames.sort(); |
| 483 List<String> typeNames = typeCounts.keys.toList(); |
| 484 typeNames.sort(); |
| 485 |
| 486 buffer.write('<p><b>Target counts</b></p>'); |
| 487 buffer.write( |
| 488 '<table style="border-collapse: separate; border-spacing: 10px 5px
;">'); |
| 489 _writeRow(buffer, ['Target', 'Count'], header: true); |
| 490 for (String sourceTypeName in sourceTypeNames) { |
| 491 _writeRow( |
| 492 buffer, [sourceTypeName, sourceTypeCounts[sourceTypeName]], |
| 493 classes: [null, "right"]); |
| 494 } |
| 495 for (String typeName in typeNames) { |
| 496 _writeRow(buffer, [typeName, typeCounts[typeName]], |
| 497 classes: [null, "right"]); |
| 498 } |
| 499 buffer.write('</table>'); |
| 500 }, (StringBuffer buffer) { |
| 501 // |
| 502 // Write task model timing information. |
| 503 // |
| 504 buffer.write('<p><b>Task performace data</b></p>'); |
| 505 buffer.write( |
| 506 '<table style="border-collapse: separate; border-spacing: 10px 5px
;">'); |
| 507 _writeRow( |
| 508 buffer, |
| 509 [ |
| 510 'Task Name', |
| 511 'Count', |
| 512 'Total Time (in ms)', |
| 513 'Average Time (in ms)' |
| 514 ], |
| 515 header: true); |
| 516 |
| 517 Map<Type, int> countMap = AnalysisTask.countMap; |
| 518 Map<Type, Stopwatch> stopwatchMap = AnalysisTask.stopwatchMap; |
| 519 List<Type> taskClasses = stopwatchMap.keys.toList(); |
| 520 taskClasses.sort((Type first, Type second) => |
| 521 first.toString().compareTo(second.toString())); |
| 522 int totalTaskTime = 0; |
| 523 taskClasses.forEach((Type taskClass) { |
| 524 int count = countMap[taskClass]; |
| 525 if (count == null) { |
| 526 count = 0; |
| 527 } |
| 528 int taskTime = stopwatchMap[taskClass].elapsedMilliseconds; |
| 529 totalTaskTime += taskTime; |
| 530 _writeRow(buffer, [ |
| 531 taskClass.toString(), |
| 532 count, |
| 533 taskTime, |
| 534 count <= 0 ? '-' : (taskTime / count).toStringAsFixed(3) |
| 535 ], classes: [ |
| 536 null, |
| 537 "right", |
| 538 "right", |
| 539 "right" |
| 540 ]); |
| 541 }); |
| 542 _writeRow(buffer, ['Total', '-', totalTaskTime, '-'], |
| 543 classes: [null, "right", "right", "right"]); |
| 544 buffer.write('</table>'); |
330 }); | 545 }); |
331 // write rows | |
332 void writeRow(PerformanceTag tag) { | |
333 double percent = (tag.elapsedMs * 100) / totalTagTime; | |
334 String percentStr = '${percent.toStringAsFixed(2)}%'; | |
335 _writeRow(buffer, [tag.elapsedMs, percentStr, tag.label], | |
336 classes: ["right", "right", null]); | |
337 } | |
338 tags.forEach(writeRow); | |
339 buffer.write('</table>'); | |
340 // | |
341 // Write task model timing information. | |
342 // | |
343 buffer.write('<p><b>Task performace data</b></p>'); | |
344 buffer.write( | |
345 '<table style="border-collapse: separate; border-spacing: 10px 5px;"
>'); | |
346 _writeRow( | |
347 buffer, | |
348 [ | |
349 'Task Name', | |
350 'Count', | |
351 'Total Time (in ms)', | |
352 'Average Time (in ms)' | |
353 ], | |
354 header: true); | |
355 | |
356 Map<Type, int> countMap = AnalysisTask.countMap; | |
357 Map<Type, Stopwatch> stopwatchMap = AnalysisTask.stopwatchMap; | |
358 List<Type> taskClasses = stopwatchMap.keys.toList(); | |
359 taskClasses.sort((Type first, Type second) => | |
360 first.toString().compareTo(second.toString())); | |
361 int totalTaskTime = 0; | |
362 taskClasses.forEach((Type taskClass) { | |
363 int count = countMap[taskClass]; | |
364 if (count == null) { | |
365 count = 0; | |
366 } | |
367 int taskTime = stopwatchMap[taskClass].elapsedMilliseconds; | |
368 totalTaskTime += taskTime; | |
369 _writeRow(buffer, [ | |
370 taskClass.toString(), | |
371 count, | |
372 taskTime, | |
373 count <= 0 ? '-' : (taskTime / count).toStringAsFixed(3) | |
374 ], classes: [ | |
375 null, | |
376 "right", | |
377 "right", | |
378 "right" | |
379 ]); | |
380 }); | |
381 _writeRow(buffer, ['Total', '-', totalTaskTime, '-'], | |
382 classes: [null, "right", "right", "right"]); | |
383 buffer.write('</table>'); | |
384 }); | 546 }); |
385 }); | 547 }); |
386 } | 548 } |
387 | 549 |
388 /** | 550 /** |
389 * Return a response containing information about an AST structure. | 551 * Return a response containing information about an AST structure. |
390 */ | 552 */ |
391 void _returnAst(HttpRequest request) { | 553 void _returnAst(HttpRequest request) { |
392 AnalysisServer analysisServer = _server.analysisServer; | 554 AnalysisServer analysisServer = _server.analysisServer; |
393 if (analysisServer == null) { | 555 if (analysisServer == null) { |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
510 buffer.write(folder.path); | 672 buffer.write(folder.path); |
511 } else { | 673 } else { |
512 buffer.write(makeLink( | 674 buffer.write(makeLink( |
513 CACHE_ENTRY_PATH, | 675 CACHE_ENTRY_PATH, |
514 { | 676 { |
515 CONTEXT_QUERY_PARAM: folder.path, | 677 CONTEXT_QUERY_PARAM: folder.path, |
516 SOURCE_QUERY_PARAM: sourceUri | 678 SOURCE_QUERY_PARAM: sourceUri |
517 }, | 679 }, |
518 HTML_ESCAPE.convert(folder.path))); | 680 HTML_ESCAPE.convert(folder.path))); |
519 } | 681 } |
520 CacheEntry sourceEntry = | 682 if (entries == null) { |
521 entries.firstWhere((CacheEntry entry) => entry.target is Source); | 683 buffer.write(' (file does not exist)'); |
522 if (sourceEntry == null) { | |
523 buffer.write(' (missing source entry)'); | |
524 } else if (sourceEntry.explicitlyAdded) { | |
525 buffer.write(' (explicit)'); | |
526 } else { | 684 } else { |
527 buffer.write(' (implicit)'); | 685 CacheEntry sourceEntry = entries |
| 686 .firstWhere((CacheEntry entry) => entry.target is Source); |
| 687 if (sourceEntry == null) { |
| 688 buffer.write(' (missing source entry)'); |
| 689 } else if (sourceEntry.explicitlyAdded) { |
| 690 buffer.write(' (explicit)'); |
| 691 } else { |
| 692 buffer.write(' (implicit)'); |
| 693 } |
528 } | 694 } |
529 }); | 695 }); |
530 buffer.write('</p>'); | 696 buffer.write('</p>'); |
531 | 697 |
532 if (entries == null) { | 698 if (entries == null) { |
533 buffer.write('<p>Not being analyzed in this context.</p>'); | 699 buffer.write('<p>Not being analyzed in this context.</p>'); |
534 return; | 700 return; |
535 } | 701 } |
536 for (CacheEntry entry in entries) { | 702 for (CacheEntry entry in entries) { |
537 Map<String, String> linkParameters = <String, String>{ | 703 Map<String, String> linkParameters = <String, String>{ |
538 CONTEXT_QUERY_PARAM: folder.path, | 704 CONTEXT_QUERY_PARAM: folder.path, |
539 SOURCE_QUERY_PARAM: sourceUri | 705 SOURCE_QUERY_PARAM: sourceUri |
540 }; | 706 }; |
541 List<ResultDescriptor> results = entry.nonInvalidResults; | 707 List<ResultDescriptor> results = _getExpectedResults(entry); |
542 results.sort((ResultDescriptor first, ResultDescriptor second) => | 708 results.sort((ResultDescriptor first, ResultDescriptor second) => |
543 first.toString().compareTo(second.toString())); | 709 first.toString().compareTo(second.toString())); |
544 | 710 |
545 buffer.write('<h3>'); | 711 buffer.write('<h3>'); |
546 buffer.write(HTML_ESCAPE.convert(entry.target.toString())); | 712 buffer.write(HTML_ESCAPE.convert(entry.target.toString())); |
547 buffer.write('</h3>'); | 713 buffer.write('</h3>'); |
548 buffer.write('<dl>'); | 714 buffer.write('<dl>'); |
549 buffer.write('<dt>time</dt><dd>'); | 715 buffer.write('<dt>time</dt><dd>'); |
550 buffer.write(entry.modificationTime); | 716 buffer.write(entry.modificationTime); |
551 buffer.write('</dd>'); | 717 buffer.write('</dd>'); |
552 for (ResultDescriptor result in results) { | 718 for (ResultDescriptor result in results) { |
553 ResultData data = entry.getResultData(result); | 719 CacheState state = entry.getState(result); |
554 String descriptorName = HTML_ESCAPE.convert(result.toString()); | 720 String descriptorName = HTML_ESCAPE.convert(result.toString()); |
555 String descriptorState = HTML_ESCAPE.convert(data.state.toString()); | 721 String descriptorState = HTML_ESCAPE.convert(state.toString()); |
556 buffer.write('<dt>$descriptorName ($descriptorState)</dt><dd>'); | 722 buffer.write('<dt>$descriptorName ($descriptorState)</dt><dd>'); |
557 try { | 723 if (state == CacheState.VALID) { |
558 _writeValueAsHtml(buffer, data.value, linkParameters); | 724 try { |
559 } catch (exception) { | 725 _writeValueAsHtml(buffer, entry.getValue(result), linkParameters
); |
560 buffer.write('(${HTML_ESCAPE.convert(exception.toString())})'); | 726 } catch (exception) { |
| 727 buffer.write('(${HTML_ESCAPE.convert(exception.toString())})'); |
| 728 } |
561 } | 729 } |
562 buffer.write('</dd>'); | 730 buffer.write('</dd>'); |
563 } | 731 } |
564 if (entry.exception != null) { | 732 if (entry.exception != null) { |
565 buffer.write('<dt>exception</dt><dd>'); | 733 buffer.write('<dt>exception</dt><dd>'); |
566 _writeException(buffer, entry.exception); | 734 _writeException(buffer, entry.exception); |
567 buffer.write('</dd>'); | 735 buffer.write('</dd>'); |
568 } | 736 } |
569 buffer.write('</dl>'); | 737 buffer.write('</dl>'); |
570 } | 738 } |
(...skipping 1068 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1639 */ | 1807 */ |
1640 static String makeLink( | 1808 static String makeLink( |
1641 String path, Map<String, String> params, String innerHtml, | 1809 String path, Map<String, String> params, String innerHtml, |
1642 [bool hasError = false]) { | 1810 [bool hasError = false]) { |
1643 Uri uri = new Uri(path: path, queryParameters: params); | 1811 Uri uri = new Uri(path: path, queryParameters: params); |
1644 String href = HTML_ESCAPE.convert(uri.toString()); | 1812 String href = HTML_ESCAPE.convert(uri.toString()); |
1645 String classAttribute = hasError ? ' class="error"' : ''; | 1813 String classAttribute = hasError ? ' class="error"' : ''; |
1646 return '<a href="$href"$classAttribute>$innerHtml</a>'; | 1814 return '<a href="$href"$classAttribute>$innerHtml</a>'; |
1647 } | 1815 } |
1648 } | 1816 } |
OLD | NEW |