attach.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. "use strict";
  2. exports.__esModule = true;
  3. var define_parents_1 = require("./utils/define-parents");
  4. var get_point_text_1 = require("./utils/get-point-text");
  5. function attachComments(root) {
  6. define_parents_1.defineParents(root);
  7. var nodeTable = createNodeTable(root);
  8. var restDocuments = root.children.slice();
  9. root.comments
  10. .sort(function (a, b) { return a.position.start.offset - b.position.end.offset; })
  11. .filter(function (comment) { return !comment._parent; })
  12. .forEach(function (comment) {
  13. while (restDocuments.length > 1 &&
  14. comment.position.start.line > restDocuments[0].position.end.line) {
  15. restDocuments.shift();
  16. }
  17. attachComment(comment, nodeTable, restDocuments[0]);
  18. });
  19. }
  20. exports.attachComments = attachComments;
  21. function createNodeTable(root) {
  22. var nodeTable = Array.from(new Array(root.position.end.line), function () { return ({}); });
  23. for (var _i = 0, _a = root.comments; _i < _a.length; _i++) {
  24. var comment = _a[_i];
  25. nodeTable[comment.position.start.line - 1].comment = comment;
  26. }
  27. initNodeTable(nodeTable, root);
  28. return nodeTable;
  29. }
  30. function initNodeTable(nodeTable, node) {
  31. // empty mappingKey/mappingValue
  32. if (node.position.start.offset === node.position.end.offset) {
  33. return;
  34. }
  35. if ("leadingComments" in node) {
  36. var start = node.position.start;
  37. var leadingAttachableNode = nodeTable[start.line - 1].leadingAttachableNode;
  38. if (!leadingAttachableNode ||
  39. start.column < leadingAttachableNode.position.start.column) {
  40. nodeTable[start.line - 1].leadingAttachableNode = node;
  41. }
  42. }
  43. if ("trailingComment" in node &&
  44. node.position.end.column > 1 &&
  45. node.type !== "document" &&
  46. node.type !== "documentHead") {
  47. var end = node.position.end;
  48. var trailingAttachableNode = nodeTable[end.line - 1].trailingAttachableNode;
  49. if (!trailingAttachableNode ||
  50. end.column >= trailingAttachableNode.position.end.column) {
  51. nodeTable[end.line - 1].trailingAttachableNode = node;
  52. }
  53. }
  54. if (node.type !== "root" &&
  55. node.type !== "document" &&
  56. node.type !== "documentHead" &&
  57. node.type !== "documentBody") {
  58. var _a = node.position, start = _a.start, end = _a.end;
  59. var lines = [end.line].concat(start.line === end.line ? [] : start.line);
  60. for (var _i = 0, lines_1 = lines; _i < lines_1.length; _i++) {
  61. var line = lines_1[_i];
  62. var currentEndNode = nodeTable[line - 1].trailingNode;
  63. if (!currentEndNode || end.column >= currentEndNode.position.end.column) {
  64. nodeTable[line - 1].trailingNode = node;
  65. }
  66. }
  67. }
  68. if ("children" in node) {
  69. node.children.forEach(function (child) {
  70. initNodeTable(nodeTable, child);
  71. });
  72. }
  73. }
  74. function attachComment(comment, nodeTable, document) {
  75. var commentLine = comment.position.start.line;
  76. var trailingAttachableNode = nodeTable[commentLine - 1].trailingAttachableNode;
  77. if (trailingAttachableNode) {
  78. // istanbul ignore next
  79. if (trailingAttachableNode.trailingComment) {
  80. throw new Error("Unexpected multiple trailing comment at " + get_point_text_1.getPointText(comment.position.start));
  81. }
  82. define_parents_1.defineParents(comment, trailingAttachableNode);
  83. trailingAttachableNode.trailingComment = comment;
  84. return;
  85. }
  86. for (var line = commentLine; line >= document.position.start.line; line--) {
  87. var trailingNode = nodeTable[line - 1].trailingNode;
  88. var currentNode = void 0;
  89. if (!trailingNode) {
  90. /**
  91. * a:
  92. * b:
  93. * #b
  94. * #a
  95. *
  96. * a:
  97. * b:
  98. * #a
  99. * #a
  100. */
  101. if (line !== commentLine && nodeTable[line - 1].comment) {
  102. currentNode = nodeTable[line - 1].comment._parent;
  103. }
  104. else {
  105. continue;
  106. }
  107. }
  108. else {
  109. currentNode = trailingNode;
  110. }
  111. if (currentNode.type === "sequence" || currentNode.type === "mapping") {
  112. currentNode = currentNode.children[0];
  113. }
  114. if (currentNode.type === "mappingItem") {
  115. var _a = currentNode.children, mappingKey = _a[0], mappingValue = _a[1];
  116. currentNode = isExplicitMappingKey(mappingKey)
  117. ? mappingKey
  118. : mappingValue;
  119. }
  120. while (true) {
  121. if (shouldOwnEndComment(currentNode, comment)) {
  122. define_parents_1.defineParents(comment, currentNode);
  123. currentNode.endComments.push(comment);
  124. return;
  125. }
  126. if (!currentNode._parent) {
  127. break;
  128. }
  129. currentNode = currentNode._parent;
  130. }
  131. break;
  132. }
  133. for (var line = commentLine + 1; line <= document.position.end.line; line++) {
  134. var leadingAttachableNode = nodeTable[line - 1].leadingAttachableNode;
  135. if (leadingAttachableNode) {
  136. define_parents_1.defineParents(comment, leadingAttachableNode);
  137. leadingAttachableNode.leadingComments.push(comment);
  138. return;
  139. }
  140. }
  141. var documentBody = document.children[1];
  142. define_parents_1.defineParents(comment, documentBody);
  143. documentBody.endComments.push(comment);
  144. }
  145. function shouldOwnEndComment(node, comment) {
  146. if (node.position.start.offset < comment.position.start.offset &&
  147. node.position.end.offset > comment.position.end.offset) {
  148. switch (node.type) {
  149. case "flowMapping":
  150. case "flowSequence":
  151. return (node.children.length === 0 ||
  152. comment.position.start.line >
  153. node.children[node.children.length - 1].position.end.line);
  154. }
  155. }
  156. if (comment.position.end.offset < node.position.end.offset) {
  157. return false;
  158. }
  159. switch (node.type) {
  160. case "sequenceItem":
  161. return comment.position.start.column > node.position.start.column;
  162. case "mappingKey":
  163. case "mappingValue":
  164. return (comment.position.start.column > node._parent.position.start.column &&
  165. (node.children.length === 0 ||
  166. (node.children.length === 1 &&
  167. node.children[0].type !== "blockFolded" &&
  168. node.children[0].type !== "blockLiteral")) &&
  169. (node.type === "mappingValue" || isExplicitMappingKey(node)));
  170. default:
  171. return false;
  172. }
  173. }
  174. function isExplicitMappingKey(node) {
  175. return (node.position.start !== node.position.end &&
  176. (node.children.length === 0 ||
  177. node.position.start.offset !== node.children[0].position.start.offset));
  178. }