goldstein 4.9.1 → 4.11.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,13 @@
1
+ 2023.10.19, v4.11.0
2
+
3
+ feature:
4
+ - 005959d goldstein: convert: if let
5
+
6
+ 2023.10.19, v4.10.0
7
+
8
+ feature:
9
+ - 0b4756a goldstein: add if let
10
+
1
11
  2023.10.19, v4.9.1
2
12
 
3
13
  fix:
package/README.md CHANGED
@@ -344,12 +344,20 @@ Object.freeze({
344
344
 
345
345
  You can omit parens. But you must use braces in this case.
346
346
 
347
- ```rust
347
+ ```swift
348
348
  if a > 3 {
349
349
  hello();
350
350
  }
351
351
  ```
352
352
 
353
+ Also you can use `if let` syntax:
354
+
355
+ ```swift
356
+ if let x = a?.b {
357
+ print(x);
358
+ }
359
+ ```
360
+
353
361
  ### `throw expression`
354
362
 
355
363
  You can use [throw as expression](https://github.com/tc39/proposal-throw-expressions), just like that:
package/build/parser.cjs CHANGED
@@ -5837,22 +5837,71 @@ var setGoldsteinIf = (node) => {
5837
5837
  // packages/keyword-if/index.js
5838
5838
  function fn2(Parser3) {
5839
5839
  return class extends Parser3 {
5840
- parseIfStatement(node) {
5840
+ parseIfStatement() {
5841
5841
  this.next();
5842
5842
  const isParenL = this.eat(types$1.parenL);
5843
- node.test = this.parseExpression();
5844
- const isParenR = this.eat(types$1.parenR);
5845
- if (!isParenL && !isParenR && this.type !== types$1.braceL)
5846
- this.raise(this.start, `Use braces ('{', '}') when omit parens ('(', ')')`);
5847
- if (isParenL !== isParenR)
5848
- this.raise(this.start, `Use both parens ('(', ')') or none`);
5849
- node.consequent = this.parseStatement("if");
5850
- node.alternate = this.eat(types$1._else) ? this.parseStatement("if") : null;
5851
- setGoldsteinIf(node);
5852
- return this.finishNode(node, "IfStatement");
5843
+ if (this.isContextual("let"))
5844
+ return createIfLet.call(this, {
5845
+ isParenL
5846
+ });
5847
+ const test = this.parseExpression();
5848
+ return createIf.call(this, {
5849
+ test,
5850
+ isParenL
5851
+ });
5853
5852
  }
5854
5853
  };
5855
5854
  }
5855
+ function check({ isParenL, isParenR }) {
5856
+ if (!isParenL && !isParenR && this.type !== types$1.braceL)
5857
+ this.raise(this.start, `Use braces ('{', '}') when omit parens ('(', ')')`);
5858
+ if (isParenL !== isParenR)
5859
+ this.raise(this.start, `Use both parens ('(', ')') or none`);
5860
+ }
5861
+ function createIfLet({ isParenL }) {
5862
+ this.next();
5863
+ this.eat(types$1.assign);
5864
+ const assignmentExpression = this.parseExpression();
5865
+ const isParenR = this.eat(types$1.parenR);
5866
+ check.call(this, {
5867
+ isParenL,
5868
+ isParenR
5869
+ });
5870
+ const ifNode = createIf.call(this, {
5871
+ test: assignmentExpression.left,
5872
+ isParenL
5873
+ });
5874
+ const node = {
5875
+ loc: {},
5876
+ range: [],
5877
+ body: [{
5878
+ type: "VariableDeclaration",
5879
+ kind: "let",
5880
+ declarations: [{
5881
+ type: "VariableDeclarator",
5882
+ id: assignmentExpression.left,
5883
+ init: assignmentExpression.right
5884
+ }]
5885
+ }, ifNode]
5886
+ };
5887
+ return this.finishNode(node, "BlockStatement");
5888
+ }
5889
+ function createIf({ test, isParenL }) {
5890
+ const node = {
5891
+ test
5892
+ };
5893
+ const isParenR = this.eat(types$1.parenR);
5894
+ check.call(this, {
5895
+ isParenL,
5896
+ isParenR
5897
+ });
5898
+ node.consequent = this.parseStatement("if");
5899
+ node.alternate = this.eat(types$1._else) ? this.parseStatement("if") : null;
5900
+ node.loc = {};
5901
+ node.range = [];
5902
+ setGoldsteinIf(node);
5903
+ return this.finishNode(node, "IfStatement");
5904
+ }
5856
5905
 
5857
5906
  // packages/keyword-import/index.js
5858
5907
  var empty2 = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "goldstein",
3
- "version": "4.9.1",
3
+ "version": "4.11.0",
4
4
  "type": "module",
5
5
  "author": "coderaiser <mnemonic.enemy@gmail.com> (https://github.com/coderaiser)",
6
6
  "description": "JavaScript with no limits",
@@ -0,0 +1,18 @@
1
+ import {types} from 'putout';
2
+ const {
3
+ VariableDeclaration,
4
+ VariableDeclarator,
5
+ } = types;
6
+
7
+ export const report = () => `Use 'add-array'`;
8
+ export const replace = () => ({
9
+ '{let __a = __b; if (__c) __d}': ({__a, __b}, path) => {
10
+ const ifPath = path.get('body.1');
11
+ ifPath.node.test = VariableDeclaration('let', [
12
+ VariableDeclarator(__a, __b),
13
+ ]);
14
+
15
+ return ifPath;
16
+ },
17
+ });
18
+
@@ -4,6 +4,7 @@ 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
6
  import * as addArray from './add-array/index.js';
7
+ import * as applyIfLet from './apply-if-let/index.js';
7
8
  import {
8
9
  fixEmpty,
9
10
  parse,
@@ -15,6 +16,7 @@ export const convert = (source) => {
15
16
  transform(ast, source, {
16
17
  plugins: [
17
18
  ['add-array', addArray],
19
+ ['apply-if-let', applyIfLet],
18
20
  ['apply-try', applyTry],
19
21
  ['remove-import-try', removeImportTry],
20
22
  ],
@@ -3,27 +3,85 @@ import {setGoldsteinIf} from '../types/if.js';
3
3
 
4
4
  export default function fn(Parser) {
5
5
  return class extends Parser {
6
- parseIfStatement(node) {
6
+ parseIfStatement() {
7
7
  this.next();
8
-
9
8
  const isParenL = this.eat(tt.parenL);
10
9
 
11
- node.test = this.parseExpression();
12
- const isParenR = this.eat(tt.parenR);
13
-
14
- if (!isParenL && !isParenR && this.type !== tt.braceL)
15
- this.raise(this.start, `Use braces ('{', '}') when omit parens ('(', ')')`);
16
-
17
- if (isParenL !== isParenR)
18
- this.raise(this.start, `Use both parens ('(', ')') or none`);
10
+ if (this.isContextual('let'))
11
+ return createIfLet.call(this, {
12
+ isParenL,
13
+ });
19
14
 
20
- node.consequent = this.parseStatement('if');
21
- node.alternate = this.eat(tt._else) ? this.parseStatement('if') : null;
15
+ const test = this.parseExpression();
22
16
 
23
- setGoldsteinIf(node);
24
-
25
- return this.finishNode(node, 'IfStatement');
17
+ return createIf.call(this, {
18
+ test,
19
+ isParenL,
20
+ });
26
21
  }
27
22
  };
28
23
  }
29
24
 
25
+ function check({isParenL, isParenR}) {
26
+ if (!isParenL && !isParenR && this.type !== tt.braceL)
27
+ this.raise(this.start, `Use braces ('{', '}') when omit parens ('(', ')')`);
28
+
29
+ if (isParenL !== isParenR)
30
+ this.raise(this.start, `Use both parens ('(', ')') or none`);
31
+ }
32
+
33
+ function createIfLet({isParenL}) {
34
+ this.next();
35
+ this.eat(tt.assign);
36
+
37
+ const assignmentExpression = this.parseExpression();
38
+ const isParenR = this.eat(tt.parenR);
39
+
40
+ check.call(this, {
41
+ isParenL,
42
+ isParenR,
43
+ });
44
+
45
+ const ifNode = createIf.call(this, {
46
+ test: assignmentExpression.left,
47
+ isParenL,
48
+ });
49
+
50
+ const node = {
51
+ loc: {},
52
+ range: [],
53
+ body: [{
54
+ type: 'VariableDeclaration',
55
+ kind: 'let',
56
+ declarations: [{
57
+ type: 'VariableDeclarator',
58
+ id: assignmentExpression.left,
59
+ init: assignmentExpression.right,
60
+ }],
61
+ }, ifNode],
62
+ };
63
+
64
+ return this.finishNode(node, 'BlockStatement');
65
+ }
66
+
67
+ function createIf({test, isParenL}) {
68
+ const node = {
69
+ test,
70
+ };
71
+
72
+ const isParenR = this.eat(tt.parenR);
73
+
74
+ check.call(this, {
75
+ isParenL,
76
+ isParenR,
77
+ });
78
+
79
+ node.consequent = this.parseStatement('if');
80
+ node.alternate = this.eat(tt._else) ? this.parseStatement('if') : null;
81
+ node.loc = {};
82
+ node.range = [];
83
+
84
+ setGoldsteinIf(node);
85
+
86
+ return this.finishNode(node, 'IfStatement');
87
+ }
@@ -1,12 +1,13 @@
1
1
  import {visitors as v} from '@putout/printer';
2
2
 
3
3
  export const IfStatement = (path, printer, semantics) => {
4
- const {print} = printer;
4
+ const {print, indent} = printer;
5
5
  const {node} = path;
6
6
 
7
7
  if (!node.goldsteinIf)
8
8
  return v.IfStatement(path, printer, semantics);
9
9
 
10
+ indent();
10
11
  print('if ');
11
12
  print('__test');
12
13
  print(' ');