Dashboard sipadu mbip
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

parseMap.js 10.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. "use strict";
  2. var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
  3. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  4. Object.defineProperty(exports, "__esModule", {
  5. value: true
  6. });
  7. exports.default = parseMap;
  8. var _constants = require("../constants");
  9. var _PlainValue = _interopRequireDefault(require("../cst/PlainValue"));
  10. var _errors = require("../errors");
  11. var _Map = _interopRequireDefault(require("./Map"));
  12. var _Merge = _interopRequireWildcard(require("./Merge"));
  13. var _Pair = _interopRequireDefault(require("./Pair"));
  14. var _parseUtils = require("./parseUtils");
  15. var _Alias = _interopRequireDefault(require("./Alias"));
  16. var _Collection = _interopRequireDefault(require("./Collection"));
  17. function parseMap(doc, cst) {
  18. if (cst.type !== _constants.Type.MAP && cst.type !== _constants.Type.FLOW_MAP) {
  19. var msg = "A ".concat(cst.type, " node cannot be resolved as a mapping");
  20. doc.errors.push(new _errors.YAMLSyntaxError(cst, msg));
  21. return null;
  22. }
  23. var _ref = cst.type === _constants.Type.FLOW_MAP ? resolveFlowMapItems(doc, cst) : resolveBlockMapItems(doc, cst),
  24. comments = _ref.comments,
  25. items = _ref.items;
  26. var map = new _Map.default();
  27. map.items = items;
  28. (0, _parseUtils.resolveComments)(map, comments);
  29. var hasCollectionKey = false;
  30. for (var i = 0; i < items.length; ++i) {
  31. var iKey = items[i].key;
  32. if (iKey instanceof _Collection.default) hasCollectionKey = true;
  33. if (doc.schema.merge && iKey && iKey.value === _Merge.MERGE_KEY) {
  34. items[i] = new _Merge.default(items[i]);
  35. var sources = items[i].value.items;
  36. var error = null;
  37. sources.some(function (node) {
  38. if (node instanceof _Alias.default) {
  39. // During parsing, alias sources are CST nodes; to account for
  40. // circular references their resolved values can't be used here.
  41. var type = node.source.type;
  42. if (type === _constants.Type.MAP || type === _constants.Type.FLOW_MAP) return false;
  43. return error = 'Merge nodes aliases can only point to maps';
  44. }
  45. return error = 'Merge nodes can only have Alias nodes as values';
  46. });
  47. if (error) doc.errors.push(new _errors.YAMLSemanticError(cst, error));
  48. } else {
  49. for (var j = i + 1; j < items.length; ++j) {
  50. var jKey = items[j].key;
  51. if (iKey === jKey || iKey && jKey && Object.prototype.hasOwnProperty.call(iKey, 'value') && iKey.value === jKey.value) {
  52. var _msg = "Map keys must be unique; \"".concat(iKey, "\" is repeated");
  53. doc.errors.push(new _errors.YAMLSemanticError(cst, _msg));
  54. break;
  55. }
  56. }
  57. }
  58. }
  59. if (hasCollectionKey && !doc.options.mapAsMap) {
  60. var warn = 'Keys with collection values will be stringified as YAML due to JS Object restrictions. Use mapAsMap: true to avoid this.';
  61. doc.warnings.push(new _errors.YAMLWarning(cst, warn));
  62. }
  63. cst.resolved = map;
  64. return map;
  65. }
  66. var valueHasPairComment = function valueHasPairComment(_ref2) {
  67. var _ref2$context = _ref2.context,
  68. lineStart = _ref2$context.lineStart,
  69. node = _ref2$context.node,
  70. src = _ref2$context.src,
  71. props = _ref2.props;
  72. if (props.length === 0) return false;
  73. var start = props[0].start;
  74. if (node && start > node.valueRange.start) return false;
  75. if (src[start] !== _constants.Char.COMMENT) return false;
  76. for (var i = lineStart; i < start; ++i) {
  77. if (src[i] === '\n') return false;
  78. }
  79. return true;
  80. };
  81. function resolvePairComment(item, pair) {
  82. if (!valueHasPairComment(item)) return;
  83. var comment = item.getPropValue(0, _constants.Char.COMMENT, true);
  84. var found = false;
  85. var cb = pair.value.commentBefore;
  86. if (cb && cb.startsWith(comment)) {
  87. pair.value.commentBefore = cb.substr(comment.length + 1);
  88. found = true;
  89. } else {
  90. var cc = pair.value.comment;
  91. if (!item.node && cc && cc.startsWith(comment)) {
  92. pair.value.comment = cc.substr(comment.length + 1);
  93. found = true;
  94. }
  95. }
  96. if (found) pair.comment = comment;
  97. }
  98. function resolveBlockMapItems(doc, cst) {
  99. var comments = [];
  100. var items = [];
  101. var key = undefined;
  102. var keyStart = null;
  103. for (var i = 0; i < cst.items.length; ++i) {
  104. var item = cst.items[i];
  105. switch (item.type) {
  106. case _constants.Type.BLANK_LINE:
  107. comments.push({
  108. afterKey: !!key,
  109. before: items.length
  110. });
  111. break;
  112. case _constants.Type.COMMENT:
  113. comments.push({
  114. afterKey: !!key,
  115. before: items.length,
  116. comment: item.comment
  117. });
  118. break;
  119. case _constants.Type.MAP_KEY:
  120. if (key !== undefined) items.push(new _Pair.default(key));
  121. if (item.error) doc.errors.push(item.error);
  122. key = doc.resolveNode(item.node);
  123. keyStart = null;
  124. break;
  125. case _constants.Type.MAP_VALUE:
  126. {
  127. if (key === undefined) key = null;
  128. if (item.error) doc.errors.push(item.error);
  129. if (!item.context.atLineStart && item.node && item.node.type === _constants.Type.MAP && !item.node.context.atLineStart) {
  130. var msg = 'Nested mappings are not allowed in compact mappings';
  131. doc.errors.push(new _errors.YAMLSemanticError(item.node, msg));
  132. }
  133. var valueNode = item.node;
  134. if (!valueNode && item.props.length > 0) {
  135. // Comments on an empty mapping value need to be preserved, so we
  136. // need to construct a minimal empty node here to use instead of the
  137. // missing `item.node`. -- eemeli/yaml#19
  138. valueNode = new _PlainValue.default(_constants.Type.PLAIN, []);
  139. valueNode.context = {
  140. parent: item,
  141. src: item.context.src
  142. };
  143. var pos = item.range.start + 1;
  144. valueNode.range = {
  145. start: pos,
  146. end: pos
  147. };
  148. valueNode.valueRange = {
  149. start: pos,
  150. end: pos
  151. };
  152. if (typeof item.range.origStart === 'number') {
  153. var origPos = item.range.origStart + 1;
  154. valueNode.range.origStart = valueNode.range.origEnd = origPos;
  155. valueNode.valueRange.origStart = valueNode.valueRange.origEnd = origPos;
  156. }
  157. }
  158. var pair = new _Pair.default(key, doc.resolveNode(valueNode));
  159. resolvePairComment(item, pair);
  160. items.push(pair);
  161. (0, _parseUtils.checkKeyLength)(doc.errors, cst, i, key, keyStart);
  162. key = undefined;
  163. keyStart = null;
  164. }
  165. break;
  166. default:
  167. if (key !== undefined) items.push(new _Pair.default(key));
  168. key = doc.resolveNode(item);
  169. keyStart = item.range.start;
  170. if (item.error) doc.errors.push(item.error);
  171. next: for (var j = i + 1;; ++j) {
  172. var nextItem = cst.items[j];
  173. switch (nextItem && nextItem.type) {
  174. case _constants.Type.BLANK_LINE:
  175. case _constants.Type.COMMENT:
  176. continue next;
  177. case _constants.Type.MAP_VALUE:
  178. break next;
  179. default:
  180. doc.errors.push(new _errors.YAMLSemanticError(item, 'Implicit map keys need to be followed by map values'));
  181. break next;
  182. }
  183. }
  184. if (item.valueRangeContainsNewline) {
  185. var _msg2 = 'Implicit map keys need to be on a single line';
  186. doc.errors.push(new _errors.YAMLSemanticError(item, _msg2));
  187. }
  188. }
  189. }
  190. if (key !== undefined) items.push(new _Pair.default(key));
  191. return {
  192. comments: comments,
  193. items: items
  194. };
  195. }
  196. function resolveFlowMapItems(doc, cst) {
  197. var comments = [];
  198. var items = [];
  199. var key = undefined;
  200. var keyStart = null;
  201. var explicitKey = false;
  202. var next = '{';
  203. for (var i = 0; i < cst.items.length; ++i) {
  204. (0, _parseUtils.checkKeyLength)(doc.errors, cst, i, key, keyStart);
  205. var item = cst.items[i];
  206. if (typeof item.char === 'string') {
  207. var char = item.char,
  208. offset = item.offset;
  209. if (char === '?' && key === undefined && !explicitKey) {
  210. explicitKey = true;
  211. next = ':';
  212. continue;
  213. }
  214. if (char === ':') {
  215. if (key === undefined) key = null;
  216. if (next === ':') {
  217. next = ',';
  218. continue;
  219. }
  220. } else {
  221. if (explicitKey) {
  222. if (key === undefined && char !== ',') key = null;
  223. explicitKey = false;
  224. }
  225. if (key !== undefined) {
  226. items.push(new _Pair.default(key));
  227. key = undefined;
  228. keyStart = null;
  229. if (char === ',') {
  230. next = ':';
  231. continue;
  232. }
  233. }
  234. }
  235. if (char === '}') {
  236. if (i === cst.items.length - 1) continue;
  237. } else if (char === next) {
  238. next = ':';
  239. continue;
  240. }
  241. var msg = "Flow map contains an unexpected ".concat(char);
  242. var err = new _errors.YAMLSyntaxError(cst, msg);
  243. err.offset = offset;
  244. doc.errors.push(err);
  245. } else if (item.type === _constants.Type.BLANK_LINE) {
  246. comments.push({
  247. afterKey: !!key,
  248. before: items.length
  249. });
  250. } else if (item.type === _constants.Type.COMMENT) {
  251. comments.push({
  252. afterKey: !!key,
  253. before: items.length,
  254. comment: item.comment
  255. });
  256. } else if (key === undefined) {
  257. if (next === ',') doc.errors.push(new _errors.YAMLSemanticError(item, 'Separator , missing in flow map'));
  258. key = doc.resolveNode(item);
  259. keyStart = explicitKey ? null : item.range.start; // TODO: add error for non-explicit multiline plain key
  260. } else {
  261. if (next !== ',') doc.errors.push(new _errors.YAMLSemanticError(item, 'Indicator : missing in flow map entry'));
  262. items.push(new _Pair.default(key, doc.resolveNode(item)));
  263. key = undefined;
  264. explicitKey = false;
  265. }
  266. }
  267. (0, _parseUtils.checkFlowCollectionEnd)(doc.errors, cst);
  268. if (key !== undefined) items.push(new _Pair.default(key));
  269. return {
  270. comments: comments,
  271. items: items
  272. };
  273. }