OffsetToLocation.cjs 2.5 KB

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