| 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 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 /** | 172 /** |
| 173 * Return the active [CompletionDomainHandler] | 173 * Return the active [CompletionDomainHandler] |
| 174 * or `null` if either analysis server is not running | 174 * or `null` if either analysis server is not running |
| 175 * or there is no completion domain handler. | 175 * or there is no completion domain handler. |
| 176 */ | 176 */ |
| 177 CompletionDomainHandler get _completionDomainHandler { | 177 CompletionDomainHandler get _completionDomainHandler { |
| 178 AnalysisServer analysisServer = _server.analysisServer; | 178 AnalysisServer analysisServer = _server.analysisServer; |
| 179 if (analysisServer == null) { | 179 if (analysisServer == null) { |
| 180 return null; | 180 return null; |
| 181 } | 181 } |
| 182 return analysisServer.handlers.firstWhere( | 182 return analysisServer.handlers |
| 183 (h) => h is CompletionDomainHandler, orElse: () => null); | 183 .firstWhere((h) => h is CompletionDomainHandler, orElse: () => null); |
| 184 } | 184 } |
| 185 | 185 |
| 186 /** | 186 /** |
| 187 * Handle a GET request received by the HTTP server. | 187 * Handle a GET request received by the HTTP server. |
| 188 */ | 188 */ |
| 189 void handleGetRequest(HttpRequest request) { | 189 void handleGetRequest(HttpRequest request) { |
| 190 String path = request.uri.path; | 190 String path = request.uri.path; |
| 191 if (path == STATUS_PATH) { | 191 if (path == STATUS_PATH) { |
| 192 _returnServerStatus(request); | 192 _returnServerStatus(request); |
| 193 } else if (path == ANALYSIS_PERFORMANCE_PATH) { | 193 } else if (path == ANALYSIS_PERFORMANCE_PATH) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 216 _returnUnknownRequest(request); | 216 _returnUnknownRequest(request); |
| 217 } | 217 } |
| 218 } | 218 } |
| 219 | 219 |
| 220 /** | 220 /** |
| 221 * Return the folder being managed by the given [analysisServer] that matches | 221 * Return the folder being managed by the given [analysisServer] that matches |
| 222 * the given [contextFilter], or `null` if there is none. | 222 * the given [contextFilter], or `null` if there is none. |
| 223 */ | 223 */ |
| 224 Folder _findFolder(AnalysisServer analysisServer, String contextFilter) { | 224 Folder _findFolder(AnalysisServer analysisServer, String contextFilter) { |
| 225 return analysisServer.folderMap.keys.firstWhere( | 225 return analysisServer.folderMap.keys.firstWhere( |
| 226 (Folder folder) => folder.path == contextFilter, orElse: () => null); | 226 (Folder folder) => folder.path == contextFilter, |
| 227 orElse: () => null); |
| 227 } | 228 } |
| 228 | 229 |
| 229 /** | 230 /** |
| 230 * Return any AST structure stored in the given [entry]. | 231 * Return any AST structure stored in the given [entry]. |
| 231 */ | 232 */ |
| 232 CompilationUnit _getAnyAst(CacheEntry entry) { | 233 CompilationUnit _getAnyAst(CacheEntry entry) { |
| 233 CompilationUnit unit = entry.getValue(PARSED_UNIT); | 234 CompilationUnit unit = entry.getValue(PARSED_UNIT); |
| 234 if (unit != null) { | 235 if (unit != null) { |
| 235 return unit; | 236 return unit; |
| 236 } | 237 } |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 classes: ["right", "right", null]); | 336 classes: ["right", "right", null]); |
| 336 } | 337 } |
| 337 tags.forEach(writeRow); | 338 tags.forEach(writeRow); |
| 338 buffer.write('</table>'); | 339 buffer.write('</table>'); |
| 339 // | 340 // |
| 340 // Write task model timing information. | 341 // Write task model timing information. |
| 341 // | 342 // |
| 342 buffer.write('<p><b>Task performace data</b></p>'); | 343 buffer.write('<p><b>Task performace data</b></p>'); |
| 343 buffer.write( | 344 buffer.write( |
| 344 '<table style="border-collapse: separate; border-spacing: 10px 5px;"
>'); | 345 '<table style="border-collapse: separate; border-spacing: 10px 5px;"
>'); |
| 345 _writeRow(buffer, [ | 346 _writeRow( |
| 346 'Task Name', | 347 buffer, |
| 347 'Count', | 348 [ |
| 348 'Total Time (in ms)', | 349 'Task Name', |
| 349 'Average Time (in ms)' | 350 'Count', |
| 350 ], header: true); | 351 'Total Time (in ms)', |
| 352 'Average Time (in ms)' |
| 353 ], |
| 354 header: true); |
| 351 | 355 |
| 352 Map<Type, int> countMap = AnalysisTask.countMap; | 356 Map<Type, int> countMap = AnalysisTask.countMap; |
| 353 Map<Type, Stopwatch> stopwatchMap = AnalysisTask.stopwatchMap; | 357 Map<Type, Stopwatch> stopwatchMap = AnalysisTask.stopwatchMap; |
| 354 List<Type> taskClasses = stopwatchMap.keys.toList(); | 358 List<Type> taskClasses = stopwatchMap.keys.toList(); |
| 355 taskClasses.sort((Type first, Type second) => | 359 taskClasses.sort((Type first, Type second) => |
| 356 first.toString().compareTo(second.toString())); | 360 first.toString().compareTo(second.toString())); |
| 357 int totalTaskTime = 0; | 361 int totalTaskTime = 0; |
| 358 taskClasses.forEach((Type taskClass) { | 362 taskClasses.forEach((Type taskClass) { |
| 359 int count = countMap[taskClass]; | 363 int count = countMap[taskClass]; |
| 360 if (count == null) { | 364 if (count == null) { |
| 361 count = 0; | 365 count = 0; |
| 362 } | 366 } |
| 363 int taskTime = stopwatchMap[taskClass].elapsedMilliseconds; | 367 int taskTime = stopwatchMap[taskClass].elapsedMilliseconds; |
| 364 totalTaskTime += taskTime; | 368 totalTaskTime += taskTime; |
| 365 _writeRow(buffer, [ | 369 _writeRow(buffer, [ |
| 366 taskClass.toString(), | 370 taskClass.toString(), |
| 367 count, | 371 count, |
| 368 taskTime, | 372 taskTime, |
| 369 count <= 0 ? '-' : (taskTime / count).toStringAsFixed(3) | 373 count <= 0 ? '-' : (taskTime / count).toStringAsFixed(3) |
| 370 ], classes: [null, "right", "right", "right"]); | 374 ], classes: [ |
| 375 null, |
| 376 "right", |
| 377 "right", |
| 378 "right" |
| 379 ]); |
| 371 }); | 380 }); |
| 372 _writeRow(buffer, ['Total', '-', totalTaskTime, '-'], | 381 _writeRow(buffer, ['Total', '-', totalTaskTime, '-'], |
| 373 classes: [null, "right", "right", "right"]); | 382 classes: [null, "right", "right", "right"]); |
| 374 buffer.write('</table>'); | 383 buffer.write('</table>'); |
| 375 }); | 384 }); |
| 376 }); | 385 }); |
| 377 } | 386 } |
| 378 | 387 |
| 379 /** | 388 /** |
| 380 * Return a response containing information about an AST structure. | 389 * Return a response containing information about an AST structure. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 395 } | 404 } |
| 396 String sourceUri = request.uri.queryParameters[SOURCE_QUERY_PARAM]; | 405 String sourceUri = request.uri.queryParameters[SOURCE_QUERY_PARAM]; |
| 397 if (sourceUri == null) { | 406 if (sourceUri == null) { |
| 398 return _returnFailure( | 407 return _returnFailure( |
| 399 request, 'Query parameter $SOURCE_QUERY_PARAM required'); | 408 request, 'Query parameter $SOURCE_QUERY_PARAM required'); |
| 400 } | 409 } |
| 401 | 410 |
| 402 InternalAnalysisContext context = analysisServer.folderMap[folder]; | 411 InternalAnalysisContext context = analysisServer.folderMap[folder]; |
| 403 | 412 |
| 404 _writeResponse(request, (StringBuffer buffer) { | 413 _writeResponse(request, (StringBuffer buffer) { |
| 405 _writePage(buffer, 'Analysis Server - AST Structure', [ | 414 _writePage(buffer, 'Analysis Server - AST Structure', |
| 406 'Context: $contextFilter', | 415 ['Context: $contextFilter', 'File: $sourceUri'], (HttpResponse) { |
| 407 'File: $sourceUri' | |
| 408 ], (HttpResponse) { | |
| 409 Source source = context.sourceFactory.forUri(sourceUri); | 416 Source source = context.sourceFactory.forUri(sourceUri); |
| 410 if (source == null) { | 417 if (source == null) { |
| 411 buffer.write('<p>Not found.</p>'); | 418 buffer.write('<p>Not found.</p>'); |
| 412 return; | 419 return; |
| 413 } | 420 } |
| 414 CacheEntry entry = context.analysisCache.get(source); | 421 CacheEntry entry = context.analysisCache.get(source); |
| 415 if (entry == null) { | 422 if (entry == null) { |
| 416 buffer.write('<p>Not found.</p>'); | 423 buffer.write('<p>Not found.</p>'); |
| 417 return; | 424 return; |
| 418 } | 425 } |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 479 entries.add(iterator.value); | 486 entries.add(iterator.value); |
| 480 } | 487 } |
| 481 } | 488 } |
| 482 } | 489 } |
| 483 }); | 490 }); |
| 484 allContexts.sort((Folder firstFolder, Folder secondFolder) => | 491 allContexts.sort((Folder firstFolder, Folder secondFolder) => |
| 485 firstFolder.path.compareTo(secondFolder.path)); | 492 firstFolder.path.compareTo(secondFolder.path)); |
| 486 InternalAnalysisContext context = analysisServer.folderMap[folder]; | 493 InternalAnalysisContext context = analysisServer.folderMap[folder]; |
| 487 | 494 |
| 488 _writeResponse(request, (StringBuffer buffer) { | 495 _writeResponse(request, (StringBuffer buffer) { |
| 489 _writePage(buffer, 'Analysis Server - Cache Entry', [ | 496 _writePage(buffer, 'Analysis Server - Cache Entry', |
| 490 'Context: $contextFilter', | 497 ['Context: $contextFilter', 'File: $sourceUri'], (HttpResponse) { |
| 491 'File: $sourceUri' | |
| 492 ], (HttpResponse) { | |
| 493 buffer.write('<h3>Analyzing Contexts</h3><p>'); | 498 buffer.write('<h3>Analyzing Contexts</h3><p>'); |
| 494 bool first = true; | 499 bool first = true; |
| 495 allContexts.forEach((Folder folder) { | 500 allContexts.forEach((Folder folder) { |
| 496 if (first) { | 501 if (first) { |
| 497 first = false; | 502 first = false; |
| 498 } else { | 503 } else { |
| 499 buffer.write('<br>'); | 504 buffer.write('<br>'); |
| 500 } | 505 } |
| 501 InternalAnalysisContext analyzingContext = | 506 InternalAnalysisContext analyzingContext = |
| 502 analysisServer.folderMap[folder]; | 507 analysisServer.folderMap[folder]; |
| 503 if (analyzingContext == context) { | 508 if (analyzingContext == context) { |
| 504 buffer.write(folder.path); | 509 buffer.write(folder.path); |
| 505 } else { | 510 } else { |
| 506 buffer.write(makeLink(CACHE_ENTRY_PATH, { | 511 buffer.write(makeLink( |
| 507 CONTEXT_QUERY_PARAM: folder.path, | 512 CACHE_ENTRY_PATH, |
| 508 SOURCE_QUERY_PARAM: sourceUri | 513 { |
| 509 }, HTML_ESCAPE.convert(folder.path))); | 514 CONTEXT_QUERY_PARAM: folder.path, |
| 515 SOURCE_QUERY_PARAM: sourceUri |
| 516 }, |
| 517 HTML_ESCAPE.convert(folder.path))); |
| 510 } | 518 } |
| 511 if (entryMap[folder][0].explicitlyAdded) { | 519 if (entryMap[folder][0].explicitlyAdded) { |
| 512 buffer.write(' (explicit)'); | 520 buffer.write(' (explicit)'); |
| 513 } else { | 521 } else { |
| 514 buffer.write(' (implicit)'); | 522 buffer.write(' (implicit)'); |
| 515 } | 523 } |
| 516 }); | 524 }); |
| 517 buffer.write('</p>'); | 525 buffer.write('</p>'); |
| 518 | 526 |
| 519 List<CacheEntry> entries = entryMap[folder]; | 527 List<CacheEntry> entries = entryMap[folder]; |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 753 while (iterator.moveNext()) { | 761 while (iterator.moveNext()) { |
| 754 Source source = iterator.key.source; | 762 Source source = iterator.key.source; |
| 755 if (source != null) { | 763 if (source != null) { |
| 756 CacheEntry entry = iterator.value; | 764 CacheEntry entry = iterator.value; |
| 757 String sourceName = source.fullName; | 765 String sourceName = source.fullName; |
| 758 if (!links.containsKey(sourceName)) { | 766 if (!links.containsKey(sourceName)) { |
| 759 CaughtException exception = entry.exception; | 767 CaughtException exception = entry.exception; |
| 760 if (exception != null) { | 768 if (exception != null) { |
| 761 exceptions.add(exception); | 769 exceptions.add(exception); |
| 762 } | 770 } |
| 763 String link = makeLink(CACHE_ENTRY_PATH, { | 771 String link = makeLink( |
| 764 CONTEXT_QUERY_PARAM: folder.path, | 772 CACHE_ENTRY_PATH, |
| 765 SOURCE_QUERY_PARAM: source.uri.toString() | 773 { |
| 766 }, sourceName, exception != null); | 774 CONTEXT_QUERY_PARAM: folder.path, |
| 775 SOURCE_QUERY_PARAM: source.uri.toString() |
| 776 }, |
| 777 sourceName, |
| 778 exception != null); |
| 767 if (entry.explicitlyAdded) { | 779 if (entry.explicitlyAdded) { |
| 768 explicitNames.add(sourceName); | 780 explicitNames.add(sourceName); |
| 769 } else { | 781 } else { |
| 770 implicitNames.add(sourceName); | 782 implicitNames.add(sourceName); |
| 771 } | 783 } |
| 772 links[sourceName] = link; | 784 links[sourceName] = link; |
| 773 } | 785 } |
| 774 } | 786 } |
| 775 } | 787 } |
| 776 explicitNames.sort(); | 788 explicitNames.sort(); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 796 buffer.write( | 808 buffer.write( |
| 797 makeLink(OVERLAY_PATH, {PATH_PARAM: fileName}, 'overlay')); | 809 makeLink(OVERLAY_PATH, {PATH_PARAM: fileName}, 'overlay')); |
| 798 } | 810 } |
| 799 buffer.write('</td></tr>'); | 811 buffer.write('</td></tr>'); |
| 800 } | 812 } |
| 801 buffer.write('</table>'); | 813 buffer.write('</table>'); |
| 802 } | 814 } |
| 803 } | 815 } |
| 804 | 816 |
| 805 _writeResponse(request, (StringBuffer buffer) { | 817 _writeResponse(request, (StringBuffer buffer) { |
| 806 _writePage(buffer, 'Analysis Server - Context', | 818 _writePage( |
| 807 ['Context: $contextFilter'], (StringBuffer buffer) { | 819 buffer, 'Analysis Server - Context', ['Context: $contextFilter'], |
| 820 (StringBuffer buffer) { |
| 808 List headerRowText = ['Context']; | 821 List headerRowText = ['Context']; |
| 809 headerRowText.addAll(CacheState.values); | 822 headerRowText.addAll(CacheState.values); |
| 810 buffer.write('<h3>Summary</h3>'); | 823 buffer.write('<h3>Summary</h3>'); |
| 811 buffer.write('<table>'); | 824 buffer.write('<table>'); |
| 812 _writeRow(buffer, headerRowText, header: true); | 825 _writeRow(buffer, headerRowText, header: true); |
| 813 AnalysisContextStatistics statistics = context.statistics; | 826 AnalysisContextStatistics statistics = context.statistics; |
| 814 statistics.cacheRows.forEach((AnalysisContextStatistics_CacheRow row) { | 827 statistics.cacheRows.forEach((AnalysisContextStatistics_CacheRow row) { |
| 815 List rowText = [row.name]; | 828 List rowText = [row.name]; |
| 816 for (CacheState state in CacheState.values) { | 829 for (CacheState state in CacheState.values) { |
| 817 String text = row.getCount(state).toString(); | 830 String text = row.getCount(state).toString(); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 921 } | 934 } |
| 922 if (index is LocalIndex) { | 935 if (index is LocalIndex) { |
| 923 Map<List<String>, List<InspectLocation>> relations = | 936 Map<List<String>, List<InspectLocation>> relations = |
| 924 await index.findElementsByName(name); | 937 await index.findElementsByName(name); |
| 925 _writeResponse(request, (StringBuffer buffer) { | 938 _writeResponse(request, (StringBuffer buffer) { |
| 926 _writePage(buffer, 'Analysis Server - Index Elements', ['Name: $name'], | 939 _writePage(buffer, 'Analysis Server - Index Elements', ['Name: $name'], |
| 927 (StringBuffer buffer) { | 940 (StringBuffer buffer) { |
| 928 buffer.write('<table border="1">'); | 941 buffer.write('<table border="1">'); |
| 929 _writeRow(buffer, ['Element', 'Relationship', 'Location'], | 942 _writeRow(buffer, ['Element', 'Relationship', 'Location'], |
| 930 header: true); | 943 header: true); |
| 931 relations.forEach((List<String> elementPath, | 944 relations.forEach( |
| 932 List<InspectLocation> relations) { | 945 (List<String> elementPath, List<InspectLocation> relations) { |
| 933 String elementLocation = elementPath.join(' '); | 946 String elementLocation = elementPath.join(' '); |
| 934 relations.forEach((InspectLocation location) { | 947 relations.forEach((InspectLocation location) { |
| 935 var relString = location.relationship.identifier; | 948 var relString = location.relationship.identifier; |
| 936 var locString = '${location.path} offset=${location.offset} ' | 949 var locString = '${location.path} offset=${location.offset} ' |
| 937 'length=${location.length} flags=${location.flags}'; | 950 'length=${location.length} flags=${location.flags}'; |
| 938 _writeRow(buffer, [elementLocation, relString, locString]); | 951 _writeRow(buffer, [elementLocation, relString, locString]); |
| 939 }); | 952 }); |
| 940 }); | 953 }); |
| 941 buffer.write('</table>'); | 954 buffer.write('</table>'); |
| 942 }); | 955 }); |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1078 buffer.write('<p><b>Analysis Contexts</b></p>'); | 1091 buffer.write('<p><b>Analysis Contexts</b></p>'); |
| 1079 buffer.write('<p>'); | 1092 buffer.write('<p>'); |
| 1080 bool first = true; | 1093 bool first = true; |
| 1081 folders.forEach((Folder folder) { | 1094 folders.forEach((Folder folder) { |
| 1082 if (first) { | 1095 if (first) { |
| 1083 first = false; | 1096 first = false; |
| 1084 } else { | 1097 } else { |
| 1085 buffer.write('<br>'); | 1098 buffer.write('<br>'); |
| 1086 } | 1099 } |
| 1087 String key = folder.shortName; | 1100 String key = folder.shortName; |
| 1088 buffer.write(makeLink(CONTEXT_PATH, { | 1101 buffer.write(makeLink(CONTEXT_PATH, {CONTEXT_QUERY_PARAM: folder.path}, |
| 1089 CONTEXT_QUERY_PARAM: folder.path | 1102 key, _hasException(folderMap[folder]))); |
| 1090 }, key, _hasException(folderMap[folder]))); | |
| 1091 }); | 1103 }); |
| 1092 buffer.write('</p>'); | 1104 buffer.write('</p>'); |
| 1093 | 1105 |
| 1094 buffer.write('<p><b>Options</b></p>'); | 1106 buffer.write('<p><b>Options</b></p>'); |
| 1095 buffer.write('<p>'); | 1107 buffer.write('<p>'); |
| 1096 _writeOption( | 1108 _writeOption( |
| 1097 buffer, 'Analyze functon bodies', options.analyzeFunctionBodies); | 1109 buffer, 'Analyze functon bodies', options.analyzeFunctionBodies); |
| 1098 _writeOption(buffer, 'Cache size', options.cacheSize); | 1110 _writeOption(buffer, 'Cache size', options.cacheSize); |
| 1099 _writeOption( | 1111 _writeOption( |
| 1100 buffer, 'Enable strict call checks', options.enableStrictCallChecks); | 1112 buffer, 'Enable strict call checks', options.enableStrictCallChecks); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1167 * Write a table showing summary information for the last several | 1179 * Write a table showing summary information for the last several |
| 1168 * completion requests to the given [buffer] object. | 1180 * completion requests to the given [buffer] object. |
| 1169 */ | 1181 */ |
| 1170 void _writeCompletionPerformanceList(StringBuffer buffer) { | 1182 void _writeCompletionPerformanceList(StringBuffer buffer) { |
| 1171 CompletionDomainHandler handler = _completionDomainHandler; | 1183 CompletionDomainHandler handler = _completionDomainHandler; |
| 1172 buffer.write('<h3>Completion Performance List</h3>'); | 1184 buffer.write('<h3>Completion Performance List</h3>'); |
| 1173 if (handler == null) { | 1185 if (handler == null) { |
| 1174 return; | 1186 return; |
| 1175 } | 1187 } |
| 1176 buffer.write('<table>'); | 1188 buffer.write('<table>'); |
| 1177 _writeRow(buffer, [ | 1189 _writeRow( |
| 1178 'Start Time', | 1190 buffer, |
| 1179 '', | 1191 [ |
| 1180 'First (ms)', | 1192 'Start Time', |
| 1181 '', | 1193 '', |
| 1182 'Complete (ms)', | 1194 'First (ms)', |
| 1183 '', | 1195 '', |
| 1184 '# Notifications', | 1196 'Complete (ms)', |
| 1185 '', | 1197 '', |
| 1186 '# Suggestions', | 1198 '# Notifications', |
| 1187 '', | 1199 '', |
| 1188 'Snippet' | 1200 '# Suggestions', |
| 1189 ], header: true); | 1201 '', |
| 1202 'Snippet' |
| 1203 ], |
| 1204 header: true); |
| 1190 int index = 0; | 1205 int index = 0; |
| 1191 for (CompletionPerformance performance in handler.performanceList) { | 1206 for (CompletionPerformance performance in handler.performanceList) { |
| 1192 String link = makeLink(COMPLETION_PATH, { | 1207 String link = makeLink(COMPLETION_PATH, {'index': '$index'}, |
| 1193 'index': '$index' | 1208 '${performance.startTimeAndMs}'); |
| 1194 }, '${performance.startTimeAndMs}'); | |
| 1195 _writeRow(buffer, [ | 1209 _writeRow(buffer, [ |
| 1196 link, | 1210 link, |
| 1197 ' ', | 1211 ' ', |
| 1198 performance.firstNotificationInMilliseconds, | 1212 performance.firstNotificationInMilliseconds, |
| 1199 ' ', | 1213 ' ', |
| 1200 performance.elapsedInMilliseconds, | 1214 performance.elapsedInMilliseconds, |
| 1201 ' ', | 1215 ' ', |
| 1202 performance.notificationCount, | 1216 performance.notificationCount, |
| 1203 ' ', | 1217 ' ', |
| 1204 performance.suggestionCount, | 1218 performance.suggestionCount, |
| (...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1641 */ | 1655 */ |
| 1642 static String makeLink( | 1656 static String makeLink( |
| 1643 String path, Map<String, String> params, String innerHtml, | 1657 String path, Map<String, String> params, String innerHtml, |
| 1644 [bool hasError = false]) { | 1658 [bool hasError = false]) { |
| 1645 Uri uri = new Uri(path: path, queryParameters: params); | 1659 Uri uri = new Uri(path: path, queryParameters: params); |
| 1646 String href = HTML_ESCAPE.convert(uri.toString()); | 1660 String href = HTML_ESCAPE.convert(uri.toString()); |
| 1647 String classAttribute = hasError ? ' class="error"' : ''; | 1661 String classAttribute = hasError ? ' class="error"' : ''; |
| 1648 return '<a href="$href"$classAttribute>$innerHtml</a>'; | 1662 return '<a href="$href"$classAttribute>$innerHtml</a>'; |
| 1649 } | 1663 } |
| 1650 } | 1664 } |
| OLD | NEW |