astro-ghostcms/.pnpm-store/v3/files/df/e9277356fe4e28a603bfdee65a3...

789 lines
28 KiB
Plaintext
Raw Normal View History

2024-02-14 14:10:47 +00:00
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getNamespaceModifiers = exports.isValidAssignmentTarget = exports.nodeCanBeDecorated = exports.getContainingFunction = exports.nodeIsPresent = exports.isThisInTypeQuery = exports.isThisIdentifier = exports.identifierIsThisKeyword = exports.firstDefined = exports.nodeHasTokens = exports.nodeHasIllegalDecorators = exports.createError = exports.TSError = exports.convertTokens = exports.convertToken = exports.getTokenType = exports.isChildUnwrappableOptionalChain = exports.isChainExpression = exports.isOptional = exports.isComputedProperty = exports.unescapeStringLiteralText = exports.hasJSXAncestor = exports.findFirstMatchingAncestor = exports.findNextToken = exports.getTSNodeAccessibility = exports.getDeclarationKind = exports.isJSXToken = exports.getRange = exports.canContainDirective = exports.getLocFor = exports.getLineAndCharacterFor = exports.getBinaryExpressionType = exports.isComment = exports.isComma = exports.getLastModifier = exports.hasModifier = exports.isESTreeClassMember = exports.getTextForTokenKind = exports.isESTreeBinaryOperator = exports.isLogicalOperator = void 0;
const ts = __importStar(require("typescript"));
const getModifiers_1 = require("./getModifiers");
const xhtml_entities_1 = require("./jsx/xhtml-entities");
const ts_estree_1 = require("./ts-estree");
const version_check_1 = require("./version-check");
const isAtLeast50 = version_check_1.typescriptVersionIsAtLeast['5.0'];
const SyntaxKind = ts.SyntaxKind;
const LOGICAL_OPERATORS = new Set([
SyntaxKind.BarBarToken,
SyntaxKind.AmpersandAmpersandToken,
SyntaxKind.QuestionQuestionToken,
]);
const ASSIGNMENT_OPERATORS = new Set([
ts.SyntaxKind.EqualsToken,
ts.SyntaxKind.PlusEqualsToken,
ts.SyntaxKind.MinusEqualsToken,
ts.SyntaxKind.AsteriskEqualsToken,
ts.SyntaxKind.AsteriskAsteriskEqualsToken,
ts.SyntaxKind.SlashEqualsToken,
ts.SyntaxKind.PercentEqualsToken,
ts.SyntaxKind.LessThanLessThanEqualsToken,
ts.SyntaxKind.GreaterThanGreaterThanEqualsToken,
ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken,
ts.SyntaxKind.AmpersandEqualsToken,
ts.SyntaxKind.BarEqualsToken,
ts.SyntaxKind.BarBarEqualsToken,
ts.SyntaxKind.AmpersandAmpersandEqualsToken,
ts.SyntaxKind.QuestionQuestionEqualsToken,
ts.SyntaxKind.CaretEqualsToken,
]);
const BINARY_OPERATORS = new Set([
SyntaxKind.InstanceOfKeyword,
SyntaxKind.InKeyword,
SyntaxKind.AsteriskAsteriskToken,
SyntaxKind.AsteriskToken,
SyntaxKind.SlashToken,
SyntaxKind.PercentToken,
SyntaxKind.PlusToken,
SyntaxKind.MinusToken,
SyntaxKind.AmpersandToken,
SyntaxKind.BarToken,
SyntaxKind.CaretToken,
SyntaxKind.LessThanLessThanToken,
SyntaxKind.GreaterThanGreaterThanToken,
SyntaxKind.GreaterThanGreaterThanGreaterThanToken,
SyntaxKind.AmpersandAmpersandToken,
SyntaxKind.BarBarToken,
SyntaxKind.LessThanToken,
SyntaxKind.LessThanEqualsToken,
SyntaxKind.GreaterThanToken,
SyntaxKind.GreaterThanEqualsToken,
SyntaxKind.EqualsEqualsToken,
SyntaxKind.EqualsEqualsEqualsToken,
SyntaxKind.ExclamationEqualsEqualsToken,
SyntaxKind.ExclamationEqualsToken,
]);
/**
* Returns true if the given ts.Token is the assignment operator
* @param operator the operator token
* @returns is assignment
*/
function isAssignmentOperator(operator) {
return ASSIGNMENT_OPERATORS.has(operator.kind);
}
/**
* Returns true if the given ts.Token is a logical operator
* @param operator the operator token
* @returns is a logical operator
*/
function isLogicalOperator(operator) {
return LOGICAL_OPERATORS.has(operator.kind);
}
exports.isLogicalOperator = isLogicalOperator;
function isESTreeBinaryOperator(operator) {
return BINARY_OPERATORS.has(operator.kind);
}
exports.isESTreeBinaryOperator = isESTreeBinaryOperator;
/**
* Returns the string form of the given TSToken SyntaxKind
* @param kind the token's SyntaxKind
* @returns the token applicable token as a string
*/
function getTextForTokenKind(kind) {
return ts.tokenToString(kind);
}
exports.getTextForTokenKind = getTextForTokenKind;
/**
* Returns true if the given ts.Node is a valid ESTree class member
* @param node TypeScript AST node
* @returns is valid ESTree class member
*/
function isESTreeClassMember(node) {
return node.kind !== SyntaxKind.SemicolonClassElement;
}
exports.isESTreeClassMember = isESTreeClassMember;
/**
* Checks if a ts.Node has a modifier
* @param modifierKind TypeScript SyntaxKind modifier
* @param node TypeScript AST node
* @returns has the modifier specified
*/
function hasModifier(modifierKind, node) {
const modifiers = (0, getModifiers_1.getModifiers)(node);
return modifiers?.some(modifier => modifier.kind === modifierKind) === true;
}
exports.hasModifier = hasModifier;
/**
* Get last last modifier in ast
* @param node TypeScript AST node
* @returns returns last modifier if present or null
*/
function getLastModifier(node) {
const modifiers = (0, getModifiers_1.getModifiers)(node);
if (modifiers == null) {
return null;
}
return modifiers[modifiers.length - 1] ?? null;
}
exports.getLastModifier = getLastModifier;
/**
* Returns true if the given ts.Token is a comma
* @param token the TypeScript token
* @returns is comma
*/
function isComma(token) {
return token.kind === SyntaxKind.CommaToken;
}
exports.isComma = isComma;
/**
* Returns true if the given ts.Node is a comment
* @param node the TypeScript node
* @returns is comment
*/
function isComment(node) {
return (node.kind === SyntaxKind.SingleLineCommentTrivia ||
node.kind === SyntaxKind.MultiLineCommentTrivia);
}
exports.isComment = isComment;
/**
* Returns true if the given ts.Node is a JSDoc comment
* @param node the TypeScript node
* @returns is JSDoc comment
*/
function isJSDocComment(node) {
// eslint-disable-next-line deprecation/deprecation -- SyntaxKind.JSDoc was only added in TS4.7 so we can't use it yet
return node.kind === SyntaxKind.JSDocComment;
}
/**
* Returns the binary expression type of the given ts.Token
* @param operator the operator token
* @returns the binary expression type
*/
function getBinaryExpressionType(operator) {
if (isAssignmentOperator(operator)) {
return {
type: ts_estree_1.AST_NODE_TYPES.AssignmentExpression,
operator: getTextForTokenKind(operator.kind),
};
}
else if (isLogicalOperator(operator)) {
return {
type: ts_estree_1.AST_NODE_TYPES.LogicalExpression,
operator: getTextForTokenKind(operator.kind),
};
}
else if (isESTreeBinaryOperator(operator)) {
return {
type: ts_estree_1.AST_NODE_TYPES.BinaryExpression,
operator: getTextForTokenKind(operator.kind),
};
}
throw new Error(`Unexpected binary operator ${ts.tokenToString(operator.kind)}`);
}
exports.getBinaryExpressionType = getBinaryExpressionType;
/**
* Returns line and column data for the given positions,
* @param pos position to check
* @param ast the AST object
* @returns line and column
*/
function getLineAndCharacterFor(pos, ast) {
const loc = ast.getLineAndCharacterOfPosition(pos);
return {
line: loc.line + 1,
column: loc.character,
};
}
exports.getLineAndCharacterFor = getLineAndCharacterFor;
/**
* Returns line and column data for the given start and end positions,
* for the given AST
* @param range start end data
* @param ast the AST object
* @returns the loc data
*/
function getLocFor(range, ast) {
const [start, end] = range.map(pos => getLineAndCharacterFor(pos, ast));
return { start, end };
}
exports.getLocFor = getLocFor;
/**
* Check whatever node can contain directive
* @returns returns true if node can contain directive
*/
function canContainDirective(node) {
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;
}
exports.canContainDirective = canContainDirective;
/**
* Returns range for the given ts.Node
* @param node the ts.Node or ts.Token
* @param ast the AST object
* @returns the range data
*/
function getRange(node, ast) {
return [node.getStart(ast), node.getEnd()];
}
exports.getRange = getRange;
/**
* Returns true if a given ts.Node is a token
* @param node the ts.Node
* @returns is a token
*/
function isToken(node) {
return (node.kind >= SyntaxKind.FirstToken && node.kind <= SyntaxKind.LastToken);
}
/**
* Returns true if a given ts.Node is a JSX token
* @param node ts.Node to be checked
* @returns is a JSX token
*/
function isJSXToken(node) {
return (node.kind >= SyntaxKind.JsxElement && node.kind <= SyntaxKind.JsxAttribute);
}
exports.isJSXToken = isJSXToken;
/**
* Returns the declaration kind of the given ts.Node
* @param node TypeScript AST node
* @returns declaration kind
*/
function getDeclarationKind(node) {
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';
}
exports.getDeclarationKind = getDeclarationKind;
/**
* Gets a ts.Node's accessibility level
* @param node The ts.Node
* @returns accessibility "public", "protected", "private", or null
*/
function getTSNodeAccessibility(node) {
const modifiers = (0, getModifiers_1.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;
}
exports.getTSNodeAccessibility = getTSNodeAccessibility;
/**
* Finds the next token based on the previous one and its parent
* Had to copy this from TS instead of using TS's version because theirs doesn't pass the ast to getChildren
* @param previousToken The previous TSToken
* @param parent The parent TSNode
* @param ast The TS AST
* @returns the next TSToken
*/
function findNextToken(previousToken, parent, ast) {
return find(parent);
function find(n) {
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) => {
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;
});
}
}
exports.findNextToken = findNextToken;
/**
* Find the first matching ancestor based on the given predicate function.
* @param node The current ts.Node
* @param predicate The predicate function to apply to each checked ancestor
* @returns a matching parent ts.Node
*/
function findFirstMatchingAncestor(node, predicate) {
let current = node;
while (current) {
if (predicate(current)) {
return current;
}
current = current.parent;
}
return undefined;
}
exports.findFirstMatchingAncestor = findFirstMatchingAncestor;
/**
* Returns true if a given ts.Node has a JSX token within its hierarchy
* @param node ts.Node to be checked
* @returns has JSX ancestor
*/
function hasJSXAncestor(node) {
return !!findFirstMatchingAncestor(node, isJSXToken);
}
exports.hasJSXAncestor = hasJSXAncestor;
/**
* Unescape the text content of string literals, e.g. &amp; -> &
* @param text The escaped string literal text.
* @returns The unescaped string literal text.
*/
function unescapeStringLiteralText(text) {
return text.replace(/&(?:#\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 xhtml_entities_1.xhtmlEntities[item] || entity;
});
}
exports.unescapeStringLiteralText = unescapeStringLiteralText;
/**
* Returns true if a given ts.Node is a computed property
* @param node ts.Node to be checked
* @returns is Computed Property
*/
function isComputedProperty(node) {
return node.kind === SyntaxKind.ComputedPropertyName;
}
exports.isComputedProperty = isComputedProperty;
/**
* Returns true if a given ts.Node is optional (has QuestionToken)
* @param node ts.Node to be checked
* @returns is Optional
*/
function isOptional(node) {
return !!node.questionToken;
}
exports.isOptional = isOptional;
/**
* Returns true if the node is an optional chain node
*/
function isChainExpression(node) {
return node.type === ts_estree_1.AST_NODE_TYPES.ChainExpression;
}
exports.isChainExpression = isChainExpression;
/**
* Returns true of the child of property access expression is an optional chain
*/
function isChildUnwrappableOptionalChain(node, child) {
return (isChainExpression(child) &&
// (x?.y).z is semantically different, and as such .z is no longer optional
node.expression.kind !== ts.SyntaxKind.ParenthesizedExpression);
}
exports.isChildUnwrappableOptionalChain = isChildUnwrappableOptionalChain;
/**
* Returns the type of a given ts.Token
* @param token the ts.Token
* @returns the token type
*/
function getTokenType(token) {
let keywordKind;
if (isAtLeast50 && token.kind === SyntaxKind.Identifier) {
keywordKind = ts.identifierToKeywordKind(token);
}
else if ('originalKeywordKind' in token) {
// eslint-disable-next-line deprecation/deprecation -- intentional fallback for older TS versions
keywordKind = token.originalKeywordKind;
}
if (keywordKind) {
if (keywordKind === SyntaxKind.NullKeyword) {
return ts_estree_1.AST_TOKEN_TYPES.Null;
}
else if (keywordKind >= SyntaxKind.FirstFutureReservedWord &&
keywordKind <= SyntaxKind.LastKeyword) {
return ts_estree_1.AST_TOKEN_TYPES.Identifier;
}
return ts_estree_1.AST_TOKEN_TYPES.Keyword;
}
if (token.kind >= SyntaxKind.FirstKeyword &&
token.kind <= SyntaxKind.LastFutureReservedWord) {
if (token.kind === SyntaxKind.FalseKeyword ||
token.kind === SyntaxKind.TrueKeyword) {
return ts_estree_1.AST_TOKEN_TYPES.Boolean;
}
return ts_estree_1.AST_TOKEN_TYPES.Keyword;
}
if (token.kind >= SyntaxKind.FirstPunctuation &&
token.kind <= SyntaxKind.LastPunctuation) {
return ts_estree_1.AST_TOKEN_TYPES.Punctuator;
}
if (token.kind >= SyntaxKind.NoSubstitutionTemplateLiteral &&
token.kind <= SyntaxKind.TemplateTail) {
return ts_estree_1.AST_TOKEN_TYPES.Template;
}
switch (token.kind) {
case SyntaxKind.NumericLiteral:
return ts_estree_1.AST_TOKEN_TYPES.Numeric;
case SyntaxKind.JsxText:
return ts_estree_1.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 ts_estree_1.AST_TOKEN_TYPES.JSXText;
}
return ts_estree_1.AST_TOKEN_TYPES.String;
case SyntaxKind.RegularExpressionLiteral:
return ts_estree_1.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 ts_estree_1.AST_TOKEN_TYPES.JSXIdentifier;
}
if (token.parent.kind === SyntaxKind.PropertyAccessExpression &&
hasJSXAncestor(token)) {
return ts_estree_1.AST_TOKEN_TYPES.JSXIdentifier;
}
}
return ts_estree_1.AST_TOKEN_TYPES.Identifier;
}
exports.getTokenType = getTokenType;
/**
* Extends and formats a given ts.Token, for a given AST
* @param token the ts.Token
* @param ast the AST object
* @returns the converted Token
*/
function convertToken(token, ast) {
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 = [start, end];
const loc = getLocFor(range, ast);
if (tokenType === ts_estree_1.AST_TOKEN_TYPES.RegularExpression) {
return {
type: tokenType,
value,
range,
loc,
regex: {
pattern: value.slice(1, value.lastIndexOf('/')),
flags: value.slice(value.lastIndexOf('/') + 1),
},
};
}
// @ts-expect-error TS is complaining about `value` not being the correct
// type but it is
return {
type: tokenType,
value,
range,
loc,
};
}
exports.convertToken = convertToken;
/**
* Converts all tokens for the given AST
* @param ast the AST object
* @returns the converted Tokens
*/
function convertTokens(ast) {
const result = [];
/**
* @param node the ts.Node
*/
function walk(node) {
// 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;
}
exports.convertTokens = convertTokens;
class TSError extends Error {
constructor(message, fileName, location) {
super(message);
this.fileName = fileName;
this.location = location;
Object.defineProperty(this, 'name', {
value: new.target.name,
enumerable: false,
configurable: true,
});
}
// For old version of ESLint https://github.com/typescript-eslint/typescript-eslint/pull/6556#discussion_r1123237311
get index() {
return this.location.start.offset;
}
// https://github.com/eslint/eslint/blob/b09a512107249a4eb19ef5a37b0bd672266eafdb/lib/linter/linter.js#L853
get lineNumber() {
return this.location.start.line;
}
// https://github.com/eslint/eslint/blob/b09a512107249a4eb19ef5a37b0bd672266eafdb/lib/linter/linter.js#L854
get column() {
return this.location.start.column;
}
}
exports.TSError = TSError;
/**
* @param message the error message
* @param ast the AST object
* @param startIndex the index at which the error starts
* @param endIndex the index at which the error ends
* @returns converted error object
*/
function createError(message, ast, startIndex, endIndex = startIndex) {
const [start, end] = [startIndex, endIndex].map(offset => {
const { line, character: column } = ast.getLineAndCharacterOfPosition(offset);
return { line: line + 1, column, offset };
});
return new TSError(message, ast.fileName, { start, end });
}
exports.createError = createError;
function nodeHasIllegalDecorators(node) {
return !!('illegalDecorators' in node &&
node.illegalDecorators?.length);
}
exports.nodeHasIllegalDecorators = nodeHasIllegalDecorators;
/**
* @param n the TSNode
* @param ast the TS AST
*/
function nodeHasTokens(n, ast) {
// 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.jsDoc
: n.getWidth(ast) !== 0;
}
exports.nodeHasTokens = nodeHasTokens;
/**
* Like `forEach`, but suitable for use with numbers and strings (which may be falsy).
*/
function firstDefined(array, callback) {
if (array === undefined) {
return undefined;
}
for (let i = 0; i < array.length; i++) {
const result = callback(array[i], i);
if (result !== undefined) {
return result;
}
}
return undefined;
}
exports.firstDefined = firstDefined;
function identifierIsThisKeyword(id) {
return (
// eslint-disable-next-line deprecation/deprecation -- intentional for older TS versions
(isAtLeast50 ? ts.identifierToKeywordKind(id) : id.originalKeywordKind) ===
SyntaxKind.ThisKeyword);
}
exports.identifierIsThisKeyword = identifierIsThisKeyword;
function isThisIdentifier(node) {
return (!!node &&
node.kind === SyntaxKind.Identifier &&
identifierIsThisKeyword(node));
}
exports.isThisIdentifier = isThisIdentifier;
function isThisInTypeQuery(node) {
if (!isThisIdentifier(node)) {
return false;
}
while (ts.isQualifiedName(node.parent) && node.parent.left === node) {
node = node.parent;
}
return node.parent.kind === SyntaxKind.TypeQuery;
}
exports.isThisInTypeQuery = isThisInTypeQuery;
// `ts.nodeIsMissing`
function nodeIsMissing(node) {
if (node === undefined) {
return true;
}
return (node.pos === node.end &&
node.pos >= 0 &&
node.kind !== SyntaxKind.EndOfFileToken);
}
// `ts.nodeIsPresent`
function nodeIsPresent(node) {
return !nodeIsMissing(node);
}
exports.nodeIsPresent = nodeIsPresent;
// `ts.getContainingFunction`
function getContainingFunction(node) {
return ts.findAncestor(node.parent, ts.isFunctionLike);
}
exports.getContainingFunction = getContainingFunction;
// `ts.hasAbstractModifier`
function hasAbstractModifier(node) {
return hasModifier(SyntaxKind.AbstractKeyword, node);
}
// `ts.getThisParameter`
function getThisParameter(signature) {
if (signature.parameters.length && !ts.isJSDocSignature(signature)) {
const thisParameter = signature.parameters[0];
if (parameterIsThisKeyword(thisParameter)) {
return thisParameter;
}
}
return null;
}
// `ts.parameterIsThisKeyword`
function parameterIsThisKeyword(parameter) {
return isThisIdentifier(parameter.name);
}
// Rewrite version of `ts.nodeCanBeDecorated`
// Returns `true` for both `useLegacyDecorators: true` and `useLegacyDecorators: false`
function nodeCanBeDecorated(node) {
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;
}
exports.nodeCanBeDecorated = nodeCanBeDecorated;
function isValidAssignmentTarget(node) {
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.NonNullExpression:
return isValidAssignmentTarget(node.expression);
default:
return false;
}
}
exports.isValidAssignmentTarget = isValidAssignmentTarget;
function getNamespaceModifiers(node) {
// For following nested namespaces, use modifiers given to the topmost namespace
// export declare namespace foo.bar.baz {}
let modifiers = (0, getModifiers_1.getModifiers)(node);
let moduleDeclaration = node;
while ((!modifiers || modifiers.length === 0) &&
ts.isModuleDeclaration(moduleDeclaration.parent)) {
const parentModifiers = (0, getModifiers_1.getModifiers)(moduleDeclaration.parent);
if (parentModifiers?.length) {
modifiers = parentModifiers;
}
moduleDeclaration = moduleDeclaration.parent;
}
return modifiers;
}
exports.getNamespaceModifiers = getNamespaceModifiers;
//# sourceMappingURL=node-utils.js.map