goldstein 5.10.0 → 5.12.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
+ 2024.05.30, v5.12.0
2
+
3
+ feature:
4
+ - ade2799 goldstein: useless comma
5
+
6
+ 2024.05.28, v5.11.0
7
+
8
+ feature:
9
+ - c84aaa4 goldstein: add support of jsx/typescript
10
+
1
11
  2024.05.27, v5.10.0
2
12
 
3
13
  feature:
package/README.md CHANGED
@@ -15,8 +15,7 @@
15
15
  >
16
16
  > *(c) “1984”, George Orwell*
17
17
 
18
- JavaScript with no limits 🤫.
19
-
18
+ JavaScript with no limits 🤫 with built-in JSX and TypeScript.
20
19
  Language ruled by the users, [create an issue](https://github.com/coderaiser/goldstein/issues/new/choose) with ideas of a new language construction and what is look like in JavaScript, and most likely we implement it :).
21
20
 
22
21
  ## Install
@@ -382,7 +381,7 @@ When you import `.gs` files during compile step it will be replaced with `.js`:
382
381
  // hello.js
383
382
  export const hello = () => 'world';
384
383
 
385
- // index.js
384
+ // index.js1
386
385
  import hello from './hello.gs';
387
386
  ```
388
387
 
@@ -440,16 +439,27 @@ const b = 'world';
440
439
 
441
440
  Forget to add assignment (`=`), not problem!
442
441
 
443
- ```gs
442
+ ```diff
444
443
  -const {code, places} await samadhi(source);
445
444
  +const {code, places} = await samadhi(source);
446
445
  ```
447
446
 
447
+ ### Useless comma
448
+
449
+ Added useless comma (`,`)? no problem!
450
+
451
+ ```diff
452
+ const a = {
453
+ - b,,
454
+ + b,
455
+ }
456
+ ```
457
+
448
458
  ## How to contribute?
449
459
 
450
460
  Clone the registry, create a new keyword with a prefix `keyword-`, then create directory `fixture` and put there two files with extensions `.js` and `.gs`. Half way done 🥳!
451
461
 
452
- Then goes test and implementation in `index.js` and `index.spec.js` accordingly. Use scripts:
462
+ Then goes test and implementation in `index.js1` and `index.spec.js` accordingly. Use scripts:
453
463
 
454
464
  - `npm test`
455
465
  - `UPDATE=1 npm test` - update `fixtures`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "goldstein",
3
- "version": "5.10.0",
3
+ "version": "5.12.0",
4
4
  "type": "module",
5
5
  "author": "coderaiser <mnemonic.enemy@gmail.com> (https://github.com/coderaiser)",
6
6
  "description": "JavaScript with no limits",
@@ -32,6 +32,7 @@
32
32
  "@putout/plugin-try-catch": "^3.0.0",
33
33
  "@putout/printer": "^8.0.1",
34
34
  "acorn": "^8.7.1",
35
+ "acorn-typescript": "^1.4.13",
35
36
  "estree-to-babel": "^9.0.0",
36
37
  "estree-util-attach-comments": "^3.0.0",
37
38
  "putout": "^35.0.0",
@@ -5,9 +5,12 @@ import declarePlugin from '@putout/plugin-declare';
5
5
  import logicalExpressionsPlugin from '@putout/plugin-logical-expressions';
6
6
  import {parse} from './parser.js';
7
7
 
8
- export * from './parser.js';
9
- export {print} from '../printer/index.js';
10
8
  export {convert} from '../convert/index.js';
9
+ export {print} from '../printer/index.js';
10
+ export * from './parser.js';
11
+
12
+ import * as renameUnnamedIdentifier from '../keyword-useless-comma/rename-unnamed-identifier/index.js';
13
+
11
14
  export const compile = (source, options = {}) => {
12
15
  const ast = parse(source, options);
13
16
 
@@ -19,6 +22,7 @@ export const compile = (source, options = {}) => {
19
22
  ['try-catch', tryCatchPlugin],
20
23
  ['declare', declarePlugin],
21
24
  ['logical-expressions', logicalExpressionsPlugin],
25
+ ['remove-unnamed-identifiers', renameUnnamedIdentifier],
22
26
  ],
23
27
  });
24
28
 
@@ -28,3 +32,4 @@ export const compile = (source, options = {}) => {
28
32
  export const fixEmpty = (source) => {
29
33
  return source.replace(/;(\s+)?;/g, ';');
30
34
  };
35
+
@@ -1,4 +1,5 @@
1
1
  import estreeToBabel from 'estree-to-babel';
2
+ import typescript from 'acorn-typescript';
2
3
  import {extendParser} from '../parser/index.js';
3
4
  import keywordFn from '../keyword-fn/index.js';
4
5
  import keywordGuard from '../keyword-guard/index.js';
@@ -14,6 +15,7 @@ import keywordArrow from '../keyword-arrow/index.js';
14
15
  import keywordAddArray from '../keyword-add-array/index.js';
15
16
  import keywordBrokenString from '../keyword-broken-string/index.js';
16
17
  import keywordMissingInitializer from '../keyword-missing-initializer/index.js';
18
+ import keywordUselessComma from '../keyword-useless-comma/index.js';
17
19
 
18
20
  const {values} = Object;
19
21
 
@@ -32,6 +34,7 @@ const defaultKeywords = {
32
34
  keywordBrokenString,
33
35
  stringInterpolation,
34
36
  keywordMissingInitializer,
37
+ keywordUselessComma,
35
38
  };
36
39
 
37
40
  export const keywords = defaultKeywords;
@@ -40,7 +43,11 @@ export const parse = (source, options = {}) => {
40
43
  const keywords = options.keywords || defaultKeywords;
41
44
  const extensions = values(keywords).filter(Boolean);
42
45
 
43
- const {parse} = extendParser(extensions);
46
+ const {parse} = extendParser([
47
+ typescript(),
48
+ ...extensions,
49
+ ]);
50
+
44
51
  const ast = parse(source);
45
52
 
46
53
  if (options.type === 'estree')
@@ -34,7 +34,8 @@ export default function keywordAddArray(Parser) {
34
34
  oldParenAssign = refDestructuringErrors.parenthesizedAssign;
35
35
  oldTrailingComma = refDestructuringErrors.trailingComma;
36
36
  oldDoubleProto = refDestructuringErrors.doubleProto;
37
- refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = -1;
37
+ refDestructuringErrors.parenthesizedAssign = -1;
38
+ refDestructuringErrors.trailingComma = -1;
38
39
  } else {
39
40
  refDestructuringErrors = new DestructuringErrors();
40
41
  ownDestructuringErrors = true;
@@ -61,8 +62,11 @@ export default function keywordAddArray(Parser) {
61
62
  if (this.type === tt.eq)
62
63
  left = this.toAssignable(left, false, refDestructuringErrors);
63
64
 
64
- if (!ownDestructuringErrors)
65
- refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = refDestructuringErrors.doubleProto = -1;
65
+ if (!ownDestructuringErrors) {
66
+ refDestructuringErrors.parenthesizedAssign = -1;
67
+ refDestructuringErrors.trailingComma = -1;
68
+ refDestructuringErrors.doubleProto = -1;
69
+ }
66
70
 
67
71
  if (refDestructuringErrors.shorthandAssign >= left.start)
68
72
  refDestructuringErrors.shorthandAssign = -1;
@@ -50,6 +50,7 @@ function createIfLet({isParenL}) {
50
50
  const node = {
51
51
  loc: {},
52
52
  range: [],
53
+ type: 'BlockStatement',
53
54
  body: [{
54
55
  type: 'VariableDeclaration',
55
56
  kind: 'let',
@@ -81,6 +82,7 @@ function createIf({test, isParenL}) {
81
82
  node.alternate = this.eat(tt._else) ? this.parseStatement('if') : null;
82
83
  node.loc = {};
83
84
  node.range = [];
85
+ node.type = 'IfStatement';
84
86
 
85
87
  setGoldsteinIf(node);
86
88
 
@@ -16,10 +16,11 @@ export default function keywordImport(Parser) {
16
16
  node.specifiers = this.parseImportSpecifiers();
17
17
  this.expectContextual('from');
18
18
 
19
- if (this.type === tokTypes.string)
19
+ if (this.type === tokTypes.string) {
20
20
  node.source = this.parseLiteral(this.value);
21
- else if (this.type === tokTypes.name) {
21
+ } else if (this.type === tokTypes.name) {
22
22
  const {value} = this;
23
+
23
24
  node.source = this.parseLiteral(this.value);
24
25
  node.source.raw = `'${value}'`;
25
26
  } else {
@@ -12,8 +12,7 @@ export default function keywordMissingInitializer(Parser) {
12
12
  if (this.eat(tt.eq))
13
13
  decl.init = this.parseMaybeAssign(isFor);
14
14
  else if (!allowMissingInitializer && kind === 'const' && !(this.type === tt._in || this.options.ecmaVersion >= 6 && this.isContextual('of')))
15
- decl.init = this.parseMaybeAssign(isFor);
16
- /* c8 ignore start */
15
+ decl.init = this.parseMaybeAssign(isFor); /* c8 ignore start */
17
16
  else if (!allowMissingInitializer && decl.id.type !== 'Identifier' && !(isFor && (this.type === tt._in || this.isContextual('of'))))
18
17
  this.raise(this.lastTokEnd, 'Complex binding patterns require an initialization value');
19
18
  else
@@ -0,0 +1,29 @@
1
+ import {tokTypes as tt} from 'acorn';
2
+
3
+ export default function fn(Parser) {
4
+ return class extends Parser {
5
+ parseIdentNode() {
6
+ const node = this.startNode();
7
+
8
+ /* c8 ignore start */
9
+ if (this.type === tt.name) {
10
+ node.name = this.value;
11
+ } else if (this.type.keyword) {
12
+ node.name = this.type.keyword;
13
+
14
+ // To fix https://github.com/acornjs/acorn/issues/575
15
+ // `class` and `function` keywords push new context into this.context.
16
+ // But there is no chance to pop the context if the keyword is consumed as an identifier such as a property name.
17
+ // If the previous token is a dot, this does not apply because the context-managing code already ignored the keyword
18
+ if ((node.name === 'class' || node.name === 'function') && (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46))
19
+ this.context.pop();
20
+
21
+ this.type = tt.name;
22
+ /* c8 ignore end */
23
+ }
24
+
25
+ return node;
26
+ }
27
+ };
28
+ }
29
+
@@ -0,0 +1,8 @@
1
+ export const report = () => {};
2
+ export const fix = (path) => path.remove();
3
+ export const traverse = ({push}) => ({
4
+ ObjectProperty(path) {
5
+ if (!path.node.key.name)
6
+ push(path);
7
+ },
8
+ });