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

Side by Side Diff: pkg/source_maps/lib/span.dart

Issue 18749005: Fixes in sourcemaps discovered in csslib (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | pkg/source_maps/test/span_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 /// Dart classes representing the souce spans and source files. 5 /// Dart classes representing the souce spans and source files.
6 library source_maps.span; 6 library source_maps.span;
7 7
8 import 'dart:utf' show stringToCodepoints; 8 import 'dart:utf' show stringToCodepoints;
9 import 'dart:math' show min, max; 9 import 'dart:math' show min, max;
10 10
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 Span span(int start, [int end, bool isIdentifier = false]) => 212 Span span(int start, [int end, bool isIdentifier = false]) =>
213 new FileSpan(this, start, end, isIdentifier); 213 new FileSpan(this, start, end, isIdentifier);
214 214
215 /// Returns a location in this [SourceFile] with the given offset. 215 /// Returns a location in this [SourceFile] with the given offset.
216 Location location(int offset) => new FileLocation(this, offset); 216 Location location(int offset) => new FileLocation(this, offset);
217 217
218 /// Gets the 0-based line corresponding to an offset. 218 /// Gets the 0-based line corresponding to an offset.
219 int getLine(int offset) => binarySearch(_lineStarts, (o) => o > offset) - 1; 219 int getLine(int offset) => binarySearch(_lineStarts, (o) => o > offset) - 1;
220 220
221 /// Gets the 0-based column corresponding to an offset. 221 /// Gets the 0-based column corresponding to an offset.
222 int getColumn(int line, int offset) => offset - _lineStarts[line]; 222 int getColumn(int line, int offset) {
223 if (line < 0 || line >= _lineStarts.length) return 0;
224 return offset - _lineStarts[line];
225 }
223 226
224 /// Get the offset for a given line and column 227 /// Get the offset for a given line and column
225 int getOffset(int line, int column) => 228 int getOffset(int line, int column) {
226 _lineStarts[max(min(line, _lineStarts.length - 1), 0)] + column; 229 if (line < 0) return getOffset(0, 0);
230 if (line < _lineStarts.length) {
231 return _lineStarts[line] + column;
232 } else {
233 return _decodedChars.length;
234 }
235 }
227 236
228 /// Gets the text at the given offsets. 237 /// Gets the text at the given offsets.
229 String getText(int start, [int end]) => 238 String getText(int start, [int end]) =>
230 new String.fromCharCodes(_decodedChars.sublist(max(start, 0), end)); 239 new String.fromCharCodes(_decodedChars.sublist(max(start, 0), end));
231 240
232 /// Create a pretty string representation from a span. 241 /// Create a pretty string representation from a span.
233 String getLocationMessage(String message, int start, int end, 242 String getLocationMessage(String message, int start, int end,
234 {bool useColors: false, String color}) { 243 {bool useColors: false, String color}) {
235 // TODO(jmesserly): it would be more useful to pass in an object that 244 // TODO(jmesserly): it would be more useful to pass in an object that
236 // controls how the errors are printed. This method is a bit too smart. 245 // controls how the errors are printed. This method is a bit too smart.
237 var line = getLine(start); 246 var line = getLine(start);
238 var column = getColumn(line, start); 247 var column = getColumn(line, start);
239 248
240 var src = url == null ? '' : url; 249 var src = url == null ? '' : url;
241 var msg = '$src:${line + 1}:${column + 1}: $message'; 250 var msg = '$src:${line + 1}:${column + 1}: $message';
242 251
243 if (_decodedChars == null) { 252 if (_decodedChars == null) {
244 // We don't have any text to include, so exit. 253 // We don't have any text to include, so exit.
245 return msg; 254 return msg;
246 } 255 }
247 256
248 var buf = new StringBuffer(msg); 257 var buf = new StringBuffer(msg);
249 buf.write('\n'); 258 buf.write('\n');
250 259
251 // +1 for 0-indexing, +1 again to avoid the last line 260 // +1 for 0-indexing, +1 again to avoid the last line
252 var textLine = getText(getOffset(line, 0), getOffset(line + 1, 0)); 261 var textLine = getText(getOffset(line, 0), getOffset(line + 1, 0));
253 262
254
255 column = min(column, textLine.length - 1); 263 column = min(column, textLine.length - 1);
256 int toColumn = min(column + end - start, textLine.length); 264 int toColumn = min(column + end - start, textLine.length);
257 if (useColors) { 265 if (useColors) {
258 if (color == null) { 266 if (color == null) {
259 color = _RED_COLOR; 267 color = _RED_COLOR;
260 } 268 }
261 buf.write(textLine.substring(0, column)); 269 buf.write(textLine.substring(0, column));
262 buf.write(color); 270 buf.write(color);
263 buf.write(textLine.substring(column, toColumn)); 271 buf.write(textLine.substring(column, toColumn));
264 buf.write(_NO_COLOR); 272 buf.write(_NO_COLOR);
265 buf.write(textLine.substring(toColumn)); 273 buf.write(textLine.substring(toColumn));
266 } else { 274 } else {
267 buf.write(textLine); 275 buf.write(textLine);
276 if (textLine != '' && !textLine.endsWith('\n')) buf.write('\n');
268 } 277 }
269 278
270 int i = 0; 279 int i = 0;
271 for (; i < column; i++) { 280 for (; i < column; i++) {
272 buf.write(' '); 281 buf.write(' ');
273 } 282 }
274 283
275 if (useColors) buf.write(color); 284 if (useColors) buf.write(color);
276 for (; i < toColumn; i++) { 285 for (; i < toColumn; i++) {
277 buf.write('^'); 286 buf.write('^');
278 } 287 }
279 if (useColors) buf.write(_NO_COLOR); 288 if (useColors) buf.write(_NO_COLOR);
280 return buf.toString(); 289 return buf.toString();
281 } 290 }
282 } 291 }
283 292
284 /// A convenience type to treat a code segment as if it were a separate 293 /// A convenience type to treat a code segment as if it were a separate
285 /// [SourceFile]. A [SourceFileSegment] shifts all locations by an offset, which 294 /// [SourceFile]. A [SourceFileSegment] shifts all locations by an offset, which
286 /// allows you to set source-map locations based on the locations relative to 295 /// allows you to set source-map locations based on the locations relative to
287 /// the start of the segment, but that get translated to absolute locations in 296 /// the start of the segment, but that get translated to absolute locations in
288 /// the original source file. 297 /// the original source file.
289 class SourceFileSegment extends SourceFile { 298 class SourceFileSegment extends SourceFile {
290 final int _baseOffset; 299 final int _baseOffset;
291 final int _baseLine; 300 final int _baseLine;
292 final int _baseColumn; 301 final int _baseColumn;
302 final int _maxOffset;
293 303
294 // TODO(sigmund): consider providing an end-offset to correctly truncate
295 // values passed the end of the segment.
296 SourceFileSegment(String url, String textSegment, Location startOffset) 304 SourceFileSegment(String url, String textSegment, Location startOffset)
297 : _baseOffset = startOffset.offset, 305 : _baseOffset = startOffset.offset,
298 _baseLine = startOffset.line, 306 _baseLine = startOffset.line,
299 _baseColumn = startOffset.column, 307 _baseColumn = startOffset.column,
308 _maxOffset = startOffset.offset + textSegment.length,
300 super.text(url, textSegment); 309 super.text(url, textSegment);
301 310
302 /// Craete a span, where [start] is relative to this segment's base offset. 311 /// Craete a span, where [start] is relative to this segment's base offset.
303 /// The returned span stores the real offset on the file, so that error 312 /// The returned span stores the real offset on the file, so that error
304 /// messages are reported at the real location. 313 /// messages are reported at the real location.
305 Span span(int start, [int end, bool isIdentifier = false]) => 314 Span span(int start, [int end, bool isIdentifier = false]) =>
306 super.span(start + _baseOffset, 315 super.span(start + _baseOffset,
307 end == null ? null : end + _baseOffset, isIdentifier); 316 end == null ? null : end + _baseOffset, isIdentifier);
308 317
309 /// Create a location, where [offset] relative to this segment's base offset. 318 /// Create a location, where [offset] relative to this segment's base offset.
310 /// The returned span stores the real offset on the file, so that error 319 /// The returned span stores the real offset on the file, so that error
311 /// messages are reported at the real location. 320 /// messages are reported at the real location.
312 Location location(int offset) => super.location(offset + _baseOffset); 321 Location location(int offset) => super.location(offset + _baseOffset);
313 322
314 /// Return the line on the underlying file associated with the [offset] of the 323 /// Return the line on the underlying file associated with the [offset] of the
315 /// underlying file. This method operates on the real offsets from the 324 /// underlying file. This method operates on the real offsets from the
316 /// original file, so that error messages can be reported accurately. 325 /// original file, so that error messages can be reported accurately. When the
317 int getLine(int offset) => 326 /// requested offset is past the length of the segment, this returns the line
318 super.getLine(max(offset - _baseOffset, 0)) + _baseLine; 327 /// number after the end of the segment (total lines + 1).
328 int getLine(int offset) {
329 var res = super.getLine(max(offset - _baseOffset, 0)) + _baseLine;
330 return (offset > _maxOffset) ? res + 1 : res;
331 }
319 332
320 /// Return the column on the underlying file associated with [line] and 333 /// Return the column on the underlying file associated with [line] and
321 /// [offset], where [line] is absolute from the beginning of the underlying 334 /// [offset], where [line] is absolute from the beginning of the underlying
322 /// file. This method operates on the real offsets from the original file, so 335 /// file. This method operates on the real offsets from the original file, so
323 /// that error messages can be reported accurately. 336 /// that error messages can be reported accurately.
324 int getColumn(int line, int offset) { 337 int getColumn(int line, int offset) {
325 var col = super.getColumn(line - _baseLine, max(offset - _baseOffset, 0)); 338 var col = super.getColumn(line - _baseLine, max(offset - _baseOffset, 0));
326 return line == _baseLine ? col + _baseColumn : col; 339 return line == _baseLine ? col + _baseColumn : col;
327 } 340 }
328 341
329 /// Return the offset associated with a line and column. This method operates 342 /// Return the offset associated with a line and column. This method operates
330 /// on the real offsets from the original file, so that error messages can be 343 /// on the real offsets from the original file, so that error messages can be
331 /// reported accurately. 344 /// reported accurately.
332 int getOffset(int line, int column) => 345 int getOffset(int line, int column) =>
333 super.getOffset(line - _baseLine, 346 super.getOffset(line - _baseLine,
334 line == _baseLine ? column - _baseColumn : column) + _baseOffset; 347 line == _baseLine ? column - _baseColumn : column) + _baseOffset;
335 348
336 /// Retrieve the text associated with the specified range. This method 349 /// Retrieve the text associated with the specified range. This method
337 /// operates on the real offsets from the original file, so that error 350 /// operates on the real offsets from the original file, so that error
338 /// messages can be reported accurately. 351 /// messages can be reported accurately.
339 String getText(int start, [int end]) => 352 String getText(int start, [int end]) =>
340 super.getText(start - _baseOffset, 353 super.getText(start - _baseOffset, end == null ? null : end - _baseOffset);
341 end == null ? null : end - _baseOffset);
342 } 354 }
OLDNEW
« no previous file with comments | « no previous file | pkg/source_maps/test/span_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698