OffsetToLocation.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. var adoptBuffer = require('./adopt-buffer');
  2. var firstCharOffset = require('../tokenizer/utils').firstCharOffset;
  3. var N = 10;
  4. var F = 12;
  5. var R = 13;
  6. function computeLinesAndColumns(host, startOffset, source) {
  7. var sourceLength = source.length;
  8. var lines = adoptBuffer(host.lines, sourceLength); // +1
  9. var line = host.startLine;
  10. var columns = adoptBuffer(host.columns, sourceLength);
  11. var column = host.startColumn;
  12. for (var i = startOffset; i < sourceLength; i++) { // -1
  13. var code = source.charCodeAt(i);
  14. lines[i] = line;
  15. columns[i] = column++;
  16. if (code === N || code === R || code === F) {
  17. if (code === R && i + 1 < sourceLength && source.charCodeAt(i + 1) === N) {
  18. i++;
  19. lines[i] = line;
  20. columns[i] = column;
  21. }
  22. line++;
  23. column = 1;
  24. }
  25. }
  26. lines[i] = line;
  27. columns[i] = column;
  28. host.lines = lines;
  29. host.columns = columns;
  30. }
  31. var OffsetToLocation = function() {
  32. this.lines = null;
  33. this.columns = null;
  34. this.linesAndColumnsComputed = false;
  35. };
  36. OffsetToLocation.prototype = {
  37. setSource: function(source, startOffset, startLine, startColumn) {
  38. this.source = source;
  39. this.startOffset = typeof startOffset === 'undefined' ? 0 : startOffset;
  40. this.startLine = typeof startLine === 'undefined' ? 1 : startLine;
  41. this.startColumn = typeof startColumn === 'undefined' ? 1 : startColumn;
  42. this.linesAndColumnsComputed = false;
  43. },
  44. ensureLinesAndColumnsComputed: function() {
  45. if (!this.linesAndColumnsComputed) {
  46. computeLinesAndColumns(this, firstCharOffset(this.source), this.source);
  47. this.linesAndColumnsComputed = true;
  48. }
  49. },
  50. getLocation: function(offset, filename) {
  51. this.ensureLinesAndColumnsComputed();
  52. return {
  53. source: filename,
  54. offset: this.startOffset + offset,
  55. line: this.lines[offset],
  56. column: this.columns[offset]
  57. };
  58. },
  59. getLocationRange: function(start, end, filename) {
  60. this.ensureLinesAndColumnsComputed();
  61. return {
  62. source: filename,
  63. start: {
  64. offset: this.startOffset + start,
  65. line: this.lines[start],
  66. column: this.columns[start]
  67. },
  68. end: {
  69. offset: this.startOffset + end,
  70. line: this.lines[end],
  71. column: this.columns[end]
  72. }
  73. };
  74. }
  75. };
  76. module.exports = OffsetToLocation;