| OLD | NEW |
| 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.output_structure; | 5 library sourcemap.output_structure; |
| 6 | 6 |
| 7 import 'dart:math' as Math; |
| 7 import 'html_parts.dart' show | 8 import 'html_parts.dart' show |
| 8 CodeLine; | 9 Annotation, |
| 10 CodeLine, |
| 11 JsonStrategy; |
| 9 | 12 |
| 10 // Constants used to identify the subsection of the JavaScript output. These | 13 // Constants used to identify the subsection of the JavaScript output. These |
| 11 // are specifically for the unminified full_emitter output. | 14 // are specifically for the unminified full_emitter output. |
| 12 const String HEAD = ' var dart = ['; | 15 const String HEAD = ' var dart = ['; |
| 13 const String TAIL = ' }], '; | 16 const String TAIL = ' }], '; |
| 14 const String END = ' setupProgram(dart'; | 17 const String END = ' setupProgram(dart'; |
| 15 | 18 |
| 16 final RegExp TOP_LEVEL_VALUE = new RegExp(r'^ (".+?"):'); | 19 final RegExp TOP_LEVEL_VALUE = new RegExp(r'^ (".+?"):'); |
| 17 final RegExp TOP_LEVEL_FUNCTION = | 20 final RegExp TOP_LEVEL_FUNCTION = |
| 18 new RegExp(r'^ ([a-zA-Z0-9_$]+): \[?function'); | 21 new RegExp(r'^ ([a-zA-Z0-9_$]+): \[?function'); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 47 } | 50 } |
| 48 | 51 |
| 49 OutputEntity getChild(int index) { | 52 OutputEntity getChild(int index) { |
| 50 return children[index]; | 53 return children[index]; |
| 51 } | 54 } |
| 52 | 55 |
| 53 accept(OutputVisitor visitor, arg); | 56 accept(OutputVisitor visitor, arg); |
| 54 | 57 |
| 55 EntityKind get kind; | 58 EntityKind get kind; |
| 56 | 59 |
| 57 Map toJson(); | 60 Map toJson(JsonStrategy strategy); |
| 58 | 61 |
| 59 OutputEntity getEntityForLine(int line); | 62 OutputEntity getEntityForLine(int line); |
| 60 } | 63 } |
| 61 | 64 |
| 62 enum EntityKind { | 65 enum EntityKind { |
| 63 STRUCTURE, | 66 STRUCTURE, |
| 64 LIBRARY, | 67 LIBRARY, |
| 65 CLASS, | 68 CLASS, |
| 66 TOP_LEVEL_FUNCTION, | 69 TOP_LEVEL_FUNCTION, |
| 67 TOP_LEVEL_VALUE, | 70 TOP_LEVEL_VALUE, |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 block.preprocess(lines); | 229 block.preprocess(lines); |
| 227 } | 230 } |
| 228 | 231 |
| 229 return new OutputStructure( | 232 return new OutputStructure( |
| 230 lines, headerEnd, footerStart, libraryBlocks); | 233 lines, headerEnd, footerStart, libraryBlocks); |
| 231 } | 234 } |
| 232 | 235 |
| 233 accept(OutputVisitor visitor, arg) => visitor.visitStructure(this, arg); | 236 accept(OutputVisitor visitor, arg) => visitor.visitStructure(this, arg); |
| 234 | 237 |
| 235 @override | 238 @override |
| 236 Map toJson() { | 239 Map toJson(JsonStrategy strategy) { |
| 237 return { | 240 return { |
| 238 'lines': lines.map((line) => line.toJson()).toList(), | 241 'lines': lines.map((line) => line.toJson(strategy)).toList(), |
| 239 'headerEnd': headerEnd, | 242 'headerEnd': headerEnd, |
| 240 'footerStart': footerStart, | 243 'footerStart': footerStart, |
| 241 'children': children.map((child) => child.toJson()).toList(), | 244 'children': children.map((child) => child.toJson(strategy)).toList(), |
| 242 }; | 245 }; |
| 243 } | 246 } |
| 244 | 247 |
| 245 static OutputStructure fromJson(Map json) { | 248 static OutputStructure fromJson(Map json, JsonStrategy strategy) { |
| 246 List<CodeLine> lines = json['lines'].map(CodeLine.fromJson).toList(); | 249 List<CodeLine> lines = |
| 250 json['lines'].map((l) => CodeLine.fromJson(l, strategy)).toList(); |
| 247 int headerEnd = json['headerEnd']; | 251 int headerEnd = json['headerEnd']; |
| 248 int footerStart = json['footerStart']; | 252 int footerStart = json['footerStart']; |
| 249 List<LibraryBlock> children = | 253 List<LibraryBlock> children = |
| 250 json['children'].map(AbstractEntity.fromJson).toList(); | 254 json['children'] |
| 255 .map((j) => AbstractEntity.fromJson(j, strategy)) |
| 256 .toList(); |
| 251 return new OutputStructure(lines, headerEnd, footerStart, children); | 257 return new OutputStructure(lines, headerEnd, footerStart, children); |
| 252 } | 258 } |
| 253 } | 259 } |
| 254 | 260 |
| 255 abstract class AbstractEntity extends OutputEntity { | 261 abstract class AbstractEntity extends OutputEntity { |
| 256 final String name; | 262 final String name; |
| 257 final int from; | 263 final int from; |
| 258 int to; | 264 int to; |
| 259 | 265 |
| 260 AbstractEntity(this.name, this.from); | 266 AbstractEntity(this.name, this.from); |
| 261 | 267 |
| 262 Interval get interval => new Interval(from, to); | 268 Interval get interval => new Interval(from, to); |
| 263 | 269 |
| 264 @override | 270 @override |
| 265 Map toJson() { | 271 Map toJson(JsonStrategy strategy) { |
| 266 return { | 272 return { |
| 267 'kind': kind.index, | 273 'kind': kind.index, |
| 268 'name': name, | 274 'name': name, |
| 269 'from': from, | 275 'from': from, |
| 270 'to': to, | 276 'to': to, |
| 271 'children': children.map((child) => child.toJson()).toList(), | 277 'children': children.map((child) => child.toJson(strategy)).toList(), |
| 272 'codeSource': codeSource != null ? codeSource.toJson() : null, | 278 'codeSource': codeSource != null ? codeSource.toJson() : null, |
| 273 }; | 279 }; |
| 274 } | 280 } |
| 275 | 281 |
| 276 static AbstractEntity fromJson(Map json) { | 282 static AbstractEntity fromJson(Map json, JsonStrategy strategy) { |
| 277 EntityKind kind = EntityKind.values[json['kind']]; | 283 EntityKind kind = EntityKind.values[json['kind']]; |
| 278 String name = json['name']; | 284 String name = json['name']; |
| 279 int from = json['from']; | 285 int from = json['from']; |
| 280 int to = json['to']; | 286 int to = json['to']; |
| 281 CodeSource codeSource = CodeSource.fromJson(json['codeSource']); | 287 CodeSource codeSource = CodeSource.fromJson(json['codeSource']); |
| 282 | 288 |
| 283 switch (kind) { | 289 switch (kind) { |
| 284 case EntityKind.STRUCTURE: | 290 case EntityKind.STRUCTURE: |
| 285 throw new StateError('Unexpected entity kind $kind'); | 291 throw new StateError('Unexpected entity kind $kind'); |
| 286 case EntityKind.LIBRARY: | 292 case EntityKind.LIBRARY: |
| 287 LibraryBlock lib = new LibraryBlock(name, from) | 293 LibraryBlock lib = new LibraryBlock(name, from) |
| 288 ..to = to | 294 ..to = to |
| 289 ..codeSource = codeSource; | 295 ..codeSource = codeSource; |
| 290 json['children'].forEach((child) => lib.children.add(fromJson(child))); | 296 json['children'] |
| 297 .forEach((child) => lib.children.add(fromJson(child, strategy))); |
| 291 return lib; | 298 return lib; |
| 292 case EntityKind.CLASS: | 299 case EntityKind.CLASS: |
| 293 LibraryClass cls = new LibraryClass(name, from) | 300 LibraryClass cls = new LibraryClass(name, from) |
| 294 ..to = to | 301 ..to = to |
| 295 ..codeSource = codeSource; | 302 ..codeSource = codeSource; |
| 296 json['children'].forEach((child) => cls.children.add(fromJson(child))); | 303 json['children'] |
| 304 .forEach((child) => cls.children.add(fromJson(child, strategy))); |
| 297 return cls; | 305 return cls; |
| 298 case EntityKind.TOP_LEVEL_FUNCTION: | 306 case EntityKind.TOP_LEVEL_FUNCTION: |
| 299 return new TopLevelFunction(name, from) | 307 return new TopLevelFunction(name, from) |
| 300 ..to = to | 308 ..to = to |
| 301 ..codeSource = codeSource; | 309 ..codeSource = codeSource; |
| 302 case EntityKind.TOP_LEVEL_VALUE: | 310 case EntityKind.TOP_LEVEL_VALUE: |
| 303 return new TopLevelValue(name, from) | 311 return new TopLevelValue(name, from) |
| 304 ..to = to | 312 ..to = to |
| 305 ..codeSource = codeSource; | 313 ..codeSource = codeSource; |
| 306 case EntityKind.MEMBER_FUNCTION: | 314 case EntityKind.MEMBER_FUNCTION: |
| 307 return new MemberFunction(name, from) | 315 return new MemberFunction(name, from) |
| 308 ..to = to | 316 ..to = to |
| 309 ..codeSource = codeSource; | 317 ..codeSource = codeSource; |
| 310 case EntityKind.MEMBER_OBJECT: | 318 case EntityKind.MEMBER_OBJECT: |
| 311 return new MemberObject(name, from) | 319 return new MemberObject(name, from) |
| 312 ..to = to | 320 ..to = to |
| 313 ..codeSource = codeSource; | 321 ..codeSource = codeSource; |
| 314 case EntityKind.MEMBER_VALUE: | 322 case EntityKind.MEMBER_VALUE: |
| 315 return new MemberValue(name, from) | 323 return new MemberValue(name, from) |
| 316 ..to = to | 324 ..to = to |
| 317 ..codeSource = codeSource; | 325 ..codeSource = codeSource; |
| 318 case EntityKind.STATICS: | 326 case EntityKind.STATICS: |
| 319 Statics statics = new Statics(from) | 327 Statics statics = new Statics(from) |
| 320 ..to = to | 328 ..to = to |
| 321 ..codeSource = codeSource; | 329 ..codeSource = codeSource; |
| 322 json['children'].forEach( | 330 json['children'].forEach( |
| 323 (child) => statics.children.add(fromJson(child))); | 331 (child) => statics.children.add(fromJson(child, strategy))); |
| 324 return statics; | 332 return statics; |
| 325 case EntityKind.STATIC_FUNCTION: | 333 case EntityKind.STATIC_FUNCTION: |
| 326 return new StaticFunction(name, from) | 334 return new StaticFunction(name, from) |
| 327 ..to = to | 335 ..to = to |
| 328 ..codeSource = codeSource; | 336 ..codeSource = codeSource; |
| 329 } | 337 } |
| 330 } | 338 } |
| 331 } | 339 } |
| 332 | 340 |
| 333 /// A block defining the content of a Dart library. | 341 /// A block defining the content of a Dart library. |
| 334 class LibraryBlock extends AbstractEntity { | 342 class LibraryBlock extends AbstractEntity { |
| 335 List<BasicEntity> children = <BasicEntity>[]; | 343 List<BasicEntity> children = <BasicEntity>[]; |
| 336 int get headerEnd => from + 2; | 344 int get headerEnd => from + 2; |
| 337 int get footerStart => to - 1; | 345 int get footerStart => to/* - 1*/; |
| 338 | 346 |
| 339 LibraryBlock(String name, int from) : super(name, from); | 347 LibraryBlock(String name, int from) : super(name, from); |
| 340 | 348 |
| 341 @override | 349 @override |
| 342 EntityKind get kind => EntityKind.LIBRARY; | 350 EntityKind get kind => EntityKind.LIBRARY; |
| 343 | 351 |
| 344 Interval get header => new Interval(from, headerEnd); | 352 Interval get header => new Interval(from, headerEnd); |
| 345 | 353 |
| 346 Interval get footer => new Interval(footerStart, to); | 354 Interval get footer => new Interval(footerStart, to); |
| 347 | 355 |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 617 } | 625 } |
| 618 | 626 |
| 619 class Interval { | 627 class Interval { |
| 620 final int from; | 628 final int from; |
| 621 final int to; | 629 final int to; |
| 622 | 630 |
| 623 const Interval(this.from, this.to); | 631 const Interval(this.from, this.to); |
| 624 | 632 |
| 625 int get length => to - from; | 633 int get length => to - from; |
| 626 | 634 |
| 635 bool get isEmpty => from == to; |
| 636 |
| 627 bool contains(int value) { | 637 bool contains(int value) { |
| 628 return from <= value && value < to; | 638 return from <= value && value < to; |
| 629 } | 639 } |
| 640 |
| 641 Interval include(int index) { |
| 642 return new Interval(Math.min(from, index), Math.max(to, index + 1)); |
| 643 } |
| 644 |
| 645 bool inWindow(int index, {int windowSize: 0}) { |
| 646 return from - windowSize <= index && index < to + windowSize; |
| 647 } |
| 648 |
| 649 String toString() => '[$from,$to['; |
| 630 } | 650 } |
| 631 | 651 |
| 632 enum CodeKind { | 652 enum CodeKind { |
| 633 LIBRARY, | 653 LIBRARY, |
| 634 CLASS, | 654 CLASS, |
| 635 MEMBER, | 655 MEMBER, |
| 636 } | 656 } |
| 637 | 657 |
| 658 class CodeLocation { |
| 659 final Uri uri; |
| 660 final String name; |
| 661 final int offset; |
| 662 |
| 663 CodeLocation(this.uri, this.name, this.offset); |
| 664 |
| 665 String toString() => '$uri:$name:$offset'; |
| 666 |
| 667 Map toJson(JsonStrategy strategy) { |
| 668 return { |
| 669 'uri': uri.toString(), |
| 670 'name': name, |
| 671 'offset': offset, |
| 672 }; |
| 673 } |
| 674 |
| 675 static CodeLocation fromJson(Map json, JsonStrategy strategy) { |
| 676 if (json == null) return null; |
| 677 return new CodeLocation( |
| 678 Uri.parse(json['uri']), |
| 679 json['name'], |
| 680 json['offset']); |
| 681 } |
| 682 } |
| 683 |
| 684 /// A named entity in source code. This is used to serialize [Element] |
| 685 /// references without serializing the [Element] itself. |
| 638 class CodeSource { | 686 class CodeSource { |
| 639 final CodeKind kind; | 687 final CodeKind kind; |
| 640 final Uri uri; | 688 final Uri uri; |
| 641 final String name; | 689 final String name; |
| 642 final int begin; | 690 final int begin; |
| 643 final int end; | 691 final int end; |
| 692 final List<CodeSource> members = <CodeSource>[]; |
| 644 | 693 |
| 645 CodeSource(this.kind, this.uri, this.name, this.begin, this.end); | 694 CodeSource(this.kind, this.uri, this.name, this.begin, this.end); |
| 646 | 695 |
| 696 int get hashCode { |
| 697 return |
| 698 kind.hashCode * 13 + |
| 699 uri.hashCode * 17 + |
| 700 name.hashCode * 19 + |
| 701 begin.hashCode * 23; |
| 702 } |
| 703 |
| 704 bool operator ==(other) { |
| 705 if (identical(this, other)) return true; |
| 706 if (other is! CodeSource) return false; |
| 707 return |
| 708 kind == other.kind && |
| 709 uri == other.uri && |
| 710 name == other.name && |
| 711 begin == other.begin; |
| 712 |
| 713 } |
| 714 |
| 647 String toString() => '${toJson()}'; | 715 String toString() => '${toJson()}'; |
| 648 | 716 |
| 649 Map toJson() { | 717 Map toJson() { |
| 650 return { | 718 return { |
| 651 'kind': kind.index, | 719 'kind': kind.index, |
| 652 'uri': uri.toString(), | 720 'uri': uri.toString(), |
| 653 'name': name, | 721 'name': name, |
| 654 'begin': begin, | 722 'begin': begin, |
| 655 'end': end, | 723 'end': end, |
| 724 'members': members.map((c) => c.toJson()).toList(), |
| 656 }; | 725 }; |
| 657 } | 726 } |
| 658 | 727 |
| 659 static CodeSource fromJson(Map json) { | 728 static CodeSource fromJson(Map json) { |
| 660 if (json == null) return null; | 729 if (json == null) return null; |
| 661 return new CodeSource( | 730 CodeSource codeSource = new CodeSource( |
| 662 CodeKind.values[json['kind']], | 731 CodeKind.values[json['kind']], |
| 663 Uri.parse(json['uri']), | 732 Uri.parse(json['uri']), |
| 664 json['name'], | 733 json['name'], |
| 665 json['begin'], | 734 json['begin'], |
| 666 json['end']); | 735 json['end']); |
| 736 json['members'].forEach((m) => codeSource.members.add(fromJson(m))); |
| 737 return codeSource; |
| 667 } | 738 } |
| 668 } | 739 } |
| OLD | NEW |