Most every linter has an option to "ignore" some parts of the code:

/* @eslint-ignore-next-line semi */
// @phpstan-ignore
// @ts-ignore
# noqa: E731

I'm wondering how these could be implemented. It seems to not simply be removing the next line from the source code, since other lines effected still work. For example, ESLint doesn't report "unused variable" errors when the only place a variable is used is in an ignored line.

Is there some kind of dual parsing mode that allows parsing a line bug ignoring any errors on that line? How is this typically implemented?

  • 7
    $\begingroup$ Could this not just be as simple as creating diagnostics normally, then filtering the ones where the source span is on an ignored line? $\endgroup$
    – Bbrk24
    Dec 11, 2023 at 20:03

1 Answer 1


The typical approach is that these annotations suppress reporting of problems, rather than their detection. Once potential issues have been found, only those that don't have something suppressing them are printed out. Those filters can then also be quite fine-grained about which lines, which classes of error, or which variables are included or excluded.

For example, ESLint gathers the list of disable directives and matches them with detected problems, suppressing reporting of the ignored issues. TypeScript does the same thing

// Diagnostics are only reported if there is no comment directive preceding them
// This will modify the directives map by marking "used" ones with a corresponding diagnostic

A significant benefit of this approach over repressing the detection in the first place is that diagnostics can also be given for ignored issues that aren't actually present; that can also be a sign of a problem, or just an opportunity to remove a marker that's no longer required.

There is no special parsing mode required, and generally no actual parsing involved: the linter operates on either already-parsed syntax trees or on the raw source text (or both) depending on the nature of the checks.

Disabling analyses at the whole-file or whole-codebase level more often does turn off running them at all, because the running cost can be spared and the benefits of reporting unneeded suppressions at that level are limited. If there is a particularly expensive single-line analysis (something interprocedural, perhaps), then it could make sense to allow turning it off individually as well, but I can't think of an instance of that off-hand; possibly loop termination checking could be an example, but that's less often a linter matter.

  • 3
    $\begingroup$ „diagnostics can also be given for ignored issues that aren't actually present“ – @ts-expect-error does exactly that, and I find it immensely useful. $\endgroup$ Dec 11, 2023 at 22:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .