You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1380 lines
43 KiB
1380 lines
43 KiB
/** |
|
* @author Yosuke Ota |
|
* See LICENSE file in root directory for full license. |
|
*/ |
|
'use strict' |
|
|
|
const { |
|
isClosingParenToken, |
|
isOpeningParenToken, |
|
isOpeningBraceToken, |
|
isNotClosingParenToken, |
|
isClosingBracketToken, |
|
isOpeningBracketToken |
|
} = require('eslint-utils') |
|
const { isTypeNode } = require('./ts-ast-utils') |
|
|
|
/** |
|
* @typedef {import('../../typings/eslint-plugin-vue/util-types/indent-helper').TSNodeListener} TSNodeListener |
|
* @typedef {import('../../typings/eslint-plugin-vue/util-types/node').HasLocation} HasLocation |
|
* @typedef { { type: string } & HasLocation } MaybeNode |
|
*/ |
|
/** |
|
* @typedef {import('@typescript-eslint/types').TSESTree.Node} TSESTreeNode |
|
* @typedef {import('@typescript-eslint/types').TSESTree.ClassExpression} ClassExpression |
|
* @typedef {import('@typescript-eslint/types').TSESTree.ClassDeclaration} ClassDeclaration |
|
* @typedef {import('@typescript-eslint/types').TSESTree.TSTypeAliasDeclaration} TSTypeAliasDeclaration |
|
* @typedef {import('@typescript-eslint/types').TSESTree.TSCallSignatureDeclaration} TSCallSignatureDeclaration |
|
* @typedef {import('@typescript-eslint/types').TSESTree.TSConstructSignatureDeclaration} TSConstructSignatureDeclaration |
|
* @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.TSEnumMember} TSEnumMember |
|
* @typedef {import('@typescript-eslint/types').TSESTree.TSPropertySignature} TSPropertySignature |
|
* @typedef {import('@typescript-eslint/types').TSESTree.TSIndexSignature} TSIndexSignature |
|
* @typedef {import('@typescript-eslint/types').TSESTree.TSMethodSignature} TSMethodSignature |
|
* @typedef {import('@typescript-eslint/types').TSESTree.TSTypeParameterInstantiation} TSTypeParameterInstantiation |
|
* @typedef {import('@typescript-eslint/types').TSESTree.TSTypeParameterDeclaration} TSTypeParameterDeclaration |
|
* @typedef {import('@typescript-eslint/types').TSESTree.TSConstructorType} TSConstructorType |
|
* @typedef {import('@typescript-eslint/types').TSESTree.TSFunctionType} TSFunctionType |
|
* @typedef {import('@typescript-eslint/types').TSESTree.TSUnionType} TSUnionType |
|
* @typedef {import('@typescript-eslint/types').TSESTree.TSIntersectionType} TSIntersectionType |
|
* @typedef {import('@typescript-eslint/types').TSESTree.TSInterfaceHeritage} TSInterfaceHeritage |
|
* @typedef {import('@typescript-eslint/types').TSESTree.TSClassImplements} TSClassImplements |
|
* @typedef {import('@typescript-eslint/types').TSESTree.TSInterfaceBody} TSInterfaceBody |
|
* @typedef {import('@typescript-eslint/types').TSESTree.TSModuleBlock} TSModuleBlock |
|
* @typedef {import('@typescript-eslint/types').TSESTree.TSDeclareFunction} TSDeclareFunction |
|
* @typedef {import('@typescript-eslint/types').TSESTree.TSEmptyBodyFunctionExpression} TSEmptyBodyFunctionExpression |
|
* @typedef {import('@typescript-eslint/types').TSESTree.TSTypeOperator} TSTypeOperator |
|
* @typedef {import('@typescript-eslint/types').TSESTree.TSTypeQuery} TSTypeQuery |
|
* @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.JSXChild} JSXChild |
|
* @typedef {import('@typescript-eslint/types').TSESTree.TypeNode} TypeNode |
|
* |
|
*/ |
|
/** |
|
* Deprecated in @typescript-eslint/parser v5 |
|
* @typedef {import('@typescript-eslint/types').TSESTree.PropertyDefinition} ClassProperty |
|
* @typedef {import('@typescript-eslint/types').TSESTree.TSAbstractPropertyDefinition} TSAbstractClassProperty |
|
*/ |
|
|
|
module.exports = { |
|
defineVisitor |
|
} |
|
|
|
/** |
|
* Process the given node list. |
|
* The first node is offsetted from the given left token. |
|
* Rest nodes are adjusted to the first node. |
|
* @callback ProcessNodeList |
|
* @param {(MaybeNode|null)[]} nodeList The node to process. |
|
* @param {MaybeNode|Token|null} left The left parenthesis token. |
|
* @param {MaybeNode|Token|null} right The right parenthesis token. |
|
* @param {number} offset The offset to set. |
|
* @param {boolean} [alignVertically=true] The flag to align vertically. If `false`, this doesn't align vertically even if the first node is not at beginning of line. |
|
* @returns {void} |
|
*/ |
|
/** |
|
* Set offset to the given tokens. |
|
* @callback SetOffset |
|
* @param {Token|Token[]|null|(Token|null)[]} token The token to set. |
|
* @param {number} offset The offset of the tokens. |
|
* @param {Token} baseToken The token of the base offset. |
|
* @returns {void} |
|
*/ |
|
/** |
|
* |
|
* Copy offset to the given tokens from srcToken. |
|
* @callback CopyOffset |
|
* @param {Token} token The token to set. |
|
* @param {Token} srcToken The token of the source offset. |
|
* @returns {void} |
|
*/ |
|
/** |
|
* Process semicolons of the given statement node. |
|
* @callback ProcessSemicolons |
|
* @param {MaybeNode} node The statement node to process. |
|
* @returns {void} |
|
*/ |
|
/** |
|
* Get the first and last tokens of the given node. |
|
* If the node is parenthesized, this gets the outermost parentheses. |
|
* @callback GetFirstAndLastTokens |
|
* @param {MaybeNode} node The node to get. |
|
* @param {number} [borderOffset] The least offset of the first token. Defailt is 0. This value is used to prevent false positive in the following case: `(a) => {}` The parentheses are enclosing the whole parameter part rather than the first parameter, but this offset parameter is needed to distinguish. |
|
* @returns {{firstToken:Token,lastToken:Token}} The gotten tokens. |
|
*/ |
|
/** |
|
* @typedef {object} DefineVisitorParam |
|
* @property {ProcessNodeList} processNodeList |
|
* @property {ParserServices.TokenStore | SourceCode} tokenStore |
|
* @property {SetOffset} setOffset |
|
* @property {CopyOffset} copyOffset |
|
* @property {ProcessSemicolons} processSemicolons |
|
* @property {GetFirstAndLastTokens} getFirstAndLastTokens |
|
*/ |
|
|
|
/** |
|
* @param {DefineVisitorParam} param |
|
* @returns {TSNodeListener} |
|
*/ |
|
function defineVisitor({ |
|
processNodeList, |
|
tokenStore, |
|
setOffset, |
|
copyOffset, |
|
processSemicolons, |
|
getFirstAndLastTokens |
|
}) { |
|
/** |
|
* Check whether a given token is the first token of: |
|
* |
|
* - A parameter of TSTypeParameterInstantiation |
|
* - An element of TSTupleType |
|
* |
|
* @param {Token} token The token to check. |
|
* @param {TSUnionType | TSIntersectionType} belongingNode The node that the token is belonging to. |
|
* @returns {boolean} `true` if the token is the first token of an element. |
|
*/ |
|
function isBeginningOfElement(token, belongingNode) { |
|
/** @type {TSESTreeNode | null} */ |
|
let node = belongingNode |
|
|
|
while (node != null && node.parent != null) { |
|
/** @type {TSESTreeNode} */ |
|
const parent = node.parent |
|
if (parent.type === 'TSTypeParameterInstantiation') { |
|
return ( |
|
parent.params.length >= 2 && |
|
parent.params.some( |
|
(param) => |
|
getFirstAndLastTokens(param).firstToken.range[0] === |
|
token.range[0] |
|
) |
|
) |
|
} |
|
if (parent.type === 'TSTupleType') { |
|
return parent.elementTypes.some( |
|
(element) => |
|
element != null && |
|
getFirstAndLastTokens(element).firstToken.range[0] === |
|
token.range[0] |
|
) |
|
} |
|
|
|
node = parent |
|
} |
|
|
|
return false |
|
} |
|
|
|
return { |
|
// Support TypeScript |
|
/** @param {ClassDeclaration | ClassExpression} node */ |
|
['ClassDeclaration[implements], ClassDeclaration[typeParameters], ClassDeclaration[superTypeParameters],' + |
|
'ClassExpression[implements], ClassExpression[typeParameters], ClassExpression[superTypeParameters]']( |
|
node |
|
) { |
|
if (node.typeParameters != null) { |
|
setOffset( |
|
tokenStore.getFirstToken(node.typeParameters), |
|
1, |
|
tokenStore.getFirstToken(node.id || node) |
|
) |
|
} |
|
if (node.superTypeParameters != null && node.superClass != null) { |
|
setOffset( |
|
tokenStore.getFirstToken(node.superTypeParameters), |
|
1, |
|
tokenStore.getFirstToken(node.superClass) |
|
) |
|
} |
|
if (node.implements != null && node.implements.length) { |
|
const classToken = tokenStore.getFirstToken(node) |
|
const implementsToken = tokenStore.getTokenBefore(node.implements[0]) |
|
setOffset(implementsToken, 1, classToken) |
|
processNodeList(node.implements, implementsToken, null, 1) |
|
} |
|
}, |
|
// Process semicolons. |
|
/** |
|
* @param {TSTypeAliasDeclaration |
|
* | TSCallSignatureDeclaration |
|
* | TSConstructSignatureDeclaration |
|
* | TSImportEqualsDeclaration |
|
* | TSAbstractMethodDefinition |
|
* | TSAbstractPropertyDefinition |
|
* | TSAbstractClassProperty |
|
* | TSEnumMember |
|
* | ClassProperty |
|
* | TSPropertySignature |
|
* | TSIndexSignature |
|
* | TSMethodSignature} node |
|
*/ |
|
['TSTypeAliasDeclaration, TSCallSignatureDeclaration, TSConstructSignatureDeclaration, TSImportEqualsDeclaration,' + |
|
'TSAbstractMethodDefinition, TSAbstractPropertyDefinition, TSEnumMember,' + |
|
'TSPropertySignature, TSIndexSignature, TSMethodSignature,' + |
|
// Deprecated in @typescript-eslint/parser v5 |
|
'ClassProperty, TSAbstractClassProperty'](node) { |
|
processSemicolons(node) |
|
}, |
|
/** |
|
* @param {TSESTreeNode} node |
|
*/ |
|
// eslint-disable-next-line complexity -- ignore |
|
'*[type=/^TS/]'(node) { |
|
if (!isTypeNode(node)) { |
|
return |
|
} |
|
const typeNode = node |
|
if (/** @type {any} */ (typeNode.parent).type === 'TSParenthesizedType') { |
|
return |
|
} |
|
// Process parentheses. |
|
let leftToken = tokenStore.getTokenBefore(node) |
|
let rightToken = tokenStore.getTokenAfter(node) |
|
let firstToken = tokenStore.getFirstToken(node) |
|
|
|
while ( |
|
leftToken && |
|
rightToken && |
|
isOpeningParenToken(leftToken) && |
|
isClosingParenToken(rightToken) |
|
) { |
|
setOffset(firstToken, 1, leftToken) |
|
setOffset(rightToken, 0, leftToken) |
|
|
|
firstToken = leftToken |
|
leftToken = tokenStore.getTokenBefore(leftToken) |
|
rightToken = tokenStore.getTokenAfter(rightToken) |
|
} |
|
}, |
|
/** |
|
* Process type annotation |
|
* |
|
* e.g. |
|
* ``` |
|
* const foo: Type |
|
* // ^^^^^^ |
|
* type foo = () => string |
|
* // ^^^^^^^^^ |
|
* ``` |
|
*/ |
|
TSTypeAnnotation(node) { |
|
const [colonOrArrowToken, secondToken] = tokenStore.getFirstTokens(node, { |
|
count: 2, |
|
includeComments: false |
|
}) |
|
const baseToken = tokenStore.getFirstToken( |
|
/** @type {HasLocation} */ (node.parent) |
|
) |
|
setOffset([colonOrArrowToken, secondToken], 1, baseToken) |
|
|
|
// a ?: T |
|
const before = tokenStore.getTokenBefore(colonOrArrowToken) |
|
if (before && before.value === '?') { |
|
setOffset(before, 1, baseToken) |
|
} |
|
}, |
|
/** |
|
* Process as expression |
|
* |
|
* e.g. |
|
* ``` |
|
* var foo = bar as boolean |
|
* // ^^^^^^^^^^^^^^ |
|
* ``` |
|
*/ |
|
TSAsExpression(node) { |
|
const expressionTokens = getFirstAndLastTokens(node.expression) |
|
const asToken = tokenStore.getTokenAfter(expressionTokens.lastToken) |
|
setOffset( |
|
[asToken, getFirstAndLastTokens(node.typeAnnotation).firstToken], |
|
1, |
|
expressionTokens.firstToken |
|
) |
|
}, |
|
/** |
|
* Process type reference |
|
* |
|
* e.g. |
|
* ``` |
|
* const foo: Type<P> |
|
* // ^^^^^^^ |
|
* ``` |
|
*/ |
|
TSTypeReference(node) { |
|
if (node.typeParameters) { |
|
const typeNameTokens = getFirstAndLastTokens(node.typeName) |
|
setOffset( |
|
tokenStore.getFirstToken(node.typeParameters), |
|
1, |
|
typeNameTokens.firstToken |
|
) |
|
} |
|
}, |
|
/** |
|
* Process type parameter instantiation and type parameter declaration |
|
* |
|
* e.g. |
|
* ``` |
|
* const foo: Type<P> |
|
* // ^^^ |
|
* ``` |
|
* |
|
* e.g. |
|
* ``` |
|
* type Foo<T> |
|
* // ^^^ |
|
* ``` |
|
* @param {TSTypeParameterInstantiation | TSTypeParameterDeclaration} node |
|
*/ |
|
'TSTypeParameterInstantiation, TSTypeParameterDeclaration'(node) { |
|
// <T> |
|
processNodeList( |
|
node.params, |
|
tokenStore.getFirstToken(node), |
|
tokenStore.getLastToken(node), |
|
1 |
|
) |
|
}, |
|
/** |
|
* Process type alias declaration |
|
* |
|
* e.g. |
|
* ``` |
|
* type Foo |
|
* ``` |
|
*/ |
|
TSTypeAliasDeclaration(node) { |
|
// type T = {} |
|
const typeToken = tokenStore.getFirstToken(node) |
|
const idToken = tokenStore.getFirstToken(node.id) |
|
setOffset(idToken, 1, typeToken) |
|
let eqToken |
|
if (node.typeParameters) { |
|
setOffset(tokenStore.getFirstToken(node.typeParameters), 1, idToken) |
|
eqToken = tokenStore.getTokenAfter(node.typeParameters) |
|
} else { |
|
eqToken = tokenStore.getTokenAfter(node.id) |
|
} |
|
const initToken = tokenStore.getTokenAfter(eqToken) |
|
setOffset([eqToken, initToken], 1, idToken) |
|
}, |
|
/** |
|
* Process constructor type or function type |
|
* |
|
* e.g. |
|
* ``` |
|
* type Foo = new () => T |
|
* // ^^^^^^^^^^^ |
|
* type Foo = () => void |
|
* // ^^^^^^^^^^ |
|
* ``` |
|
* @param {TSConstructorType | TSFunctionType} node |
|
*/ |
|
'TSConstructorType, TSFunctionType'(node) { |
|
// ()=>void |
|
const firstToken = tokenStore.getFirstToken(node) |
|
// new or < or ( |
|
let currToken = firstToken |
|
if (node.type === 'TSConstructorType') { |
|
// currToken is new token |
|
// < or ( |
|
currToken = tokenStore.getTokenAfter(currToken) |
|
setOffset(currToken, 1, firstToken) |
|
} |
|
if (node.typeParameters) { |
|
// currToken is < token |
|
// ( |
|
currToken = tokenStore.getTokenAfter(node.typeParameters) |
|
setOffset(currToken, 1, firstToken) |
|
} |
|
const leftParenToken = currToken |
|
const rightParenToken = /**@type {Token} */ ( |
|
tokenStore.getTokenAfter( |
|
node.params[node.params.length - 1] || leftParenToken, |
|
isClosingParenToken |
|
) |
|
) |
|
processNodeList(node.params, leftParenToken, rightParenToken, 1) |
|
const arrowToken = tokenStore.getTokenAfter(rightParenToken) |
|
setOffset(arrowToken, 1, leftParenToken) |
|
}, |
|
/** |
|
* Process type literal |
|
* |
|
* e.g. |
|
* ``` |
|
* const foo: { bar: string } |
|
* // ^^^^^^^^^^^^^^^ |
|
* ``` |
|
*/ |
|
TSTypeLiteral(node) { |
|
processNodeList( |
|
node.members, |
|
tokenStore.getFirstToken(node), |
|
tokenStore.getLastToken(node), |
|
1 |
|
) |
|
}, |
|
/** |
|
* Process property signature |
|
* |
|
* e.g. |
|
* ``` |
|
* const foo: { bar: string } |
|
* // ^^^^^^^^^^^ |
|
* ``` |
|
*/ |
|
TSPropertySignature(node) { |
|
const firstToken = tokenStore.getFirstToken(node) |
|
const keyTokens = getFirstAndLastTokens(node.key) |
|
let keyLast |
|
if (node.computed) { |
|
const closeBracket = tokenStore.getTokenAfter(keyTokens.lastToken) |
|
processNodeList([node.key], firstToken, closeBracket, 1) |
|
keyLast = closeBracket |
|
} else { |
|
keyLast = keyTokens.lastToken |
|
} |
|
if (node.typeAnnotation) { |
|
const typeAnnotationToken = tokenStore.getFirstToken( |
|
node.typeAnnotation |
|
) |
|
setOffset( |
|
[ |
|
...tokenStore.getTokensBetween(keyLast, typeAnnotationToken), |
|
typeAnnotationToken |
|
], |
|
1, |
|
firstToken |
|
) |
|
} else if (node.optional) { |
|
const qToken = tokenStore.getLastToken(node) |
|
setOffset(qToken, 1, firstToken) |
|
} |
|
}, |
|
/** |
|
* Process index signature |
|
* |
|
* e.g. |
|
* ``` |
|
* const foo: { [bar: string]: string } |
|
* // ^^^^^^^^^^^^^^^^^^^^^ |
|
* ``` |
|
*/ |
|
TSIndexSignature(node) { |
|
const leftBracketToken = tokenStore.getFirstToken(node) |
|
const rightBracketToken = /**@type {Token} */ ( |
|
tokenStore.getTokenAfter( |
|
node.parameters[node.parameters.length - 1] || leftBracketToken, |
|
isClosingBracketToken |
|
) |
|
) |
|
processNodeList(node.parameters, leftBracketToken, rightBracketToken, 1) |
|
const keyLast = rightBracketToken |
|
if (node.typeAnnotation) { |
|
const typeAnnotationToken = tokenStore.getFirstToken( |
|
node.typeAnnotation |
|
) |
|
setOffset( |
|
[ |
|
...tokenStore.getTokensBetween(keyLast, typeAnnotationToken), |
|
typeAnnotationToken |
|
], |
|
1, |
|
leftBracketToken |
|
) |
|
} |
|
}, |
|
/** |
|
* Process array type |
|
* |
|
* e.g. |
|
* ``` |
|
* const foo: Type[] |
|
* // ^^^^^^ |
|
* ``` |
|
*/ |
|
TSArrayType(node) { |
|
const firstToken = tokenStore.getFirstToken(node) |
|
setOffset( |
|
tokenStore.getLastTokens(node, { count: 2, includeComments: false }), |
|
0, |
|
firstToken |
|
) |
|
}, |
|
TSTupleType(node) { |
|
// [T, U] |
|
processNodeList( |
|
node.elementTypes, |
|
tokenStore.getFirstToken(node), |
|
tokenStore.getLastToken(node), |
|
1 |
|
) |
|
}, |
|
TSQualifiedName(node) { |
|
// A.B |
|
const objectToken = tokenStore.getFirstToken(node) |
|
const dotToken = tokenStore.getTokenBefore(node.right) |
|
const propertyToken = tokenStore.getTokenAfter(dotToken) |
|
setOffset([dotToken, propertyToken], 1, objectToken) |
|
}, |
|
TSIndexedAccessType(node) { |
|
// A[B] |
|
const objectToken = tokenStore.getFirstToken(node) |
|
const leftBracketToken = tokenStore.getTokenBefore( |
|
node.indexType, |
|
isOpeningBracketToken |
|
) |
|
const rightBracketToken = tokenStore.getTokenAfter( |
|
node.indexType, |
|
isClosingBracketToken |
|
) |
|
setOffset(leftBracketToken, 1, objectToken) |
|
processNodeList([node.indexType], leftBracketToken, rightBracketToken, 1) |
|
}, |
|
/** @param {TSUnionType | TSIntersectionType} node */ |
|
'TSUnionType, TSIntersectionType'(node) { |
|
// A | B |
|
// A & B |
|
const firstToken = tokenStore.getFirstToken(node) |
|
|
|
const prevToken = tokenStore.getTokenBefore(firstToken) |
|
const shouldIndent = |
|
prevToken == null || |
|
prevToken.loc.end.line === firstToken.loc.start.line || |
|
isBeginningOfElement(firstToken, node) |
|
const offset = shouldIndent ? 1 : 0 |
|
|
|
const typeTokensList = node.types.map(getFirstAndLastTokens) |
|
const typeTokens = typeTokensList.shift() |
|
if (!typeTokens) { |
|
return |
|
} |
|
let lastToken |
|
if (typeTokens.firstToken === firstToken) { |
|
lastToken = typeTokens.lastToken |
|
} else { |
|
typeTokensList.unshift(typeTokens) |
|
lastToken = firstToken |
|
} |
|
for (const typeTokens of typeTokensList) { |
|
setOffset( |
|
tokenStore.getTokensBetween(lastToken, typeTokens.firstToken), |
|
offset, |
|
firstToken |
|
) |
|
setOffset(typeTokens.firstToken, offset, firstToken) |
|
} |
|
}, |
|
TSMappedType(node) { |
|
// {[key in foo]: bar} |
|
const leftBraceToken = tokenStore.getFirstToken(node) |
|
const leftBracketToken = tokenStore.getTokenBefore(node.typeParameter) |
|
const rightBracketToken = tokenStore.getTokenAfter( |
|
node.nameType || node.typeParameter |
|
) |
|
setOffset( |
|
[ |
|
...tokenStore.getTokensBetween(leftBraceToken, leftBracketToken), |
|
leftBracketToken |
|
], |
|
1, |
|
leftBraceToken |
|
) |
|
processNodeList( |
|
[node.typeParameter, node.nameType], |
|
leftBracketToken, |
|
rightBracketToken, |
|
1 |
|
) |
|
const rightBraceToken = tokenStore.getLastToken(node) |
|
if (node.typeAnnotation) { |
|
const typeAnnotationToken = tokenStore.getFirstToken( |
|
node.typeAnnotation |
|
) |
|
setOffset( |
|
[ |
|
...tokenStore.getTokensBetween( |
|
rightBracketToken, |
|
typeAnnotationToken |
|
), |
|
typeAnnotationToken |
|
], |
|
1, |
|
leftBraceToken |
|
) |
|
} else { |
|
setOffset( |
|
[...tokenStore.getTokensBetween(rightBracketToken, rightBraceToken)], |
|
1, |
|
leftBraceToken |
|
) |
|
} |
|
setOffset(rightBraceToken, 0, leftBraceToken) |
|
}, |
|
/** |
|
* Process type parameter |
|
* |
|
* e.g. |
|
* ``` |
|
* type Foo<T, U extends T, V = U> |
|
* // ^ ^^^^^^^^^^^ ^^^^^ |
|
* type Foo = {[key in foo]: bar} |
|
* // ^^^^^^^^^^ |
|
* ``` |
|
*/ |
|
TSTypeParameter(node) { |
|
const [firstToken, ...afterTokens] = tokenStore.getTokens(node) |
|
for (const child of [node.constraint, node.default]) { |
|
if (!child) { |
|
continue |
|
} |
|
const [, ...removeTokens] = tokenStore.getTokens(child) |
|
for (const token of removeTokens) { |
|
const i = afterTokens.indexOf(token) |
|
if (i >= 0) { |
|
afterTokens.splice(i, 1) |
|
} |
|
} |
|
} |
|
const secondToken = afterTokens.shift() |
|
if (!secondToken) { |
|
return |
|
} |
|
setOffset(secondToken, 1, firstToken) |
|
if (secondToken.value === 'extends') { |
|
let prevToken = null |
|
let token = afterTokens.shift() |
|
while (token) { |
|
if (token.value === '=') { |
|
break |
|
} |
|
setOffset(token, 1, secondToken) |
|
prevToken = token |
|
token = afterTokens.shift() |
|
} |
|
while (token) { |
|
setOffset(token, 1, prevToken || secondToken) |
|
token = afterTokens.shift() |
|
} |
|
} else { |
|
setOffset(afterTokens, 1, firstToken) |
|
} |
|
}, |
|
/** |
|
* Process conditional type |
|
* |
|
* e.g. |
|
* ``` |
|
* type Foo = A extends B ? Bar : Baz |
|
* // ^^^^^^^^^^^^^^^^^^^^^^^ |
|
* ``` |
|
*/ |
|
TSConditionalType(node) { |
|
// T extends Foo ? T : U |
|
const checkTypeToken = tokenStore.getFirstToken(node) |
|
const extendsToken = tokenStore.getTokenAfter(node.checkType) |
|
const extendsTypeToken = tokenStore.getFirstToken(node.extendsType) |
|
setOffset(extendsToken, 1, checkTypeToken) |
|
setOffset(extendsTypeToken, 1, extendsToken) |
|
const questionToken = /**@type {Token} */ ( |
|
tokenStore.getTokenAfter(node.extendsType, isNotClosingParenToken) |
|
) |
|
const consequentToken = tokenStore.getTokenAfter(questionToken) |
|
const colonToken = /**@type {Token} */ ( |
|
tokenStore.getTokenAfter(node.trueType, isNotClosingParenToken) |
|
) |
|
const alternateToken = tokenStore.getTokenAfter(colonToken) |
|
let baseNode = node |
|
let parent = baseNode.parent |
|
while ( |
|
parent && |
|
parent.type === 'TSConditionalType' && |
|
parent.falseType === baseNode |
|
) { |
|
baseNode = parent |
|
parent = baseNode.parent |
|
} |
|
const baseToken = tokenStore.getFirstToken(baseNode) |
|
setOffset([questionToken, colonToken], 1, baseToken) |
|
setOffset(consequentToken, 1, questionToken) |
|
setOffset(alternateToken, 1, colonToken) |
|
}, |
|
/** |
|
* Process interface declaration |
|
* |
|
* e.g. |
|
* ``` |
|
* interface Foo { } |
|
* ``` |
|
*/ |
|
TSInterfaceDeclaration(node) { |
|
const interfaceToken = tokenStore.getFirstToken(node) |
|
setOffset(tokenStore.getFirstToken(node.id), 1, interfaceToken) |
|
if (node.typeParameters != null) { |
|
setOffset( |
|
tokenStore.getFirstToken(node.typeParameters), |
|
1, |
|
tokenStore.getFirstToken(node.id) |
|
) |
|
} |
|
if (node.extends != null && node.extends.length) { |
|
const extendsToken = tokenStore.getTokenBefore(node.extends[0]) |
|
setOffset(extendsToken, 1, interfaceToken) |
|
processNodeList(node.extends, extendsToken, null, 1) |
|
} |
|
// It may not calculate the correct location because the visitor key is not provided. |
|
// if (node.implements != null && node.implements.length) { |
|
// const implementsToken = tokenStore.getTokenBefore(node.implements[0]) |
|
// setOffset(implementsToken, 1, interfaceToken) |
|
// processNodeList(node.implements, implementsToken, null, 1) |
|
// } |
|
const bodyToken = tokenStore.getFirstToken(node.body) |
|
setOffset(bodyToken, 0, interfaceToken) |
|
}, |
|
/** |
|
* Process interface body |
|
* |
|
* e.g. |
|
* ``` |
|
* interface Foo { } |
|
* // ^^^ |
|
* ``` |
|
* |
|
* @param {TSInterfaceBody | TSModuleBlock} node |
|
*/ |
|
'TSInterfaceBody, TSModuleBlock'(node) { |
|
processNodeList( |
|
node.body, |
|
tokenStore.getFirstToken(node), |
|
tokenStore.getLastToken(node), |
|
1 |
|
) |
|
}, |
|
/** |
|
* Process interface heritage and class implements |
|
* |
|
* e.g. |
|
* ``` |
|
* interface Foo<T> extends Bar<T> { } |
|
* // ^^^^^^ |
|
* class Foo<T> implements Bar<T> { } |
|
* // ^^^^^^ |
|
* ``` |
|
* @param {TSInterfaceHeritage | TSClassImplements} node |
|
*/ |
|
'TSClassImplements, TSInterfaceHeritage'(node) { |
|
if (node.typeParameters) { |
|
setOffset( |
|
tokenStore.getFirstToken(node.typeParameters), |
|
1, |
|
tokenStore.getFirstToken(node) |
|
) |
|
} |
|
}, |
|
/** |
|
* Process enum |
|
* |
|
* e.g. |
|
* ``` |
|
* enum Foo { } |
|
* ``` |
|
*/ |
|
TSEnumDeclaration(node) { |
|
const firstToken = tokenStore.getFirstToken(node) |
|
const idTokens = getFirstAndLastTokens(node.id) |
|
const prefixTokens = tokenStore.getTokensBetween( |
|
firstToken, |
|
idTokens.firstToken |
|
) |
|
setOffset(prefixTokens, 0, firstToken) |
|
setOffset(idTokens.firstToken, 1, firstToken) |
|
const leftBraceToken = tokenStore.getTokenAfter(idTokens.lastToken) |
|
const rightBraceToken = tokenStore.getLastToken(node) |
|
setOffset(leftBraceToken, 0, firstToken) |
|
processNodeList(node.members, leftBraceToken, rightBraceToken, 1) |
|
}, |
|
TSModuleDeclaration(node) { |
|
const firstToken = tokenStore.getFirstToken(node) |
|
const idTokens = getFirstAndLastTokens(node.id) |
|
const prefixTokens = tokenStore.getTokensBetween( |
|
firstToken, |
|
idTokens.firstToken |
|
) |
|
setOffset(prefixTokens, 0, firstToken) |
|
setOffset(idTokens.firstToken, 1, firstToken) |
|
if (node.body) { |
|
const bodyFirstToken = tokenStore.getFirstToken(node.body) |
|
setOffset( |
|
bodyFirstToken, |
|
isOpeningBraceToken(bodyFirstToken) ? 0 : 1, |
|
firstToken |
|
) |
|
} |
|
}, |
|
TSMethodSignature(node) { |
|
// fn(arg: A): R | null; |
|
const firstToken = tokenStore.getFirstToken(node) |
|
const keyTokens = getFirstAndLastTokens(node.key) |
|
let keyLast |
|
if (node.computed) { |
|
const closeBracket = tokenStore.getTokenAfter(keyTokens.lastToken) |
|
processNodeList([node.key], firstToken, closeBracket, 1) |
|
keyLast = closeBracket |
|
} else { |
|
keyLast = keyTokens.lastToken |
|
} |
|
const leftParenToken = /** @type {Token} */ ( |
|
tokenStore.getTokenAfter(keyLast, isOpeningParenToken) |
|
) |
|
setOffset( |
|
[ |
|
...tokenStore.getTokensBetween(keyLast, leftParenToken), |
|
leftParenToken |
|
], |
|
1, |
|
firstToken |
|
) |
|
const rightParenToken = tokenStore.getTokenAfter( |
|
node.params[node.params.length - 1] || leftParenToken, |
|
isClosingParenToken |
|
) |
|
processNodeList(node.params, leftParenToken, rightParenToken, 1) |
|
if (node.returnType) { |
|
const typeAnnotationToken = tokenStore.getFirstToken(node.returnType) |
|
setOffset( |
|
[ |
|
...tokenStore.getTokensBetween(keyLast, typeAnnotationToken), |
|
typeAnnotationToken |
|
], |
|
1, |
|
firstToken |
|
) |
|
} |
|
}, |
|
/** |
|
* Process call signature declaration and construct signature declaration |
|
* |
|
* e.g. |
|
* ``` |
|
* interface Foo { |
|
* (): string; |
|
* //^^^^^^^^^^^ |
|
* <T> (e: E): R |
|
* //^^^^^^^^^^^^^ |
|
* } |
|
* ``` |
|
* |
|
* e.g. |
|
* ``` |
|
* interface Foo { |
|
* new (); |
|
* //^^^^^^^ |
|
* } |
|
* interface A { new <T> (e: E): R } |
|
* // ^^^^^^^^^^^^^^^^^ |
|
* ``` |
|
* @param {TSCallSignatureDeclaration | TSConstructSignatureDeclaration} node |
|
*/ |
|
'TSCallSignatureDeclaration, TSConstructSignatureDeclaration'(node) { |
|
const firstToken = tokenStore.getFirstToken(node) |
|
// new or < or ( |
|
let currToken = firstToken |
|
if (node.type === 'TSConstructSignatureDeclaration') { |
|
// currToken is new token |
|
// < or ( |
|
currToken = tokenStore.getTokenAfter(currToken) |
|
setOffset(currToken, 1, firstToken) |
|
} |
|
if (node.typeParameters) { |
|
// currToken is < token |
|
// ( |
|
currToken = tokenStore.getTokenAfter(node.typeParameters) |
|
setOffset(currToken, 1, firstToken) |
|
} |
|
const leftParenToken = currToken |
|
const rightParenToken = /** @type {Token} */ ( |
|
tokenStore.getTokenAfter( |
|
node.params[node.params.length - 1] || leftParenToken, |
|
isClosingParenToken |
|
) |
|
) |
|
processNodeList(node.params, leftParenToken, rightParenToken, 1) |
|
if (node.returnType) { |
|
const typeAnnotationToken = tokenStore.getFirstToken(node.returnType) |
|
setOffset( |
|
[ |
|
...tokenStore.getTokensBetween( |
|
rightParenToken, |
|
typeAnnotationToken |
|
), |
|
typeAnnotationToken |
|
], |
|
1, |
|
firstToken |
|
) |
|
} |
|
}, |
|
/** |
|
* Process declare function and empty body function |
|
* |
|
* e.g. |
|
* ``` |
|
* declare function foo(); |
|
* ``` |
|
* |
|
* e.g. |
|
* ``` |
|
* class Foo { |
|
* abstract fn(); |
|
* // ^^^ |
|
* } |
|
* ``` |
|
* @param {TSDeclareFunction | TSEmptyBodyFunctionExpression} node |
|
*/ |
|
'TSDeclareFunction, TSEmptyBodyFunctionExpression'(node) { |
|
const firstToken = tokenStore.getFirstToken(node) |
|
let leftParenToken, bodyBaseToken |
|
if (firstToken.type === 'Punctuator') { |
|
// method |
|
leftParenToken = firstToken |
|
bodyBaseToken = tokenStore.getFirstToken( |
|
/** @type {HasLocation} */ (node.parent) |
|
) |
|
} else { |
|
let nextToken = tokenStore.getTokenAfter(firstToken) |
|
let nextTokenOffset = 0 |
|
while ( |
|
nextToken && |
|
!isOpeningParenToken(nextToken) && |
|
nextToken.value !== '<' |
|
) { |
|
if ( |
|
nextToken.value === '*' || |
|
(node.id && nextToken.range[0] === node.id.range[0]) |
|
) { |
|
nextTokenOffset = 1 |
|
} |
|
setOffset(nextToken, nextTokenOffset, firstToken) |
|
nextToken = tokenStore.getTokenAfter(nextToken) |
|
} |
|
|
|
leftParenToken = nextToken |
|
bodyBaseToken = firstToken |
|
} |
|
if (!isOpeningParenToken(leftParenToken) && node.typeParameters) { |
|
leftParenToken = tokenStore.getTokenAfter(node.typeParameters) |
|
} |
|
const rightParenToken = tokenStore.getTokenAfter( |
|
node.params[node.params.length - 1] || leftParenToken, |
|
isClosingParenToken |
|
) |
|
setOffset(leftParenToken, 1, bodyBaseToken) |
|
processNodeList(node.params, leftParenToken, rightParenToken, 1) |
|
}, |
|
/** |
|
* Process type operator, type query and infer type |
|
* |
|
* e.g. |
|
* ``` |
|
* type Foo = keyof Bar |
|
* // ^^^^^^^^^ |
|
* ``` |
|
* |
|
* e.g. |
|
* ``` |
|
* type T = typeof a |
|
* // ^^^^^^^^ |
|
* ``` |
|
* |
|
* e.g. |
|
* ``` |
|
* type Foo<T> = T extends Bar<infer U> ? U : T; |
|
* // ^^^^^^^ |
|
* ``` |
|
* |
|
* @param {TSTypeOperator | TSTypeQuery | TSInferType} node |
|
*/ |
|
'TSTypeOperator, TSTypeQuery, TSInferType'(node) { |
|
// keyof T |
|
// type T = typeof av |
|
// infer U |
|
const firstToken = tokenStore.getFirstToken(node) |
|
const nextToken = tokenStore.getTokenAfter(firstToken) |
|
setOffset(nextToken, 1, firstToken) |
|
}, |
|
/** |
|
* Process type predicate |
|
* |
|
* e.g. |
|
* ``` |
|
* function foo(value): value is string; |
|
* // ^^^^^^^^^^^^^^^ |
|
* ``` |
|
*/ |
|
TSTypePredicate(node) { |
|
const firstToken = tokenStore.getFirstToken(node) |
|
const opToken = tokenStore.getTokenAfter( |
|
node.parameterName, |
|
isNotClosingParenToken |
|
) |
|
const rightToken = |
|
node.typeAnnotation && |
|
getFirstAndLastTokens(node.typeAnnotation).firstToken |
|
setOffset( |
|
[opToken, rightToken], |
|
1, |
|
getFirstAndLastTokens(firstToken).firstToken |
|
) |
|
}, |
|
/** |
|
* Process abstract method definition, abstract class property, enum member and class property |
|
* |
|
* e.g. |
|
* ``` |
|
* class Foo { |
|
* abstract fn() |
|
* //^^^^^^^^^^^^^ |
|
* abstract x |
|
* //^^^^^^^^^^ |
|
* x |
|
* //^ |
|
* } |
|
* ``` |
|
* |
|
* e.g. |
|
* ``` |
|
* enum Foo { Bar = x } |
|
* // ^^^^^^^ |
|
* ``` |
|
* |
|
* @param {TSAbstractMethodDefinition | TSAbstractPropertyDefinition | TSEnumMember | TSAbstractClassProperty | ClassProperty} node |
|
* |
|
*/ |
|
['TSAbstractMethodDefinition, TSAbstractPropertyDefinition, TSEnumMember,' + |
|
// Deprecated in @typescript-eslint/parser v5 |
|
'ClassProperty, TSAbstractClassProperty'](node) { |
|
const { keyNode, valueNode } = |
|
node.type === 'TSEnumMember' |
|
? { keyNode: node.id, valueNode: node.initializer } |
|
: { keyNode: node.key, 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 [ |
|
} |
|
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 |
|
) |
|
} |
|
}, |
|
|
|
/** |
|
* Process optional type, non-null expression and JSDocNonNullableType |
|
* |
|
* e.g. |
|
* ``` |
|
* type Foo = [number?] |
|
* // ^^^^^^^ |
|
* const a = v! |
|
* // ^ |
|
* type T = U! |
|
* // ^^ |
|
* ``` |
|
* |
|
* @param {TSOptionalType | TSNonNullExpression} node |
|
*/ |
|
'TSOptionalType, TSNonNullExpression, TSJSDocNonNullableType'(node) { |
|
setOffset( |
|
tokenStore.getLastToken(node), |
|
1, |
|
tokenStore.getFirstToken(node) |
|
) |
|
}, |
|
TSTypeAssertion(node) { |
|
// <const> |
|
const firstToken = tokenStore.getFirstToken(node) |
|
const expressionToken = getFirstAndLastTokens(node.expression).firstToken |
|
processNodeList( |
|
[node.typeAnnotation], |
|
firstToken, |
|
tokenStore.getTokenBefore(expressionToken), |
|
1 |
|
) |
|
setOffset(expressionToken, 1, firstToken) |
|
}, |
|
/** |
|
* Process import type |
|
* |
|
* e.g. |
|
* ``` |
|
* const foo: import('foo').Bar<T> |
|
* // ^^^^^^^^^^^^^^^^^^^^ |
|
* ``` |
|
*/ |
|
TSImportType(node) { |
|
const firstToken = tokenStore.getFirstToken(node) |
|
const leftParenToken = tokenStore.getTokenAfter( |
|
firstToken, |
|
isOpeningParenToken |
|
) |
|
setOffset(leftParenToken, 1, firstToken) |
|
const rightParenToken = tokenStore.getTokenAfter( |
|
node.parameter, |
|
isClosingParenToken |
|
) |
|
processNodeList([node.parameter], leftParenToken, rightParenToken, 1) |
|
if (node.qualifier) { |
|
const dotToken = tokenStore.getTokenBefore(node.qualifier) |
|
const propertyToken = tokenStore.getTokenAfter(dotToken) |
|
setOffset([dotToken, propertyToken], 1, firstToken) |
|
} |
|
if (node.typeParameters) { |
|
setOffset(tokenStore.getFirstToken(node.typeParameters), 1, firstToken) |
|
} |
|
}, |
|
TSParameterProperty(node) { |
|
// constructor(private a) |
|
const firstToken = tokenStore.getFirstToken(node) |
|
const parameterToken = tokenStore.getFirstToken(node.parameter) |
|
setOffset( |
|
[ |
|
...tokenStore.getTokensBetween(firstToken, parameterToken), |
|
parameterToken |
|
], |
|
1, |
|
firstToken |
|
) |
|
}, |
|
/** |
|
* Process import equal |
|
* |
|
* e.g. |
|
* ``` |
|
* import foo = require('foo') |
|
* ``` |
|
*/ |
|
TSImportEqualsDeclaration(node) { |
|
const importToken = tokenStore.getFirstToken(node) |
|
const idTokens = getFirstAndLastTokens(node.id) |
|
setOffset(idTokens.firstToken, 1, importToken) |
|
const opToken = tokenStore.getTokenAfter(idTokens.lastToken) |
|
setOffset( |
|
[opToken, tokenStore.getFirstToken(node.moduleReference)], |
|
1, |
|
idTokens.lastToken |
|
) |
|
}, |
|
/** |
|
* Process external module reference |
|
* |
|
* e.g. |
|
* ``` |
|
* import foo = require('foo') |
|
* // ^^^^^^^^^^^^^^ |
|
* ``` |
|
*/ |
|
TSExternalModuleReference(node) { |
|
const requireToken = tokenStore.getFirstToken(node) |
|
const leftParenToken = tokenStore.getTokenAfter( |
|
requireToken, |
|
isOpeningParenToken |
|
) |
|
const rightParenToken = tokenStore.getLastToken(node) |
|
setOffset(leftParenToken, 1, requireToken) |
|
processNodeList([node.expression], leftParenToken, rightParenToken, 1) |
|
}, |
|
/** |
|
* Process export assignment |
|
* |
|
* e.g. |
|
* ``` |
|
* export = foo |
|
* ``` |
|
*/ |
|
TSExportAssignment(node) { |
|
const exportNode = tokenStore.getFirstToken(node) |
|
const exprTokens = getFirstAndLastTokens(node.expression) |
|
const opToken = tokenStore.getTokenBefore(exprTokens.firstToken) |
|
setOffset([opToken, exprTokens.firstToken], 1, exportNode) |
|
}, |
|
TSNamedTupleMember(node) { |
|
// [a: string, ...b: string[]] |
|
// ^^^^^^^^^ |
|
const labelToken = tokenStore.getFirstToken(node) |
|
const elementTokens = getFirstAndLastTokens(node.elementType) |
|
setOffset( |
|
[ |
|
...tokenStore.getTokensBetween(labelToken, elementTokens.firstToken), |
|
elementTokens.firstToken |
|
], |
|
1, |
|
labelToken |
|
) |
|
}, |
|
TSRestType(node) { |
|
// [a: string, ...b: string[]] |
|
// ^^^^^^^^^^^^^^ |
|
const firstToken = tokenStore.getFirstToken(node) |
|
const nextToken = tokenStore.getTokenAfter(firstToken) |
|
setOffset(nextToken, 1, firstToken) |
|
}, |
|
TSNamespaceExportDeclaration(node) { |
|
const firstToken = tokenStore.getFirstToken(node) |
|
const idToken = tokenStore.getFirstToken(node.id) |
|
setOffset( |
|
[...tokenStore.getTokensBetween(firstToken, idToken), idToken], |
|
1, |
|
firstToken |
|
) |
|
}, |
|
TSTemplateLiteralType(node) { |
|
const firstToken = tokenStore.getFirstToken(node) |
|
const quasiTokens = node.quasis |
|
.slice(1) |
|
.map((n) => tokenStore.getFirstToken(n)) |
|
const expressionToken = node.quasis |
|
.slice(0, -1) |
|
.map((n) => tokenStore.getTokenAfter(n)) |
|
setOffset(quasiTokens, 0, firstToken) |
|
setOffset(expressionToken, 1, firstToken) |
|
}, |
|
// ---------------------------------------------------------------------- |
|
// NON-STANDARD NODES |
|
// ---------------------------------------------------------------------- |
|
Decorator(node) { |
|
// @Decorator |
|
const [atToken, secondToken] = tokenStore.getFirstTokens(node, { |
|
count: 2, |
|
includeComments: false |
|
}) |
|
setOffset(secondToken, 0, atToken) |
|
const parent = /** @type {any} */ (node.parent) |
|
const { decorators } = parent |
|
if (!decorators || decorators.length === 0) { |
|
return |
|
} |
|
if (decorators[0] === node) { |
|
if (parent.range[0] === node.range[0]) { |
|
const startParentToken = tokenStore.getTokenAfter( |
|
decorators[decorators.length - 1] |
|
) |
|
setOffset(startParentToken, 0, atToken) |
|
} else { |
|
const startParentToken = tokenStore.getFirstToken( |
|
parent.parent && |
|
(parent.parent.type === 'ExportDefaultDeclaration' || |
|
parent.parent.type === 'ExportNamedDeclaration') && |
|
node.range[0] < parent.parent.range[0] |
|
? parent.parent |
|
: parent |
|
) |
|
copyOffset(atToken, startParentToken) |
|
} |
|
} else { |
|
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 |
|
// ---------------------------------------------------------------------- |
|
/** @param {any} node */ |
|
TSParenthesizedType(node) { |
|
// Deprecated in @typescript-eslint/parser v5 |
|
// (T) |
|
processNodeList( |
|
[node.typeAnnotation], |
|
tokenStore.getFirstToken(node), |
|
tokenStore.getLastToken(node), |
|
1 |
|
) |
|
}, |
|
// ---------------------------------------------------------------------- |
|
// SINGLE TOKEN NODES |
|
// ---------------------------------------------------------------------- |
|
TSPrivateIdentifier() { |
|
// Perhaps this node will be deprecated in the future. |
|
// It was present in @typescript-eslint/parser@4.1.0. |
|
}, |
|
// VALUES KEYWORD |
|
TSAnyKeyword() {}, |
|
TSBigIntKeyword() {}, |
|
TSBooleanKeyword() {}, |
|
TSNeverKeyword() {}, |
|
TSNullKeyword() {}, |
|
TSNumberKeyword() {}, |
|
TSObjectKeyword() {}, |
|
TSStringKeyword() {}, |
|
TSSymbolKeyword() {}, |
|
TSUndefinedKeyword() {}, |
|
TSUnknownKeyword() {}, |
|
TSVoidKeyword() {}, |
|
// MODIFIERS KEYWORD |
|
TSAbstractKeyword() {}, |
|
TSAsyncKeyword() {}, |
|
TSPrivateKeyword() {}, |
|
TSProtectedKeyword() {}, |
|
TSPublicKeyword() {}, |
|
TSReadonlyKeyword() {}, |
|
TSStaticKeyword() {}, |
|
// OTHERS KEYWORD |
|
TSDeclareKeyword() {}, |
|
TSExportKeyword() {}, |
|
TSIntrinsicKeyword() {}, |
|
// OTHERS |
|
TSThisType() {}, |
|
// ---------------------------------------------------------------------- |
|
// WRAPPER NODES |
|
// ---------------------------------------------------------------------- |
|
TSLiteralType() {} |
|
} |
|
}
|
|
|