Skip to content

Commit

Permalink
Improve indent rule to support more ts syntax (#2042)
Browse files Browse the repository at this point in the history
Co-authored-by: Flo Edelmann <[email protected]>
  • Loading branch information
ota-meshi and FloEdelmann authored Dec 25, 2022
1 parent 89fb2fe commit e42f737
Show file tree
Hide file tree
Showing 14 changed files with 196 additions and 23 deletions.
17 changes: 14 additions & 3 deletions lib/utils/indent-common.js
Original file line number Diff line number Diff line change
Expand Up @@ -1171,11 +1171,18 @@ module.exports.defineVisitor = function create(
const firstToken = tokenStore.getFirstToken(node)
const rightToken = tokenStore.getLastToken(node)
const leftToken = /** @type {Token} */ (
tokenStore.getTokenAfter(node.callee, isOpeningParenToken)
tokenStore.getTokenAfter(
node.typeParameters || node.callee,
isOpeningParenToken
)
)

if (node.typeParameters) {
setOffset(tokenStore.getFirstToken(node.typeParameters), 1, firstToken)
}

for (const optionalToken of tokenStore.getTokensBetween(
tokenStore.getLastToken(node.callee),
tokenStore.getLastToken(node.typeParameters || node.callee),
leftToken,
isOptionalToken
)) {
Expand Down Expand Up @@ -1692,12 +1699,16 @@ module.exports.defineVisitor = function create(
const rightToken = tokenStore.getLastToken(node)
const leftToken = isClosingParenToken(rightToken)
? tokenStore.getFirstTokenBetween(
node.callee,
node.typeParameters || node.callee,
rightToken,
isOpeningParenToken
)
: null

if (node.typeParameters) {
setOffset(tokenStore.getFirstToken(node.typeParameters), 1, calleeToken)
}

setOffset(calleeToken, 1, newToken)
if (leftToken != null) {
setOffset(leftToken, 1, calleeToken)
Expand Down
95 changes: 77 additions & 18 deletions lib/utils/indent-ts.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const { isTypeNode } = require('./ts-ast-utils')
* @typedef {import('@typescript-eslint/types').TSESTree.TSImportEqualsDeclaration} TSImportEqualsDeclaration
* @typedef {import('@typescript-eslint/types').TSESTree.TSAbstractMethodDefinition} TSAbstractMethodDefinition
* @typedef {import('@typescript-eslint/types').TSESTree.TSAbstractPropertyDefinition} TSAbstractPropertyDefinition
* @typedef {import('@typescript-eslint/types').TSESTree.TSAbstractAccessorProperty} TSAbstractAccessorProperty
* @typedef {import('@typescript-eslint/types').TSESTree.TSEnumMember} TSEnumMember
* @typedef {import('@typescript-eslint/types').TSESTree.TSPropertySignature} TSPropertySignature
* @typedef {import('@typescript-eslint/types').TSESTree.TSIndexSignature} TSIndexSignature
Expand All @@ -50,6 +51,10 @@ const { isTypeNode } = require('./ts-ast-utils')
* @typedef {import('@typescript-eslint/types').TSESTree.TSInferType} TSInferType
* @typedef {import('@typescript-eslint/types').TSESTree.TSOptionalType} TSOptionalType
* @typedef {import('@typescript-eslint/types').TSESTree.TSNonNullExpression} TSNonNullExpression
* @typedef {import('@typescript-eslint/types').TSESTree.TSAsExpression} TSAsExpression
* @typedef {import('@typescript-eslint/types').TSESTree.TSSatisfiesExpression} TSSatisfiesExpression
* @typedef {import('@typescript-eslint/types').TSESTree.TSTypeReference} TSTypeReference
* @typedef {import('@typescript-eslint/types').TSESTree.TSInstantiationExpression} TSInstantiationExpression
* @typedef {import('@typescript-eslint/types').TSESTree.JSXChild} JSXChild
* @typedef {import('@typescript-eslint/types').TSESTree.TypeNode} TypeNode
*
Expand Down Expand Up @@ -206,15 +211,16 @@ function defineVisitor({
* | TSImportEqualsDeclaration
* | TSAbstractMethodDefinition
* | TSAbstractPropertyDefinition
* | TSAbstractClassProperty
* | TSAbstractAccessorProperty
* | TSEnumMember
* | ClassProperty
* | TSPropertySignature
* | TSIndexSignature
* | TSMethodSignature} node
* | TSMethodSignature
* | ClassProperty
* | TSAbstractClassProperty} node
*/
['TSTypeAliasDeclaration, TSCallSignatureDeclaration, TSConstructSignatureDeclaration, TSImportEqualsDeclaration,' +
'TSAbstractMethodDefinition, TSAbstractPropertyDefinition, TSEnumMember,' +
'TSAbstractMethodDefinition, TSAbstractPropertyDefinition, TSAbstractAccessorProperty, TSEnumMember,' +
'TSPropertySignature, TSIndexSignature, TSMethodSignature,' +
// Deprecated in @typescript-eslint/parser v5
'ClassProperty, TSAbstractClassProperty'](node) {
Expand Down Expand Up @@ -279,40 +285,57 @@ function defineVisitor({
}
},
/**
* Process as expression
* Process as expression or satisfies expression
*
* e.g.
* ```
* var foo = bar as boolean
* // ^^^^^^^^^^^^^^
* ```
*
* e.g.
* ```
* var foo = bar satisfies Bar
* // ^^^^^^^^^^^^^^^^^
* ```
*
* @param {TSAsExpression | TSSatisfiesExpression} node
*/
TSAsExpression(node) {
'TSAsExpression, TSSatisfiesExpression'(node) {
const expressionTokens = getFirstAndLastTokens(node.expression)
const asToken = tokenStore.getTokenAfter(expressionTokens.lastToken)
const asOrSatisfiesToken = tokenStore.getTokenAfter(
expressionTokens.lastToken
)
setOffset(
[asToken, getFirstAndLastTokens(node.typeAnnotation).firstToken],
[
asOrSatisfiesToken,
getFirstAndLastTokens(node.typeAnnotation).firstToken
],
1,
expressionTokens.firstToken
)
},
/**
* Process type reference
* Process type reference and instantiation expression
*
* e.g.
* ```
* const foo: Type<P>
* // ^^^^^^^
* ```
*
* e.g.
* ```
* const ErrorMap = Map<string, Error>;
* // ^^^^^^^^^^^^^^^^^^
* ```
*
* @param {TSTypeReference | TSInstantiationExpression} node
*/
TSTypeReference(node) {
'TSTypeReference, TSInstantiationExpression'(node) {
if (node.typeParameters) {
const typeNameTokens = getFirstAndLastTokens(node.typeName)
setOffset(
tokenStore.getFirstToken(node.typeParameters),
1,
typeNameTokens.firstToken
)
const firstToken = tokenStore.getFirstToken(node)
setOffset(tokenStore.getFirstToken(node.typeParameters), 1, firstToken)
}
},
/**
Expand Down Expand Up @@ -1053,10 +1076,10 @@ function defineVisitor({
* // ^^^^^^^
* ```
*
* @param {TSAbstractMethodDefinition | TSAbstractPropertyDefinition | TSEnumMember | TSAbstractClassProperty | ClassProperty} node
* @param {TSAbstractMethodDefinition | TSAbstractPropertyDefinition | TSAbstractAccessorProperty | TSEnumMember | TSAbstractClassProperty | ClassProperty} node
*
*/
['TSAbstractMethodDefinition, TSAbstractPropertyDefinition, TSEnumMember,' +
['TSAbstractMethodDefinition, TSAbstractPropertyDefinition, TSAbstractAccessorProperty, TSEnumMember,' +
// Deprecated in @typescript-eslint/parser v5
'ClassProperty, TSAbstractClassProperty'](node) {
const { keyNode, valueNode } =
Expand Down Expand Up @@ -1302,6 +1325,42 @@ function defineVisitor({
setOffset(atToken, 0, tokenStore.getFirstToken(decorators[0]))
}
},
AccessorProperty(node) {
const keyNode = node.key
const valueNode = node.value
const firstToken = tokenStore.getFirstToken(node)
const keyTokens = getFirstAndLastTokens(keyNode)
const prefixTokens = tokenStore.getTokensBetween(
firstToken,
keyTokens.firstToken
)
if (node.computed) {
prefixTokens.pop() // pop opening bracket character (`[`)
}
setOffset(prefixTokens, 0, firstToken)
let lastKeyToken
if (node.computed) {
const leftBracketToken = tokenStore.getTokenBefore(keyTokens.firstToken)
const rightBracketToken = (lastKeyToken = tokenStore.getTokenAfter(
keyTokens.lastToken
))
setOffset(leftBracketToken, 0, firstToken)
processNodeList([keyNode], leftBracketToken, rightBracketToken, 1)
} else {
setOffset(keyTokens.firstToken, 0, firstToken)
lastKeyToken = keyTokens.lastToken
}

if (valueNode != null) {
const initToken = tokenStore.getFirstToken(valueNode)
setOffset(
[...tokenStore.getTokensBetween(lastKeyToken, initToken), initToken],
1,
lastKeyToken
)
}
processSemicolons(node)
},
ImportAttribute(node) {
const firstToken = tokenStore.getFirstToken(node)
const keyTokens = getFirstAndLastTokens(node.key)
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
"@types/node": "^13.13.5",
"@types/semver": "^7.3.9",
"@types/xml-name-validator": "^4.0.0",
"@typescript-eslint/parser": "^5.23.0",
"@typescript-eslint/parser": "^5.45.0",
"assert": "^2.0.0",
"env-cmd": "^10.1.0",
"esbuild": "^0.15.15",
Expand All @@ -90,7 +90,7 @@
"mocha": "^10.0.0",
"nyc": "^15.1.0",
"prettier": "^2.6.2",
"typescript": "^4.6.4",
"typescript": "^4.9.3",
"vitepress": "^1.0.0-alpha.29"
}
}
12 changes: 12 additions & 0 deletions tests/fixtures/script-indent/ts-abstract-accessor-property-01.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!--{"parserOptions": {"parser":"@typescript-eslint/parser"}, "requirements": { "@typescript-eslint/parser": ">=5.44.1-alpha.15"}}-->
<script lang="ts">
abstract class Foo {
abstract accessor
foo:
number
// parser v5 does not parse value.
// =
// 1
;
}
</script>
8 changes: 8 additions & 0 deletions tests/fixtures/script-indent/ts-accessor-property-01.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<!--{"parserOptions": {"parser":"@typescript-eslint/parser"}, "requirements": { "@typescript-eslint/parser": ">=5.44.1-alpha.15"}}-->
<script lang="ts">
class Foo {
accessor
foo
;
}
</script>
10 changes: 10 additions & 0 deletions tests/fixtures/script-indent/ts-accessor-property-02.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!--{"parserOptions": {"parser":"@typescript-eslint/parser"}, "requirements": { "@typescript-eslint/parser": ">=5.44.1-alpha.15"}}-->
<script lang="ts">
class Foo {
accessor
foo
=
2
;
}
</script>
9 changes: 9 additions & 0 deletions tests/fixtures/script-indent/ts-accessor-property-03.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<!--{"parserOptions": {"parser":"@typescript-eslint/parser"}, "requirements": { "@typescript-eslint/parser": ">=5.44.1-alpha.15"}}-->
<script lang="ts">
class Foo {
declare accessor
foo:
number
;
}
</script>
10 changes: 10 additions & 0 deletions tests/fixtures/script-indent/ts-accessor-property-04.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!--{"parserOptions": {"parser":"@typescript-eslint/parser"}, "requirements": { "@typescript-eslint/parser": ">=5.44.1-alpha.15"}}-->
<script lang="ts">
class Foo {
override accessor
foo
=
2
;
}
</script>
12 changes: 12 additions & 0 deletions tests/fixtures/script-indent/ts-accessor-property-05.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!--{"parserOptions": {"parser":"@typescript-eslint/parser"}, "requirements": { "@typescript-eslint/parser": ">=5.44.1-alpha.15"}}-->
<script lang="ts">
class Foo {
accessor
[
1
]
=
2
;
}
</script>
12 changes: 12 additions & 0 deletions tests/fixtures/script-indent/ts-call-expression-01.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!--{"parserOptions": {"parser":"@typescript-eslint/parser"}}-->
<script lang="ts">
foo
<
T
,
U
>
(
arg
)
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<!--{"parserOptions": {"parser":"@typescript-eslint/parser"}, "requirements": { "@typescript-eslint/parser": ">=5.44.0"}}-->
<script lang="ts">
const ErrorMap = Map
<
string,
Error
>;
</script>
13 changes: 13 additions & 0 deletions tests/fixtures/script-indent/ts-new-expression-01.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!--{"parserOptions": {"parser":"@typescript-eslint/parser"}}-->
<script lang="ts">
const foo = new
Foo
<
T
,
U
>
(
arg
)
</script>
8 changes: 8 additions & 0 deletions tests/fixtures/script-indent/ts-satisfies-operators-01.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<!--{"parserOptions": {"parser":"@typescript-eslint/parser"}, "requirements": { "@typescript-eslint/parser": ">=5.44.0" } }-->
<script lang="ts">
var a =
{} satisfies
Foo
var b =
{} satisfies Bar
</script>
1 change: 1 addition & 0 deletions typings/eslint-plugin-vue/util-types/ast/es-ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,7 @@ export interface NewExpression extends HasParentNode {
type: 'NewExpression'
callee: Expression
arguments: (Expression | SpreadElement)[]
typeParameters?: TSTypeParameterInstantiation
}
interface BaseMemberExpression extends HasParentNode {
type: 'MemberExpression'
Expand Down

0 comments on commit e42f737

Please sign in to comment.