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

Side by Side Diff: src/messages.js

Issue 21041: Refactor code for determining line position in a source file.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 10 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 | « src/compiler.cc ('k') | src/objects.cc » ('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 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 apply_non_function: "Function.prototype.apply was called on %0, whic h is a %1 and not a function", 95 apply_non_function: "Function.prototype.apply was called on %0, whic h is a %1 and not a function",
96 apply_wrong_args: "Function.prototype.apply: Arguments list has wr ong type", 96 apply_wrong_args: "Function.prototype.apply: Arguments list has wr ong type",
97 invalid_in_operator_use: "Cannot use 'in' operator to search for '%0' in %1", 97 invalid_in_operator_use: "Cannot use 'in' operator to search for '%0' in %1",
98 instanceof_function_expected: "Expecting a function in instanceof check, but g ot %0", 98 instanceof_function_expected: "Expecting a function in instanceof check, but g ot %0",
99 instanceof_nonobject_proto: "Function has non-object prototype '%0' in insta nceof check", 99 instanceof_nonobject_proto: "Function has non-object prototype '%0' in insta nceof check",
100 null_to_object: "Cannot convert null to object", 100 null_to_object: "Cannot convert null to object",
101 // RangeError 101 // RangeError
102 invalid_array_length: "Invalid array length", 102 invalid_array_length: "Invalid array length",
103 invalid_array_apply_length: "Function.prototype.apply supports only up to 10 24 arguments", 103 invalid_array_apply_length: "Function.prototype.apply supports only up to 10 24 arguments",
104 stack_overflow: "Maximum call stack size exceeded", 104 stack_overflow: "Maximum call stack size exceeded",
105 apply_overflow: "Function.prototype.apply cannot support %0 argu ments", 105 apply_overflow: "Function.prototype.apply cannot support %0 argu ments",
106 // SyntaxError 106 // SyntaxError
107 unable_to_parse: "Parse error", 107 unable_to_parse: "Parse error",
108 duplicate_regexp_flag: "Duplicate RegExp flag %0", 108 duplicate_regexp_flag: "Duplicate RegExp flag %0",
109 unrecognized_regexp_flag: "Unrecognized RegExp flag %0", 109 unrecognized_regexp_flag: "Unrecognized RegExp flag %0",
110 invalid_regexp: "Invalid RegExp pattern /%0/", 110 invalid_regexp: "Invalid RegExp pattern /%0/",
111 illegal_break: "Illegal break statement", 111 illegal_break: "Illegal break statement",
112 illegal_continue: "Illegal continue statement", 112 illegal_continue: "Illegal continue statement",
113 illegal_return: "Illegal return statement", 113 illegal_return: "Illegal return statement",
114 error_loading_debugger: "Error loading debugger %0", 114 error_loading_debugger: "Error loading debugger %0",
115 no_input_to_regexp: "No input to %0", 115 no_input_to_regexp: "No input to %0",
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 return MakeGenericError($EvalError, type, args); 221 return MakeGenericError($EvalError, type, args);
222 } 222 }
223 223
224 224
225 function MakeError(type, args) { 225 function MakeError(type, args) {
226 return MakeGenericError($Error, type, args); 226 return MakeGenericError($Error, type, args);
227 } 227 }
228 228
229 229
230 /** 230 /**
231 * Initialize the cached source information in a script. Currently all line
232 * end positions are cached.
233 */
234 Script.prototype.initSourceInfo_ = function () {
235 // Just return if initialized.
236 if (this.lineEnds_) return;
237
238 // Collect all line endings.
239 this.lineEnds_ = [];
240 for (var i = 0; i < this.source.length; i++) {
241 var current = this.source.charAt(i);
242 if (current == '\n') {
243 this.lineEnds_.push(i);
244 }
245 }
246
247 // If the script does not end with a line ending add the final end position
248 // as just past the last line ending.
249 if (this.lineEnds_[this.lineEnds_.length - 1] != this.source.length - 1) {
250 this.lineEnds_.push(this.source.length);
251 }
252 };
253
254
255 /**
256 * Get information on a specific source position. 231 * Get information on a specific source position.
257 * @param {number} position The source position 232 * @param {number} position The source position
258 * @return {SourceLocation} 233 * @return {SourceLocation}
259 * If line is negative or not in the source null is returned. 234 * If line is negative or not in the source null is returned.
260 */ 235 */
261 Script.prototype.locationFromPosition = function (position) { 236 Script.prototype.locationFromPosition = function (position) {
262 // Make sure source info has been initialized.
263 this.initSourceInfo_();
264
265 var lineCount = this.lineCount(); 237 var lineCount = this.lineCount();
266 var line = -1; 238 var line = -1;
267 if (position <= this.lineEnds_[0]) { 239 if (position <= this.line_ends[0]) {
268 line = 0; 240 line = 0;
269 } else { 241 } else {
270 for (var i = 1; i < lineCount; i++) { 242 for (var i = 1; i < lineCount; i++) {
271 if (this.lineEnds_[i - 1] < position && position <= this.lineEnds_[i]) { 243 if (this.line_ends[i - 1] < position && position <= this.line_ends[i]) {
272 line = i; 244 line = i;
273 break; 245 break;
274 } 246 }
275 } 247 }
276 } 248 }
277 249
278 if (line == -1) return null; 250 if (line == -1) return null;
279 251
280 // Determine start, end and column. 252 // Determine start, end and column.
281 var start = line == 0 ? 0 : this.lineEnds_[line - 1] + 1; 253 var start = line == 0 ? 0 : this.line_ends[line - 1] + 1;
282 var end = this.lineEnds_[line]; 254 var end = this.line_ends[line];
283 if (end > 0 && this.source.charAt(end - 1) == '\r') end--; 255 if (end > 0 && this.source.charAt(end - 1) == '\r') end--;
284 var column = position - start; 256 var column = position - start;
285 257
286 // Adjust according to the offset within the resource. 258 // Adjust according to the offset within the resource.
287 line += this.line_offset; 259 line += this.line_offset;
288 if (line == this.line_offset) { 260 if (line == this.line_offset) {
289 column += this.column_offset; 261 column += this.column_offset;
290 } 262 }
291 263
292 return new SourceLocation(this, position, line, column, start, end); 264 return new SourceLocation(this, position, line, column, start, end);
293 }; 265 };
294 266
295 267
296 /** 268 /**
297 * Get information on a specific source line and column possibly offset by a 269 * Get information on a specific source line and column possibly offset by a
298 * fixed source position. This function is used to find a source position from 270 * fixed source position. This function is used to find a source position from
299 * a line and column position. The fixed source position offset is typically 271 * a line and column position. The fixed source position offset is typically
300 * used to find a source position in a function based on a line and column in 272 * used to find a source position in a function based on a line and column in
301 * the source for the function alone. The offset passed will then be the 273 * the source for the function alone. The offset passed will then be the
302 * start position of the source for the function within the full script source. 274 * start position of the source for the function within the full script source.
303 * @param {number} opt_line The line within the source. Default value is 0 275 * @param {number} opt_line The line within the source. Default value is 0
304 * @param {number} opt_column The column in within the line. Default value is 0 276 * @param {number} opt_column The column in within the line. Default value is 0
305 * @param {number} opt_offset_position The offset from the begining of the 277 * @param {number} opt_offset_position The offset from the begining of the
306 * source from where the line and column calculation starts. Default value i s 0 278 * source from where the line and column calculation starts. Default value i s 0
307 * @return {SourceLocation} 279 * @return {SourceLocation}
308 * If line is negative or not in the source null is returned. 280 * If line is negative or not in the source null is returned.
309 */ 281 */
310 Script.prototype.locationFromLine = function (opt_line, opt_column, opt_offset_p osition) { 282 Script.prototype.locationFromLine = function (opt_line, opt_column, opt_offset_p osition) {
311 // Make soure source info has been initialized.
312 this.initSourceInfo_();
313
314 // Default is the first line in the script. Lines in the script is relative 283 // Default is the first line in the script. Lines in the script is relative
315 // to the offset within the resource. 284 // to the offset within the resource.
316 var line = 0; 285 var line = 0;
317 if (!IS_UNDEFINED(opt_line)) { 286 if (!IS_UNDEFINED(opt_line)) {
318 line = opt_line - this.line_offset; 287 line = opt_line - this.line_offset;
319 } 288 }
320 289
321 // Default is first column. If on the first line add the offset within the 290 // Default is first column. If on the first line add the offset within the
322 // resource. 291 // resource.
323 var column = opt_column || 0; 292 var column = opt_column || 0;
324 if (line == 0) { 293 if (line == 0) {
325 column -= this.column_offset 294 column -= this.column_offset
326 } 295 }
327 296
328 var offset_position = opt_offset_position || 0; 297 var offset_position = opt_offset_position || 0;
329 if (line < 0 || column < 0 || offset_position < 0) return null; 298 if (line < 0 || column < 0 || offset_position < 0) return null;
330 if (line == 0) { 299 if (line == 0) {
331 return this.locationFromPosition(offset_position + column); 300 return this.locationFromPosition(offset_position + column);
332 } else { 301 } else {
333 // Find the line where the offset position is located 302 // Find the line where the offset position is located
334 var lineCount = this.lineCount(); 303 var lineCount = this.lineCount();
335 var offset_line; 304 var offset_line;
336 for (var i = 0; i < lineCount; i++) { 305 for (var i = 0; i < lineCount; i++) {
337 if (offset_position <= this.lineEnds_[i]) { 306 if (offset_position <= this.line_ends[i]) {
338 offset_line = i; 307 offset_line = i;
339 break; 308 break;
340 } 309 }
341 } 310 }
342 if (offset_line + line >= lineCount) return null; 311 if (offset_line + line >= lineCount) return null;
343 return this.locationFromPosition(this.lineEnds_[offset_line + line - 1] + 1 + column); // line > 0 here. 312 return this.locationFromPosition(this.line_ends[offset_line + line - 1] + 1 + column); // line > 0 here.
344 } 313 }
345 } 314 }
346 315
347 316
348 /** 317 /**
349 * Get a slice of source code from the script. The boundaries for the slice is 318 * Get a slice of source code from the script. The boundaries for the slice is
350 * specified in lines. 319 * specified in lines.
351 * @param {number} opt_from_line The first line (zero bound) in the slice. 320 * @param {number} opt_from_line The first line (zero bound) in the slice.
352 * Default is 0 321 * Default is 0
353 * @param {number} opt_to_column The last line (zero bound) in the slice (non 322 * @param {number} opt_to_column The last line (zero bound) in the slice (non
354 * inclusive). Default is the number of lines in the script 323 * inclusive). Default is the number of lines in the script
355 * @return {SourceSlice} The source slice or null of the parameters where 324 * @return {SourceSlice} The source slice or null of the parameters where
356 * invalid 325 * invalid
357 */ 326 */
358 Script.prototype.sourceSlice = function (opt_from_line, opt_to_line) { 327 Script.prototype.sourceSlice = function (opt_from_line, opt_to_line) {
359 // Make soure source info has been initialized.
360 this.initSourceInfo_();
361
362 var from_line = IS_UNDEFINED(opt_from_line) ? this.line_offset : opt_from_line ; 328 var from_line = IS_UNDEFINED(opt_from_line) ? this.line_offset : opt_from_line ;
363 var to_line = IS_UNDEFINED(opt_to_line) ? this.line_offset + this.lineCount() : opt_to_line 329 var to_line = IS_UNDEFINED(opt_to_line) ? this.line_offset + this.lineCount() : opt_to_line
364 330
365 // Adjust according to the offset within the resource. 331 // Adjust according to the offset within the resource.
366 from_line -= this.line_offset; 332 from_line -= this.line_offset;
367 to_line -= this.line_offset; 333 to_line -= this.line_offset;
368 if (from_line < 0) from_line = 0; 334 if (from_line < 0) from_line = 0;
369 if (to_line > this.lineCount()) to_line = this.lineCount(); 335 if (to_line > this.lineCount()) to_line = this.lineCount();
370 336
371 // Check parameters. 337 // Check parameters.
372 if (from_line >= this.lineCount() || 338 if (from_line >= this.lineCount() ||
373 to_line < 0 || 339 to_line < 0 ||
374 from_line > to_line) { 340 from_line > to_line) {
375 return null; 341 return null;
376 } 342 }
377 343
378 var from_position = from_line == 0 ? 0 : this.lineEnds_[from_line - 1] + 1; 344 var from_position = from_line == 0 ? 0 : this.line_ends[from_line - 1] + 1;
379 var to_position = to_line == 0 ? 0 : this.lineEnds_[to_line - 1] + 1; 345 var to_position = to_line == 0 ? 0 : this.line_ends[to_line - 1] + 1;
380 346
381 // Return a source slice with line numbers re-adjusted to the resource. 347 // Return a source slice with line numbers re-adjusted to the resource.
382 return new SourceSlice(this, from_line + this.line_offset, to_line + this.line _offset, 348 return new SourceSlice(this, from_line + this.line_offset, to_line + this.line _offset,
383 from_position, to_position); 349 from_position, to_position);
384 } 350 }
385 351
386 352
387 Script.prototype.sourceLine = function (opt_line) { 353 Script.prototype.sourceLine = function (opt_line) {
388 // Default is the first line in the script. Lines in the script are relative 354 // Default is the first line in the script. Lines in the script are relative
389 // to the offset within the resource. 355 // to the offset within the resource.
390 var line = 0; 356 var line = 0;
391 if (!IS_UNDEFINED(opt_line)) { 357 if (!IS_UNDEFINED(opt_line)) {
392 line = opt_line - this.line_offset; 358 line = opt_line - this.line_offset;
393 } 359 }
394 360
395 // Check parameter. 361 // Check parameter.
396 if (line < 0 || this.lineCount() <= line) { 362 if (line < 0 || this.lineCount() <= line) {
397 return null; 363 return null;
398 } 364 }
399 365
400 // Return the source line. 366 // Return the source line.
401 var start = line == 0 ? 0 : this.lineEnds_[line - 1] + 1; 367 var start = line == 0 ? 0 : this.line_ends[line - 1] + 1;
402 var end = this.lineEnds_[line]; 368 var end = this.line_ends[line];
403 return this.source.substring(start, end); 369 return this.source.substring(start, end);
404 } 370 }
405 371
406 372
407 /** 373 /**
408 * Returns the number of source lines. 374 * Returns the number of source lines.
409 * @return {number} 375 * @return {number}
410 * Number of source lines. 376 * Number of source lines.
411 */ 377 */
412 Script.prototype.lineCount = function() { 378 Script.prototype.lineCount = function() {
413 // Make soure source info has been initialized. 379 // Return number of source lines.
414 this.initSourceInfo_(); 380 return this.line_ends.length;
415
416 // Return number of source lines.
417 return this.lineEnds_.length;
418 }; 381 };
419 382
420 383
421 /** 384 /**
422 * Class for source location. A source location is a position within some 385 * Class for source location. A source location is a position within some
423 * source with the following properties: 386 * source with the following properties:
424 * script : script object for the source 387 * script : script object for the source
425 * line : source line number 388 * line : source line number
426 * column : source column within the line 389 * column : source column within the line
427 * position : position within the source 390 * position : position within the source
428 * start : position of start of source context (inclusive) 391 * start : position of start of source context (inclusive)
429 * end : position of end of source context (not inclusive) 392 * end : position of end of source context (not inclusive)
430 * Source text for the source context is the character interval [start, end[. In 393 * Source text for the source context is the character interval [start, end[. In
431 * most cases end will point to a newline character. It might point just past 394 * most cases end will point to a newline character. It might point just past
432 * the final position of the source if the last source line does not end with a 395 * the final position of the source if the last source line does not end with a
433 * newline character. 396 * newline character.
434 * @param {Script} script The Script object for which this is a location 397 * @param {Script} script The Script object for which this is a location
435 * @param {number} position Source position for the location 398 * @param {number} position Source position for the location
436 * @param {number} line The line number for the location 399 * @param {number} line The line number for the location
437 * @param {number} column The column within the line for the location 400 * @param {number} column The column within the line for the location
438 * @param {number} start Source position for start of source context 401 * @param {number} start Source position for start of source context
439 * @param {number} end Source position for end of source context 402 * @param {number} end Source position for end of source context
440 * @constructor 403 * @constructor
441 */ 404 */
442 function SourceLocation(script, position, line, column, start, end) { 405 function SourceLocation(script, position, line, column, start, end) {
443 this.script = script; 406 this.script = script;
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
670 return this.name + ": " + FormatMessage({ type: type, args: this.arguments } ); 633 return this.name + ": " + FormatMessage({ type: type, args: this.arguments } );
671 } 634 }
672 var message = this.message; 635 var message = this.message;
673 return this.name + (message ? (": " + message) : ""); 636 return this.name + (message ? (": " + message) : "");
674 }, DONT_ENUM); 637 }, DONT_ENUM);
675 638
676 639
677 // Boilerplate for exceptions for stack overflows. Used from 640 // Boilerplate for exceptions for stack overflows. Used from
678 // Top::StackOverflow(). 641 // Top::StackOverflow().
679 const kStackOverflowBoilerplate = MakeRangeError('stack_overflow', []); 642 const kStackOverflowBoilerplate = MakeRangeError('stack_overflow', []);
OLDNEW
« no previous file with comments | « src/compiler.cc ('k') | src/objects.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698