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

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

Issue 2345083003: dart2js: run dartfmt on tests (Closed)
Patch Set: 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; 5 library sourcemap.diff;
6 6
7 import 'package:compiler/src/io/source_file.dart'; 7 import 'package:compiler/src/io/source_file.dart';
8 8
9 import 'html_parts.dart'; 9 import 'html_parts.dart';
10 import 'output_structure.dart'; 10 import 'output_structure.dart';
11 import 'sourcemap_helper.dart'; 11 import 'sourcemap_helper.dart';
12 import 'sourcemap_html_helper.dart'; 12 import 'sourcemap_html_helper.dart';
13 13
14 enum DiffKind { 14 enum DiffKind { UNMATCHED, MATCHING, IDENTICAL, }
15 UNMATCHED,
16 MATCHING,
17 IDENTICAL,
18 }
19 15
20 /// Id for an output column. 16 /// Id for an output column.
21 class DiffColumn { 17 class DiffColumn {
22 final String type; 18 final String type;
23 final int index; 19 final int index;
24 20
25 const DiffColumn(this.type, [this.index]); 21 const DiffColumn(this.type, [this.index]);
26 22
27 int get hashCode => type.hashCode * 19 + index.hashCode * 23; 23 int get hashCode => type.hashCode * 19 + index.hashCode * 23;
28 24
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 final Map<CodeLine, List<CodeLine>> jsToDartMap; 57 final Map<CodeLine, List<CodeLine>> jsToDartMap;
62 58
63 CodeLinesColumnBlock(this.jsCodeLines, this.jsToDartMap); 59 CodeLinesColumnBlock(this.jsCodeLines, this.jsToDartMap);
64 60
65 void printHtmlOn(StringBuffer htmlBuffer, HtmlPrintContext context) { 61 void printHtmlOn(StringBuffer htmlBuffer, HtmlPrintContext context) {
66 if (jsCodeLines.isNotEmpty) { 62 if (jsCodeLines.isNotEmpty) {
67 htmlBuffer.write('<table style="width:100%">'); 63 htmlBuffer.write('<table style="width:100%">');
68 for (CodeLine codeLine in jsCodeLines) { 64 for (CodeLine codeLine in jsCodeLines) {
69 htmlBuffer.write('<tr><td class="${ClassNames.innerCell}">'); 65 htmlBuffer.write('<tr><td class="${ClassNames.innerCell}">');
70 codeLine.printHtmlOn(htmlBuffer, context); 66 codeLine.printHtmlOn(htmlBuffer, context);
71 htmlBuffer.write( 67 htmlBuffer.write('</td><td '
72 '</td><td '
73 'class="${ClassNames.innerCell} ${ClassNames.sourceMapped}">'); 68 'class="${ClassNames.innerCell} ${ClassNames.sourceMapped}">');
74 List<CodeLine> lines = jsToDartMap[codeLine]; 69 List<CodeLine> lines = jsToDartMap[codeLine];
75 if (lines != null) { 70 if (lines != null) {
76 for (CodeLine line in lines) { 71 for (CodeLine line in lines) {
77 line.printHtmlOn(htmlBuffer, 72 line.printHtmlOn(htmlBuffer, context.from(includeAnnotation: (a) {
78 context.from(includeAnnotation: (a) { 73 CodeLineAnnotation annotation = a.data;
79 CodeLineAnnotation annotation = a.data; 74 return annotation.annotationType.isSourceMapped;
80 return annotation.annotationType.isSourceMapped; 75 }));
81 }));
82 } 76 }
83 } 77 }
84 htmlBuffer.write('</td></tr>'); 78 htmlBuffer.write('</td></tr>');
85 } 79 }
86 htmlBuffer.write('</table>'); 80 htmlBuffer.write('</table>');
87 } 81 }
88 } 82 }
89 } 83 }
90 84
91 /// A list of columns that should align in output. 85 /// A list of columns that should align in output.
92 class DiffBlock { 86 class DiffBlock {
93 final DiffKind kind; 87 final DiffKind kind;
94 Map<DiffColumn, DiffColumnBlock> _columns = <DiffColumn, DiffColumnBlock>{}; 88 Map<DiffColumn, DiffColumnBlock> _columns = <DiffColumn, DiffColumnBlock>{};
95 89
96 DiffBlock(this.kind); 90 DiffBlock(this.kind);
97 91
98 void addColumnBlock(DiffColumn column, DiffColumnBlock block) { 92 void addColumnBlock(DiffColumn column, DiffColumnBlock block) {
99 _columns[column] = block; 93 _columns[column] = block;
100 } 94 }
101 95
102 Iterable<DiffColumn> get columns => _columns.keys; 96 Iterable<DiffColumn> get columns => _columns.keys;
103 97
104 void printHtmlOn(DiffColumn column, 98 void printHtmlOn(
105 StringBuffer htmlBuffer, 99 DiffColumn column, StringBuffer htmlBuffer, HtmlPrintContext context) {
106 HtmlPrintContext context) {
107 DiffColumnBlock block = _columns[column]; 100 DiffColumnBlock block = _columns[column];
108 if (block != null) { 101 if (block != null) {
109 block.printHtmlOn(htmlBuffer, context); 102 block.printHtmlOn(htmlBuffer, context);
110 } 103 }
111 } 104 }
112 } 105 }
113 106
114
115 /// Align the content of [list1] and [list2]. 107 /// Align the content of [list1] and [list2].
116 /// 108 ///
117 /// If provided, [range1] and [range2] aligned the subranges of [list1] and 109 /// If provided, [range1] and [range2] aligned the subranges of [list1] and
118 /// [list2], otherwise the whole lists are aligned. 110 /// [list2], otherwise the whole lists are aligned.
119 /// 111 ///
120 /// If provided, [match] determines the equality between members of [list1] and 112 /// If provided, [match] determines the equality between members of [list1] and
121 /// [list2], otherwise `==` is used. 113 /// [list2], otherwise `==` is used.
122 /// 114 ///
123 /// [handleSkew] is called when a subrange of one list is not found in the 115 /// [handleSkew] is called when a subrange of one list is not found in the
124 /// other. 116 /// other.
125 /// 117 ///
126 /// [handleMatched] is called when two indices match up. 118 /// [handleMatched] is called when two indices match up.
127 /// 119 ///
128 /// [handleUnmatched] is called when two indices don't match up (none are found 120 /// [handleUnmatched] is called when two indices don't match up (none are found
129 /// in the other list). 121 /// in the other list).
130 void align(List list1, 122 void align(List list1, List list2,
131 List list2, 123 {Interval range1,
132 {Interval range1, 124 Interval range2,
133 Interval range2, 125 bool match(a, b),
134 bool match(a, b), 126 void handleSkew(int listIndex, Interval range),
135 void handleSkew(int listIndex, Interval range), 127 void handleMatched(List<int> indices),
136 void handleMatched(List<int> indices), 128 void handleUnmatched(List<int> indices)}) {
137 void handleUnmatched(List<int> indices)}) {
138 if (match == null) { 129 if (match == null) {
139 match = (a, b) => a == b; 130 match = (a, b) => a == b;
140 } 131 }
141 132
142 if (range1 == null) { 133 if (range1 == null) {
143 range1 = new Interval(0, list1.length); 134 range1 = new Interval(0, list1.length);
144 } 135 }
145 if (range2 == null) { 136 if (range2 == null) {
146 range2 = new Interval(0, list2.length); 137 range2 = new Interval(0, list2.length);
147 } 138 }
148 139
149 Interval findInOther( 140 Interval findInOther(List thisLines, Interval thisRange, List otherLines,
150 List thisLines, Interval thisRange, 141 Interval otherRange) {
151 List otherLines, Interval otherRange) {
152 for (int index = otherRange.from; index < otherRange.to; index++) { 142 for (int index = otherRange.from; index < otherRange.to; index++) {
153 if (match(thisLines[thisRange.from], otherLines[index])) { 143 if (match(thisLines[thisRange.from], otherLines[index])) {
154 int offset = 1; 144 int offset = 1;
155 while (thisRange.from + offset < thisRange.to && 145 while (thisRange.from + offset < thisRange.to &&
156 otherRange.from + offset < otherRange.to && 146 otherRange.from + offset < otherRange.to &&
157 match(thisLines[thisRange.from + offset], 147 match(thisLines[thisRange.from + offset],
158 otherLines[otherRange.from + offset])) { 148 otherLines[otherRange.from + offset])) {
159 offset++; 149 offset++;
160 } 150 }
161 return new Interval(index, index + offset); 151 return new Interval(index, index + offset);
162 } 152 }
163 } 153 }
164 return null; 154 return null;
165 } 155 }
166 156
167 int start1 = range1.from; 157 int start1 = range1.from;
168 int end1 = range1.to; 158 int end1 = range1.to;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 handleSkew(0, new Interval(start1, end1)); 212 handleSkew(0, new Interval(start1, end1));
223 } 213 }
224 if (start2 < end2) { 214 if (start2 < end2) {
225 handleSkew(1, new Interval(start2, end2)); 215 handleSkew(1, new Interval(start2, end2));
226 } 216 }
227 } 217 }
228 218
229 /// Create a list of blocks containing the diff of the two output [structures] 219 /// Create a list of blocks containing the diff of the two output [structures]
230 /// and the corresponding Dart code. 220 /// and the corresponding Dart code.
231 List<DiffBlock> createDiffBlocks( 221 List<DiffBlock> createDiffBlocks(
232 List<OutputStructure> structures, 222 List<OutputStructure> structures, SourceFileManager sourceFileManager) {
233 SourceFileManager sourceFileManager) {
234 return new DiffCreator(structures, sourceFileManager).computeBlocks(); 223 return new DiffCreator(structures, sourceFileManager).computeBlocks();
235 } 224 }
236 225
237 class DiffCreator { 226 class DiffCreator {
238 final List<OutputStructure> structures; 227 final List<OutputStructure> structures;
239 final SourceFileManager sourceFileManager; 228 final SourceFileManager sourceFileManager;
240 229
241 List<List<CodeLine>> inputLines; 230 List<List<CodeLine>> inputLines;
242 231
243 List<int> nextInputLine = [0, 0]; 232 List<int> nextInputLine = [0, 0];
(...skipping 12 matching lines...) Expand all
256 sources.add(entity.codeSource); 245 sources.add(entity.codeSource);
257 } 246 }
258 } 247 }
259 return sources; 248 return sources;
260 } 249 }
261 250
262 /// Create a block with the code from [codeSources]. The [CodeSource]s in 251 /// Create a block with the code from [codeSources]. The [CodeSource]s in
263 /// [mainSources] are tagged as original code sources, the rest as inlined 252 /// [mainSources] are tagged as original code sources, the rest as inlined
264 /// code sources. 253 /// code sources.
265 DiffColumnBlock codeLinesFromCodeSources( 254 DiffColumnBlock codeLinesFromCodeSources(
266 Iterable<CodeSource> mainSources, 255 Iterable<CodeSource> mainSources, Iterable<CodeSource> codeSources) {
267 Iterable<CodeSource> codeSources) {
268 List<HtmlPart> parts = <HtmlPart>[]; 256 List<HtmlPart> parts = <HtmlPart>[];
269 for (CodeSource codeSource in codeSources) { 257 for (CodeSource codeSource in codeSources) {
270 //parts.addAll(codeLinesFromCodeSource(codeSource)); 258 //parts.addAll(codeLinesFromCodeSource(codeSource));
271 String className = 259 String className = mainSources.contains(codeSource)
272 mainSources.contains(codeSource) 260 ? ClassNames.originalDart
273 ? ClassNames.originalDart : ClassNames.inlinedDart; 261 : ClassNames.inlinedDart;
274 parts.add( 262 parts.add(new TagPart('div',
275 new TagPart('div', 263 properties: {'class': className},
276 properties: {'class': className}, 264 content: codeLinesFromCodeSource(codeSource)));
277 content: codeLinesFromCodeSource(codeSource)));
278 } 265 }
279 return new PartsColumnBlock(parts); 266 return new PartsColumnBlock(parts);
280 } 267 }
281 268
282 /// Adds all [CodeSource]s used in [dartCodeLines] to [codeSourceSet]. 269 /// Adds all [CodeSource]s used in [dartCodeLines] to [codeSourceSet].
283 void collectCodeSources(Set<CodeSource> codeSourceSet, 270 void collectCodeSources(Set<CodeSource> codeSourceSet,
284 Map<CodeLine, List<CodeLine>> dartCodeLines) { 271 Map<CodeLine, List<CodeLine>> dartCodeLines) {
285 for (List<CodeLine> codeLines in dartCodeLines.values) { 272 for (List<CodeLine> codeLines in dartCodeLines.values) {
286 for (CodeLine dartCodeLine in codeLines) { 273 for (CodeLine dartCodeLine in codeLines) {
287 if (dartCodeLine.lineAnnotation != null) { 274 if (dartCodeLine.lineAnnotation != null) {
288 codeSourceSet.add(dartCodeLine.lineAnnotation); 275 codeSourceSet.add(dartCodeLine.lineAnnotation);
289 } 276 }
290 } 277 }
291 } 278 }
292 } 279 }
293 280
294 /// Checks that lines are added in sequence without gaps or duplicates. 281 /// Checks that lines are added in sequence without gaps or duplicates.
(...skipping 14 matching lines...) Expand all
309 print(inputLines[index][i++].code); 296 print(inputLines[index][i++].code);
310 } 297 }
311 } 298 }
312 } 299 }
313 nextInputLine[index] = range.to; 300 nextInputLine[index] = range.to;
314 } 301 }
315 302
316 /// Creates a block containing the code lines in [range] from input number 303 /// Creates a block containing the code lines in [range] from input number
317 /// [index]. If [codeSource] is provided, the block will contain a 304 /// [index]. If [codeSource] is provided, the block will contain a
318 /// corresponding Dart code column. 305 /// corresponding Dart code column.
319 void handleSkew( 306 void handleSkew(int index, Interval range,
320 int index,
321 Interval range,
322 [Iterable<CodeSource> mainCodeSources = const <CodeSource>[]]) { 307 [Iterable<CodeSource> mainCodeSources = const <CodeSource>[]]) {
323 if (range.isEmpty) return; 308 if (range.isEmpty) return;
324 309
325 Set<CodeSource> codeSources = new Set<CodeSource>(); 310 Set<CodeSource> codeSources = new Set<CodeSource>();
326 codeSources.addAll(mainCodeSources); 311 codeSources.addAll(mainCodeSources);
327 312
328 DiffBlock block = new DiffBlock(DiffKind.UNMATCHED); 313 DiffBlock block = new DiffBlock(DiffKind.UNMATCHED);
329 checkLineInvariant(index, range); 314 checkLineInvariant(index, range);
330 List<CodeLine> jsCodeLines = 315 List<CodeLine> jsCodeLines =
331 inputLines[index].sublist(range.from, range.to); 316 inputLines[index].sublist(range.from, range.to);
332 Map<CodeLine, List<CodeLine>> dartCodeLines = 317 Map<CodeLine, List<CodeLine>> dartCodeLines =
333 dartCodeLinesFromJsCodeLines(jsCodeLines); 318 dartCodeLinesFromJsCodeLines(jsCodeLines);
334 block.addColumnBlock( 319 block.addColumnBlock(new DiffColumn('js', index),
335 new DiffColumn('js', index),
336 new CodeLinesColumnBlock(jsCodeLines, dartCodeLines)); 320 new CodeLinesColumnBlock(jsCodeLines, dartCodeLines));
337 collectCodeSources(codeSources, dartCodeLines); 321 collectCodeSources(codeSources, dartCodeLines);
338 322
339 if (codeSources.isNotEmpty) { 323 if (codeSources.isNotEmpty) {
340 block.addColumnBlock( 324 block.addColumnBlock(const DiffColumn('dart'),
341 const DiffColumn('dart'),
342 codeLinesFromCodeSources(mainCodeSources, codeSources)); 325 codeLinesFromCodeSources(mainCodeSources, codeSources));
343 } 326 }
344 blocks.add(block); 327 blocks.add(block);
345 } 328 }
346 329
347 /// Create a block containing the code lines in [ranges] from the 330 /// Create a block containing the code lines in [ranges] from the
348 /// corresponding JavaScript inputs. If [codeSource] is provided, the block 331 /// corresponding JavaScript inputs. If [codeSource] is provided, the block
349 /// will contain a corresponding Dart code column. 332 /// will contain a corresponding Dart code column.
350 void addLines( 333 void addLines(DiffKind kind, List<Interval> ranges,
351 DiffKind kind,
352 List<Interval> ranges,
353 [Iterable<CodeSource> mainCodeSources = const <CodeSource>[]]) { 334 [Iterable<CodeSource> mainCodeSources = const <CodeSource>[]]) {
354 if (ranges.every((range) => range.isEmpty)) return; 335 if (ranges.every((range) => range.isEmpty)) return;
355 336
356 Set<CodeSource> codeSources = new Set<CodeSource>(); 337 Set<CodeSource> codeSources = new Set<CodeSource>();
357 codeSources.addAll(mainCodeSources); 338 codeSources.addAll(mainCodeSources);
358 339
359 DiffBlock block = new DiffBlock(kind); 340 DiffBlock block = new DiffBlock(kind);
360 for (int i = 0; i < ranges.length; i++) { 341 for (int i = 0; i < ranges.length; i++) {
361 checkLineInvariant(i, ranges[i]); 342 checkLineInvariant(i, ranges[i]);
362 List<CodeLine> jsCodeLines = 343 List<CodeLine> jsCodeLines =
363 inputLines[i].sublist(ranges[i].from, ranges[i].to); 344 inputLines[i].sublist(ranges[i].from, ranges[i].to);
364 Map<CodeLine, List<CodeLine>> dartCodeLines = 345 Map<CodeLine, List<CodeLine>> dartCodeLines =
365 dartCodeLinesFromJsCodeLines(jsCodeLines); 346 dartCodeLinesFromJsCodeLines(jsCodeLines);
366 block.addColumnBlock( 347 block.addColumnBlock(new DiffColumn('js', i),
367 new DiffColumn('js', i),
368 new CodeLinesColumnBlock(jsCodeLines, dartCodeLines)); 348 new CodeLinesColumnBlock(jsCodeLines, dartCodeLines));
369 collectCodeSources(codeSources, dartCodeLines); 349 collectCodeSources(codeSources, dartCodeLines);
370 } 350 }
371 if (codeSources.isNotEmpty) { 351 if (codeSources.isNotEmpty) {
372 block.addColumnBlock(const DiffColumn('dart'), 352 block.addColumnBlock(const DiffColumn('dart'),
373 codeLinesFromCodeSources(mainCodeSources, codeSources)); 353 codeLinesFromCodeSources(mainCodeSources, codeSources));
374 } 354 }
375 blocks.add(block); 355 blocks.add(block);
376 } 356 }
377 357
(...skipping 17 matching lines...) Expand all
395 if (currentUnmatchedIntervals != null) { 375 if (currentUnmatchedIntervals != null) {
396 addLines(DiffKind.UNMATCHED, currentUnmatchedIntervals); 376 addLines(DiffKind.UNMATCHED, currentUnmatchedIntervals);
397 } 377 }
398 currentUnmatchedIntervals = null; 378 currentUnmatchedIntervals = null;
399 } 379 }
400 380
401 List<Interval> updateIntervals(List<Interval> current, List<int> indices) { 381 List<Interval> updateIntervals(List<Interval> current, List<int> indices) {
402 if (current == null) { 382 if (current == null) {
403 return [ 383 return [
404 new Interval(indices[0], indices[0] + 1), 384 new Interval(indices[0], indices[0] + 1),
405 new Interval(indices[1], indices[1] + 1)]; 385 new Interval(indices[1], indices[1] + 1)
386 ];
406 } else { 387 } else {
407 current[0] = 388 current[0] = new Interval(current[0].from, indices[0] + 1);
408 new Interval(current[0].from, indices[0] + 1); 389 current[1] = new Interval(current[1].from, indices[1] + 1);
409 current[1] =
410 new Interval(current[1].from, indices[1] + 1);
411 return current; 390 return current;
412 } 391 }
413 } 392 }
414 393
415 align( 394 align(inputLines[0], inputLines[1],
416 inputLines[0],
417 inputLines[1],
418 range1: range1, 395 range1: range1,
419 range2: range2, 396 range2: range2,
420 match: match, 397 match: match, handleSkew: (int listIndex, Interval range) {
421 handleSkew: (int listIndex, Interval range) { 398 flushMatching();
422 flushMatching(); 399 flushUnmatched();
423 flushUnmatched(); 400 handleSkew(listIndex, range);
424 handleSkew(listIndex, range); 401 }, handleMatched: (List<int> indices) {
425 }, 402 flushUnmatched();
426 handleMatched: (List<int> indices) { 403 currentMatchedIntervals =
427 flushUnmatched(); 404 updateIntervals(currentMatchedIntervals, indices);
428 currentMatchedIntervals = 405 }, handleUnmatched: (List<int> indices) {
429 updateIntervals(currentMatchedIntervals, indices); 406 flushMatching();
430 }, 407 currentUnmatchedIntervals =
431 handleUnmatched: (List<int> indices) { 408 updateIntervals(currentUnmatchedIntervals, indices);
432 flushMatching(); 409 });
433 currentUnmatchedIntervals =
434 updateIntervals(currentUnmatchedIntervals, indices);
435 });
436 410
437 flushMatching(); 411 flushMatching();
438 flushUnmatched(); 412 flushUnmatched();
439 } 413 }
440 414
441 /// Adds the top level blocks in [childRange] for structure [index]. 415 /// Adds the top level blocks in [childRange] for structure [index].
442 void addBlock(int index, Interval childRange) { 416 void addBlock(int index, Interval childRange) {
443 addSkewedChildren(index, structures[index], childRange); 417 addSkewedChildren(index, structures[index], childRange);
444 } 418 }
445 419
446 /// Adds the [entity] from structure [index]. If the [entity] supports child 420 /// Adds the [entity] from structure [index]. If the [entity] supports child
447 /// entities, these are process individually. Otherwise the lines from 421 /// entities, these are process individually. Otherwise the lines from
448 /// [entity] are added directly. 422 /// [entity] are added directly.
449 void addSkewedEntity(int index, OutputEntity entity) { 423 void addSkewedEntity(int index, OutputEntity entity) {
450 if (entity.canHaveChildren) { 424 if (entity.canHaveChildren) {
451 handleSkew(index, entity.header); 425 handleSkew(index, entity.header);
452 addSkewedChildren( 426 addSkewedChildren(index, entity, new Interval(0, entity.children.length));
453 index, entity, new Interval(0, entity.children.length));
454 handleSkew(index, entity.footer); 427 handleSkew(index, entity.footer);
455 } else { 428 } else {
456 handleSkew(index, entity.interval, codeSourceFromEntities([entity])); 429 handleSkew(index, entity.interval, codeSourceFromEntities([entity]));
457 } 430 }
458 } 431 }
459 432
460 /// Adds the children of [parent] in [childRange] from structure [index]. 433 /// Adds the children of [parent] in [childRange] from structure [index].
461 void addSkewedChildren(int index, OutputEntity parent, Interval childRange) { 434 void addSkewedChildren(int index, OutputEntity parent, Interval childRange) {
462 for (int i = childRange.from; i < childRange.to; i++) { 435 for (int i = childRange.from; i < childRange.to; i++) {
463 addSkewedEntity(index, parent.getChild(i)); 436 addSkewedEntity(index, parent.getChild(i));
464 } 437 }
465 } 438 }
466 439
467 /// Adds the members of the [classes] aligned. 440 /// Adds the members of the [classes] aligned.
468 void addMatchingContainers(List<OutputEntity> classes) { 441 void addMatchingContainers(List<OutputEntity> classes) {
469 addLines(DiffKind.MATCHING, classes.map((c) => c.header).toList()); 442 addLines(DiffKind.MATCHING, classes.map((c) => c.header).toList());
470 align(classes[0].children, classes[1].children, 443 align(classes[0].children, classes[1].children,
471 match: (a, b) => a.name == b.name, 444 match: (a, b) => a.name == b.name,
472 handleSkew: (int listIndex, Interval childRange) { 445 handleSkew: (int listIndex, Interval childRange) {
473 addSkewedChildren(listIndex, classes[listIndex], childRange); 446 addSkewedChildren(listIndex, classes[listIndex], childRange);
474 }, 447 }, handleMatched: (List<int> indices) {
475 handleMatched: (List<int> indices) { 448 List<BasicEntity> entities = [
476 List<BasicEntity> entities = [ 449 classes[0].getChild(indices[0]),
477 classes[0].getChild(indices[0]), 450 classes[1].getChild(indices[1])
478 classes[1].getChild(indices[1])]; 451 ];
479 if (entities.every((e) => e is Statics)) { 452 if (entities.every((e) => e is Statics)) {
480 addMatchingContainers(entities); 453 addMatchingContainers(entities);
481 } else { 454 } else {
482 addLines(DiffKind.MATCHING, 455 addLines(DiffKind.MATCHING, entities.map((e) => e.interval).toList(),
483 entities.map((e) => e.interval).toList(), 456 codeSourceFromEntities(entities));
484 codeSourceFromEntities(entities)); 457 }
485 } 458 }, handleUnmatched: (List<int> indices) {
486 }, 459 List<Interval> intervals = [
487 handleUnmatched: (List<int> indices) { 460 classes[0].getChild(indices[0]).interval,
488 List<Interval> intervals = [ 461 classes[1].getChild(indices[1]).interval
489 classes[0].getChild(indices[0]).interval, 462 ];
490 classes[1].getChild(indices[1]).interval]; 463 addLines(DiffKind.UNMATCHED, intervals);
491 addLines(DiffKind.UNMATCHED, intervals); 464 });
492 });
493 addLines(DiffKind.MATCHING, classes.map((c) => c.footer).toList()); 465 addLines(DiffKind.MATCHING, classes.map((c) => c.footer).toList());
494 } 466 }
495 467
496 /// Adds the library blocks in [indices] from the corresponding 468 /// Adds the library blocks in [indices] from the corresponding
497 /// [OutputStructure]s, aligning their content. 469 /// [OutputStructure]s, aligning their content.
498 void addMatchingBlocks(List<int> indices) { 470 void addMatchingBlocks(List<int> indices) {
499 List<LibraryBlock> blocks = [ 471 List<LibraryBlock> blocks = [
500 structures[0].getChild(indices[0]), 472 structures[0].getChild(indices[0]),
501 structures[1].getChild(indices[1])]; 473 structures[1].getChild(indices[1])
474 ];
502 475
503 addLines(DiffKind.MATCHING, blocks.map((b) => b.header).toList()); 476 addLines(DiffKind.MATCHING, blocks.map((b) => b.header).toList());
504 align(blocks[0].children, blocks[1].children, 477 align(blocks[0].children, blocks[1].children,
505 match: (a, b) => a.name == b.name, 478 match: (a, b) => a.name == b.name,
506 handleSkew: (int listIndex, Interval childRange) { 479 handleSkew: (int listIndex, Interval childRange) {
507 addSkewedChildren( 480 addSkewedChildren(listIndex, blocks[listIndex], childRange);
508 listIndex, blocks[listIndex], childRange); 481 }, handleMatched: (List<int> indices) {
509 }, 482 List<BasicEntity> entities = [
510 handleMatched: (List<int> indices) { 483 blocks[0].getChild(indices[0]),
511 List<BasicEntity> entities = [ 484 blocks[1].getChild(indices[1])
512 blocks[0].getChild(indices[0]), 485 ];
513 blocks[1].getChild(indices[1])]; 486 if (entities.every((e) => e is LibraryClass)) {
514 if (entities.every((e) => e is LibraryClass)) { 487 addMatchingContainers(entities);
515 addMatchingContainers(entities); 488 } else {
516 } else { 489 addLines(DiffKind.MATCHING, entities.map((e) => e.interval).toList(),
517 addLines( 490 codeSourceFromEntities(entities));
518 DiffKind.MATCHING, 491 }
519 entities.map((e) => e.interval).toList(), 492 }, handleUnmatched: (List<int> indices) {
520 codeSourceFromEntities(entities)); 493 List<Interval> intervals = [
521 } 494 blocks[0].getChild(indices[0]).interval,
522 }, 495 blocks[1].getChild(indices[1]).interval
523 handleUnmatched: (List<int> indices) { 496 ];
524 List<Interval> intervals = [ 497 addLines(DiffKind.UNMATCHED, intervals);
525 blocks[0].getChild(indices[0]).interval, 498 });
526 blocks[1].getChild(indices[1]).interval];
527 addLines(DiffKind.UNMATCHED, intervals);
528 });
529 addLines(DiffKind.MATCHING, blocks.map((b) => b.footer).toList()); 499 addLines(DiffKind.MATCHING, blocks.map((b) => b.footer).toList());
530 } 500 }
531 501
532 /// Adds the lines of the blocks in [indices] from the corresponding 502 /// Adds the lines of the blocks in [indices] from the corresponding
533 /// [OutputStructure]s. 503 /// [OutputStructure]s.
534 void addUnmatchedBlocks(List<int> indices) { 504 void addUnmatchedBlocks(List<int> indices) {
535 List<LibraryBlock> blocks = [ 505 List<LibraryBlock> blocks = [
536 structures[0].getChild(indices[0]), 506 structures[0].getChild(indices[0]),
537 structures[1].getChild(indices[1])]; 507 structures[1].getChild(indices[1])
508 ];
538 addLines(DiffKind.UNMATCHED, [blocks[0].interval, blocks[1].interval]); 509 addLines(DiffKind.UNMATCHED, [blocks[0].interval, blocks[1].interval]);
539 } 510 }
540 511
541 /// Computes the diff blocks for [OutputStructure]s. 512 /// Computes the diff blocks for [OutputStructure]s.
542 List<DiffBlock> computeBlocks() { 513 List<DiffBlock> computeBlocks() {
543 addRaw(structures[0].header, structures[1].header); 514 addRaw(structures[0].header, structures[1].header);
544 515
545 align(structures[0].children, 516 align(structures[0].children, structures[1].children,
546 structures[1].children, 517 match: (a, b) => a.name == b.name,
547 match: (a, b) => a.name == b.name, 518 handleSkew: addBlock,
548 handleSkew: addBlock, 519 handleMatched: addMatchingBlocks,
549 handleMatched: addMatchingBlocks, 520 handleUnmatched: addUnmatchedBlocks);
550 handleUnmatched: addUnmatchedBlocks);
551 521
552 addRaw(structures[0].footer, structures[1].footer); 522 addRaw(structures[0].footer, structures[1].footer);
553 523
554 return blocks; 524 return blocks;
555 } 525 }
556 526
557 /// Creates html lines for code lines in [codeSource]. The [sourceFileManager] 527 /// Creates html lines for code lines in [codeSource]. The [sourceFileManager]
558 /// is used to read that text from the source URIs. 528 /// is used to read that text from the source URIs.
559 List<HtmlPart> codeLinesFromCodeSource(CodeSource codeSource) { 529 List<HtmlPart> codeLinesFromCodeSource(CodeSource codeSource) {
560 List<HtmlPart> lines = <HtmlPart>[]; 530 List<HtmlPart> lines = <HtmlPart>[];
561 SourceFile sourceFile = sourceFileManager.getSourceFile(codeSource.uri); 531 SourceFile sourceFile = sourceFileManager.getSourceFile(codeSource.uri);
562 String elementName = codeSource.name; 532 String elementName = codeSource.name;
563 HtmlLine line = new HtmlLine(); 533 HtmlLine line = new HtmlLine();
564 line.htmlParts.add(new ConstHtmlPart('<span class="comment">')); 534 line.htmlParts.add(new ConstHtmlPart('<span class="comment">'));
565 line.htmlParts.add(new HtmlText( 535 line.htmlParts.add(new HtmlText('${elementName}: ${sourceFile.filename}'));
566 '${elementName}: ${sourceFile.filename}'));
567 line.htmlParts.add(new ConstHtmlPart('</span>')); 536 line.htmlParts.add(new ConstHtmlPart('</span>'));
568 lines.add(line); 537 lines.add(line);
569 if (codeSource.begin != null) { 538 if (codeSource.begin != null) {
570 int startLine = sourceFile.getLine(codeSource.begin); 539 int startLine = sourceFile.getLine(codeSource.begin);
571 int endLine = sourceFile.getLine(codeSource.end) + 1; 540 int endLine = sourceFile.getLine(codeSource.end) + 1;
572 for (CodeLine codeLine in convertAnnotatedCodeToCodeLines( 541 for (CodeLine codeLine in convertAnnotatedCodeToCodeLines(
573 sourceFile.slowText(), 542 sourceFile.slowText(), const <Annotation>[],
574 const <Annotation>[], 543 startLine: startLine, endLine: endLine)) {
575 startLine: startLine,
576 endLine: endLine)) {
577 codeLine.lineAnnotation = codeSource; 544 codeLine.lineAnnotation = codeSource;
578 lines.add(codeLine); 545 lines.add(codeLine);
579 } 546 }
580 } 547 }
581 return lines; 548 return lines;
582 } 549 }
583 550
584 /// Creates a map from JavaScript [CodeLine]s in [jsCodeLines] to the Dart 551 /// Creates a map from JavaScript [CodeLine]s in [jsCodeLines] to the Dart
585 /// [CodeLine]s references in the source information. 552 /// [CodeLine]s references in the source information.
586 Map<CodeLine, List<CodeLine>> dartCodeLinesFromJsCodeLines( 553 Map<CodeLine, List<CodeLine>> dartCodeLinesFromJsCodeLines(
587 List<CodeLine> jsCodeLines) { 554 List<CodeLine> jsCodeLines) {
588 Map<CodeLine, Interval> codeLineInterval = <CodeLine, Interval>{}; 555 Map<CodeLine, Interval> codeLineInterval = <CodeLine, Interval>{};
589 Map<CodeLine, List<CodeLine>> jsToDartMap = <CodeLine, List<CodeLine>>{}; 556 Map<CodeLine, List<CodeLine>> jsToDartMap = <CodeLine, List<CodeLine>>{};
590 List<Annotation> annotations = <Annotation>[]; 557 List<Annotation> annotations = <Annotation>[];
591 Uri currentUri; 558 Uri currentUri;
592 Interval interval; 559 Interval interval;
593 560
594 Map<Uri, Set<CodeSource>> codeSourceMap = <Uri, Set<CodeSource>>{}; 561 Map<Uri, Set<CodeSource>> codeSourceMap = <Uri, Set<CodeSource>>{};
595 562
596 for (CodeLine jsCodeLine in jsCodeLines) { 563 for (CodeLine jsCodeLine in jsCodeLines) {
597 for (Annotation annotation in jsCodeLine.annotations) { 564 for (Annotation annotation in jsCodeLine.annotations) {
598 CodeLineAnnotation codeLineAnnotation = annotation.data; 565 CodeLineAnnotation codeLineAnnotation = annotation.data;
599 for (CodeSource codeSource in codeLineAnnotation.codeSources) { 566 for (CodeSource codeSource in codeLineAnnotation.codeSources) {
600 codeSourceMap.putIfAbsent(codeSource.uri, 567 codeSourceMap
601 () => new Set<CodeSource>()).add(codeSource); 568 .putIfAbsent(codeSource.uri, () => new Set<CodeSource>())
569 .add(codeSource);
602 } 570 }
603 } 571 }
604 } 572 }
605 573
606 void flush() { 574 void flush() {
607 if (currentUri == null) return; 575 if (currentUri == null) return;
608 576
609 Set<CodeSource> codeSources = codeSourceMap[currentUri]; 577 Set<CodeSource> codeSources = codeSourceMap[currentUri];
610 SourceFile sourceFile = sourceFileManager.getSourceFile(currentUri); 578 SourceFile sourceFile = sourceFileManager.getSourceFile(currentUri);
611 List<CodeLine> annotatedDartCodeLines = 579 List<CodeLine> annotatedDartCodeLines = convertAnnotatedCodeToCodeLines(
612 convertAnnotatedCodeToCodeLines( 580 sourceFile.slowText(), annotations,
613 sourceFile.slowText(), 581 startLine: interval.from, endLine: interval.to, uri: currentUri);
614 annotations,
615 startLine: interval.from,
616 endLine: interval.to,
617 uri: currentUri);
618 if (codeSources != null) { 582 if (codeSources != null) {
619 CodeSource currentCodeSource; 583 CodeSource currentCodeSource;
620 Interval currentLineInterval; 584 Interval currentLineInterval;
621 for (CodeLine dartCodeLine in annotatedDartCodeLines) { 585 for (CodeLine dartCodeLine in annotatedDartCodeLines) {
622 if (currentCodeSource == null || 586 if (currentCodeSource == null ||
623 !currentLineInterval.contains(dartCodeLine.lineNo)) { 587 !currentLineInterval.contains(dartCodeLine.lineNo)) {
624 currentCodeSource = null; 588 currentCodeSource = null;
625 for (CodeSource codeSource in codeSources) { 589 for (CodeSource codeSource in codeSources) {
626 Interval interval = new Interval( 590 Interval interval = new Interval(
627 sourceFile.getLine(codeSource.begin), 591 sourceFile.getLine(codeSource.begin),
(...skipping 13 matching lines...) Expand all
641 605
642 int index = 0; 606 int index = 0;
643 for (CodeLine jsCodeLine in codeLineInterval.keys) { 607 for (CodeLine jsCodeLine in codeLineInterval.keys) {
644 List<CodeLine> dartCodeLines = 608 List<CodeLine> dartCodeLines =
645 jsToDartMap.putIfAbsent(jsCodeLine, () => <CodeLine>[]); 609 jsToDartMap.putIfAbsent(jsCodeLine, () => <CodeLine>[]);
646 if (dartCodeLines.isEmpty && index < annotatedDartCodeLines.length) { 610 if (dartCodeLines.isEmpty && index < annotatedDartCodeLines.length) {
647 dartCodeLines.add(annotatedDartCodeLines[index++]); 611 dartCodeLines.add(annotatedDartCodeLines[index++]);
648 } 612 }
649 } 613 }
650 while (index < annotatedDartCodeLines.length) { 614 while (index < annotatedDartCodeLines.length) {
651 jsToDartMap[codeLineInterval.keys.last].add( 615 jsToDartMap[codeLineInterval.keys.last]
652 annotatedDartCodeLines[index++]); 616 .add(annotatedDartCodeLines[index++]);
653 } 617 }
654 618
655 currentUri = null; 619 currentUri = null;
656 } 620 }
657 621
658 void restart(CodeLine codeLine, CodeLocation codeLocation, int line) { 622 void restart(CodeLine codeLine, CodeLocation codeLocation, int line) {
659 flush(); 623 flush();
660 624
661 currentUri = codeLocation.uri; 625 currentUri = codeLocation.uri;
662 interval = new Interval(line, line + 1); 626 interval = new Interval(line, line + 1);
(...skipping 11 matching lines...) Expand all
674 int line = sourceFile.getLine(location.offset); 638 int line = sourceFile.getLine(location.offset);
675 if (currentUri != location.uri) { 639 if (currentUri != location.uri) {
676 restart(jsCodeLine, location, line); 640 restart(jsCodeLine, location, line);
677 } else if (interval.inWindow(line, windowSize: 2)) { 641 } else if (interval.inWindow(line, windowSize: 2)) {
678 interval = interval.include(line); 642 interval = interval.include(line);
679 codeLineInterval[jsCodeLine] = interval; 643 codeLineInterval[jsCodeLine] = interval;
680 } else { 644 } else {
681 restart(jsCodeLine, location, line); 645 restart(jsCodeLine, location, line);
682 } 646 }
683 647
684 annotations.add(new Annotation( 648 annotations.add(new Annotation(codeLineAnnotation.annotationType,
685 codeLineAnnotation.annotationType, 649 location.offset, 'id=${codeLineAnnotation.annotationId}',
686 location.offset,
687 'id=${codeLineAnnotation.annotationId}',
688 data: codeLineAnnotation)); 650 data: codeLineAnnotation));
689 } 651 }
690 } 652 }
691 } 653 }
692 flush(); 654 flush();
693 return jsToDartMap; 655 return jsToDartMap;
694 } 656 }
695 } 657 }
696 658
697 const DiffColumn column_js0 = const DiffColumn('js', 0); 659 const DiffColumn column_js0 = const DiffColumn('js', 0);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 final int index; 711 final int index;
750 final String className; 712 final String className;
751 final bool isSourceMapped; 713 final bool isSourceMapped;
752 714
753 const AnnotationType(this.index, this.className, this.isSourceMapped); 715 const AnnotationType(this.index, this.className, this.isSourceMapped);
754 716
755 static const List<AnnotationType> values = const <AnnotationType>[ 717 static const List<AnnotationType> values = const <AnnotationType>[
756 WITH_SOURCE_INFO, 718 WITH_SOURCE_INFO,
757 WITHOUT_SOURCE_INFO, 719 WITHOUT_SOURCE_INFO,
758 ADDITIONAL_SOURCE_INFO, 720 ADDITIONAL_SOURCE_INFO,
759 UNUSED_SOURCE_INFO]; 721 UNUSED_SOURCE_INFO
722 ];
760 } 723 }
761 724
762 class CodeLineAnnotation { 725 class CodeLineAnnotation {
763 final int annotationId; 726 final int annotationId;
764 final AnnotationType annotationType; 727 final AnnotationType annotationType;
765 final List<CodeLocation> codeLocations; 728 final List<CodeLocation> codeLocations;
766 final List<CodeSource> codeSources; 729 final List<CodeSource> codeSources;
767 final String stepInfo; 730 final String stepInfo;
768 int sourceMappingIndex; 731 int sourceMappingIndex;
769 732
770 CodeLineAnnotation( 733 CodeLineAnnotation(
771 {this.annotationId, 734 {this.annotationId,
772 this.annotationType, 735 this.annotationType,
773 this.codeLocations, 736 this.codeLocations,
774 this.codeSources, 737 this.codeSources,
775 this.stepInfo, 738 this.stepInfo,
776 this.sourceMappingIndex}); 739 this.sourceMappingIndex});
777 740
778 Map toJson(JsonStrategy strategy) { 741 Map toJson(JsonStrategy strategy) {
779 return { 742 return {
780 'annotationId': annotationId, 743 'annotationId': annotationId,
781 'annotationType': annotationType.index, 744 'annotationType': annotationType.index,
782 'codeLocations': codeLocations.map((l) => l.toJson(strategy)).toList(), 745 'codeLocations': codeLocations.map((l) => l.toJson(strategy)).toList(),
783 'codeSources': codeSources.map((c) => c.toJson()).toList(), 746 'codeSources': codeSources.map((c) => c.toJson()).toList(),
784 'stepInfo': stepInfo, 747 'stepInfo': stepInfo,
785 'sourceMappingIndex': sourceMappingIndex, 748 'sourceMappingIndex': sourceMappingIndex,
786 }; 749 };
787 } 750 }
788 751
789 static fromJson(Map json, JsonStrategy strategy) { 752 static fromJson(Map json, JsonStrategy strategy) {
790 return new CodeLineAnnotation( 753 return new CodeLineAnnotation(
791 annotationId: json['id'], 754 annotationId: json['id'],
792 annotationType: AnnotationType.values[json['annotationType']], 755 annotationType: AnnotationType.values[json['annotationType']],
793 codeLocations: json['codeLocations'] 756 codeLocations: json['codeLocations']
794 .map((j) => CodeLocation.fromJson(j, strategy)) 757 .map((j) => CodeLocation.fromJson(j, strategy))
795 .toList(), 758 .toList(),
796 codeSources: json['codeSources'] 759 codeSources:
797 .map((j) => CodeSource.fromJson(j)) 760 json['codeSources'].map((j) => CodeSource.fromJson(j)).toList(),
798 .toList(),
799 stepInfo: json['stepInfo'], 761 stepInfo: json['stepInfo'],
800 sourceMappingIndex: json['sourceMappingIndex']); 762 sourceMappingIndex: json['sourceMappingIndex']);
801 } 763 }
802 } 764 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698