Skip to content

Commit

Permalink
feat: add allowReserved for ES3 (#522)
Browse files Browse the repository at this point in the history
  • Loading branch information
ljharb committed Nov 25, 2021
1 parent 34b9a6a commit e807c20
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 5 deletions.
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, 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.
ecmaVersion: 5,
ecmaVersion: 3,

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

// 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;
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
}
);
});
});

it("Should throw error when using module in pre-ES6", () => {
assert.throws(() => {
espree.parse(
Expand Down

0 comments on commit e807c20

Please sign in to comment.