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

Side by Side Diff: src/js/messages.js

Issue 2002993002: Refactor script position calculation (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 7 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
« no previous file with comments | « src/isolate.cc ('k') | src/objects.h » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // ------------------------------------------------------------------- 5 // -------------------------------------------------------------------
6 6
7 (function(global, utils) { 7 (function(global, utils) {
8 8
9 %CheckIsBootstrapping(); 9 %CheckIsBootstrapping();
10 10
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 } 207 }
208 208
209 209
210 // Returns the source code line containing the given source 210 // Returns the source code line containing the given source
211 // position, or the empty string if the position is invalid. 211 // position, or the empty string if the position is invalid.
212 function GetSourceLine(message) { 212 function GetSourceLine(message) {
213 var script = %MessageGetScript(message); 213 var script = %MessageGetScript(message);
214 var start_position = %MessageGetStartPosition(message); 214 var start_position = %MessageGetStartPosition(message);
215 var location = script.locationFromPosition(start_position, true); 215 var location = script.locationFromPosition(start_position, true);
216 if (location == null) return ""; 216 if (location == null) return "";
217 return location.sourceText(); 217 return location.sourceText;
218 } 218 }
219 219
220 220
221 /** 221 /**
222 * Find a line number given a specific source position. 222 * Find a line number given a specific source position.
223 * @param {number} position The source position. 223 * @param {number} position The source position.
224 * @return {number} 0 if input too small, -1 if input too large, 224 * @return {number} 0 if input too small, -1 if input too large,
225 else the line number. 225 else the line number.
226 */ 226 */
227 function ScriptLineFromPosition(position) { 227 function ScriptLineFromPosition(position) {
228 var lower = 0; 228 var info = %ScriptPositionInfo(this, position, false);
229 var upper = this.lineCount() - 1; 229 return (info == null) ? -1 : info.line;
230 var line_ends = this.line_ends;
231
232 // We'll never find invalid positions so bail right away.
233 if (position > line_ends[upper]) {
234 return -1;
235 }
236
237 // This means we don't have to safe-guard indexing line_ends[i - 1].
238 if (position <= line_ends[0]) {
239 return 0;
240 }
241
242 // Binary search to find line # from position range.
243 while (upper >= 1) {
244 var i = (lower + upper) >> 1;
245
246 if (position > line_ends[i]) {
247 lower = i + 1;
248 } else if (position <= line_ends[i - 1]) {
249 upper = i - 1;
250 } else {
251 return i;
252 }
253 }
254
255 return -1;
256 } 230 }
257 231
258 232
259 /** 233 /**
260 * Get information on a specific source position. 234 * Get information on a specific source position.
235 * Returns an object with the following following properties:
236 * script : script object for the source
237 * line : source line number
238 * column : source column within the line
239 * position : position within the source
240 * sourceText : a string containing the current line
261 * @param {number} position The source position 241 * @param {number} position The source position
262 * @param {boolean} include_resource_offset Set to true to have the resource 242 * @param {boolean} include_resource_offset Set to true to have the resource
263 * offset added to the location 243 * offset added to the location
264 * @return {SourceLocation} 244 * @return If line is negative or not in the source null is returned.
265 * If line is negative or not in the source null is returned.
266 */ 245 */
267 function ScriptLocationFromPosition(position, 246 function ScriptLocationFromPosition(position,
268 include_resource_offset) { 247 include_resource_offset) {
269 var line = this.lineFromPosition(position); 248 return %ScriptPositionInfo(this, position, !!include_resource_offset);
270 if (line == -1) return null;
271
272 // Determine start, end and column.
273 var line_ends = this.line_ends;
274 var start = line == 0 ? 0 : line_ends[line - 1] + 1;
275 var end = line_ends[line];
276 if (end > 0 && %_StringCharAt(this.source, end - 1) === '\r') {
277 end--;
278 }
279 var column = position - start;
280
281 // Adjust according to the offset within the resource.
282 if (include_resource_offset) {
283 line += this.line_offset;
284 if (line == this.line_offset) {
285 column += this.column_offset;
286 }
287 }
288
289 return new SourceLocation(this, position, line, column, start, end);
290 } 249 }
291 250
292 251
293 /** 252 /**
294 * Get information on a specific source line and column possibly offset by a 253 * Get information on a specific source line and column possibly offset by a
295 * fixed source position. This function is used to find a source position from 254 * fixed source position. This function is used to find a source position from
296 * a line and column position. The fixed source position offset is typically 255 * a line and column position. The fixed source position offset is typically
297 * used to find a source position in a function based on a line and column in 256 * used to find a source position in a function based on a line and column in
298 * the source for the function alone. The offset passed will then be the 257 * the source for the function alone. The offset passed will then be the
299 * start position of the source for the function within the full script source. 258 * start position of the source for the function within the full script source.
300 * @param {number} opt_line The line within the source. Default value is 0 259 * @param {number} opt_line The line within the source. Default value is 0
301 * @param {number} opt_column The column in within the line. Default value is 0 260 * @param {number} opt_column The column in within the line. Default value is 0
302 * @param {number} opt_offset_position The offset from the begining of the 261 * @param {number} opt_offset_position The offset from the begining of the
303 * source from where the line and column calculation starts. 262 * source from where the line and column calculation starts.
304 * Default value is 0 263 * Default value is 0
305 * @return {SourceLocation} 264 * @return If line is negative or not in the source null is returned.
306 * If line is negative or not in the source null is returned.
307 */ 265 */
308 function ScriptLocationFromLine(opt_line, opt_column, opt_offset_position) { 266 function ScriptLocationFromLine(opt_line, opt_column, opt_offset_position) {
309 // Default is the first line in the script. Lines in the script is relative 267 // Default is the first line in the script. Lines in the script is relative
310 // to the offset within the resource. 268 // to the offset within the resource.
311 var line = 0; 269 var line = 0;
312 if (!IS_UNDEFINED(opt_line)) { 270 if (!IS_UNDEFINED(opt_line)) {
313 line = opt_line - this.line_offset; 271 line = opt_line - this.line_offset;
314 } 272 }
315 273
316 // Default is first column. If on the first line add the offset within the 274 // Default is first column. If on the first line add the offset within the
317 // resource. 275 // resource.
318 var column = opt_column || 0; 276 var column = opt_column || 0;
319 if (line == 0) { 277 if (line == 0) {
320 column -= this.column_offset; 278 column -= this.column_offset;
321 } 279 }
322 280
323 var offset_position = opt_offset_position || 0; 281 var offset_position = opt_offset_position || 0;
324 if (line < 0 || column < 0 || offset_position < 0) return null; 282 if (line < 0 || column < 0 || offset_position < 0) return null;
325 if (line == 0) { 283 if (line == 0) {
326 return this.locationFromPosition(offset_position + column, false); 284 return this.locationFromPosition(offset_position + column, false);
327 } else { 285 } else {
328 // Find the line where the offset position is located. 286 // Find the line where the offset position is located.
329 var offset_line = this.lineFromPosition(offset_position); 287 var offset_line = this.lineFromPosition(offset_position);
330 288
331 if (offset_line == -1 || offset_line + line >= this.lineCount()) { 289 if (offset_line == -1 || offset_line + line >= this.lineCount()) {
332 return null; 290 return null;
333 } 291 }
334 292
335 return this.locationFromPosition( 293 return this.locationFromPosition(
336 this.line_ends[offset_line + line - 1] + 1 + column); // line > 0 here. 294 %ScriptLineStartPosition(this, offset_line + line) + column);
337 } 295 }
338 } 296 }
339 297
340 298
341 /** 299 /**
342 * Get a slice of source code from the script. The boundaries for the slice is 300 * Get a slice of source code from the script. The boundaries for the slice is
343 * specified in lines. 301 * specified in lines.
344 * @param {number} opt_from_line The first line (zero bound) in the slice. 302 * @param {number} opt_from_line The first line (zero bound) in the slice.
345 * Default is 0 303 * Default is 0
346 * @param {number} opt_to_column The last line (zero bound) in the slice (non 304 * @param {number} opt_to_column The last line (zero bound) in the slice (non
(...skipping 13 matching lines...) Expand all
360 if (from_line < 0) from_line = 0; 318 if (from_line < 0) from_line = 0;
361 if (to_line > this.lineCount()) to_line = this.lineCount(); 319 if (to_line > this.lineCount()) to_line = this.lineCount();
362 320
363 // Check parameters. 321 // Check parameters.
364 if (from_line >= this.lineCount() || 322 if (from_line >= this.lineCount() ||
365 to_line < 0 || 323 to_line < 0 ||
366 from_line > to_line) { 324 from_line > to_line) {
367 return null; 325 return null;
368 } 326 }
369 327
370 var line_ends = this.line_ends; 328 var from_position = %ScriptLineStartPosition(this, from_line);
371 var from_position = from_line == 0 ? 0 : line_ends[from_line - 1] + 1; 329 var to_position = %ScriptLineStartPosition(this, to_line);
372 var to_position = to_line == 0 ? 0 : line_ends[to_line - 1] + 1;
373 330
374 // Return a source slice with line numbers re-adjusted to the resource. 331 // Return a source slice with line numbers re-adjusted to the resource.
375 return new SourceSlice(this, 332 return new SourceSlice(this,
376 from_line + this.line_offset, 333 from_line + this.line_offset,
377 to_line + this.line_offset, 334 to_line + this.line_offset,
378 from_position, to_position); 335 from_position, to_position);
379 } 336 }
380 337
381 338
382 function ScriptSourceLine(opt_line) { 339 function ScriptSourceLine(opt_line) {
383 // Default is the first line in the script. Lines in the script are relative 340 // Default is the first line in the script. Lines in the script are relative
384 // to the offset within the resource. 341 // to the offset within the resource.
385 var line = 0; 342 var line = 0;
386 if (!IS_UNDEFINED(opt_line)) { 343 if (!IS_UNDEFINED(opt_line)) {
387 line = opt_line - this.line_offset; 344 line = opt_line - this.line_offset;
388 } 345 }
389 346
390 // Check parameter. 347 // Check parameter.
391 if (line < 0 || this.lineCount() <= line) { 348 if (line < 0 || this.lineCount() <= line) {
392 return null; 349 return null;
393 } 350 }
394 351
395 // Return the source line. 352 // Return the source line.
396 var line_ends = this.line_ends; 353 var start = %ScriptLineStartPosition(this, line);
397 var start = line == 0 ? 0 : line_ends[line - 1] + 1; 354 var end = %ScriptLineEndPosition(this, line);
398 var end = line_ends[line];
399 return %_Call(StringSubstring, this.source, start, end); 355 return %_Call(StringSubstring, this.source, start, end);
400 } 356 }
401 357
402 358
403 /** 359 /**
404 * Returns the number of source lines. 360 * Returns the number of source lines.
405 * @return {number} 361 * @return {number}
406 * Number of source lines. 362 * Number of source lines.
407 */ 363 */
408 function ScriptLineCount() { 364 function ScriptLineCount() {
409 // Return number of source lines. 365 // Return number of source lines.
410 return this.line_ends.length; 366 return %ScriptLineCount(this);
411 } 367 }
412 368
413 369
414 /**
415 * Returns the position of the nth line end.
416 * @return {number}
417 * Zero-based position of the nth line end in the script.
418 */
419 function ScriptLineEnd(n) {
420 return this.line_ends[n];
421 }
422
423
424 /** 370 /**
425 * If sourceURL comment is available returns sourceURL comment contents. 371 * If sourceURL comment is available returns sourceURL comment contents.
426 * Otherwise, script name is returned. See 372 * Otherwise, script name is returned. See
427 * http://fbug.googlecode.com/svn/branches/firebug1.1/docs/ReleaseNotes_1.1.txt 373 * http://fbug.googlecode.com/svn/branches/firebug1.1/docs/ReleaseNotes_1.1.txt
428 * and Source Map Revision 3 proposal for details on using //# sourceURL and 374 * and Source Map Revision 3 proposal for details on using //# sourceURL and
429 * deprecated //@ sourceURL comment to identify scripts that don't have name. 375 * deprecated //@ sourceURL comment to identify scripts that don't have name.
430 * 376 *
431 * @return {?string} script name if present, value for //# sourceURL comment or 377 * @return {?string} script name if present, value for //# sourceURL comment or
432 * deprecated //@ sourceURL comment otherwise. 378 * deprecated //@ sourceURL comment otherwise.
433 */ 379 */
434 function ScriptNameOrSourceURL() { 380 function ScriptNameOrSourceURL() {
435 if (this.source_url) return this.source_url; 381 if (this.source_url) return this.source_url;
436 return this.name; 382 return this.name;
437 } 383 }
438 384
439 385
440 utils.SetUpLockedPrototype(Script, [ 386 utils.SetUpLockedPrototype(Script, [
441 "source", 387 "source",
442 "name", 388 "name",
443 "source_url", 389 "source_url",
444 "source_mapping_url", 390 "source_mapping_url",
445 "line_ends",
446 "line_offset", 391 "line_offset",
447 "column_offset" 392 "column_offset"
448 ], [ 393 ], [
449 "lineFromPosition", ScriptLineFromPosition, 394 "lineFromPosition", ScriptLineFromPosition,
450 "locationFromPosition", ScriptLocationFromPosition, 395 "locationFromPosition", ScriptLocationFromPosition,
451 "locationFromLine", ScriptLocationFromLine, 396 "locationFromLine", ScriptLocationFromLine,
452 "sourceSlice", ScriptSourceSlice, 397 "sourceSlice", ScriptSourceSlice,
453 "sourceLine", ScriptSourceLine, 398 "sourceLine", ScriptSourceLine,
454 "lineCount", ScriptLineCount, 399 "lineCount", ScriptLineCount,
455 "nameOrSourceURL", ScriptNameOrSourceURL, 400 "nameOrSourceURL", ScriptNameOrSourceURL,
456 "lineEnd", ScriptLineEnd
457 ] 401 ]
458 ); 402 );
459 403
460 404
461 /** 405 /**
462 * Class for source location. A source location is a position within some
463 * source with the following properties:
464 * script : script object for the source
465 * line : source line number
466 * column : source column within the line
467 * position : position within the source
468 * start : position of start of source context (inclusive)
469 * end : position of end of source context (not inclusive)
470 * Source text for the source context is the character interval
471 * [start, end[. In most cases end will point to a newline character.
472 * It might point just past the final position of the source if the last
473 * source line does not end with a newline character.
474 * @param {Script} script The Script object for which this is a location
475 * @param {number} position Source position for the location
476 * @param {number} line The line number for the location
477 * @param {number} column The column within the line for the location
478 * @param {number} start Source position for start of source context
479 * @param {number} end Source position for end of source context
480 * @constructor
481 */
482 function SourceLocation(script, position, line, column, start, end) {
483 this.script = script;
484 this.position = position;
485 this.line = line;
486 this.column = column;
487 this.start = start;
488 this.end = end;
489 }
490
491
492 /**
493 * Get the source text for a SourceLocation
494 * @return {String}
495 * Source text for this location.
496 */
497 function SourceLocationSourceText() {
498 return %_Call(StringSubstring, this.script.source, this.start, this.end);
499 }
500
501
502 utils.SetUpLockedPrototype(SourceLocation,
503 ["script", "position", "line", "column", "start", "end"],
504 ["sourceText", SourceLocationSourceText]
505 );
506
507
508 /**
509 * Class for a source slice. A source slice is a part of a script source with 406 * Class for a source slice. A source slice is a part of a script source with
510 * the following properties: 407 * the following properties:
511 * script : script object for the source 408 * script : script object for the source
512 * from_line : line number for the first line in the slice 409 * from_line : line number for the first line in the slice
513 * to_line : source line number for the last line in the slice 410 * to_line : source line number for the last line in the slice
514 * from_position : position of the first character in the slice 411 * from_position : position of the first character in the slice
515 * to_position : position of the last character in the slice 412 * to_position : position of the last character in the slice
516 * The to_line and to_position are not included in the slice, that is the lines 413 * The to_line and to_position are not included in the slice, that is the lines
517 * in the slice are [from_line, to_line[. Likewise the characters in the slice 414 * in the slice are [from_line, to_line[. Likewise the characters in the slice
518 * are [from_position, to_position[. 415 * are [from_position, to_position[.
(...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after
1040 utils.Export(function(to) { 937 utils.Export(function(to) {
1041 to.ErrorToString = ErrorToString; 938 to.ErrorToString = ErrorToString;
1042 to.MakeError = MakeError; 939 to.MakeError = MakeError;
1043 to.MakeRangeError = MakeRangeError; 940 to.MakeRangeError = MakeRangeError;
1044 to.MakeSyntaxError = MakeSyntaxError; 941 to.MakeSyntaxError = MakeSyntaxError;
1045 to.MakeTypeError = MakeTypeError; 942 to.MakeTypeError = MakeTypeError;
1046 to.MakeURIError = MakeURIError; 943 to.MakeURIError = MakeURIError;
1047 }); 944 });
1048 945
1049 }); 946 });
OLDNEW
« no previous file with comments | « src/isolate.cc ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698