📄 node-utils.ts¶
📊 Analysis Summary¶
| Metric | Count |
|---|---|
| 🔧 Functions | 48 |
| 🧱 Classes | 1 |
| 📦 Imports | 7 |
| 📊 Variables & Constants | 15 |
| 📐 Interfaces | 1 |
| 📑 Type Aliases | 5 |
📚 Table of Contents¶
🛠️ File Location:¶
📂 packages/typescript-estree/src/node-utils.ts
📦 Imports¶
| Name | Source |
|---|---|
TSESTree |
./ts-estree |
TSNode |
./ts-estree |
getModifiers |
./getModifiers |
xhtmlEntities |
./jsx/xhtml-entities |
AST_NODE_TYPES |
./ts-estree |
AST_TOKEN_TYPES |
./ts-estree |
typescriptVersionIsAtLeast |
./version-check |
Variables & Constants¶
| Name | Type | Kind | Value | Exported |
|---|---|---|---|---|
isAtLeast50 |
boolean |
const | typescriptVersionIsAtLeast['5.0'] |
✗ |
SyntaxKind |
any |
const | ts.SyntaxKind |
✗ |
LOGICAL_OPERATORS |
ReadonlySet<LogicalOperatorKind> |
const | `new Set([ | |
| SyntaxKind.AmpersandAmpersandToken, | ||||
| SyntaxKind.BarBarToken, | ||||
| SyntaxKind.QuestionQuestionToken, | ||||
| ])` | ✗ | |||
ASSIGNMENT_OPERATORS |
ReadonlySet<AssignmentOperatorKind> |
const | `new Set([ | |
| ts.SyntaxKind.AmpersandAmpersandEqualsToken, | ||||
| ts.SyntaxKind.AmpersandEqualsToken, | ||||
| ts.SyntaxKind.AsteriskAsteriskEqualsToken, | ||||
| ts.SyntaxKind.AsteriskEqualsToken, | ||||
| ts.SyntaxKind.BarBarEqualsToken, | ||||
| ts.SyntaxKind.BarEqualsToken, | ||||
| ts.SyntaxKind.CaretEqualsToken, | ||||
| ts.SyntaxKind.EqualsToken, | ||||
| ts.SyntaxKind.GreaterThanGreaterThanEqualsToken, | ||||
| ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken, | ||||
| ts.SyntaxKind.LessThanLessThanEqualsToken, | ||||
| ts.SyntaxKind.MinusEqualsToken, | ||||
| ts.SyntaxKind.PercentEqualsToken, | ||||
| ts.SyntaxKind.PlusEqualsToken, | ||||
| ts.SyntaxKind.QuestionQuestionEqualsToken, | ||||
| ts.SyntaxKind.SlashEqualsToken, | ||||
| ])` | ✗ | |||
BINARY_OPERATORS |
ReadonlySet<BinaryOperatorKind> |
const | `new Set([ | |
| SyntaxKind.AmpersandAmpersandToken, | ||||
| SyntaxKind.AmpersandToken, | ||||
| SyntaxKind.AsteriskAsteriskToken, | ||||
| SyntaxKind.AsteriskToken, | ||||
| SyntaxKind.BarBarToken, | ||||
| SyntaxKind.BarToken, | ||||
| SyntaxKind.CaretToken, | ||||
| SyntaxKind.EqualsEqualsEqualsToken, | ||||
| SyntaxKind.EqualsEqualsToken, | ||||
| SyntaxKind.ExclamationEqualsEqualsToken, | ||||
| SyntaxKind.ExclamationEqualsToken, | ||||
| SyntaxKind.GreaterThanEqualsToken, | ||||
| SyntaxKind.GreaterThanGreaterThanGreaterThanToken, | ||||
| SyntaxKind.GreaterThanGreaterThanToken, | ||||
| SyntaxKind.GreaterThanToken, | ||||
| SyntaxKind.InKeyword, | ||||
| SyntaxKind.InstanceOfKeyword, | ||||
| SyntaxKind.LessThanEqualsToken, | ||||
| SyntaxKind.LessThanLessThanToken, | ||||
| SyntaxKind.LessThanToken, | ||||
| SyntaxKind.MinusToken, | ||||
| SyntaxKind.PercentToken, | ||||
| SyntaxKind.PlusToken, | ||||
| SyntaxKind.SlashToken, | ||||
| ])` | ✗ | |||
shouldDiveInChildNode |
boolean |
const | `(child.pos <= previousToken.pos && child.end > previousToken.end) | |
| // previous token ends exactly at the beginning of child | ||||
| child.pos === previousToken.end` | ✗ | |||
current |
ts.Node | undefined |
let/var | node |
✗ |
codePoint |
number |
const | `item[1] === 'x' | |
| ? parseInt(item.slice(2), 16) | ||||
| : parseInt(item.slice(1), 10)` | ✗ | |||
keywordKind |
ts.SyntaxKind | undefined |
let/var | *not shown* |
✗ |
start |
any |
const | `token.kind === SyntaxKind.JsxText | |
| ? token.getFullStart() | ||||
| : token.getStart(ast)` | ✗ | |||
range |
TSESTree.Range |
const | [start, end] |
✗ |
result |
TSESTree.Token[] |
const | [] |
✗ |
thisParameter |
any |
const | signature.parameters[0] |
✗ |
grandparent |
any |
const | parent.parent |
✗ |
moduleDeclaration |
ts.ModuleDeclaration |
let/var | node |
✗ |
Functions¶
isAssignmentOperator(operator: ts.BinaryOperatorToken): operator is ts.Token<AssignmentOperatorKind>¶
Code
-
JSDoc:
-
Parameters:
operator: ts.BinaryOperatorToken- Return Type:
operator is ts.Token<AssignmentOperatorKind> - Calls:
(ASSIGNMENT_OPERATORS as ReadonlySet<ts.SyntaxKind>).has
isLogicalOperator(operator: ts.BinaryOperatorToken): operator is ts.Token<LogicalOperatorKind>¶
Code
-
JSDoc:
-
Parameters:
operator: ts.BinaryOperatorToken- Return Type:
operator is ts.Token<LogicalOperatorKind> - Calls:
(LOGICAL_OPERATORS as ReadonlySet<ts.SyntaxKind>).has
isESTreeBinaryOperator(operator: ts.BinaryOperatorToken): operator is ts.Token<BinaryOperatorKind>¶
Code
- Parameters:
operator: ts.BinaryOperatorToken- Return Type:
operator is ts.Token<BinaryOperatorKind> - Calls:
(BINARY_OPERATORS as ReadonlySet<ts.SyntaxKind>).has
getTextForTokenKind(kind: T): TokenForTokenKind<T>¶
Code
-
JSDoc:
-
Parameters:
kind: T- Return Type:
TokenForTokenKind<T> - Calls:
ts.tokenToString
isESTreeClassMember(node: ts.Node): boolean¶
Code
-
JSDoc:
-
Parameters:
node: ts.Node- Return Type:
boolean
hasModifier(modifierKind: ts.KeywordSyntaxKind, node: ts.Node): boolean¶
Code
-
JSDoc:
-
Parameters:
modifierKind: ts.KeywordSyntaxKindnode: ts.Node- Return Type:
boolean - Calls:
getModifiers (from ./getModifiers)modifiers?.some
getLastModifier(node: ts.Node): ts.Modifier | null¶
Code
-
JSDoc:
-
Parameters:
node: ts.Node- Return Type:
ts.Modifier | null - Calls:
getModifiers (from ./getModifiers)
isComma(token: ts.Node): token is ts.Token<ts.SyntaxKind.CommaToken>¶
Code
-
JSDoc:
-
Parameters:
token: ts.Node- Return Type:
token is ts.Token<ts.SyntaxKind.CommaToken>
isComment(node: ts.Node): boolean¶
Code
-
JSDoc:
-
Parameters:
node: ts.Node- Return Type:
boolean
isJSDocComment(node: ts.Node): node is ts.JSDoc¶
Code
-
JSDoc:
-
Parameters:
node: ts.Node- Return Type:
node is ts.JSDoc - Internal Comments:
`getBinaryExpressionType(operator: ts.BinaryOperatorToken): | {¶
operator: TokenForTokenKind<AssignmentOperatorKind>;
type: AST_NODE_TYPES.AssignmentExpression;
}
| {
operator: TokenForTokenKind
Code
export function getBinaryExpressionType(operator: ts.BinaryOperatorToken):
| {
operator: TokenForTokenKind<AssignmentOperatorKind>;
type: AST_NODE_TYPES.AssignmentExpression;
}
| {
operator: TokenForTokenKind<BinaryOperatorKind>;
type: AST_NODE_TYPES.BinaryExpression;
}
| {
operator: TokenForTokenKind<LogicalOperatorKind>;
type: AST_NODE_TYPES.LogicalExpression;
} {
if (isAssignmentOperator(operator)) {
return {
type: AST_NODE_TYPES.AssignmentExpression,
operator: getTextForTokenKind(operator.kind),
};
}
if (isLogicalOperator(operator)) {
return {
type: AST_NODE_TYPES.LogicalExpression,
operator: getTextForTokenKind(operator.kind),
};
}
if (isESTreeBinaryOperator(operator)) {
return {
type: AST_NODE_TYPES.BinaryExpression,
operator: getTextForTokenKind(operator.kind),
};
}
throw new Error(
`Unexpected binary operator ${ts.tokenToString(operator.kind)}`,
);
}
-
JSDoc:
-
Parameters:
operator: ts.BinaryOperatorToken- Return Type:
| { operator: TokenForTokenKind<AssignmentOperatorKind>; type: AST_NODE_TYPES.AssignmentExpression; } | { operator: TokenForTokenKind<BinaryOperatorKind>; type: AST_NODE_TYPES.BinaryExpression; } | { operator: TokenForTokenKind<LogicalOperatorKind>; type: AST_NODE_TYPES.LogicalExpression; } - Calls:
isAssignmentOperatorgetTextForTokenKindisLogicalOperatorisESTreeBinaryOperatorts.tokenToString
getLineAndCharacterFor(pos: number, ast: ts.SourceFile): TSESTree.Position¶
Code
-
JSDoc:
-
Parameters:
pos: numberast: ts.SourceFile- Return Type:
TSESTree.Position - Calls:
ast.getLineAndCharacterOfPosition
getLocFor(range: TSESTree.Range, ast: ts.SourceFile): TSESTree.SourceLocation¶
Code
-
JSDoc:
-
Parameters:
range: TSESTree.Rangeast: ts.SourceFile- Return Type:
TSESTree.SourceLocation - Calls:
range.mapgetLineAndCharacterFor
`canContainDirective(node: | ts.Block¶
| ts.ClassStaticBlockDeclaration
| ts.ModuleBlock
| ts.SourceFile): boolean`
Code
export function canContainDirective(
node:
| ts.Block
| ts.ClassStaticBlockDeclaration
| ts.ModuleBlock
| ts.SourceFile,
): boolean {
if (node.kind === ts.SyntaxKind.Block) {
switch (node.parent.kind) {
case ts.SyntaxKind.Constructor:
case ts.SyntaxKind.GetAccessor:
case ts.SyntaxKind.SetAccessor:
case ts.SyntaxKind.ArrowFunction:
case ts.SyntaxKind.FunctionExpression:
case ts.SyntaxKind.FunctionDeclaration:
case ts.SyntaxKind.MethodDeclaration:
return true;
default:
return false;
}
}
return true;
}
-
JSDoc:
-
Parameters:
node: | ts.Block | ts.ClassStaticBlockDeclaration | ts.ModuleBlock | ts.SourceFile- Return Type:
boolean
getRange(node: Pick<ts.Node, 'getEnd' | 'getStart'>, ast: ts.SourceFile): [number, number]¶
Code
-
JSDoc:
-
Parameters:
node: Pick<ts.Node, 'getEnd' | 'getStart'>ast: ts.SourceFile- Return Type:
[number, number] - Calls:
node.getStartnode.getEnd
isToken(node: ts.Node): node is ts.Token<ts.TokenSyntaxKind>¶
Code
-
JSDoc:
-
Parameters:
node: ts.Node- Return Type:
node is ts.Token<ts.TokenSyntaxKind>
isJSXToken(node: ts.Node): boolean¶
Code
-
JSDoc:
-
Parameters:
node: ts.Node- Return Type:
boolean
getDeclarationKind(node: ts.VariableDeclarationList): DeclarationKind¶
Code
export function getDeclarationKind(
node: ts.VariableDeclarationList,
): DeclarationKind {
if (node.flags & ts.NodeFlags.Let) {
return 'let';
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
if ((node.flags & ts.NodeFlags.AwaitUsing) === ts.NodeFlags.AwaitUsing) {
return 'await using';
}
if (node.flags & ts.NodeFlags.Const) {
return 'const';
}
if (node.flags & ts.NodeFlags.Using) {
return 'using';
}
return 'var';
}
-
JSDoc:
-
Parameters:
node: ts.VariableDeclarationList- Return Type:
DeclarationKind - Internal Comments:
getTSNodeAccessibility(node: ts.Node): 'private' | 'protected' | 'public' | undefined¶
Code
export function getTSNodeAccessibility(
node: ts.Node,
): 'private' | 'protected' | 'public' | undefined {
const modifiers = getModifiers(node);
if (modifiers == null) {
return undefined;
}
for (const modifier of modifiers) {
switch (modifier.kind) {
case SyntaxKind.PublicKeyword:
return 'public';
case SyntaxKind.ProtectedKeyword:
return 'protected';
case SyntaxKind.PrivateKeyword:
return 'private';
default:
break;
}
}
return undefined;
}
-
JSDoc:
-
Parameters:
node: ts.Node- Return Type:
'private' | 'protected' | 'public' | undefined - Calls:
getModifiers (from ./getModifiers)
findNextToken(previousToken: ts.TextRange, parent: ts.Node, ast: ts.SourceFile): ts.Node | undefined¶
Code
export function findNextToken(
previousToken: ts.TextRange,
parent: ts.Node,
ast: ts.SourceFile,
): ts.Node | undefined {
return find(parent);
function find(n: ts.Node): ts.Node | undefined {
if (ts.isToken(n) && n.pos === previousToken.end) {
// this is token that starts at the end of previous token - return it
return n;
}
return firstDefined(n.getChildren(ast), (child: ts.Node) => {
const shouldDiveInChildNode =
// previous token is enclosed somewhere in the child
(child.pos <= previousToken.pos && child.end > previousToken.end) ||
// previous token ends exactly at the beginning of child
child.pos === previousToken.end;
return shouldDiveInChildNode && nodeHasTokens(child, ast)
? find(child)
: undefined;
});
}
}
-
JSDoc:
-
Parameters:
previousToken: ts.TextRangeparent: ts.Nodeast: ts.SourceFile- Return Type:
ts.Node | undefined - Calls:
findts.isTokenfirstDefinedn.getChildrennodeHasTokens- Internal Comments:
find(n: ts.Node): ts.Node | undefined¶
Code
function find(n: ts.Node): ts.Node | undefined {
if (ts.isToken(n) && n.pos === previousToken.end) {
// this is token that starts at the end of previous token - return it
return n;
}
return firstDefined(n.getChildren(ast), (child: ts.Node) => {
const shouldDiveInChildNode =
// previous token is enclosed somewhere in the child
(child.pos <= previousToken.pos && child.end > previousToken.end) ||
// previous token ends exactly at the beginning of child
child.pos === previousToken.end;
return shouldDiveInChildNode && nodeHasTokens(child, ast)
? find(child)
: undefined;
});
}
- Parameters:
n: ts.Node- Return Type:
ts.Node | undefined - Calls:
ts.isTokenfirstDefinedn.getChildrennodeHasTokensfind- Internal Comments:
findFirstMatchingAncestor(node: ts.Node, predicate: (node: ts.Node) => boolean): ts.Node | undefined¶
Code
-
JSDoc:
-
Parameters:
node: ts.Nodepredicate: (node: ts.Node) => boolean- Return Type:
ts.Node | undefined - Calls:
predicate
hasJSXAncestor(node: ts.Node): boolean¶
Code
-
JSDoc:
-
Parameters:
node: ts.Node- Return Type:
boolean - Calls:
findFirstMatchingAncestor
unescapeStringLiteralText(text: string): string¶
Code
export function unescapeStringLiteralText(text: string): string {
return text.replaceAll(/&(?:#\d+|#x[\da-fA-F]+|[0-9a-zA-Z]+);/g, entity => {
const item = entity.slice(1, -1);
if (item[0] === '#') {
const codePoint =
item[1] === 'x'
? parseInt(item.slice(2), 16)
: parseInt(item.slice(1), 10);
return codePoint > 0x10ffff // RangeError: Invalid code point
? entity
: String.fromCodePoint(codePoint);
}
return xhtmlEntities[item] || entity;
});
}
-
JSDoc:
-
Parameters:
text: string- Return Type:
string - Calls:
text.replaceAllentity.sliceparseIntitem.sliceString.fromCodePoint
isComputedProperty(node: ts.Node): node is ts.ComputedPropertyName¶
Code
-
JSDoc:
-
Parameters:
node: ts.Node- Return Type:
node is ts.ComputedPropertyName
`isOptional(node: {¶
questionToken?: ts.QuestionToken; }): boolean`
Code
-
JSDoc:
-
Parameters:
node: { questionToken?: ts.QuestionToken; }- Return Type:
boolean
isChainExpression(node: TSESTree.Node): node is TSESTree.ChainExpression¶
Code
-
JSDoc:
-
Parameters:
node: TSESTree.Node- Return Type:
node is TSESTree.ChainExpression
`isChildUnwrappableOptionalChain(node: | ts.CallExpression¶
| ts.ElementAccessExpression
| ts.NonNullExpression
| ts.PropertyAccessExpression, child: TSESTree.Node): boolean`
Code
export function isChildUnwrappableOptionalChain(
node:
| ts.CallExpression
| ts.ElementAccessExpression
| ts.NonNullExpression
| ts.PropertyAccessExpression,
child: TSESTree.Node,
): boolean {
return (
isChainExpression(child) &&
// (x?.y).z is semantically different, and as such .z is no longer optional
node.expression.kind !== ts.SyntaxKind.ParenthesizedExpression
);
}
-
JSDoc:
-
Parameters:
node: | ts.CallExpression | ts.ElementAccessExpression | ts.NonNullExpression | ts.PropertyAccessExpressionchild: TSESTree.Node- Return Type:
boolean - Calls:
isChainExpression- Internal Comments:
getTokenType(token: ts.Identifier | ts.Token<ts.SyntaxKind>): Exclude<AST_TOKEN_TYPES, AST_TOKEN_TYPES.Block | AST_TOKEN_TYPES.Line>¶
Code
export function getTokenType(
token: ts.Identifier | ts.Token<ts.SyntaxKind>,
): Exclude<AST_TOKEN_TYPES, AST_TOKEN_TYPES.Block | AST_TOKEN_TYPES.Line> {
let keywordKind: ts.SyntaxKind | undefined;
if (isAtLeast50 && token.kind === SyntaxKind.Identifier) {
keywordKind = ts.identifierToKeywordKind(token as ts.Identifier);
} else if ('originalKeywordKind' in token) {
// @ts-expect-error -- intentional fallback for older TS versions <=4.9
keywordKind = token.originalKeywordKind;
}
if (keywordKind) {
if (keywordKind === SyntaxKind.NullKeyword) {
return AST_TOKEN_TYPES.Null;
}
if (
keywordKind >= SyntaxKind.FirstFutureReservedWord &&
keywordKind <= SyntaxKind.LastKeyword
) {
return AST_TOKEN_TYPES.Identifier;
}
return AST_TOKEN_TYPES.Keyword;
}
if (
token.kind >= SyntaxKind.FirstKeyword &&
token.kind <= SyntaxKind.LastFutureReservedWord
) {
if (
token.kind === SyntaxKind.FalseKeyword ||
token.kind === SyntaxKind.TrueKeyword
) {
return AST_TOKEN_TYPES.Boolean;
}
return AST_TOKEN_TYPES.Keyword;
}
if (
token.kind >= SyntaxKind.FirstPunctuation &&
token.kind <= SyntaxKind.LastPunctuation
) {
return AST_TOKEN_TYPES.Punctuator;
}
if (
token.kind >= SyntaxKind.NoSubstitutionTemplateLiteral &&
token.kind <= SyntaxKind.TemplateTail
) {
return AST_TOKEN_TYPES.Template;
}
switch (token.kind) {
case SyntaxKind.NumericLiteral:
case SyntaxKind.BigIntLiteral:
return AST_TOKEN_TYPES.Numeric;
case SyntaxKind.PrivateIdentifier:
return AST_TOKEN_TYPES.PrivateIdentifier;
case SyntaxKind.JsxText:
return AST_TOKEN_TYPES.JSXText;
case SyntaxKind.StringLiteral:
// A TypeScript-StringLiteral token with a TypeScript-JsxAttribute or TypeScript-JsxElement parent,
// must actually be an ESTree-JSXText token
if (
token.parent.kind === SyntaxKind.JsxAttribute ||
token.parent.kind === SyntaxKind.JsxElement
) {
return AST_TOKEN_TYPES.JSXText;
}
return AST_TOKEN_TYPES.String;
case SyntaxKind.RegularExpressionLiteral:
return AST_TOKEN_TYPES.RegularExpression;
case SyntaxKind.Identifier:
case SyntaxKind.ConstructorKeyword:
case SyntaxKind.GetKeyword:
case SyntaxKind.SetKeyword:
// intentional fallthrough
default:
}
// Some JSX tokens have to be determined based on their parent
if (token.kind === SyntaxKind.Identifier) {
if (isJSXToken(token.parent)) {
return AST_TOKEN_TYPES.JSXIdentifier;
}
if (
token.parent.kind === SyntaxKind.PropertyAccessExpression &&
hasJSXAncestor(token)
) {
return AST_TOKEN_TYPES.JSXIdentifier;
}
}
return AST_TOKEN_TYPES.Identifier;
}
-
JSDoc:
-
Parameters:
token: ts.Identifier | ts.Token<ts.SyntaxKind>- Return Type:
Exclude<AST_TOKEN_TYPES, AST_TOKEN_TYPES.Block | AST_TOKEN_TYPES.Line> - Calls:
ts.identifierToKeywordKindisJSXTokenhasJSXAncestor- Internal Comments:
// @ts-expect-error -- intentional fallback for older TS versions <=4.9 (x3) // A TypeScript-StringLiteral token with a TypeScript-JsxAttribute or TypeScript-JsxElement parent, // must actually be an ESTree-JSXText token // intentional fallthrough // Some JSX tokens have to be determined based on their parent
convertToken(token: ts.Token<ts.TokenSyntaxKind>, ast: ts.SourceFile): TSESTree.Token¶
Code
export function convertToken(
token: ts.Token<ts.TokenSyntaxKind>,
ast: ts.SourceFile,
): TSESTree.Token {
const start =
token.kind === SyntaxKind.JsxText
? token.getFullStart()
: token.getStart(ast);
const end = token.getEnd();
const value = ast.text.slice(start, end);
const tokenType = getTokenType(token);
const range: TSESTree.Range = [start, end];
const loc = getLocFor(range, ast);
if (tokenType === AST_TOKEN_TYPES.RegularExpression) {
return {
type: tokenType,
loc,
range,
regex: {
flags: value.slice(value.lastIndexOf('/') + 1),
pattern: value.slice(1, value.lastIndexOf('/')),
},
value,
};
}
if (tokenType === AST_TOKEN_TYPES.PrivateIdentifier) {
return {
type: tokenType,
loc,
range,
value: value.slice(1),
};
}
// @ts-expect-error TS is complaining about `value` not being the correct
// type but it is
return {
type: tokenType,
loc,
range,
value,
};
}
-
JSDoc:
-
Parameters:
token: ts.Token<ts.TokenSyntaxKind>ast: ts.SourceFile- Return Type:
TSESTree.Token - Calls:
token.getFullStarttoken.getStarttoken.getEndast.text.slicegetTokenTypegetLocForvalue.slicevalue.lastIndexOf- Internal Comments:
convertTokens(ast: ts.SourceFile): TSESTree.Token[]¶
Code
export function convertTokens(ast: ts.SourceFile): TSESTree.Token[] {
const result: TSESTree.Token[] = [];
/**
* @param node the ts.Node
*/
function walk(node: ts.Node): void {
// TypeScript generates tokens for types in JSDoc blocks. Comment tokens
// and their children should not be walked or added to the resulting tokens list.
if (isComment(node) || isJSDocComment(node)) {
return;
}
if (isToken(node) && node.kind !== SyntaxKind.EndOfFileToken) {
result.push(convertToken(node, ast));
} else {
node.getChildren(ast).forEach(walk);
}
}
walk(ast);
return result;
}
-
JSDoc:
-
Parameters:
ast: ts.SourceFile- Return Type:
TSESTree.Token[] - Calls:
isCommentisJSDocCommentisTokenresult.pushconvertTokennode.getChildren(ast).forEachwalk- Internal Comments:
walk(node: ts.Node): void¶
Code
function walk(node: ts.Node): void {
// TypeScript generates tokens for types in JSDoc blocks. Comment tokens
// and their children should not be walked or added to the resulting tokens list.
if (isComment(node) || isJSDocComment(node)) {
return;
}
if (isToken(node) && node.kind !== SyntaxKind.EndOfFileToken) {
result.push(convertToken(node, ast));
} else {
node.getChildren(ast).forEach(walk);
}
}
-
JSDoc:
-
Parameters:
node: ts.Node- Return Type:
void - Calls:
isCommentisJSDocCommentisTokenresult.pushconvertTokennode.getChildren(ast).forEach- Internal Comments:
createError(message: string, ast: ts.SourceFile, startIndex: number, endIndex: number): TSError¶
Code
export function createError(
message: string,
ast: ts.SourceFile,
startIndex: number,
endIndex: number = startIndex,
): TSError {
const [start, end] = [startIndex, endIndex].map(offset => {
const { character: column, line } =
ast.getLineAndCharacterOfPosition(offset);
return { column, line: line + 1, offset };
});
return new TSError(message, ast.fileName, { end, start });
}
- Parameters:
message: stringast: ts.SourceFilestartIndex: numberendIndex: number- Return Type:
TSError - Calls:
[startIndex, endIndex].mapast.getLineAndCharacterOfPosition
nodeHasIllegalDecorators(node: ts.Node): node is { illegalDecorators: ts.Node[] } & ts.Node¶
Code
- Parameters:
node: ts.Node- Return Type:
node is { illegalDecorators: ts.Node[] } & ts.Node
nodeHasTokens(n: ts.Node, ast: ts.SourceFile): boolean¶
Code
export function nodeHasTokens(n: ts.Node, ast: ts.SourceFile): boolean {
// If we have a token or node that has a non-zero width, it must have tokens.
// Note: getWidth() does not take trivia into account.
return n.kind === SyntaxKind.EndOfFileToken
? !!(n as ts.JSDocContainer).jsDoc
: n.getWidth(ast) !== 0;
}
- Parameters:
n: ts.Nodeast: ts.SourceFile- Return Type:
boolean - Calls:
n.getWidth- Internal Comments:
firstDefined(array: readonly T[] | undefined, callback: (element: T, index: number) => U | undefined): U | undefined¶
Code
export function firstDefined<T, U>(
array: readonly T[] | undefined,
callback: (element: T, index: number) => U | undefined,
): U | undefined {
// eslint-disable-next-line @typescript-eslint/internal/eqeq-nullish
if (array === undefined) {
return undefined;
}
for (let i = 0; i < array.length; i++) {
const result = callback(array[i], i);
// eslint-disable-next-line @typescript-eslint/internal/eqeq-nullish
if (result !== undefined) {
return result;
}
}
return undefined;
}
-
JSDoc:
-
Parameters:
array: readonly T[] | undefinedcallback: (element: T, index: number) => U | undefined- Return Type:
U | undefined - Calls:
callback- Internal Comments:
identifierIsThisKeyword(id: ts.Identifier): boolean¶
Code
- Parameters:
id: ts.Identifier- Return Type:
boolean - Calls:
ts.identifierToKeywordKind
isThisIdentifier(node: ts.Node | undefined): node is ts.Identifier¶
Code
- Parameters:
node: ts.Node | undefined- Return Type:
node is ts.Identifier - Calls:
identifierIsThisKeyword
isThisInTypeQuery(node: ts.Node): boolean¶
Code
- Parameters:
node: ts.Node- Return Type:
boolean - Calls:
isThisIdentifierts.isQualifiedName
nodeIsMissing(node: ts.Node | undefined): boolean¶
Code
- Parameters:
node: ts.Node | undefined- Return Type:
boolean
nodeIsPresent(node: ts.Node | undefined): node is ts.Node¶
Code
- Parameters:
node: ts.Node | undefined- Return Type:
node is ts.Node - Calls:
nodeIsMissing
getContainingFunction(node: ts.Node): ts.SignatureDeclaration | undefined¶
Code
- Parameters:
node: ts.Node- Return Type:
ts.SignatureDeclaration | undefined - Calls:
ts.findAncestor
hasAbstractModifier(node: ts.Node): boolean¶
Code
- Parameters:
node: ts.Node- Return Type:
boolean - Calls:
hasModifier
getThisParameter(signature: ts.SignatureDeclaration): ts.ParameterDeclaration | null¶
Code
function getThisParameter(
signature: ts.SignatureDeclaration,
): ts.ParameterDeclaration | null {
if (signature.parameters.length && !ts.isJSDocSignature(signature)) {
const thisParameter = signature.parameters[0];
if (parameterIsThisKeyword(thisParameter)) {
return thisParameter;
}
}
return null;
}
- Parameters:
signature: ts.SignatureDeclaration- Return Type:
ts.ParameterDeclaration | null - Calls:
ts.isJSDocSignatureparameterIsThisKeyword
parameterIsThisKeyword(parameter: ts.ParameterDeclaration): boolean¶
Code
- Parameters:
parameter: ts.ParameterDeclaration- Return Type:
boolean - Calls:
isThisIdentifier
nodeCanBeDecorated(node: TSNode): boolean¶
Code
export function nodeCanBeDecorated(node: TSNode): boolean {
switch (node.kind) {
case SyntaxKind.ClassDeclaration:
return true;
case SyntaxKind.ClassExpression:
// `ts.nodeCanBeDecorated` returns `false` if `useLegacyDecorators: true`
return true;
case SyntaxKind.PropertyDeclaration: {
const { parent } = node;
// `ts.nodeCanBeDecorated` uses this if `useLegacyDecorators: true`
if (ts.isClassDeclaration(parent)) {
return true;
}
// `ts.nodeCanBeDecorated` uses this if `useLegacyDecorators: false`
if (ts.isClassLike(parent) && !hasAbstractModifier(node)) {
return true;
}
return false;
}
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
case SyntaxKind.MethodDeclaration: {
const { parent } = node;
// In `ts.nodeCanBeDecorated`
// when `useLegacyDecorators: true` uses `ts.isClassDeclaration`
// when `useLegacyDecorators: true` uses `ts.isClassLike`
return (
Boolean(node.body) &&
(ts.isClassDeclaration(parent) || ts.isClassLike(parent))
);
}
case SyntaxKind.Parameter: {
// `ts.nodeCanBeDecorated` returns `false` if `useLegacyDecorators: false`
const { parent } = node;
const grandparent = parent.parent;
return (
Boolean(parent) &&
'body' in parent &&
Boolean(parent.body) &&
(parent.kind === SyntaxKind.Constructor ||
parent.kind === SyntaxKind.MethodDeclaration ||
parent.kind === SyntaxKind.SetAccessor) &&
getThisParameter(parent) !== node &&
Boolean(grandparent) &&
grandparent.kind === SyntaxKind.ClassDeclaration
);
}
}
return false;
}
- Parameters:
node: TSNode- Return Type:
boolean - Calls:
ts.isClassDeclarationts.isClassLikehasAbstractModifierBooleangetThisParameter- Internal Comments:
// `ts.nodeCanBeDecorated` returns `false` if `useLegacyDecorators: true` // `ts.nodeCanBeDecorated` uses this if `useLegacyDecorators: true` // `ts.nodeCanBeDecorated` uses this if `useLegacyDecorators: false` // In `ts.nodeCanBeDecorated` // when `useLegacyDecorators: true` uses `ts.isClassDeclaration` // when `useLegacyDecorators: true` uses `ts.isClassLike` // `ts.nodeCanBeDecorated` returns `false` if `useLegacyDecorators: false` (x2)
isValidAssignmentTarget(node: ts.Node): boolean¶
Code
export function isValidAssignmentTarget(node: ts.Node): boolean {
switch (node.kind) {
case SyntaxKind.Identifier:
return true;
case SyntaxKind.PropertyAccessExpression:
case SyntaxKind.ElementAccessExpression:
if (node.flags & ts.NodeFlags.OptionalChain) {
return false;
}
return true;
case SyntaxKind.ParenthesizedExpression:
case SyntaxKind.TypeAssertionExpression:
case SyntaxKind.AsExpression:
case SyntaxKind.SatisfiesExpression:
case SyntaxKind.ExpressionWithTypeArguments:
case SyntaxKind.NonNullExpression:
return isValidAssignmentTarget(
(
node as
| ts.AssertionExpression
| ts.ExpressionWithTypeArguments
| ts.NonNullExpression
| ts.ParenthesizedExpression
| ts.SatisfiesExpression
).expression,
);
default:
return false;
}
}
- Parameters:
node: ts.Node- Return Type:
boolean - Calls:
isValidAssignmentTarget
getNamespaceModifiers(node: ts.ModuleDeclaration): ts.Modifier[] | undefined¶
Code
export function getNamespaceModifiers(
node: ts.ModuleDeclaration,
): ts.Modifier[] | undefined {
// For following nested namespaces, use modifiers given to the topmost namespace
// export declare namespace foo.bar.baz {}
let modifiers = getModifiers(node);
let moduleDeclaration = node;
while (
(!modifiers || modifiers.length === 0) &&
ts.isModuleDeclaration(moduleDeclaration.parent)
) {
const parentModifiers = getModifiers(moduleDeclaration.parent);
if (parentModifiers?.length) {
modifiers = parentModifiers;
}
moduleDeclaration = moduleDeclaration.parent;
}
return modifiers;
}
- Parameters:
node: ts.ModuleDeclaration- Return Type:
ts.Modifier[] | undefined - Calls:
getModifiers (from ./getModifiers)ts.isModuleDeclaration- Internal Comments:
Classes¶
TSError¶
Class Code
export class TSError extends Error {
constructor(
message: string,
public readonly fileName: string,
public readonly location: {
end: {
column: number;
line: number;
offset: number;
};
start: {
column: number;
line: number;
offset: number;
};
},
) {
super(message);
Object.defineProperty(this, 'name', {
configurable: true,
enumerable: false,
value: new.target.name,
});
}
// For old version of ESLint https://github.com/typescript-eslint/typescript-eslint/pull/6556#discussion_r1123237311
get index(): number {
return this.location.start.offset;
}
// https://github.com/eslint/eslint/blob/b09a512107249a4eb19ef5a37b0bd672266eafdb/lib/linter/linter.js#L853
get lineNumber(): number {
return this.location.start.line;
}
// https://github.com/eslint/eslint/blob/b09a512107249a4eb19ef5a37b0bd672266eafdb/lib/linter/linter.js#L854
get column(): number {
return this.location.start.column;
}
}
Interfaces¶
TokenToText¶
Interface Code
Properties¶
| Name | Type | Optional | Description |
|---|---|---|---|
[SyntaxKind.ImportKeyword] |
'import' |
✗ | |
[SyntaxKind.KeyOfKeyword] |
'keyof' |
✗ | |
[SyntaxKind.NewKeyword] |
'new' |
✗ | |
[SyntaxKind.ReadonlyKeyword] |
'readonly' |
✗ | |
[SyntaxKind.UniqueKeyword] |
'unique' |
✗ |
Type Aliases¶
LogicalOperatorKind¶
type LogicalOperatorKind = | ts.SyntaxKind.AmpersandAmpersandToken
| ts.SyntaxKind.BarBarToken
| ts.SyntaxKind.QuestionQuestionToken;
AssignmentOperatorKind¶
BinaryOperatorKind¶
DeclarationKind¶
TokenForTokenKind<T extends ts.SyntaxKind extends ts.SyntaxKind>¶
type TokenForTokenKind<T extends ts.SyntaxKind extends ts.SyntaxKind> = T extends keyof TokenToText
? TokenToText[T]
: string | undefined;