| 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 |