tools: update ESLint to 8.3.0

PR-URL: https://github.com/nodejs/node/pull/40917
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
This commit is contained in:
Luigi Pinca 2021-11-22 13:38:27 +01:00 committed by GitHub
parent 8ee4e672ec
commit 7ad052d2bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
56 changed files with 1700 additions and 1287 deletions

View File

@ -206,6 +206,9 @@ This means:
These folks keep the project moving and are resources for help. These folks keep the project moving and are resources for help.
<!-- NOTE: This section is autogenerated. Do not manually edit.--> <!-- NOTE: This section is autogenerated. Do not manually edit.-->
<!--teamstart--> <!--teamstart-->
### Technical Steering Committee (TSC) ### Technical Steering Committee (TSC)
@ -288,6 +291,9 @@ Nitin Kumar
<!--teamend--> <!--teamend-->
## <a name="sponsors"></a>Sponsors ## <a name="sponsors"></a>Sponsors
The following companies, organizations, and individuals support ESLint's ongoing maintenance and development. [Become a Sponsor](https://opencollective.com/eslint) to get your logo on our README and website. The following companies, organizations, and individuals support ESLint's ongoing maintenance and development. [Become a Sponsor](https://opencollective.com/eslint) to get your logo on our README and website.

View File

@ -461,6 +461,10 @@ function processCodePathToEnter(analyzer, node) {
startCodePath("function"); startCodePath("function");
break; break;
case "StaticBlock":
startCodePath("class-static-block");
break;
case "ChainExpression": case "ChainExpression":
state.pushChainContext(); state.pushChainContext();
break; break;
@ -706,7 +710,8 @@ function postprocess(analyzer, node) {
case "Program": case "Program":
case "FunctionDeclaration": case "FunctionDeclaration":
case "FunctionExpression": case "FunctionExpression":
case "ArrowFunctionExpression": { case "ArrowFunctionExpression":
case "StaticBlock": {
endCodePath(); endCodePath();
break; break;
} }

View File

@ -40,7 +40,7 @@ class CodePath {
/** /**
* The reason that this code path was started. May be "program", * The reason that this code path was started. May be "program",
* "function", or "class-field-initializer". * "function", "class-field-initializer", or "class-static-block".
* @type {string} * @type {string}
*/ */
this.origin = origin; this.origin = origin;

View File

@ -626,7 +626,7 @@ function analyzeScope(ast, parserOptions, visitorKeys) {
ignoreEval: true, ignoreEval: true,
nodejsScope: ecmaFeatures.globalReturn, nodejsScope: ecmaFeatures.globalReturn,
impliedStrict: ecmaFeatures.impliedStrict, impliedStrict: ecmaFeatures.impliedStrict,
ecmaVersion, ecmaVersion: typeof ecmaVersion === "number" ? ecmaVersion : 6,
sourceType: parserOptions.sourceType || "script", sourceType: parserOptions.sourceType || "script",
childVisitorKeys: visitorKeys || evk.KEYS, childVisitorKeys: visitorKeys || evk.KEYS,
fallback: Traverser.getKeys fallback: Traverser.getKeys

View File

@ -112,6 +112,8 @@ module.exports = {
"SwitchStatement:exit": exitScope, "SwitchStatement:exit": exitScope,
CatchClause: enterScope, CatchClause: enterScope,
"CatchClause:exit": exitScope, "CatchClause:exit": exitScope,
StaticBlock: enterScope,
"StaticBlock:exit": exitScope,
// Finds and reports references which are outside of valid scope. // Finds and reports references which are outside of valid scope.
VariableDeclaration: checkForVariables VariableDeclaration: checkForVariables

View File

@ -40,7 +40,7 @@ module.exports = {
/** /**
* Gets the open brace token from a given node. * Gets the open brace token from a given node.
* @param {ASTNode} node A BlockStatement/SwitchStatement node to get. * @param {ASTNode} node A BlockStatement/StaticBlock/SwitchStatement node to get.
* @returns {Token} The token of the open brace. * @returns {Token} The token of the open brace.
*/ */
function getOpenBrace(node) { function getOpenBrace(node) {
@ -50,6 +50,12 @@ module.exports = {
} }
return sourceCode.getLastToken(node, 1); return sourceCode.getLastToken(node, 1);
} }
if (node.type === "StaticBlock") {
return sourceCode.getFirstToken(node, { skip: 1 }); // skip the `static` token
}
// "BlockStatement"
return sourceCode.getFirstToken(node); return sourceCode.getFirstToken(node);
} }
@ -72,8 +78,8 @@ module.exports = {
} }
/** /**
* Reports invalid spacing style inside braces. * Checks and reports invalid spacing style inside braces.
* @param {ASTNode} node A BlockStatement/SwitchStatement node to get. * @param {ASTNode} node A BlockStatement/StaticBlock/SwitchStatement node to check.
* @returns {void} * @returns {void}
*/ */
function checkSpacingInsideBraces(node) { function checkSpacingInsideBraces(node) {
@ -157,6 +163,7 @@ module.exports = {
return { return {
BlockStatement: checkSpacingInsideBraces, BlockStatement: checkSpacingInsideBraces,
StaticBlock: checkSpacingInsideBraces,
SwitchStatement: checkSpacingInsideBraces SwitchStatement: checkSpacingInsideBraces
}; };
} }

View File

@ -155,6 +155,12 @@ module.exports = {
validateCurlyPair(sourceCode.getFirstToken(node), sourceCode.getLastToken(node)); validateCurlyPair(sourceCode.getFirstToken(node), sourceCode.getLastToken(node));
} }
}, },
StaticBlock(node) {
validateCurlyPair(
sourceCode.getFirstToken(node, { skip: 1 }), // skip the `static` token
sourceCode.getLastToken(node)
);
},
ClassBody(node) { ClassBody(node) {
validateCurlyPair(sourceCode.getFirstToken(node), sourceCode.getLastToken(node)); validateCurlyPair(sourceCode.getFirstToken(node), sourceCode.getLastToken(node));
}, },

View File

@ -161,8 +161,17 @@ module.exports = {
/* /*
* Class field value are implicit functions. * Class field value are implicit functions.
*/ */
"PropertyDefinition:exit": popContext,
"PropertyDefinition > *.key:exit": pushContext, "PropertyDefinition > *.key:exit": pushContext,
"PropertyDefinition:exit": popContext,
/*
* Class static blocks are implicit functions. They aren't required to use `this`,
* but we have to push context so that it captures any use of `this` in the static block
* separately from enclosing contexts, because static blocks have their own `this` and it
* shouldn't count as used `this` in enclosing contexts.
*/
StaticBlock: pushContext,
"StaticBlock:exit": popContext,
ThisExpression: markThisUsed, ThisExpression: markThisUsed,
Super: markThisUsed, Super: markThisUsed,

View File

@ -124,20 +124,28 @@ module.exports = {
/* /*
* This rule only evaluates complexity of functions, so "program" is excluded. * This rule only evaluates complexity of functions, so "program" is excluded.
* Class field initializers are implicit functions. Therefore, they shouldn't contribute * Class field initializers and class static blocks are implicit functions. Therefore,
* to the enclosing function's complexity, but their own complexity should be evaluated. * they shouldn't contribute to the enclosing function's complexity, but their
* own complexity should be evaluated.
*/ */
if ( if (
codePath.origin !== "function" && codePath.origin !== "function" &&
codePath.origin !== "class-field-initializer" codePath.origin !== "class-field-initializer" &&
codePath.origin !== "class-static-block"
) { ) {
return; return;
} }
if (complexity > THRESHOLD) { if (complexity > THRESHOLD) {
const name = codePath.origin === "class-field-initializer" let name;
? "class field initializer"
: astUtils.getFunctionNameWithKind(node); if (codePath.origin === "class-field-initializer") {
name = "class field initializer";
} else if (codePath.origin === "class-static-block") {
name = "class static block";
} else {
name = astUtils.getFunctionNameWithKind(node);
}
context.report({ context.report({
node, node,

View File

@ -68,6 +68,7 @@ const KNOWN_NODES = new Set([
"ReturnStatement", "ReturnStatement",
"SequenceExpression", "SequenceExpression",
"SpreadElement", "SpreadElement",
"StaticBlock",
"Super", "Super",
"SwitchCase", "SwitchCase",
"SwitchStatement", "SwitchStatement",
@ -583,6 +584,16 @@ module.exports = {
}, },
additionalProperties: false additionalProperties: false
}, },
StaticBlock: {
type: "object",
properties: {
body: {
type: "integer",
minimum: 0
}
},
additionalProperties: false
},
CallExpression: { CallExpression: {
type: "object", type: "object",
properties: { properties: {
@ -646,6 +657,9 @@ module.exports = {
parameters: DEFAULT_PARAMETER_INDENT, parameters: DEFAULT_PARAMETER_INDENT,
body: DEFAULT_FUNCTION_BODY_INDENT body: DEFAULT_FUNCTION_BODY_INDENT
}, },
StaticBlock: {
body: DEFAULT_FUNCTION_BODY_INDENT
},
CallExpression: { CallExpression: {
arguments: DEFAULT_PARAMETER_INDENT arguments: DEFAULT_PARAMETER_INDENT
}, },
@ -1397,6 +1411,13 @@ module.exports = {
} }
}, },
StaticBlock(node) {
const openingCurly = sourceCode.getFirstToken(node, { skip: 1 }); // skip the `static` token
const closingCurly = sourceCode.getLastToken(node);
addElementListIndent(node.body, openingCurly, closingCurly, options.StaticBlock.body);
},
SwitchStatement(node) { SwitchStatement(node) {
const openingCurly = sourceCode.getTokenAfter(node.discriminant, astUtils.isOpeningBraceToken); const openingCurly = sourceCode.getTokenAfter(node.discriminant, astUtils.isOpeningBraceToken);
const closingCurly = sourceCode.getLastToken(node); const closingCurly = sourceCode.getLastToken(node);

View File

@ -590,6 +590,7 @@ module.exports = {
ImportNamespaceSpecifier: checkSpacingForImportNamespaceSpecifier, ImportNamespaceSpecifier: checkSpacingForImportNamespaceSpecifier,
MethodDefinition: checkSpacingForProperty, MethodDefinition: checkSpacingForProperty,
PropertyDefinition: checkSpacingForProperty, PropertyDefinition: checkSpacingForProperty,
StaticBlock: checkSpacingAroundFirstToken,
Property: checkSpacingForProperty, Property: checkSpacingForProperty,
// To avoid conflicts with `space-infix-ops`, e.g. `a > this.b` // To avoid conflicts with `space-infix-ops`, e.g. `a > this.b`

View File

@ -185,10 +185,39 @@ module.exports = {
/** /**
* Returns the parent node that contains the given token. * Returns the parent node that contains the given token.
* @param {token} token The token to check. * @param {token} token The token to check.
* @returns {ASTNode} The parent node that contains the given token. * @returns {ASTNode|null} The parent node that contains the given token.
*/ */
function getParentNodeOfToken(token) { function getParentNodeOfToken(token) {
return sourceCode.getNodeByRangeIndex(token.range[0]); const node = sourceCode.getNodeByRangeIndex(token.range[0]);
/*
* For the purpose of this rule, the comment token is in a `StaticBlock` node only
* if it's inside the braces of that `StaticBlock` node.
*
* Example where this function returns `null`:
*
* static
* // comment
* {
* }
*
* Example where this function returns `StaticBlock` node:
*
* static
* {
* // comment
* }
*
*/
if (node && node.type === "StaticBlock") {
const openingBrace = sourceCode.getFirstToken(node, { skip: 1 }); // skip the `static` token
return token.range[0] >= openingBrace.range[0]
? node
: null;
}
return node;
} }
/** /**
@ -200,8 +229,15 @@ module.exports = {
function isCommentAtParentStart(token, nodeType) { function isCommentAtParentStart(token, nodeType) {
const parent = getParentNodeOfToken(token); const parent = getParentNodeOfToken(token);
return parent && isParentNodeType(parent, nodeType) && if (parent && isParentNodeType(parent, nodeType)) {
token.loc.start.line - parent.loc.start.line === 1; const parentStartNodeOrToken = parent.type === "StaticBlock"
? sourceCode.getFirstToken(parent, { skip: 1 }) // opening brace of the static block
: parent;
return token.loc.start.line - parentStartNodeOrToken.loc.start.line === 1;
}
return false;
} }
/** /**
@ -213,7 +249,7 @@ module.exports = {
function isCommentAtParentEnd(token, nodeType) { function isCommentAtParentEnd(token, nodeType) {
const parent = getParentNodeOfToken(token); const parent = getParentNodeOfToken(token);
return parent && isParentNodeType(parent, nodeType) && return !!parent && isParentNodeType(parent, nodeType) &&
parent.loc.end.line - token.loc.end.line === 1; parent.loc.end.line - token.loc.end.line === 1;
} }
@ -223,7 +259,12 @@ module.exports = {
* @returns {boolean} True if the comment is at block start. * @returns {boolean} True if the comment is at block start.
*/ */
function isCommentAtBlockStart(token) { function isCommentAtBlockStart(token) {
return isCommentAtParentStart(token, "ClassBody") || isCommentAtParentStart(token, "BlockStatement") || isCommentAtParentStart(token, "SwitchCase"); return (
isCommentAtParentStart(token, "ClassBody") ||
isCommentAtParentStart(token, "BlockStatement") ||
isCommentAtParentStart(token, "StaticBlock") ||
isCommentAtParentStart(token, "SwitchCase")
);
} }
/** /**
@ -232,7 +273,13 @@ module.exports = {
* @returns {boolean} True if the comment is at block end. * @returns {boolean} True if the comment is at block end.
*/ */
function isCommentAtBlockEnd(token) { function isCommentAtBlockEnd(token) {
return isCommentAtParentEnd(token, "ClassBody") || isCommentAtParentEnd(token, "BlockStatement") || isCommentAtParentEnd(token, "SwitchCase") || isCommentAtParentEnd(token, "SwitchStatement"); return (
isCommentAtParentEnd(token, "ClassBody") ||
isCommentAtParentEnd(token, "BlockStatement") ||
isCommentAtParentEnd(token, "StaticBlock") ||
isCommentAtParentEnd(token, "SwitchCase") ||
isCommentAtParentEnd(token, "SwitchStatement")
);
} }
/** /**

View File

@ -118,6 +118,7 @@ module.exports = {
FunctionDeclaration: startFunction, FunctionDeclaration: startFunction,
FunctionExpression: startFunction, FunctionExpression: startFunction,
ArrowFunctionExpression: startFunction, ArrowFunctionExpression: startFunction,
StaticBlock: startFunction,
IfStatement(node) { IfStatement(node) {
if (node.parent.type !== "IfStatement") { if (node.parent.type !== "IfStatement") {
@ -146,6 +147,7 @@ module.exports = {
"FunctionDeclaration:exit": endFunction, "FunctionDeclaration:exit": endFunction,
"FunctionExpression:exit": endFunction, "FunctionExpression:exit": endFunction,
"ArrowFunctionExpression:exit": endFunction, "ArrowFunctionExpression:exit": endFunction,
"StaticBlock:exit": endFunction,
"Program:exit": endFunction "Program:exit": endFunction
}; };

View File

@ -123,6 +123,14 @@ module.exports = {
function endFunction(node) { function endFunction(node) {
const count = functionStack.pop(); const count = functionStack.pop();
/*
* This rule does not apply to class static blocks, but we have to track them so
* that stataments in them do not count as statements in the enclosing function.
*/
if (node.type === "StaticBlock") {
return;
}
if (ignoreTopLevelFunctions && functionStack.length === 0) { if (ignoreTopLevelFunctions && functionStack.length === 0) {
topLevelFunctions.push({ node, count }); topLevelFunctions.push({ node, count });
} else { } else {
@ -148,12 +156,14 @@ module.exports = {
FunctionDeclaration: startFunction, FunctionDeclaration: startFunction,
FunctionExpression: startFunction, FunctionExpression: startFunction,
ArrowFunctionExpression: startFunction, ArrowFunctionExpression: startFunction,
StaticBlock: startFunction,
BlockStatement: countStatements, BlockStatement: countStatements,
"FunctionDeclaration:exit": endFunction, "FunctionDeclaration:exit": endFunction,
"FunctionExpression:exit": endFunction, "FunctionExpression:exit": endFunction,
"ArrowFunctionExpression:exit": endFunction, "ArrowFunctionExpression:exit": endFunction,
"StaticBlock:exit": endFunction,
"Program:exit"() { "Program:exit"() {
if (topLevelFunctions.length === 1) { if (topLevelFunctions.length === 1) {

View File

@ -248,6 +248,8 @@ module.exports = {
"ArrowFunctionExpression:exit": exitVarScope, "ArrowFunctionExpression:exit": exitVarScope,
"PropertyDefinition > *.value": enterVarScope, "PropertyDefinition > *.value": enterVarScope,
"PropertyDefinition > *.value:exit": exitVarScope, "PropertyDefinition > *.value:exit": exitVarScope,
StaticBlock: enterVarScope,
"StaticBlock:exit": exitVarScope,
ThisExpression(node) { ThisExpression(node) {
if (!isMember(node.parent, "eval")) { if (!isMember(node.parent, "eval")) {

View File

@ -116,7 +116,7 @@ module.exports = {
* @param {Node} node A MethodDefinition node of the start point. * @param {Node} node A MethodDefinition node of the start point.
* @returns {void} * @returns {void}
*/ */
"MethodDefinition, PropertyDefinition"(node) { "MethodDefinition, PropertyDefinition, StaticBlock"(node) {
checkForPartOfClassBody(sourceCode.getTokenAfter(node)); checkForPartOfClassBody(sourceCode.getTokenAfter(node));
} }
}; };

View File

@ -15,9 +15,33 @@ const astUtils = require("./utils/ast-utils");
// Rule Definition // Rule Definition
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
const validParent = new Set(["Program", "ExportNamedDeclaration", "ExportDefaultDeclaration"]); const validParent = new Set(["Program", "StaticBlock", "ExportNamedDeclaration", "ExportDefaultDeclaration"]);
const validBlockStatementParent = new Set(["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"]); const validBlockStatementParent = new Set(["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"]);
/**
* Finds the nearest enclosing context where this rule allows declarations and returns its description.
* @param {ASTNode} node Node to search from.
* @returns {string} Description. One of "program", "function body", "class static block body".
*/
function getAllowedBodyDescription(node) {
let { parent } = node;
while (parent) {
if (parent.type === "StaticBlock") {
return "class static block body";
}
if (astUtils.isFunction(parent)) {
return "function body";
}
({ parent } = parent);
}
return "program";
}
module.exports = { module.exports = {
meta: { meta: {
type: "problem", type: "problem",
@ -59,14 +83,12 @@ module.exports = {
return; return;
} }
const upperFunction = astUtils.getUpperFunction(parent);
context.report({ context.report({
node, node,
messageId: "moveDeclToRoot", messageId: "moveDeclToRoot",
data: { data: {
type: (node.type === "FunctionDeclaration" ? "function" : "variable"), type: (node.type === "FunctionDeclaration" ? "function" : "variable"),
body: (upperFunction === null ? "program" : "function body") body: getAllowedBodyDescription(node)
} }
}); });
} }

View File

@ -132,6 +132,10 @@ module.exports = {
"PropertyDefinition > *.value": enterFunction, "PropertyDefinition > *.value": enterFunction,
"PropertyDefinition > *.value:exit": exitFunction, "PropertyDefinition > *.value:exit": exitFunction,
// Class static blocks are implicit functions.
StaticBlock: enterFunction,
"StaticBlock:exit": exitFunction,
// Reports if `this` of the current context is invalid. // Reports if `this` of the current context is invalid.
ThisExpression(node) { ThisExpression(node) {
const current = stack.getCurrent(); const current = stack.getCurrent();

View File

@ -39,7 +39,9 @@ module.exports = {
* @returns {void} * @returns {void}
*/ */
function report(node) { function report(node) {
const messageId = node.parent.type === "BlockStatement" ? "redundantNestedBlock" : "redundantBlock"; const messageId = node.parent.type === "BlockStatement" || node.parent.type === "StaticBlock"
? "redundantNestedBlock"
: "redundantBlock";
context.report({ context.report({
node, node,
@ -54,6 +56,7 @@ module.exports = {
*/ */
function isLoneBlock(node) { function isLoneBlock(node) {
return node.parent.type === "BlockStatement" || return node.parent.type === "BlockStatement" ||
node.parent.type === "StaticBlock" ||
node.parent.type === "Program" || node.parent.type === "Program" ||
// Don't report blocks in switch cases if the block is the only statement of the case. // Don't report blocks in switch cases if the block is the only statement of the case.
@ -99,7 +102,10 @@ module.exports = {
loneBlocks.pop(); loneBlocks.pop();
report(node); report(node);
} else if ( } else if (
node.parent.type === "BlockStatement" && (
node.parent.type === "BlockStatement" ||
node.parent.type === "StaticBlock"
) &&
node.parent.body.length === 1 node.parent.body.length === 1
) { ) {
report(node); report(node);

View File

@ -161,6 +161,8 @@ module.exports = {
FunctionExpression: checkForBlock, FunctionExpression: checkForBlock,
ArrowFunctionExpression: checkForBlock, ArrowFunctionExpression: checkForBlock,
StaticBlock: checkForBlock,
BlockStatement: checkForBlock, BlockStatement: checkForBlock,
ForStatement: checkForBlock, ForStatement: checkForBlock,
ForInStatement: checkForBlock, ForInStatement: checkForBlock,

View File

@ -115,6 +115,12 @@ module.exports = {
const parent = ancestors[ancestors.length - 1], const parent = ancestors[ancestors.length - 1],
grandparent = ancestors[ancestors.length - 2]; grandparent = ancestors[ancestors.length - 2];
/**
* https://tc39.es/ecma262/#directive-prologue
*
* Only `FunctionBody`, `ScriptBody` and `ModuleBody` can have directive prologue.
* Class static blocks do not have directive prologue.
*/
return (parent.type === "Program" || parent.type === "BlockStatement" && return (parent.type === "Program" || parent.type === "BlockStatement" &&
(/Function/u.test(grandparent.type))) && (/Function/u.test(grandparent.type))) &&
directives(parent).indexOf(node) >= 0; directives(parent).indexOf(node) >= 0;

View File

@ -45,25 +45,37 @@ function isInRange(node, location) {
/** /**
* Checks whether or not a given location is inside of the range of a class static initializer. * Checks whether or not a given location is inside of the range of a class static initializer.
* Static initializers are static blocks and initializers of static fields.
* @param {ASTNode} node `ClassBody` node to check static initializers. * @param {ASTNode} node `ClassBody` node to check static initializers.
* @param {number} location A location to check. * @param {number} location A location to check.
* @returns {boolean} `true` if the location is inside of a class static initializer. * @returns {boolean} `true` if the location is inside of a class static initializer.
*/ */
function isInClassStaticInitializerRange(node, location) { function isInClassStaticInitializerRange(node, location) {
return node.body.some(classMember => ( return node.body.some(classMember => (
classMember.type === "PropertyDefinition" && (
classMember.static && classMember.type === "StaticBlock" &&
classMember.value && isInRange(classMember, location)
isInRange(classMember.value, location) ) ||
(
classMember.type === "PropertyDefinition" &&
classMember.static &&
classMember.value &&
isInRange(classMember.value, location)
)
)); ));
} }
/** /**
* Checks whether a given scope is the scope of a static class field initializer. * Checks whether a given scope is the scope of a a class static initializer.
* Static initializers are static blocks and initializers of static fields.
* @param {eslint-scope.Scope} scope A scope to check. * @param {eslint-scope.Scope} scope A scope to check.
* @returns {boolean} `true` if the scope is a class static initializer scope. * @returns {boolean} `true` if the scope is a class static initializer scope.
*/ */
function isClassStaticInitializerScope(scope) { function isClassStaticInitializerScope(scope) {
if (scope.type === "class-static-block") {
return true;
}
if (scope.type === "class-field-initializer") { if (scope.type === "class-field-initializer") {
// `scope.block` is PropertyDefinition#value node // `scope.block` is PropertyDefinition#value node
@ -82,7 +94,8 @@ function isClassStaticInitializerScope(scope) {
* - top-level * - top-level
* - functions * - functions
* - class field initializers (implicit functions) * - class field initializers (implicit functions)
* Static class field initializers are automatically run during the class definition evaluation, * - class static blocks (implicit functions)
* Static class field initializers and class static blocks are automatically run during the class definition evaluation,
* and therefore we'll consider them as a part of the parent execution context. * and therefore we'll consider them as a part of the parent execution context.
* Example: * Example:
* *
@ -90,6 +103,7 @@ function isClassStaticInitializerScope(scope) {
* *
* x; // returns `false` * x; // returns `false`
* () => x; // returns `true` * () => x; // returns `true`
*
* class C { * class C {
* field = x; // returns `true` * field = x; // returns `true`
* static field = x; // returns `false` * static field = x; // returns `false`
@ -97,6 +111,14 @@ function isClassStaticInitializerScope(scope) {
* method() { * method() {
* x; // returns `true` * x; // returns `true`
* } * }
*
* static method() {
* x; // returns `true`
* }
*
* static {
* x; // returns `false`
* }
* } * }
* @param {eslint-scope.Reference} reference A reference to check. * @param {eslint-scope.Reference} reference A reference to check.
* @returns {boolean} `true` if the reference is from a separate execution context. * @returns {boolean} `true` if the reference is from a separate execution context.
@ -127,8 +149,9 @@ function isFromSeparateExecutionContext(reference) {
* var {a = a} = obj * var {a = a} = obj
* for (var a in a) {} * for (var a in a) {}
* for (var a of a) {} * for (var a of a) {}
* var C = class { [C]; } * var C = class { [C]; };
* var C = class { static foo = C; } * var C = class { static foo = C; };
* var C = class { static { foo = C; } };
* class C extends C {} * class C extends C {}
* class C extends (class { static foo = C; }) {} * class C extends (class { static foo = C; }) {}
* class C { [C]; } * class C { [C]; }
@ -158,7 +181,7 @@ function isEvaluatedDuringInitialization(reference) {
/* /*
* Class binding is initialized before running static initializers. * Class binding is initialized before running static initializers.
* For example, `class C { static foo = C; }` is valid. * For example, `class C { static foo = C; static { bar = C; } }` is valid.
*/ */
!isInClassStaticInitializerRange(classDefinition.body, location) !isInClassStaticInitializerRange(classDefinition.body, location)
); );

View File

@ -541,6 +541,8 @@ module.exports = {
FunctionDeclaration: startFunction, FunctionDeclaration: startFunction,
FunctionExpression: startFunction, FunctionExpression: startFunction,
ArrowFunctionExpression: startFunction, ArrowFunctionExpression: startFunction,
StaticBlock: startFunction, // StaticBlock creates a new scope for `var` variables
BlockStatement: startBlock, BlockStatement: startBlock,
ForStatement: startBlock, ForStatement: startBlock,
ForInStatement: startBlock, ForInStatement: startBlock,
@ -552,10 +554,12 @@ module.exports = {
"ForInStatement:exit": endBlock, "ForInStatement:exit": endBlock,
"SwitchStatement:exit": endBlock, "SwitchStatement:exit": endBlock,
"BlockStatement:exit": endBlock, "BlockStatement:exit": endBlock,
"Program:exit": endFunction, "Program:exit": endFunction,
"FunctionDeclaration:exit": endFunction, "FunctionDeclaration:exit": endFunction,
"FunctionExpression:exit": endFunction, "FunctionExpression:exit": endFunction,
"ArrowFunctionExpression:exit": endFunction "ArrowFunctionExpression:exit": endFunction,
"StaticBlock:exit": endFunction
}; };
} }

View File

@ -106,6 +106,12 @@ module.exports = {
if (node.type === "SwitchStatement") { if (node.type === "SwitchStatement") {
return sourceCode.getTokenBefore(node.cases[0]); return sourceCode.getTokenBefore(node.cases[0]);
} }
if (node.type === "StaticBlock") {
return sourceCode.getFirstToken(node, { skip: 1 }); // skip the `static` token
}
// `BlockStatement` or `ClassBody`
return sourceCode.getFirstToken(node); return sourceCode.getFirstToken(node);
} }
@ -172,6 +178,7 @@ module.exports = {
function requirePaddingFor(node) { function requirePaddingFor(node) {
switch (node.type) { switch (node.type) {
case "BlockStatement": case "BlockStatement":
case "StaticBlock":
return options.blocks; return options.blocks;
case "SwitchStatement": case "SwitchStatement":
return options.switches; return options.switches;
@ -282,6 +289,7 @@ module.exports = {
} }
checkPadding(node); checkPadding(node);
}; };
rule.StaticBlock = rule.BlockStatement;
} }
if (Object.prototype.hasOwnProperty.call(options, "classes")) { if (Object.prototype.hasOwnProperty.call(options, "classes")) {

View File

@ -618,9 +618,11 @@ module.exports = {
Program: enterScope, Program: enterScope,
BlockStatement: enterScope, BlockStatement: enterScope,
SwitchStatement: enterScope, SwitchStatement: enterScope,
StaticBlock: enterScope,
"Program:exit": exitScope, "Program:exit": exitScope,
"BlockStatement:exit": exitScope, "BlockStatement:exit": exitScope,
"SwitchStatement:exit": exitScope, "SwitchStatement:exit": exitScope,
"StaticBlock:exit": exitScope,
":statement": verify, ":statement": verify,

View File

@ -17,7 +17,7 @@ const astUtils = require("./utils/ast-utils");
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
const PATTERN_TYPE = /^(?:.+?Pattern|RestElement|SpreadProperty|ExperimentalRestProperty|Property)$/u; const PATTERN_TYPE = /^(?:.+?Pattern|RestElement|SpreadProperty|ExperimentalRestProperty|Property)$/u;
const DECLARATION_HOST_TYPE = /^(?:Program|BlockStatement|SwitchCase)$/u; const DECLARATION_HOST_TYPE = /^(?:Program|BlockStatement|StaticBlock|SwitchCase)$/u;
const DESTRUCTURING_HOST_TYPE = /^(?:VariableDeclarator|AssignmentExpression)$/u; const DESTRUCTURING_HOST_TYPE = /^(?:VariableDeclarator|AssignmentExpression)$/u;
/** /**

View File

@ -176,7 +176,17 @@ module.exports = {
}, },
fixable: null, fixable: null,
schema: [],
schema: [{
type: "object",
properties: {
allowProperties: {
type: "boolean",
default: false
}
},
additionalProperties: false
}],
messages: { messages: {
nonAtomicUpdate: "Possible race condition: `{{value}}` might be reassigned based on an outdated value of `{{value}}`.", nonAtomicUpdate: "Possible race condition: `{{value}}` might be reassigned based on an outdated value of `{{value}}`.",
@ -185,6 +195,8 @@ module.exports = {
}, },
create(context) { create(context) {
const allowProperties = !!context.options[0] && context.options[0].allowProperties;
const sourceCode = context.getSourceCode(); const sourceCode = context.getSourceCode();
const assignmentReferences = new Map(); const assignmentReferences = new Map();
const segmentInfo = new SegmentInfo(); const segmentInfo = new SegmentInfo();
@ -284,7 +296,7 @@ module.exports = {
value: variable.name value: variable.name
} }
}); });
} else { } else if (!allowProperties) {
context.report({ context.report({
node: node.parent, node: node.parent,
messageId: "nonAtomicObjectUpdate", messageId: "nonAtomicObjectUpdate",

View File

@ -25,7 +25,8 @@ const SELECTOR = [
/** /**
* Get the child node list of a given node. * Get the child node list of a given node.
* This returns `Program#body`, `BlockStatement#body`, or `SwitchCase#consequent`. * This returns `BlockStatement#body`, `StaticBlock#body`, `Program#body`,
* `ClassBody#body`, or `SwitchCase#consequent`.
* This is used to check whether a node is the first/last child. * This is used to check whether a node is the first/last child.
* @param {Node} node A node to get child node list. * @param {Node} node A node to get child node list.
* @returns {Node[]|null} The child node list. * @returns {Node[]|null} The child node list.
@ -33,7 +34,12 @@ const SELECTOR = [
function getChildren(node) { function getChildren(node) {
const t = node.type; const t = node.type;
if (t === "BlockStatement" || t === "Program" || t === "ClassBody") { if (
t === "BlockStatement" ||
t === "StaticBlock" ||
t === "Program" ||
t === "ClassBody"
) {
return node.body; return node.body;
} }
if (t === "SwitchCase") { if (t === "SwitchCase") {

View File

@ -306,22 +306,31 @@ module.exports = {
} }
/** /**
* Checks a node to see if it's in a one-liner block statement. * Checks a node to see if it's the last item in a one-liner block.
* Block is any `BlockStatement` or `StaticBlock` node. Block is a one-liner if its
* braces (and consequently everything between them) are on the same line.
* @param {ASTNode} node The node to check. * @param {ASTNode} node The node to check.
* @returns {boolean} whether the node is in a one-liner block statement. * @returns {boolean} whether the node is the last item in a one-liner block.
*/ */
function isOneLinerBlock(node) { function isLastInOneLinerBlock(node) {
const parent = node.parent; const parent = node.parent;
const nextToken = sourceCode.getTokenAfter(node); const nextToken = sourceCode.getTokenAfter(node);
if (!nextToken || nextToken.value !== "}") { if (!nextToken || nextToken.value !== "}") {
return false; return false;
} }
return (
!!parent && if (parent.type === "BlockStatement") {
parent.type === "BlockStatement" && return parent.loc.start.line === parent.loc.end.line;
parent.loc.start.line === parent.loc.end.line }
);
if (parent.type === "StaticBlock") {
const openingBrace = sourceCode.getFirstToken(parent, { skip: 1 }); // skip the `static` token
return openingBrace.loc.start.line === parent.loc.end.line;
}
return false;
} }
/** /**
@ -343,7 +352,7 @@ module.exports = {
report(node); report(node);
} }
} else { } else {
const oneLinerBlock = (exceptOneLine && isOneLinerBlock(node)); const oneLinerBlock = (exceptOneLine && isLastInOneLinerBlock(node));
if (isSemi && oneLinerBlock) { if (isSemi && oneLinerBlock) {
report(node, true); report(node, true);

View File

@ -35,7 +35,7 @@ const COMMENTS_IGNORE_PATTERN = /^\s*(?:eslint|jshint\s+|jslint\s+|istanbul\s+|g
const LINEBREAKS = new Set(["\r\n", "\r", "\n", "\u2028", "\u2029"]); const LINEBREAKS = new Set(["\r\n", "\r", "\n", "\u2028", "\u2029"]);
// A set of node types that can contain a list of statements // A set of node types that can contain a list of statements
const STATEMENT_LIST_PARENTS = new Set(["Program", "BlockStatement", "SwitchCase"]); const STATEMENT_LIST_PARENTS = new Set(["Program", "BlockStatement", "StaticBlock", "SwitchCase"]);
const DECIMAL_INTEGER_PATTERN = /^(?:0|0[0-7]*[89]\d*|[1-9](?:_?\d)*)$/u; const DECIMAL_INTEGER_PATTERN = /^(?:0|0[0-7]*[89]\d*|[1-9](?:_?\d)*)$/u;
@ -937,6 +937,8 @@ module.exports = {
* *
* First, this checks the node: * First, this checks the node:
* *
* - The given node is not in `PropertyDefinition#value` position.
* - The given node is not `StaticBlock`.
* - The function name does not start with uppercase. It's a convention to capitalize the names * - The function name does not start with uppercase. It's a convention to capitalize the names
* of constructor functions. This check is not performed if `capIsConstructor` is set to `false`. * of constructor functions. This check is not performed if `capIsConstructor` is set to `false`.
* - The function does not have a JSDoc comment that has a @this tag. * - The function does not have a JSDoc comment that has a @this tag.
@ -951,7 +953,8 @@ module.exports = {
* - The location is not on an ES2015 class. * - The location is not on an ES2015 class.
* - Its `bind`/`call`/`apply` method is not called directly. * - Its `bind`/`call`/`apply` method is not called directly.
* - The function is not a callback of array methods (such as `.forEach()`) if `thisArg` is given. * - The function is not a callback of array methods (such as `.forEach()`) if `thisArg` is given.
* @param {ASTNode} node A function node to check. * @param {ASTNode} node A function node to check. It also can be an implicit function, like `StaticBlock`
* or any expression that is `PropertyDefinition#value` node.
* @param {SourceCode} sourceCode A SourceCode instance to get comments. * @param {SourceCode} sourceCode A SourceCode instance to get comments.
* @param {boolean} [capIsConstructor = true] `false` disables the assumption that functions which name starts * @param {boolean} [capIsConstructor = true] `false` disables the assumption that functions which name starts
* with an uppercase or are assigned to a variable which name starts with an uppercase are constructors. * with an uppercase or are assigned to a variable which name starts with an uppercase are constructors.
@ -964,7 +967,12 @@ module.exports = {
* Therefore, A expression node at `PropertyDefinition#value` is a function. * Therefore, A expression node at `PropertyDefinition#value` is a function.
* In this case, `this` is always not default binding. * In this case, `this` is always not default binding.
*/ */
if (node && node.parent && node.parent.type === "PropertyDefinition" && node.value === node) { if (node.parent.type === "PropertyDefinition" && node.parent.value === node) {
return false;
}
// Class static blocks are implicit functions. In this case, `this` is always not default binding.
if (node.type === "StaticBlock") {
return false; return false;
} }
@ -1825,6 +1833,10 @@ module.exports = {
return true; return true;
} }
if (rightToken.type === "PrivateIdentifier") {
return true;
}
return false; return false;
}, },

View File

@ -77,10 +77,12 @@ module.exports = {
const l = statements.length; const l = statements.length;
let i = 0; let i = 0;
// skip over directives // Skip over directives and imports. Static blocks don't have either.
for (; i < l; ++i) { if (node.parent.type !== "StaticBlock") {
if (!looksLikeDirective(statements[i]) && !looksLikeImport(statements[i])) { for (; i < l; ++i) {
break; if (!looksLikeDirective(statements[i]) && !looksLikeImport(statements[i])) {
break;
}
} }
} }
@ -111,16 +113,27 @@ module.exports = {
/** /**
* Checks whether variable is on top at functional block scope level * Checks whether variable is on top at functional block scope level
* @param {ASTNode} node The node to check * @param {ASTNode} node The node to check
* @param {ASTNode} parent Parent of the node
* @param {ASTNode} grandParent Parent of the node's parent
* @returns {void} * @returns {void}
*/ */
function blockScopeVarCheck(node, parent, grandParent) { function blockScopeVarCheck(node) {
if (!(/Function/u.test(grandParent.type) && const { parent } = node;
parent.type === "BlockStatement" &&
isVarOnTop(node, parent.body))) { if (
context.report({ node, messageId: "top" }); parent.type === "BlockStatement" &&
/Function/u.test(parent.parent.type) &&
isVarOnTop(node, parent.body)
) {
return;
} }
if (
parent.type === "StaticBlock" &&
isVarOnTop(node, parent.body)
) {
return;
}
context.report({ node, messageId: "top" });
} }
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
@ -134,7 +147,7 @@ module.exports = {
} else if (node.parent.type === "Program") { } else if (node.parent.type === "Program") {
globalVarCheck(node, node.parent); globalVarCheck(node, node.parent);
} else { } else {
blockScopeVarCheck(node, node.parent, node.parent.parent); blockScopeVarCheck(node);
} }
} }
}; };

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,26 @@ var path = require('path');
var fs = require('fs'); var fs = require('fs');
var acorn = require('./acorn.js'); var acorn = require('./acorn.js');
function _interopNamespace(e) {
if (e && e.__esModule) return e;
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n["default"] = e;
return Object.freeze(n);
}
var acorn__namespace = /*#__PURE__*/_interopNamespace(acorn);
var inputFilePaths = [], forceFileName = false, fileMode = false, silent = false, compact = false, tokenize = false; var inputFilePaths = [], forceFileName = false, fileMode = false, silent = false, compact = false, tokenize = false;
var options = {}; var options = {};
@ -44,14 +64,14 @@ function run(codeList) {
codeList.forEach(function (code, idx) { codeList.forEach(function (code, idx) {
fileIdx = idx; fileIdx = idx;
if (!tokenize) { if (!tokenize) {
result = acorn.parse(code, options); result = acorn__namespace.parse(code, options);
options.program = result; options.program = result;
} else { } else {
var tokenizer = acorn.tokenizer(code, options), token; var tokenizer = acorn__namespace.tokenizer(code, options), token;
do { do {
token = tokenizer.getToken(); token = tokenizer.getToken();
result.push(token); result.push(token);
} while (token.type !== acorn.tokTypes.eof) } while (token.type !== acorn__namespace.tokTypes.eof)
} }
}); });
} catch (e) { } catch (e) {

View File

@ -16,7 +16,7 @@
], ],
"./package.json": "./package.json" "./package.json": "./package.json"
}, },
"version": "8.5.0", "version": "8.6.0",
"engines": {"node": ">=0.4.0"}, "engines": {"node": ">=0.4.0"},
"maintainers": [ "maintainers": [
{ {

View File

@ -366,7 +366,7 @@ class ParameterDefinition extends Definition {
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
const { Syntax: Syntax$2 } = estraverse__default['default']; const { Syntax: Syntax$2 } = estraverse__default["default"];
/** /**
* Test if scope is struct * Test if scope is struct
@ -491,7 +491,8 @@ class Scope {
constructor(scopeManager, type, upperScope, block, isMethodDefinition) { constructor(scopeManager, type, upperScope, block, isMethodDefinition) {
/** /**
* One of 'module', 'block', 'switch', 'function', 'catch', 'with', 'function', 'class', 'global'. * One of "global", "module", "function", "function-expression-name", "block", "switch", "catch", "with", "for",
* "class", "class-field-initializer", "class-static-block".
* @member {string} Scope#type * @member {string} Scope#type
*/ */
this.type = type; this.type = type;
@ -559,7 +560,13 @@ class Scope {
* @member {Scope} Scope#variableScope * @member {Scope} Scope#variableScope
*/ */
this.variableScope = this.variableScope =
(this.type === "global" || this.type === "function" || this.type === "module" || this.type === "class-field-initializer") ? this : upperScope.variableScope; this.type === "global" ||
this.type === "module" ||
this.type === "function" ||
this.type === "class-field-initializer" ||
this.type === "class-static-block"
? this
: upperScope.variableScope;
/** /**
* Whether this scope is created by a FunctionExpression. * Whether this scope is created by a FunctionExpression.
@ -803,8 +810,8 @@ class Scope {
resolve(ident) { resolve(ident) {
let ref, i, iz; let ref, i, iz;
assert__default['default'](this.__isClosed(), "Scope should be closed."); assert__default["default"](this.__isClosed(), "Scope should be closed.");
assert__default['default'](ident.type === Syntax$2.Identifier, "Target should be identifier."); assert__default["default"](ident.type === Syntax$2.Identifier, "Target should be identifier.");
for (i = 0, iz = this.references.length; i < iz; ++i) { for (i = 0, iz = this.references.length; i < iz; ++i) {
ref = this.references[i]; ref = this.references[i];
if (ref.identifier === ident) { if (ref.identifier === ident) {
@ -1008,7 +1015,7 @@ class FunctionScope extends Scope {
const variable = this.set.get("arguments"); const variable = this.set.get("arguments");
assert__default['default'](variable, "Always have arguments variable."); assert__default["default"](variable, "Always have arguments variable.");
return variable.tainted || variable.references.length !== 0; return variable.tainted || variable.references.length !== 0;
} }
@ -1072,6 +1079,12 @@ class ClassFieldInitializerScope extends Scope {
} }
} }
class ClassStaticBlockScope extends Scope {
constructor(scopeManager, upperScope, block) {
super(scopeManager, "class-static-block", upperScope, block, true);
}
}
/* vim: set sw=4 ts=4 et tw=80 : */ /* vim: set sw=4 ts=4 et tw=80 : */
/* /*
@ -1124,7 +1137,7 @@ class ScopeManager {
} }
__isNodejsScope() { __isNodejsScope() {
return this.__options.nodejsScope; return this.__options.nodejsScope || this.__options.sourceType === "commonjs";
} }
isModule() { isModule() {
@ -1248,7 +1261,7 @@ class ScopeManager {
__nestScope(scope) { __nestScope(scope) {
if (scope instanceof GlobalScope) { if (scope instanceof GlobalScope) {
assert__default['default'](this.__currentScope === null); assert__default["default"](this.__currentScope === null);
this.globalScope = scope; this.globalScope = scope;
} }
this.__currentScope = scope; this.__currentScope = scope;
@ -1287,6 +1300,10 @@ class ScopeManager {
return this.__nestScope(new ClassFieldInitializerScope(this, this.__currentScope, node)); return this.__nestScope(new ClassFieldInitializerScope(this, this.__currentScope, node));
} }
__nestClassStaticBlockScope(node) {
return this.__nestScope(new ClassStaticBlockScope(this, this.__currentScope, node));
}
__nestSwitchScope(node) { __nestSwitchScope(node) {
return this.__nestScope(new SwitchScope(this, this.__currentScope, node)); return this.__nestScope(new SwitchScope(this, this.__currentScope, node));
} }
@ -1330,7 +1347,7 @@ class ScopeManager {
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
const { Syntax: Syntax$1 } = estraverse__default['default']; const { Syntax: Syntax$1 } = estraverse__default["default"];
/** /**
* Get last array element * Get last array element
@ -1341,7 +1358,7 @@ function getLast(xs) {
return xs[xs.length - 1] || null; return xs[xs.length - 1] || null;
} }
class PatternVisitor extends esrecurse__default['default'].Visitor { class PatternVisitor extends esrecurse__default["default"].Visitor {
static isPattern(node) { static isPattern(node) {
const nodeType = node.type; const nodeType = node.type;
@ -1477,7 +1494,7 @@ class PatternVisitor extends esrecurse__default['default'].Visitor {
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
const { Syntax } = estraverse__default['default']; const { Syntax } = estraverse__default["default"];
/** /**
* Traverse identifier in pattern * Traverse identifier in pattern
@ -1506,7 +1523,7 @@ function traverseIdentifierInPattern(options, rootPattern, referencer, callback)
// FIXME: Now, we don't create module environment, because the context is // FIXME: Now, we don't create module environment, because the context is
// implementation dependent. // implementation dependent.
class Importer extends esrecurse__default['default'].Visitor { class Importer extends esrecurse__default["default"].Visitor {
constructor(declaration, referencer) { constructor(declaration, referencer) {
super(null, referencer.options); super(null, referencer.options);
this.declaration = declaration; this.declaration = declaration;
@ -1553,7 +1570,7 @@ class Importer extends esrecurse__default['default'].Visitor {
} }
// Referencing variables and creating bindings. // Referencing variables and creating bindings.
class Referencer extends esrecurse__default['default'].Visitor { class Referencer extends esrecurse__default["default"].Visitor {
constructor(options, scopeManager) { constructor(options, scopeManager) {
super(null, options); super(null, options);
this.options = options; this.options = options;
@ -1914,6 +1931,14 @@ class Referencer extends esrecurse__default['default'].Visitor {
} }
} }
StaticBlock(node) {
this.scopeManager.__nestClassStaticBlockScope(node);
this.visitChildren(node);
this.close(node);
}
MethodDefinition(node) { MethodDefinition(node) {
this.visitProperty(node); this.visitProperty(node);
} }
@ -2035,7 +2060,7 @@ class Referencer extends esrecurse__default['default'].Visitor {
} }
ImportDeclaration(node) { ImportDeclaration(node) {
assert__default['default'](this.scopeManager.__isES6() && this.scopeManager.isModule(), "ImportDeclaration should appear when the mode is ES6 and in the module context."); assert__default["default"](this.scopeManager.__isES6() && this.scopeManager.isModule(), "ImportDeclaration should appear when the mode is ES6 and in the module context.");
const importer = new Importer(node, this); const importer = new Importer(node, this);
@ -2087,7 +2112,7 @@ class Referencer extends esrecurse__default['default'].Visitor {
/* vim: set sw=4 ts=4 et tw=80 : */ /* vim: set sw=4 ts=4 et tw=80 : */
const version = "6.0.0"; const version = "7.1.0";
/* /*
Copyright (C) 2012-2014 Yusuke Suzuki <utatane.tea@gmail.com> Copyright (C) 2012-2014 Yusuke Suzuki <utatane.tea@gmail.com>
@ -2125,7 +2150,7 @@ function defaultOptions() {
directive: false, directive: false,
nodejsScope: false, nodejsScope: false,
impliedStrict: false, impliedStrict: false,
sourceType: "script", // one of ['script', 'module'] sourceType: "script", // one of ['script', 'module', 'commonjs']
ecmaVersion: 5, ecmaVersion: 5,
childVisitorKeys: null, childVisitorKeys: null,
fallback: "iteration" fallback: "iteration"
@ -2181,7 +2206,7 @@ function updateDeeply(target, override) {
* a function scope immediately following the global scope. * a function scope immediately following the global scope.
* @param {boolean} [providedOptions.impliedStrict=false] implied strict mode * @param {boolean} [providedOptions.impliedStrict=false] implied strict mode
* (if ecmaVersion >= 5). * (if ecmaVersion >= 5).
* @param {string} [providedOptions.sourceType='script'] the source type of the script. one of 'script' and 'module' * @param {string} [providedOptions.sourceType='script'] the source type of the script. one of 'script', 'module', and 'commonjs'
* @param {number} [providedOptions.ecmaVersion=5] which ECMAScript version is considered * @param {number} [providedOptions.ecmaVersion=5] which ECMAScript version is considered
* @param {Object} [providedOptions.childVisitorKeys=null] Additional known visitor keys. See [esrecurse](https://github.com/estools/esrecurse)'s the `childVisitorKeys` option. * @param {Object} [providedOptions.childVisitorKeys=null] Additional known visitor keys. See [esrecurse](https://github.com/estools/esrecurse)'s the `childVisitorKeys` option.
* @param {string} [providedOptions.fallback='iteration'] A kind of the fallback in order to encounter with unknown node. See [esrecurse](https://github.com/estools/esrecurse)'s the `fallback` option. * @param {string} [providedOptions.fallback='iteration'] A kind of the fallback in order to encounter with unknown node. See [esrecurse](https://github.com/estools/esrecurse)'s the `fallback` option.
@ -2194,7 +2219,7 @@ function analyze(tree, providedOptions) {
referencer.visit(tree); referencer.visit(tree);
assert__default['default'](scopeManager.__currentScope === null, "currentScope should be null."); assert__default["default"](scopeManager.__currentScope === null, "currentScope should be null.");
return scopeManager; return scopeManager;
} }

View File

@ -66,7 +66,7 @@ function defaultOptions() {
directive: false, directive: false,
nodejsScope: false, nodejsScope: false,
impliedStrict: false, impliedStrict: false,
sourceType: "script", // one of ['script', 'module'] sourceType: "script", // one of ['script', 'module', 'commonjs']
ecmaVersion: 5, ecmaVersion: 5,
childVisitorKeys: null, childVisitorKeys: null,
fallback: "iteration" fallback: "iteration"
@ -122,7 +122,7 @@ function updateDeeply(target, override) {
* a function scope immediately following the global scope. * a function scope immediately following the global scope.
* @param {boolean} [providedOptions.impliedStrict=false] implied strict mode * @param {boolean} [providedOptions.impliedStrict=false] implied strict mode
* (if ecmaVersion >= 5). * (if ecmaVersion >= 5).
* @param {string} [providedOptions.sourceType='script'] the source type of the script. one of 'script' and 'module' * @param {string} [providedOptions.sourceType='script'] the source type of the script. one of 'script', 'module', and 'commonjs'
* @param {number} [providedOptions.ecmaVersion=5] which ECMAScript version is considered * @param {number} [providedOptions.ecmaVersion=5] which ECMAScript version is considered
* @param {Object} [providedOptions.childVisitorKeys=null] Additional known visitor keys. See [esrecurse](https://github.com/estools/esrecurse)'s the `childVisitorKeys` option. * @param {Object} [providedOptions.childVisitorKeys=null] Additional known visitor keys. See [esrecurse](https://github.com/estools/esrecurse)'s the `childVisitorKeys` option.
* @param {string} [providedOptions.fallback='iteration'] A kind of the fallback in order to encounter with unknown node. See [esrecurse](https://github.com/estools/esrecurse)'s the `fallback` option. * @param {string} [providedOptions.fallback='iteration'] A kind of the fallback in order to encounter with unknown node. See [esrecurse](https://github.com/estools/esrecurse)'s the `fallback` option.

View File

@ -470,6 +470,14 @@ class Referencer extends esrecurse.Visitor {
} }
} }
StaticBlock(node) {
this.scopeManager.__nestClassStaticBlockScope(node);
this.visitChildren(node);
this.close(node);
}
MethodDefinition(node) { MethodDefinition(node) {
this.visitProperty(node); this.visitProperty(node);
} }

View File

@ -28,6 +28,7 @@ import {
BlockScope, BlockScope,
CatchScope, CatchScope,
ClassFieldInitializerScope, ClassFieldInitializerScope,
ClassStaticBlockScope,
ClassScope, ClassScope,
ForScope, ForScope,
FunctionExpressionNameScope, FunctionExpressionNameScope,
@ -65,7 +66,7 @@ class ScopeManager {
} }
__isNodejsScope() { __isNodejsScope() {
return this.__options.nodejsScope; return this.__options.nodejsScope || this.__options.sourceType === "commonjs";
} }
isModule() { isModule() {
@ -228,6 +229,10 @@ class ScopeManager {
return this.__nestScope(new ClassFieldInitializerScope(this, this.__currentScope, node)); return this.__nestScope(new ClassFieldInitializerScope(this, this.__currentScope, node));
} }
__nestClassStaticBlockScope(node) {
return this.__nestScope(new ClassStaticBlockScope(this, this.__currentScope, node));
}
__nestSwitchScope(node) { __nestSwitchScope(node) {
return this.__nestScope(new SwitchScope(this, this.__currentScope, node)); return this.__nestScope(new SwitchScope(this, this.__currentScope, node));
} }

View File

@ -157,7 +157,8 @@ class Scope {
constructor(scopeManager, type, upperScope, block, isMethodDefinition) { constructor(scopeManager, type, upperScope, block, isMethodDefinition) {
/** /**
* One of 'module', 'block', 'switch', 'function', 'catch', 'with', 'function', 'class', 'global'. * One of "global", "module", "function", "function-expression-name", "block", "switch", "catch", "with", "for",
* "class", "class-field-initializer", "class-static-block".
* @member {string} Scope#type * @member {string} Scope#type
*/ */
this.type = type; this.type = type;
@ -225,7 +226,13 @@ class Scope {
* @member {Scope} Scope#variableScope * @member {Scope} Scope#variableScope
*/ */
this.variableScope = this.variableScope =
(this.type === "global" || this.type === "function" || this.type === "module" || this.type === "class-field-initializer") ? this : upperScope.variableScope; this.type === "global" ||
this.type === "module" ||
this.type === "function" ||
this.type === "class-field-initializer" ||
this.type === "class-static-block"
? this
: upperScope.variableScope;
/** /**
* Whether this scope is created by a FunctionExpression. * Whether this scope is created by a FunctionExpression.
@ -738,6 +745,12 @@ class ClassFieldInitializerScope extends Scope {
} }
} }
class ClassStaticBlockScope extends Scope {
constructor(scopeManager, upperScope, block) {
super(scopeManager, "class-static-block", upperScope, block, true);
}
}
export { export {
Scope, Scope,
GlobalScope, GlobalScope,
@ -750,7 +763,8 @@ export {
FunctionScope, FunctionScope,
ForScope, ForScope,
ClassScope, ClassScope,
ClassFieldInitializerScope ClassFieldInitializerScope,
ClassStaticBlockScope
}; };
/* vim: set sw=4 ts=4 et tw=80 : */ /* vim: set sw=4 ts=4 et tw=80 : */

View File

@ -1,3 +1,3 @@
const version = "6.0.0"; const version = "7.1.0";
export default version; export default version;

View File

@ -11,7 +11,7 @@
}, },
"./package.json": "./package.json" "./package.json": "./package.json"
}, },
"version": "6.0.0", "version": "7.1.0",
"engines": { "engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}, },
@ -50,9 +50,9 @@
"eslint-config-eslint": "^7.0.0", "eslint-config-eslint": "^7.0.0",
"eslint-plugin-jsdoc": "^35.4.1", "eslint-plugin-jsdoc": "^35.4.1",
"eslint-plugin-node": "^11.1.0", "eslint-plugin-node": "^11.1.0",
"eslint-release": "^3.1.2", "eslint-release": "^3.2.0",
"eslint-visitor-keys": "^3.0.0", "eslint-visitor-keys": "^3.1.0",
"espree": "^8.0.0", "espree": "^9.0.0",
"mocha": "^9.0.1", "mocha": "^9.0.1",
"npm-license": "^0.3.3", "npm-license": "^0.3.3",
"rollup": "^2.52.7", "rollup": "^2.52.7",

View File

@ -17,7 +17,8 @@ $ npm install eslint-visitor-keys
### Requirements ### Requirements
- [Node.js] 10.0.0 or later. - [Node.js] `^12.22.0`, `^14.17.0`, or `>=16.0.0`
## 📖 Usage ## 📖 Usage
@ -102,5 +103,5 @@ Welcome. See [ESLint contribution guidelines](https://eslint.org/docs/developer-
[npm]: https://www.npmjs.com/ [npm]: https://www.npmjs.com/
[Node.js]: https://nodejs.org/en/ [Node.js]: https://nodejs.org/
[ESTree]: https://github.com/estree/estree [ESTree]: https://github.com/estree/estree

View File

@ -239,6 +239,9 @@ const KEYS = {
SpreadElement: [ SpreadElement: [
"argument" "argument"
], ],
StaticBlock: [
"body"
],
Super: [], Super: [],
SwitchStatement: [ SwitchStatement: [
"discriminant", "discriminant",

View File

@ -235,6 +235,9 @@ const KEYS = {
SpreadElement: [ SpreadElement: [
"argument" "argument"
], ],
StaticBlock: [
"body"
],
Super: [], Super: [],
SwitchStatement: [ SwitchStatement: [
"discriminant", "discriminant",

View File

@ -1,6 +1,6 @@
{ {
"name": "eslint-visitor-keys", "name": "eslint-visitor-keys",
"version": "3.0.0", "version": "3.1.0",
"description": "Constants and utilities about visitor keys to traverse AST.", "description": "Constants and utilities about visitor keys to traverse AST.",
"type": "module", "type": "module",
"main": "dist/eslint-visitor-keys.cjs", "main": "dist/eslint-visitor-keys.cjs",
@ -27,7 +27,7 @@
"eslint-config-eslint": "^7.0.0", "eslint-config-eslint": "^7.0.0",
"eslint-plugin-jsdoc": "^35.4.0", "eslint-plugin-jsdoc": "^35.4.0",
"eslint-plugin-node": "^11.1.0", "eslint-plugin-node": "^11.1.0",
"eslint-release": "^3.1.2", "eslint-release": "^3.2.0",
"mocha": "^9.0.1", "mocha": "^9.0.1",
"opener": "^1.5.2", "opener": "^1.5.2",
"rollup": "^2.52.1" "rollup": "^2.52.1"

View File

@ -145,7 +145,7 @@ const options = {
// You can also set "latest" to use the most recently supported version. // You can also set "latest" to use the most recently supported version.
ecmaVersion: 5, ecmaVersion: 5,
// specify which type of script you're parsing ("script" or "module") // specify which type of script you're parsing ("script", "module", or "commonjs")
sourceType: "script", sourceType: "script",
// specify additional language features // specify additional language features
@ -154,7 +154,7 @@ const options = {
// enable JSX parsing // enable JSX parsing
jsx: false, jsx: false,
// enable return in global scope // enable return in global scope (set to true automatically when sourceType is "commonjs")
globalReturn: false, globalReturn: false,
// enable implied strict mode (if ecmaVersion >= 5) // enable implied strict mode (if ecmaVersion >= 5)
@ -238,6 +238,7 @@ Because ECMAScript 2022 is still under development, we are implementing features
* [Class static fields, static private methods and accessors](https://github.com/tc39/proposal-static-class-features) * [Class static fields, static private methods and accessors](https://github.com/tc39/proposal-static-class-features)
* [RegExp match indices](https://github.com/tc39/proposal-regexp-match-indices) * [RegExp match indices](https://github.com/tc39/proposal-regexp-match-indices)
* [Top-level await](https://github.com/tc39/proposal-top-level-await) * [Top-level await](https://github.com/tc39/proposal-top-level-await)
* [Class static initialization blocks](https://github.com/tc39/proposal-class-static-block)
See [finished-proposals.md](https://github.com/tc39/proposals/blob/master/finished-proposals.md) to know what features are finalized. See [finished-proposals.md](https://github.com/tc39/proposals/blob/master/finished-proposals.md) to know what features are finalized.

View File

@ -17,14 +17,12 @@ function _interopNamespace(e) {
var d = Object.getOwnPropertyDescriptor(e, k); var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : { Object.defineProperty(n, k, d.get ? d : {
enumerable: true, enumerable: true,
get: function () { get: function () { return e[k]; }
return e[k];
}
}); });
} }
}); });
} }
n['default'] = e; n["default"] = e;
return Object.freeze(n); return Object.freeze(n);
} }
@ -462,6 +460,11 @@ function normalizeSourceType(sourceType = "script") {
if (sourceType === "script" || sourceType === "module") { if (sourceType === "script" || sourceType === "module") {
return sourceType; return sourceType;
} }
if (sourceType === "commonjs") {
return "script";
}
throw new Error("Invalid sourceType."); throw new Error("Invalid sourceType.");
} }
@ -477,16 +480,21 @@ function normalizeOptions(options) {
const ranges = options.range === true; const ranges = options.range === true;
const locations = options.loc === true; const locations = options.loc === true;
const allowReserved = ecmaVersion === 3 ? "never" : false; const allowReserved = ecmaVersion === 3 ? "never" : false;
const ecmaFeatures = options.ecmaFeatures || {};
const allowReturnOutsideFunction = options.sourceType === "commonjs" ||
Boolean(ecmaFeatures.globalReturn);
if (sourceType === "module" && ecmaVersion < 6) { if (sourceType === "module" && ecmaVersion < 6) {
throw new Error("sourceType 'module' is not supported when ecmaVersion < 2015. Consider adding `{ ecmaVersion: 2015 }` to the parser options."); throw new Error("sourceType 'module' is not supported when ecmaVersion < 2015. Consider adding `{ ecmaVersion: 2015 }` to the parser options.");
} }
return Object.assign({}, options, { return Object.assign({}, options, {
ecmaVersion, ecmaVersion,
sourceType, sourceType,
ranges, ranges,
locations, locations,
allowReserved allowReserved,
allowReturnOutsideFunction
}); });
} }
@ -546,6 +554,8 @@ var espree = () => Parser => {
code = String(code); code = String(code);
} }
// save original source type in case of commonjs
const originalSourceType = opts.sourceType;
const options = normalizeOptions(opts); const options = normalizeOptions(opts);
const ecmaFeatures = options.ecmaFeatures || {}; const ecmaFeatures = options.ecmaFeatures || {};
const tokenTranslator = const tokenTranslator =
@ -564,7 +574,7 @@ var espree = () => Parser => {
allowReserved: options.allowReserved, allowReserved: options.allowReserved,
// Truthy value is true for backward compatibility. // Truthy value is true for backward compatibility.
allowReturnOutsideFunction: Boolean(ecmaFeatures.globalReturn), allowReturnOutsideFunction: options.allowReturnOutsideFunction,
// Collect tokens // Collect tokens
onToken: token => { onToken: token => {
@ -588,8 +598,13 @@ var espree = () => Parser => {
} }
}, code); }, code);
// Initialize internal state. /*
* Data that is unique to Espree and is not represented internally in
* Acorn. We put all of this data into a symbol property as a way to
* avoid potential naming conflicts with future versions of Acorn.
*/
this[STATE] = { this[STATE] = {
originalSourceType: originalSourceType || options.sourceType,
tokens: tokenTranslator ? [] : null, tokens: tokenTranslator ? [] : null,
comments: options.comment === true ? [] : null, comments: options.comment === true ? [] : null,
impliedStrict: ecmaFeatures.impliedStrict === true && this.options.ecmaVersion >= 5, impliedStrict: ecmaFeatures.impliedStrict === true && this.options.ecmaVersion >= 5,
@ -634,7 +649,7 @@ var espree = () => Parser => {
const extra = this[STATE]; const extra = this[STATE];
const program = super.parse(); const program = super.parse();
program.sourceType = this.options.sourceType; program.sourceType = extra.originalSourceType;
if (extra.comments) { if (extra.comments) {
program.comments = extra.comments; program.comments = extra.comments;
@ -810,7 +825,7 @@ var espree = () => Parser => {
}; };
}; };
const version$1 = "9.0.0"; const version$1 = "9.1.0";
/** /**
* @fileoverview Main Espree file that converts Acorn into Esprima output. * @fileoverview Main Espree file that converts Acorn into Esprima output.
@ -884,7 +899,7 @@ const parsers = {
get jsx() { get jsx() {
if (this._jsx === null) { if (this._jsx === null) {
this._jsx = acorn__namespace.Parser.extend(jsx__default['default'](), espree()); this._jsx = acorn__namespace.Parser.extend(jsx__default["default"](), espree());
} }
return this._jsx; return this._jsx;
}, },

View File

@ -56,6 +56,8 @@ export default () => Parser => {
code = String(code); code = String(code);
} }
// save original source type in case of commonjs
const originalSourceType = opts.sourceType;
const options = normalizeOptions(opts); const options = normalizeOptions(opts);
const ecmaFeatures = options.ecmaFeatures || {}; const ecmaFeatures = options.ecmaFeatures || {};
const tokenTranslator = const tokenTranslator =
@ -74,7 +76,7 @@ export default () => Parser => {
allowReserved: options.allowReserved, allowReserved: options.allowReserved,
// Truthy value is true for backward compatibility. // Truthy value is true for backward compatibility.
allowReturnOutsideFunction: Boolean(ecmaFeatures.globalReturn), allowReturnOutsideFunction: options.allowReturnOutsideFunction,
// Collect tokens // Collect tokens
onToken: token => { onToken: token => {
@ -98,8 +100,13 @@ export default () => Parser => {
} }
}, code); }, code);
// Initialize internal state. /*
* Data that is unique to Espree and is not represented internally in
* Acorn. We put all of this data into a symbol property as a way to
* avoid potential naming conflicts with future versions of Acorn.
*/
this[STATE] = { this[STATE] = {
originalSourceType: originalSourceType || options.sourceType,
tokens: tokenTranslator ? [] : null, tokens: tokenTranslator ? [] : null,
comments: options.comment === true ? [] : null, comments: options.comment === true ? [] : null,
impliedStrict: ecmaFeatures.impliedStrict === true && this.options.ecmaVersion >= 5, impliedStrict: ecmaFeatures.impliedStrict === true && this.options.ecmaVersion >= 5,
@ -144,7 +151,7 @@ export default () => Parser => {
const extra = this[STATE]; const extra = this[STATE];
const program = super.parse(); const program = super.parse();
program.sourceType = this.options.sourceType; program.sourceType = extra.originalSourceType;
if (extra.comments) { if (extra.comments) {
program.comments = extra.comments; program.comments = extra.comments;

View File

@ -73,6 +73,11 @@ function normalizeSourceType(sourceType = "script") {
if (sourceType === "script" || sourceType === "module") { if (sourceType === "script" || sourceType === "module") {
return sourceType; return sourceType;
} }
if (sourceType === "commonjs") {
return "script";
}
throw new Error("Invalid sourceType."); throw new Error("Invalid sourceType.");
} }
@ -88,15 +93,20 @@ export function normalizeOptions(options) {
const ranges = options.range === true; const ranges = options.range === true;
const locations = options.loc === true; const locations = options.loc === true;
const allowReserved = ecmaVersion === 3 ? "never" : false; const allowReserved = ecmaVersion === 3 ? "never" : false;
const ecmaFeatures = options.ecmaFeatures || {};
const allowReturnOutsideFunction = options.sourceType === "commonjs" ||
Boolean(ecmaFeatures.globalReturn);
if (sourceType === "module" && ecmaVersion < 6) { if (sourceType === "module" && ecmaVersion < 6) {
throw new Error("sourceType 'module' is not supported when ecmaVersion < 2015. Consider adding `{ ecmaVersion: 2015 }` to the parser options."); throw new Error("sourceType 'module' is not supported when ecmaVersion < 2015. Consider adding `{ ecmaVersion: 2015 }` to the parser options.");
} }
return Object.assign({}, options, { return Object.assign({}, options, {
ecmaVersion, ecmaVersion,
sourceType, sourceType,
ranges, ranges,
locations, locations,
allowReserved allowReserved,
allowReturnOutsideFunction
}); });
} }

View File

@ -1,3 +1,3 @@
const version = "9.0.0"; const version = "9.1.0";
export default version; export default version;

View File

@ -16,7 +16,7 @@
], ],
"./package.json": "./package.json" "./package.json": "./package.json"
}, },
"version": "9.0.0", "version": "9.1.0",
"files": [ "files": [
"lib", "lib",
"dist/espree.cjs", "dist/espree.cjs",
@ -31,9 +31,9 @@
}, },
"license": "BSD-2-Clause", "license": "BSD-2-Clause",
"dependencies": { "dependencies": {
"acorn": "^8.5.0", "acorn": "^8.6.0",
"acorn-jsx": "^5.3.1", "acorn-jsx": "^5.3.1",
"eslint-visitor-keys": "^3.0.0" "eslint-visitor-keys": "^3.1.0"
}, },
"devDependencies": { "devDependencies": {
"@rollup/plugin-commonjs": "^17.1.0", "@rollup/plugin-commonjs": "^17.1.0",
@ -44,7 +44,7 @@
"eslint-config-eslint": "^7.0.0", "eslint-config-eslint": "^7.0.0",
"eslint-plugin-jsdoc": "^32.2.0", "eslint-plugin-jsdoc": "^32.2.0",
"eslint-plugin-node": "^11.1.0", "eslint-plugin-node": "^11.1.0",
"eslint-release": "^3.1.2", "eslint-release": "^3.2.0",
"esprima": "latest", "esprima": "latest",
"esprima-fb": "^8001.2001.0-dev-harmony-fb", "esprima-fb": "^8001.2001.0-dev-harmony-fb",
"json-diff": "^0.5.4", "json-diff": "^0.5.4",

View File

@ -6,6 +6,18 @@
<sup>**Social Media Photo by [Matt Seymour](https://unsplash.com/@mattseymour) on [Unsplash](https://unsplash.com/)**</sup> <sup>**Social Media Photo by [Matt Seymour](https://unsplash.com/@mattseymour) on [Unsplash](https://unsplash.com/)**</sup>
## Announcement 📣
There is a standard approach to recursion and more data-types than what JSON allow, and it's part of this [Structured Clone Module](https://github.com/ungap/structured-clone/#readme).
Beside acting as a polyfill, its `@ungap/structured-clone/json` export provides both `stringify` and `parse`, and it's been tested for being faster than *flatted*, but its produced output is also smaller than *flatted*.
The *@ungap/structured-clone* module is, in short, a drop in replacement for *flatted*, but it's not compatible with *flatted* specialized syntax.
However, if recursion, as well as more data-types, are what you are after, or interesting for your projects, consider switching to this new module whenever you can 👍
- - -
A super light (0.5K) and fast circular JSON parser, directly from the creator of [CircularJSON](https://github.com/WebReflection/circular-json/#circularjson). A super light (0.5K) and fast circular JSON parser, directly from the creator of [CircularJSON](https://github.com/WebReflection/circular-json/#circularjson).
Now available also for **[PHP](./php/flatted.php)**. Now available also for **[PHP](./php/flatted.php)**.

View File

@ -124,4 +124,4 @@ self.Flatted = (function (exports) {
return exports; return exports;
}({})); })({});

View File

@ -1,6 +1,6 @@
{ {
"name": "flatted", "name": "flatted",
"version": "3.2.2", "version": "3.2.4",
"description": "A super light and fast circular JSON parser.", "description": "A super light and fast circular JSON parser.",
"unpkg": "min.js", "unpkg": "min.js",
"types": "types.d.ts", "types": "types.d.ts",
@ -12,9 +12,9 @@
"rollup:babel": "rollup --config rollup/babel.config.js && sed -i.bck 's/^var /self./' index.js && rm -rf index.js.bck && drop-babel-typeof index.js", "rollup:babel": "rollup --config rollup/babel.config.js && sed -i.bck 's/^var /self./' index.js && rm -rf index.js.bck && drop-babel-typeof index.js",
"min": "terser index.js -c -m -o min.js", "min": "terser index.js -c -m -o min.js",
"size": "cat index.js | wc -c;cat min.js | wc -c;gzip -c9 min.js | wc -c;cat min.js | brotli | wc -c; cat es.js | brotli | wc -c", "size": "cat index.js | wc -c;cat min.js | wc -c;gzip -c9 min.js | wc -c;cat min.js | brotli | wc -c; cat es.js | brotli | wc -c",
"coveralls": "c8 report --reporter=text-lcov | coveralls",
"test": "c8 node test/index.js", "test": "c8 node test/index.js",
"test:php": "php php/test.php" "test:php": "php php/test.php",
"coverage": "mkdir -p ./coverage; c8 report --reporter=text-lcov > ./coverage/lcov.info"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@ -34,20 +34,20 @@
}, },
"homepage": "https://github.com/WebReflection/flatted#readme", "homepage": "https://github.com/WebReflection/flatted#readme",
"devDependencies": { "devDependencies": {
"@babel/core": "^7.14.6", "@babel/core": "^7.16.0",
"@babel/preset-env": "^7.14.7", "@babel/preset-env": "^7.16.0",
"@ungap/structured-clone": "^0.3.4",
"ascjs": "^5.0.1", "ascjs": "^5.0.1",
"c8": "^7.7.3", "c8": "^7.10.0",
"circular-json": "^0.5.9", "circular-json": "^0.5.9",
"circular-json-es6": "^2.0.2", "circular-json-es6": "^2.0.2",
"coveralls": "^3.1.1",
"drop-babel-typeof": "^1.0.3", "drop-babel-typeof": "^1.0.3",
"jsan": "^3.1.13", "jsan": "^3.1.13",
"rollup": "^2.52.8", "rollup": "^2.59.0",
"rollup-plugin-babel": "^4.4.0", "rollup-plugin-babel": "^4.4.0",
"rollup-plugin-node-resolve": "^5.2.0", "rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-terser": "^7.0.2", "rollup-plugin-terser": "^7.0.2",
"terser": "^5.7.1" "terser": "^5.9.0"
}, },
"module": "./esm/index.js", "module": "./esm/index.js",
"type": "module", "type": "module",

View File

@ -1,6 +1,6 @@
{ {
"name": "eslint", "name": "eslint",
"version": "8.2.0", "version": "8.3.0",
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>", "author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
"description": "An AST-based pattern checker for JavaScript.", "description": "An AST-based pattern checker for JavaScript.",
"bin": { "bin": {
@ -56,10 +56,10 @@
"doctrine": "^3.0.0", "doctrine": "^3.0.0",
"enquirer": "^2.3.5", "enquirer": "^2.3.5",
"escape-string-regexp": "^4.0.0", "escape-string-regexp": "^4.0.0",
"eslint-scope": "^6.0.0", "eslint-scope": "^7.1.0",
"eslint-utils": "^3.0.0", "eslint-utils": "^3.0.0",
"eslint-visitor-keys": "^3.0.0", "eslint-visitor-keys": "^3.1.0",
"espree": "^9.0.0", "espree": "^9.1.0",
"esquery": "^1.4.0", "esquery": "^1.4.0",
"esutils": "^2.0.2", "esutils": "^2.0.2",
"fast-deep-equal": "^3.1.3", "fast-deep-equal": "^3.1.3",