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

Side by Side Diff: tests/compiler/dart2js/sourcemaps/sourcemap_html_helper.dart

Issue 2345083003: dart2js: run dartfmt on tests (Closed)
Patch Set: revert another multipart test Created 4 years, 3 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
OLDNEW
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 /// Helper for creating HTML visualization of the source map information 5 /// Helper for creating HTML visualization of the source map information
6 /// generated by a [SourceMapProcessor]. 6 /// generated by a [SourceMapProcessor].
7 7
8 library sourcemap.html.helper; 8 library sourcemap.html.helper;
9 9
10 import 'dart:convert'; 10 import 'dart:convert';
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 /// Use gradient on spans to visually identify consecutive spans mapped to the 47 /// Use gradient on spans to visually identify consecutive spans mapped to the
48 /// same source location. 48 /// same source location.
49 HSV startColor = toColor(index); 49 HSV startColor = toColor(index);
50 HSV endColor = new HSV(startColor.h, startColor.s + 0.4, startColor.v - 0.2); 50 HSV endColor = new HSV(startColor.h, startColor.s + 0.4, startColor.v - 0.2);
51 return 'linear-gradient(to right, ${startColor.toCss}, ${endColor.toCss})'; 51 return 'linear-gradient(to right, ${startColor.toCss}, ${endColor.toCss})';
52 } 52 }
53 53
54 /// Return the html for the [index] line number. If [width] is provided, shorter 54 /// Return the html for the [index] line number. If [width] is provided, shorter
55 /// line numbers will be prefixed with spaces to match the width. 55 /// line numbers will be prefixed with spaces to match the width.
56 String lineNumber(int index, 56 String lineNumber(int index,
57 {int width, 57 {int width, bool useNbsp: false, String className}) {
58 bool useNbsp: false,
59 String className}) {
60 if (className == null) { 58 if (className == null) {
61 className = 'lineNumber'; 59 className = 'lineNumber';
62 } 60 }
63 String text = '${index + 1}'; 61 String text = '${index + 1}';
64 String padding = useNbsp ? ' ' : ' '; 62 String padding = useNbsp ? ' ' : ' ';
65 if (width != null && text.length < width) { 63 if (width != null && text.length < width) {
66 text = (padding * (width - text.length)) + text; 64 text = (padding * (width - text.length)) + text;
67 } 65 }
68 return '<span class="$className">$text$padding</span>'; 66 return '<span class="$className">$text$padding</span>';
69 } 67 }
70 68
71 /// Return the html escaped [text]. 69 /// Return the html escaped [text].
72 String escape(String text) { 70 String escape(String text) {
73 return const HtmlEscape().convert(text); 71 return const HtmlEscape().convert(text);
74 } 72 }
75 73
76 /// Information needed to generate HTML for a single [SourceMapInfo]. 74 /// Information needed to generate HTML for a single [SourceMapInfo].
77 class SourceMapHtmlInfo { 75 class SourceMapHtmlInfo {
78 final SourceMapInfo sourceMapInfo; 76 final SourceMapInfo sourceMapInfo;
79 final CodeProcessor codeProcessor; 77 final CodeProcessor codeProcessor;
80 final SourceLocationCollection sourceLocationCollection; 78 final SourceLocationCollection sourceLocationCollection;
81 79
82 SourceMapHtmlInfo(this.sourceMapInfo, 80 SourceMapHtmlInfo(
83 this.codeProcessor, 81 this.sourceMapInfo, this.codeProcessor, this.sourceLocationCollection);
84 this.sourceLocationCollection);
85 82
86 String toString() { 83 String toString() {
87 return sourceMapInfo.toString(); 84 return sourceMapInfo.toString();
88 } 85 }
89 } 86 }
90 87
91 /// A collection of source locations. 88 /// A collection of source locations.
92 /// 89 ///
93 /// Used to index source locations for visualization and linking. 90 /// Used to index source locations for visualization and linking.
94 class SourceLocationCollection { 91 class SourceLocationCollection {
(...skipping 24 matching lines...) Expand all
119 bool get showLocationAsSpan; 116 bool get showLocationAsSpan;
120 } 117 }
121 118
122 class CustomColorScheme implements CssColorScheme { 119 class CustomColorScheme implements CssColorScheme {
123 final bool showLocationAsSpan; 120 final bool showLocationAsSpan;
124 final Function single; 121 final Function single;
125 final Function multi; 122 final Function multi;
126 123
127 CustomColorScheme( 124 CustomColorScheme(
128 {this.showLocationAsSpan: false, 125 {this.showLocationAsSpan: false,
129 String this.single(var id), 126 String this.single(var id),
130 String this.multi(List ids)}); 127 String this.multi(List ids)});
131 128
132 String singleLocationToCssColor(var id) => single != null ? single(id) : null; 129 String singleLocationToCssColor(var id) => single != null ? single(id) : null;
133 130
134 String multiLocationToCssColor(List ids) => multi != null ? multi(ids) : null; 131 String multiLocationToCssColor(List ids) => multi != null ? multi(ids) : null;
135 } 132 }
136 133
137 class PatternCssColorScheme implements CssColorScheme { 134 class PatternCssColorScheme implements CssColorScheme {
138 const PatternCssColorScheme(); 135 const PatternCssColorScheme();
139 136
140 bool get showLocationAsSpan => true; 137 bool get showLocationAsSpan => true;
141 138
142 String singleLocationToCssColor(int index) { 139 String singleLocationToCssColor(int index) {
143 return "background:${toPattern(index)};"; 140 return "background:${toPattern(index)};";
144 } 141 }
145 142
146 String multiLocationToCssColor(List<int> indices) { 143 String multiLocationToCssColor(List<int> indices) {
147
148 StringBuffer sb = new StringBuffer(); 144 StringBuffer sb = new StringBuffer();
149 double delta = 100.0 / (indices.length); 145 double delta = 100.0 / (indices.length);
150 double position = 0.0; 146 double position = 0.0;
151 147
152 void addColor(String color) { 148 void addColor(String color) {
153 sb.write(', ${color} ${position.toInt()}%'); 149 sb.write(', ${color} ${position.toInt()}%');
154 position += delta; 150 position += delta;
155 sb.write(', ${color} ${position.toInt()}%'); 151 sb.write(', ${color} ${position.toInt()}%');
156 } 152 }
157 153
158 for (int index in indices) { 154 for (int index in indices) {
159 addColor('${toColorCss(index)}'); 155 addColor('${toColorCss(index)}');
160 } 156 }
161 return 'background: linear-gradient(to right${sb}); ' 157 return 'background: linear-gradient(to right${sb}); '
162 'background-size: 10px 10px;'; 158 'background-size: 10px 10px;';
163 } 159 }
164 } 160 }
165 161
166 class SingleColorScheme implements CssColorScheme { 162 class SingleColorScheme implements CssColorScheme {
167 const SingleColorScheme(); 163 const SingleColorScheme();
168 164
169 bool get showLocationAsSpan => false; 165 bool get showLocationAsSpan => false;
170 166
171 String singleLocationToCssColor(int index) { 167 String singleLocationToCssColor(int index) {
172 return "background:${toColorCss(index)};"; 168 return "background:${toColorCss(index)};";
173 } 169 }
174 170
175 String multiLocationToCssColor(List<int> indices) { 171 String multiLocationToCssColor(List<int> indices) {
176 StringBuffer sb = new StringBuffer(); 172 StringBuffer sb = new StringBuffer();
177 double delta = 100.0 / (indices.length); 173 double delta = 100.0 / (indices.length);
178 double position = 0.0; 174 double position = 0.0;
179 175
180 void addColor(String color) { 176 void addColor(String color) {
181 sb.write(', ${color} ${position.toInt()}%'); 177 sb.write(', ${color} ${position.toInt()}%');
182 position += delta; 178 position += delta;
183 sb.write(', ${color} ${position.toInt()}%'); 179 sb.write(', ${color} ${position.toInt()}%');
184 } 180 }
185 181
186 for (int index in indices) { 182 for (int index in indices) {
187 addColor('${toColorCss(index)}'); 183 addColor('${toColorCss(index)}');
188 } 184 }
189 return 'background: linear-gradient(to bottom${sb}); ' 185 return 'background: linear-gradient(to bottom${sb}); '
190 'background-size: 10px 3px;'; 186 'background-size: 10px 3px;';
191 } 187 }
192 } 188 }
193 189
194 /// Processor that computes the HTML representation of a block of JavaScript 190 /// Processor that computes the HTML representation of a block of JavaScript
195 /// code and collects the source locations mapped in the code. 191 /// code and collects the source locations mapped in the code.
196 class CodeProcessor { 192 class CodeProcessor {
197 int lineIndex = 0; 193 int lineIndex = 0;
198 final String name; 194 final String name;
199 int currentJsSourceOffset = 0; 195 int currentJsSourceOffset = 0;
200 final SourceLocationCollection collection; 196 final SourceLocationCollection collection;
201 final Map<int, List<SourceLocation>> codeLocations = {}; 197 final Map<int, List<SourceLocation>> codeLocations = {};
202 final CssColorScheme colorScheme; 198 final CssColorScheme colorScheme;
203 199
204 CodeProcessor(this.name, this.collection, 200 CodeProcessor(this.name, this.collection,
205 {this.colorScheme: const PatternCssColorScheme()}); 201 {this.colorScheme: const PatternCssColorScheme()});
206 202
207 void addSourceLocation(int targetOffset, SourceLocation sourceLocation) { 203 void addSourceLocation(int targetOffset, SourceLocation sourceLocation) {
208 codeLocations.putIfAbsent(targetOffset, () => []).add(sourceLocation); 204 codeLocations.putIfAbsent(targetOffset, () => []).add(sourceLocation);
209 collection.registerSourceLocation(sourceLocation); 205 collection.registerSourceLocation(sourceLocation);
210 } 206 }
211 207
212 String convertToHtml(String text) { 208 String convertToHtml(String text) {
213 List<Annotation> annotations = <Annotation>[]; 209 List<Annotation> annotations = <Annotation>[];
214 codeLocations.forEach((int codeOffset, List<SourceLocation> locations) { 210 codeLocations.forEach((int codeOffset, List<SourceLocation> locations) {
215 for (SourceLocation location in locations) { 211 for (SourceLocation location in locations) {
216 if (location != null) { 212 if (location != null) {
217 annotations.add(new Annotation( 213 annotations.add(new Annotation(
218 collection.getIndex(location), 214 collection.getIndex(location), codeOffset, location.shortText));
219 codeOffset,
220 location.shortText));
221 } 215 }
222 } 216 }
223 }); 217 });
224 return convertAnnotatedCodeToHtml( 218 return convertAnnotatedCodeToHtml(text, annotations,
225 text, annotations, colorScheme: colorScheme, 219 colorScheme: colorScheme,
226 elementScheme: new HighlightLinkScheme(name), 220 elementScheme: new HighlightLinkScheme(name),
227 windowSize: 3); 221 windowSize: 3);
228 } 222 }
229 } 223 }
230 224
231 class ElementScheme { 225 class ElementScheme {
232 const ElementScheme(); 226 const ElementScheme();
233 227
234 String getName(var id, Set ids) => null; 228 String getName(var id, Set ids) => null;
235 String getHref(var id, Set ids) => null; 229 String getHref(var id, Set ids) => null;
(...skipping 27 matching lines...) Expand all
263 String onmouseover = indices.map((i) => '\'$i\'').join(','); 257 String onmouseover = indices.map((i) => '\'$i\'').join(',');
264 return "highlight([${onmouseover}]);"; 258 return "highlight([${onmouseover}]);";
265 } 259 }
266 260
267 @override 261 @override
268 String onMouseOver(int id, Set<int> indices) { 262 String onMouseOver(int id, Set<int> indices) {
269 return "highlight([]);"; 263 return "highlight([]);";
270 } 264 }
271 } 265 }
272 266
273 String convertAnnotatedCodeToHtml( 267 String convertAnnotatedCodeToHtml(String code, Iterable<Annotation> annotations,
274 String code,
275 Iterable<Annotation> annotations,
276 {CssColorScheme colorScheme: const SingleColorScheme(), 268 {CssColorScheme colorScheme: const SingleColorScheme(),
277 ElementScheme elementScheme: const ElementScheme(), 269 ElementScheme elementScheme: const ElementScheme(),
278 int windowSize}) { 270 int windowSize}) {
279 StringBuffer htmlBuffer = new StringBuffer(); 271 StringBuffer htmlBuffer = new StringBuffer();
280 List<CodeLine> lines = convertAnnotatedCodeToCodeLines( 272 List<CodeLine> lines = convertAnnotatedCodeToCodeLines(code, annotations,
281 code, annotations,
282 windowSize: windowSize); 273 windowSize: windowSize);
283 int lineNoWidth; 274 int lineNoWidth;
284 if (lines.isNotEmpty) { 275 if (lines.isNotEmpty) {
285 lineNoWidth = '${lines.last.lineNo + 1}'.length; 276 lineNoWidth = '${lines.last.lineNo + 1}'.length;
286 } 277 }
287 HtmlPrintContext context = new HtmlPrintContext( 278 HtmlPrintContext context = new HtmlPrintContext(
288 lineNoWidth: lineNoWidth, 279 lineNoWidth: lineNoWidth,
289 getAnnotationData: createAnnotationDataFunction( 280 getAnnotationData: createAnnotationDataFunction(
290 colorScheme: colorScheme, 281 colorScheme: colorScheme, elementScheme: elementScheme));
291 elementScheme: elementScheme));
292 for (CodeLine line in lines) { 282 for (CodeLine line in lines) {
293 line.printHtmlOn(htmlBuffer, context); 283 line.printHtmlOn(htmlBuffer, context);
294 } 284 }
295 return htmlBuffer.toString(); 285 return htmlBuffer.toString();
296 } 286 }
297 287
298 List<CodeLine> convertAnnotatedCodeToCodeLines( 288 List<CodeLine> convertAnnotatedCodeToCodeLines(
299 String code, 289 String code, Iterable<Annotation> annotations,
300 Iterable<Annotation> annotations, 290 {int startLine, int endLine, int windowSize, Uri uri}) {
301 {int startLine,
302 int endLine,
303 int windowSize,
304 Uri uri}) {
305
306 List<CodeLine> lines = <CodeLine>[]; 291 List<CodeLine> lines = <CodeLine>[];
307 CodeLine currentLine; 292 CodeLine currentLine;
308 final List<Annotation> currentAnnotations = <Annotation>[]; 293 final List<Annotation> currentAnnotations = <Annotation>[];
309 int offset = 0; 294 int offset = 0;
310 int lineIndex = 0; 295 int lineIndex = 0;
311 int firstLine; 296 int firstLine;
312 int lastLine; 297 int lastLine;
313 298
314 void addCode(String code) { 299 void addCode(String code) {
315 if (currentLine != null) { 300 if (currentLine != null) {
316 currentLine.codeBuffer.write(code); 301 currentLine.codeBuffer.write(code);
317 currentLine.codeParts.add( 302 currentLine.codeParts
318 new CodePart(currentAnnotations.toList(), code)); 303 .add(new CodePart(currentAnnotations.toList(), code));
319 currentAnnotations.clear(); 304 currentAnnotations.clear();
320 } 305 }
321 } 306 }
322 307
323 void addAnnotations(List<Annotation> annotations) { 308 void addAnnotations(List<Annotation> annotations) {
324 currentAnnotations.addAll(annotations); 309 currentAnnotations.addAll(annotations);
325 currentLine.annotations.addAll(annotations); 310 currentLine.annotations.addAll(annotations);
326 } 311 }
327 312
328 void beginLine(int currentOffset) { 313 void beginLine(int currentOffset) {
329 lines.add(currentLine = 314 lines
330 new CodeLine(lines.length, currentOffset, uri: uri)); 315 .add(currentLine = new CodeLine(lines.length, currentOffset, uri: uri));
331 } 316 }
332 317
333 void endCurrentLocation() { 318 void endCurrentLocation() {
334 if (currentAnnotations.isNotEmpty) { 319 if (currentAnnotations.isNotEmpty) {
335 addCode(''); 320 addCode('');
336 } 321 }
337 } 322 }
338 323
339 void addSubstring(int until, {bool isFirst: false, bool isLast: false}) { 324 void addSubstring(int until, {bool isFirst: false, bool isLast: false}) {
340 if (until <= offset) return; 325 if (until <= offset) return;
(...skipping 28 matching lines...) Expand all
369 void insertAnnotations(List<Annotation> annotations) { 354 void insertAnnotations(List<Annotation> annotations) {
370 endCurrentLocation(); 355 endCurrentLocation();
371 addAnnotations(annotations); 356 addAnnotations(annotations);
372 if (annotations.last == null) { 357 if (annotations.last == null) {
373 endCurrentLocation(); 358 endCurrentLocation();
374 } 359 }
375 } 360 }
376 361
377 Map<int, List<Annotation>> annotationMap = <int, List<Annotation>>{}; 362 Map<int, List<Annotation>> annotationMap = <int, List<Annotation>>{};
378 for (Annotation annotation in annotations) { 363 for (Annotation annotation in annotations) {
379 annotationMap.putIfAbsent(annotation.codeOffset, () => <Annotation>[]) 364 annotationMap
380 .add(annotation); 365 .putIfAbsent(annotation.codeOffset, () => <Annotation>[])
366 .add(annotation);
381 } 367 }
382 368
383 bool first = true; 369 bool first = true;
384 for (int codeOffset in annotationMap.keys.toList()..sort()) { 370 for (int codeOffset in annotationMap.keys.toList()..sort()) {
385 List<Annotation> annotationList = annotationMap[codeOffset]; 371 List<Annotation> annotationList = annotationMap[codeOffset];
386 addSubstring(codeOffset, isFirst: first); 372 addSubstring(codeOffset, isFirst: first);
387 insertAnnotations(annotationList); 373 insertAnnotations(annotationList);
388 first = false; 374 first = false;
389 } 375 }
390 376
391 addSubstring(code.length, isFirst: first, isLast: true); 377 addSubstring(code.length, isFirst: first, isLast: true);
392 endCurrentLocation(); 378 endCurrentLocation();
393 379
394 int start = startLine ?? 0; 380 int start = startLine ?? 0;
395 int end = endLine ?? lines.length - 1; 381 int end = endLine ?? lines.length - 1;
396 if (windowSize != null) { 382 if (windowSize != null) {
397 start = Math.max(firstLine - windowSize, start); 383 start = Math.max(firstLine - windowSize, start);
398 end = Math.min(lastLine + windowSize, end); 384 end = Math.min(lastLine + windowSize, end);
399 } 385 }
400 return lines.sublist(start, end); 386 return lines.sublist(start, end);
401 } 387 }
402 388
403 /// Computes the HTML representation for a collection of JavaScript code blocks. 389 /// Computes the HTML representation for a collection of JavaScript code blocks.
404 String computeJsHtml(Iterable<SourceMapHtmlInfo> infoList) { 390 String computeJsHtml(Iterable<SourceMapHtmlInfo> infoList) {
405
406 StringBuffer jsCodeBuffer = new StringBuffer(); 391 StringBuffer jsCodeBuffer = new StringBuffer();
407 for (SourceMapHtmlInfo info in infoList) { 392 for (SourceMapHtmlInfo info in infoList) {
408 String name = info.sourceMapInfo.name; 393 String name = info.sourceMapInfo.name;
409 String html = info.codeProcessor.convertToHtml(info.sourceMapInfo.code); 394 String html = info.codeProcessor.convertToHtml(info.sourceMapInfo.code);
410 String onclick = 'show(\'$name\');'; 395 String onclick = 'show(\'$name\');';
411 jsCodeBuffer.write( 396 jsCodeBuffer
412 '<h3 onclick="$onclick">JS code for: ${escape(name)}</h3>\n'); 397 .write('<h3 onclick="$onclick">JS code for: ${escape(name)}</h3>\n');
413 jsCodeBuffer.write(''' 398 jsCodeBuffer.write('''
414 <pre> 399 <pre>
415 $html 400 $html
416 </pre> 401 </pre>
417 '''); 402 ''');
418 } 403 }
419 return jsCodeBuffer.toString(); 404 return jsCodeBuffer.toString();
420 } 405 }
421 406
422 /// Computes the HTML representation of the source mapping information for a 407 /// Computes the HTML representation of the source mapping information for a
423 /// collection of JavaScript code blocks. 408 /// collection of JavaScript code blocks.
424 String computeJsTraceHtml(Iterable<SourceMapHtmlInfo> infoList) { 409 String computeJsTraceHtml(Iterable<SourceMapHtmlInfo> infoList) {
425 StringBuffer jsTraceBuffer = new StringBuffer(); 410 StringBuffer jsTraceBuffer = new StringBuffer();
426 for (SourceMapHtmlInfo info in infoList) { 411 for (SourceMapHtmlInfo info in infoList) {
427 String name = info.sourceMapInfo.name; 412 String name = info.sourceMapInfo.name;
428 String jsTrace = computeJsTraceHtmlPart( 413 String jsTrace = computeJsTraceHtmlPart(
429 info.sourceMapInfo.codePoints, info.sourceLocationCollection); 414 info.sourceMapInfo.codePoints, info.sourceLocationCollection);
430 jsTraceBuffer.write(''' 415 jsTraceBuffer.write('''
431 <div name="$name" class="js-trace-buffer" style="display:none;"> 416 <div name="$name" class="js-trace-buffer" style="display:none;">
432 <h3>Trace for: ${escape(name)}</h3> 417 <h3>Trace for: ${escape(name)}</h3>
433 $jsTrace 418 $jsTrace
434 </div> 419 </div>
435 '''); 420 ''');
436 } 421 }
437 return jsTraceBuffer.toString(); 422 return jsTraceBuffer.toString();
438 } 423 }
439 424
440 /// Computes the HTML information for the [info]. 425 /// Computes the HTML information for the [info].
441 SourceMapHtmlInfo createHtmlInfo(SourceLocationCollection collection, 426 SourceMapHtmlInfo createHtmlInfo(
442 SourceMapInfo info) { 427 SourceLocationCollection collection, SourceMapInfo info) {
443 js.Node node = info.node; 428 js.Node node = info.node;
444 String code = info.code; 429 String code = info.code;
445 String name = info.name; 430 String name = info.name;
446 SourceLocationCollection subcollection = 431 SourceLocationCollection subcollection =
447 new SourceLocationCollection(collection); 432 new SourceLocationCollection(collection);
448 CodeProcessor codeProcessor = new CodeProcessor(name, subcollection); 433 CodeProcessor codeProcessor = new CodeProcessor(name, subcollection);
449 for (js.Node node in info.nodeMap.nodes) { 434 for (js.Node node in info.nodeMap.nodes) {
450 info.nodeMap[node].forEach( 435 info.nodeMap[node]
451 (int targetOffset, List<SourceLocation> sourceLocations) { 436 .forEach((int targetOffset, List<SourceLocation> sourceLocations) {
452 for (SourceLocation sourceLocation in sourceLocations) { 437 for (SourceLocation sourceLocation in sourceLocations) {
453 codeProcessor.addSourceLocation(targetOffset, sourceLocation); 438 codeProcessor.addSourceLocation(targetOffset, sourceLocation);
454 } 439 }
455 }); 440 });
456 } 441 }
457 return new SourceMapHtmlInfo(info, codeProcessor, subcollection); 442 return new SourceMapHtmlInfo(info, codeProcessor, subcollection);
458 } 443 }
459 444
460 /// Outputs a HTML file in [jsMapHtmlUri] containing an interactive 445 /// Outputs a HTML file in [jsMapHtmlUri] containing an interactive
461 /// visualization of the source mapping information in [infoList] computed 446 /// visualization of the source mapping information in [infoList] computed
462 /// with the [sourceMapProcessor]. 447 /// with the [sourceMapProcessor].
463 void createTraceSourceMapHtml(Uri jsMapHtmlUri, 448 void createTraceSourceMapHtml(Uri jsMapHtmlUri,
464 SourceMapProcessor sourceMapProcessor, 449 SourceMapProcessor sourceMapProcessor, Iterable<SourceMapInfo> infoList) {
465 Iterable<SourceMapInfo> infoList) {
466 SourceFileManager sourceFileManager = sourceMapProcessor.sourceFileManager; 450 SourceFileManager sourceFileManager = sourceMapProcessor.sourceFileManager;
467 SourceLocationCollection collection = new SourceLocationCollection(); 451 SourceLocationCollection collection = new SourceLocationCollection();
468 List<SourceMapHtmlInfo> htmlInfoList = <SourceMapHtmlInfo>[]; 452 List<SourceMapHtmlInfo> htmlInfoList = <SourceMapHtmlInfo>[];
469 for (SourceMapInfo info in infoList) { 453 for (SourceMapInfo info in infoList) {
470 htmlInfoList.add(createHtmlInfo(collection, info)); 454 htmlInfoList.add(createHtmlInfo(collection, info));
471 } 455 }
472 456
473 String jsCode = computeJsHtml(htmlInfoList); 457 String jsCode = computeJsHtml(htmlInfoList);
474 String dartCode = computeDartHtml(sourceFileManager, htmlInfoList); 458 String dartCode = computeDartHtml(sourceFileManager, htmlInfoList);
475 459
476 String jsTraceHtml = computeJsTraceHtml(htmlInfoList); 460 String jsTraceHtml = computeJsTraceHtml(htmlInfoList);
477 outputJsDartTrace(jsMapHtmlUri, jsCode, dartCode, jsTraceHtml); 461 outputJsDartTrace(jsMapHtmlUri, jsCode, dartCode, jsTraceHtml);
478 print('Trace source map html generated: $jsMapHtmlUri'); 462 print('Trace source map html generated: $jsMapHtmlUri');
479 } 463 }
480 464
481 /// Computes the HTML representation for the Dart code snippets referenced in 465 /// Computes the HTML representation for the Dart code snippets referenced in
482 /// [infoList]. 466 /// [infoList].
483 String computeDartHtml( 467 String computeDartHtml(
484 SourceFileManager sourceFileManager, 468 SourceFileManager sourceFileManager, Iterable<SourceMapHtmlInfo> infoList) {
485 Iterable<SourceMapHtmlInfo> infoList) {
486
487 StringBuffer dartCodeBuffer = new StringBuffer(); 469 StringBuffer dartCodeBuffer = new StringBuffer();
488 for (SourceMapHtmlInfo info in infoList) { 470 for (SourceMapHtmlInfo info in infoList) {
489 dartCodeBuffer.write(computeDartHtmlPart(info.sourceMapInfo.name, 471 dartCodeBuffer.write(computeDartHtmlPart(info.sourceMapInfo.name,
490 sourceFileManager, info.sourceLocationCollection)); 472 sourceFileManager, info.sourceLocationCollection));
491 } 473 }
492 return dartCodeBuffer.toString(); 474 return dartCodeBuffer.toString();
493
494 } 475 }
495 476
496 /// Computes the HTML representation for the Dart code snippets in [collection]. 477 /// Computes the HTML representation for the Dart code snippets in [collection].
497 String computeDartHtmlPart(String name, 478 String computeDartHtmlPart(String name, SourceFileManager sourceFileManager,
498 SourceFileManager sourceFileManager, 479 SourceLocationCollection collection,
499 SourceLocationCollection collection, 480 {bool showAsBlock: false}) {
500 {bool showAsBlock: false}) {
501 const int windowSize = 3; 481 const int windowSize = 3;
502 StringBuffer dartCodeBuffer = new StringBuffer(); 482 StringBuffer dartCodeBuffer = new StringBuffer();
503 Map<Uri, Map<int, List<SourceLocation>>> sourceLocationMap = {}; 483 Map<Uri, Map<int, List<SourceLocation>>> sourceLocationMap = {};
504 collection.sourceLocations.forEach((SourceLocation sourceLocation) { 484 collection.sourceLocations.forEach((SourceLocation sourceLocation) {
505 Map<int, List<SourceLocation>> uriMap = 485 Map<int, List<SourceLocation>> uriMap =
506 sourceLocationMap.putIfAbsent(sourceLocation.sourceUri, () => {}); 486 sourceLocationMap.putIfAbsent(sourceLocation.sourceUri, () => {});
507 List<SourceLocation> lineList = 487 List<SourceLocation> lineList =
508 uriMap.putIfAbsent(sourceLocation.line, () => []); 488 uriMap.putIfAbsent(sourceLocation.line, () => []);
509 lineList.add(sourceLocation); 489 lineList.add(sourceLocation);
510 }); 490 });
511 sourceLocationMap.forEach((Uri uri, Map<int, List<SourceLocation>> uriMap) { 491 sourceLocationMap.forEach((Uri uri, Map<int, List<SourceLocation>> uriMap) {
512 SourceFile sourceFile = sourceFileManager.getSourceFile(uri); 492 SourceFile sourceFile = sourceFileManager.getSourceFile(uri);
513 if (sourceFile == null) return; 493 if (sourceFile == null) return;
514 StringBuffer codeBuffer = new StringBuffer(); 494 StringBuffer codeBuffer = new StringBuffer();
515 495
516 int firstLineIndex; 496 int firstLineIndex;
517 int lastLineIndex; 497 int lastLineIndex;
518 List<int> lineIndices = uriMap.keys.toList()..sort(); 498 List<int> lineIndices = uriMap.keys.toList()..sort();
519 int lineNoWidth; 499 int lineNoWidth;
520 if (lineIndices.isNotEmpty) { 500 if (lineIndices.isNotEmpty) {
521 lineNoWidth = '${lineIndices.last + windowSize + 1}'.length; 501 lineNoWidth = '${lineIndices.last + windowSize + 1}'.length;
522 } 502 }
523 503
524 void flush() { 504 void flush() {
525 if (firstLineIndex != null && lastLineIndex != null) { 505 if (firstLineIndex != null && lastLineIndex != null) {
526 dartCodeBuffer.write( 506 dartCodeBuffer.write('<h4>${uri.pathSegments.last}, '
527 '<h4>${uri.pathSegments.last}, '
528 '${firstLineIndex - windowSize + 1}-' 507 '${firstLineIndex - windowSize + 1}-'
529 '${lastLineIndex + windowSize + 1}' 508 '${lastLineIndex + windowSize + 1}'
530 '</h4>\n'); 509 '</h4>\n');
531 dartCodeBuffer.write('<pre>\n'); 510 dartCodeBuffer.write('<pre>\n');
532 for (int line = firstLineIndex - windowSize; 511 for (int line = firstLineIndex - windowSize;
533 line < firstLineIndex; 512 line < firstLineIndex;
534 line++) { 513 line++) {
535 if (line >= 0) { 514 if (line >= 0) {
536 dartCodeBuffer.write(lineNumber(line, width: lineNoWidth)); 515 dartCodeBuffer.write(lineNumber(line, width: lineNoWidth));
537 dartCodeBuffer.write(sourceFile.getLineText(line)); 516 dartCodeBuffer.write(sourceFile.getLineText(line));
538 } 517 }
539 } 518 }
540 dartCodeBuffer.write(codeBuffer); 519 dartCodeBuffer.write(codeBuffer);
541 for (int line = lastLineIndex + 1; 520 for (int line = lastLineIndex + 1;
542 line <= lastLineIndex + windowSize; 521 line <= lastLineIndex + windowSize;
543 line++) { 522 line++) {
544 if (line < sourceFile.lines) { 523 if (line < sourceFile.lines) {
545 dartCodeBuffer.write(lineNumber(line, width: lineNoWidth)); 524 dartCodeBuffer.write(lineNumber(line, width: lineNoWidth));
546 dartCodeBuffer.write(sourceFile.getLineText(line)); 525 dartCodeBuffer.write(sourceFile.getLineText(line));
547 } 526 }
548 } 527 }
549 dartCodeBuffer.write('</pre>\n'); 528 dartCodeBuffer.write('</pre>\n');
550 firstLineIndex = null; 529 firstLineIndex = null;
551 lastLineIndex = null; 530 lastLineIndex = null;
552 } 531 }
553 codeBuffer.clear(); 532 codeBuffer.clear();
554 } 533 }
555 534
556 lineIndices.forEach((int lineIndex) { 535 lineIndices.forEach((int lineIndex) {
557 List<SourceLocation> locations = uriMap[lineIndex]; 536 List<SourceLocation> locations = uriMap[lineIndex];
558 if (lastLineIndex != null && 537 if (lastLineIndex != null && lastLineIndex + windowSize * 4 < lineIndex) {
559 lastLineIndex + windowSize * 4 < lineIndex) {
560 flush(); 538 flush();
561 } 539 }
562 if (firstLineIndex == null) { 540 if (firstLineIndex == null) {
563 firstLineIndex = lineIndex; 541 firstLineIndex = lineIndex;
564 } else { 542 } else {
565 for (int line = lastLineIndex + 1; line < lineIndex; line++) { 543 for (int line = lastLineIndex + 1; line < lineIndex; line++) {
566 codeBuffer.write(lineNumber(line, width: lineNoWidth)); 544 codeBuffer.write(lineNumber(line, width: lineNoWidth));
567 codeBuffer.write(sourceFile.getLineText(line)); 545 codeBuffer.write(sourceFile.getLineText(line));
568 } 546 }
569 } 547 }
570 String line = sourceFile.getLineText(lineIndex); 548 String line = sourceFile.getLineText(lineIndex);
571 locations.sort((a, b) => a.offset.compareTo(b.offset)); 549 locations.sort((a, b) => a.offset.compareTo(b.offset));
572 for (int i = 0; i < locations.length; i++) { 550 for (int i = 0; i < locations.length; i++) {
573 SourceLocation sourceLocation = locations[i]; 551 SourceLocation sourceLocation = locations[i];
574 int index = collection.getIndex(sourceLocation); 552 int index = collection.getIndex(sourceLocation);
575 int start = sourceLocation.column; 553 int start = sourceLocation.column;
576 int end = line.length; 554 int end = line.length;
577 if (i + 1 < locations.length) { 555 if (i + 1 < locations.length) {
578 end = locations[i + 1].column; 556 end = locations[i + 1].column;
579 } 557 }
580 if (i == 0) { 558 if (i == 0) {
581 codeBuffer.write(lineNumber(lineIndex, width: lineNoWidth)); 559 codeBuffer.write(lineNumber(lineIndex, width: lineNoWidth));
582 codeBuffer.write(line.substring(0, start)); 560 codeBuffer.write(line.substring(0, start));
583 } 561 }
584 codeBuffer.write( 562 codeBuffer
585 '<a name="${index}" style="background:${toPattern(index)};" ' 563 .write('<a name="${index}" style="background:${toPattern(index)};" '
586 'title="[${lineIndex + 1},${start + 1}]" ' 564 'title="[${lineIndex + 1},${start + 1}]" '
587 'onmouseover="highlight(\'$index\');" ' 565 'onmouseover="highlight(\'$index\');" '
588 'onmouseout="highlight();">'); 566 'onmouseout="highlight();">');
589 codeBuffer.write(line.substring(start, end)); 567 codeBuffer.write(line.substring(start, end));
590 codeBuffer.write('</a>'); 568 codeBuffer.write('</a>');
591 } 569 }
592 lastLineIndex = lineIndex; 570 lastLineIndex = lineIndex;
593 }); 571 });
594 572
595 flush(); 573 flush();
596 }); 574 });
597 String display = showAsBlock ? 'block' : 'none'; 575 String display = showAsBlock ? 'block' : 'none';
598 return ''' 576 return '''
599 <div name="$name" class="dart-buffer" style="display:$display;"> 577 <div name="$name" class="dart-buffer" style="display:$display;">
600 <h3>Dart code for: ${escape(name)}</h3> 578 <h3>Dart code for: ${escape(name)}</h3>
601 ${dartCodeBuffer} 579 ${dartCodeBuffer}
602 </div>'''; 580 </div>''';
603 } 581 }
604 582
605 /// Computes a HTML visualization of the [codePoints]. 583 /// Computes a HTML visualization of the [codePoints].
606 String computeJsTraceHtmlPart(List<CodePoint> codePoints, 584 String computeJsTraceHtmlPart(
607 SourceLocationCollection collection) { 585 List<CodePoint> codePoints, SourceLocationCollection collection) {
608 StringBuffer buffer = new StringBuffer(); 586 StringBuffer buffer = new StringBuffer();
609 buffer.write('<table style="width:100%;">'); 587 buffer.write('<table style="width:100%;">');
610 buffer.write( 588 buffer.write('<tr><th>Node kind</th><th>JS code @ offset</th>'
611 '<tr><th>Node kind</th><th>JS code @ offset</th>'
612 '<th>Dart code @ mapped location</th><th>file:position:name</th></tr>'); 589 '<th>Dart code @ mapped location</th><th>file:position:name</th></tr>');
613 codePoints.forEach((CodePoint codePoint) { 590 codePoints.forEach((CodePoint codePoint) {
614 String jsCode = truncate(codePoint.jsCode, 50); 591 String jsCode = truncate(codePoint.jsCode, 50);
615 if (codePoint.sourceLocation != null) { 592 if (codePoint.sourceLocation != null) {
616 int index = collection.getIndex(codePoint.sourceLocation); 593 int index = collection.getIndex(codePoint.sourceLocation);
617 if (index != null) { 594 if (index != null) {
618 String style = ''; 595 String style = '';
619 if (!codePoint.isMissing) { 596 if (!codePoint.isMissing) {
620 style = 'style="background:${toColorCss(index)};" '; 597 style = 'style="background:${toColorCss(index)};" ';
621 } 598 }
622 buffer.write('<tr $style' 599 buffer.write('<tr $style'
623 'name="trace$index" ' 600 'name="trace$index" '
624 'onmouseover="highlight([${index}]);"' 601 'onmouseover="highlight([${index}]);"'
625 'onmouseout="highlight([]);">'); 602 'onmouseout="highlight([]);">');
626 } else { 603 } else {
627 buffer.write('<tr>'); 604 buffer.write('<tr>');
628 print('${codePoint.sourceLocation} not found in '); 605 print('${codePoint.sourceLocation} not found in ');
629 collection.sourceLocationIndexMap.keys 606 collection.sourceLocationIndexMap.keys
630 .where((l) => l.sourceUri == codePoint.sourceLocation.sourceUri) 607 .where((l) => l.sourceUri == codePoint.sourceLocation.sourceUri)
631 .forEach((l) => print(' $l')); 608 .forEach((l) => print(' $l'));
632 } 609 }
633 } else { 610 } else {
634 buffer.write('<tr>'); 611 buffer.write('<tr>');
635 } 612 }
636 buffer.write('<td>${codePoint.kind}</td>'); 613 buffer.write('<td>${codePoint.kind}</td>');
637 buffer.write('<td class="code">${jsCode}</td>'); 614 buffer.write('<td class="code">${jsCode}</td>');
638 if (codePoint.sourceLocation == null) { 615 if (codePoint.sourceLocation == null) {
639 //buffer.write('<td></td>'); 616 //buffer.write('<td></td>');
640 } else { 617 } else {
641 String dartCode = truncate(codePoint.dartCode, 50); 618 String dartCode = truncate(codePoint.dartCode, 50);
642 buffer.write('<td class="code">${dartCode}</td>'); 619 buffer.write('<td class="code">${dartCode}</td>');
643 buffer.write('<td>${escape(codePoint.sourceLocation.shortText)}</td>'); 620 buffer.write('<td>${escape(codePoint.sourceLocation.shortText)}</td>');
644 } 621 }
645 buffer.write('</tr>'); 622 buffer.write('</tr>');
646 }); 623 });
647 buffer.write('</table>'); 624 buffer.write('</table>');
648 625
649 return buffer.toString(); 626 return buffer.toString();
650 } 627 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698