React-Doctor Inline Suppression System: How Stacked Comments Work
React-Doctor's inline suppression system evaluates stacked disable-next-line comments by walking upward from a diagnostic to build a chain of contiguous directives, using the isInChain flag to determine active suppressors while generating actionable hints for rule mismatches or excessive distance via evaluateSuppression in src/utils/evaluate-suppression.ts.
React-Doctor, an open-source diagnostic tool maintained at millionco/react-doctor, provides a robust inline suppression system that allows developers to silence specific linting rules directly within source code. Unlike basic line-by-line disable comments, the system supports stacked comments—multiple directives placed consecutively above a diagnostic—that collectively determine whether a rule fires. Understanding the mechanism behind these stacked comments, including how the engine detects chains and surfaces "near-miss" hints, is essential for effective diagnostic management.
Core Suppression Directives and Syntax
React-Doctor recognizes two primary inline suppression patterns controlled by regex constants defined in src/constants.ts:
// react-doctor-disable-line– Suppresses a rule on the same line where the comment appears. The scanner matches this againstDISABLE_LINE_PATTERN.// react-doctor-disable-next-line– Suppresses a rule on the following line. This matchesDISABLE_NEXT_LINE_PATTERN, which uses a permissive[^\r\n]*?capture to include optional explanatory text after--.
Block-style JSX variants {/* react-doctor-disable-next-line */} function identically within JSX contexts. When multiple disable-next-line comments appear directly above a diagnostic, the stacked comment logic groups them to determine if the diagnostic is truly suppressed.
Detecting Stacked Comments
The Upward Walk Algorithm
The engine identifies stacked comments through findStackedDisableCommentsAbove in src/utils/find-stacked-disable-comments.ts. Starting from the diagnostic line (the anchor index), the function walks upward through the source array passed from scan.ts, collecting matches for up to SUPPRESSION_NEAR_MISS_MAX_LINES lines.
Each match produces a StackedDisableComment object containing:
- The line index of the comment
- The raw rule list (e.g.,
no-console, react-doctor/no-useless-memo) - The
isInChainboolean flag
The Role of isInChain
The isInChain flag is the critical mechanism enabling stacked behavior. As the walker encounters consecutive disable-next-line comments, it marks each with isInChain: true. If a non-matching line interrupts the sequence—such as a blank line or code—subsequent comments receive isInChain: false. Only comments where isInChain remains true can suppress the current diagnostic, ensuring that separated comment blocks do not unintentionally disable unrelated code.
Evaluating Suppression Logic
Same-Line Suppression Checks
In src/utils/evaluate-suppression.ts, the evaluateSuppression function first checks for same-line directives. If DISABLE_LINE_PATTERN matches the current line and isRuleListedInComment (from src/utils/is-rule-listed-in-comment.ts) confirms the rule ID is present—including stripping any -- description tail—the diagnostic is immediately suppressed.
Chain Suppression and JSX Handling
For disable-next-line directives, the evaluator checks two potential chains:
- Direct chain – Uses
hasChainSuppressorto verify if any collectedStackedDisableCommentwithisInChain: truelists the fired rule. - JSX opener chain – For attribute-level diagnostics, the engine calls
findEnclosingMultilineJsxOpenerStartfromsrc/utils/find-enclosing-multiline-jsx-opener.tsto locate the opening tag line, allowing suppressions placed above the tag to affect attributes within it.
If neither chain contains a matching rule, the diagnostic reports, but the system proceeds to generate helpful hints.
Near-Miss Hint System
When suppression fails, React-Doctor analyzes the collected comments to distinguish between adjacent mismatches and distance violations, outputting guidance via src/cli.ts in --json or --audit mode.
Adjacent Rule-List Mismatch
If a comment remains in the chain (isInChain: true) but its rule list excludes the fired rule—detected by isRuleListedInComment—the system invokes buildAdjacentMismatchHint. This produces a message indicating which rules are present and suggests using comma-separated IDs to combine suppressions.
Gap Detection Using SUPPRESSION_NEAR_MISS_MAX_LINES
If the nearest matching comment exceeds SUPPRESSION_NEAR_MISS_MAX_LINES (defined in src/constants.ts), the engine triggers buildGapHint. This informs the user that the comment is too distant from the diagnostic, recommending they move the directive adjacent to the target line or refactor the code into a helper function.
Practical Implementation Examples
Example 1: Same-Line Suppression
// react-doctor-disable-line no-console
console.log('debug'); // Diagnostic suppressed via direct line match
The scanner matches DISABLE_LINE_PATTERN and isRuleListedInComment returns true, yielding a SuppressionEvaluation with isSuppressed: true.
Example 2: Stacked disable-next-line Comments
// react-doctor-disable-next-line no-console
// react-doctor-disable-next-line react-doctor/no-useless-memo
const value = expensiveComputation(); // Both rules suppressed
findStackedDisableCommentsAbove returns two objects with isInChain: true. hasChainSuppressor identifies that each rule is covered by at least one comment in the chain.
Example 3: Rule-List Mismatch
// react-doctor-disable-next-line no-console
const value = expensiveComputation(); // react-doctor/no-useless-memo fires
The comment is in-chain, but isRuleListedInComment detects the absence of react-doctor/no-useless-memo. buildAdjacentMismatchHint generates a message suggesting the comma form to include both rules.
Example 4: Comment Distance Violation
// react-doctor-disable-next-line react-doctor/no-useless-memo
function helper() {
return null;
}
const value = expensiveComputation(); // Gap hint triggered
With three lines separating the comment from the diagnostic, exceeding SUPPRESSION_NEAR_MISS_MAX_LINES, hasChainSuppressor returns false and buildGapHint advises moving the comment to line 9.
Summary
- Stacked comments are detected by
findStackedDisableCommentsAboveinsrc/utils/find-stacked-disable-comments.ts, which walks upward from the diagnostic to collect contiguousdisable-next-linedirectives. - The
isInChainflag determines whether a comment remains part of an uninterrupted block; once broken, subsequent comments cannot suppress the current diagnostic. - Suppression evaluation in
src/utils/evaluate-suppression.tschecks same-line patterns viaDISABLE_LINE_PATTERN, then validates chains usinghasChainSuppressorand JSX opener logic. - Near-miss hints distinguish between adjacent rule mismatches (fixed by updating the rule list) and gap violations (fixed by repositioning the comment within
SUPPRESSION_NEAR_MISS_MAX_LINES). - Rule parsing occurs in
src/utils/is-rule-listed-in-comment.ts, which strips descriptive text after--to accurately identify suppression targets.
Frequently Asked Questions
How does React-Doctor distinguish between stacked and separated disable-next-line comments?
The system uses the isInChain boolean flag set by findStackedDisableCommentsAbove. Comments are marked isInChain: true only while consecutive disable-next-line matches continue uninterrupted; any non-matching line breaks the chain, setting subsequent comments to isInChain: false and excluding them from suppression evaluation.
Can I suppress multiple rules with a single stacked comment block?
Yes. By placing multiple // react-doctor-disable-next-line comments consecutively above a diagnostic—each listing different rules—the engine treats them as a single chain. hasChainSuppressor checks the aggregate rule lists of all in-chain comments, suppressing the diagnostic if any comment includes the fired rule.
What happens if my disable-next-line comment is too far from the diagnostic?
If the comment exceeds SUPPRESSION_NEAR_MISS_MAX_LINES (defined in src/constants.ts), the engine classifies it as a gap violation. While the comment remains in the chain, hasChainSuppressor returns false, and buildGapHint generates a message advising you to move the comment adjacent to the diagnostic line.
How does the system handle JSX attribute-level suppressions?
For diagnostics targeting JSX attributes, evaluateSuppression calls findEnclosingMultilineJsxOpenerStart from src/utils/find-enclosing-multiline-jsx-opener.ts to locate the opening tag line. This allows disable-next-line comments placed above the JSX tag itself to suppress attribute-level rules within the tag, treating the opener as part of the suppression chain.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →