View Javadoc
1   ////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code for adherence to a set of rules.
3   // Copyright (C) 2001-2017 the original author or authors.
4   //
5   // This library is free software; you can redistribute it and/or
6   // modify it under the terms of the GNU Lesser General Public
7   // License as published by the Free Software Foundation; either
8   // version 2.1 of the License, or (at your option) any later version.
9   //
10  // This library is distributed in the hope that it will be useful,
11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  // Lesser General Public License for more details.
14  //
15  // You should have received a copy of the GNU Lesser General Public
16  // License along with this library; if not, write to the Free Software
17  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  ////////////////////////////////////////////////////////////////////////////////
19  
20  package com.puppycrawl.tools.checkstyle.checks.sizes;
21  
22  import java.util.regex.Pattern;
23  
24  import com.puppycrawl.tools.checkstyle.StatelessCheck;
25  import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
26  import com.puppycrawl.tools.checkstyle.api.DetailAST;
27  import com.puppycrawl.tools.checkstyle.utils.CommonUtils;
28  
29  /**
30   * Checks for long lines.
31   *
32   * <p>
33   * Rationale: Long lines are hard to read in printouts or if developers
34   * have limited screen space for the source code, e.g. if the IDE displays
35   * additional information like project tree, class hierarchy, etc.
36   * </p>
37   *
38   * <p>
39   * Package statements and import statements (lines matching pattern
40   * {@code ^(package|import) .*}), and are not verified by this check.
41   * </p>
42   * <p>
43   * The default maximum allowable line length is 80 characters. To change the
44   * maximum, set property max.
45   * </p>
46   * <p>
47   * To ignore lines in the check, set property ignorePattern to a regular
48   * expression for the lines to ignore.
49   * </p>
50   * <p>
51   * An example of how to configure the check is:
52   * </p>
53   * <pre>
54   * &lt;module name="LineLength"/&gt;
55   * </pre>
56   * <p> An example of how to configure the check to accept lines up to 120
57   * characters long is:
58   *</p>
59   * <pre>
60   * &lt;module name="LineLength"&gt;
61   *    &lt;property name="max" value="120"/&gt;
62   * &lt;/module&gt;
63   * </pre>
64   * <p> An example of how to configure the check to ignore lines that begin with
65   * &quot; * &quot;, followed by just one word, such as within a Javadoc comment,
66   * is:
67   * </p>
68   * <pre>
69   * &lt;module name="LineLength"&gt;
70   *    &lt;property name="ignorePattern" value="^ *\* *[^ ]+$"/&gt;
71   * &lt;/module&gt;
72   * </pre>
73   *
74   * @author Lars K├╝hne
75   */
76  @StatelessCheck
77  public class LineLengthCheck extends AbstractCheck {
78  
79      /**
80       * A key is pointing to the warning message text in "messages.properties"
81       * file.
82       */
83      public static final String MSG_KEY = "maxLineLen";
84  
85      /** Default maximum number of columns in a line. */
86      private static final int DEFAULT_MAX_COLUMNS = 80;
87  
88      /** Patterns matching package, import, and import static statements. */
89      private static final Pattern IGNORE_PATTERN = Pattern.compile("^(package|import) .*");
90  
91      /** The maximum number of columns in a line. */
92      private int max = DEFAULT_MAX_COLUMNS;
93  
94      /** The regexp when long lines are ignored. */
95      private Pattern ignorePattern = Pattern.compile("^$");
96  
97      @Override
98      public int[] getDefaultTokens() {
99          return getRequiredTokens();
100     }
101 
102     @Override
103     public int[] getAcceptableTokens() {
104         return getRequiredTokens();
105     }
106 
107     @Override
108     public int[] getRequiredTokens() {
109         return CommonUtils.EMPTY_INT_ARRAY;
110     }
111 
112     @Override
113     public void beginTree(DetailAST rootAST) {
114         final String[] lines = getLines();
115         for (int i = 0; i < lines.length; i++) {
116 
117             final String line = lines[i];
118             final int realLength = CommonUtils.lengthExpandedTabs(
119                 line, line.length(), getTabWidth());
120 
121             if (realLength > max && !IGNORE_PATTERN.matcher(line).find()
122                 && !ignorePattern.matcher(line).find()) {
123                 log(i + 1, MSG_KEY, max, realLength);
124             }
125         }
126     }
127 
128     /**
129      * Sets the maximum length of a line.
130      * @param length the maximum length of a line
131      */
132     public void setMax(int length) {
133         max = length;
134     }
135 
136     /**
137      * Set the ignore pattern.
138      * @param pattern a pattern.
139      */
140     public final void setIgnorePattern(Pattern pattern) {
141         ignorePattern = pattern;
142     }
143 }