From cb963b9b2da80af1aaba2deafa762867b038bc56 Mon Sep 17 00:00:00 2001 From: yosuke ota Date: Thu, 18 Nov 2021 16:45:34 +0900 Subject: [PATCH 1/2] Add support for ts4.5 to `vue/script-indent` rule --- .vscode/settings.json | 2 +- lib/utils/indent-common.js | 127 +++++++++++++----- lib/utils/indent-ts.js | 21 +++ package.json | 4 +- .../script-indent/ts-import-assertion-01.vue | 9 ++ .../script-indent/ts-import-assertion-02.vue | 15 +++ .../script-indent/ts-import-assertion-03.vue | 10 ++ .../script-indent/ts-import-assertion-04.vue | 10 ++ .../ts-type-only-import-export-01.vue | 17 +++ .../ts-type-only-import-export-02.vue | 23 ++++ .../ts-type-only-import-export-03.vue | 26 ++++ 11 files changed, 231 insertions(+), 33 deletions(-) create mode 100644 tests/fixtures/script-indent/ts-import-assertion-01.vue create mode 100644 tests/fixtures/script-indent/ts-import-assertion-02.vue create mode 100644 tests/fixtures/script-indent/ts-import-assertion-03.vue create mode 100644 tests/fixtures/script-indent/ts-import-assertion-04.vue create mode 100644 tests/fixtures/script-indent/ts-type-only-import-export-01.vue create mode 100644 tests/fixtures/script-indent/ts-type-only-import-export-02.vue create mode 100644 tests/fixtures/script-indent/ts-type-only-import-export-03.vue diff --git a/.vscode/settings.json b/.vscode/settings.json index 7bb646536..80e1f88fd 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,7 +10,7 @@ "json", "jsonc" ], - "typescript.tsdk": "node_modules/typescript/lib", + "typescript.tsdk": "./node_modules/typescript/lib", "vetur.validation.script": false, "[typescript]": { "editor.formatOnSave": true, diff --git a/lib/utils/indent-common.js b/lib/utils/indent-common.js index 39ef58670..d208d5a08 100644 --- a/lib/utils/indent-common.js +++ b/lib/utils/indent-common.js @@ -19,7 +19,8 @@ const { isNotOpeningBraceToken, isOpeningBracketToken, isClosingBracketToken, - isSemicolonToken + isSemicolonToken, + isNotSemicolonToken } = require('eslint-utils') const { isComment, @@ -1288,13 +1289,13 @@ module.exports.defineVisitor = function create( }, /** @param {ExportAllDeclaration} node */ ExportAllDeclaration(node) { - const tokens = tokenStore.getTokens(node) - const firstToken = /** @type {Token} */ (tokens.shift()) - if (isSemicolonToken(tokens[tokens.length - 1])) { - tokens.pop() - } + const exportToken = tokenStore.getFirstToken(node) + const tokens = [ + ...tokenStore.getTokensBetween(exportToken, node.source), + tokenStore.getFirstToken(node.source) + ] if (!node.exported) { - setOffset(tokens, 1, firstToken) + setOffset(tokens, 1, exportToken) } else { // export * as foo from "mod" const starToken = /** @type {Token} */ (tokens.find(isWildcard)) @@ -1302,10 +1303,28 @@ module.exports.defineVisitor = function create( const exportedToken = tokenStore.getTokenAfter(asToken) const afterTokens = tokens.slice(tokens.indexOf(exportedToken) + 1) - setOffset(starToken, 1, firstToken) + setOffset(starToken, 1, exportToken) setOffset(asToken, 1, starToken) setOffset(exportedToken, 1, starToken) - setOffset(afterTokens, 1, firstToken) + setOffset(afterTokens, 1, exportToken) + } + + // assertions + const lastToken = /** @type {Token} */ ( + tokenStore.getLastToken(node, isNotSemicolonToken) + ) + const assertionTokens = tokenStore.getTokensBetween( + node.source, + lastToken + ) + if (assertionTokens.length) { + const assertToken = /** @type {Token} */ (assertionTokens.shift()) + setOffset(assertToken, 0, exportToken) + const assertionOpen = assertionTokens.shift() + if (assertionOpen) { + setOffset(assertionOpen, 1, assertToken) + processNodeList(assertionTokens, assertionOpen, lastToken, 1) + } } }, /** @param {ExportDefaultDeclaration} node */ @@ -1328,28 +1347,66 @@ module.exports.defineVisitor = function create( const firstSpecifier = node.specifiers[0] if (!firstSpecifier || firstSpecifier.type === 'ExportSpecifier') { // export {foo, bar}; or export {foo, bar} from "mod"; - const leftParenToken = tokenStore.getFirstToken(node, 1) - const rightParenToken = /** @type {Token} */ ( - tokenStore.getLastToken(node, isClosingBraceToken) + const leftBraceTokens = firstSpecifier + ? tokenStore.getTokensBetween(exportToken, firstSpecifier) + : [tokenStore.getTokenAfter(exportToken)] + const rightBraceToken = /** @type {Token} */ ( + node.source + ? tokenStore.getTokenBefore(node.source, isClosingBraceToken) + : tokenStore.getLastToken(node, isClosingBraceToken) + ) + setOffset(leftBraceTokens, 0, exportToken) + processNodeList( + node.specifiers, + /** @type {Token} */ (last(leftBraceTokens)), + rightBraceToken, + 1 ) - setOffset(leftParenToken, 0, exportToken) - processNodeList(node.specifiers, leftParenToken, rightParenToken, 1) - - const maybeFromToken = tokenStore.getTokenAfter(rightParenToken) - if (maybeFromToken != null && maybeFromToken.value === 'from') { - const fromToken = maybeFromToken - const nameToken = tokenStore.getTokenAfter(fromToken) - setOffset([fromToken, nameToken], 1, exportToken) + + if (node.source) { + const tokens = tokenStore.getTokensBetween( + rightBraceToken, + node.source + ) + setOffset( + [...tokens, sourceCode.getFirstToken(node.source)], + 1, + exportToken + ) + + // assertions + const lastToken = /** @type {Token} */ ( + tokenStore.getLastToken(node, isNotSemicolonToken) + ) + const assertionTokens = tokenStore.getTokensBetween( + node.source, + lastToken + ) + if (assertionTokens.length) { + const assertToken = /** @type {Token} */ (assertionTokens.shift()) + setOffset(assertToken, 0, exportToken) + const assertionOpen = assertionTokens.shift() + if (assertionOpen) { + setOffset(assertionOpen, 1, assertToken) + processNodeList(assertionTokens, assertionOpen, lastToken, 1) + } + } } } else { // maybe babel parser } } }, - /** @param {ExportSpecifier} node */ - ExportSpecifier(node) { + /** @param {ExportSpecifier | ImportSpecifier} node */ + 'ExportSpecifier, ImportSpecifier'(node) { const tokens = tokenStore.getTokens(node) - const firstToken = /** @type {Token} */ (tokens.shift()) + let firstToken = /** @type {Token} */ (tokens.shift()) + if (firstToken.value === 'type') { + const typeToken = firstToken + firstToken = /** @type {Token} */ (tokens.shift()) + setOffset(firstToken, 0, typeToken) + } + setOffset(tokens, 1, firstToken) }, /** @param {ForInStatement | ForOfStatement} node */ @@ -1540,13 +1597,23 @@ module.exports.defineVisitor = function create( setOffset(fromToken, 1, importToken) setOffset(afterTokens, 0, fromToken) } - }, - /** @param {ImportSpecifier} node */ - ImportSpecifier(node) { - if (node.local.range[0] !== node.imported.range[0]) { - const tokens = tokenStore.getTokens(node) - const firstToken = /** @type {Token} */ (tokens.shift()) - setOffset(tokens, 1, firstToken) + + // assertions + const lastToken = /** @type {Token} */ ( + tokenStore.getLastToken(node, isNotSemicolonToken) + ) + const assertionTokens = tokenStore.getTokensBetween( + node.source, + lastToken + ) + if (assertionTokens.length) { + const assertToken = /** @type {Token} */ (assertionTokens.shift()) + setOffset(assertToken, 0, importToken) + const assertionOpen = assertionTokens.shift() + if (assertionOpen) { + setOffset(assertionOpen, 1, assertToken) + processNodeList(assertionTokens, assertionOpen, lastToken, 1) + } } }, /** @param {ImportNamespaceSpecifier} node */ diff --git a/lib/utils/indent-ts.js b/lib/utils/indent-ts.js index b98e9d105..496e892cd 100644 --- a/lib/utils/indent-ts.js +++ b/lib/utils/indent-ts.js @@ -1302,6 +1302,27 @@ function defineVisitor({ setOffset(atToken, 0, tokenStore.getFirstToken(decorators[0])) } }, + ImportAttribute(node) { + const firstToken = tokenStore.getFirstToken(node) + const keyTokens = getFirstAndLastTokens(node.key) + const prefixTokens = tokenStore.getTokensBetween( + firstToken, + keyTokens.firstToken + ) + setOffset(prefixTokens, 0, firstToken) + + setOffset(keyTokens.firstToken, 0, firstToken) + + const initToken = tokenStore.getFirstToken(node.value) + setOffset( + [ + ...tokenStore.getTokensBetween(keyTokens.lastToken, initToken), + initToken + ], + 1, + keyTokens.lastToken + ) + }, // ---------------------------------------------------------------------- // DEPRECATED NODES diff --git a/package.json b/package.json index 2c9bcbf18..f233fbd63 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "@types/natural-compare": "^1.4.0", "@types/node": "^13.13.5", "@types/semver": "^7.2.0", - "@typescript-eslint/parser": "^5.4.0", + "@typescript-eslint/parser": "^5.4.1-0", "@vuepress/plugin-pwa": "^1.4.1", "acorn": "^8.5.0", "env-cmd": "^10.1.0", @@ -82,7 +82,7 @@ "mocha": "^7.1.2", "nyc": "^15.1.0", "prettier": "^2.4.1", - "typescript": "^4.5.0-0", + "typescript": "^4.5.0", "vue-eslint-editor": "^1.1.0", "vuepress": "^1.8.2" } diff --git a/tests/fixtures/script-indent/ts-import-assertion-01.vue b/tests/fixtures/script-indent/ts-import-assertion-01.vue new file mode 100644 index 000000000..f14761841 --- /dev/null +++ b/tests/fixtures/script-indent/ts-import-assertion-01.vue @@ -0,0 +1,9 @@ + + diff --git a/tests/fixtures/script-indent/ts-import-assertion-02.vue b/tests/fixtures/script-indent/ts-import-assertion-02.vue new file mode 100644 index 000000000..86fe80b4e --- /dev/null +++ b/tests/fixtures/script-indent/ts-import-assertion-02.vue @@ -0,0 +1,15 @@ + + diff --git a/tests/fixtures/script-indent/ts-import-assertion-03.vue b/tests/fixtures/script-indent/ts-import-assertion-03.vue new file mode 100644 index 000000000..ee88e92ce --- /dev/null +++ b/tests/fixtures/script-indent/ts-import-assertion-03.vue @@ -0,0 +1,10 @@ + + diff --git a/tests/fixtures/script-indent/ts-import-assertion-04.vue b/tests/fixtures/script-indent/ts-import-assertion-04.vue new file mode 100644 index 000000000..76d2f2860 --- /dev/null +++ b/tests/fixtures/script-indent/ts-import-assertion-04.vue @@ -0,0 +1,10 @@ + + diff --git a/tests/fixtures/script-indent/ts-type-only-import-export-01.vue b/tests/fixtures/script-indent/ts-type-only-import-export-01.vue new file mode 100644 index 000000000..97c6dc192 --- /dev/null +++ b/tests/fixtures/script-indent/ts-type-only-import-export-01.vue @@ -0,0 +1,17 @@ + + diff --git a/tests/fixtures/script-indent/ts-type-only-import-export-02.vue b/tests/fixtures/script-indent/ts-type-only-import-export-02.vue new file mode 100644 index 000000000..0ef5f1106 --- /dev/null +++ b/tests/fixtures/script-indent/ts-type-only-import-export-02.vue @@ -0,0 +1,23 @@ + + diff --git a/tests/fixtures/script-indent/ts-type-only-import-export-03.vue b/tests/fixtures/script-indent/ts-type-only-import-export-03.vue new file mode 100644 index 000000000..ca280f03c --- /dev/null +++ b/tests/fixtures/script-indent/ts-type-only-import-export-03.vue @@ -0,0 +1,26 @@ + + From 0fb2c94633b103c9b99a86d6b6d7001f5aadc405 Mon Sep 17 00:00:00 2001 From: yosuke ota Date: Tue, 30 Nov 2021 14:03:07 +0900 Subject: [PATCH 2/2] update deps --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f233fbd63..96da9be83 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "@types/natural-compare": "^1.4.0", "@types/node": "^13.13.5", "@types/semver": "^7.2.0", - "@typescript-eslint/parser": "^5.4.1-0", + "@typescript-eslint/parser": "^5.5.0", "@vuepress/plugin-pwa": "^1.4.1", "acorn": "^8.5.0", "env-cmd": "^10.1.0",