goldstein 4.7.0 → 4.9.0
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/ChangeLog +10 -0
- package/README.md +26 -6
- package/build/parser.cjs +99 -0
- package/package.json +1 -1
- package/packages/convert/add-array/index.js +4 -0
- package/packages/convert/index.js +2 -0
- package/packages/goldstein/parser.js +2 -0
- package/packages/keyword-add-array/index.js +121 -0
- package/packages/operator/index.js +7 -0
package/ChangeLog
CHANGED
package/README.md
CHANGED
|
@@ -165,7 +165,7 @@ parse(`
|
|
|
165
165
|
|
|
166
166
|
You can parse to **ESTree**:
|
|
167
167
|
|
|
168
|
-
```
|
|
168
|
+
```js
|
|
169
169
|
const options = {
|
|
170
170
|
type: 'estree',
|
|
171
171
|
};
|
|
@@ -184,8 +184,11 @@ parse(`
|
|
|
184
184
|
|
|
185
185
|
You can make any modifications to **Goldstein AST** and then `print` back to **Goldstein**:
|
|
186
186
|
|
|
187
|
-
```
|
|
188
|
-
import {
|
|
187
|
+
```js
|
|
188
|
+
import {
|
|
189
|
+
parse,
|
|
190
|
+
print,
|
|
191
|
+
} from 'goldstein';
|
|
189
192
|
|
|
190
193
|
const ast = parse(`const t = try f('hello')`);
|
|
191
194
|
const source = print(ast);
|
|
@@ -195,13 +198,13 @@ const source = print(ast);
|
|
|
195
198
|
|
|
196
199
|
You can even convert **JavaScript** to **Goldstein** with:
|
|
197
200
|
|
|
198
|
-
```
|
|
201
|
+
```js
|
|
199
202
|
import {convert} from 'goldstein';
|
|
200
203
|
|
|
201
|
-
const ast = convert(`const t = tryCatch(f, 'hello')
|
|
204
|
+
const ast = convert(`const t = tryCatch(f, 'hello')`);
|
|
202
205
|
|
|
203
206
|
// returns
|
|
204
|
-
`const t = try f('hello')
|
|
207
|
+
`const t = try f('hello')`;
|
|
205
208
|
```
|
|
206
209
|
|
|
207
210
|
## Keywords
|
|
@@ -227,6 +230,23 @@ function hello() {
|
|
|
227
230
|
}
|
|
228
231
|
```
|
|
229
232
|
|
|
233
|
+
### `append array`
|
|
234
|
+
|
|
235
|
+
Append new elements to an array just like in Swift:
|
|
236
|
+
|
|
237
|
+
```js
|
|
238
|
+
let a = [1];
|
|
239
|
+
|
|
240
|
+
a += [2, 3];
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Is the same as:
|
|
244
|
+
|
|
245
|
+
```js
|
|
246
|
+
const a = [1];
|
|
247
|
+
a.push(...[2, 3]);
|
|
248
|
+
```
|
|
249
|
+
|
|
230
250
|
### `guard`
|
|
231
251
|
|
|
232
252
|
Applies not to `IfCondition`:
|
package/build/parser.cjs
CHANGED
|
@@ -5410,6 +5410,13 @@ function addKeyword(keyword, keywords3) {
|
|
|
5410
5410
|
const str = keywords3.toString().replace(")$", `|${keyword})$`).slice(1, -1);
|
|
5411
5411
|
return RegExp(str);
|
|
5412
5412
|
}
|
|
5413
|
+
var DestructuringErrors3 = class {
|
|
5414
|
+
shorthandAssign = -1;
|
|
5415
|
+
trailingComma = -1;
|
|
5416
|
+
parenthesizedAssign = -1;
|
|
5417
|
+
parenthesizedBind = -1;
|
|
5418
|
+
doubleProto = -1;
|
|
5419
|
+
};
|
|
5413
5420
|
|
|
5414
5421
|
// packages/keyword-fn/index.js
|
|
5415
5422
|
function fn(Parser3) {
|
|
@@ -5902,6 +5909,97 @@ function fn3(Parser3) {
|
|
|
5902
5909
|
};
|
|
5903
5910
|
}
|
|
5904
5911
|
|
|
5912
|
+
// packages/keyword-add-array/index.js
|
|
5913
|
+
var import_putout7 = require("putout");
|
|
5914
|
+
var { assign: assign3 } = Object;
|
|
5915
|
+
var {
|
|
5916
|
+
identifier,
|
|
5917
|
+
isArrayExpression: isArrayExpression2,
|
|
5918
|
+
memberExpression,
|
|
5919
|
+
spreadElement
|
|
5920
|
+
} = import_putout7.types;
|
|
5921
|
+
function keywordAddArray(Parser3) {
|
|
5922
|
+
return class extends Parser3 {
|
|
5923
|
+
parseMaybeAssign(forInit, refDestructuringErrors, afterLeftParse) {
|
|
5924
|
+
if (this.isContextual("yield")) {
|
|
5925
|
+
if (this.inGenerator) {
|
|
5926
|
+
return this.parseYield(forInit);
|
|
5927
|
+
}
|
|
5928
|
+
this.exprAllowed = false;
|
|
5929
|
+
}
|
|
5930
|
+
let ownDestructuringErrors = false;
|
|
5931
|
+
let oldParenAssign = -1;
|
|
5932
|
+
let oldTrailingComma = -1;
|
|
5933
|
+
let oldDoubleProto = -1;
|
|
5934
|
+
if (refDestructuringErrors) {
|
|
5935
|
+
oldParenAssign = refDestructuringErrors.parenthesizedAssign;
|
|
5936
|
+
oldTrailingComma = refDestructuringErrors.trailingComma;
|
|
5937
|
+
oldDoubleProto = refDestructuringErrors.doubleProto;
|
|
5938
|
+
refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = -1;
|
|
5939
|
+
} else {
|
|
5940
|
+
refDestructuringErrors = new DestructuringErrors3();
|
|
5941
|
+
ownDestructuringErrors = true;
|
|
5942
|
+
}
|
|
5943
|
+
const startPos = this.start;
|
|
5944
|
+
const { startLoc } = this;
|
|
5945
|
+
if (this.type === types$1.parenL || this.type === types$1.name) {
|
|
5946
|
+
this.potentialArrowAt = this.start;
|
|
5947
|
+
this.potentialArrowInForAwait = forInit === "await";
|
|
5948
|
+
}
|
|
5949
|
+
let left = this.parseMaybeConditional(forInit, refDestructuringErrors);
|
|
5950
|
+
if (afterLeftParse) {
|
|
5951
|
+
left = afterLeftParse.call(this, left, startPos, startLoc);
|
|
5952
|
+
}
|
|
5953
|
+
if (this.type.isAssign) {
|
|
5954
|
+
const node = this.startNodeAt(startPos, startLoc);
|
|
5955
|
+
node.operator = this.value;
|
|
5956
|
+
if (this.type === types$1.eq) {
|
|
5957
|
+
left = this.toAssignable(left, false, refDestructuringErrors);
|
|
5958
|
+
}
|
|
5959
|
+
if (!ownDestructuringErrors) {
|
|
5960
|
+
refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = refDestructuringErrors.doubleProto = -1;
|
|
5961
|
+
}
|
|
5962
|
+
if (refDestructuringErrors.shorthandAssign >= left.start) {
|
|
5963
|
+
refDestructuringErrors.shorthandAssign = -1;
|
|
5964
|
+
}
|
|
5965
|
+
if (this.type === types$1.eq) {
|
|
5966
|
+
this.checkLValPattern(left);
|
|
5967
|
+
} else {
|
|
5968
|
+
this.checkLValSimple(left);
|
|
5969
|
+
}
|
|
5970
|
+
node.left = left;
|
|
5971
|
+
this.next();
|
|
5972
|
+
node.right = this.parseMaybeAssign(forInit);
|
|
5973
|
+
if (oldDoubleProto > -1) {
|
|
5974
|
+
refDestructuringErrors.doubleProto = oldDoubleProto;
|
|
5975
|
+
}
|
|
5976
|
+
if (node.operator === "+=" && isArrayExpression2(node.right))
|
|
5977
|
+
return createAppendNode(this, node);
|
|
5978
|
+
return this.finishNode(node, "AssignmentExpression");
|
|
5979
|
+
}
|
|
5980
|
+
if (ownDestructuringErrors) {
|
|
5981
|
+
this.checkExpressionErrors(refDestructuringErrors, true);
|
|
5982
|
+
}
|
|
5983
|
+
if (oldParenAssign > -1) {
|
|
5984
|
+
refDestructuringErrors.parenthesizedAssign = oldParenAssign;
|
|
5985
|
+
}
|
|
5986
|
+
if (oldTrailingComma > -1) {
|
|
5987
|
+
refDestructuringErrors.trailingComma = oldTrailingComma;
|
|
5988
|
+
}
|
|
5989
|
+
return left;
|
|
5990
|
+
}
|
|
5991
|
+
};
|
|
5992
|
+
}
|
|
5993
|
+
function createAppendNode(context, node) {
|
|
5994
|
+
const { left, right } = node;
|
|
5995
|
+
assign3(node, {
|
|
5996
|
+
a: "x",
|
|
5997
|
+
callee: memberExpression(left, identifier("push")),
|
|
5998
|
+
arguments: [spreadElement(right)]
|
|
5999
|
+
});
|
|
6000
|
+
return context.finishNode(node, "CallExpression");
|
|
6001
|
+
}
|
|
6002
|
+
|
|
5905
6003
|
// packages/goldstein/parser.js
|
|
5906
6004
|
var defaultKeywords = {
|
|
5907
6005
|
keywordFn: fn,
|
|
@@ -5914,6 +6012,7 @@ var defaultKeywords = {
|
|
|
5914
6012
|
keywordIf: fn2,
|
|
5915
6013
|
keywordImport,
|
|
5916
6014
|
keywordArrow: fn3,
|
|
6015
|
+
keywordAddArray,
|
|
5917
6016
|
stringInterpolation
|
|
5918
6017
|
};
|
|
5919
6018
|
var keywords2 = defaultKeywords;
|
package/package.json
CHANGED
|
@@ -3,6 +3,7 @@ import {transform} from 'putout';
|
|
|
3
3
|
import {print} from '../printer/index.js';
|
|
4
4
|
import * as removeImportTry from './remove-import-try/index.js';
|
|
5
5
|
import * as applyTry from './apply-try/index.js';
|
|
6
|
+
import * as addArray from './add-array/index.js';
|
|
6
7
|
import {
|
|
7
8
|
fixEmpty,
|
|
8
9
|
parse,
|
|
@@ -13,6 +14,7 @@ export const convert = (source) => {
|
|
|
13
14
|
|
|
14
15
|
transform(ast, source, {
|
|
15
16
|
plugins: [
|
|
17
|
+
['add-array', addArray],
|
|
16
18
|
['apply-try', applyTry],
|
|
17
19
|
['remove-import-try', removeImportTry],
|
|
18
20
|
],
|
|
@@ -11,6 +11,7 @@ import keywordFreeze from '../keyword-freeze/index.js';
|
|
|
11
11
|
import keywordIf from '../keyword-if/index.js';
|
|
12
12
|
import keywordImport from '../keyword-import/index.js';
|
|
13
13
|
import keywordArrow from '../keyword-arrow/index.js';
|
|
14
|
+
import keywordAddArray from '../keyword-add-array/index.js';
|
|
14
15
|
|
|
15
16
|
const defaultKeywords = {
|
|
16
17
|
keywordFn,
|
|
@@ -23,6 +24,7 @@ const defaultKeywords = {
|
|
|
23
24
|
keywordIf,
|
|
24
25
|
keywordImport,
|
|
25
26
|
keywordArrow,
|
|
27
|
+
keywordAddArray,
|
|
26
28
|
stringInterpolation,
|
|
27
29
|
};
|
|
28
30
|
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import {types} from 'putout';
|
|
2
|
+
import {tokTypes as tt} from 'acorn';
|
|
3
|
+
import {DestructuringErrors} from '../operator/index.js';
|
|
4
|
+
|
|
5
|
+
const {assign} = Object;
|
|
6
|
+
|
|
7
|
+
const {
|
|
8
|
+
identifier,
|
|
9
|
+
isArrayExpression,
|
|
10
|
+
memberExpression,
|
|
11
|
+
spreadElement,
|
|
12
|
+
} = types;
|
|
13
|
+
|
|
14
|
+
export default function keywordAddArray(Parser) {
|
|
15
|
+
return class extends Parser {
|
|
16
|
+
parseMaybeAssign(forInit, refDestructuringErrors, afterLeftParse) {
|
|
17
|
+
if (this.isContextual('yield')) {
|
|
18
|
+
if (this.inGenerator) {
|
|
19
|
+
return this.parseYield(forInit);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// The tokenizer will assume an expression is allowed after
|
|
23
|
+
// `yield`, but this isn't that kind of yield
|
|
24
|
+
this.exprAllowed = false;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let ownDestructuringErrors = false;
|
|
28
|
+
let oldParenAssign = -1;
|
|
29
|
+
let oldTrailingComma = -1;
|
|
30
|
+
let oldDoubleProto = -1;
|
|
31
|
+
|
|
32
|
+
if (refDestructuringErrors) {
|
|
33
|
+
oldParenAssign = refDestructuringErrors.parenthesizedAssign;
|
|
34
|
+
oldTrailingComma = refDestructuringErrors.trailingComma;
|
|
35
|
+
oldDoubleProto = refDestructuringErrors.doubleProto;
|
|
36
|
+
refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = -1;
|
|
37
|
+
} else {
|
|
38
|
+
refDestructuringErrors = new DestructuringErrors();
|
|
39
|
+
ownDestructuringErrors = true;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const startPos = this.start;
|
|
43
|
+
const {startLoc} = this;
|
|
44
|
+
|
|
45
|
+
if (this.type === tt.parenL || this.type === tt.name) {
|
|
46
|
+
this.potentialArrowAt = this.start;
|
|
47
|
+
this.potentialArrowInForAwait = forInit === 'await';
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let left = this.parseMaybeConditional(forInit, refDestructuringErrors);
|
|
51
|
+
|
|
52
|
+
if (afterLeftParse) {
|
|
53
|
+
left = afterLeftParse.call(this, left, startPos, startLoc);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (this.type.isAssign) {
|
|
57
|
+
const node = this.startNodeAt(startPos, startLoc);
|
|
58
|
+
|
|
59
|
+
node.operator = this.value;
|
|
60
|
+
|
|
61
|
+
if (this.type === tt.eq) {
|
|
62
|
+
left = this.toAssignable(left, false, refDestructuringErrors);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (!ownDestructuringErrors) {
|
|
66
|
+
refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = refDestructuringErrors.doubleProto = -1;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (refDestructuringErrors.shorthandAssign >= left.start) {
|
|
70
|
+
refDestructuringErrors.shorthandAssign = -1;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// reset because shorthand default was used correctly
|
|
74
|
+
if (this.type === tt.eq) {
|
|
75
|
+
this.checkLValPattern(left);
|
|
76
|
+
} else {
|
|
77
|
+
this.checkLValSimple(left);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
node.left = left;
|
|
81
|
+
this.next();
|
|
82
|
+
node.right = this.parseMaybeAssign(forInit);
|
|
83
|
+
|
|
84
|
+
if (oldDoubleProto > -1) {
|
|
85
|
+
refDestructuringErrors.doubleProto = oldDoubleProto;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (node.operator === '+=' && isArrayExpression(node.right))
|
|
89
|
+
return createAppendNode(this, node);
|
|
90
|
+
|
|
91
|
+
return this.finishNode(node, 'AssignmentExpression');
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (ownDestructuringErrors) {
|
|
95
|
+
this.checkExpressionErrors(refDestructuringErrors, true);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (oldParenAssign > -1) {
|
|
99
|
+
refDestructuringErrors.parenthesizedAssign = oldParenAssign;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (oldTrailingComma > -1) {
|
|
103
|
+
refDestructuringErrors.trailingComma = oldTrailingComma;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return left;
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function createAppendNode(context, node) {
|
|
112
|
+
const {left, right} = node;
|
|
113
|
+
|
|
114
|
+
assign(node, {
|
|
115
|
+
a: 'x',
|
|
116
|
+
callee: memberExpression(left, identifier('push')),
|
|
117
|
+
arguments: [spreadElement(right)],
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
return context.finishNode(node, 'CallExpression');
|
|
121
|
+
}
|