Skip to content

Commit

Permalink
Update: support bigint and dynamic import (refs #11803) (#11983)
Browse files Browse the repository at this point in the history
* upgrade deps

* make CodePathAnalyzer handling ImportExpression as throwable

* fix new-cap rule

* fix astUtils.getPrecedence

* fix astUtils.isNullLiteral

* add env.es2020

* fix func-call-spacing rule

* fix function-paren-newline rule

* fix indent rule

* fix no-extra-parens rule

* Upgrade: espree@^6.1.0, eslint-visitor-keys@^1.1.0

* Chore: Ignore tools/internal-rules/node_modules

* Upgrade: acorn@^7.0.0

This avoids a dependency deduplication conflict for developers
  • Loading branch information
mysticatea authored and kaicataldo committed Aug 18, 2019
1 parent afd8012 commit fee6acb
Show file tree
Hide file tree
Showing 17 changed files with 415 additions and 90 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Expand Up @@ -7,6 +7,7 @@
/tests/fixtures/**
/tests/performance/**
/tmp/**
/tools/internal-rules/node_modules/**
/lib/rules/utils/unicode/is-combining-character.js
test.js
!.eslintrc.js
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -13,6 +13,7 @@ versions.json
.eslintcache
.cache
/packages/**/node_modules
/tools/internal-rules/node_modules
/.vscode
.sublimelinterrc
.eslint-release-info.json
Expand Down
87 changes: 72 additions & 15 deletions conf/environments.js
Expand Up @@ -10,15 +10,76 @@

const globals = require("globals");

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

/**
* Get the object that has differentce.
* @param {Record<string,boolean>} current The newer object.
* @param {Record<string,boolean>} prev The older object.
* @returns {Record<string,boolean>} The difference object.
*/
function getDiff(current, prev) {
const retv = {};

for (const [key, value] of Object.entries(current)) {
if (!Object.hasOwnProperty.call(prev, key)) {
retv[key] = value;
}
}

return retv;
}

const newGlobals2015 = getDiff(globals.es2015, globals.es5); // 19 variables such as Promise, Map, ...
const newGlobals2017 = {
Atomics: false,
SharedArrayBuffer: false
};
const newGlobals2020 = {
BigInt: false,
BigInt64Array: false,
BigUint64Array: false
};

//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------

/** @type {Map<string, import("../lib/shared/types").Environment>} */
module.exports = new Map(Object.entries({

// Language
builtin: {
globals: globals.es5
},
es6: {
globals: newGlobals2015,
parserOptions: {
ecmaVersion: 6
}
},
es2015: {
globals: newGlobals2015,
parserOptions: {
ecmaVersion: 6
}
},
es2017: {
globals: { ...newGlobals2015, ...newGlobals2017 },
parserOptions: {
ecmaVersion: 8
}
},
es2020: {
globals: { ...newGlobals2015, ...newGlobals2017, ...newGlobals2020 },
parserOptions: {
ecmaVersion: 11
}
},

// Platforms
browser: {
globals: globals.browser
},
Expand All @@ -30,6 +91,17 @@ module.exports = new Map(Object.entries({
}
}
},
"shared-node-browser": {
globals: globals["shared-node-browser"]
},
worker: {
globals: globals.worker
},
serviceworker: {
globals: globals.serviceworker
},

// Frameworks
commonjs: {
globals: globals.commonjs,
parserOptions: {
Expand All @@ -38,12 +110,6 @@ module.exports = new Map(Object.entries({
}
}
},
"shared-node-browser": {
globals: globals["shared-node-browser"]
},
worker: {
globals: globals.worker
},
amd: {
globals: globals.amd
},
Expand Down Expand Up @@ -86,9 +152,6 @@ module.exports = new Map(Object.entries({
nashorn: {
globals: globals.nashorn
},
serviceworker: {
globals: globals.serviceworker
},
atomtest: {
globals: globals.atomtest
},
Expand All @@ -98,12 +161,6 @@ module.exports = new Map(Object.entries({
webextensions: {
globals: globals.webextensions
},
es6: {
globals: globals.es2015,
parserOptions: {
ecmaVersion: 6
}
},
greasemonkey: {
globals: globals.greasemonkey
}
Expand Down
1 change: 1 addition & 0 deletions lib/linter/code-path-analysis/code-path-analyzer.js
Expand Up @@ -526,6 +526,7 @@ function processCodePathToExit(analyzer, node) {
break;

case "CallExpression":
case "ImportExpression":
case "MemberExpression":
case "NewExpression":
state.makeFirstThrowablePathInTryBlock();
Expand Down
50 changes: 30 additions & 20 deletions lib/rules/func-call-spacing.js
Expand Up @@ -78,21 +78,13 @@ module.exports = {
/**
* Check if open space is present in a function name
* @param {ASTNode} node node to evaluate
* @param {Token} leftToken The last token of the callee. This may be the closing parenthesis that encloses the callee.
* @param {Token} rightToken Tha first token of the arguments. this is the opening parenthesis that encloses the arguments.
* @returns {void}
* @private
*/
function checkSpacing(node) {
const lastToken = sourceCode.getLastToken(node);
const lastCalleeToken = sourceCode.getLastToken(node.callee);
const parenToken = sourceCode.getFirstTokenBetween(lastCalleeToken, lastToken, astUtils.isOpeningParenToken);
const prevToken = parenToken && sourceCode.getTokenBefore(parenToken);

// Parens in NewExpression are optional
if (!(parenToken && parenToken.range[1] < node.range[1])) {
return;
}

const textBetweenTokens = text.slice(prevToken.range[1], parenToken.range[0]).replace(/\/\*.*?\*\//gu, "");
function checkSpacing(node, leftToken, rightToken) {
const textBetweenTokens = text.slice(leftToken.range[1], rightToken.range[0]).replace(/\/\*.*?\*\//gu, "");
const hasWhitespace = /\s/u.test(textBetweenTokens);
const hasNewline = hasWhitespace && astUtils.LINEBREAK_MATCHER.test(textBetweenTokens);

Expand Down Expand Up @@ -123,7 +115,7 @@ module.exports = {
if (never && hasWhitespace) {
context.report({
node,
loc: lastCalleeToken.loc.start,
loc: leftToken.loc.start,
messageId: "unexpected",
fix(fixer) {

Expand All @@ -132,7 +124,7 @@ module.exports = {
* https://github.com/eslint/eslint/issues/7787
*/
if (!hasNewline) {
return fixer.removeRange([prevToken.range[1], parenToken.range[0]]);
return fixer.removeRange([leftToken.range[1], rightToken.range[0]]);
}

return null;
Expand All @@ -141,27 +133,45 @@ module.exports = {
} else if (!never && !hasWhitespace) {
context.report({
node,
loc: lastCalleeToken.loc.start,
loc: leftToken.loc.start,
messageId: "missing",
fix(fixer) {
return fixer.insertTextBefore(parenToken, " ");
return fixer.insertTextBefore(rightToken, " ");
}
});
} else if (!never && !allowNewlines && hasNewline) {
context.report({
node,
loc: lastCalleeToken.loc.start,
loc: leftToken.loc.start,
messageId: "unexpected",
fix(fixer) {
return fixer.replaceTextRange([prevToken.range[1], parenToken.range[0]], " ");
return fixer.replaceTextRange([leftToken.range[1], rightToken.range[0]], " ");
}
});
}
}

return {
CallExpression: checkSpacing,
NewExpression: checkSpacing
"CallExpression, NewExpression"(node) {
const lastToken = sourceCode.getLastToken(node);
const lastCalleeToken = sourceCode.getLastToken(node.callee);
const parenToken = sourceCode.getFirstTokenBetween(lastCalleeToken, lastToken, astUtils.isOpeningParenToken);
const prevToken = parenToken && sourceCode.getTokenBefore(parenToken);

// Parens in NewExpression are optional
if (!(parenToken && parenToken.range[1] < node.range[1])) {
return;
}

checkSpacing(node, prevToken, parenToken);
},

ImportExpression(node) {
const leftToken = sourceCode.getFirstToken(node);
const rightToken = sourceCode.getTokenAfter(leftToken);

checkSpacing(node, leftToken, rightToken);
}
};

}
Expand Down
56 changes: 34 additions & 22 deletions lib/rules/function-paren-newline.js
Expand Up @@ -232,25 +232,15 @@ module.exports = {
};
}

default:
throw new TypeError(`unexpected node with type ${node.type}`);
}
}

/**
* Validates the parentheses for a node
* @param {ASTNode} node The node with parens
* @returns {void}
*/
function validateNode(node) {
const parens = getParenTokens(node);

if (parens) {
validateParens(parens, astUtils.isFunction(node) ? node.params : node.arguments);
case "ImportExpression": {
const leftParen = sourceCode.getFirstToken(node, 1);
const rightParen = sourceCode.getLastToken(node);

if (multilineArgumentsOption) {
validateArguments(parens, astUtils.isFunction(node) ? node.params : node.arguments);
return { leftParen, rightParen };
}

default:
throw new TypeError(`unexpected node with type ${node.type}`);
}
}

Expand All @@ -259,11 +249,33 @@ module.exports = {
//----------------------------------------------------------------------

return {
ArrowFunctionExpression: validateNode,
CallExpression: validateNode,
FunctionDeclaration: validateNode,
FunctionExpression: validateNode,
NewExpression: validateNode
[[
"ArrowFunctionExpression",
"CallExpression",
"FunctionDeclaration",
"FunctionExpression",
"ImportExpression",
"NewExpression"
]](node) {
const parens = getParenTokens(node);
let params;

if (node.type === "ImportExpression") {
params = [node.source];
} else if (astUtils.isFunction(node)) {
params = node.params;
} else {
params = node.arguments;
}

if (parens) {
validateParens(parens, params);

if (multilineArgumentsOption) {
validateArguments(parens, params);
}
}
}
};
}
};
15 changes: 13 additions & 2 deletions lib/rules/indent.js
Expand Up @@ -99,7 +99,8 @@ const KNOWN_NODES = new Set([
"ImportDeclaration",
"ImportSpecifier",
"ImportDefaultSpecifier",
"ImportNamespaceSpecifier"
"ImportNamespaceSpecifier",
"ImportExpression"
]);

/*
Expand Down Expand Up @@ -1109,7 +1110,6 @@ module.exports = {

CallExpression: addFunctionCallIndent,


"ClassDeclaration[superClass], ClassExpression[superClass]"(node) {
const classToken = sourceCode.getFirstToken(node);
const extendsToken = sourceCode.getTokenBefore(node.superClass, astUtils.isNotOpeningParenToken);
Expand Down Expand Up @@ -1236,6 +1236,17 @@ module.exports = {
}
},

ImportExpression(node) {
const openingParen = sourceCode.getFirstToken(node, 1);
const closingParen = sourceCode.getLastToken(node);

parameterParens.add(openingParen);
parameterParens.add(closingParen);
offsets.setDesiredOffset(openingParen, sourceCode.getTokenBefore(openingParen), 0);

addElementListIndent([node.source], openingParen, closingParen, options.CallExpression.arguments);
},

"MemberExpression, JSXMemberExpression, MetaProperty"(node) {
const object = node.type === "MetaProperty" ? node.meta : node.object;
const firstNonObjectToken = sourceCode.getFirstTokenBetween(object, node.property, astUtils.isNotClosingParenToken);
Expand Down
3 changes: 2 additions & 1 deletion lib/rules/new-cap.js
Expand Up @@ -23,7 +23,8 @@ const CAPS_ALLOWED = [
"Object",
"RegExp",
"String",
"Symbol"
"Symbol",
"BigInt"
];

/**
Expand Down

0 comments on commit fee6acb

Please sign in to comment.