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

Side by Side Diff: tests/compiler/dart2js/sourcemaps/diff_view.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) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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:convert'; 8 import 'dart:convert';
9 import 'dart:io'; 9 import 'dart:io';
10 10
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 } 83 }
84 84
85 SourceFileManager sourceFileManager = new IOSourceFileManager(Uri.base); 85 SourceFileManager sourceFileManager = new IOSourceFileManager(Uri.base);
86 List<AnnotatedOutput> outputs = <AnnotatedOutput>[]; 86 List<AnnotatedOutput> outputs = <AnnotatedOutput>[];
87 for (int i = 0; i < 2; i++) { 87 for (int i = 0; i < 2; i++) {
88 AnnotatedOutput output; 88 AnnotatedOutput output;
89 if (loadFrom.containsKey(i)) { 89 if (loadFrom.containsKey(i)) {
90 output = AnnotatedOutput.loadOutput(loadFrom[i]); 90 output = AnnotatedOutput.loadOutput(loadFrom[i]);
91 } else { 91 } else {
92 print('Compiling ${options[i].join(' ')} $filename'); 92 print('Compiling ${options[i].join(' ')} $filename');
93 CodeLinesResult result = await computeCodeLines( 93 CodeLinesResult result = await computeCodeLines(options[i], filename);
94 options[i], filename);
95 OutputStructure structure = OutputStructure.parse(result.codeLines); 94 OutputStructure structure = OutputStructure.parse(result.codeLines);
96 computeEntityCodeSources(result, structure); 95 computeEntityCodeSources(result, structure);
97 output = new AnnotatedOutput( 96 output = new AnnotatedOutput(
98 filename, 97 filename, options[i], structure, result.coverage.getCoverageReport());
99 options[i],
100 structure,
101 result.coverage.getCoverageReport());
102 } 98 }
103 if (saveTo.containsKey(i)) { 99 if (saveTo.containsKey(i)) {
104 AnnotatedOutput.saveOutput(output, saveTo[i]); 100 AnnotatedOutput.saveOutput(output, saveTo[i]);
105 } 101 }
106 outputs.add(output); 102 outputs.add(output);
107 } 103 }
108 104
109 List<DiffBlock> blocks = createDiffBlocks( 105 List<DiffBlock> blocks = createDiffBlocks(
110 outputs.map((o) => o.structure).toList(), 106 outputs.map((o) => o.structure).toList(), sourceFileManager);
111 sourceFileManager);
112 107
113 outputDiffView( 108 outputDiffView(out, outputs, blocks,
114 out, outputs, blocks, 109 showMarkers: showAnnotations, showSourceMapped: showAnnotations);
115 showMarkers: showAnnotations,
116 showSourceMapped: showAnnotations);
117 } 110 }
118 111
119 /// Attaches [CodeSource]s to the entities in [structure] using the 112 /// Attaches [CodeSource]s to the entities in [structure] using the
120 /// element-to-offset in [result]. 113 /// element-to-offset in [result].
121 void computeEntityCodeSources( 114 void computeEntityCodeSources(
122 CodeLinesResult result, OutputStructure structure) { 115 CodeLinesResult result, OutputStructure structure) {
123 result.elementMap.forEach((int line, Element element) { 116 result.elementMap.forEach((int line, Element element) {
124 OutputEntity entity = structure.getEntityForLine(line); 117 OutputEntity entity = structure.getEntityForLine(line);
125 if (entity != null) { 118 if (entity != null) {
126 entity.codeSource = codeSourceFromElement(element); 119 entity.codeSource = codeSourceFromElement(element);
127 } 120 }
128 }); 121 });
129 } 122 }
130 123
131 class CodeLineAnnotationJsonStrategy implements JsonStrategy { 124 class CodeLineAnnotationJsonStrategy implements JsonStrategy {
132 const CodeLineAnnotationJsonStrategy(); 125 const CodeLineAnnotationJsonStrategy();
133 126
134 Map encodeAnnotation(Annotation annotation) { 127 Map encodeAnnotation(Annotation annotation) {
135 CodeLineAnnotation data = annotation.data; 128 CodeLineAnnotation data = annotation.data;
136 return { 129 return {
137 'id': annotation.id, 130 'id': annotation.id,
138 'codeOffset': annotation.codeOffset, 131 'codeOffset': annotation.codeOffset,
139 'title': annotation.title, 132 'title': annotation.title,
140 'data': data.toJson(this), 133 'data': data.toJson(this),
141 }; 134 };
142 } 135 }
143 136
144 Annotation decodeAnnotation(Map json) { 137 Annotation decodeAnnotation(Map json) {
145 return new Annotation( 138 return new Annotation(json['id'], json['codeOffset'], json['title'],
146 json['id'],
147 json['codeOffset'],
148 json['title'],
149 data: CodeLineAnnotation.fromJson(json['data'], this)); 139 data: CodeLineAnnotation.fromJson(json['data'], this));
150 } 140 }
151 141
152 @override 142 @override
153 decodeLineAnnotation(json) { 143 decodeLineAnnotation(json) {
154 if (json != null) { 144 if (json != null) {
155 return CodeSource.fromJson(json); 145 return CodeSource.fromJson(json);
156 } 146 }
157 return null; 147 return null;
158 } 148 }
(...skipping 30 matching lines...) Expand all
189 static AnnotatedOutput fromJson(Map json) { 179 static AnnotatedOutput fromJson(Map json) {
190 String filename = json['filename']; 180 String filename = json['filename'];
191 List<String> options = json['options']; 181 List<String> options = json['options'];
192 OutputStructure structure = OutputStructure.fromJson( 182 OutputStructure structure = OutputStructure.fromJson(
193 json['structure'], const CodeLineAnnotationJsonStrategy()); 183 json['structure'], const CodeLineAnnotationJsonStrategy());
194 String coverage = json['coverage']; 184 String coverage = json['coverage'];
195 return new AnnotatedOutput(filename, options, structure, coverage); 185 return new AnnotatedOutput(filename, options, structure, coverage);
196 } 186 }
197 187
198 static AnnotatedOutput loadOutput(filename) { 188 static AnnotatedOutput loadOutput(filename) {
199 AnnotatedOutput output = AnnotatedOutput.fromJson( 189 AnnotatedOutput output = AnnotatedOutput
200 JSON.decode(new File(filename).readAsStringSync())); 190 .fromJson(JSON.decode(new File(filename).readAsStringSync()));
201 print('Output loaded from $filename'); 191 print('Output loaded from $filename');
202 return output; 192 return output;
203 } 193 }
204 194
205 static void saveOutput(AnnotatedOutput output, String filename) { 195 static void saveOutput(AnnotatedOutput output, String filename) {
206 if (filename != null) { 196 if (filename != null) {
207 new File(filename).writeAsStringSync( 197 new File(filename).writeAsStringSync(
208 const JsonEncoder.withIndent(' ').convert(output.toJson())); 198 const JsonEncoder.withIndent(' ').convert(output.toJson()));
209 print('Output saved in $filename'); 199 print('Output saved in $filename');
210 } 200 }
211 } 201 }
212 } 202 }
213 203
214 void outputDiffView( 204 void outputDiffView(
215 String out, 205 String out, List<AnnotatedOutput> outputs, List<DiffBlock> blocks,
216 List<AnnotatedOutput> outputs, 206 {bool showMarkers: true, bool showSourceMapped: true}) {
217 List<DiffBlock> blocks,
218 {bool showMarkers: true,
219 bool showSourceMapped: true}) {
220 assert(outputs[0].filename == outputs[1].filename); 207 assert(outputs[0].filename == outputs[1].filename);
221 bool usePre = true; 208 bool usePre = true;
222 209
223 StringBuffer sb = new StringBuffer(); 210 StringBuffer sb = new StringBuffer();
224 sb.write(''' 211 sb.write('''
225 <html> 212 <html>
226 <head> 213 <head>
227 <title>Diff for ${outputs[0].filename}</title> 214 <title>Diff for ${outputs[0].filename}</title>
228 <style> 215 <style>
229 .${ClassNames.lineNumber} { 216 .${ClassNames.lineNumber} {
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
472 sb.write(''' 459 sb.write('''
473 <span class="${ClassNames.sourceMappingIndex(i)}">&nbsp;&nbsp;</span>'''); 460 <span class="${ClassNames.sourceMappingIndex(i)}">&nbsp;&nbsp;</span>''');
474 } 461 }
475 sb.write(''' 462 sb.write('''
476 <span title="JavaScript offsets and their corresponding Dart Code offset 463 <span title="JavaScript offsets and their corresponding Dart Code offset
477 as mapped through source-maps."> 464 as mapped through source-maps.">
478 mapped source locations</span> 465 mapped source locations</span>
479 </span> 466 </span>
480 '''); 467 ''');
481 468
482
483 /// Marker to alternate output colors. 469 /// Marker to alternate output colors.
484 bool alternating = false; 470 bool alternating = false;
485 471
486 List<HtmlPrintContext> printContexts = <HtmlPrintContext>[]; 472 List<HtmlPrintContext> printContexts = <HtmlPrintContext>[];
487 for (int i = 0; i < 2; i++) { 473 for (int i = 0; i < 2; i++) {
488 int lineNoWidth; 474 int lineNoWidth;
489 if (outputs[i].codeLines.isNotEmpty) { 475 if (outputs[i].codeLines.isNotEmpty) {
490 lineNoWidth = '${outputs[i].codeLines.last.lineNo + 1}'.length; 476 lineNoWidth = '${outputs[i].codeLines.last.lineNo + 1}'.length;
491 } 477 }
492 printContexts.add(new HtmlPrintContext( 478 printContexts.add(new HtmlPrintContext(
493 lineNoWidth: lineNoWidth, 479 lineNoWidth: lineNoWidth,
494 getAnnotationData: getAnnotationData, 480 getAnnotationData: getAnnotationData,
495 getLineData: getLineData)); 481 getLineData: getLineData));
496 } 482 }
497 483
498 Set<DiffColumn> allColumns = new Set<DiffColumn>(); 484 Set<DiffColumn> allColumns = new Set<DiffColumn>();
499 for (DiffBlock block in blocks) { 485 for (DiffBlock block in blocks) {
500 allColumns.addAll(block.columns); 486 allColumns.addAll(block.columns);
501 } 487 }
502 488
503 List<DiffColumn> columns = [column_js0, column_js1, column_dart] 489 List<DiffColumn> columns = [column_js0, column_js1, column_dart]
504 .where((c) => allColumns.contains(c)).toList(); 490 .where((c) => allColumns.contains(c))
491 .toList();
505 492
506 sb.write(''' 493 sb.write('''
507 </div> 494 </div>
508 <table class="${ClassNames.headerTable}"><tr>'''); 495 <table class="${ClassNames.headerTable}"><tr>''');
509 for (DiffColumn column in columns) { 496 for (DiffColumn column in columns) {
510 sb.write(''' 497 sb.write('''
511 <td class="${ClassNames.headerColumn} ${ClassNames.column(column)}">'''); 498 <td class="${ClassNames.headerColumn} ${ClassNames.column(column)}">''');
512 if (column.type == 'js') { 499 if (column.type == 'js') {
513 sb.write('''[${outputs[column.index].options.join(',')}]'''); 500 sb.write('''[${outputs[column.index].options.join(',')}]''');
514 } else { 501 } else {
(...skipping 13 matching lines...) Expand all
528 switch (block.kind) { 515 switch (block.kind) {
529 case DiffKind.UNMATCHED: 516 case DiffKind.UNMATCHED:
530 className = '${ClassNames.cell}'; 517 className = '${ClassNames.cell}';
531 break; 518 break;
532 case DiffKind.MATCHING: 519 case DiffKind.MATCHING:
533 className = 520 className =
534 '${ClassNames.cell} ${ClassNames.corresponding(alternating)}'; 521 '${ClassNames.cell} ${ClassNames.corresponding(alternating)}';
535 alternating = !alternating; 522 alternating = !alternating;
536 break; 523 break;
537 case DiffKind.IDENTICAL: 524 case DiffKind.IDENTICAL:
538 className = 525 className = '${ClassNames.cell} ${ClassNames.identical(alternating)}';
539 '${ClassNames.cell} ${ClassNames.identical(alternating)}';
540 alternating = !alternating; 526 alternating = !alternating;
541 break; 527 break;
542 } 528 }
543 sb.write('<tr>'); 529 sb.write('<tr>');
544 for (DiffColumn column in columns) { 530 for (DiffColumn column in columns) {
545 sb.write('''<td class="$className ${ClassNames.column(column)}">'''); 531 sb.write('''<td class="$className ${ClassNames.column(column)}">''');
546 HtmlPrintContext context = new HtmlPrintContext( 532 HtmlPrintContext context = new HtmlPrintContext(
547 lineNoWidth: 4, 533 lineNoWidth: 4,
548 includeAnnotation: (Annotation annotation) { 534 includeAnnotation: (Annotation annotation) {
549 CodeLineAnnotation data = annotation.data; 535 CodeLineAnnotation data = annotation.data;
550 return data.annotationType == AnnotationType.WITH_SOURCE_INFO || 536 return data.annotationType == AnnotationType.WITH_SOURCE_INFO ||
551 data.annotationType == AnnotationType.ADDITIONAL_SOURCE_INFO; 537 data.annotationType == AnnotationType.ADDITIONAL_SOURCE_INFO;
552 }, 538 },
553 getAnnotationData: getAnnotationData, 539 getAnnotationData: getAnnotationData,
554 getLineData: getLineData); 540 getLineData: getLineData);
555 if (column.type == 'js') { 541 if (column.type == 'js') {
556 context = printContexts[column.index]; 542 context = printContexts[column.index];
557 } 543 }
558 block.printHtmlOn(column, sb, context); 544 block.printHtmlOn(column, sb, context);
559 sb.write('''</td>'''); 545 sb.write('''</td>''');
560 } 546 }
561 sb.write('</tr>'); 547 sb.write('</tr>');
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 print('Diff generated in $out'); 602 print('Diff generated in $out');
617 } 603 }
618 604
619 class CodeLinesResult { 605 class CodeLinesResult {
620 final List<CodeLine> codeLines; 606 final List<CodeLine> codeLines;
621 final Coverage coverage; 607 final Coverage coverage;
622 final Map<int, Element> elementMap; 608 final Map<int, Element> elementMap;
623 final SourceFileManager sourceFileManager; 609 final SourceFileManager sourceFileManager;
624 final CodeSources codeSources; 610 final CodeSources codeSources;
625 611
626 CodeLinesResult( 612 CodeLinesResult(this.codeLines, this.coverage, this.elementMap,
627 this.codeLines, 613 this.sourceFileManager, this.codeSources);
628 this.coverage,
629 this.elementMap,
630 this.sourceFileManager,
631 this.codeSources);
632 } 614 }
633 615
634 class CodeSources { 616 class CodeSources {
635 Map<Element, CodeSource> codeSourceMap = <Element, CodeSource>{}; 617 Map<Element, CodeSource> codeSourceMap = <Element, CodeSource>{};
636 Map<Uri, Map<Interval, CodeSource>> uriCodeSourceMap = 618 Map<Uri, Map<Interval, CodeSource>> uriCodeSourceMap =
637 <Uri, Map<Interval, CodeSource>>{}; 619 <Uri, Map<Interval, CodeSource>>{};
638 620
639 CodeSources( 621 CodeSources(SourceMapProcessor processor, SourceMaps sourceMaps) {
640 SourceMapProcessor processor,
641 SourceMaps sourceMaps) {
642
643 CodeSource computeCodeSource(Element element) { 622 CodeSource computeCodeSource(Element element) {
644 return codeSourceMap.putIfAbsent(element, () { 623 return codeSourceMap.putIfAbsent(element, () {
645 CodeSource codeSource = codeSourceFromElement(element); 624 CodeSource codeSource = codeSourceFromElement(element);
646 if (codeSource.begin != null) { 625 if (codeSource.begin != null) {
647 Interval interval = new Interval(codeSource.begin, codeSource.end); 626 Interval interval = new Interval(codeSource.begin, codeSource.end);
648 Map<Interval, CodeSource> intervals = 627 Map<Interval, CodeSource> intervals =
649 uriCodeSourceMap[codeSource.uri]; 628 uriCodeSourceMap[codeSource.uri];
650 if (intervals == null) { 629 if (intervals == null) {
651 intervals = <Interval, CodeSource>{}; 630 intervals = <Interval, CodeSource>{};
652 uriCodeSourceMap[codeSource.uri] = intervals; 631 uriCodeSourceMap[codeSource.uri] = intervals;
653 } else { 632 } else {
654 for (Interval existingInterval in intervals.keys.toList()) { 633 for (Interval existingInterval in intervals.keys.toList()) {
655 if (existingInterval.contains(interval.from)) { 634 if (existingInterval.contains(interval.from)) {
656 CodeSource existingCodeSource = intervals[existingInterval]; 635 CodeSource existingCodeSource = intervals[existingInterval];
657 intervals.remove(existingInterval); 636 intervals.remove(existingInterval);
658 if (existingInterval.from < interval.from) { 637 if (existingInterval.from < interval.from) {
659 Interval preInterval = new Interval( 638 Interval preInterval =
660 existingInterval.from, interval.from); 639 new Interval(existingInterval.from, interval.from);
661 intervals[preInterval] = existingCodeSource; 640 intervals[preInterval] = existingCodeSource;
662 } 641 }
663 if (interval.to < existingInterval.to) { 642 if (interval.to < existingInterval.to) {
664 Interval postInterval = new Interval( 643 Interval postInterval =
665 interval.to, existingInterval.to); 644 new Interval(interval.to, existingInterval.to);
666 intervals[postInterval] = existingCodeSource; 645 intervals[postInterval] = existingCodeSource;
667 } 646 }
668 } 647 }
669 } 648 }
670 } 649 }
671 intervals[interval] = codeSource; 650 intervals[interval] = codeSource;
672 } 651 }
673 if (element is ClassElement) { 652 if (element is ClassElement) {
674 element.forEachLocalMember((Element member) { 653 element.forEachLocalMember((Element member) {
675 codeSource.members.add(computeCodeSource(member)); 654 codeSource.members.add(computeCodeSource(member));
676 }); 655 });
677 element.implementation.forEachLocalMember((Element member) { 656 element.implementation.forEachLocalMember((Element member) {
678 codeSource.members.add(computeCodeSource(member)); 657 codeSource.members.add(computeCodeSource(member));
679 }); 658 });
680 } else if (element is MemberElement) { 659 } else if (element is MemberElement) {
681 element.nestedClosures.forEach((Element closure) { 660 element.nestedClosures.forEach((Element closure) {
682 codeSource.members.add(computeCodeSource(closure)); 661 codeSource.members.add(computeCodeSource(closure));
683 }); 662 });
684 } 663 }
685 return codeSource; 664 return codeSource;
686 }); 665 });
687 } 666 }
688 667
689 for (LibraryElement library in 668 for (LibraryElement library
690 sourceMaps.compiler.libraryLoader.libraries) { 669 in sourceMaps.compiler.libraryLoader.libraries) {
691 library.forEachLocalMember(computeCodeSource); 670 library.forEachLocalMember(computeCodeSource);
692 library.implementation.forEachLocalMember(computeCodeSource); 671 library.implementation.forEachLocalMember(computeCodeSource);
693 } 672 }
694 673
695 uriCodeSourceMap.forEach((Uri uri, Map<Interval, CodeSource> intervals) { 674 uriCodeSourceMap.forEach((Uri uri, Map<Interval, CodeSource> intervals) {
696 List<Interval> sortedKeys = intervals.keys.toList()..sort( 675 List<Interval> sortedKeys = intervals.keys.toList()
697 (i1, i2) => i1.from.compareTo(i2.from)); 676 ..sort((i1, i2) => i1.from.compareTo(i2.from));
698 Map<Interval, CodeSource> sortedintervals = <Interval, CodeSource>{}; 677 Map<Interval, CodeSource> sortedintervals = <Interval, CodeSource>{};
699 sortedKeys.forEach((Interval interval) { 678 sortedKeys.forEach((Interval interval) {
700 sortedintervals[interval] = intervals[interval]; 679 sortedintervals[interval] = intervals[interval];
701 }); 680 });
702 uriCodeSourceMap[uri] = sortedintervals; 681 uriCodeSourceMap[uri] = sortedintervals;
703 }); 682 });
704 } 683 }
705 684
706 CodeSource sourceLocationToCodeSource(SourceLocation sourceLocation) { 685 CodeSource sourceLocationToCodeSource(SourceLocation sourceLocation) {
707 Map<Interval, CodeSource> intervals = 686 Map<Interval, CodeSource> intervals =
708 uriCodeSourceMap[sourceLocation.sourceUri]; 687 uriCodeSourceMap[sourceLocation.sourceUri];
709 if (intervals == null) { 688 if (intervals == null) {
710 print('No code source for $sourceLocation(${sourceLocation.offset})'); 689 print('No code source for $sourceLocation(${sourceLocation.offset})');
711 print(' -- no intervals for ${sourceLocation.sourceUri}'); 690 print(' -- no intervals for ${sourceLocation.sourceUri}');
712 return null; 691 return null;
713 } 692 }
714 for (Interval interval in intervals.keys) { 693 for (Interval interval in intervals.keys) {
715 if (interval.contains(sourceLocation.offset)) { 694 if (interval.contains(sourceLocation.offset)) {
716 return intervals[interval]; 695 return intervals[interval];
717 } 696 }
718 } 697 }
719 print('No code source for $sourceLocation(${sourceLocation.offset})'); 698 print('No code source for $sourceLocation(${sourceLocation.offset})');
720 intervals.forEach((k, v) => print(' $k: ${v.name}')); 699 intervals.forEach((k, v) => print(' $k: ${v.name}'));
721 return null; 700 return null;
722 } 701 }
723 } 702 }
724 703
725 /// Compute [CodeLine]s and [Coverage] for [filename] using the given [options]. 704 /// Compute [CodeLine]s and [Coverage] for [filename] using the given [options].
726 Future<CodeLinesResult> computeCodeLines( 705 Future<CodeLinesResult> computeCodeLines(
727 List<String> options, 706 List<String> options, String filename) async {
728 String filename) async {
729 SourceMapProcessor processor = new SourceMapProcessor(filename); 707 SourceMapProcessor processor = new SourceMapProcessor(filename);
730 SourceMaps sourceMaps = 708 SourceMaps sourceMaps =
731 await processor.process(options, perElement: true, forMain: true); 709 await processor.process(options, perElement: true, forMain: true);
732 710
733 CodeSources codeSources = new CodeSources(processor, sourceMaps); 711 CodeSources codeSources = new CodeSources(processor, sourceMaps);
734 712
735 SourceMapInfo info = sourceMaps.mainSourceMapInfo; 713 SourceMapInfo info = sourceMaps.mainSourceMapInfo;
736 714
737 int nextAnnotationId = 0; 715 int nextAnnotationId = 0;
738 List<CodeLine> codeLines; 716 List<CodeLine> codeLines;
739 Coverage coverage = new Coverage(); 717 Coverage coverage = new Coverage();
740 Map<int, List<CodeLineAnnotation>> codeLineAnnotationMap = 718 Map<int, List<CodeLineAnnotation>> codeLineAnnotationMap =
741 <int, List<CodeLineAnnotation>>{}; 719 <int, List<CodeLineAnnotation>>{};
742 720
743 /// Create a [CodeLineAnnotation] for [codeOffset]. 721 /// Create a [CodeLineAnnotation] for [codeOffset].
744 void addCodeLineAnnotation( 722 void addCodeLineAnnotation(
745 {AnnotationType annotationType, 723 {AnnotationType annotationType,
746 int codeOffset, 724 int codeOffset,
747 List<SourceLocation> locations: const <SourceLocation>[], 725 List<SourceLocation> locations: const <SourceLocation>[],
748 String stepInfo}) { 726 String stepInfo}) {
749 if (annotationType == AnnotationType.WITHOUT_SOURCE_INFO || 727 if (annotationType == AnnotationType.WITHOUT_SOURCE_INFO ||
750 annotationType == AnnotationType.UNUSED_SOURCE_INFO) { 728 annotationType == AnnotationType.UNUSED_SOURCE_INFO) {
751 locations = []; 729 locations = [];
752 } 730 }
753 List<CodeLocation> codeLocations = locations 731 List<CodeLocation> codeLocations = locations
754 .map((l) => new CodeLocation(l.sourceUri, l.sourceName, l.offset)) 732 .map((l) => new CodeLocation(l.sourceUri, l.sourceName, l.offset))
755 .toList(); 733 .toList();
756 List<CodeSource> codeSourceList = locations 734 List<CodeSource> codeSourceList = locations
757 .map(codeSources.sourceLocationToCodeSource) 735 .map(codeSources.sourceLocationToCodeSource)
758 .where((c) => c != null) 736 .where((c) => c != null)
759 .toList(); 737 .toList();
760 CodeLineAnnotation data = new CodeLineAnnotation( 738 CodeLineAnnotation data = new CodeLineAnnotation(
761 annotationId: nextAnnotationId++, 739 annotationId: nextAnnotationId++,
762 annotationType: annotationType, 740 annotationType: annotationType,
763 codeLocations: codeLocations, 741 codeLocations: codeLocations,
764 codeSources: codeSourceList, 742 codeSources: codeSourceList,
765 stepInfo: stepInfo); 743 stepInfo: stepInfo);
766 codeLineAnnotationMap.putIfAbsent( 744 codeLineAnnotationMap
767 codeOffset, () => <CodeLineAnnotation>[]).add(data); 745 .putIfAbsent(codeOffset, () => <CodeLineAnnotation>[])
746 .add(data);
768 } 747 }
769 748
770 String code = info.code; 749 String code = info.code;
771 TraceGraph graph = createTraceGraph(info, coverage); 750 TraceGraph graph = createTraceGraph(info, coverage);
772 751
773 Set<js.Node> mappedNodes = new Set<js.Node>(); 752 Set<js.Node> mappedNodes = new Set<js.Node>();
774 753
775 /// Add an annotation for [codeOffset] pointing to [locations]. 754 /// Add an annotation for [codeOffset] pointing to [locations].
776 void addSourceLocations( 755 void addSourceLocations(
777 {AnnotationType annotationType, 756 {AnnotationType annotationType,
778 int codeOffset, 757 int codeOffset,
779 List<SourceLocation> locations, 758 List<SourceLocation> locations,
780 String stepInfo}) { 759 String stepInfo}) {
781 locations = locations.where((l) => l != null).toList(); 760 locations = locations.where((l) => l != null).toList();
782 addCodeLineAnnotation( 761 addCodeLineAnnotation(
783 annotationType: annotationType, 762 annotationType: annotationType,
784 codeOffset: codeOffset, 763 codeOffset: codeOffset,
785 stepInfo: stepInfo, 764 stepInfo: stepInfo,
786 locations: locations); 765 locations: locations);
787 } 766 }
788 767
789 /// Add annotations for all mappings created for [node]. 768 /// Add annotations for all mappings created for [node].
790 bool addSourceLocationsForNode( 769 bool addSourceLocationsForNode(
791 {AnnotationType annotationType, 770 {AnnotationType annotationType, js.Node node, String stepInfo}) {
792 js.Node node,
793 String stepInfo}) {
794 Map<int, List<SourceLocation>> locations = info.nodeMap[node]; 771 Map<int, List<SourceLocation>> locations = info.nodeMap[node];
795 if (locations == null || locations.isEmpty) { 772 if (locations == null || locations.isEmpty) {
796 return false; 773 return false;
797 } 774 }
798 locations.forEach((int offset, List<SourceLocation> locations) { 775 locations.forEach((int offset, List<SourceLocation> locations) {
799 addSourceLocations( 776 addSourceLocations(
800 annotationType: annotationType, 777 annotationType: annotationType,
801 codeOffset: offset, 778 codeOffset: offset,
802 locations: locations, 779 locations: locations,
803 stepInfo: stepInfo); 780 stepInfo: stepInfo);
(...skipping 22 matching lines...) Expand all
826 codeOffset: offset, 803 codeOffset: offset,
827 stepInfo: stepInfo); 804 stepInfo: stepInfo);
828 } 805 }
829 } 806 }
830 } 807 }
831 808
832 // Add additional annotations for mappings created for particular nodes. 809 // Add additional annotations for mappings created for particular nodes.
833 for (js.Node node in info.nodeMap.nodes) { 810 for (js.Node node in info.nodeMap.nodes) {
834 if (!mappedNodes.contains(node)) { 811 if (!mappedNodes.contains(node)) {
835 addSourceLocationsForNode( 812 addSourceLocationsForNode(
836 annotationType: AnnotationType.ADDITIONAL_SOURCE_INFO, 813 annotationType: AnnotationType.ADDITIONAL_SOURCE_INFO, node: node);
837 node: node);
838 } 814 }
839 } 815 }
840 816
841 // Add annotations for unused source information associated with nodes. 817 // Add annotations for unused source information associated with nodes.
842 SourceLocationCollector collector = new SourceLocationCollector(); 818 SourceLocationCollector collector = new SourceLocationCollector();
843 info.node.accept(collector); 819 info.node.accept(collector);
844 collector.sourceLocations.forEach( 820 collector.sourceLocations
845 (js.Node node, List<SourceLocation> locations) { 821 .forEach((js.Node node, List<SourceLocation> locations) {
846 if (!mappedNodes.contains(node)) { 822 if (!mappedNodes.contains(node)) {
847 int offset = info.jsCodePositions[node].startPosition; 823 int offset = info.jsCodePositions[node].startPosition;
848 addSourceLocations( 824 addSourceLocations(
849 annotationType: AnnotationType.UNUSED_SOURCE_INFO, 825 annotationType: AnnotationType.UNUSED_SOURCE_INFO,
850 codeOffset: offset, 826 codeOffset: offset,
851 locations: locations); 827 locations: locations);
852 } 828 }
853 }); 829 });
854 830
855 // Assign consecutive ids to source mappings. 831 // Assign consecutive ids to source mappings.
856 int nextSourceMappedLocationIndex = 0; 832 int nextSourceMappedLocationIndex = 0;
857 List<Annotation> annotations = <Annotation>[]; 833 List<Annotation> annotations = <Annotation>[];
858 for (int codeOffset in codeLineAnnotationMap.keys.toList()..sort()) { 834 for (int codeOffset in codeLineAnnotationMap.keys.toList()..sort()) {
859 bool hasSourceMappedLocation = false; 835 bool hasSourceMappedLocation = false;
860 for (CodeLineAnnotation data in codeLineAnnotationMap[codeOffset]) { 836 for (CodeLineAnnotation data in codeLineAnnotationMap[codeOffset]) {
861 if (data.annotationType.isSourceMapped) { 837 if (data.annotationType.isSourceMapped) {
862 data.sourceMappingIndex = nextSourceMappedLocationIndex; 838 data.sourceMappingIndex = nextSourceMappedLocationIndex;
863 hasSourceMappedLocation = true; 839 hasSourceMappedLocation = true;
864 } 840 }
865 annotations.add(new Annotation( 841 annotations.add(new Annotation(
866 data.annotationType.index, 842 data.annotationType.index, codeOffset, 'id=${data.annotationId}',
867 codeOffset,
868 'id=${data.annotationId}',
869 data: data)); 843 data: data));
870 } 844 }
871 if (hasSourceMappedLocation) { 845 if (hasSourceMappedLocation) {
872 nextSourceMappedLocationIndex++; 846 nextSourceMappedLocationIndex++;
873 } 847 }
874 } 848 }
875 849
876 // Associate JavaScript offsets with [Element]s. 850 // Associate JavaScript offsets with [Element]s.
877 StringSourceFile sourceFile = new StringSourceFile.fromName(filename, code); 851 StringSourceFile sourceFile = new StringSourceFile.fromName(filename, code);
878 Map<int, Element> elementMap = <int, Element>{}; 852 Map<int, Element> elementMap = <int, Element>{};
879 sourceMaps.elementSourceMapInfos.forEach( 853 sourceMaps.elementSourceMapInfos
880 (Element element, SourceMapInfo info) { 854 .forEach((Element element, SourceMapInfo info) {
881 CodePosition position = info.jsCodePositions[info.node]; 855 CodePosition position = info.jsCodePositions[info.node];
882 elementMap[sourceFile.getLine(position.startPosition)] = element; 856 elementMap[sourceFile.getLine(position.startPosition)] = element;
883 }); 857 });
884 858
885 codeLines = convertAnnotatedCodeToCodeLines(code, annotations); 859 codeLines = convertAnnotatedCodeToCodeLines(code, annotations);
886 return new CodeLinesResult( 860 return new CodeLinesResult(codeLines, coverage, elementMap,
887 codeLines, coverage, elementMap, 861 sourceMaps.sourceFileManager, codeSources);
888 sourceMaps.sourceFileManager,
889 codeSources);
890 } 862 }
891 863
892 /// Visitor that computes a map from [js.Node]s to all attached source 864 /// Visitor that computes a map from [js.Node]s to all attached source
893 /// locations. 865 /// locations.
894 class SourceLocationCollector extends js.BaseVisitor { 866 class SourceLocationCollector extends js.BaseVisitor {
895 Map<js.Node, List<SourceLocation>> sourceLocations = 867 Map<js.Node, List<SourceLocation>> sourceLocations =
896 <js.Node, List<SourceLocation>>{}; 868 <js.Node, List<SourceLocation>>{};
897 869
898 @override 870 @override
899 visitNode(js.Node node) { 871 visitNode(js.Node node) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
933 } 905 }
934 return new CodeSource(kind, uri, name, begin, end); 906 return new CodeSource(kind, uri, name, begin, end);
935 } 907 }
936 908
937 /// Create [LineData] that colors line numbers according to the [CodeSource]s 909 /// Create [LineData] that colors line numbers according to the [CodeSource]s
938 /// origin if available. 910 /// origin if available.
939 LineData getLineData(CodeSource lineAnnotation) { 911 LineData getLineData(CodeSource lineAnnotation) {
940 if (lineAnnotation != null) { 912 if (lineAnnotation != null) {
941 return new LineData( 913 return new LineData(
942 lineClass: ClassNames.line, 914 lineClass: ClassNames.line,
943 lineNumberClass: 915 lineNumberClass: '${ClassNames.lineNumber} '
944 '${ClassNames.lineNumber} ' 916 '${ClassNames.colored(lineAnnotation.hashCode % 4)}');
945 '${ClassNames.colored(lineAnnotation.hashCode % 4)}');
946 } 917 }
947 return new LineData( 918 return new LineData(
948 lineClass: ClassNames.line, 919 lineClass: ClassNames.line, lineNumberClass: ClassNames.lineNumber);
949 lineNumberClass: ClassNames.lineNumber);
950 } 920 }
951 921
952 AnnotationData getAnnotationData(Iterable<Annotation> annotations, 922 AnnotationData getAnnotationData(Iterable<Annotation> annotations,
953 {bool forSpan}) { 923 {bool forSpan}) {
954 for (Annotation annotation in annotations) { 924 for (Annotation annotation in annotations) {
955 CodeLineAnnotation data = annotation.data; 925 CodeLineAnnotation data = annotation.data;
956 if (data.annotationType.isSourceMapped) { 926 if (data.annotationType.isSourceMapped) {
957 if (forSpan) { 927 if (forSpan) {
958 int index = data.sourceMappingIndex; 928 int index = data.sourceMappingIndex;
959 return new AnnotationData( 929 return new AnnotationData(tag: 'span', properties: {
960 tag: 'span', 930 'class': '${ClassNames.sourceMapping} '
961 properties: { 931 '${ClassNames.sourceMappingIndex(index % HUE_COUNT)}',
962 'class': 932 'title': 'index=$index',
963 '${ClassNames.sourceMapping} ' 933 });
964 '${ClassNames.sourceMappingIndex(index % HUE_COUNT)}',
965 'title': 'index=$index',
966 });
967 } else { 934 } else {
968 return new AnnotationData( 935 return new AnnotationData(tag: 'span', properties: {
969 tag: 'span', 936 'title': annotation.title,
970 properties: { 937 'class': '${ClassNames.marker} '
971 'title': annotation.title, 938 '${data.annotationType.className}'
972 'class': '${ClassNames.marker} ' 939 });
973 '${data.annotationType.className}'});
974 } 940 }
975 } 941 }
976 } 942 }
977 if (forSpan) return null; 943 if (forSpan) return null;
978 for (Annotation annotation in annotations) { 944 for (Annotation annotation in annotations) {
979 CodeLineAnnotation data = annotation.data; 945 CodeLineAnnotation data = annotation.data;
980 if (data.annotationType == AnnotationType.UNUSED_SOURCE_INFO) { 946 if (data.annotationType == AnnotationType.UNUSED_SOURCE_INFO) {
981 return new AnnotationData( 947 return new AnnotationData(tag: 'span', properties: {
982 tag: 'span', 948 'title': annotation.title,
983 properties: { 949 'class': '${ClassNames.marker} '
984 'title': annotation.title, 950 '${data.annotationType.className}'
985 'class': '${ClassNames.marker} ' 951 });
986 '${data.annotationType.className}'});
987 } 952 }
988 } 953 }
989 for (Annotation annotation in annotations) { 954 for (Annotation annotation in annotations) {
990 CodeLineAnnotation data = annotation.data; 955 CodeLineAnnotation data = annotation.data;
991 if (data.annotationType == AnnotationType.WITHOUT_SOURCE_INFO) { 956 if (data.annotationType == AnnotationType.WITHOUT_SOURCE_INFO) {
992 return new AnnotationData( 957 return new AnnotationData(tag: 'span', properties: {
993 tag: 'span', 958 'title': annotation.title,
994 properties: { 959 'class': '${ClassNames.marker} '
995 'title': annotation.title, 960 '${data.annotationType.className}'
996 'class': '${ClassNames.marker} ' 961 });
997 '${data.annotationType.className}'});
998 } 962 }
999 } 963 }
1000 return null; 964 return null;
1001 } 965 }
OLDNEW
« no previous file with comments | « tests/compiler/dart2js/sourcemaps/diff.dart ('k') | tests/compiler/dart2js/sourcemaps/html_parts.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698