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.</p>
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      /**
28       * Default constructor.
29       */
30      public ImportCohesionCheck() {
31          // nothing to initialize
32      }
33  
34      @Override
35      public void processFiltered(final File file, final FileText lines) {
36          int first = -1;
37          int last = -1;
38          for (int pos = 0; pos < lines.size(); pos += 1) {
39              final String line = lines.get(pos);
40              if (line.startsWith(ImportCohesionCheck.IMPORT)) {
41                  if (first == -1) {
42                      first = pos;
43                  }
44                  last = pos;
45              }
46          }
47          if (first == -1) {
48              return;
49          }
50          if (this.check(first, last, lines)) {
51              this.fireErrors(file.getPath());
52          }
53      }
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  }