UNPKG

el-beeswarm

Version:

<div style="display: flex; padding: 1rem; flex-direction: column; align-items: center; justify-content: center; height: 100vh; text-align: center; display: flex;

114 lines (91 loc) 3.57 kB
'use strict'; const _ = require('lodash'); const putIfAbsent = require('./utils/putIfAbsent'); /** @typedef {import('postcss/lib/comment')} PostcssComment */ /** @typedef {import('stylelint').DisabledRange} DisabledRange */ /** @typedef {import('stylelint').RangeType} RangeType */ /** @typedef {import('stylelint').DisableReportRange} DisableReportRange */ /** * @param {import('stylelint').StylelintResult[]} results */ module.exports = function (results) { results.forEach((result) => { // File with `CssSyntaxError` have not `_postcssResult` if (!result._postcssResult) { return; } const stylelintResult = result._postcssResult.stylelint; if (!stylelintResult.config) return; // Linting error if (!stylelintResult.config.reportNeedlessDisables) return; /** @type {{[ruleName: string]: Array<DisabledRange>}} */ const rangeData = _.cloneDeep(stylelintResult.disabledRanges); if (!rangeData) { return; } const disabledWarnings = stylelintResult.disabledWarnings || []; // A map from `stylelint-disable` comments to the set of rules that // are usefully disabled by each comment. We track this // comment-by-comment rather than range-by-range because ranges that // disable *all* rules are duplicated for each rule they apply to in // practice. /** @type {Map<PostcssComment, Set<string>>}} */ const usefulDisables = new Map(); for (const warning of disabledWarnings) { const rule = warning.rule; const ruleRanges = rangeData[rule]; if (ruleRanges) { for (const range of ruleRanges) { if (isWarningInRange(warning, range)) { putIfAbsent(usefulDisables, range.comment, () => new Set()).add(rule); } } } for (const range of rangeData.all) { if (isWarningInRange(warning, range)) { putIfAbsent(usefulDisables, range.comment, () => new Set()).add(rule); } } } const rangeEntries = Object.entries(rangeData); // Get rid of the duplicated ranges for each `all` rule. We only care // if the entire `all` rule is useful as a whole or not. for (const range of rangeData.all) { for (const [rule, ranges] of rangeEntries) { if (rule === 'all') continue; _.remove(ranges, (otherRange) => range.comment === otherRange.comment); } } for (const [rule, ranges] of rangeEntries) { for (const range of ranges) { const useful = usefulDisables.get(range.comment) || new Set(); // Only emit a warning if this range's comment isn't useful for this rule. // For the special rule "all", only emit a warning if it's not useful for // *any* rules, because it covers all of them. if (rule === 'all' ? useful.size !== 0 : useful.has(rule)) continue; // If the comment doesn't have a location, we can't report a useful error. // In practice we expect all comments to have locations, though. if (!range.comment.source || !range.comment.source.start) continue; result.warnings.push({ text: `Needless disable for "${rule}"`, rule: '--report-needless-disables', line: range.comment.source.start.line, column: range.comment.source.start.column, severity: 'error', }); } } }); }; /** * @param {import('stylelint').DisabledWarning} warning * @param {RangeType} range * @return {boolean} */ function isWarningInRange(warning, range) { const line = warning.line; // Need to check if range.end exist, because line number type cannot be compared to undefined return ( range.start <= line && ((range.end !== undefined && range.end >= line) || range.end === undefined) ); }