yaml 2.0.0-6 → 2.0.0-7
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.
- package/browser/dist/compose/compose-node.js +8 -1
- package/browser/dist/compose/composer.js +2 -1
- package/browser/dist/compose/resolve-flow-scalar.js +12 -6
- package/browser/dist/doc/createNode.js +6 -2
- package/browser/dist/nodes/addPairToJSMap.js +2 -2
- package/browser/dist/parse/lexer.js +35 -17
- package/dist/compose/compose-node.js +8 -1
- package/dist/compose/composer.js +2 -1
- package/dist/compose/resolve-flow-scalar.js +12 -6
- package/dist/doc/createNode.js +6 -2
- package/dist/errors.d.ts +1 -1
- package/dist/nodes/addPairToJSMap.js +2 -2
- package/dist/parse/lexer.d.ts +1 -1
- package/dist/parse/lexer.js +35 -17
- package/package.json +1 -1
|
@@ -33,6 +33,8 @@ function composeNode(ctx, token, props, onError) {
|
|
|
33
33
|
console.log(token);
|
|
34
34
|
throw new Error(`Unsupporten token type: ${token.type}`);
|
|
35
35
|
}
|
|
36
|
+
if (anchor && node.anchor === '')
|
|
37
|
+
onError(anchor, 'BAD_ALIAS', 'Anchor cannot be an empty string');
|
|
36
38
|
if (spaceBefore)
|
|
37
39
|
node.spaceBefore = true;
|
|
38
40
|
if (comment) {
|
|
@@ -51,8 +53,11 @@ function composeEmptyNode(ctx, offset, before, pos, { spaceBefore, comment, anch
|
|
|
51
53
|
source: ''
|
|
52
54
|
};
|
|
53
55
|
const node = composeScalar(ctx, token, tag, onError);
|
|
54
|
-
if (anchor)
|
|
56
|
+
if (anchor) {
|
|
55
57
|
node.anchor = anchor.source.substring(1);
|
|
58
|
+
if (node.anchor === '')
|
|
59
|
+
onError(anchor, 'BAD_ALIAS', 'Anchor cannot be an empty string');
|
|
60
|
+
}
|
|
56
61
|
if (spaceBefore)
|
|
57
62
|
node.spaceBefore = true;
|
|
58
63
|
if (comment)
|
|
@@ -61,6 +66,8 @@ function composeEmptyNode(ctx, offset, before, pos, { spaceBefore, comment, anch
|
|
|
61
66
|
}
|
|
62
67
|
function composeAlias({ options }, { offset, source, end }, onError) {
|
|
63
68
|
const alias = new Alias(source.substring(1));
|
|
69
|
+
if (alias.source === '')
|
|
70
|
+
onError(offset, 'BAD_ALIAS', 'Alias cannot be an empty string');
|
|
64
71
|
const valueEnd = offset + source.length;
|
|
65
72
|
const re = resolveEnd(end, valueEnd, options.strict, onError);
|
|
66
73
|
alias.range = [offset, valueEnd, re.offset];
|
|
@@ -15,6 +15,7 @@ function getErrorPos(src) {
|
|
|
15
15
|
return [offset, offset + (typeof source === 'string' ? source.length : 1)];
|
|
16
16
|
}
|
|
17
17
|
function parsePrelude(prelude) {
|
|
18
|
+
var _a;
|
|
18
19
|
let comment = '';
|
|
19
20
|
let atComment = false;
|
|
20
21
|
let afterEmptyLine = false;
|
|
@@ -29,7 +30,7 @@ function parsePrelude(prelude) {
|
|
|
29
30
|
afterEmptyLine = false;
|
|
30
31
|
break;
|
|
31
32
|
case '%':
|
|
32
|
-
if (prelude[i + 1][0] !== '#')
|
|
33
|
+
if (((_a = prelude[i + 1]) === null || _a === void 0 ? void 0 : _a[0]) !== '#')
|
|
33
34
|
i += 1;
|
|
34
35
|
atComment = false;
|
|
35
36
|
break;
|
|
@@ -39,25 +39,31 @@ function resolveFlowScalar(scalar, strict, onError) {
|
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
41
|
function plainValue(source, onError) {
|
|
42
|
-
let
|
|
42
|
+
let badChar = '';
|
|
43
43
|
switch (source[0]) {
|
|
44
44
|
/* istanbul ignore next should not happen */
|
|
45
45
|
case '\t':
|
|
46
|
-
|
|
46
|
+
badChar = 'a tab character';
|
|
47
|
+
break;
|
|
48
|
+
case ',':
|
|
49
|
+
badChar = 'flow indicator character ,';
|
|
50
|
+
break;
|
|
51
|
+
case '%':
|
|
52
|
+
badChar = 'directive indicator character %';
|
|
47
53
|
break;
|
|
48
54
|
case '|':
|
|
49
55
|
case '>': {
|
|
50
|
-
|
|
56
|
+
badChar = `block scalar indicator ${source[0]}`;
|
|
51
57
|
break;
|
|
52
58
|
}
|
|
53
59
|
case '@':
|
|
54
60
|
case '`': {
|
|
55
|
-
|
|
61
|
+
badChar = `reserved character ${source[0]}`;
|
|
56
62
|
break;
|
|
57
63
|
}
|
|
58
64
|
}
|
|
59
|
-
if (
|
|
60
|
-
onError(0, 'BAD_SCALAR_START',
|
|
65
|
+
if (badChar)
|
|
66
|
+
onError(0, 'BAD_SCALAR_START', `Plain value cannot start with ${badChar}`);
|
|
61
67
|
return foldLines(source);
|
|
62
68
|
}
|
|
63
69
|
function singleQuotedValue(source, onError) {
|
|
@@ -52,8 +52,12 @@ function createNode(value, tagName, ctx) {
|
|
|
52
52
|
if (!tagObj) {
|
|
53
53
|
if (value && typeof value.toJSON === 'function')
|
|
54
54
|
value = value.toJSON();
|
|
55
|
-
if (!value || typeof value !== 'object')
|
|
56
|
-
|
|
55
|
+
if (!value || typeof value !== 'object') {
|
|
56
|
+
const node = new Scalar(value);
|
|
57
|
+
if (ref)
|
|
58
|
+
ref.node = node;
|
|
59
|
+
return node;
|
|
60
|
+
}
|
|
57
61
|
tagObj =
|
|
58
62
|
value instanceof Map
|
|
59
63
|
? schema[MAP]
|
|
@@ -52,9 +52,9 @@ const isMergeKey = (key) => key === MERGE_KEY ||
|
|
|
52
52
|
// Keys in mapping nodes earlier in the sequence override keys specified in
|
|
53
53
|
// later mapping nodes. -- http://yaml.org/type/merge.html
|
|
54
54
|
function mergeToJSMap(ctx, map, value) {
|
|
55
|
-
const source = ctx && isAlias(value) ? value.resolve(ctx.doc) :
|
|
55
|
+
const source = ctx && isAlias(value) ? value.resolve(ctx.doc) : value;
|
|
56
56
|
if (!isMap(source))
|
|
57
|
-
throw new Error('Merge sources must be map aliases');
|
|
57
|
+
throw new Error('Merge sources must be maps or map aliases');
|
|
58
58
|
const srcMap = source.toJSON(null, ctx, Map);
|
|
59
59
|
for (const [key, value] of srcMap) {
|
|
60
60
|
if (map instanceof Map) {
|
|
@@ -79,9 +79,11 @@ function isEmpty(ch) {
|
|
|
79
79
|
return false;
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
|
-
const
|
|
83
|
-
const
|
|
84
|
-
const
|
|
82
|
+
const hexDigits = '0123456789ABCDEFabcdef'.split('');
|
|
83
|
+
const tagChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-#;/?:@&=+$_.!~*'()".split('');
|
|
84
|
+
const invalidFlowScalarChars = ',[]{}'.split('');
|
|
85
|
+
const invalidAnchorChars = ' ,[]{}\n\r\t'.split('');
|
|
86
|
+
const isNotAnchorChar = (ch) => !ch || invalidAnchorChars.includes(ch);
|
|
85
87
|
/**
|
|
86
88
|
* Splits an input string into lexical tokens, i.e. smaller strings that are
|
|
87
89
|
* easily identifiable by `tokens.tokenType()`.
|
|
@@ -325,7 +327,7 @@ class Lexer {
|
|
|
325
327
|
yield* this.pushCount(1);
|
|
326
328
|
return 'doc';
|
|
327
329
|
case '*':
|
|
328
|
-
yield* this.pushUntil(
|
|
330
|
+
yield* this.pushUntil(isNotAnchorChar);
|
|
329
331
|
return 'doc';
|
|
330
332
|
case '"':
|
|
331
333
|
case "'":
|
|
@@ -393,7 +395,7 @@ class Lexer {
|
|
|
393
395
|
this.flowLevel -= 1;
|
|
394
396
|
return this.flowLevel ? 'flow' : 'doc';
|
|
395
397
|
case '*':
|
|
396
|
-
yield* this.pushUntil(
|
|
398
|
+
yield* this.pushUntil(isNotAnchorChar);
|
|
397
399
|
return 'flow';
|
|
398
400
|
case '"':
|
|
399
401
|
case "'":
|
|
@@ -593,13 +595,11 @@ class Lexer {
|
|
|
593
595
|
*pushIndicators() {
|
|
594
596
|
switch (this.charAt(0)) {
|
|
595
597
|
case '!':
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
(yield* this.pushIndicators()));
|
|
600
|
-
// fallthrough
|
|
598
|
+
return ((yield* this.pushTag()) +
|
|
599
|
+
(yield* this.pushSpaces(true)) +
|
|
600
|
+
(yield* this.pushIndicators()));
|
|
601
601
|
case '&':
|
|
602
|
-
return ((yield* this.pushUntil(
|
|
602
|
+
return ((yield* this.pushUntil(isNotAnchorChar)) +
|
|
603
603
|
(yield* this.pushSpaces(true)) +
|
|
604
604
|
(yield* this.pushIndicators()));
|
|
605
605
|
case ':':
|
|
@@ -615,12 +615,30 @@ class Lexer {
|
|
|
615
615
|
}
|
|
616
616
|
return 0;
|
|
617
617
|
}
|
|
618
|
-
*
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
ch
|
|
623
|
-
|
|
618
|
+
*pushTag() {
|
|
619
|
+
if (this.charAt(1) === '<') {
|
|
620
|
+
let i = this.pos + 2;
|
|
621
|
+
let ch = this.buffer[i];
|
|
622
|
+
while (!isEmpty(ch) && ch !== '>')
|
|
623
|
+
ch = this.buffer[++i];
|
|
624
|
+
return yield* this.pushToIndex(ch === '>' ? i + 1 : i, false);
|
|
625
|
+
}
|
|
626
|
+
else {
|
|
627
|
+
let i = this.pos + 1;
|
|
628
|
+
let ch = this.buffer[i];
|
|
629
|
+
while (ch) {
|
|
630
|
+
if (tagChars.includes(ch))
|
|
631
|
+
ch = this.buffer[++i];
|
|
632
|
+
else if (ch === '%' &&
|
|
633
|
+
hexDigits.includes(this.buffer[i + 1]) &&
|
|
634
|
+
hexDigits.includes(this.buffer[i + 2])) {
|
|
635
|
+
ch = this.buffer[(i += 3)];
|
|
636
|
+
}
|
|
637
|
+
else
|
|
638
|
+
break;
|
|
639
|
+
}
|
|
640
|
+
return yield* this.pushToIndex(i, false);
|
|
641
|
+
}
|
|
624
642
|
}
|
|
625
643
|
*pushNewline() {
|
|
626
644
|
const ch = this.buffer[this.pos];
|
|
@@ -35,6 +35,8 @@ function composeNode(ctx, token, props, onError) {
|
|
|
35
35
|
console.log(token);
|
|
36
36
|
throw new Error(`Unsupporten token type: ${token.type}`);
|
|
37
37
|
}
|
|
38
|
+
if (anchor && node.anchor === '')
|
|
39
|
+
onError(anchor, 'BAD_ALIAS', 'Anchor cannot be an empty string');
|
|
38
40
|
if (spaceBefore)
|
|
39
41
|
node.spaceBefore = true;
|
|
40
42
|
if (comment) {
|
|
@@ -53,8 +55,11 @@ function composeEmptyNode(ctx, offset, before, pos, { spaceBefore, comment, anch
|
|
|
53
55
|
source: ''
|
|
54
56
|
};
|
|
55
57
|
const node = composeScalar.composeScalar(ctx, token, tag, onError);
|
|
56
|
-
if (anchor)
|
|
58
|
+
if (anchor) {
|
|
57
59
|
node.anchor = anchor.source.substring(1);
|
|
60
|
+
if (node.anchor === '')
|
|
61
|
+
onError(anchor, 'BAD_ALIAS', 'Anchor cannot be an empty string');
|
|
62
|
+
}
|
|
58
63
|
if (spaceBefore)
|
|
59
64
|
node.spaceBefore = true;
|
|
60
65
|
if (comment)
|
|
@@ -63,6 +68,8 @@ function composeEmptyNode(ctx, offset, before, pos, { spaceBefore, comment, anch
|
|
|
63
68
|
}
|
|
64
69
|
function composeAlias({ options }, { offset, source, end }, onError) {
|
|
65
70
|
const alias = new Alias.Alias(source.substring(1));
|
|
71
|
+
if (alias.source === '')
|
|
72
|
+
onError(offset, 'BAD_ALIAS', 'Alias cannot be an empty string');
|
|
66
73
|
const valueEnd = offset + source.length;
|
|
67
74
|
const re = resolveEnd.resolveEnd(end, valueEnd, options.strict, onError);
|
|
68
75
|
alias.range = [offset, valueEnd, re.offset];
|
package/dist/compose/composer.js
CHANGED
|
@@ -17,6 +17,7 @@ function getErrorPos(src) {
|
|
|
17
17
|
return [offset, offset + (typeof source === 'string' ? source.length : 1)];
|
|
18
18
|
}
|
|
19
19
|
function parsePrelude(prelude) {
|
|
20
|
+
var _a;
|
|
20
21
|
let comment = '';
|
|
21
22
|
let atComment = false;
|
|
22
23
|
let afterEmptyLine = false;
|
|
@@ -31,7 +32,7 @@ function parsePrelude(prelude) {
|
|
|
31
32
|
afterEmptyLine = false;
|
|
32
33
|
break;
|
|
33
34
|
case '%':
|
|
34
|
-
if (prelude[i + 1][0] !== '#')
|
|
35
|
+
if (((_a = prelude[i + 1]) === null || _a === void 0 ? void 0 : _a[0]) !== '#')
|
|
35
36
|
i += 1;
|
|
36
37
|
atComment = false;
|
|
37
38
|
break;
|
|
@@ -41,25 +41,31 @@ function resolveFlowScalar(scalar, strict, onError) {
|
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
43
|
function plainValue(source, onError) {
|
|
44
|
-
let
|
|
44
|
+
let badChar = '';
|
|
45
45
|
switch (source[0]) {
|
|
46
46
|
/* istanbul ignore next should not happen */
|
|
47
47
|
case '\t':
|
|
48
|
-
|
|
48
|
+
badChar = 'a tab character';
|
|
49
|
+
break;
|
|
50
|
+
case ',':
|
|
51
|
+
badChar = 'flow indicator character ,';
|
|
52
|
+
break;
|
|
53
|
+
case '%':
|
|
54
|
+
badChar = 'directive indicator character %';
|
|
49
55
|
break;
|
|
50
56
|
case '|':
|
|
51
57
|
case '>': {
|
|
52
|
-
|
|
58
|
+
badChar = `block scalar indicator ${source[0]}`;
|
|
53
59
|
break;
|
|
54
60
|
}
|
|
55
61
|
case '@':
|
|
56
62
|
case '`': {
|
|
57
|
-
|
|
63
|
+
badChar = `reserved character ${source[0]}`;
|
|
58
64
|
break;
|
|
59
65
|
}
|
|
60
66
|
}
|
|
61
|
-
if (
|
|
62
|
-
onError(0, 'BAD_SCALAR_START',
|
|
67
|
+
if (badChar)
|
|
68
|
+
onError(0, 'BAD_SCALAR_START', `Plain value cannot start with ${badChar}`);
|
|
63
69
|
return foldLines(source);
|
|
64
70
|
}
|
|
65
71
|
function singleQuotedValue(source, onError) {
|
package/dist/doc/createNode.js
CHANGED
|
@@ -54,8 +54,12 @@ function createNode(value, tagName, ctx) {
|
|
|
54
54
|
if (!tagObj) {
|
|
55
55
|
if (value && typeof value.toJSON === 'function')
|
|
56
56
|
value = value.toJSON();
|
|
57
|
-
if (!value || typeof value !== 'object')
|
|
58
|
-
|
|
57
|
+
if (!value || typeof value !== 'object') {
|
|
58
|
+
const node = new Scalar.Scalar(value);
|
|
59
|
+
if (ref)
|
|
60
|
+
ref.node = node;
|
|
61
|
+
return node;
|
|
62
|
+
}
|
|
59
63
|
tagObj =
|
|
60
64
|
value instanceof Map
|
|
61
65
|
? schema[Node.MAP]
|
package/dist/errors.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { LineCounter } from './parse/line-counter';
|
|
2
|
-
export declare type ErrorCode = 'ALIAS_PROPS' | 'BAD_DIRECTIVE' | 'BAD_DQ_ESCAPE' | 'BAD_INDENT' | 'BAD_PROP_ORDER' | 'BAD_SCALAR_START' | 'BLOCK_AS_IMPLICIT_KEY' | 'BLOCK_IN_FLOW' | 'DUPLICATE_KEY' | 'IMPOSSIBLE' | 'KEY_OVER_1024_CHARS' | '
|
|
2
|
+
export declare type ErrorCode = 'ALIAS_PROPS' | 'BAD_ALIAS' | 'BAD_DIRECTIVE' | 'BAD_DQ_ESCAPE' | 'BAD_INDENT' | 'BAD_PROP_ORDER' | 'BAD_SCALAR_START' | 'BLOCK_AS_IMPLICIT_KEY' | 'BLOCK_IN_FLOW' | 'DUPLICATE_KEY' | 'IMPOSSIBLE' | 'KEY_OVER_1024_CHARS' | 'MISSING_CHAR' | 'MULTILINE_IMPLICIT_KEY' | 'MULTIPLE_ANCHORS' | 'MULTIPLE_DOCS' | 'MULTIPLE_TAGS' | 'TAB_AS_INDENT' | 'TAG_RESOLVE_FAILED' | 'UNEXPECTED_TOKEN';
|
|
3
3
|
export declare type LinePos = {
|
|
4
4
|
line: number;
|
|
5
5
|
col: number;
|
|
@@ -54,9 +54,9 @@ const isMergeKey = (key) => key === MERGE_KEY ||
|
|
|
54
54
|
// Keys in mapping nodes earlier in the sequence override keys specified in
|
|
55
55
|
// later mapping nodes. -- http://yaml.org/type/merge.html
|
|
56
56
|
function mergeToJSMap(ctx, map, value) {
|
|
57
|
-
const source = ctx && Node.isAlias(value) ? value.resolve(ctx.doc) :
|
|
57
|
+
const source = ctx && Node.isAlias(value) ? value.resolve(ctx.doc) : value;
|
|
58
58
|
if (!Node.isMap(source))
|
|
59
|
-
throw new Error('Merge sources must be map aliases');
|
|
59
|
+
throw new Error('Merge sources must be maps or map aliases');
|
|
60
60
|
const srcMap = source.toJSON(null, ctx, Map);
|
|
61
61
|
for (const [key, value] of srcMap) {
|
|
62
62
|
if (map instanceof Map) {
|
package/dist/parse/lexer.d.ts
CHANGED
package/dist/parse/lexer.js
CHANGED
|
@@ -81,9 +81,11 @@ function isEmpty(ch) {
|
|
|
81
81
|
return false;
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
|
-
const
|
|
85
|
-
const
|
|
86
|
-
const
|
|
84
|
+
const hexDigits = '0123456789ABCDEFabcdef'.split('');
|
|
85
|
+
const tagChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-#;/?:@&=+$_.!~*'()".split('');
|
|
86
|
+
const invalidFlowScalarChars = ',[]{}'.split('');
|
|
87
|
+
const invalidAnchorChars = ' ,[]{}\n\r\t'.split('');
|
|
88
|
+
const isNotAnchorChar = (ch) => !ch || invalidAnchorChars.includes(ch);
|
|
87
89
|
/**
|
|
88
90
|
* Splits an input string into lexical tokens, i.e. smaller strings that are
|
|
89
91
|
* easily identifiable by `tokens.tokenType()`.
|
|
@@ -327,7 +329,7 @@ class Lexer {
|
|
|
327
329
|
yield* this.pushCount(1);
|
|
328
330
|
return 'doc';
|
|
329
331
|
case '*':
|
|
330
|
-
yield* this.pushUntil(
|
|
332
|
+
yield* this.pushUntil(isNotAnchorChar);
|
|
331
333
|
return 'doc';
|
|
332
334
|
case '"':
|
|
333
335
|
case "'":
|
|
@@ -395,7 +397,7 @@ class Lexer {
|
|
|
395
397
|
this.flowLevel -= 1;
|
|
396
398
|
return this.flowLevel ? 'flow' : 'doc';
|
|
397
399
|
case '*':
|
|
398
|
-
yield* this.pushUntil(
|
|
400
|
+
yield* this.pushUntil(isNotAnchorChar);
|
|
399
401
|
return 'flow';
|
|
400
402
|
case '"':
|
|
401
403
|
case "'":
|
|
@@ -595,13 +597,11 @@ class Lexer {
|
|
|
595
597
|
*pushIndicators() {
|
|
596
598
|
switch (this.charAt(0)) {
|
|
597
599
|
case '!':
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
(yield* this.pushIndicators()));
|
|
602
|
-
// fallthrough
|
|
600
|
+
return ((yield* this.pushTag()) +
|
|
601
|
+
(yield* this.pushSpaces(true)) +
|
|
602
|
+
(yield* this.pushIndicators()));
|
|
603
603
|
case '&':
|
|
604
|
-
return ((yield* this.pushUntil(
|
|
604
|
+
return ((yield* this.pushUntil(isNotAnchorChar)) +
|
|
605
605
|
(yield* this.pushSpaces(true)) +
|
|
606
606
|
(yield* this.pushIndicators()));
|
|
607
607
|
case ':':
|
|
@@ -617,12 +617,30 @@ class Lexer {
|
|
|
617
617
|
}
|
|
618
618
|
return 0;
|
|
619
619
|
}
|
|
620
|
-
*
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
ch
|
|
625
|
-
|
|
620
|
+
*pushTag() {
|
|
621
|
+
if (this.charAt(1) === '<') {
|
|
622
|
+
let i = this.pos + 2;
|
|
623
|
+
let ch = this.buffer[i];
|
|
624
|
+
while (!isEmpty(ch) && ch !== '>')
|
|
625
|
+
ch = this.buffer[++i];
|
|
626
|
+
return yield* this.pushToIndex(ch === '>' ? i + 1 : i, false);
|
|
627
|
+
}
|
|
628
|
+
else {
|
|
629
|
+
let i = this.pos + 1;
|
|
630
|
+
let ch = this.buffer[i];
|
|
631
|
+
while (ch) {
|
|
632
|
+
if (tagChars.includes(ch))
|
|
633
|
+
ch = this.buffer[++i];
|
|
634
|
+
else if (ch === '%' &&
|
|
635
|
+
hexDigits.includes(this.buffer[i + 1]) &&
|
|
636
|
+
hexDigits.includes(this.buffer[i + 2])) {
|
|
637
|
+
ch = this.buffer[(i += 3)];
|
|
638
|
+
}
|
|
639
|
+
else
|
|
640
|
+
break;
|
|
641
|
+
}
|
|
642
|
+
return yield* this.pushToIndex(i, false);
|
|
643
|
+
}
|
|
626
644
|
}
|
|
627
645
|
*pushNewline() {
|
|
628
646
|
const ch = this.buffer[this.pos];
|