goldstein 5.17.0 → 5.19.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 CHANGED
@@ -1,3 +1,17 @@
1
+ 2024.10.27, v5.19.0
2
+
3
+ feature:
4
+ - 76cb57d goldstein: @putout/printer v10.0.1
5
+ - ee20f4e goldstein: estree-to-babel v10.0.0
6
+ - ebd230e goldstein: esbuild v0.24.0
7
+
8
+ 2024.09.06, v5.18.0
9
+
10
+ feature:
11
+ - 641db76 goldstein: eslint-plugin-putout v23.1.0
12
+ - 84be18f goldstein: @putout/plugin-try-catch v4.0.0
13
+ - b2b030b goldstein: add support of safe assignment operator (https://github.com/arthurfiorette/proposal-safe-assignment-operator/issues/41)
14
+
1
15
  2024.07.27, v5.17.0
2
16
 
3
17
  feature:
package/README.md CHANGED
@@ -299,6 +299,36 @@ import tryToCatch from 'try-catch';
299
299
  const [error, result] = await tryToCatch(hello, 'world');
300
300
  ```
301
301
 
302
+ ### [`operator-safe-assignment`](https://github.com/arthurfiorette/proposal-safe-assignment-operator)
303
+
304
+ You can use `?=` instead of [`try`](#try):
305
+
306
+ ```gs
307
+ const [error, result] ?= hello('world');
308
+ ```
309
+
310
+ Is the same as:
311
+
312
+ ```js
313
+ import tryCatch from 'try-catch';
314
+
315
+ const [error, result] = tryCatch(hello, 'world');
316
+ ```
317
+
318
+ and
319
+
320
+ ```gs
321
+ const [error, result] ?= await hello('world');
322
+ ```
323
+
324
+ Is the same as:
325
+
326
+ ```js
327
+ import tryToCatch from 'try-catch';
328
+
329
+ const [error, result] = await tryToCatch(hello, 'world');
330
+ ```
331
+
302
332
  ### `should`
303
333
 
304
334
  `should` can be used as an expression (just like [`try`](https://github.com/coderaiser/goldstein/edit/master/README.md#try)).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "goldstein",
3
- "version": "5.17.0",
3
+ "version": "5.19.0",
4
4
  "type": "module",
5
5
  "author": "coderaiser <mnemonic.enemy@gmail.com> (https://github.com/coderaiser)",
6
6
  "description": "JavaScript with no limits",
@@ -12,7 +12,7 @@
12
12
  },
13
13
  "repository": {
14
14
  "type": "git",
15
- "url": "git://github.com/coderaiser/goldstein.git"
15
+ "url": "git+https://github.com/coderaiser/goldstein.git"
16
16
  },
17
17
  "keywords": [
18
18
  "JavaScript",
@@ -29,11 +29,11 @@
29
29
  "dependencies": {
30
30
  "@putout/plugin-declare": "^4.0.0",
31
31
  "@putout/plugin-logical-expressions": "^6.0.0",
32
- "@putout/plugin-try-catch": "^3.0.0",
33
- "@putout/printer": "^9.0.1",
32
+ "@putout/plugin-try-catch": "^4.0.0",
33
+ "@putout/printer": "^10.0.1",
34
34
  "acorn": "^8.7.1",
35
35
  "acorn-typescript": "^1.4.13",
36
- "estree-to-babel": "^9.0.0",
36
+ "estree-to-babel": "^10.0.0",
37
37
  "estree-util-attach-comments": "^3.0.0",
38
38
  "putout": "^36.0.3",
39
39
  "try-catch": "^3.0.1"
@@ -46,10 +46,10 @@
46
46
  "@putout/test": "^11.0.0",
47
47
  "c8": "^10.0.0",
48
48
  "check-dts": "^0.8.0",
49
- "esbuild": "^0.23.0",
49
+ "esbuild": "^0.24.0",
50
50
  "esbuild-node-builtins": "^0.1.0",
51
51
  "eslint": "^9.2.0",
52
- "eslint-plugin-putout": "^22.0.0",
52
+ "eslint-plugin-putout": "^23.1.0",
53
53
  "madrun": "^10.0.0",
54
54
  "mock-require": "^3.0.3",
55
55
  "montag": "^1.2.1",
@@ -19,6 +19,7 @@ import keywordUselessComma from '../keyword-useless-comma/index.js';
19
19
  import keywordUselessSemicolon from '../keyword-useless-semicolon/index.js';
20
20
  import keywordAssignFrom from '../keyword-assign-from/index.js';
21
21
  import internalParseMaybeAssign from '../internal-parse-maybe-assign/index.js';
22
+ import operatorSafeAssignment from '../operator-safe-assignment/index.js';
22
23
 
23
24
  const {values} = Object;
24
25
 
@@ -40,6 +41,7 @@ const defaultKeywords = {
40
41
  keywordUselessComma,
41
42
  keywordUselessSemicolon,
42
43
  keywordAssignFrom,
44
+ operatorSafeAssignment,
43
45
  };
44
46
 
45
47
  const internals = [
@@ -9,14 +9,21 @@ export default function keywordMissingInitializer(Parser) {
9
9
  const decl = this.startNode();
10
10
  this.parseVarId(decl, kind);
11
11
 
12
- if (this.eat(tt.eq))
12
+ /* c8 ignore start */
13
+ if (this.eat(tt.question) && this.eat(tt.eq)) {
14
+ if (!this.parseSafeAssignment)
15
+ this.raise(this.lastTokEnd, `Enable 'operator-safe-assignment' to have ability to use '?='`);
16
+
17
+ decl.init = this.parseSafeAssignment(); /* c8 ignore start */
18
+ } else if (this.eat(tt.eq)) {
13
19
  decl.init = this.parseMaybeAssign(isFor);
14
- else if (!allowMissingInitializer && kind === 'const' && !(this.type === tt._in || this.options.ecmaVersion >= 6 && this.isContextual('of')))
15
- decl.init = this.parseMaybeAssign(isFor); /* c8 ignore start */
16
- else if (!allowMissingInitializer && decl.id.type !== 'Identifier' && !(isFor && (this.type === tt._in || this.isContextual('of'))))
20
+ } else if (!allowMissingInitializer && kind === 'const' && !(this.type === tt._in || this.options.ecmaVersion >= 6 && this.isContextual('of'))) {
21
+ decl.init = MissingInitializer.missInitializer.call(this, isFor);
22
+ } else if (!allowMissingInitializer && decl.id.type !== 'Identifier' && !(isFor && (this.type === tt._in || this.isContextual('of')))) {
17
23
  this.raise(this.lastTokEnd, 'Complex binding patterns require an initialization value');
18
- else
24
+ } else {
19
25
  decl.init = null;
26
+ }
20
27
 
21
28
  /* c8 ignore end */
22
29
  node.declarations.push(this.finishNode(decl, 'VariableDeclarator'));
@@ -29,3 +36,9 @@ export default function keywordMissingInitializer(Parser) {
29
36
  }
30
37
  };
31
38
  }
39
+
40
+ export const MissingInitializer = {
41
+ missInitializer(isFor) {
42
+ return this.parseMaybeAssign(isFor);
43
+ },
44
+ };
@@ -0,0 +1,81 @@
1
+ import {types} from 'putout';
2
+ import {setGoldsteinTry} from '../types/try.js';
3
+ import {MissingInitializer} from '../keyword-missing-initializer/index.js';
4
+ import {tokTypes as tt} from '../operator/index.js';
5
+
6
+ const {assign} = Object;
7
+
8
+ const {
9
+ isCallExpression,
10
+ isAwaitExpression,
11
+ } = types;
12
+
13
+ export default function operatorSafeAssignment(Parser) {
14
+ return class extends Parser {
15
+ parseVar(node, isFor, kind, allowMissingInitializer) {
16
+ node.declarations = [];
17
+ node.kind = kind;
18
+ for (;;) {
19
+ const decl = this.startNode();
20
+ this.parseVarId(decl, kind);
21
+
22
+ if (this.eat(tt.question) && this.eat(tt.eq))
23
+ decl.init = this.parseSafeAssignment(); /* c8 ignore start */
24
+ else if (this.eat(tt.eq))
25
+ decl.init = this.parseMaybeAssign(isFor);
26
+ else if (!allowMissingInitializer && kind === 'const' && !(this.type === tt._in || this.options.ecmaVersion >= 6 && this.isContextual('of')))
27
+ decl.init = MissingInitializer.missInitializer.call(this, isFor);
28
+ else if (!allowMissingInitializer && decl.id.type !== 'Identifier' && !(isFor && (this.type === tt._in || this.isContextual('of'))))
29
+ this.raise(this.lastTokEnd, 'Complex binding patterns require an initialization value');
30
+ else
31
+ decl.init = null;
32
+
33
+ /* c8 ignore end */
34
+ node.declarations.push(this.finishNode(decl, 'VariableDeclarator'));
35
+
36
+ if (!this.eat(tt.comma))
37
+ break;
38
+ }
39
+
40
+ return node;
41
+ }
42
+
43
+ parseSafeAssignment() {
44
+ const node = super.startNode();
45
+ const expression = this.parseExpression();
46
+
47
+ if (isCallExpression(expression))
48
+ assign(node, {
49
+ type: 'CallExpression',
50
+ callee: {
51
+ type: 'Identifier',
52
+ name: 'tryCatch',
53
+ },
54
+ arguments: [
55
+ expression.callee,
56
+ ...expression.arguments,
57
+ ],
58
+ });
59
+ else if (isAwaitExpression(expression))
60
+ assign(node, {
61
+ type: 'AwaitExpression',
62
+ argument: {
63
+ type: 'CallExpression',
64
+ callee: {
65
+ type: 'Identifier',
66
+ name: 'tryToCatch',
67
+ },
68
+ arguments: [
69
+ expression.argument.callee,
70
+ ...expression.argument.arguments,
71
+ ],
72
+ },
73
+ });
74
+ else
75
+ this.raise(this.start, `After '?=' only 'await' and 'function call' can come`);
76
+
77
+ setGoldsteinTry(node);
78
+ return super.finishNode(node, node.type);
79
+ }
80
+ };
81
+ }
@@ -1,10 +1,13 @@
1
- import {visitors as v} from '@putout/printer';
1
+ import {
2
+ maybeVisitor,
3
+ visitors as v,
4
+ } from '@putout/printer';
2
5
 
3
6
  export const CallExpression = (path, printer, semantics) => {
4
7
  const {print} = printer;
5
8
 
6
9
  if (!path.node.goldstein)
7
- return v.CallExpression(path, printer, semantics);
10
+ return maybeVisitor(v.CallExpression, path, printer, semantics);
8
11
 
9
- print('__goldstein');
12
+ return print('__goldstein');
10
13
  };