From 5862427fdc3780233eb3e7836dcd6f460b294607 Mon Sep 17 00:00:00 2001 From: fisker Date: Wed, 18 Mar 2020 15:39:45 +0800 Subject: [PATCH 1/2] `prefer-spread`: Insert semicolon in more cases --- rules/prefer-spread.js | 15 +++++ test/prefer-spread.js | 126 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+) diff --git a/rules/prefer-spread.js b/rules/prefer-spread.js index e00d63ab11..54758292de 100644 --- a/rules/prefer-spread.js +++ b/rules/prefer-spread.js @@ -13,6 +13,17 @@ const selector = [ '[arguments.0.type!="ObjectExpression"]' ].join(''); +// https://github.com/eslint/espree/blob/6b7d0b8100537dcd5c84a7fb17bbe28edcabe05d/lib/token-translator.js#L20 +const tokenTypesCantFollowOpenBracket = new Set([ + 'String', + 'Null', + 'Boolean', + 'Numeric', + 'Template', + 'RegularExpression', + 'Identifier' +]); + const create = context => { const sourceCode = context.getSourceCode(); const getSource = node => sourceCode.getText(node); @@ -32,6 +43,10 @@ const create = context => { } } + if (tokenTypesCantFollowOpenBracket.has(type)) { + return true; + } + const lastBlockNode = sourceCode.getNodeByRangeIndex(tokenBefore.range[0]); if (lastBlockNode && lastBlockNode.type === 'ObjectExpression') { return true; diff --git a/test/prefer-spread.js b/test/prefer-spread.js index 2c8b05ffa5..44fb4c5f72 100644 --- a/test/prefer-spread.js +++ b/test/prefer-spread.js @@ -124,6 +124,8 @@ ruleTester.run('prefer-spread', rule, { ], output: '[...document.querySelectorAll("*")].map(() => {});' }, + + // Semicolon // #254 { code: ` @@ -140,6 +142,130 @@ ruleTester.run('prefer-spread', rule, { ;[...arrayLike].forEach(doSomething) ` }, + { + code: ` + const foo = "1" + Array.from(arrayLike).forEach(doSomething) + `, + errors: [{}], + output: ` + const foo = "1" + ;[...arrayLike].forEach(doSomething) + ` + }, + { + code: ` + const foo = null + Array.from(arrayLike).forEach(doSomething) + `, + errors: [{}], + output: ` + const foo = null + ;[...arrayLike].forEach(doSomething) + ` + }, + { + code: ` + const foo = true + Array.from(arrayLike).forEach(doSomething) + `, + errors: [{}], + output: ` + const foo = true + ;[...arrayLike].forEach(doSomething) + ` + }, + { + code: ` + const foo = 1 + Array.from(arrayLike).forEach(doSomething) + `, + errors: [{}], + output: ` + const foo = 1 + ;[...arrayLike].forEach(doSomething) + ` + }, + { + code: ` + const foo = /./ + Array.from(arrayLike).forEach(doSomething) + `, + errors: [{}], + output: ` + const foo = /./ + ;[...arrayLike].forEach(doSomething) + ` + }, + { + code: ` + const foo = /./g + Array.from(arrayLike).forEach(doSomething) + `, + errors: [{}], + output: ` + const foo = /./g + ;[...arrayLike].forEach(doSomething) + ` + }, + { + code: ` + const foo = bar + Array.from(arrayLike).forEach(doSomething) + `, + errors: [{}], + output: ` + const foo = bar + ;[...arrayLike].forEach(doSomething) + ` + }, + { + code: ` + const foo = bar.baz + Array.from(arrayLike).forEach(doSomething) + `, + errors: [{}], + output: ` + const foo = bar.baz + ;[...arrayLike].forEach(doSomething) + ` + }, + { + code: ` + function* foo() { + yield Array.from(arrayLike).forEach(doSomething) + } + `, + errors: [{}], + output: ` + function* foo() { + yield [...arrayLike].forEach(doSomething) + } + ` + }, + { + code: ` + const foo = \`bar\` + Array.from(arrayLike).forEach(doSomething) + `, + errors: [{}], + output: ` + const foo = \`bar\` + ;[...arrayLike].forEach(doSomething) + ` + }, + { + code: ` + const foo = []; + Array.from(arrayLike).forEach(doSomething) + `, + errors: [{}], + output: ` + const foo = []; + [...arrayLike].forEach(doSomething) + ` + }, + // https://github.com/gatsbyjs/gatsby/blob/e720d8efe58eba0f6fae9f26ec8879128967d0b5/packages/gatsby/src/bootstrap/page-hot-reloader.js#L30 { code: ` From 41547fc0b92b71a8ab7541f439f237a490834704 Mon Sep 17 00:00:00 2001 From: fisker Date: Wed, 18 Mar 2020 17:23:29 +0800 Subject: [PATCH 2/2] Fix integration test --- rules/prefer-spread.js | 13 ++++++++++--- test/prefer-spread.js | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/rules/prefer-spread.js b/rules/prefer-spread.js index 54758292de..1176477001 100644 --- a/rules/prefer-spread.js +++ b/rules/prefer-spread.js @@ -19,9 +19,7 @@ const tokenTypesCantFollowOpenBracket = new Set([ 'Null', 'Boolean', 'Numeric', - 'Template', - 'RegularExpression', - 'Identifier' + 'RegularExpression' ]); const create = context => { @@ -47,10 +45,19 @@ const create = context => { return true; } + if (type === 'Template') { + return !value.endsWith('${'); + } + const lastBlockNode = sourceCode.getNodeByRangeIndex(tokenBefore.range[0]); if (lastBlockNode && lastBlockNode.type === 'ObjectExpression') { return true; } + + // `for...of` + if (type === 'Identifier') { + return !(value === 'of' && lastBlockNode && lastBlockNode.type === 'ForOfStatement'); + } } return false; diff --git a/test/prefer-spread.js b/test/prefer-spread.js index 44fb4c5f72..0fec869562 100644 --- a/test/prefer-spread.js +++ b/test/prefer-spread.js @@ -265,6 +265,39 @@ ruleTester.run('prefer-spread', rule, { [...arrayLike].forEach(doSomething) ` }, + // https://github.com/angular/angular/blob/9e70bcb34f91d439f5203dc22a44f323d02c4648/packages/benchpress/src/webdriver/selenium_webdriver_adapter.ts#L37 + // TokenType of `of` is `Identifier` + { + code: ` + for (const key of Array.from(arrayLike)) { + } + `, + errors: [{}], + output: ` + for (const key of [...arrayLike]) { + } + ` + }, + // TokenType of `in` is `Keyword` + { + code: ` + for (const key in Array.from(arrayLike)) { + } + `, + errors: [{}], + output: ` + for (const key in [...arrayLike]) { + } + ` + }, + // https://github.com/facebook/relay/blob/c7dd4cc33eb2dba82629884bff865f0905fc269e/packages/relay-compiler/transforms/ValidateUnusedVariablesTransform.js#L57 + { + // eslint-disable-next-line no-template-curly-in-string + code: 'const foo = `${Array.from(arrayLike)}`', + errors: [{}], + // eslint-disable-next-line no-template-curly-in-string + output: 'const foo = `${[...arrayLike]}`' + }, // https://github.com/gatsbyjs/gatsby/blob/e720d8efe58eba0f6fae9f26ec8879128967d0b5/packages/gatsby/src/bootstrap/page-hot-reloader.js#L30 {