import { RULE_NAME_ALL } from './constants.mjs'; import optionsMatches from './utils/optionsMatches.mjs'; import reportCommentProblem from './utils/reportCommentProblem.mjs'; import validateDisableSettings from './validateDisableSettings.mjs'; /** @typedef {import('postcss').Node} Node */ /** @param {import('stylelint').PostcssResult} postcssResult */ export default function reportUnscopedDisables(postcssResult) { const [enabled, options] = validateDisableSettings(postcssResult, 'reportUnscopedDisables'); if (!options) return; const isDisabled = !enabled && !options.except.length; if (isDisabled) return; const stylelint = postcssResult.stylelint; const unscopedComments = stylelint.disabledRanges[RULE_NAME_ALL]; if (!unscopedComments) return; /** @param {Node} node */ const report = (node) => { reportCommentProblem({ rule: '--report-unscoped-disables', message: `Configuration comment must be scoped`, severity: options.severity, node, postcssResult, }); }; const hasExceptions = options.except.length; if (hasExceptions && !enabled) { const configRules = stylelint.config?.rules; if (!configRules) return; const warnings = stylelint.disabledWarnings; if (!warnings) return; /** @type {Set} */ const alreadyReported = new Set(); for (const { line, rule } of warnings) { const isException = optionsMatches(options, 'except', rule); if (!isException) continue; for (const { start, end, node } of unscopedComments) { if (alreadyReported.has(node)) continue; if (start <= line && (end === undefined || end >= line)) { report(node); alreadyReported.add(node); } } } } else if (enabled) { for (const { node } of unscopedComments) report(node); } }