View Javadoc
1   /*
2    * SPDX-FileCopyrightText: Copyright (c) 2011-2026 Yegor Bugayenko
3    * SPDX-License-Identifier: MIT
4    */
5   package com.qulice.checkstyle;
6   
7   import com.puppycrawl.tools.checkstyle.api.AuditEvent;
8   import java.util.Collection;
9   
10  /**
11   * One {@code @checkstyle} suppression comment and the range it covers.
12   *
13   * <p>A comment like {@code @checkstyle TypeName (N lines)} tells the
14   * suppression filters of {@code checks.xml} to drop violations of
15   * {@code TypeName} on the lines it influences. The same holds for a pair
16   * of {@code disable} and {@code enable} comments, whose range runs from
17   * one to the other. A tag that influences
18   * no violation of its check suppresses nothing and lingers as a lie about
19   * the code, which is what {@link Suppressions} finds with the help of this
20   * class.</p>
21   *
22   * @since 1.0
23   */
24  final class SuppressionTag {
25  
26      /**
27       * Name of the check that the suppression targets.
28       */
29      private final String check;
30  
31      /**
32       * First line of the range the suppression influences, which is also
33       * the line of the comment where a violation about it is reported.
34       */
35      private final int first;
36  
37      /**
38       * Last line of the range the suppression influences.
39       */
40      private final int last;
41  
42      /**
43       * Constructor.
44       *
45       * @param check Name of the suppressed check
46       * @param first First line of the influence range, and of the comment
47       * @param last Last line of the influence range
48       */
49      SuppressionTag(final String check, final int first, final int last) {
50          this.check = check;
51          this.first = first;
52          this.last = last;
53      }
54  
55      /**
56       * Name of the suppressed check.
57       *
58       * @return The name
59       */
60      String check() {
61          return this.check;
62      }
63  
64      /**
65       * Line of the comment, where a violation about it belongs.
66       *
67       * @return Line number
68       */
69      int line() {
70          return this.first;
71      }
72  
73      /**
74       * Does this suppression influence none of these events?
75       *
76       * <p>The filters match the captured name against the fully qualified
77       * class name of the check, which the name is a substring of, so the
78       * same test decides here whether an event belongs to the suppressed
79       * check.</p>
80       *
81       * @param events Events collected with the nearby filters removed
82       * @return True if no event of the check falls in the influence range
83       */
84      boolean unused(final Collection<AuditEvent> events) {
85          return events.stream().noneMatch(this::covers);
86      }
87  
88      private boolean covers(final AuditEvent event) {
89          return event.getSourceName().contains(this.check)
90              && event.getLine() >= this.first
91              && event.getLine() <= this.last;
92      }
93  }