Skip to content

Commit

Permalink
Update: add latestEcmaVersion & supportedEcmaVersions (#430)
Browse files Browse the repository at this point in the history
* Update: add latestEcmaVersion() & supportedEcmaVersions()

* Address feedback

* Change public API from getter methods to static property
  • Loading branch information
kaicataldo authored Feb 19, 2020
1 parent 8a67b2f commit acb8776
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 67 deletions.
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]
);
});
});

0 comments on commit acb8776

Please sign in to comment.