diffLines.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', {
  3. value: true
  4. });
  5. exports.printDiffLines =
  6. exports.diffLinesUnified2 =
  7. exports.diffLinesUnified =
  8. exports.diffLinesRaw =
  9. void 0;
  10. var _diffSequences = _interopRequireDefault(require('diff-sequences'));
  11. var _cleanupSemantic = require('./cleanupSemantic');
  12. var _joinAlignedDiffs = require('./joinAlignedDiffs');
  13. var _normalizeDiffOptions = require('./normalizeDiffOptions');
  14. function _interopRequireDefault(obj) {
  15. return obj && obj.__esModule ? obj : {default: obj};
  16. }
  17. /**
  18. * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
  19. *
  20. * This source code is licensed under the MIT license found in the
  21. * LICENSE file in the root directory of this source tree.
  22. */
  23. const isEmptyString = lines => lines.length === 1 && lines[0].length === 0;
  24. const countChanges = diffs => {
  25. let a = 0;
  26. let b = 0;
  27. diffs.forEach(diff => {
  28. switch (diff[0]) {
  29. case _cleanupSemantic.DIFF_DELETE:
  30. a += 1;
  31. break;
  32. case _cleanupSemantic.DIFF_INSERT:
  33. b += 1;
  34. break;
  35. }
  36. });
  37. return {
  38. a,
  39. b
  40. };
  41. };
  42. const printAnnotation = (
  43. {
  44. aAnnotation,
  45. aColor,
  46. aIndicator,
  47. bAnnotation,
  48. bColor,
  49. bIndicator,
  50. includeChangeCounts,
  51. omitAnnotationLines
  52. },
  53. changeCounts
  54. ) => {
  55. if (omitAnnotationLines) {
  56. return '';
  57. }
  58. let aRest = '';
  59. let bRest = '';
  60. if (includeChangeCounts) {
  61. const aCount = String(changeCounts.a);
  62. const bCount = String(changeCounts.b); // Padding right aligns the ends of the annotations.
  63. const baAnnotationLengthDiff = bAnnotation.length - aAnnotation.length;
  64. const aAnnotationPadding = ' '.repeat(Math.max(0, baAnnotationLengthDiff));
  65. const bAnnotationPadding = ' '.repeat(Math.max(0, -baAnnotationLengthDiff)); // Padding left aligns the ends of the counts.
  66. const baCountLengthDiff = bCount.length - aCount.length;
  67. const aCountPadding = ' '.repeat(Math.max(0, baCountLengthDiff));
  68. const bCountPadding = ' '.repeat(Math.max(0, -baCountLengthDiff));
  69. aRest =
  70. aAnnotationPadding + ' ' + aIndicator + ' ' + aCountPadding + aCount;
  71. bRest =
  72. bAnnotationPadding + ' ' + bIndicator + ' ' + bCountPadding + bCount;
  73. }
  74. return (
  75. aColor(aIndicator + ' ' + aAnnotation + aRest) +
  76. '\n' +
  77. bColor(bIndicator + ' ' + bAnnotation + bRest) +
  78. '\n\n'
  79. );
  80. };
  81. const printDiffLines = (diffs, options) =>
  82. printAnnotation(options, countChanges(diffs)) +
  83. (options.expand
  84. ? (0, _joinAlignedDiffs.joinAlignedDiffsExpand)(diffs, options)
  85. : (0, _joinAlignedDiffs.joinAlignedDiffsNoExpand)(diffs, options)); // Compare two arrays of strings line-by-line. Format as comparison lines.
  86. exports.printDiffLines = printDiffLines;
  87. const diffLinesUnified = (aLines, bLines, options) =>
  88. printDiffLines(
  89. diffLinesRaw(
  90. isEmptyString(aLines) ? [] : aLines,
  91. isEmptyString(bLines) ? [] : bLines
  92. ),
  93. (0, _normalizeDiffOptions.normalizeDiffOptions)(options)
  94. ); // Given two pairs of arrays of strings:
  95. // Compare the pair of comparison arrays line-by-line.
  96. // Format the corresponding lines in the pair of displayable arrays.
  97. exports.diffLinesUnified = diffLinesUnified;
  98. const diffLinesUnified2 = (
  99. aLinesDisplay,
  100. bLinesDisplay,
  101. aLinesCompare,
  102. bLinesCompare,
  103. options
  104. ) => {
  105. if (isEmptyString(aLinesDisplay) && isEmptyString(aLinesCompare)) {
  106. aLinesDisplay = [];
  107. aLinesCompare = [];
  108. }
  109. if (isEmptyString(bLinesDisplay) && isEmptyString(bLinesCompare)) {
  110. bLinesDisplay = [];
  111. bLinesCompare = [];
  112. }
  113. if (
  114. aLinesDisplay.length !== aLinesCompare.length ||
  115. bLinesDisplay.length !== bLinesCompare.length
  116. ) {
  117. // Fall back to diff of display lines.
  118. return diffLinesUnified(aLinesDisplay, bLinesDisplay, options);
  119. }
  120. const diffs = diffLinesRaw(aLinesCompare, bLinesCompare); // Replace comparison lines with displayable lines.
  121. let aIndex = 0;
  122. let bIndex = 0;
  123. diffs.forEach(diff => {
  124. switch (diff[0]) {
  125. case _cleanupSemantic.DIFF_DELETE:
  126. diff[1] = aLinesDisplay[aIndex];
  127. aIndex += 1;
  128. break;
  129. case _cleanupSemantic.DIFF_INSERT:
  130. diff[1] = bLinesDisplay[bIndex];
  131. bIndex += 1;
  132. break;
  133. default:
  134. diff[1] = bLinesDisplay[bIndex];
  135. aIndex += 1;
  136. bIndex += 1;
  137. }
  138. });
  139. return printDiffLines(
  140. diffs,
  141. (0, _normalizeDiffOptions.normalizeDiffOptions)(options)
  142. );
  143. }; // Compare two arrays of strings line-by-line.
  144. exports.diffLinesUnified2 = diffLinesUnified2;
  145. const diffLinesRaw = (aLines, bLines) => {
  146. const aLength = aLines.length;
  147. const bLength = bLines.length;
  148. const isCommon = (aIndex, bIndex) => aLines[aIndex] === bLines[bIndex];
  149. const diffs = [];
  150. let aIndex = 0;
  151. let bIndex = 0;
  152. const foundSubsequence = (nCommon, aCommon, bCommon) => {
  153. for (; aIndex !== aCommon; aIndex += 1) {
  154. diffs.push(
  155. new _cleanupSemantic.Diff(_cleanupSemantic.DIFF_DELETE, aLines[aIndex])
  156. );
  157. }
  158. for (; bIndex !== bCommon; bIndex += 1) {
  159. diffs.push(
  160. new _cleanupSemantic.Diff(_cleanupSemantic.DIFF_INSERT, bLines[bIndex])
  161. );
  162. }
  163. for (; nCommon !== 0; nCommon -= 1, aIndex += 1, bIndex += 1) {
  164. diffs.push(
  165. new _cleanupSemantic.Diff(_cleanupSemantic.DIFF_EQUAL, bLines[bIndex])
  166. );
  167. }
  168. };
  169. (0, _diffSequences.default)(aLength, bLength, isCommon, foundSubsequence); // After the last common subsequence, push remaining change items.
  170. for (; aIndex !== aLength; aIndex += 1) {
  171. diffs.push(
  172. new _cleanupSemantic.Diff(_cleanupSemantic.DIFF_DELETE, aLines[aIndex])
  173. );
  174. }
  175. for (; bIndex !== bLength; bIndex += 1) {
  176. diffs.push(
  177. new _cleanupSemantic.Diff(_cleanupSemantic.DIFF_INSERT, bLines[bIndex])
  178. );
  179. }
  180. return diffs;
  181. };
  182. exports.diffLinesRaw = diffLinesRaw;