SourceTermAnalysisSystem_vue/node_modules/@eslint-community/eslint-plugin-eslint-comments/lib/internal/get-all-directive-comments.js
2026-05-15 10:22:44 +08:00

155 lines
5.6 KiB
JavaScript

"use strict"
const utils = require("./utils")
/**
* @typedef {object} DirectiveComment
* @property {string} kind The kind of directive comment.
* @property {string} [value] The directive value if it is `eslint-` comment.
* @property {string} description The description of the directive comment.
* @property {object} node The node of the directive comment.
* @property {import("@eslint/core").SourceRange} range The range of the directive comment.
* @property {import("@eslint/core").SourceLocation} loc The location of the directive comment.
*/
const pool = new WeakMap()
/**
* @param {import('eslint').SourceCode} sourceCode - The source code to scan.
* @returns {DirectiveComment[]} The directive comments.
*/
function getAllDirectiveCommentsFromAllComments(sourceCode) {
return sourceCode
.getAllComments()
.map((comment) => ({
comment,
directiveComment: utils.parseDirectiveComment(comment),
}))
.filter(({ directiveComment }) => Boolean(directiveComment))
.map(
({ comment, directiveComment }) =>
/** @type {DirectiveComment} */ ({
kind: directiveComment.kind,
value: directiveComment.value,
description: directiveComment.description,
node: comment,
range: comment.range,
loc: comment.loc,
})
)
}
/**
* @param {import('@eslint/core').TextSourceCode} sourceCode - The source code to scan.
* @returns {DirectiveComment[]} The directive comments.
*/
function getAllDirectiveCommentsFromInlineConfigNodes(sourceCode) {
const result = sourceCode.getDisableDirectives().directives.map(
(directive) =>
/** @type {DirectiveComment} */ ({
kind: `eslint-${directive.type}`,
value: directive.value,
description: directive.justification,
node: directive.node,
range: sourceCode.getRange(directive.node),
get loc() {
return sourceCode.getLoc(directive.node)
},
})
)
return result.concat(
sourceCode
.getInlineConfigNodes()
.map((node) => ({
node,
range: sourceCode.getRange(node),
}))
.filter(
({ range }) =>
// The node has intersection of the directive comment.
// So, we need to skip it.
!result.some(
(comment) =>
comment.range[0] <= range[1] &&
range[0] <= comment.range[1]
)
)
.map(({ node, range }) => {
const nodeText = sourceCode.text.slice(range[0], range[1])
const commentValue = extractCommentContent(nodeText)
const directiveComment = utils.parseDirectiveText(commentValue)
return {
directiveComment,
node,
range,
}
})
.filter(
({ directiveComment }) =>
directiveComment != null &&
![
"eslint-disable",
"eslint-disable-line",
"eslint-disable-next-line",
"eslint-enable",
].includes(directiveComment.kind)
)
.map(
({ directiveComment, node, range }) =>
/** @type {DirectiveComment} */ ({
kind: directiveComment.kind,
value: directiveComment.value,
description: directiveComment.description,
node,
range,
get loc() {
return sourceCode.getLoc(node)
},
})
)
)
}
function extractCommentContent(text) {
// Extract comment content from the comment text.
// The comment format was based on the language comment definition in vscode-eslint.
// See https://github.com/microsoft/vscode-eslint/blob/c0e753713ea9935667e849d91e549adbff213e7e/server/src/languageDefaults.ts#L14
return text.startsWith("/*") && text.endsWith("*/")
? text.slice(2, -2)
: text.startsWith("//")
? text.slice(2)
: text.startsWith("<!--") && text.endsWith("-->")
? text.slice(4, -3)
: text.startsWith("###") && text.endsWith("###")
? text.slice(3, -3)
: text.startsWith("#")
? text.slice(1)
: text
}
module.exports = {
/**
* Get all directive comments for the given rule context.
*
* @param {import("@eslint/core").RuleContext} context - The rule context to get.
* @returns {DirectiveComment[]} The all directive comments object for the rule context.
*/
getAllDirectiveComments(context) {
const sourceCode = context.sourceCode || context.getSourceCode()
let result = pool.get(sourceCode.ast)
if (result == null) {
result =
typeof sourceCode.getInlineConfigNodes === "function" &&
typeof sourceCode.getDisableDirectives === "function"
? getAllDirectiveCommentsFromInlineConfigNodes(sourceCode)
: getAllDirectiveCommentsFromAllComments(sourceCode)
pool.set(sourceCode.ast, result)
}
return result
},
}