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 latestEcmaVersion & supportedEcmaVersions #430

Merged
merged 3 commits into from
Feb 19, 2020
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions espree.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ const acorn = require("acorn");
const jsx = require("acorn-jsx");
const astNodeTypes = require("./lib/ast-node-types");
const espree = require("./lib/espree");
const { getLatestEcmaVersion, getSupportedEcmaVersions } = require("./lib/options");

// To initialize lazily.
const parsers = {
Expand Down Expand Up @@ -170,3 +171,7 @@ exports.Syntax = (function() {
exports.VisitorKeys = (function() {
return require("eslint-visitor-keys").KEYS;
}());

exports.latestEcmaVersion = getLatestEcmaVersion();

exports.supportedEcmaVersions = getSupportedEcmaVersions();
68 changes: 1 addition & 67 deletions lib/espree.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,77 +2,11 @@

/* eslint-disable no-param-reassign*/
const TokenTranslator = require("./token-translator");
const { normalizeOptions } = require("./options");

const DEFAULT_ECMA_VERSION = 5;
const STATE = Symbol("espree's internal state");
const ESPRIMA_FINISH_NODE = Symbol("espree's esprimaFinishNode");

/**
* Normalize ECMAScript version from the initial config
* @param {number} ecmaVersion ECMAScript version from the initial config
* @throws {Error} throws an error if the ecmaVersion is invalid.
* @returns {number} normalized ECMAScript version
*/
function normalizeEcmaVersion(ecmaVersion = DEFAULT_ECMA_VERSION) {
if (typeof ecmaVersion !== "number") {
throw new Error(`ecmaVersion must be a number. Received value of type ${typeof ecmaVersion} instead.`);
}

let version = ecmaVersion;

// Calculate ECMAScript edition number from official year version starting with
// ES2015, which corresponds with ES6 (or a difference of 2009).
if (version >= 2015) {
version -= 2009;
}

switch (version) {
case 3:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
return version;

// no default
}

throw new Error("Invalid ecmaVersion.");
}

/**
* Normalize sourceType from the initial config
* @param {string} sourceType to normalize
* @throws {Error} throw an error if sourceType is invalid
* @returns {string} normalized sourceType
*/
function normalizeSourceType(sourceType = "script") {
if (sourceType === "script" || sourceType === "module") {
return sourceType;
}
throw new Error("Invalid sourceType.");
}

/**
* Normalize parserOptions
* @param {Object} options the parser options to normalize
* @throws {Error} throw an error if found invalid option.
* @returns {Object} normalized options
*/
function normalizeOptions(options) {
const ecmaVersion = normalizeEcmaVersion(options.ecmaVersion);
const sourceType = normalizeSourceType(options.sourceType);
const ranges = options.range === true;
const locations = options.loc === true;

if (sourceType === "module" && ecmaVersion < 6) {
throw new Error("sourceType 'module' is not supported when ecmaVersion < 2015. Consider adding `{ ecmaVersion: 2015 }` to the parser options.");
}
return Object.assign({}, options, { ecmaVersion, sourceType, ranges, locations });
}

/**
* Converts an Acorn comment to a Esprima comment.
Expand Down
105 changes: 105 additions & 0 deletions lib/options.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/**
* @fileoverview A collection of methods for processing Espree's options.
* @author Kai Cataldo
*/

"use strict";

//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------

const DEFAULT_ECMA_VERSION = 5;
const SUPPORTED_VERSIONS = [
3,
5,
6,
7,
8,
9,
10,
11
];

/**
* Normalize ECMAScript version from the initial config
* @param {number} ecmaVersion ECMAScript version from the initial config
* @throws {Error} throws an error if the ecmaVersion is invalid.
* @returns {number} normalized ECMAScript version
*/
function normalizeEcmaVersion(ecmaVersion = DEFAULT_ECMA_VERSION) {
if (typeof ecmaVersion !== "number") {
throw new Error(`ecmaVersion must be a number. Received value of type ${typeof ecmaVersion} instead.`);
}

let version = ecmaVersion;

// Calculate ECMAScript edition number from official year version starting with
// ES2015, which corresponds with ES6 (or a difference of 2009).
if (version >= 2015) {
version -= 2009;
}

if (!SUPPORTED_VERSIONS.includes(version)) {
throw new Error("Invalid ecmaVersion.");
}

return version;
}

/**
* Normalize sourceType from the initial config
* @param {string} sourceType to normalize
* @throws {Error} throw an error if sourceType is invalid
* @returns {string} normalized sourceType
*/
function normalizeSourceType(sourceType = "script") {
if (sourceType === "script" || sourceType === "module") {
return sourceType;
}
throw new Error("Invalid sourceType.");
}

/**
* Normalize parserOptions
* @param {Object} options the parser options to normalize
* @throws {Error} throw an error if found invalid option.
* @returns {Object} normalized options
*/
function normalizeOptions(options) {
const ecmaVersion = normalizeEcmaVersion(options.ecmaVersion);
const sourceType = normalizeSourceType(options.sourceType);
const ranges = options.range === true;
const locations = options.loc === true;

if (sourceType === "module" && ecmaVersion < 6) {
throw new Error("sourceType 'module' is not supported when ecmaVersion < 2015. Consider adding `{ ecmaVersion: 2015 }` to the parser options.");
}
return Object.assign({}, options, { ecmaVersion, sourceType, ranges, locations });
}

/**
* Get the latest ECMAScript version supported by Espree.
* @returns {number} The latest ECMAScript version.
*/
function getLatestEcmaVersion() {
return SUPPORTED_VERSIONS[SUPPORTED_VERSIONS.length - 1];
}

/**
* Get the list of ECMAScript versions supported by Espree.
* @returns {number[]} An array containing the supported ECMAScript versions.
*/
function getSupportedEcmaVersions() {
return [...SUPPORTED_VERSIONS];
}

//------------------------------------------------------------------------------
// Public
//------------------------------------------------------------------------------

module.exports = {
normalizeOptions,
getLatestEcmaVersion,
getSupportedEcmaVersions
};
32 changes: 32 additions & 0 deletions tests/lib/supported-ecmaversions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* @fileoverview Tests for latestEcmaVersion & supportedEcmaVersions.
* @author Kai Cataldo
*/

"use strict";

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

const assert = require("assert"),
espree = require("../../espree");

//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------

describe("latestEcmaVersion", () => {
it("should return the latest supported ecmaVersion", () => {
assert.strictEqual(espree.latestEcmaVersion, 11);
});
});

describe("supportedEcmaVersions", () => {
it("should return an array of all supported versions", () => {
assert.deepStrictEqual(
espree.supportedEcmaVersions,
[3, 5, 6, 7, 8, 9, 10, 11]
);
});
});