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.AbstractFileSetCheck;
8   import com.puppycrawl.tools.checkstyle.api.FileText;
9   import java.io.File;
10  
11  /**
12   * Check if import lines are all together without any empty lines or comments.
13   *
14   * <p>All {@code import} instructions shall stay together, without any empty
15   * lines between them. If you need to separate them because the list is too
16   * big - it's time to refactor the class and make is smaller.
17   *
18   * @since 0.3
19   */
20  public final class ImportCohesionCheck extends AbstractFileSetCheck {
21  
22      /**
23       * The "import" keyword.
24       */
25      private static final String IMPORT = "import ";
26  
27      @Override
28      public void processFiltered(final File file, final FileText lines) {
29          int first = -1;
30          int last = -1;
31          for (int pos = 0; pos < lines.size(); pos += 1) {
32              final String line = lines.get(pos);
33              if (line.startsWith(ImportCohesionCheck.IMPORT)) {
34                  if (first == -1) {
35                      first = pos;
36                  }
37                  last = pos;
38              }
39          }
40          if (first == -1) {
41              return;
42          }
43          if (this.check(first, last, lines)) {
44              this.fireErrors(file.getPath());
45          }
46      }
47  
48      /**
49       * Perform check for empty lines and comments inside imports.
50       * @param first Line number where import occurred first
51       * @param last Line number where import occurred first
52       * @param lines All file line by line
53       * @return True if check is failed
54       */
55      private boolean check(final int first, final int last,
56          final FileText lines
57      ) {
58          boolean failure = false;
59          if (first == 0 || !lines.get(first - 1).isEmpty()) {
60              this.log(first, "Line before imports should be empty");
61              failure = true;
62          }
63          if (lines.size() > last + 1 && !lines.get(last + 1).isEmpty()) {
64              this.log(last + 2, "Line after imports should be empty");
65              failure = true;
66          }
67          for (int pos = first; pos < last; pos += 1) {
68              final String line = lines.get(pos);
69              if (!line.startsWith(ImportCohesionCheck.IMPORT)) {
70                  this.log(
71                      pos + 1,
72                      "Empty line or comment between imports is not allowed"
73                  );
74                  failure = true;
75              }
76          }
77          return failure;
78      }
79  }