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..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.0",
+ "@typescript-eslint/parser": "^5.5.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 @@
+
+