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

feat: add allowReserved parser option #15387

Merged
merged 2 commits into from Dec 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/user-guide/configuring/language-options.md
Expand Up @@ -187,6 +187,7 @@ Parser options are set in your `.eslintrc.*` file by using the `parserOptions` p

* `ecmaVersion` - 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. You can also set "latest" to use the most recently supported version.
* `sourceType` - set to `"script"` (default) or `"module"` if your code is in ECMAScript modules.
* `allowReserved` - allow the use of reserved words as identifiers (if `ecmaVersion` is 3).
* `ecmaFeatures` - an object indicating which additional language features you'd like to use:
* `globalReturn` - allow `return` statements in the global scope
* `impliedStrict` - enable global [strict mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode) (if `ecmaVersion` is 5 or greater)
Expand Down
1 change: 1 addition & 0 deletions lib/shared/types.js
Expand Up @@ -23,6 +23,7 @@ module.exports = {};
* @property {EcmaFeatures} [ecmaFeatures] The optional features.
* @property {3|5|6|7|8|9|10|11|12|13|2015|2016|2017|2018|2019|2020|2021|2022} [ecmaVersion] The ECMAScript version (or revision number).
* @property {"script"|"module"} [sourceType] The source code type.
* @property {boolean} [allowReserved] Allowing the use of reserved words as identifiers in ES3.
*/

/**
Expand Down
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -59,7 +59,7 @@
"eslint-scope": "^7.1.0",
"eslint-utils": "^3.0.0",
"eslint-visitor-keys": "^3.1.0",
"espree": "^9.1.0",
"espree": "^9.2.0",
"esquery": "^1.4.0",
"esutils": "^2.0.2",
"fast-deep-equal": "^3.1.3",
Expand Down
76 changes: 76 additions & 0 deletions tests/lib/linter/linter.js
Expand Up @@ -4358,6 +4358,82 @@ var a = "test2";
assert.strictEqual(messages.length, 0);
});

it("should not allow the use of reserved words as variable names in ES3", () => {
const code = "var char;";
const messages = linter.verify(code, { parserOptions: { ecmaVersion: 3 } }, filename);

assert.strictEqual(messages.length, 1);
assert.strictEqual(messages[0].severity, 2);
assert.isTrue(messages[0].fatal);
assert.match(messages[0].message, /^Parsing error:.*'char'/u);
});

it("should not allow the use of reserved words as property names in member expressions in ES3", () => {
const code = "obj.char;";
const messages = linter.verify(code, { parserOptions: { ecmaVersion: 3 } }, filename);

assert.strictEqual(messages.length, 1);
assert.strictEqual(messages[0].severity, 2);
assert.isTrue(messages[0].fatal);
assert.match(messages[0].message, /^Parsing error:.*'char'/u);
});

it("should not allow the use of reserved words as property names in object literals in ES3", () => {
const code = "var obj = { char: 1 };";
const messages = linter.verify(code, { parserOptions: { ecmaVersion: 3 } }, filename);

assert.strictEqual(messages.length, 1);
assert.strictEqual(messages[0].severity, 2);
assert.isTrue(messages[0].fatal);
assert.match(messages[0].message, /^Parsing error:.*'char'/u);
});

it("should allow the use of reserved words as variable and property names in ES3 when allowReserved is true", () => {
const code = "var char; obj.char; var obj = { char: 1 };";
const messages = linter.verify(code, { parserOptions: { ecmaVersion: 3, allowReserved: true } }, filename);

assert.strictEqual(messages.length, 0);
});

it("should not allow the use of reserved words as variable names in ES > 3", () => {
const ecmaVersions = [void 0, ...espree.supportedEcmaVersions.filter(ecmaVersion => ecmaVersion > 3)];

ecmaVersions.forEach(ecmaVersion => {
const code = "var enum;";
const messages = linter.verify(code, { parserOptions: { ecmaVersion } }, filename);

assert.strictEqual(messages.length, 1);
assert.strictEqual(messages[0].severity, 2);
assert.isTrue(messages[0].fatal);
assert.match(messages[0].message, /^Parsing error:.*'enum'/u);
});
});

it("should allow the use of reserved words as property names in ES > 3", () => {
const ecmaVersions = [void 0, ...espree.supportedEcmaVersions.filter(ecmaVersion => ecmaVersion > 3)];

ecmaVersions.forEach(ecmaVersion => {
const code = "obj.enum; obj.function; var obj = { enum: 1, function: 2 };";
const messages = linter.verify(code, { parserOptions: { ecmaVersion } }, filename);

assert.strictEqual(messages.length, 0);
});
});

it("should not allow `allowReserved: true` in ES > 3", () => {
const ecmaVersions = [void 0, ...espree.supportedEcmaVersions.filter(ecmaVersion => ecmaVersion > 3)];

ecmaVersions.forEach(ecmaVersion => {
const code = "";
const messages = linter.verify(code, { parserOptions: { ecmaVersion, allowReserved: true } }, filename);

assert.strictEqual(messages.length, 1);
assert.strictEqual(messages[0].severity, 2);
assert.isTrue(messages[0].fatal);
assert.match(messages[0].message, /^Parsing error:.*allowReserved/u);
});
});

it("should be able to use es6 features if there is a comment which has \"eslint-env es6\"", () => {
const code = [
"/* eslint-env es6 */",
Expand Down