yaml 2.0.0-4 → 2.0.0-8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/README.md +5 -5
  2. package/browser/dist/compose/compose-collection.js +12 -9
  3. package/browser/dist/compose/compose-doc.js +23 -6
  4. package/browser/dist/compose/compose-node.js +27 -17
  5. package/browser/dist/compose/compose-scalar.js +21 -23
  6. package/browser/dist/compose/composer.js +108 -78
  7. package/browser/dist/compose/resolve-block-map.js +41 -29
  8. package/browser/dist/compose/resolve-block-scalar.js +14 -17
  9. package/browser/dist/compose/resolve-block-seq.js +21 -17
  10. package/browser/dist/compose/resolve-end.js +7 -8
  11. package/browser/dist/compose/resolve-flow-collection.js +158 -199
  12. package/browser/dist/compose/resolve-flow-scalar.js +62 -26
  13. package/browser/dist/compose/resolve-props.js +72 -37
  14. package/browser/dist/compose/util-contains-newline.js +15 -12
  15. package/browser/dist/compose/util-map-includes.js +17 -0
  16. package/browser/dist/doc/Document.js +74 -99
  17. package/browser/dist/doc/anchors.js +72 -0
  18. package/browser/dist/doc/createNode.js +35 -19
  19. package/browser/dist/doc/directives.js +5 -0
  20. package/browser/dist/errors.js +16 -12
  21. package/browser/dist/index.js +3 -3
  22. package/browser/dist/nodes/Alias.js +51 -28
  23. package/browser/dist/nodes/Collection.js +23 -92
  24. package/browser/dist/nodes/Node.js +9 -1
  25. package/browser/dist/nodes/Pair.js +16 -231
  26. package/browser/dist/nodes/YAMLMap.js +8 -4
  27. package/browser/dist/nodes/YAMLSeq.js +7 -4
  28. package/browser/dist/nodes/addPairToJSMap.js +103 -0
  29. package/browser/dist/nodes/toJS.js +12 -10
  30. package/browser/dist/options.js +1 -2
  31. package/browser/dist/parse/cst-scalar.js +219 -0
  32. package/browser/dist/parse/cst-stringify.js +61 -0
  33. package/browser/dist/parse/cst-visit.js +97 -0
  34. package/{dist/parse/tokens.js → browser/dist/parse/cst.js} +12 -7
  35. package/browser/dist/parse/lexer.js +149 -125
  36. package/browser/dist/parse/parser.js +272 -196
  37. package/browser/dist/public-api.js +11 -14
  38. package/browser/dist/schema/Schema.js +28 -0
  39. package/browser/dist/{tags/failsafe → schema/common}/map.js +0 -0
  40. package/browser/dist/schema/common/null.js +13 -0
  41. package/browser/dist/{tags/failsafe → schema/common}/seq.js +1 -1
  42. package/browser/dist/{tags/failsafe → schema/common}/string.js +0 -0
  43. package/browser/dist/schema/core/bool.js +19 -0
  44. package/browser/dist/schema/core/float.js +40 -0
  45. package/browser/dist/schema/core/int.js +38 -0
  46. package/browser/dist/schema/core/schema.js +23 -0
  47. package/browser/dist/{tags/json.js → schema/json/schema.js} +5 -6
  48. package/browser/dist/schema/tags.js +79 -0
  49. package/browser/dist/{tags → schema}/yaml-1.1/binary.js +0 -0
  50. package/browser/dist/schema/yaml-1.1/bool.js +26 -0
  51. package/browser/dist/schema/yaml-1.1/float.js +43 -0
  52. package/browser/dist/schema/yaml-1.1/int.js +71 -0
  53. package/browser/dist/{tags → schema}/yaml-1.1/omap.js +0 -0
  54. package/browser/dist/{tags → schema}/yaml-1.1/pairs.js +9 -6
  55. package/browser/dist/schema/yaml-1.1/schema.js +37 -0
  56. package/browser/dist/{tags → schema}/yaml-1.1/set.js +0 -0
  57. package/browser/dist/{tags → schema}/yaml-1.1/timestamp.js +0 -0
  58. package/browser/dist/stringify/stringify.js +8 -6
  59. package/browser/dist/stringify/stringifyCollection.js +122 -0
  60. package/browser/dist/stringify/stringifyComment.js +14 -0
  61. package/browser/dist/stringify/stringifyDocument.js +64 -0
  62. package/browser/dist/stringify/stringifyPair.js +111 -0
  63. package/browser/dist/stringify/stringifyString.js +53 -52
  64. package/browser/dist/visit.js +20 -1
  65. package/dist/compose/compose-collection.d.ts +4 -4
  66. package/dist/compose/compose-collection.js +12 -9
  67. package/dist/compose/compose-doc.d.ts +4 -3
  68. package/dist/compose/compose-doc.js +23 -6
  69. package/dist/compose/compose-node.d.ts +15 -7
  70. package/dist/compose/compose-node.js +27 -17
  71. package/dist/compose/compose-scalar.d.ts +4 -3
  72. package/dist/compose/compose-scalar.js +20 -22
  73. package/dist/compose/composer.d.ts +28 -23
  74. package/dist/compose/composer.js +109 -79
  75. package/dist/compose/resolve-block-map.d.ts +5 -4
  76. package/dist/compose/resolve-block-map.js +41 -29
  77. package/dist/compose/resolve-block-scalar.d.ts +5 -3
  78. package/dist/compose/resolve-block-scalar.js +14 -17
  79. package/dist/compose/resolve-block-seq.d.ts +4 -4
  80. package/dist/compose/resolve-block-seq.js +21 -17
  81. package/dist/compose/resolve-end.d.ts +3 -2
  82. package/dist/compose/resolve-end.js +7 -8
  83. package/dist/compose/resolve-flow-collection.d.ts +4 -5
  84. package/dist/compose/resolve-flow-collection.js +157 -198
  85. package/dist/compose/resolve-flow-scalar.d.ts +5 -3
  86. package/dist/compose/resolve-flow-scalar.js +62 -26
  87. package/dist/compose/resolve-props.d.ts +16 -10
  88. package/dist/compose/resolve-props.js +72 -37
  89. package/dist/compose/util-contains-newline.d.ts +1 -1
  90. package/dist/compose/util-contains-newline.js +15 -12
  91. package/dist/compose/util-empty-scalar-position.d.ts +1 -1
  92. package/dist/compose/util-map-includes.d.ts +4 -0
  93. package/dist/compose/util-map-includes.js +19 -0
  94. package/dist/doc/Document.d.ts +35 -15
  95. package/dist/doc/Document.js +72 -97
  96. package/dist/doc/anchors.d.ts +24 -0
  97. package/dist/doc/anchors.js +77 -0
  98. package/dist/doc/createNode.d.ts +10 -11
  99. package/dist/doc/createNode.js +34 -18
  100. package/dist/doc/directives.d.ts +1 -0
  101. package/dist/doc/directives.js +5 -0
  102. package/dist/errors.d.ts +11 -8
  103. package/dist/errors.js +16 -12
  104. package/dist/index.d.ts +5 -3
  105. package/dist/index.js +3 -3
  106. package/dist/nodes/Alias.d.ts +19 -9
  107. package/dist/nodes/Alias.js +51 -28
  108. package/dist/nodes/Collection.d.ts +9 -17
  109. package/dist/nodes/Collection.js +22 -91
  110. package/dist/nodes/Node.d.ts +10 -4
  111. package/dist/nodes/Node.js +9 -0
  112. package/dist/nodes/Pair.d.ts +10 -13
  113. package/dist/nodes/Pair.js +15 -230
  114. package/dist/nodes/Scalar.d.ts +6 -3
  115. package/dist/nodes/YAMLMap.d.ts +3 -3
  116. package/dist/nodes/YAMLMap.js +8 -4
  117. package/dist/nodes/YAMLSeq.d.ts +3 -3
  118. package/dist/nodes/YAMLSeq.js +7 -4
  119. package/dist/nodes/addPairToJSMap.d.ts +3 -0
  120. package/dist/nodes/addPairToJSMap.js +105 -0
  121. package/dist/nodes/toJS.d.ts +4 -5
  122. package/dist/nodes/toJS.js +12 -10
  123. package/dist/options.d.ts +41 -25
  124. package/dist/options.js +1 -2
  125. package/dist/parse/cst-scalar.d.ts +58 -0
  126. package/dist/parse/cst-scalar.js +223 -0
  127. package/dist/parse/cst-stringify.d.ts +8 -0
  128. package/dist/parse/cst-stringify.js +63 -0
  129. package/dist/parse/cst-visit.d.ts +39 -0
  130. package/dist/parse/cst-visit.js +99 -0
  131. package/dist/parse/{tokens.d.ts → cst.d.ts} +23 -7
  132. package/{browser/dist/parse/tokens.js → dist/parse/cst.js} +27 -1
  133. package/dist/parse/lexer.d.ts +7 -14
  134. package/dist/parse/lexer.js +150 -126
  135. package/dist/parse/parser.d.ts +31 -24
  136. package/dist/parse/parser.js +274 -198
  137. package/dist/public-api.d.ts +7 -7
  138. package/dist/public-api.js +11 -14
  139. package/dist/{doc → schema}/Schema.d.ts +6 -3
  140. package/dist/schema/Schema.js +30 -0
  141. package/dist/{tags/failsafe → schema/common}/map.d.ts +0 -0
  142. package/dist/{tags/failsafe → schema/common}/map.js +0 -0
  143. package/dist/schema/common/null.d.ts +4 -0
  144. package/dist/schema/common/null.js +15 -0
  145. package/dist/{tags/failsafe → schema/common}/seq.d.ts +0 -0
  146. package/dist/{tags/failsafe → schema/common}/seq.js +1 -1
  147. package/dist/{tags/failsafe → schema/common}/string.d.ts +0 -0
  148. package/dist/{tags/failsafe → schema/common}/string.js +0 -0
  149. package/dist/schema/core/bool.d.ts +4 -0
  150. package/dist/schema/core/bool.js +21 -0
  151. package/dist/schema/core/float.d.ts +4 -0
  152. package/dist/schema/core/float.js +44 -0
  153. package/dist/schema/core/int.d.ts +4 -0
  154. package/dist/schema/core/int.js +42 -0
  155. package/dist/schema/core/schema.d.ts +1 -0
  156. package/dist/schema/core/schema.js +25 -0
  157. package/dist/schema/json/schema.d.ts +2 -0
  158. package/dist/{tags/json.js → schema/json/schema.js} +5 -6
  159. package/dist/schema/tags.d.ts +41 -0
  160. package/dist/schema/tags.js +82 -0
  161. package/dist/{tags → schema}/types.d.ts +3 -7
  162. package/dist/{tags → schema}/yaml-1.1/binary.d.ts +0 -0
  163. package/dist/{tags → schema}/yaml-1.1/binary.js +0 -0
  164. package/dist/schema/yaml-1.1/bool.d.ts +7 -0
  165. package/dist/schema/yaml-1.1/bool.js +29 -0
  166. package/dist/schema/yaml-1.1/float.d.ts +4 -0
  167. package/dist/schema/yaml-1.1/float.js +47 -0
  168. package/dist/schema/yaml-1.1/int.d.ts +5 -0
  169. package/dist/schema/yaml-1.1/int.js +76 -0
  170. package/dist/{tags → schema}/yaml-1.1/omap.d.ts +0 -0
  171. package/dist/{tags → schema}/yaml-1.1/omap.js +0 -0
  172. package/dist/{tags → schema}/yaml-1.1/pairs.d.ts +3 -2
  173. package/dist/{tags → schema}/yaml-1.1/pairs.js +9 -6
  174. package/dist/schema/yaml-1.1/schema.d.ts +1 -0
  175. package/dist/schema/yaml-1.1/schema.js +39 -0
  176. package/dist/{tags → schema}/yaml-1.1/set.d.ts +1 -1
  177. package/dist/{tags → schema}/yaml-1.1/set.js +0 -0
  178. package/dist/{tags → schema}/yaml-1.1/timestamp.d.ts +0 -0
  179. package/dist/{tags → schema}/yaml-1.1/timestamp.js +0 -0
  180. package/dist/stringify/stringify.d.ts +1 -2
  181. package/dist/stringify/stringify.js +8 -6
  182. package/dist/stringify/stringifyCollection.d.ts +21 -0
  183. package/dist/stringify/stringifyCollection.js +124 -0
  184. package/dist/stringify/stringifyComment.d.ts +2 -0
  185. package/dist/stringify/stringifyComment.js +17 -0
  186. package/dist/stringify/stringifyDocument.d.ts +3 -0
  187. package/dist/stringify/stringifyDocument.js +66 -0
  188. package/dist/stringify/stringifyPair.d.ts +3 -0
  189. package/dist/stringify/stringifyPair.js +113 -0
  190. package/dist/stringify/stringifyString.js +53 -52
  191. package/dist/test-events.d.ts +1 -2
  192. package/dist/test-events.js +25 -12
  193. package/dist/util.d.ts +1 -1
  194. package/dist/visit.d.ts +10 -1
  195. package/dist/visit.js +20 -1
  196. package/package.json +9 -8
  197. package/browser/dist/doc/Anchors.js +0 -102
  198. package/browser/dist/doc/Schema.js +0 -27
  199. package/browser/dist/doc/getSchemaTags.js +0 -30
  200. package/browser/dist/stringify/addComment.js +0 -17
  201. package/browser/dist/tags/core.js +0 -109
  202. package/browser/dist/tags/failsafe/index.js +0 -7
  203. package/browser/dist/tags/index.js +0 -34
  204. package/browser/dist/tags/yaml-1.1/index.js +0 -152
  205. package/dist/doc/Anchors.d.ts +0 -36
  206. package/dist/doc/Anchors.js +0 -104
  207. package/dist/doc/Schema.js +0 -29
  208. package/dist/doc/getSchemaTags.d.ts +0 -3
  209. package/dist/doc/getSchemaTags.js +0 -32
  210. package/dist/stringify/addComment.d.ts +0 -2
  211. package/dist/stringify/addComment.js +0 -20
  212. package/dist/tags/core.d.ts +0 -14
  213. package/dist/tags/core.js +0 -119
  214. package/dist/tags/failsafe/index.d.ts +0 -1
  215. package/dist/tags/failsafe/index.js +0 -9
  216. package/dist/tags/index.d.ts +0 -31
  217. package/dist/tags/index.js +0 -37
  218. package/dist/tags/json.d.ts +0 -2
  219. package/dist/tags/yaml-1.1/index.d.ts +0 -2
  220. package/dist/tags/yaml-1.1/index.js +0 -154
@@ -1,5 +1,5 @@
1
+ import { tokenType } from './cst.js';
1
2
  import { Lexer } from './lexer.js';
2
- import { tokenType } from './tokens.js';
3
3
 
4
4
  function includesToken(list, type) {
5
5
  for (let i = 0; i < list.length; ++i)
@@ -20,38 +20,6 @@ function includesNonEmpty(list) {
20
20
  }
21
21
  return false;
22
22
  }
23
- function atFirstEmptyLineAfterComments(start) {
24
- let hasComment = false;
25
- for (let i = 0; i < start.length; ++i) {
26
- switch (start[i].type) {
27
- case 'space':
28
- break;
29
- case 'comment':
30
- hasComment = true;
31
- break;
32
- case 'newline':
33
- if (!hasComment)
34
- return false;
35
- break;
36
- default:
37
- return false;
38
- }
39
- }
40
- if (hasComment) {
41
- for (let i = start.length - 1; i >= 0; --i) {
42
- switch (start[i].type) {
43
- /* istanbul ignore next */
44
- case 'space':
45
- break;
46
- case 'newline':
47
- return true;
48
- default:
49
- return false;
50
- }
51
- }
52
- }
53
- return false;
54
- }
55
23
  function isFlowToken(token) {
56
24
  switch (token === null || token === void 0 ? void 0 : token.type) {
57
25
  case 'alias':
@@ -87,6 +55,7 @@ function getFirstKeyStartProps(prev) {
87
55
  let i = prev.length;
88
56
  loop: while (--i >= 0) {
89
57
  switch (prev[i].type) {
58
+ case 'doc-start':
90
59
  case 'explicit-key-ind':
91
60
  case 'map-value-ind':
92
61
  case 'seq-item-ind':
@@ -99,31 +68,62 @@ function getFirstKeyStartProps(prev) {
99
68
  }
100
69
  return prev.splice(i, prev.length);
101
70
  }
71
+ function fixFlowSeqItems(fc) {
72
+ if (fc.start.type === 'flow-seq-start') {
73
+ for (const it of fc.items) {
74
+ if (it.sep &&
75
+ !it.value &&
76
+ !includesToken(it.start, 'explicit-key-ind') &&
77
+ !includesToken(it.sep, 'map-value-ind')) {
78
+ if (it.key)
79
+ it.value = it.key;
80
+ delete it.key;
81
+ if (isFlowToken(it.value)) {
82
+ if (it.value.end)
83
+ Array.prototype.push.apply(it.value.end, it.sep);
84
+ else
85
+ it.value.end = it.sep;
86
+ }
87
+ else
88
+ Array.prototype.push.apply(it.start, it.sep);
89
+ delete it.sep;
90
+ }
91
+ }
92
+ }
93
+ }
102
94
  /**
103
95
  * A YAML concrete syntax tree (CST) parser
104
96
  *
105
- * While the `parse()` method provides an API for parsing a source string
106
- * directly, the parser may also be used with a user-provided lexer:
107
- *
108
97
  * ```ts
109
- * const cst: Token[] = []
110
- * const parser = new Parser(tok => cst.push(tok))
111
98
  * const src: string = ...
99
+ * for (const token of new Parser().parse(src)) {
100
+ * // token: Token
101
+ * }
102
+ * ```
103
+ *
104
+ * To use the parser with a user-provided lexer:
105
+ *
106
+ * ```ts
107
+ * function* parse(source: string, lexer: Lexer) {
108
+ * const parser = new Parser()
109
+ * for (const lexeme of lexer.lex(source))
110
+ * yield* parser.next(lexeme)
111
+ * yield* parser.end()
112
+ * }
112
113
  *
113
- * // The following would be equivalent to `parser.parse(src, false)`
114
- * const lexer = new Lexer(parser.next)
115
- * lexer.lex(src, false)
116
- * parser.end()
114
+ * const src: string = ...
115
+ * const lexer = new Lexer()
116
+ * for (const token of parse(src, lexer)) {
117
+ * // token: Token
118
+ * }
117
119
  * ```
118
120
  */
119
121
  class Parser {
120
122
  /**
121
- * @param push - Called separately with each parsed token
122
123
  * @param onNewLine - If defined, called separately with the start position of
123
124
  * each new line (in `parse()`, including the start of input).
124
- * @public
125
125
  */
126
- constructor(push, onNewLine) {
126
+ constructor(onNewLine) {
127
127
  /** If true, space and sequence indicators count as indentation */
128
128
  this.atNewLine = true;
129
129
  /** If true, next token is a scalar value */
@@ -140,94 +140,95 @@ class Parser {
140
140
  this.source = '';
141
141
  /** The type of the current token, set in parse() */
142
142
  this.type = '';
143
- /**
144
- * Advance the parser by the `source` of one lexical token. Bound to the
145
- * Parser instance, so may be used directly as a callback function.
146
- */
147
- this.next = (source) => {
148
- this.source = source;
149
- if (this.atScalar) {
150
- this.atScalar = false;
151
- this.step();
152
- this.offset += source.length;
153
- return;
154
- }
155
- const type = tokenType(source);
156
- if (!type) {
157
- const message = `Not a YAML token: ${source}`;
158
- this.pop({ type: 'error', offset: this.offset, message, source });
159
- this.offset += source.length;
160
- }
161
- else if (type === 'scalar') {
162
- this.atNewLine = false;
163
- this.atScalar = true;
164
- this.type = 'scalar';
165
- }
166
- else {
167
- this.type = type;
168
- this.step();
169
- switch (type) {
170
- case 'newline':
171
- this.atNewLine = true;
172
- this.indent = 0;
173
- if (this.onNewLine)
174
- this.onNewLine(this.offset + source.length);
175
- break;
176
- case 'space':
177
- if (this.atNewLine && source[0] === ' ')
178
- this.indent += source.length;
179
- break;
180
- case 'explicit-key-ind':
181
- case 'map-value-ind':
182
- case 'seq-item-ind':
183
- if (this.atNewLine)
184
- this.indent += source.length;
185
- break;
186
- case 'doc-mode':
187
- return;
188
- default:
189
- this.atNewLine = false;
190
- }
191
- this.offset += source.length;
192
- }
193
- };
194
143
  // Must be defined after `next()`
195
- this.lexer = new Lexer(this.next);
196
- this.push = push;
144
+ this.lexer = new Lexer();
197
145
  this.onNewLine = onNewLine;
198
146
  }
199
147
  /**
200
- * Parse `source` as a YAML stream, calling `push` with each directive,
201
- * document and other structure as it is completely parsed. If `incomplete`,
202
- * a part of the last line may be left as a buffer for the next call.
148
+ * Parse `source` as a YAML stream.
149
+ * If `incomplete`, a part of the last line may be left as a buffer for the next call.
203
150
  *
204
- * Errors are not thrown, but pushed out as `{ type: 'error', message }` tokens.
205
- * @public
151
+ * Errors are not thrown, but yielded as `{ type: 'error', message }` tokens.
152
+ *
153
+ * @returns A generator of tokens representing each directive, document, and other structure.
206
154
  */
207
- parse(source, incomplete = false) {
155
+ *parse(source, incomplete = false) {
208
156
  if (this.onNewLine && this.offset === 0)
209
157
  this.onNewLine(0);
210
- this.lexer.lex(source, incomplete);
158
+ for (const lexeme of this.lexer.lex(source, incomplete))
159
+ yield* this.next(lexeme);
211
160
  if (!incomplete)
212
- this.end();
161
+ yield* this.end();
162
+ }
163
+ /**
164
+ * Advance the parser by the `source` of one lexical token.
165
+ */
166
+ *next(source) {
167
+ this.source = source;
168
+ if (this.atScalar) {
169
+ this.atScalar = false;
170
+ yield* this.step();
171
+ this.offset += source.length;
172
+ return;
173
+ }
174
+ const type = tokenType(source);
175
+ if (!type) {
176
+ const message = `Not a YAML token: ${source}`;
177
+ yield* this.pop({ type: 'error', offset: this.offset, message, source });
178
+ this.offset += source.length;
179
+ }
180
+ else if (type === 'scalar') {
181
+ this.atNewLine = false;
182
+ this.atScalar = true;
183
+ this.type = 'scalar';
184
+ }
185
+ else {
186
+ this.type = type;
187
+ yield* this.step();
188
+ switch (type) {
189
+ case 'newline':
190
+ this.atNewLine = true;
191
+ this.indent = 0;
192
+ if (this.onNewLine)
193
+ this.onNewLine(this.offset + source.length);
194
+ break;
195
+ case 'space':
196
+ if (this.atNewLine && source[0] === ' ')
197
+ this.indent += source.length;
198
+ break;
199
+ case 'explicit-key-ind':
200
+ case 'map-value-ind':
201
+ case 'seq-item-ind':
202
+ if (this.atNewLine)
203
+ this.indent += source.length;
204
+ break;
205
+ case 'doc-mode':
206
+ return;
207
+ default:
208
+ this.atNewLine = false;
209
+ }
210
+ this.offset += source.length;
211
+ }
213
212
  }
214
213
  /** Call at end of input to push out any remaining constructions */
215
- end() {
214
+ *end() {
216
215
  while (this.stack.length > 0)
217
- this.pop();
216
+ yield* this.pop();
218
217
  }
219
218
  get sourceToken() {
220
- return {
219
+ const st = {
221
220
  type: this.type,
221
+ offset: this.offset,
222
222
  indent: this.indent,
223
223
  source: this.source
224
224
  };
225
+ return st;
225
226
  }
226
- step() {
227
+ *step() {
227
228
  const top = this.peek(1);
228
229
  if (this.type === 'doc-end' && (!top || top.type !== 'doc-end')) {
229
230
  while (this.stack.length > 0)
230
- this.pop();
231
+ yield* this.pop();
231
232
  this.stack.push({
232
233
  type: 'doc-end',
233
234
  offset: this.offset,
@@ -236,47 +237,49 @@ class Parser {
236
237
  return;
237
238
  }
238
239
  if (!top)
239
- return this.stream();
240
+ return yield* this.stream();
240
241
  switch (top.type) {
241
242
  case 'document':
242
- return this.document(top);
243
+ return yield* this.document(top);
243
244
  case 'alias':
244
245
  case 'scalar':
245
246
  case 'single-quoted-scalar':
246
247
  case 'double-quoted-scalar':
247
- return this.scalar(top);
248
+ return yield* this.scalar(top);
248
249
  case 'block-scalar':
249
- return this.blockScalar(top);
250
+ return yield* this.blockScalar(top);
250
251
  case 'block-map':
251
- return this.blockMap(top);
252
+ return yield* this.blockMap(top);
252
253
  case 'block-seq':
253
- return this.blockSequence(top);
254
+ return yield* this.blockSequence(top);
254
255
  case 'flow-collection':
255
- return this.flowCollection(top);
256
+ return yield* this.flowCollection(top);
256
257
  case 'doc-end':
257
- return this.documentEnd(top);
258
+ return yield* this.documentEnd(top);
258
259
  }
259
260
  /* istanbul ignore next should not happen */
260
- this.pop();
261
+ yield* this.pop();
261
262
  }
262
263
  peek(n) {
263
264
  return this.stack[this.stack.length - n];
264
265
  }
265
- pop(error) {
266
+ *pop(error) {
266
267
  const token = error || this.stack.pop();
267
268
  /* istanbul ignore if should not happen */
268
269
  if (!token) {
269
270
  const message = 'Tried to pop an empty stack';
270
- this.push({ type: 'error', source: '', message });
271
+ yield { type: 'error', offset: this.offset, source: '', message };
271
272
  }
272
273
  else if (this.stack.length === 0) {
273
- this.push(token);
274
+ yield token;
274
275
  }
275
276
  else {
276
277
  const top = this.peek(1);
277
278
  // For these, parent indent is needed instead of own
278
279
  if (token.type === 'block-scalar' || token.type === 'flow-collection')
279
280
  token.indent = 'indent' in top ? top.indent : -1;
281
+ if (token.type === 'flow-collection')
282
+ fixFlowSeqItems(token);
280
283
  switch (top.type) {
281
284
  case 'document':
282
285
  top.value = token;
@@ -309,13 +312,20 @@ class Parser {
309
312
  it.value = token;
310
313
  break;
311
314
  }
312
- case 'flow-collection':
313
- top.items.push(token);
314
- break;
315
+ case 'flow-collection': {
316
+ const it = top.items[top.items.length - 1];
317
+ if (!it || it.value)
318
+ top.items.push({ start: [], key: token, sep: [] });
319
+ else if (it.sep)
320
+ it.value = token;
321
+ else
322
+ Object.assign(it, { key: token, sep: [] });
323
+ return;
324
+ }
315
325
  /* istanbul ignore next should not happen */
316
326
  default:
317
- this.pop();
318
- this.pop(token);
327
+ yield* this.pop();
328
+ yield* this.pop(token);
319
329
  }
320
330
  if ((top.type === 'document' ||
321
331
  top.type === 'block-map' ||
@@ -338,16 +348,16 @@ class Parser {
338
348
  }
339
349
  }
340
350
  }
341
- stream() {
351
+ *stream() {
342
352
  switch (this.type) {
343
353
  case 'directive-line':
344
- this.push({ type: 'directive', source: this.source });
354
+ yield { type: 'directive', offset: this.offset, source: this.source };
345
355
  return;
346
356
  case 'byte-order-mark':
347
357
  case 'space':
348
358
  case 'comment':
349
359
  case 'newline':
350
- this.push(this.sourceToken);
360
+ yield this.sourceToken;
351
361
  return;
352
362
  case 'doc-mode':
353
363
  case 'doc-start': {
@@ -362,21 +372,21 @@ class Parser {
362
372
  return;
363
373
  }
364
374
  }
365
- this.push({
375
+ yield {
366
376
  type: 'error',
367
377
  offset: this.offset,
368
378
  message: `Unexpected ${this.type} token in YAML stream`,
369
379
  source: this.source
370
- });
380
+ };
371
381
  }
372
- document(doc) {
382
+ *document(doc) {
373
383
  if (doc.value)
374
- return this.lineEnd(doc);
384
+ return yield* this.lineEnd(doc);
375
385
  switch (this.type) {
376
386
  case 'doc-start': {
377
387
  if (includesNonEmpty(doc.start)) {
378
- this.pop();
379
- this.step();
388
+ yield* this.pop();
389
+ yield* this.step();
380
390
  }
381
391
  else
382
392
  doc.start.push(this.sourceToken);
@@ -394,15 +404,15 @@ class Parser {
394
404
  if (bv)
395
405
  this.stack.push(bv);
396
406
  else {
397
- this.push({
407
+ yield {
398
408
  type: 'error',
399
409
  offset: this.offset,
400
410
  message: `Unexpected ${this.type} token in YAML document`,
401
411
  source: this.source
402
- });
412
+ };
403
413
  }
404
414
  }
405
- scalar(scalar) {
415
+ *scalar(scalar) {
406
416
  if (this.type === 'map-value-ind') {
407
417
  const prev = getPrevProps(this.peek(2));
408
418
  const start = getFirstKeyStartProps(prev);
@@ -424,9 +434,9 @@ class Parser {
424
434
  this.stack[this.stack.length - 1] = map;
425
435
  }
426
436
  else
427
- this.lineEnd(scalar);
437
+ yield* this.lineEnd(scalar);
428
438
  }
429
- blockScalar(scalar) {
439
+ *blockScalar(scalar) {
430
440
  switch (this.type) {
431
441
  case 'space':
432
442
  case 'comment':
@@ -445,39 +455,53 @@ class Parser {
445
455
  nl = this.source.indexOf('\n', nl) + 1;
446
456
  }
447
457
  }
448
- this.pop();
458
+ yield* this.pop();
449
459
  break;
450
460
  /* istanbul ignore next should not happen */
451
461
  default:
452
- this.pop();
453
- this.step();
462
+ yield* this.pop();
463
+ yield* this.step();
454
464
  }
455
465
  }
456
- blockMap(map) {
466
+ *blockMap(map) {
457
467
  var _a;
458
468
  const it = map.items[map.items.length - 1];
459
469
  // it.sep is true-ish if pair already has key or : separator
460
470
  switch (this.type) {
461
471
  case 'newline':
462
472
  this.onKeyLine = false;
463
- if (!it.sep && atFirstEmptyLineAfterComments(it.start)) {
464
- const prev = map.items[map.items.length - 2];
465
- const end = (_a = prev === null || prev === void 0 ? void 0 : prev.value) === null || _a === void 0 ? void 0 : _a.end;
466
- if (Array.isArray(end)) {
467
- Array.prototype.push.apply(end, it.start);
468
- it.start = [this.sourceToken];
469
- return;
470
- }
473
+ if (it.value) {
474
+ const end = 'end' in it.value ? it.value.end : undefined;
475
+ const last = Array.isArray(end) ? end[end.length - 1] : undefined;
476
+ if ((last === null || last === void 0 ? void 0 : last.type) === 'comment')
477
+ end === null || end === void 0 ? void 0 : end.push(this.sourceToken);
478
+ else
479
+ map.items.push({ start: [this.sourceToken] });
471
480
  }
472
- // fallthrough
481
+ else if (it.sep)
482
+ it.sep.push(this.sourceToken);
483
+ else
484
+ it.start.push(this.sourceToken);
485
+ return;
473
486
  case 'space':
474
487
  case 'comment':
475
488
  if (it.value)
476
489
  map.items.push({ start: [this.sourceToken] });
477
490
  else if (it.sep)
478
491
  it.sep.push(this.sourceToken);
479
- else
492
+ else {
493
+ if (this.atIndentedComment(it.start, map.indent)) {
494
+ const prev = map.items[map.items.length - 2];
495
+ const end = (_a = prev === null || prev === void 0 ? void 0 : prev.value) === null || _a === void 0 ? void 0 : _a.end;
496
+ if (Array.isArray(end)) {
497
+ Array.prototype.push.apply(end, it.start);
498
+ end.push(this.sourceToken);
499
+ map.items.pop();
500
+ return;
501
+ }
502
+ }
480
503
  it.start.push(this.sourceToken);
504
+ }
481
505
  return;
482
506
  }
483
507
  if (this.indent >= map.indent) {
@@ -574,30 +598,42 @@ class Parser {
574
598
  }
575
599
  }
576
600
  }
577
- this.pop();
578
- this.step();
601
+ yield* this.pop();
602
+ yield* this.step();
579
603
  }
580
- blockSequence(seq) {
604
+ *blockSequence(seq) {
581
605
  var _a;
582
606
  const it = seq.items[seq.items.length - 1];
583
607
  switch (this.type) {
584
608
  case 'newline':
585
- if (!it.value && atFirstEmptyLineAfterComments(it.start)) {
586
- const prev = seq.items[seq.items.length - 2];
587
- const end = (_a = prev === null || prev === void 0 ? void 0 : prev.value) === null || _a === void 0 ? void 0 : _a.end;
588
- if (Array.isArray(end)) {
589
- Array.prototype.push.apply(end, it.start);
590
- it.start = [this.sourceToken];
591
- return;
592
- }
609
+ if (it.value) {
610
+ const end = 'end' in it.value ? it.value.end : undefined;
611
+ const last = Array.isArray(end) ? end[end.length - 1] : undefined;
612
+ if ((last === null || last === void 0 ? void 0 : last.type) === 'comment')
613
+ end === null || end === void 0 ? void 0 : end.push(this.sourceToken);
614
+ else
615
+ seq.items.push({ start: [this.sourceToken] });
593
616
  }
594
- // fallthrough
617
+ else
618
+ it.start.push(this.sourceToken);
619
+ return;
595
620
  case 'space':
596
621
  case 'comment':
597
622
  if (it.value)
598
623
  seq.items.push({ start: [this.sourceToken] });
599
- else
624
+ else {
625
+ if (this.atIndentedComment(it.start, seq.indent)) {
626
+ const prev = seq.items[seq.items.length - 2];
627
+ const end = (_a = prev === null || prev === void 0 ? void 0 : prev.value) === null || _a === void 0 ? void 0 : _a.end;
628
+ if (Array.isArray(end)) {
629
+ Array.prototype.push.apply(end, it.start);
630
+ end.push(this.sourceToken);
631
+ seq.items.pop();
632
+ return;
633
+ }
634
+ }
600
635
  it.start.push(this.sourceToken);
636
+ }
601
637
  return;
602
638
  case 'anchor':
603
639
  case 'tag':
@@ -616,38 +652,65 @@ class Parser {
616
652
  }
617
653
  if (this.indent > seq.indent) {
618
654
  const bv = this.startBlockValue(seq);
619
- if (bv)
620
- return this.stack.push(bv);
655
+ if (bv) {
656
+ this.stack.push(bv);
657
+ return;
658
+ }
621
659
  }
622
- this.pop();
623
- this.step();
660
+ yield* this.pop();
661
+ yield* this.step();
624
662
  }
625
- flowCollection(fc) {
663
+ *flowCollection(fc) {
664
+ const it = fc.items[fc.items.length - 1];
626
665
  if (this.type === 'flow-error-end') {
627
666
  let top;
628
667
  do {
629
- this.pop();
668
+ yield* this.pop();
630
669
  top = this.peek(1);
631
670
  } while (top && top.type === 'flow-collection');
632
671
  }
633
672
  else if (fc.end.length === 0) {
634
673
  switch (this.type) {
635
- case 'space':
636
- case 'comment':
637
- case 'newline':
638
674
  case 'comma':
639
675
  case 'explicit-key-ind':
676
+ if (!it || it.sep)
677
+ fc.items.push({ start: [this.sourceToken] });
678
+ else
679
+ it.start.push(this.sourceToken);
680
+ return;
640
681
  case 'map-value-ind':
682
+ if (!it || it.value)
683
+ fc.items.push({ start: [], key: null, sep: [this.sourceToken] });
684
+ else if (it.sep)
685
+ it.sep.push(this.sourceToken);
686
+ else
687
+ Object.assign(it, { key: null, sep: [this.sourceToken] });
688
+ return;
689
+ case 'space':
690
+ case 'comment':
691
+ case 'newline':
641
692
  case 'anchor':
642
693
  case 'tag':
643
- fc.items.push(this.sourceToken);
694
+ if (!it || it.value)
695
+ fc.items.push({ start: [this.sourceToken] });
696
+ else if (it.sep)
697
+ it.sep.push(this.sourceToken);
698
+ else
699
+ it.start.push(this.sourceToken);
644
700
  return;
645
701
  case 'alias':
646
702
  case 'scalar':
647
703
  case 'single-quoted-scalar':
648
- case 'double-quoted-scalar':
649
- fc.items.push(this.flowScalar(this.type));
704
+ case 'double-quoted-scalar': {
705
+ const fs = this.flowScalar(this.type);
706
+ if (!it || it.value)
707
+ fc.items.push({ start: [], key: fs, sep: [] });
708
+ else if (it.sep)
709
+ this.stack.push(fs);
710
+ else
711
+ Object.assign(it, { key: fs, sep: [] });
650
712
  return;
713
+ }
651
714
  case 'flow-map-end':
652
715
  case 'flow-seq-end':
653
716
  fc.end.push(this.sourceToken);
@@ -656,10 +719,10 @@ class Parser {
656
719
  const bv = this.startBlockValue(fc);
657
720
  /* istanbul ignore else should not happen */
658
721
  if (bv)
659
- return this.stack.push(bv);
722
+ this.stack.push(bv);
660
723
  else {
661
- this.pop();
662
- this.step();
724
+ yield* this.pop();
725
+ yield* this.step();
663
726
  }
664
727
  }
665
728
  else {
@@ -668,13 +731,14 @@ class Parser {
668
731
  (this.type === 'map-value-ind' ||
669
732
  (this.type === 'newline' &&
670
733
  !parent.items[parent.items.length - 1].sep))) {
671
- this.pop();
672
- this.step();
734
+ yield* this.pop();
735
+ yield* this.step();
673
736
  }
674
737
  else if (this.type === 'map-value-ind' &&
675
738
  parent.type !== 'flow-collection') {
676
739
  const prev = getPrevProps(parent);
677
740
  const start = getFirstKeyStartProps(prev);
741
+ fixFlowSeqItems(fc);
678
742
  const sep = fc.end.splice(1, fc.end.length);
679
743
  sep.push(this.sourceToken);
680
744
  const map = {
@@ -687,7 +751,7 @@ class Parser {
687
751
  this.stack[this.stack.length - 1] = map;
688
752
  }
689
753
  else {
690
- this.lineEnd(fc);
754
+ yield* this.lineEnd(fc);
691
755
  }
692
756
  }
693
757
  }
@@ -718,7 +782,8 @@ class Parser {
718
782
  type: 'block-scalar',
719
783
  offset: this.offset,
720
784
  indent: this.indent,
721
- props: [this.sourceToken]
785
+ props: [this.sourceToken],
786
+ source: ''
722
787
  };
723
788
  case 'flow-map-start':
724
789
  case 'flow-seq-start':
@@ -737,14 +802,18 @@ class Parser {
737
802
  indent: this.indent,
738
803
  items: [{ start: [this.sourceToken] }]
739
804
  };
740
- case 'explicit-key-ind':
805
+ case 'explicit-key-ind': {
741
806
  this.onKeyLine = true;
807
+ const prev = getPrevProps(parent);
808
+ const start = getFirstKeyStartProps(prev);
809
+ start.push(this.sourceToken);
742
810
  return {
743
811
  type: 'block-map',
744
812
  offset: this.offset,
745
813
  indent: this.indent,
746
- items: [{ start: [this.sourceToken] }]
814
+ items: [{ start }]
747
815
  };
816
+ }
748
817
  case 'map-value-ind': {
749
818
  this.onKeyLine = true;
750
819
  const prev = getPrevProps(parent);
@@ -759,17 +828,24 @@ class Parser {
759
828
  }
760
829
  return null;
761
830
  }
762
- documentEnd(docEnd) {
831
+ atIndentedComment(start, indent) {
832
+ if (this.type !== 'comment')
833
+ return false;
834
+ if (this.indent <= indent)
835
+ return false;
836
+ return start.every(st => st.type === 'newline' || st.type === 'space');
837
+ }
838
+ *documentEnd(docEnd) {
763
839
  if (this.type !== 'doc-mode') {
764
840
  if (docEnd.end)
765
841
  docEnd.end.push(this.sourceToken);
766
842
  else
767
843
  docEnd.end = [this.sourceToken];
768
844
  if (this.type === 'newline')
769
- this.pop();
845
+ yield* this.pop();
770
846
  }
771
847
  }
772
- lineEnd(token) {
848
+ *lineEnd(token) {
773
849
  switch (this.type) {
774
850
  case 'comma':
775
851
  case 'doc-start':
@@ -777,8 +853,8 @@ class Parser {
777
853
  case 'flow-seq-end':
778
854
  case 'flow-map-end':
779
855
  case 'map-value-ind':
780
- this.pop();
781
- this.step();
856
+ yield* this.pop();
857
+ yield* this.step();
782
858
  break;
783
859
  case 'newline':
784
860
  this.onKeyLine = false;
@@ -792,7 +868,7 @@ class Parser {
792
868
  else
793
869
  token.end = [this.sourceToken];
794
870
  if (this.type === 'newline')
795
- this.pop();
871
+ yield* this.pop();
796
872
  }
797
873
  }
798
874
  }