mapping.js 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. var tslib_1 = require("tslib");
  4. var assert_1 = tslib_1.__importDefault(require("assert"));
  5. var util_1 = require("./util");
  6. var Mapping = /** @class */ (function () {
  7. function Mapping(sourceLines, sourceLoc, targetLoc) {
  8. if (targetLoc === void 0) { targetLoc = sourceLoc; }
  9. this.sourceLines = sourceLines;
  10. this.sourceLoc = sourceLoc;
  11. this.targetLoc = targetLoc;
  12. }
  13. Mapping.prototype.slice = function (lines, start, end) {
  14. if (end === void 0) { end = lines.lastPos(); }
  15. var sourceLines = this.sourceLines;
  16. var sourceLoc = this.sourceLoc;
  17. var targetLoc = this.targetLoc;
  18. function skip(name) {
  19. var sourceFromPos = sourceLoc[name];
  20. var targetFromPos = targetLoc[name];
  21. var targetToPos = start;
  22. if (name === "end") {
  23. targetToPos = end;
  24. }
  25. else {
  26. assert_1.default.strictEqual(name, "start");
  27. }
  28. return skipChars(sourceLines, sourceFromPos, lines, targetFromPos, targetToPos);
  29. }
  30. if ((0, util_1.comparePos)(start, targetLoc.start) <= 0) {
  31. if ((0, util_1.comparePos)(targetLoc.end, end) <= 0) {
  32. targetLoc = {
  33. start: subtractPos(targetLoc.start, start.line, start.column),
  34. end: subtractPos(targetLoc.end, start.line, start.column),
  35. };
  36. // The sourceLoc can stay the same because the contents of the
  37. // targetLoc have not changed.
  38. }
  39. else if ((0, util_1.comparePos)(end, targetLoc.start) <= 0) {
  40. return null;
  41. }
  42. else {
  43. sourceLoc = {
  44. start: sourceLoc.start,
  45. end: skip("end"),
  46. };
  47. targetLoc = {
  48. start: subtractPos(targetLoc.start, start.line, start.column),
  49. end: subtractPos(end, start.line, start.column),
  50. };
  51. }
  52. }
  53. else {
  54. if ((0, util_1.comparePos)(targetLoc.end, start) <= 0) {
  55. return null;
  56. }
  57. if ((0, util_1.comparePos)(targetLoc.end, end) <= 0) {
  58. sourceLoc = {
  59. start: skip("start"),
  60. end: sourceLoc.end,
  61. };
  62. targetLoc = {
  63. // Same as subtractPos(start, start.line, start.column):
  64. start: { line: 1, column: 0 },
  65. end: subtractPos(targetLoc.end, start.line, start.column),
  66. };
  67. }
  68. else {
  69. sourceLoc = {
  70. start: skip("start"),
  71. end: skip("end"),
  72. };
  73. targetLoc = {
  74. // Same as subtractPos(start, start.line, start.column):
  75. start: { line: 1, column: 0 },
  76. end: subtractPos(end, start.line, start.column),
  77. };
  78. }
  79. }
  80. return new Mapping(this.sourceLines, sourceLoc, targetLoc);
  81. };
  82. Mapping.prototype.add = function (line, column) {
  83. return new Mapping(this.sourceLines, this.sourceLoc, {
  84. start: addPos(this.targetLoc.start, line, column),
  85. end: addPos(this.targetLoc.end, line, column),
  86. });
  87. };
  88. Mapping.prototype.subtract = function (line, column) {
  89. return new Mapping(this.sourceLines, this.sourceLoc, {
  90. start: subtractPos(this.targetLoc.start, line, column),
  91. end: subtractPos(this.targetLoc.end, line, column),
  92. });
  93. };
  94. Mapping.prototype.indent = function (by, skipFirstLine, noNegativeColumns) {
  95. if (skipFirstLine === void 0) { skipFirstLine = false; }
  96. if (noNegativeColumns === void 0) { noNegativeColumns = false; }
  97. if (by === 0) {
  98. return this;
  99. }
  100. var targetLoc = this.targetLoc;
  101. var startLine = targetLoc.start.line;
  102. var endLine = targetLoc.end.line;
  103. if (skipFirstLine && startLine === 1 && endLine === 1) {
  104. return this;
  105. }
  106. targetLoc = {
  107. start: targetLoc.start,
  108. end: targetLoc.end,
  109. };
  110. if (!skipFirstLine || startLine > 1) {
  111. var startColumn = targetLoc.start.column + by;
  112. targetLoc.start = {
  113. line: startLine,
  114. column: noNegativeColumns ? Math.max(0, startColumn) : startColumn,
  115. };
  116. }
  117. if (!skipFirstLine || endLine > 1) {
  118. var endColumn = targetLoc.end.column + by;
  119. targetLoc.end = {
  120. line: endLine,
  121. column: noNegativeColumns ? Math.max(0, endColumn) : endColumn,
  122. };
  123. }
  124. return new Mapping(this.sourceLines, this.sourceLoc, targetLoc);
  125. };
  126. return Mapping;
  127. }());
  128. exports.default = Mapping;
  129. function addPos(toPos, line, column) {
  130. return {
  131. line: toPos.line + line - 1,
  132. column: toPos.line === 1 ? toPos.column + column : toPos.column,
  133. };
  134. }
  135. function subtractPos(fromPos, line, column) {
  136. return {
  137. line: fromPos.line - line + 1,
  138. column: fromPos.line === line ? fromPos.column - column : fromPos.column,
  139. };
  140. }
  141. function skipChars(sourceLines, sourceFromPos, targetLines, targetFromPos, targetToPos) {
  142. var targetComparison = (0, util_1.comparePos)(targetFromPos, targetToPos);
  143. if (targetComparison === 0) {
  144. // Trivial case: no characters to skip.
  145. return sourceFromPos;
  146. }
  147. var sourceCursor, targetCursor;
  148. if (targetComparison < 0) {
  149. // Skipping forward.
  150. sourceCursor =
  151. sourceLines.skipSpaces(sourceFromPos) || sourceLines.lastPos();
  152. targetCursor =
  153. targetLines.skipSpaces(targetFromPos) || targetLines.lastPos();
  154. var lineDiff = targetToPos.line - targetCursor.line;
  155. sourceCursor.line += lineDiff;
  156. targetCursor.line += lineDiff;
  157. if (lineDiff > 0) {
  158. // If jumping to later lines, reset columns to the beginnings
  159. // of those lines.
  160. sourceCursor.column = 0;
  161. targetCursor.column = 0;
  162. }
  163. else {
  164. assert_1.default.strictEqual(lineDiff, 0);
  165. }
  166. while ((0, util_1.comparePos)(targetCursor, targetToPos) < 0 &&
  167. targetLines.nextPos(targetCursor, true)) {
  168. assert_1.default.ok(sourceLines.nextPos(sourceCursor, true));
  169. assert_1.default.strictEqual(sourceLines.charAt(sourceCursor), targetLines.charAt(targetCursor));
  170. }
  171. }
  172. else {
  173. // Skipping backward.
  174. sourceCursor =
  175. sourceLines.skipSpaces(sourceFromPos, true) || sourceLines.firstPos();
  176. targetCursor =
  177. targetLines.skipSpaces(targetFromPos, true) || targetLines.firstPos();
  178. var lineDiff = targetToPos.line - targetCursor.line;
  179. sourceCursor.line += lineDiff;
  180. targetCursor.line += lineDiff;
  181. if (lineDiff < 0) {
  182. // If jumping to earlier lines, reset columns to the ends of
  183. // those lines.
  184. sourceCursor.column = sourceLines.getLineLength(sourceCursor.line);
  185. targetCursor.column = targetLines.getLineLength(targetCursor.line);
  186. }
  187. else {
  188. assert_1.default.strictEqual(lineDiff, 0);
  189. }
  190. while ((0, util_1.comparePos)(targetToPos, targetCursor) < 0 &&
  191. targetLines.prevPos(targetCursor, true)) {
  192. assert_1.default.ok(sourceLines.prevPos(sourceCursor, true));
  193. assert_1.default.strictEqual(sourceLines.charAt(sourceCursor), targetLines.charAt(targetCursor));
  194. }
  195. }
  196. return sourceCursor;
  197. }