eslint-plugin-svelte
Version:
ESLint plugin for Svelte using AST
149 lines (148 loc) • 6.25 kB
JavaScript
import { FindVariableContext } from './ast-utils.js';
export function extractExpressionPrefixVariable(context, expression) {
return extractExpressionPrefixVariableInternal(new FindVariableContext(context), expression);
}
export function extractExpressionPrefixLiteral(context, expression) {
return extractExpressionPrefixLiteralInternal(new FindVariableContext(context), expression);
}
export function extractExpressionSuffixLiteral(context, expression) {
return extractExpressionSuffixLiteralInternal(new FindVariableContext(context), expression);
}
// Variable prefix extraction
function extractExpressionPrefixVariableInternal(context, expression) {
switch (expression.type) {
case 'BinaryExpression':
return extractBinaryExpressionPrefixVariable(context, expression);
case 'Identifier':
return extractVariablePrefixVariable(context, expression);
case 'MemberExpression':
return extractMemberExpressionPrefixVariable(expression);
case 'TemplateLiteral':
return extractTemplateLiteralPrefixVariable(context, expression);
default:
return null;
}
}
function extractBinaryExpressionPrefixVariable(context, expression) {
return expression.left.type !== 'PrivateIdentifier'
? extractExpressionPrefixVariableInternal(context, expression.left)
: null;
}
function extractVariablePrefixVariable(context, expression) {
const variable = context.findVariable(expression);
if (variable === null ||
variable.identifiers.length !== 1 ||
variable.identifiers[0].parent.type !== 'VariableDeclarator' ||
variable.identifiers[0].parent.init === null) {
return expression;
}
return (extractExpressionPrefixVariableInternal(context, variable.identifiers[0].parent.init) ??
expression);
}
function extractMemberExpressionPrefixVariable(expression) {
return expression.property.type === 'Identifier' ? expression.property : null;
}
function extractTemplateLiteralPrefixVariable(context, expression) {
const literalParts = [...expression.expressions, ...expression.quasis].sort((a, b) => a.range[0] < b.range[0] ? -1 : 1);
for (const part of literalParts) {
if (part.type === 'TemplateElement' && part.value.raw === '') {
// Skip empty quasi in the begining
continue;
}
if (part.type !== 'TemplateElement') {
return extractExpressionPrefixVariableInternal(context, part);
}
return null;
}
return null;
}
// Literal prefix extraction
function extractExpressionPrefixLiteralInternal(context, expression) {
switch (expression.type) {
case 'BinaryExpression':
return extractBinaryExpressionPrefixLiteral(context, expression);
case 'Identifier':
return extractVariablePrefixLiteral(context, expression);
case 'Literal':
return typeof expression.value === 'string' ? expression.value : null;
case 'SvelteLiteral':
return expression.value;
case 'TemplateLiteral':
return extractTemplateLiteralPrefixLiteral(context, expression);
default:
return null;
}
}
function extractBinaryExpressionPrefixLiteral(context, expression) {
return expression.left.type !== 'PrivateIdentifier'
? extractExpressionPrefixLiteralInternal(context, expression.left)
: null;
}
function extractVariablePrefixLiteral(context, expression) {
const variable = context.findVariable(expression);
if (variable === null ||
variable.identifiers.length !== 1 ||
variable.identifiers[0].parent.type !== 'VariableDeclarator' ||
variable.identifiers[0].parent.init === null) {
return null;
}
return extractExpressionPrefixLiteralInternal(context, variable.identifiers[0].parent.init);
}
function extractTemplateLiteralPrefixLiteral(context, expression) {
const literalParts = [...expression.expressions, ...expression.quasis].sort((a, b) => a.range[0] < b.range[0] ? -1 : 1);
for (const part of literalParts) {
if (part.type === 'TemplateElement') {
if (part.value.raw === '') {
// Skip empty quasi
continue;
}
return part.value.raw;
}
return extractExpressionPrefixLiteralInternal(context, part);
}
return null;
}
// Literal suffix extraction
function extractExpressionSuffixLiteralInternal(context, expression) {
switch (expression.type) {
case 'BinaryExpression':
return extractBinaryExpressionSuffixLiteral(context, expression);
case 'Identifier':
return extractVariableSuffixLiteral(context, expression);
case 'Literal':
return typeof expression.value === 'string' ? expression.value : null;
case 'SvelteLiteral':
return expression.value;
case 'TemplateLiteral':
return extractTemplateLiteralSuffixLiteral(context, expression);
default:
return null;
}
}
function extractBinaryExpressionSuffixLiteral(context, expression) {
return extractExpressionSuffixLiteralInternal(context, expression.right);
}
function extractVariableSuffixLiteral(context, expression) {
const variable = context.findVariable(expression);
if (variable === null ||
variable.identifiers.length !== 1 ||
variable.identifiers[0].parent.type !== 'VariableDeclarator' ||
variable.identifiers[0].parent.init === null) {
return null;
}
return extractExpressionSuffixLiteralInternal(context, variable.identifiers[0].parent.init);
}
function extractTemplateLiteralSuffixLiteral(context, expression) {
const literalParts = [...expression.expressions, ...expression.quasis].sort((a, b) => a.range[0] < b.range[0] ? -1 : 1);
for (const part of literalParts.reverse()) {
if (part.type === 'TemplateElement') {
if (part.value.raw === '') {
// Skip empty quasi
continue;
}
return part.value.raw;
}
return extractExpressionSuffixLiteralInternal(context, part);
}
return null;
}