Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 sourcemap.diff_view; | 5 library sourcemap.diff_view; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:io'; | 8 import 'dart:io'; |
| 9 import 'package:compiler/src/commandline_options.dart'; | 9 import 'package:compiler/src/commandline_options.dart'; |
| 10 import 'package:compiler/src/diagnostics/invariant.dart'; | 10 import 'package:compiler/src/diagnostics/invariant.dart'; |
| 11 import 'package:compiler/src/io/position_information.dart'; | 11 import 'package:compiler/src/io/position_information.dart'; |
| 12 import 'package:compiler/src/js/js.dart' as js; | 12 import 'package:compiler/src/js/js.dart' as js; |
| 13 import 'sourcemap_helper.dart'; | 13 import 'sourcemap_helper.dart'; |
| 14 import 'sourcemap_html_helper.dart'; | 14 import 'sourcemap_html_helper.dart'; |
| 15 import 'trace_graph.dart'; | 15 import 'trace_graph.dart'; |
| 16 import 'js_tracer.dart'; | 16 import 'js_tracer.dart'; |
| 17 | 17 |
| 18 const String WITH_SOURCE_INFO_STYLE = 'background-color:#FF8080;'; | 18 const String WITH_SOURCE_INFO_STYLE = 'background-color:#FF8080;'; |
| 19 const String WITHOUT_SOURCE_INFO_STYLE = 'border: solid 1px #FF8080;'; | 19 const String WITHOUT_SOURCE_INFO_STYLE = 'border: solid 1px #FF8080;'; |
| 20 const String ADDITIONAL_SOURCE_INFO_STYLE = 'border: solid 1px #8080FF;'; | 20 const String ADDITIONAL_SOURCE_INFO_STYLE = 'border: solid 1px #8080FF;'; |
| 21 | 21 |
| 22 main(List<String> args) async { | 22 main(List<String> args) async { |
| 23 DEBUG_MODE = true; | 23 DEBUG_MODE = true; |
| 24 String out = 'out.js.diff_view.html'; | 24 String out = 'out.js.diff_view.html'; |
| 25 String filename; | 25 String filename; |
| 26 List<String> currentOptions = []; | 26 List<String> currentOptions = []; |
| 27 List<List<String>> options = [currentOptions]; | 27 List<List<String>> options = [currentOptions]; |
| 28 int argGroup = 0; | 28 int argGroup = 0; |
| 29 bool showAnnotations = true; | |
| 29 for (String arg in args) { | 30 for (String arg in args) { |
| 30 if (arg == '--') { | 31 if (arg == '--') { |
| 31 currentOptions = []; | 32 currentOptions = []; |
| 32 options.add(currentOptions); | 33 options.add(currentOptions); |
| 33 argGroup++; | 34 argGroup++; |
| 35 } else if (arg == '-h') { | |
| 36 showAnnotations = false; | |
| 37 print('Hiding annotations'); | |
| 34 } else if (arg.startsWith('-o')) { | 38 } else if (arg.startsWith('-o')) { |
| 35 out = arg.substring('-o'.length); | 39 out = arg.substring('-o'.length); |
| 36 } else if (arg.startsWith('--out=')) { | 40 } else if (arg.startsWith('--out=')) { |
| 37 out = arg.substring('--out='.length); | 41 out = arg.substring('--out='.length); |
| 38 } else if (arg.startsWith('-')) { | 42 } else if (arg.startsWith('-')) { |
| 39 currentOptions.add(arg); | 43 currentOptions.add(arg); |
| 40 } else { | 44 } else { |
| 41 filename = arg; | 45 filename = arg; |
| 42 } | 46 } |
| 43 } | 47 } |
| 44 List<String> commonArguments = options[0]; | 48 List<String> commonArguments = options[0]; |
| 45 List<String> options1; | 49 List<String> options1; |
| 46 List<String> options2; | 50 List<String> options2; |
| 47 if (options.length == 1) { | 51 if (options.length == 1) { |
| 48 // Use default options; comparing SSA and CPS output using the new | 52 // Use default options; comparing SSA and CPS output using the new |
| 49 // source information strategy. | 53 // source information strategy. |
| 50 options1 = [USE_NEW_SOURCE_INFO]..addAll(commonArguments); | 54 options1 = [USE_NEW_SOURCE_INFO]..addAll(commonArguments); |
| 51 options2 = [USE_NEW_SOURCE_INFO, Flags.useCpsIr]..addAll(commonArguments); | 55 options2 = [USE_NEW_SOURCE_INFO, Flags.useCpsIr]..addAll(commonArguments); |
| 52 } else if (options.length == 2) { | 56 } else if (options.length == 2) { |
| 53 // Use alternative options for the second output column. | 57 // Use alternative options for the second output column. |
| 54 options1 = commonArguments; | 58 options1 = commonArguments; |
| 55 options2 = options[1]..addAll(commonArguments); | 59 options2 = options[1]..addAll(commonArguments); |
| 56 } else { | 60 } else { |
| 57 // Use specific options for both output columns. | 61 // Use specific options for both output columns. |
| 58 options1 = options[1]..addAll(commonArguments); | 62 options1 = options[1]..addAll(commonArguments); |
| 59 options2 = options[2]..addAll(commonArguments); | 63 options2 = options[2]..addAll(commonArguments); |
| 60 } | 64 } |
| 61 | 65 |
| 62 print('Compiling ${options1.join(' ')} $filename'); | 66 print('Compiling ${options1.join(' ')} $filename'); |
| 63 CodeLinesResult result1 = await computeCodeLines(options1, filename); | 67 CodeLinesResult result1 = await computeCodeLines( |
| 68 options1, filename, addAnnotations: showAnnotations); | |
|
asgerf
2016/01/28 14:47:42
Why not pick one name and stick with it.
Johnni Winther
2016/01/28 14:51:25
Done.
| |
| 64 print('Compiling ${options2.join(' ')} $filename'); | 69 print('Compiling ${options2.join(' ')} $filename'); |
| 65 CodeLinesResult result2 = await computeCodeLines(options2, filename); | 70 CodeLinesResult result2 = await computeCodeLines( |
| 71 options2, filename, addAnnotations: showAnnotations); | |
| 66 | 72 |
| 67 StringBuffer sb = new StringBuffer(); | 73 StringBuffer sb = new StringBuffer(); |
| 68 sb.write(''' | 74 sb.write(''' |
| 69 <html> | 75 <html> |
| 70 <head> | 76 <head> |
| 71 <title>Diff for $filename</title> | 77 <title>Diff for $filename</title> |
| 72 <style> | 78 <style> |
| 73 .lineNumber { | 79 .lineNumber { |
| 74 font-size: smaller; | 80 font-size: smaller; |
| 75 color: #888; | 81 color: #888; |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 100 .identical2 { | 106 .identical2 { |
| 101 background-color: #C0E0C0; | 107 background-color: #C0E0C0; |
| 102 } | 108 } |
| 103 </style> | 109 </style> |
| 104 </head> | 110 </head> |
| 105 <body>'''); | 111 <body>'''); |
| 106 | 112 |
| 107 sb.write(''' | 113 sb.write(''' |
| 108 <div class="header" style="left: 0px;">[${options1.join(',')}]</div> | 114 <div class="header" style="left: 0px;">[${options1.join(',')}]</div> |
| 109 <div class="header" style="right: 0px;">[${options2.join(',')}]</div> | 115 <div class="header" style="right: 0px;">[${options2.join(',')}]</div> |
| 110 <div style="position:absolute;top:22px;width:100%;height:18px;"> | 116 <div style="position:absolute;left:0px;top:22px;width:100%;height:18px;"> |
| 111 <span class="identical1"> </span> | 117 <span class="identical1"> </span> |
| 112 <span class="identical2"> </span> | 118 <span class="identical2"> </span> |
| 113 identical blocks | 119 identical blocks |
| 114 <span class="corresponding1"> </span> | 120 <span class="corresponding1"> </span> |
| 115 <span class="corresponding2"> </span> | 121 <span class="corresponding2"> </span> |
| 116 corresponding blocks | 122 corresponding blocks |
| 123 '''); | |
| 124 if (showAnnotations) { | |
| 125 sb.write(''' | |
| 117 <span style="$WITH_SOURCE_INFO_STYLE"> </span> | 126 <span style="$WITH_SOURCE_INFO_STYLE"> </span> |
| 118 offset with source information | 127 offset with source information |
| 119 <span style="$WITHOUT_SOURCE_INFO_STYLE"> </span> | 128 <span style="$WITHOUT_SOURCE_INFO_STYLE"> </span> |
| 120 offset without source information | 129 offset without source information |
| 121 <span style="$ADDITIONAL_SOURCE_INFO_STYLE"> </span> | 130 <span style="$ADDITIONAL_SOURCE_INFO_STYLE"> </span> |
| 122 offset with unneeded source information | 131 offset with unneeded source information |
| 132 '''); | |
| 133 } | |
| 134 sb.write(''' | |
| 123 </div> | 135 </div> |
| 124 <table style="position:absolute;top:40px;width:100%;"><tr> | 136 <table style="position:absolute;left:0px;top:40px;width:100%;"><tr> |
| 125 '''); | 137 '''); |
| 126 | 138 |
| 127 void addCell(String content) { | 139 void addCell(String content) { |
| 128 sb.write(''' | 140 sb.write(''' |
| 129 <td class="cell"><pre> | 141 <td class="cell"><pre> |
| 130 '''); | 142 '''); |
| 131 sb.write(content); | 143 sb.write(content); |
| 132 sb.write(''' | 144 sb.write(''' |
| 133 </pre></td> | 145 </pre></td> |
| 134 '''); | 146 '''); |
| (...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 797 class CodeLinesResult { | 809 class CodeLinesResult { |
| 798 final List<CodeLine> codeLines; | 810 final List<CodeLine> codeLines; |
| 799 final Coverage coverage; | 811 final Coverage coverage; |
| 800 | 812 |
| 801 CodeLinesResult(this.codeLines, this.coverage); | 813 CodeLinesResult(this.codeLines, this.coverage); |
| 802 } | 814 } |
| 803 | 815 |
| 804 /// Compute [CodeLine]s and [Coverage] for [filename] using the given [options]. | 816 /// Compute [CodeLine]s and [Coverage] for [filename] using the given [options]. |
| 805 Future<CodeLinesResult> computeCodeLines( | 817 Future<CodeLinesResult> computeCodeLines( |
| 806 List<String> options, | 818 List<String> options, |
| 807 String filename) async { | 819 String filename, |
| 820 {bool addAnnotations: true}) async { | |
| 808 SourceMapProcessor processor = new SourceMapProcessor(filename); | 821 SourceMapProcessor processor = new SourceMapProcessor(filename); |
| 809 List<SourceMapInfo> sourceMapInfoList = | 822 List<SourceMapInfo> sourceMapInfoList = |
| 810 await processor.process(options, perElement: false); | 823 await processor.process(options, perElement: false); |
| 811 | 824 |
| 812 const int WITH_SOURCE_INFO = 0; | 825 const int WITH_SOURCE_INFO = 0; |
| 813 const int WITHOUT_SOURCE_INFO = 1; | 826 const int WITHOUT_SOURCE_INFO = 1; |
| 814 const int ADDITIONAL_SOURCE_INFO = 2; | 827 const int ADDITIONAL_SOURCE_INFO = 2; |
| 815 | 828 |
| 816 for (SourceMapInfo info in sourceMapInfoList) { | 829 for (SourceMapInfo info in sourceMapInfoList) { |
| 817 if (info.element != null) continue; | 830 if (info.element != null) continue; |
| 818 | 831 |
| 819 List<CodeLine> codeLines; | 832 List<CodeLine> codeLines; |
| 820 Coverage coverage = new Coverage(); | 833 Coverage coverage = new Coverage(); |
| 821 List<Annotation> annotations = <Annotation>[]; | 834 List<Annotation> annotations = <Annotation>[]; |
| 835 | |
| 822 String code = info.code; | 836 String code = info.code; |
| 823 TraceGraph graph = createTraceGraph(info, coverage); | 837 TraceGraph graph = createTraceGraph(info, coverage); |
| 824 Set<js.Node> mappedNodes = new Set<js.Node>(); | 838 if (addAnnotations) { |
| 825 for (TraceStep step in graph.steps) { | 839 Set<js.Node> mappedNodes = new Set<js.Node>(); |
| 826 int offset; | 840 for (TraceStep step in graph.steps) { |
| 827 if (options.contains(USE_NEW_SOURCE_INFO)) { | 841 int offset; |
| 828 offset = step.offset.subexpressionOffset; | 842 if (options.contains(USE_NEW_SOURCE_INFO)) { |
| 829 } else { | 843 offset = step.offset.subexpressionOffset; |
| 830 offset = info.jsCodePositions[step.node].startPosition; | 844 } else { |
| 845 offset = info.jsCodePositions[step.node].startPosition; | |
| 846 } | |
| 847 if (offset != null) { | |
| 848 int id = step.sourceLocation != null | |
| 849 ? WITH_SOURCE_INFO : WITHOUT_SOURCE_INFO; | |
| 850 annotations.add( | |
| 851 new Annotation(id, offset, null)); | |
| 852 } | |
| 831 } | 853 } |
| 832 if (offset != null) { | 854 if (!options.contains(USE_NEW_SOURCE_INFO)) { |
| 833 int id = step.sourceLocation != null | 855 for (js.Node node in info.nodeMap.nodes) { |
| 834 ? WITH_SOURCE_INFO : WITHOUT_SOURCE_INFO; | 856 if (!mappedNodes.contains(node)) { |
| 835 annotations.add( | 857 int offset = info.jsCodePositions[node].startPosition; |
| 836 new Annotation(id, offset, null)); | 858 annotations.add( |
| 837 } | 859 new Annotation(ADDITIONAL_SOURCE_INFO, offset, null)); |
| 838 } | 860 } |
| 839 if (!options.contains(USE_NEW_SOURCE_INFO)) { | |
| 840 for (js.Node node in info.nodeMap.nodes) { | |
| 841 if (!mappedNodes.contains(node)) { | |
| 842 int offset = info.jsCodePositions[node].startPosition; | |
| 843 annotations.add( | |
| 844 new Annotation(ADDITIONAL_SOURCE_INFO, offset, null)); | |
| 845 } | 861 } |
| 846 } | 862 } |
| 847 } | 863 } |
| 848 codeLines = convertAnnotatedCodeToCodeLines( | 864 codeLines = convertAnnotatedCodeToCodeLines( |
| 849 code, | 865 code, |
| 850 annotations, | 866 annotations, |
| 851 colorScheme: new CustomColorScheme( | 867 colorScheme: new CustomColorScheme( |
| 852 single: (int id) { | 868 single: (int id) { |
| 853 if (id == WITH_SOURCE_INFO) { | 869 if (id == WITH_SOURCE_INFO) { |
| 854 return WITH_SOURCE_INFO_STYLE; | 870 return WITH_SOURCE_INFO_STYLE; |
| 855 } else if (id == ADDITIONAL_SOURCE_INFO) { | 871 } else if (id == ADDITIONAL_SOURCE_INFO) { |
| 856 return ADDITIONAL_SOURCE_INFO_STYLE; | 872 return ADDITIONAL_SOURCE_INFO_STYLE; |
| 857 } | 873 } |
| 858 return WITHOUT_SOURCE_INFO_STYLE; | 874 return WITHOUT_SOURCE_INFO_STYLE; |
| 859 }, | 875 }, |
| 860 multi: (List ids) { | 876 multi: (List ids) { |
| 861 if (ids.contains(WITH_SOURCE_INFO)) { | 877 if (ids.contains(WITH_SOURCE_INFO)) { |
| 862 return WITH_SOURCE_INFO_STYLE; | 878 return WITH_SOURCE_INFO_STYLE; |
| 863 } else if (ids.contains(ADDITIONAL_SOURCE_INFO)) { | 879 } else if (ids.contains(ADDITIONAL_SOURCE_INFO)) { |
| 864 return ADDITIONAL_SOURCE_INFO_STYLE; | 880 return ADDITIONAL_SOURCE_INFO_STYLE; |
| 865 } | 881 } |
| 866 return WITHOUT_SOURCE_INFO_STYLE; | 882 return WITHOUT_SOURCE_INFO_STYLE; |
| 867 } | 883 } |
| 868 )); | 884 )); |
| 869 return new CodeLinesResult(codeLines, coverage); | 885 return new CodeLinesResult(codeLines, coverage); |
| 870 } | 886 } |
| 871 } | 887 } |
| OLD | NEW |