Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update: add class fields (refs eslint/eslint#14343) #486

Merged
merged 13 commits into from Jun 11, 2021
4 changes: 3 additions & 1 deletion .eslintignore
@@ -1,3 +1,5 @@
/node_modules
/tests/fixtures
/tools
/tools/*
!/tools/update-ecma-version-tests.js
/dist
21 changes: 17 additions & 4 deletions .eslintrc.cjs
Expand Up @@ -4,17 +4,30 @@ module.exports = {
root: true,
extends: "eslint",
env: {
es6: true
es2020: true
},
parserOptions: {
ecmaVersion: 2020,
sourceType: "module"
},
overrides: [
{
files: ["tests/lib/**"],
files: ["*.cjs"],
parserOptions: {
ecmaVersion: 2020
},
sourceType: "script"
Comment on lines +11 to +17
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mysticatea doesn't plugin:node/recommended already handle this?

}
},
{
files: ["tests/lib/**"],
env: {
mocha: true
}
},
{
files: ["tools/**"],
rules: {
"no-console": "off"
}
}
]
};
14 changes: 14 additions & 0 deletions CONTRIBUTING.md
Expand Up @@ -6,3 +6,17 @@ Please sign the [jQuery Foundation Contributor License Agreement](https://contri

Our full contribution guidelines can be found at:
<http://eslint.org/docs/developer-guide/contributing/>

# How to upgrade `acorn` to support new syntax

1. `npm install acorn@latest`
1. If a new `ecmaVersion` value is added, update `SUPPORTED_VERSIONS` constant in `lib/options.js` and tests in `tests/lib/supported-ecmaversions.js`.
1. If new token types are added, update `lib/token-translator.js` file to translate the tokens.
1. Add tests in `tests/fixtures/ecma-version/<ecma-vesion>/`.
- Add a directory named the new syntax name.
- Add `valid-<test-case-name>.src.js` files for parseable codes.
- Add `invalid-<test-case-name>.src.js` files for syntax error codes.
- Run `node tools/update-ecma-version-tests.js <ecma-vesion>` command to generate `<name>.result.js` files.
- Check the `<name>.result.js` files are expected results.
1. Update `README.md`.
1. Send a pull request.
13 changes: 7 additions & 6 deletions README.md
Expand Up @@ -140,8 +140,8 @@ const options = {
// create a top-level tokens array containing all tokens
tokens: false,

// Set to 3, 5 (default), 6, 7, 8, 9, 10, 11, or 12 to specify the version of ECMAScript syntax you want to use.
// You can also set to 2015 (same as 6), 2016 (same as 7), 2017 (same as 8), 2018 (same as 9), 2019 (same as 10), 2020 (same as 11), or 2021 (same as 12) to use the year-based naming.
// Set to 3, 5 (default), 6, 7, 8, 9, 10, 11, 12, or 13 to specify the version of ECMAScript syntax you want to use.
// You can also set to 2015 (same as 6), 2016 (same as 7), 2017 (same as 8), 2018 (same as 9), 2019 (same as 10), 2020 (same as 11), 2021 (same as 12), or 2022 (same as 13) to use the year-based naming.
ecmaVersion: 5,

// specify which type of script you're parsing ("script" or "module")
Expand Down Expand Up @@ -228,12 +228,13 @@ We are building on top of Acorn, however, so that we can contribute back and hel

### What ECMAScript features do you support?

Espree supports all ECMAScript 2020 features and partially supports ECMAScript 2021 features.
Espree supports all ECMAScript 2021 features and partially supports ECMAScript 2022 features.

Because ECMAScript 2021 is still under development, we are implementing features as they are finalized. Currently, Espree supports:
Because ECMAScript 2022 is still under development, we are implementing features as they are finalized. Currently, Espree supports:

* [Logical Assignment Operators](https://github.com/tc39/proposal-logical-assignment)
* [Numeric Separators](https://github.com/tc39/proposal-numeric-separator)
* [Class instance fields](https://github.com/tc39/proposal-class-fields)
* [Class private instance methods and accessors](https://github.com/tc39/proposal-private-methods)
* [Class static fields, static private methods and accessors](https://github.com/tc39/proposal-static-class-features)

See [finished-proposals.md](https://github.com/tc39/proposals/blob/master/finished-proposals.md) to know what features are finalized.

Expand Down
3 changes: 2 additions & 1 deletion lib/options.js
Expand Up @@ -17,7 +17,8 @@ const SUPPORTED_VERSIONS = [
9,
10,
11,
12
12,
13
];

/**
Expand Down
4 changes: 4 additions & 0 deletions lib/token-translator.js
Expand Up @@ -20,6 +20,7 @@ const Token = {
Boolean: "Boolean",
EOF: "<end>",
Identifier: "Identifier",
PrivateIdentifier: "PrivateIdentifier",
Keyword: "Keyword",
Null: "Null",
Numeric: "Numeric",
Expand Down Expand Up @@ -114,6 +115,9 @@ TokenTranslator.prototype = {
token.type = Token.Keyword;
}

} else if (type === tt.privateId) {
token.type = Token.PrivateIdentifier;

} else if (type === tt.semi || type === tt.comma ||
type === tt.parenL || type === tt.parenR ||
type === tt.braceL || type === tt.braceR ||
Expand Down
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -33,7 +33,7 @@
"dependencies": {
"acorn": "^8.2.2",
"acorn-jsx": "^5.3.1",
"eslint-visitor-keys": "^2.0.0"
"eslint-visitor-keys": "^2.1.0"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^17.1.0",
Expand Down
@@ -0,0 +1,6 @@
export default {
"index": 28,
"lineNumber": 3,
"column": 11,
"message": "Private fields can not be deleted"
};
@@ -0,0 +1,4 @@
class C {
#a;
f() { delete this?.#a }
}
@@ -0,0 +1,6 @@
export default {
"index": 28,
"lineNumber": 3,
"column": 11,
"message": "Private fields can not be deleted"
};
@@ -0,0 +1,4 @@
class C {
#a;
f() { delete this.#a }
}
@@ -0,0 +1,6 @@
export default {
"index": 43,
"lineNumber": 3,
"column": 15,
"message": "Cannot use 'arguments' in class field initializer"
};
@@ -0,0 +1,5 @@
function f() {
class C {
aaa = arguments
}
}
@@ -0,0 +1,6 @@
export default {
"index": 49,
"lineNumber": 3,
"column": 21,
"message": "Cannot use 'arguments' in class field initializer"
};
@@ -0,0 +1,5 @@
function f() {
class C {
aaa = () => arguments
}
}
@@ -0,0 +1,6 @@
export default {
"index": 333,
"lineNumber": 7,
"column": 15,
"message": "The keyword 'yield' is reserved"
};
@@ -0,0 +1,9 @@
function* f() {
class C {
// `yield` is an identifier reference in field initializers even if it's in a generator function.
// But `yield` as identifier references is disallowed in strict mode.
// And the inside of classes is always strict mode.
// Therefore this is a syntax error.
aaa = yield
}
}
@@ -0,0 +1,6 @@
export default {
"index": 41,
"lineNumber": 4,
"column": 14,
"message": "Private field '#b' must be declared in an enclosing class"
};
@@ -0,0 +1,6 @@
class C {
#a;
f() {
this.#b
}
}
@@ -0,0 +1,6 @@
export default {
"index": 49,
"lineNumber": 3,
"column": 17,
"message": "Unexpected token #foo"
};
@@ -0,0 +1,4 @@
class C extends Base {
#foo;
f() { super.#foo }
}
@@ -0,0 +1,6 @@
export default {
"index": 14,
"lineNumber": 2,
"column": 5,
"message": "Classes can't have an element named '#constructor'"
};
@@ -0,0 +1,3 @@
class C {
#constructor = () => {}
}
@@ -0,0 +1,6 @@
export default {
"index": 22,
"lineNumber": 3,
"column": 5,
"message": "Identifier '#a' has already been declared"
};
@@ -0,0 +1,4 @@
class C {
#a;
#a;
}
@@ -0,0 +1,6 @@
export default {
"index": 14,
"lineNumber": 2,
"column": 5,
"message": "Classes can't have a field named 'constructor'"
};
@@ -0,0 +1,3 @@
class C {
constructor = () => {}
}
@@ -0,0 +1,6 @@
export default {
"index": 304,
"lineNumber": 6,
"column": 15,
"message": "Cannot use keyword 'await' outside an async function"
};