| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 }); |
| OLD | NEW |