arui-presets-lint
Version:
Config files for arui-apps
80 lines (79 loc) • 3 kB
JavaScript
import { AST_TOKEN_TYPES } from '@typescript-eslint/utils';
import { DESCRIPTION_SEPARATOR, FORBIDDEN_PATTERNS, MEANINGFUL_PATTERNS, MIN_DESCRIPTION_LENGTH, SUPPORTED_DIRECTIVES, } from '../constants/index.js';
import {} from '../types/index.js';
function isDirectiveKind(value) {
return SUPPORTED_DIRECTIVES.includes(value);
}
function divideDirectiveComment(value) {
const divided = value.split(DESCRIPTION_SEPARATOR);
const text = divided[0].trim();
return {
text,
description: divided.length > 1 ? divided[1].trim() : undefined,
};
}
function isValidLineDirective(directiveKind, comment) {
const LINE_DIRECTIVE_PATTERN = /^eslint-disable-(next-)?line$/u;
const isLineComment = comment.type === AST_TOKEN_TYPES.Line;
const isLineDirective = LINE_DIRECTIVE_PATTERN.test(directiveKind);
if (isLineDirective && comment.loc.start.line !== comment.loc.end.line) {
return false;
}
return !isLineComment || isLineDirective;
}
function removeCommentDecorations(line) {
return line.replace(/^\s*\*\s?/, '').trim();
}
export function parseDirectiveComment(comment) {
const DIRECTIVE_PATTERN = /^(eslint(?:-env|-enable|-disable(?:(?:-next)?-line)?)?)(?:\s|$)/u;
const commentValue = comment.type === AST_TOKEN_TYPES.Block
? comment.value
.split('\n')
.map((line) => removeCommentDecorations(line))
.join(' ')
.trim()
: comment.value;
const { text, description } = divideDirectiveComment(commentValue);
const match = DIRECTIVE_PATTERN.exec(text);
if (!match) {
return undefined;
}
const directiveKind = match[1];
if (!isDirectiveKind(directiveKind)) {
return undefined;
}
if (!isValidLineDirective(directiveKind, comment)) {
return undefined;
}
const directiveValue = text.slice(match.index + directiveKind.length).trim();
return {
kind: directiveKind,
value: directiveValue,
description,
};
}
export function getPreviousComment(allComments, currentComment) {
const currentIndex = allComments.indexOf(currentComment);
return currentIndex > 0 ? allComments[currentIndex - 1] : undefined;
}
export function isAdjacentComment(previousComment, currentComment) {
return previousComment.loc.end.line + 1 === currentComment.loc.start.line;
}
export function isValidDescription(description) {
const trimmed = description.trim();
if (trimmed.length < MIN_DESCRIPTION_LENGTH) {
return false;
}
for (const pattern of FORBIDDEN_PATTERNS) {
if (pattern.test(trimmed)) {
return false;
}
}
return MEANINGFUL_PATTERNS.some((pattern) => pattern.test(trimmed));
}
export function validateAboveComment(comment) {
const commentText = comment.type === AST_TOKEN_TYPES.Line
? comment.value.trim()
: comment.value.replaceAll(/\/\*|\*\//g, '').trim();
return isValidDescription(commentText);
}