Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update: support bigint and dynamic import (refs #11803) #11983

Merged
merged 13 commits into from Aug 18, 2019
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