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

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

Issue 1752393002: Add source mappings and inlined Dart code to diff_view. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Updated cf. comments. Created 4 years, 9 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
« no previous file with comments | « tests/compiler/dart2js/sourcemaps/sourcemap_helper.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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';
11 import 'dart:math' as Math; 11 import 'dart:math' as Math;
12 12
13 import 'package:compiler/src/io/source_file.dart'; 13 import 'package:compiler/src/io/source_file.dart';
14 import 'package:compiler/src/io/source_information.dart'; 14 import 'package:compiler/src/io/source_information.dart';
15 import 'package:compiler/src/js/js.dart' as js; 15 import 'package:compiler/src/js/js.dart' as js;
16 16
17 import 'colors.dart'; 17 import 'colors.dart';
18 import 'sourcemap_helper.dart'; 18 import 'sourcemap_helper.dart';
19 import 'sourcemap_html_templates.dart'; 19 import 'sourcemap_html_templates.dart';
20 import 'html_parts.dart'; 20 import 'html_parts.dart';
21 21
22 /// Truncate [input] to [length], adding '...' if truncated. 22 /// Truncate [input] to [length], adding '...' if truncated.
23 String truncate(String input, int length) { 23 String truncate(String input, int length) {
24 if (input.length > length) { 24 if (input.length > length) {
25 return '${input.substring(0, length - 3)}...'; 25 return '${input.substring(0, length - 3)}...';
26 } 26 }
27 return input; 27 return input;
28 } 28 }
29 29
30 const int HUE_COUNT = 24;
31
30 /// Returns the [index]th color for visualization. 32 /// Returns the [index]th color for visualization.
31 HSV toColor(int index) { 33 HSV toColor(int index) {
32 int hueCount = 24; 34 double h = 360.0 * (index % HUE_COUNT) / HUE_COUNT;
33 double h = 360.0 * (index % hueCount) / hueCount;
34 double v = 1.0; 35 double v = 1.0;
35 double s = 0.5; 36 double s = 0.5;
36 return new HSV(h, s, v); 37 return new HSV(h, s, v);
37 } 38 }
38 39
39 /// Return the CSS color value for the [index]th color. 40 /// Return the CSS color value for the [index]th color.
40 String toColorCss(int index) { 41 String toColorCss(int index) {
41 return toColor(index).toCss; 42 return toColor(index).toCss;
42 } 43 }
43 44
44 /// Return the CSS color value for the [index]th span. 45 /// Return the CSS color value for the [index]th span.
45 String toPattern(int index) { 46 String toPattern(int index) {
46 /// 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
47 /// same source location. 48 /// same source location.
48 HSV startColor = toColor(index); 49 HSV startColor = toColor(index);
49 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);
50 return 'linear-gradient(to right, ${startColor.toCss}, ${endColor.toCss})'; 51 return 'linear-gradient(to right, ${startColor.toCss}, ${endColor.toCss})';
51 } 52 }
52 53
53 /// 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
54 /// line numbers will be prefixed with spaces to match the width. 55 /// line numbers will be prefixed with spaces to match the width.
55 String lineNumber(int index, {int width, bool useNbsp: false}) { 56 String lineNumber(int index,
57 {int width,
58 bool useNbsp: false,
59 String className}) {
60 if (className == null) {
61 className = 'lineNumber';
62 }
56 String text = '${index + 1}'; 63 String text = '${index + 1}';
57 String padding = useNbsp ? ' ' : ' '; 64 String padding = useNbsp ? ' ' : ' ';
58 if (width != null && text.length < width) { 65 if (width != null && text.length < width) {
59 text = (padding * (width - text.length)) + text; 66 text = (padding * (width - text.length)) + text;
60 } 67 }
61 return '<span class="lineNumber">$text$padding</span>'; 68 return '<span class="$className">$text$padding</span>';
62 } 69 }
63 70
64 /// Return the html escaped [text]. 71 /// Return the html escaped [text].
65 String escape(String text) { 72 String escape(String text) {
66 return const HtmlEscape().convert(text); 73 return const HtmlEscape().convert(text);
67 } 74 }
68 75
69 /// Information needed to generate HTML for a single [SourceMapInfo]. 76 /// Information needed to generate HTML for a single [SourceMapInfo].
70 class SourceMapHtmlInfo { 77 class SourceMapHtmlInfo {
71 final SourceMapInfo sourceMapInfo; 78 final SourceMapInfo sourceMapInfo;
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 } 221 }
215 } 222 }
216 }); 223 });
217 return convertAnnotatedCodeToHtml( 224 return convertAnnotatedCodeToHtml(
218 text, annotations, colorScheme: colorScheme, 225 text, annotations, colorScheme: colorScheme,
219 elementScheme: new HighlightLinkScheme(name), 226 elementScheme: new HighlightLinkScheme(name),
220 windowSize: 3); 227 windowSize: 3);
221 } 228 }
222 } 229 }
223 230
224 class Annotation {
225 final id;
226 final int codeOffset;
227 final String title;
228
229 Annotation(this.id, this.codeOffset, this.title);
230 }
231
232 class ElementScheme { 231 class ElementScheme {
233 const ElementScheme(); 232 const ElementScheme();
234 233
235 String getName(var id, Set ids) => null; 234 String getName(var id, Set ids) => null;
236 String getHref(var id, Set ids) => null; 235 String getHref(var id, Set ids) => null;
237 String onClick(var id, Set ids) => null; 236 String onClick(var id, Set ids) => null;
238 String onMouseOver(var id, Set ids) => null; 237 String onMouseOver(var id, Set ids) => null;
239 String onMouseOut(var id, Set ids) => null; 238 String onMouseOut(var id, Set ids) => null;
240 } 239 }
241 240
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 272
274 String convertAnnotatedCodeToHtml( 273 String convertAnnotatedCodeToHtml(
275 String code, 274 String code,
276 Iterable<Annotation> annotations, 275 Iterable<Annotation> annotations,
277 {CssColorScheme colorScheme: const SingleColorScheme(), 276 {CssColorScheme colorScheme: const SingleColorScheme(),
278 ElementScheme elementScheme: const ElementScheme(), 277 ElementScheme elementScheme: const ElementScheme(),
279 int windowSize}) { 278 int windowSize}) {
280 StringBuffer htmlBuffer = new StringBuffer(); 279 StringBuffer htmlBuffer = new StringBuffer();
281 List<CodeLine> lines = convertAnnotatedCodeToCodeLines( 280 List<CodeLine> lines = convertAnnotatedCodeToCodeLines(
282 code, annotations, 281 code, annotations,
283 colorScheme: colorScheme,
284 elementScheme: elementScheme,
285 windowSize: windowSize); 282 windowSize: windowSize);
286 int lineNoWidth; 283 int lineNoWidth;
287 if (lines.isNotEmpty) { 284 if (lines.isNotEmpty) {
288 lineNoWidth = '${lines.last.lineNo + 1}'.length; 285 lineNoWidth = '${lines.last.lineNo + 1}'.length;
289 } 286 }
290 HtmlPrintContext context = new HtmlPrintContext(lineNoWidth: lineNoWidth); 287 HtmlPrintContext context = new HtmlPrintContext(
288 lineNoWidth: lineNoWidth,
289 getAnnotationData: createAnnotationDataFunction(
290 colorScheme: colorScheme,
291 elementScheme: elementScheme));
291 for (CodeLine line in lines) { 292 for (CodeLine line in lines) {
292 line.printHtmlOn(htmlBuffer, context); 293 line.printHtmlOn(htmlBuffer, context);
293 } 294 }
294 return htmlBuffer.toString(); 295 return htmlBuffer.toString();
295 } 296 }
296 297
297 List<CodeLine> convertAnnotatedCodeToCodeLines( 298 List<CodeLine> convertAnnotatedCodeToCodeLines(
298 String code, 299 String code,
299 Iterable<Annotation> annotations, 300 Iterable<Annotation> annotations,
300 {CssColorScheme colorScheme: const SingleColorScheme(), 301 {int startLine,
301 ElementScheme elementScheme: const ElementScheme(), 302 int endLine,
302 int windowSize}) { 303 int windowSize,
304 Uri uri}) {
303 305
304 List<CodeLine> lines = <CodeLine>[]; 306 List<CodeLine> lines = <CodeLine>[];
305 CodeLine currentLine; 307 CodeLine currentLine;
308 final List<Annotation> currentAnnotations = <Annotation>[];
306 int offset = 0; 309 int offset = 0;
307 int lineIndex = 0; 310 int lineIndex = 0;
308 int firstLine; 311 int firstLine;
309 int lastLine; 312 int lastLine;
310 bool pendingSourceLocationsEnd = false;
311 313
312 void write(String code, HtmlPart html) { 314 void addCode(String code) {
313 if (currentLine != null) { 315 if (currentLine != null) {
314 currentLine.codeBuffer.write(code); 316 currentLine.codeBuffer.write(code);
315 currentLine.htmlParts.add(html); 317 currentLine.codeParts.add(
318 new CodePart(currentAnnotations.toList(), code));
319 currentAnnotations.clear();
316 } 320 }
317 } 321 }
318 322
319 void startLine(int currentOffset) { 323 void addAnnotations(List<Annotation> annotations) {
320 lines.add(currentLine = new CodeLine(lines.length, currentOffset)); 324 currentAnnotations.addAll(annotations);
325 currentLine.annotations.addAll(annotations);
326 }
327
328 void beginLine(int currentOffset) {
329 lines.add(currentLine =
330 new CodeLine(lines.length, currentOffset, uri: uri));
321 } 331 }
322 332
323 void endCurrentLocation() { 333 void endCurrentLocation() {
324 if (pendingSourceLocationsEnd) { 334 if (currentAnnotations.isNotEmpty) {
325 write('', const ConstHtmlPart('</a>')); 335 addCode('');
326 } 336 }
327 pendingSourceLocationsEnd = false;
328 } 337 }
329 338
330 void addSubstring(int until, {bool isFirst: false, bool isLast: false}) { 339 void addSubstring(int until, {bool isFirst: false, bool isLast: false}) {
331 if (until <= offset) return; 340 if (until <= offset) return;
332 if (offset >= code.length) return; 341 if (offset >= code.length) return;
333 342
334 String substring = code.substring(offset, until); 343 String substring = code.substring(offset, until);
335 bool first = true; 344 bool first = true;
336 345
337 if (isLast) { 346 if (isLast) {
338 lastLine = lineIndex; 347 lastLine = lineIndex;
339 } 348 }
340 int localOffset = 0; 349 int localOffset = 0;
341 if (isFirst) { 350 if (isFirst) {
342 startLine(offset + localOffset); 351 beginLine(offset + localOffset);
343 } 352 }
344 for (String line in substring.split('\n')) { 353 for (String line in substring.split('\n')) {
345 if (!first) { 354 if (!first) {
346 endCurrentLocation(); 355 endCurrentLocation();
347 write('', const NewLine());
348 lineIndex++; 356 lineIndex++;
349 startLine(offset + localOffset); 357 beginLine(offset + localOffset);
350 } 358 }
351 if (pendingSourceLocationsEnd && !colorScheme.showLocationAsSpan) { 359 addCode(line);
352 if (line.isNotEmpty) {
353 String before = line.substring(0, 1);
354 write(before, new HtmlText(before));
355 endCurrentLocation();
356 String after = line.substring(1);
357 write(after, new HtmlText(after));
358 }
359 } else {
360 write(line, new HtmlText(line));
361 }
362 first = false; 360 first = false;
363 localOffset += line.length + 1; 361 localOffset += line.length + 1;
364 } 362 }
365 if (isFirst) { 363 if (isFirst) {
366 firstLine = lineIndex; 364 firstLine = lineIndex;
367 } 365 }
368 offset = until; 366 offset = until;
369 } 367 }
370 368
371 void insertAnnotations(List<Annotation> annotations) { 369 void insertAnnotations(List<Annotation> annotations) {
372 endCurrentLocation(); 370 endCurrentLocation();
373 371 addAnnotations(annotations);
374 String color;
375 var id;
376 String title;
377 if (annotations.length == 1) {
378 Annotation annotation = annotations.single;
379 if (annotation != null) {
380 id = annotation.id;
381 color = colorScheme.singleLocationToCssColor(id);
382 title = annotation.title;
383 }
384 } else {
385 id = annotations.first.id;
386 List ids = [];
387 for (Annotation annotation in annotations) {
388 ids.add(annotation.id);
389 }
390 color = colorScheme.multiLocationToCssColor(ids);
391 title = annotations.map((l) => l.title).join(',');
392 }
393 if (id != null) {
394 Set ids = annotations.map((l) => l.id).toSet();
395 String name = elementScheme.getName(id, ids);
396 String href = elementScheme.getHref(id, ids);
397 String onclick = elementScheme.onClick(id, ids);
398 String onmouseover = elementScheme.onMouseOver(id, ids);
399 String onmouseout = elementScheme.onMouseOut(id, ids);
400 write('', new AnchorHtmlPart(
401 color: color,
402 name: name,
403 href: href,
404 title: title,
405 onclick: onclick,
406 onmouseover: onmouseover,
407 onmouseout: onmouseout));
408 pendingSourceLocationsEnd = true;
409 }
410 currentLine.annotations.addAll(annotations);
411 if (annotations.last == null) { 372 if (annotations.last == null) {
412 endCurrentLocation(); 373 endCurrentLocation();
413 } 374 }
414 } 375 }
415 376
416 Map<int, List<Annotation>> annotationMap = <int, List<Annotation>>{}; 377 Map<int, List<Annotation>> annotationMap = <int, List<Annotation>>{};
417 for (Annotation annotation in annotations) { 378 for (Annotation annotation in annotations) {
418 annotationMap.putIfAbsent(annotation.codeOffset, () => <Annotation>[]) 379 annotationMap.putIfAbsent(annotation.codeOffset, () => <Annotation>[])
419 .add(annotation); 380 .add(annotation);
420 } 381 }
421 382
422 bool first = true; 383 bool first = true;
423 for (int codeOffset in annotationMap.keys.toList()..sort()) { 384 for (int codeOffset in annotationMap.keys.toList()..sort()) {
424 List<Annotation> annotationList = annotationMap[codeOffset]; 385 List<Annotation> annotationList = annotationMap[codeOffset];
425 addSubstring(codeOffset, isFirst: first); 386 addSubstring(codeOffset, isFirst: first);
426 insertAnnotations(annotationList); 387 insertAnnotations(annotationList);
427 first = false; 388 first = false;
428 } 389 }
429 390
430 addSubstring(code.length, isFirst: first, isLast: true); 391 addSubstring(code.length, isFirst: first, isLast: true);
431 endCurrentLocation(); 392 endCurrentLocation();
432 393
433 int start = 0; 394 int start = startLine ?? 0;
434 int end = lines.length - 1; 395 int end = endLine ?? lines.length - 1;
435 if (windowSize != null) { 396 if (windowSize != null) {
436 start = Math.max(firstLine - windowSize, start); 397 start = Math.max(firstLine - windowSize, start);
437 end = Math.min(lastLine + windowSize, end); 398 end = Math.min(lastLine + windowSize, end);
438 } 399 }
439 return lines.sublist(start, end); 400 return lines.sublist(start, end);
440 } 401 }
441 402
442 /// Computes the HTML representation for a collection of JavaScript code blocks. 403 /// Computes the HTML representation for a collection of JavaScript code blocks.
443 String computeJsHtml(Iterable<SourceMapHtmlInfo> infoList) { 404 String computeJsHtml(Iterable<SourceMapHtmlInfo> infoList) {
444 405
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
680 String dartCode = truncate(codePoint.dartCode, 50); 641 String dartCode = truncate(codePoint.dartCode, 50);
681 buffer.write('<td class="code">${dartCode}</td>'); 642 buffer.write('<td class="code">${dartCode}</td>');
682 buffer.write('<td>${escape(codePoint.sourceLocation.shortText)}</td>'); 643 buffer.write('<td>${escape(codePoint.sourceLocation.shortText)}</td>');
683 } 644 }
684 buffer.write('</tr>'); 645 buffer.write('</tr>');
685 }); 646 });
686 buffer.write('</table>'); 647 buffer.write('</table>');
687 648
688 return buffer.toString(); 649 return buffer.toString();
689 } 650 }
OLDNEW
« no previous file with comments | « tests/compiler/dart2js/sourcemaps/sourcemap_helper.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698