| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 dart2js.source_map_builder; | 5 library dart2js.source_map_builder; |
| 6 | 6 |
| 7 import '../util/util.dart'; | 7 import '../util/util.dart'; |
| 8 import '../util/uri_extras.dart' show relativize; | 8 import '../util/uri_extras.dart' show relativize; |
| 9 import 'line_column_provider.dart'; | 9 import 'line_column_provider.dart'; |
| 10 import 'source_information.dart' show SourceLocation; | 10 import 'source_information.dart' show SourceLocation; |
| 11 | 11 |
| 12 class SourceMapBuilder { | 12 class SourceMapBuilder { |
| 13 | |
| 14 /// The URI of the source map file. | 13 /// The URI of the source map file. |
| 15 final Uri sourceMapUri; | 14 final Uri sourceMapUri; |
| 15 |
| 16 /// The URI of the target language file. | 16 /// The URI of the target language file. |
| 17 final Uri targetFileUri; | 17 final Uri targetFileUri; |
| 18 | 18 |
| 19 final LineColumnProvider lineColumnProvider; | 19 final LineColumnProvider lineColumnProvider; |
| 20 final List<SourceMapEntry> entries = new List<SourceMapEntry>(); | 20 final List<SourceMapEntry> entries = new List<SourceMapEntry>(); |
| 21 | 21 |
| 22 SourceMapBuilder(this.sourceMapUri, | 22 SourceMapBuilder( |
| 23 this.targetFileUri, | 23 this.sourceMapUri, this.targetFileUri, this.lineColumnProvider); |
| 24 this.lineColumnProvider); | |
| 25 | 24 |
| 26 void addMapping(int targetOffset, SourceLocation sourceLocation) { | 25 void addMapping(int targetOffset, SourceLocation sourceLocation) { |
| 27 entries.add(new SourceMapEntry(sourceLocation, targetOffset)); | 26 entries.add(new SourceMapEntry(sourceLocation, targetOffset)); |
| 28 } | 27 } |
| 29 | 28 |
| 30 void printStringListOn(Iterable<String> strings, StringBuffer buffer) { | 29 void printStringListOn(Iterable<String> strings, StringBuffer buffer) { |
| 31 bool first = true; | 30 bool first = true; |
| 32 buffer.write('['); | 31 buffer.write('['); |
| 33 for (String string in strings) { | 32 for (String string in strings) { |
| 34 if (!first) buffer.write(','); | 33 if (!first) buffer.write(','); |
| 35 buffer.write('"'); | 34 buffer.write('"'); |
| 36 writeJsonEscapedCharsOn(string, buffer); | 35 writeJsonEscapedCharsOn(string, buffer); |
| 37 buffer.write('"'); | 36 buffer.write('"'); |
| 38 first = false; | 37 first = false; |
| 39 } | 38 } |
| 40 buffer.write(']'); | 39 buffer.write(']'); |
| 41 } | 40 } |
| 42 | 41 |
| 43 String build() { | 42 String build() { |
| 44 | |
| 45 LineColumnMap<SourceMapEntry> lineColumnMap = | 43 LineColumnMap<SourceMapEntry> lineColumnMap = |
| 46 new LineColumnMap<SourceMapEntry>(); | 44 new LineColumnMap<SourceMapEntry>(); |
| 47 Map<Uri, LineColumnMap<SourceMapEntry>> sourceLocationMap = | 45 Map<Uri, LineColumnMap<SourceMapEntry>> sourceLocationMap = |
| 48 <Uri, LineColumnMap<SourceMapEntry>>{}; | 46 <Uri, LineColumnMap<SourceMapEntry>>{}; |
| 49 entries.forEach((SourceMapEntry sourceMapEntry) { | 47 entries.forEach((SourceMapEntry sourceMapEntry) { |
| 50 int line = lineColumnProvider.getLine(sourceMapEntry.targetOffset); | 48 int line = lineColumnProvider.getLine(sourceMapEntry.targetOffset); |
| 51 int column = | 49 int column = |
| 52 lineColumnProvider.getColumn(line, sourceMapEntry.targetOffset); | 50 lineColumnProvider.getColumn(line, sourceMapEntry.targetOffset); |
| 53 lineColumnMap.add(line, column, sourceMapEntry); | 51 lineColumnMap.add(line, column, sourceMapEntry); |
| 54 | 52 |
| 55 SourceLocation location = sourceMapEntry.sourceLocation; | 53 SourceLocation location = sourceMapEntry.sourceLocation; |
| 56 if (location != null) { | 54 if (location != null) { |
| 57 LineColumnMap<SourceMapEntry> sourceLineColumnMap = | 55 LineColumnMap<SourceMapEntry> sourceLineColumnMap = |
| 58 sourceLocationMap.putIfAbsent(location.sourceUri, | 56 sourceLocationMap.putIfAbsent( |
| 59 () => new LineColumnMap<SourceMapEntry>()); | 57 location.sourceUri, () => new LineColumnMap<SourceMapEntry>()); |
| 60 sourceLineColumnMap.add(location.line, location.column, sourceMapEntry); | 58 sourceLineColumnMap.add(location.line, location.column, sourceMapEntry); |
| 61 } | 59 } |
| 62 }); | 60 }); |
| 63 | 61 |
| 64 return _build(lineColumnMap); | 62 return _build(lineColumnMap); |
| 65 } | 63 } |
| 66 | 64 |
| 67 String _build(LineColumnMap<SourceMapEntry> lineColumnMap) { | 65 String _build(LineColumnMap<SourceMapEntry> lineColumnMap) { |
| 68 IndexMap<Uri> uriMap = new IndexMap<Uri>(); | 66 IndexMap<Uri> uriMap = new IndexMap<Uri>(); |
| 69 IndexMap<String> nameMap = new IndexMap<String>(); | 67 IndexMap<String> nameMap = new IndexMap<String>(); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 85 buffer.write('{\n'); | 83 buffer.write('{\n'); |
| 86 buffer.write(' "version": 3,\n'); | 84 buffer.write(' "version": 3,\n'); |
| 87 if (sourceMapUri != null && targetFileUri != null) { | 85 if (sourceMapUri != null && targetFileUri != null) { |
| 88 buffer.write( | 86 buffer.write( |
| 89 ' "file": "${relativize(sourceMapUri, targetFileUri, false)}",\n'); | 87 ' "file": "${relativize(sourceMapUri, targetFileUri, false)}",\n'); |
| 90 } | 88 } |
| 91 buffer.write(' "sourceRoot": "",\n'); | 89 buffer.write(' "sourceRoot": "",\n'); |
| 92 buffer.write(' "sources": '); | 90 buffer.write(' "sources": '); |
| 93 Iterable<String> relativeSourceUriList = const <String>[]; | 91 Iterable<String> relativeSourceUriList = const <String>[]; |
| 94 if (sourceMapUri != null) { | 92 if (sourceMapUri != null) { |
| 95 relativeSourceUriList = uriMap.elements | 93 relativeSourceUriList = |
| 96 .map((u) => relativize(sourceMapUri, u, false)); | 94 uriMap.elements.map((u) => relativize(sourceMapUri, u, false)); |
| 97 } | 95 } |
| 98 printStringListOn(relativeSourceUriList, buffer); | 96 printStringListOn(relativeSourceUriList, buffer); |
| 99 buffer.write(',\n'); | 97 buffer.write(',\n'); |
| 100 buffer.write(' "names": '); | 98 buffer.write(' "names": '); |
| 101 printStringListOn(nameMap.elements, buffer); | 99 printStringListOn(nameMap.elements, buffer); |
| 102 buffer.write(',\n'); | 100 buffer.write(',\n'); |
| 103 buffer.write(' "mappings": "'); | 101 buffer.write(' "mappings": "'); |
| 104 buffer.write(mappingsBuffer); | 102 buffer.write(mappingsBuffer); |
| 105 buffer.write('"\n}\n'); | 103 buffer.write('"\n}\n'); |
| 106 return buffer.toString(); | 104 return buffer.toString(); |
| 107 } | 105 } |
| 108 | 106 |
| 109 void writeEntries(LineColumnMap<SourceMapEntry> entries, | 107 void writeEntries(LineColumnMap<SourceMapEntry> entries, IndexMap<Uri> uriMap, |
| 110 IndexMap<Uri> uriMap, | 108 IndexMap<String> nameMap, StringBuffer output) { |
| 111 IndexMap<String> nameMap, | |
| 112 StringBuffer output) { | |
| 113 SourceLocation previousSourceLocation; | 109 SourceLocation previousSourceLocation; |
| 114 int previousTargetLine = 0; | 110 int previousTargetLine = 0; |
| 115 DeltaEncoder targetColumnEncoder = new DeltaEncoder(); | 111 DeltaEncoder targetColumnEncoder = new DeltaEncoder(); |
| 116 bool firstEntryInLine = true; | 112 bool firstEntryInLine = true; |
| 117 DeltaEncoder sourceUriIndexEncoder = new DeltaEncoder(); | 113 DeltaEncoder sourceUriIndexEncoder = new DeltaEncoder(); |
| 118 DeltaEncoder sourceLineEncoder = new DeltaEncoder(); | 114 DeltaEncoder sourceLineEncoder = new DeltaEncoder(); |
| 119 DeltaEncoder sourceColumnEncoder = new DeltaEncoder(); | 115 DeltaEncoder sourceColumnEncoder = new DeltaEncoder(); |
| 120 DeltaEncoder sourceNameIndexEncoder = new DeltaEncoder(); | 116 DeltaEncoder sourceNameIndexEncoder = new DeltaEncoder(); |
| 121 | 117 |
| 122 entries.forEach((int targetLine, | 118 entries.forEach((int targetLine, int targetColumn, SourceMapEntry entry) { |
| 123 int targetColumn, | |
| 124 SourceMapEntry entry) { | |
| 125 SourceLocation sourceLocation = entry.sourceLocation; | 119 SourceLocation sourceLocation = entry.sourceLocation; |
| 126 if (sourceLocation == previousSourceLocation) { | 120 if (sourceLocation == previousSourceLocation) { |
| 127 return; | 121 return; |
| 128 } | 122 } |
| 129 | 123 |
| 130 if (targetLine > previousTargetLine) { | 124 if (targetLine > previousTargetLine) { |
| 131 for (int i = previousTargetLine; i < targetLine; ++i) { | 125 for (int i = previousTargetLine; i < targetLine; ++i) { |
| 132 output.write(';'); | 126 output.write(';'); |
| 133 } | 127 } |
| 134 previousTargetLine = targetLine; | 128 previousTargetLine = targetLine; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 /// [output] and updates the last emitted value of the encoder. | 171 /// [output] and updates the last emitted value of the encoder. |
| 178 void encode(StringBuffer output, int value) { | 172 void encode(StringBuffer output, int value) { |
| 179 _value = encodeVLQ(output, value, _value); | 173 _value = encodeVLQ(output, value, _value); |
| 180 } | 174 } |
| 181 | 175 |
| 182 static const int VLQ_BASE_SHIFT = 5; | 176 static const int VLQ_BASE_SHIFT = 5; |
| 183 static const int VLQ_BASE_MASK = (1 << 5) - 1; | 177 static const int VLQ_BASE_MASK = (1 << 5) - 1; |
| 184 static const int VLQ_CONTINUATION_BIT = 1 << 5; | 178 static const int VLQ_CONTINUATION_BIT = 1 << 5; |
| 185 static const int VLQ_CONTINUATION_MASK = 1 << 5; | 179 static const int VLQ_CONTINUATION_MASK = 1 << 5; |
| 186 static const String BASE64_DIGITS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn' | 180 static const String BASE64_DIGITS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn' |
| 187 'opqrstuvwxyz0123456789+/'; | 181 'opqrstuvwxyz0123456789+/'; |
| 188 | 182 |
| 189 /// Writes the VLQ of delta between [value] and [offset] into [output] and | 183 /// Writes the VLQ of delta between [value] and [offset] into [output] and |
| 190 /// return [value]. | 184 /// return [value]. |
| 191 static int encodeVLQ(StringBuffer output, int value, int offset) { | 185 static int encodeVLQ(StringBuffer output, int value, int offset) { |
| 192 int delta = value - offset; | 186 int delta = value - offset; |
| 193 int signBit = 0; | 187 int signBit = 0; |
| 194 if (delta < 0) { | 188 if (delta < 0) { |
| 195 signBit = 1; | 189 signBit = 1; |
| 196 delta = -delta; | 190 delta = -delta; |
| 197 } | 191 } |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 int register(T element) { | 291 int register(T element) { |
| 298 return map.putIfAbsent(element, () => map.length); | 292 return map.putIfAbsent(element, () => map.length); |
| 299 } | 293 } |
| 300 | 294 |
| 301 /// Returns the index of [element]. | 295 /// Returns the index of [element]. |
| 302 int operator [](T element) => map[element]; | 296 int operator [](T element) => map[element]; |
| 303 | 297 |
| 304 /// Returns the indexed elements. | 298 /// Returns the indexed elements. |
| 305 Iterable<T> get elements => map.keys; | 299 Iterable<T> get elements => map.keys; |
| 306 } | 300 } |
| OLD | NEW |