Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

espree

Package Overview
Dependencies
Maintainers
3
Versions
98
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

espree - npm Package Compare versions

Comparing version 4.0.0 to 4.1.0

lib/espree.js

7

CHANGELOG.md

@@ -0,1 +1,8 @@

v4.1.0 - October 24, 2018
* 8eadb88 Upgrade: acorn 6, acorn-jsx 5, and istanbul (#391) (Toru Nagashima)
* 0f2edb8 Upgrade: eslint-release@1.0.0 (#392) (Teddy Katz)
* 560b6f7 Update: VisitorKeys depend on eslint-visitor-keys (#389) (othree)
* 6bf2ebf Docs: Fix some typos in the README (#386) (Hugo Locurcio)
v4.0.0 - June 21, 2018

@@ -2,0 +9,0 @@

553

espree.js

@@ -61,267 +61,34 @@ /**

var astNodeTypes = require("./lib/ast-node-types"),
commentAttachment = require("./lib/comment-attachment"),
TokenTranslator = require("./lib/token-translator"),
acornJSX = require("acorn-jsx/inject"),
rawAcorn = require("acorn");
const acorn = require("acorn");
const jsx = require("acorn-jsx");
const astNodeTypes = require("./lib/ast-node-types");
const espree = require("./lib/espree");
// To initialize lazily.
const parsers = {
_regular: null,
_jsx: null,
var acorn = acornJSX(rawAcorn);
var DEFAULT_ECMA_VERSION = 5;
var lookahead,
extra,
lastToken;
/**
* Resets the extra object to its default.
* @returns {void}
* @private
*/
function resetExtra() {
extra = {
tokens: null,
range: false,
loc: false,
comment: false,
comments: [],
tolerant: false,
errors: [],
strict: false,
ecmaFeatures: {},
ecmaVersion: DEFAULT_ECMA_VERSION,
isModule: false
};
}
var tt = acorn.tokTypes,
getLineInfo = acorn.getLineInfo;
// custom type for JSX attribute values
tt.jsxAttrValueToken = {};
/**
* Normalize ECMAScript version from the initial config
* @param {number} ecmaVersion ECMAScript version from the initial config
* @returns {number} normalized ECMAScript version
*/
function normalizeEcmaVersion(ecmaVersion) {
if (typeof ecmaVersion === "number") {
var 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;
get regular() {
if (this._regular === null) {
this._regular = acorn.Parser.extend(espree());
}
return this._regular;
},
switch (version) {
case 3:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
return version;
default:
throw new Error("Invalid ecmaVersion.");
get jsx() {
if (this._jsx === null) {
this._jsx = acorn.Parser.extend(jsx(), espree());
}
} else {
return DEFAULT_ECMA_VERSION;
}
}
return this._jsx;
},
/**
* Determines if a node is valid given the set of ecmaFeatures.
* @param {ASTNode} node The node to check.
* @returns {boolean} True if the node is allowed, false if not.
* @private
*/
function isValidNode(node) {
switch (node.type) {
case "ImportDeclaration":
case "ExportNamedDeclaration":
case "ExportDefaultDeclaration":
case "ExportAllDeclaration":
return extra.isModule;
default:
return true;
get(options) {
const useJsx = Boolean(
options &&
options.ecmaFeatures &&
options.ecmaFeatures.jsx
);
return useJsx ? this.jsx : this.regular;
}
}
/**
* Performs last-minute Esprima-specific compatibility checks and fixes.
* @param {ASTNode} result The node to check.
* @returns {ASTNode} The finished node.
* @private
* @this acorn.Parser
*/
function esprimaFinishNode(result) {
// ensure that parsed node was allowed through ecmaFeatures
if (!isValidNode(result)) {
this.unexpected(result.start);
}
// Acorn doesn't count the opening and closing backticks as part of templates
// so we have to adjust ranges/locations appropriately.
if (result.type === "TemplateElement") {
// additional adjustment needed if ${ is the last token
var terminalDollarBraceL = this.input.slice(result.end, result.end + 2) === "${";
if (result.range) {
result.range[0]--;
result.range[1] += (terminalDollarBraceL ? 2 : 1);
}
if (result.loc) {
result.loc.start.column--;
result.loc.end.column += (terminalDollarBraceL ? 2 : 1);
}
}
if (extra.attachComment) {
commentAttachment.processComment(result);
}
if (result.type.indexOf("Function") > -1 && !result.generator) {
result.generator = false;
}
return result;
}
/**
* Determines if a token is valid given the set of ecmaFeatures.
* @param {acorn.Parser} parser The parser to check.
* @returns {boolean} True if the token is allowed, false if not.
* @private
*/
function isValidToken(parser) {
var ecma = extra.ecmaFeatures;
var type = parser.type;
switch (type) {
case tt.jsxName:
case tt.jsxText:
case tt.jsxTagStart:
case tt.jsxTagEnd:
return ecma.jsx;
// https://github.com/ternjs/acorn/issues/363
case tt.regexp:
if (extra.ecmaVersion < 6 && parser.value.flags && parser.value.flags.indexOf("y") > -1) {
return false;
}
return true;
default:
return true;
}
}
/**
* Injects esprimaFinishNode into the finishNode process.
* @param {Function} finishNode Original finishNode function.
* @returns {ASTNode} The finished node.
* @private
*/
function wrapFinishNode(finishNode) {
return /** @this acorn.Parser */ function(node, type, pos, loc) {
var result = finishNode.call(this, node, type, pos, loc);
return esprimaFinishNode.call(this, result);
};
}
acorn.plugins.espree = function(instance) {
instance.extend("finishNode", wrapFinishNode);
instance.extend("finishNodeAt", wrapFinishNode);
instance.extend("next", function(next) {
return /** @this acorn.Parser */ function() {
if (!isValidToken(this)) {
this.unexpected();
}
return next.call(this);
};
});
instance.extend("parseTopLevel", function(parseTopLevel) {
return /** @this acorn.Parser */ function(node) {
if (extra.ecmaFeatures.impliedStrict && this.options.ecmaVersion >= 5) {
this.strict = true;
}
return parseTopLevel.call(this, node);
};
});
/**
* Overwrites the default raise method to throw Esprima-style errors.
* @param {int} pos The position of the error.
* @param {string} message The error message.
* @throws {SyntaxError} A syntax error.
* @returns {void}
*/
instance.raise = instance.raiseRecoverable = function(pos, message) {
var loc = getLineInfo(this.input, pos);
var err = new SyntaxError(message);
err.index = pos;
err.lineNumber = loc.line;
err.column = loc.column + 1; // acorn uses 0-based columns
throw err;
};
/**
* Overwrites the default unexpected method to throw Esprima-style errors.
* @param {int} pos The position of the error.
* @throws {SyntaxError} A syntax error.
* @returns {void}
*/
instance.unexpected = function(pos) {
var message = "Unexpected token";
if (pos !== null && pos !== undefined) {
this.pos = pos;
if (this.options.locations) {
while (this.pos < this.lineStart) {
this.lineStart = this.input.lastIndexOf("\n", this.lineStart - 2) + 1;
--this.curLine;
}
}
this.nextToken();
}
if (this.end > this.start) {
message += " " + this.input.slice(this.start, this.end);
}
this.raise(this.start, message);
};
/*
* Esprima-FB represents JSX strings as tokens called "JSXText", but Acorn-JSX
* uses regular tt.string without any distinction between this and regular JS
* strings. As such, we intercept an attempt to read a JSX string and set a flag
* on extra so that when tokens are converted, the next token will be switched
* to JSXText via onToken.
*/
instance.extend("jsx_readString", function(jsxReadString) {
return /** @this acorn.Parser */ function(quote) {
var result = jsxReadString.call(this, quote);
if (this.type === tt.string) {
extra.jsxAttrValueToken = true;
}
return result;
};
});
};

@@ -342,75 +109,10 @@

function tokenize(code, options) {
var toString,
tokens,
impliedStrict,
translator = new TokenTranslator(tt, code);
const Parser = parsers.get(options);
toString = String;
if (typeof code !== "string" && !(code instanceof String)) {
code = toString(code);
// Ensure to collect tokens.
if (!options || options.tokens !== true) {
options = Object.assign({}, options, { tokens: true });
}
lookahead = null;
// Options matching.
options = Object.assign({}, options);
var acornOptions = {
ecmaVersion: DEFAULT_ECMA_VERSION,
plugins: {
espree: true
}
};
resetExtra();
// Of course we collect tokens here.
options.tokens = true;
extra.tokens = [];
extra.range = (typeof options.range === "boolean") && options.range;
acornOptions.ranges = extra.range;
extra.loc = (typeof options.loc === "boolean") && options.loc;
acornOptions.locations = extra.loc;
extra.comment = typeof options.comment === "boolean" && options.comment;
if (extra.comment) {
acornOptions.onComment = function() {
var comment = convertAcornCommentToEsprimaComment.apply(this, arguments);
extra.comments.push(comment);
};
}
extra.tolerant = typeof options.tolerant === "boolean" && options.tolerant;
acornOptions.ecmaVersion = extra.ecmaVersion = normalizeEcmaVersion(options.ecmaVersion);
// apply parsing flags
if (options.ecmaFeatures && typeof options.ecmaFeatures === "object") {
extra.ecmaFeatures = Object.assign({}, options.ecmaFeatures);
impliedStrict = extra.ecmaFeatures.impliedStrict;
extra.ecmaFeatures.impliedStrict = typeof impliedStrict === "boolean" && impliedStrict;
}
try {
var tokenizer = acorn.tokenizer(code, acornOptions);
while ((lookahead = tokenizer.getToken()).type !== tt.eof) {
translator.onToken(lookahead, extra);
}
// filterTokenLocation();
tokens = extra.tokens;
if (extra.comment) {
tokens.comments = extra.comments;
}
if (extra.tolerant) {
tokens.errors = extra.errors;
}
} catch (e) {
throw e;
}
return tokens;
return new Parser(options, code).tokenize();
}

@@ -422,38 +124,3 @@

/**
* Converts an Acorn comment to a Esprima comment.
* @param {boolean} block True if it's a block comment, false if not.
* @param {string} text The text of the comment.
* @param {int} start The index at which the comment starts.
* @param {int} end The index at which the comment ends.
* @param {Location} startLoc The location at which the comment starts.
* @param {Location} endLoc The location at which the comment ends.
* @returns {Object} The comment object.
* @private
*/
function convertAcornCommentToEsprimaComment(block, text, start, end, startLoc, endLoc) {
var comment = {
type: block ? "Block" : "Line",
value: text
};
if (typeof start === "number") {
comment.start = start;
comment.end = end;
comment.range = [start, end];
}
if (typeof startLoc === "object") {
comment.loc = {
start: startLoc,
end: endLoc
};
}
return comment;
}
/**
* Parses the given code.

@@ -464,142 +131,6 @@ * @param {string} code The code to tokenize.

* @throws {SyntaxError} If the input code is invalid.
* @private
*/
function parse(code, options) {
var program,
toString = String,
translator,
impliedStrict,
acornOptions = {
ecmaVersion: DEFAULT_ECMA_VERSION,
plugins: {
espree: true
}
};
lastToken = null;
if (typeof code !== "string" && !(code instanceof String)) {
code = toString(code);
}
resetExtra();
commentAttachment.reset();
if (typeof options !== "undefined") {
extra.range = (typeof options.range === "boolean") && options.range;
extra.loc = (typeof options.loc === "boolean") && options.loc;
extra.attachComment = (typeof options.attachComment === "boolean") && options.attachComment;
if (extra.loc && options.source !== null && options.source !== undefined) {
extra.source = toString(options.source);
}
if (typeof options.tokens === "boolean" && options.tokens) {
extra.tokens = [];
translator = new TokenTranslator(tt, code);
}
if (typeof options.comment === "boolean" && options.comment) {
extra.comment = true;
extra.comments = [];
}
if (typeof options.tolerant === "boolean" && options.tolerant) {
extra.errors = [];
}
if (extra.attachComment) {
extra.range = true;
extra.comments = [];
commentAttachment.reset();
}
acornOptions.ecmaVersion = extra.ecmaVersion = normalizeEcmaVersion(options.ecmaVersion);
if (options.sourceType === "module") {
extra.isModule = true;
// modules must be in 6 at least
if (acornOptions.ecmaVersion < 6) {
acornOptions.ecmaVersion = 6;
extra.ecmaVersion = 6;
}
acornOptions.sourceType = "module";
}
// apply parsing flags after sourceType to allow overriding
if (options.ecmaFeatures && typeof options.ecmaFeatures === "object") {
extra.ecmaFeatures = Object.assign({}, options.ecmaFeatures);
impliedStrict = extra.ecmaFeatures.impliedStrict;
extra.ecmaFeatures.impliedStrict = typeof impliedStrict === "boolean" && impliedStrict;
if (options.ecmaFeatures.globalReturn) {
acornOptions.allowReturnOutsideFunction = true;
}
}
acornOptions.onToken = function(token) {
if (extra.tokens) {
translator.onToken(token, extra);
}
if (token.type !== tt.eof) {
lastToken = token;
}
};
if (extra.attachComment || extra.comment) {
acornOptions.onComment = function() {
var comment = convertAcornCommentToEsprimaComment.apply(this, arguments);
extra.comments.push(comment);
if (extra.attachComment) {
commentAttachment.addComment(comment);
}
};
}
if (extra.range) {
acornOptions.ranges = true;
}
if (extra.loc) {
acornOptions.locations = true;
}
if (extra.ecmaFeatures.jsx) {
// Should process jsx plugin before espree plugin.
acornOptions.plugins = {
jsx: true,
espree: true
};
}
}
program = acorn.parse(code, acornOptions);
program.sourceType = extra.isModule ? "module" : "script";
if (extra.comment || extra.attachComment) {
program.comments = extra.comments;
}
if (extra.tokens) {
program.tokens = extra.tokens;
}
/*
* Adjust opening and closing position of program to match Esprima.
* Acorn always starts programs at range 0 whereas Esprima starts at the
* first AST node's start (the only real difference is when there's leading
* whitespace or leading comments). Acorn also counts trailing whitespace
* as part of the program whereas Esprima only counts up to the last token.
*/
if (program.range) {
program.range[0] = program.body.length ? program.body[0].range[0] : program.range[0];
program.range[1] = lastToken ? lastToken.range[1] : program.range[1];
}
if (program.loc) {
program.loc.start = program.body.length ? program.body[0].loc.start : program.loc.start;
program.loc.end = lastToken ? lastToken.loc.end : program.loc.end;
}
return program;
const Parser = parsers.get(options);
return new Parser(options, code).parse();
}

@@ -641,21 +172,3 @@

exports.VisitorKeys = (function() {
var visitorKeys = require("./lib/visitor-keys");
var name,
keys = {};
if (typeof Object.create === "function") {
keys = Object.create(null);
}
for (name in visitorKeys) {
if (visitorKeys.hasOwnProperty(name)) {
keys[name] = visitorKeys[name];
}
}
if (typeof Object.freeze === "function") {
Object.freeze(keys);
}
return keys;
return require("eslint-visitor-keys").KEYS;
}());

@@ -7,3 +7,3 @@ {

"main": "espree.js",
"version": "4.0.0",
"version": "4.1.0",
"files": [

@@ -22,4 +22,5 @@ "lib",

"dependencies": {
"acorn": "^5.6.0",
"acorn-jsx": "^4.1.1"
"acorn": "^6.0.2",
"acorn-jsx": "^5.0.0",
"eslint-visitor-keys": "^1.0.0"
},

@@ -31,9 +32,9 @@ "devDependencies": {

"eslint-config-eslint": "^3.0.0",
"eslint-release": "^0.11.1",
"eslint-release": "^1.0.0",
"esprima": "latest",
"esprima-fb": "^8001.2001.0-dev-harmony-fb",
"istanbul": "~0.2.6",
"json-diff": "~0.3.1",
"leche": "^1.0.1",
"mocha": "^2.0.1",
"nyc": "^13.0.1",
"regenerate": "~0.5.4",

@@ -56,10 +57,9 @@ "shelljs": "^0.3.0",

"lint": "node Makefile.js lint",
"release": "eslint-release",
"ci-release": "eslint-ci-release",
"gh-release": "eslint-gh-release",
"alpharelease": "eslint-prerelease alpha",
"betarelease": "eslint-prerelease beta",
"rcrelease": "eslint-prerelease rc",
"browserify": "node Makefile.js browserify"
"browserify": "node Makefile.js browserify",
"generate-release": "eslint-generate-release",
"generate-alpharelease": "eslint-generate-prerelease alpha",
"generate-betarelease": "eslint-generate-prerelease beta",
"generate-rcrelease": "eslint-generate-prerelease rc",
"publish-release": "eslint-publish-release"
}
}

@@ -153,4 +153,4 @@ [![npm version](https://img.shields.io/npm/v/espree.svg)](https://www.npmjs.com/package/espree)

* RegExp named capture groups
* RegExp lookhehind assersions
* RegExp unicode property escapes
* RegExp lookbehind assertions
* RegExp Unicode property escapes

@@ -157,0 +157,0 @@ Espree supports all of them.

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc