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 for ES3 #522

Merged
merged 1 commit into from Nov 25, 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
10 changes: 6 additions & 4 deletions README.md
Expand Up @@ -37,7 +37,7 @@ const ast = espree.parse(code);

`parse` parses the given code and returns a abstract syntax tree (AST). It takes two parameters.

- `code` [string]() - the code which needs to be parsed.
- `code` [string]() - the code which needs to be parsed.
- `options (Optional)` [Object]() - read more about this [here](#options).

```js
Expand Down Expand Up @@ -81,7 +81,7 @@ Node {

`tokenize` returns the tokens of a given code. It takes two parameters.

- `code` [string]() - the code which needs to be parsed.
- `code` [string]() - the code which needs to be parsed.
- `options (Optional)` [Object]() - read more about this [here](#options).

Even if `options` is empty or undefined or `options.tokens` is `false`, it assigns it to `true` in order to get the `tokens` array
Expand Down Expand Up @@ -124,7 +124,7 @@ Returns the latest ECMAScript supported by `espree`

Returns an array of all supported ECMAScript versions

## Options
## Options

```js
const options = {
Expand All @@ -143,7 +143,9 @@ const options = {
// Set to 3, 5 (the 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), 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.
ecmaVersion: 5,
ecmaVersion: 3,

allowReserved: true, // only allowed when ecmaVersion is 3

aladdin-add marked this conversation as resolved.
Show resolved Hide resolved
// specify which type of script you're parsing ("script", "module", or "commonjs")
sourceType: "script",
Expand Down
11 changes: 10 additions & 1 deletion lib/options.js
Expand Up @@ -92,7 +92,16 @@ export function normalizeOptions(options) {
const sourceType = normalizeSourceType(options.sourceType);
const ranges = options.range === true;
const locations = options.loc === true;
const allowReserved = ecmaVersion === 3 ? "never" : false;

if (ecmaVersion !== 3 && options.allowReserved) {

// a value of `false` is intentionally allowed here, so a shared config can overwrite it when needed
throw new Error("`allowReserved` is only supported when ecmaVersion is 3");
}
if (typeof options.allowReserved !== "undefined" && typeof options.allowReserved !== "boolean") {
throw new Error("`allowReserved`, when present, must be `true` or `false`");
}
const allowReserved = ecmaVersion === 3 ? (options.allowReserved || "never") : false;
ljharb marked this conversation as resolved.
Show resolved Hide resolved
const ecmaFeatures = options.ecmaFeatures || {};
const allowReturnOutsideFunction = options.sourceType === "commonjs" ||
Boolean(ecmaFeatures.globalReturn);
Expand Down
66 changes: 66 additions & 0 deletions tests/lib/ecma-version.js
Expand Up @@ -196,6 +196,72 @@ describe("ecmaVersion", () => {
}, /'char' is reserved/u);
});

it("Should throw error when using ES3, allowReserved: false, and reserved words", () => {
assert.throws(() => {
espree.parse(
"var char = 'c'", {
ecmaVersion: 3,
allowReserved: false
}
);
}, /'char' is reserved/u);
});

it("Should not throw error when using ES3, allowReserved: true, and reserved words", () => {
assert.doesNotThrow(() => {
espree.parse(
"var char = 'c'", {
ecmaVersion: 3,
allowReserved: true
}
);
});
});

it("Should not throw error when using ES3, allowReserved: true, and reserved words in object literals", () => {
assert.doesNotThrow(() => {
espree.parse(
"var x = { char: 'c' }", {
ecmaVersion: 3,
allowReserved: true
}
);
});
});

it("Should throw error when using ES5, allowReserved: true", () => {
assert.throws(() => {
espree.parse(
"var x = { char: 'c' }", {
ecmaVersion: 5,
allowReserved: true
}
);
}, /`allowReserved` is only supported when ecmaVersion is 3/u);
});

it("Should throw error when using ES3, allowReserved: non-boolean", () => {
assert.throws(() => {
espree.parse(
"var x = { char: 'c' }", {
ecmaVersion: 3,
allowReserved: "true"
}
);
}, /`allowReserved`, when present, must be `true` or `false`/u);
});

it("Should not throw error when using ES5, allowReserved: false, and ES3 reserved words in object literals", () => {
assert.doesNotThrow(() => {
espree.parse(
"var x = { char: 'c' }", {
ecmaVersion: 5,
allowReserved: false
}
);
});
});

ljharb marked this conversation as resolved.
Show resolved Hide resolved
it("Should throw error when using module in pre-ES6", () => {
assert.throws(() => {
espree.parse(
Expand Down