package org.sonar.java.ast.check;
-import com.puppycrawl.tools.checkstyle.api.DetailAST;
-import com.puppycrawl.tools.checkstyle.api.TokenTypes;
+import java.util.Arrays;
+import java.util.List;
+
import org.sonar.check.Priority;
import org.sonar.check.Rule;
import org.sonar.java.ast.visitor.AstUtils;
import org.sonar.squid.api.CheckMessage;
import org.sonar.squid.api.SourceFile;
-import java.util.Arrays;
-import java.util.List;
+import com.puppycrawl.tools.checkstyle.api.DetailAST;
+import com.puppycrawl.tools.checkstyle.api.TokenTypes;
-@Rule(
- key = "AvoidBreakOutsideSwitch",
- name = "Avoid using 'break' branching statement outside a 'switch' statement",
- priority = Priority.MAJOR,
- description = "<p>The use of the 'break' branching statement increases the essential complexity of the source code and "
- + "so prevents any refactoring of this source code to replace all well structured control structures with a single statement.</p>"
- + "<p>For instance, with the following java program fragment, it's not possible to apply "
- + "the 'extract method' refactoring pattern :</p>"
- + "<pre>"
- + "mylabel : for (int i = 0 ; i< 3; i++) {\n"
- + " for (int j = 0; j < 4 ; j++) {\n"
- + " doSomething();\n"
- + " if (checkSomething()) {\n"
- + " break mylabel;\n"
- + " }\n"
- + " }\n"
- + "}\n"
- + "</pre>"
- + "<p>The use of the 'break' branching statement is only authorized inside a 'switch' statement.</p>")
+@Rule(key = "AvoidBreakOutsideSwitch", priority = Priority.MAJOR)
public class BreakCheck extends JavaAstCheck {
@Override
package org.sonar.java.ast.check;
-import com.puppycrawl.tools.checkstyle.api.DetailAST;
-import com.puppycrawl.tools.checkstyle.api.TokenTypes;
+import java.util.Arrays;
+import java.util.List;
+
import org.sonar.check.Priority;
import org.sonar.check.Rule;
import org.sonar.squid.api.CheckMessage;
import org.sonar.squid.api.SourceCode;
import org.sonar.squid.api.SourceFile;
-import java.util.Arrays;
-import java.util.List;
+import com.puppycrawl.tools.checkstyle.api.DetailAST;
+import com.puppycrawl.tools.checkstyle.api.TokenTypes;
-@Rule(key = "AvoidContinueStatement", name = "Avoid using 'continue' branching statement",
- priority = Priority.MAJOR, description = "<p>The use of the 'continue' branching statement increase the essential complexity "
- + "of the source code and so prevent any refactoring of this source code to replace all well structured control structures "
- + "with a single statement.</p><p>For instance, in the following java program fragment, it's not possible to apply "
- + "the 'extract method' refactoring pattern :</p>"
- + "<pre>"
- + "mylabel : for(int i = 0 ; i< 3; i++) {\n"
- + " for (int j = 0; j < 4 ; j++) {\n"
- + " doSomething();\n"
- + " if (checkSomething()) {\n"
- + " continue mylabel;\n"
- + " }\n"
- + " }\n"
- + "}\n"
- + "</pre>")
+@Rule(key = "AvoidContinueStatement", priority = Priority.MAJOR)
public class ContinueCheck extends JavaAstCheck {
@Override
package org.sonar.java.ast.check;
-import com.puppycrawl.tools.checkstyle.api.DetailAST;
+import java.util.List;
+
import org.apache.commons.lang.StringUtils;
import org.sonar.api.utils.WildcardPattern;
import org.sonar.check.Priority;
import org.sonar.check.RuleProperty;
import org.sonar.java.PatternUtils;
import org.sonar.java.ast.visitor.PublicApiVisitor;
-import org.sonar.squid.api.*;
+import org.sonar.squid.api.CheckMessage;
+import org.sonar.squid.api.SourceClass;
+import org.sonar.squid.api.SourceCode;
+import org.sonar.squid.api.SourceFile;
+import org.sonar.squid.api.SourceMethod;
-import java.util.List;
+import com.puppycrawl.tools.checkstyle.api.DetailAST;
-@Rule(key = "UndocumentedApi", name = "Undocumented API", priority = Priority.MAJOR,
- description = "<p>Check that each public class, interface, method and constructor has a Javadoc comment. "
- + "The following public methods/constructors are not concerned by this rule :</p>" + "<ul><li>Getter / Setter</li>"
- + "<li>Method with @Override annotation</li>" + "<li>Empty constructor</li></ul>")
+@Rule(key = "UndocumentedApi", priority = Priority.MAJOR)
public class UndocumentedApiCheck extends JavaAstCheck {
- @RuleProperty(description = "Optional. If this property is not defined, all classes should adhere to this constraint. Ex : **.api.**")
+ @RuleProperty
private String forClasses = "";
private WildcardPattern[] patterns;
*/
package org.sonar.java.bytecode.check;
-import com.google.common.collect.Maps;
+import java.util.Map;
+
import org.apache.commons.lang.StringUtils;
import org.sonar.api.utils.WildcardPattern;
import org.sonar.check.Cardinality;
import org.sonar.squid.api.SourceFile;
import org.sonar.squid.api.SourceMethod;
-import java.util.Map;
+import com.google.common.collect.Maps;
-@Rule(key = "ArchitecturalConstraint", name = "Architectural constraint", cardinality = Cardinality.MULTIPLE,
- priority = Priority.MAJOR,
- description = "<p>A source code comply to an architectural model when it fully adheres to a set of architectural constraints. " +
- "A constraint allows to deny references between classes by pattern.</p>" +
- "<p>You can for instance use this rule to :</p>" +
- "<ul><li>forbid access to **.web.** from **.dao.** classes</li>" +
- "<li>forbid access to java.util.Vector, java.util.Hashtable and java.util.Enumeration from any classes</li>" +
- "<li>forbid access to java.sql.** from **.ui.** and **.web.** classes</li></ul>")
+@Rule(key = "ArchitecturalConstraint", cardinality = Cardinality.MULTIPLE, priority = Priority.MAJOR)
public class ArchitectureCheck extends BytecodeCheck {
- @RuleProperty(description = "Optional. If this property is not defined, all classes should adhere to this constraint. Ex : **.web.**")
+ @RuleProperty
private String fromClasses = "";
- @RuleProperty(description = "Mandatory. Ex : java.util.Vector, java.util.Hashtable, java.util.Enumeration")
+ @RuleProperty
private String toClasses = "";
private WildcardPattern[] fromPatterns;
public void visitEdge(AsmEdge edge) {
if (asmClass != null && edge != null) {
String internalNameTargetClass = edge.getTargetAsmClass().getInternalName();
- if (!internalNames.containsKey(internalNameTargetClass)) {
+ if ( !internalNames.containsKey(internalNameTargetClass)) {
if (WildcardPattern.match(getToPatterns(), internalNameTargetClass)) {
int sourceLineNumber = getSourceLineNumber(edge);
logMessage(asmClass.getInternalName(), internalNameTargetClass, sourceLineNumber);
import org.sonar.squid.api.CheckMessage;
import org.sonar.squid.api.SourceFile;
-@Rule(key = "CallToDeprecatedMethod", name = "Avoid use of deprecated method", priority = Priority.MINOR,
- description = "<p>Once deprecated, a method should no longer be used as it means that "
- + "the method might be removed sooner or later.</p>")
+@Rule(key = "CallToDeprecatedMethod", priority = Priority.MINOR)
public class CallToDeprecatedMethodCheck extends BytecodeCheck {
private AsmClass asmClass;
import org.sonar.squid.api.SourceFile;
import org.sonar.squid.api.SourceMethod;
-@Rule(key = "UnusedPrivateMethod", name = "Unused private method",
- priority = Priority.MAJOR, description = "<p>Private methods that are never executed are dead code. " +
- "Dead code means unnecessary, inoperative code that should be removed. " +
- "This helps in maintenance by decreasing the maintained code size, " +
- "making it easier to understand the program and preventing bugs from being introduced.</p>" +
- "<p>In the following two cases, private methods are not considered as dead code by Sonar :</p>" +
- "<ul><li>Private empty constructors that are intentionally used to prevent any direct instantiation of a class.</li>" +
- "<li>Private methods : readObject(...), writeObject(...), writeReplace(...), readResolve(...) " +
- "which can contractually be used when implementing the Serializable interface.</li></ul>")
+@Rule(key = "UnusedPrivateMethod", priority = Priority.MAJOR)
public class UnusedPrivateMethodCheck extends BytecodeCheck {
private AsmClass asmClass;
@Override
public void visitMethod(AsmMethod asmMethod) {
- if (!asmMethod.isUsed() && asmMethod.isPrivate() && !asmMethod.isDefaultConstructor() && !SerializableContract.methodMatch(asmMethod)) {
+ if ( !asmMethod.isUsed() && asmMethod.isPrivate() && !asmMethod.isDefaultConstructor() && !SerializableContract.methodMatch(asmMethod)) {
CheckMessage message = new CheckMessage(this, "Private method '" + asmMethod.getName() + "(...)' is never used.");
SourceMethod sourceMethod = getSourceMethod(asmMethod);
if (sourceMethod != null) {
import org.sonar.squid.api.SourceFile;
import org.sonar.squid.api.SourceMethod;
-@Rule(key = "UnusedProtectedMethod", name = "Unused protected method",
- priority = Priority.MAJOR, description = "<p>Protected methods that are never used by any classes " +
- "in the same project are strongly suspected to be dead code. "
- + "Dead code means unnecessary, inoperative code that should be removed. "
- + "This helps in maintenance by decreasing the maintained code size, "
- + "making it easier to understand the program and preventing bugs from being introduced.</p>"
- + "<p>In the following case, unused protected methods are not considered as dead code by Sonar :</p>"
- + "<ul><li>Protected methods which override a method from a parent class.</li></ul>"
- + "<ul><li>Protected methods of an abstract class.</li></ul>")
+@Rule(key = "UnusedProtectedMethod", priority = Priority.MAJOR)
public class UnusedProtectedMethodCheck extends BytecodeCheck {
private AsmClass asmClass;
@Override
public void visitMethod(AsmMethod asmMethod) {
- if (!asmMethod.isUsed() && asmMethod.isProtected() && !asmClass.isAbstract() && !SerializableContract.methodMatch(asmMethod)
+ if ( !asmMethod.isUsed() && asmMethod.isProtected() && !asmClass.isAbstract() && !SerializableContract.methodMatch(asmMethod)
&& !asmMethod.isInherited()) {
CheckMessage message = new CheckMessage(this, "Protected method '" + asmMethod.getName() + "(...)' is never used.");
SourceMethod sourceMethod = getSourceMethod(asmMethod);
import org.sonar.squid.api.SourceFile;
import org.sonar.squid.measures.Metric;
-@Rule(key = "ClassCyclomaticComplexity", name = "Avoid too complex class",
- priority = Priority.MAJOR, description = "<p>The Cyclomatic Complexity is measured by the number of (&&, ||) operators "
- + "and (if, while, do, for, ?:, catch, switch, case, return, throw) statements in the body of a class plus one for "
- + "each constructor, method (but not getter/setter), static initializer, or instance initializer in the class. "
- + "The last return stament in method, if exists, is not taken into account.</p>"
- + "<p>Even when the Cyclomatic Complexity of a class is very high, this complexity might be well distributed among all methods. "
- + "Nevertheless, most of the time, a very complex class is a class which breaks the "
- + "<a href='http://en.wikipedia.org/wiki/Single_responsibility_principle'>Single Responsibility Principle</a> "
- + "and which should be re-factored to be split in several classes.</p>")
+@Rule(key = "ClassCyclomaticComplexity", priority = Priority.MAJOR)
public class ClassComplexityCheck extends SquidCheck {
public static final int DEFAULT_MAX = 200;
- @RuleProperty(description = "Maximum complexity allowed.", defaultValue = "" + DEFAULT_MAX)
+ @RuleProperty(defaultValue = "" + DEFAULT_MAX)
private Integer max = DEFAULT_MAX;
@Override
import org.sonar.squid.api.SourceFile;
import org.sonar.squid.measures.Metric;
-@Rule(key = "MaximumInheritanceDepth", name = "Avoid too deep inheritance tree",
- priority = Priority.MAJOR, description = "<p>Inheritance is certainly one of the most valuable concept of object-oriented "
- + "programming. It's a way to compartmentalize and reuse code by creating collections of attributes and behaviors called "
- + "classes which can be based on previously created classes. But abusing of this concept by creating a deep inheritance tree "
- + "can lead to very complex and unmaintainable source code.</p>"
- + "<p>Most of the time a too deep inheritance tree is due to bad object oriented design which has led to systematically use "
- + "'inheritance' when 'composition' would suit better.</p>")
+@Rule(key = "MaximumInheritanceDepth", priority = Priority.MAJOR)
public class DITCheck extends SquidCheck {
public static final int DEFAULT_MAX = 5;
- @RuleProperty(description = "Maximum depth of the inheritance tree.", defaultValue = "" + DEFAULT_MAX)
+ @RuleProperty(defaultValue = "" + DEFAULT_MAX)
private Integer max = DEFAULT_MAX;
@Override
import org.sonar.squid.api.SourceFile;
import org.sonar.squid.measures.Metric;
-@Rule(key = "EmptyFile", name = "Empty file", priority = Priority.MAJOR,
- description = "Detect empty files, which do not have any lines of code. Example: <pre>\n//package org.foo;\n//\n//public class Bar {}\n</pre>")
+@Rule(key = "EmptyFile", priority = Priority.MAJOR)
public final class EmptyFileCheck extends SquidCheck {
@Override
import org.sonar.squid.api.SourceMethod;
import org.sonar.squid.measures.Metric;
-@Rule(key = "MethodCyclomaticComplexity", name = "Avoid too complex method",
- priority = Priority.MAJOR, description = "<p>The Cyclomatic Complexity is measured by the number of (&&, ||) operators "
- + "and (if, while, do, for, ?:, catch, switch, case, return, throw) statements in the body of a constructor, "
- + "method, static initializer, or instance initializer. "
- + "The minimun Cyclomatic Complexity of a method is 1 and the last return stament, if exists, is not taken into account. "
- + "The more complex is a method, the more possible different paths through the source code exist. "
- + "Generally 1-4 is considered good, 5-7 ok, 8-10 consider re-factoring, and 11+ re-factor now. "
- + "Indeed above 10, it's pretty difficult to be able to think about all possible paths when maintaining the source code, "
- + "so the risk of regression increases exponentially.</p>")
+@Rule(key = "MethodCyclomaticComplexity", priority = Priority.MAJOR)
public class MethodComplexityCheck extends SquidCheck {
public static final int DEFAULT_MAX = 10;
- @RuleProperty(description = "Maximum complexity allowed.", defaultValue = "" + DEFAULT_MAX)
+ @RuleProperty(defaultValue = "" + DEFAULT_MAX)
private Integer max = DEFAULT_MAX;
@Override
import org.sonar.squid.api.CheckMessage;
import org.sonar.squid.api.SourceFile;
-@Rule(key = "NoSonar", name = "Avoid use of //NOSONAR marker", priority = Priority.INFO,
- description = "<p>Any violation to quality rule can be deactivated with the //NOSONAR marker. This marker is pretty useful to exclude "
- + "false-positive results but sometimes it can abusively be used to hide real quality flaws.</p>"
- + "<p>This rule allows to track and/or forbid use of this marker</p>")
+@Rule(key = "NoSonar", priority = Priority.INFO)
public class NoSonarCheck extends SquidCheck {
@Override