OffsetToLocation.js 2.6 KB

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