Skip to content

Commit

Permalink
Add support for ts4.5 to vue/script-indent rule
Browse files Browse the repository at this point in the history
  • Loading branch information
ota-meshi committed Nov 18, 2021
1 parent 20eaee7 commit 9826ee1
Show file tree
Hide file tree
Showing 11 changed files with 231 additions and 33 deletions.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Expand Up @@ -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,
Expand Down
127 changes: 97 additions & 30 deletions lib/utils/indent-common.js
Expand Up @@ -19,7 +19,8 @@ const {
isNotOpeningBraceToken,
isOpeningBracketToken,
isClosingBracketToken,
isSemicolonToken
isSemicolonToken,
isNotSemicolonToken
} = require('eslint-utils')
const {
isComment,
Expand Down Expand Up @@ -1288,24 +1289,42 @@ 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))
const asToken = tokenStore.getTokenAfter(starToken)
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 */
Expand All @@ -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 */
Expand Down Expand Up @@ -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 */
Expand Down
21 changes: 21 additions & 0 deletions lib/utils/indent-ts.js
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions package.json
Expand Up @@ -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",
Expand All @@ -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"
}
Expand Down
9 changes: 9 additions & 0 deletions tests/fixtures/script-indent/ts-import-assertion-01.vue
@@ -0,0 +1,9 @@
<!--{"parserOptions": {"parser":"@typescript-eslint/parser"}, "requirements": { "@typescript-eslint/parser": ">=5.4.1 || ^5.4.1-0" } }-->
<script lang="ts">
import foo from "./foo.json" assert
{
type
:
"json"
}
</script>
15 changes: 15 additions & 0 deletions tests/fixtures/script-indent/ts-import-assertion-02.vue
@@ -0,0 +1,15 @@
<!--{"parserOptions": {"parser":"@typescript-eslint/parser"}, "requirements": { "@typescript-eslint/parser": ">=5.4.1 || ^5.4.1-0" } }-->
<script lang="ts">
import(
"./foo.json",
{
assert
:
{
type
:
"json"
}
}
)
</script>
10 changes: 10 additions & 0 deletions tests/fixtures/script-indent/ts-import-assertion-03.vue
@@ -0,0 +1,10 @@
<!--{"parserOptions": {"parser":"@typescript-eslint/parser"}, "requirements": { "@typescript-eslint/parser": ">=5.4.1 || ^5.4.1-0" } }-->
<script lang="ts">
export * from "mod" assert
{
type
:
"json"
}
;
</script>
10 changes: 10 additions & 0 deletions tests/fixtures/script-indent/ts-import-assertion-04.vue
@@ -0,0 +1,10 @@
<!--{"parserOptions": {"parser":"@typescript-eslint/parser"}, "requirements": { "@typescript-eslint/parser": ">=5.4.1 || ^5.4.1-0" } }-->
<script lang="ts">
export { foo } from "mod" assert
{
type
:
"json"
}
;
</script>
17 changes: 17 additions & 0 deletions tests/fixtures/script-indent/ts-type-only-import-export-01.vue
@@ -0,0 +1,17 @@
<!--{"parserOptions": {"parser":"@typescript-eslint/parser"}, "requirements": { "@typescript-eslint/parser": ">=5.4.0 || ^5.4.1-0" } }-->
<script lang="ts">
import
type
Foo
from
'foo'
import
type
{
Foo
}
from
'foo';
export
type Foo = {}
</script>
23 changes: 23 additions & 0 deletions tests/fixtures/script-indent/ts-type-only-import-export-02.vue
@@ -0,0 +1,23 @@
<!--{"parserOptions": {"parser":"@typescript-eslint/parser"}, "requirements": { "@typescript-eslint/parser": ">=5.4.0 || ^5.4.1-0" } }-->
<script lang="ts">
import
{
type
Foo
}
from
'foo';
export
{
type
Bar
}
from
'bar';
export
{
type
Baz
}
;
</script>
26 changes: 26 additions & 0 deletions tests/fixtures/script-indent/ts-type-only-import-export-03.vue
@@ -0,0 +1,26 @@
<!--{"parserOptions": {"parser":"@typescript-eslint/parser"}, "requirements": { "@typescript-eslint/parser": ">=5.4.0 || ^5.4.1-0" } }-->
<script lang="ts">
import
{
type
Foo
as Foo2
}
from
'foo';
export
{
type
Bar
as Bar2
}
from
'bar';
export
{
type
Baz
as Baz2
}
;
</script>

0 comments on commit 9826ee1

Please sign in to comment.