]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-1930: Create a SQUID rule : depth of inheritance should not exceed XX
authorGodin <mandrikov@gmail.com>
Tue, 23 Nov 2010 15:43:22 +0000 (15:43 +0000)
committerGodin <mandrikov@gmail.com>
Tue, 23 Nov 2010 15:43:22 +0000 (15:43 +0000)
plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/check/DITCheck.java
plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/check/DITCheckTest.java

index 0dbe5e0bb7f9c0e3dda15c78b51859bb1d42857f..0b88ee55da199417beec2dcb5243b0658c6ceb1a 100644 (file)
@@ -1,6 +1,7 @@
 package org.sonar.java.bytecode.check;
 
 import org.sonar.check.IsoCategory;
+import org.sonar.check.Priority;
 import org.sonar.check.Rule;
 import org.sonar.check.RuleProperty;
 import org.sonar.java.bytecode.asm.AsmClass;
@@ -8,24 +9,32 @@ import org.sonar.squid.api.CheckMessage;
 import org.sonar.squid.api.SourceClass;
 import org.sonar.squid.measures.Metric;
 
-@Rule(key = "DIT", name = "DIT", isoCategory = IsoCategory.Maintainability)
+@Rule(key = "MaximumInheritanceDepth", name = "Avoid too deep inheritance tree", isoCategory = IsoCategory.Maintainability,
+    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>")
 public class DITCheck extends BytecodeCheck {
 
-  @RuleProperty(description = "Threshold.")
-  private Integer threshold;
+  @RuleProperty(description = "Maximum depth of the inheritance tree.", defaultValue = "5")
+  private Integer max;
 
   @Override
   public void visitClass(AsmClass asmClass) {
     SourceClass sourceClass = getSourceClass(asmClass);
     int dit = sourceClass.getInt(Metric.DIT);
-    if (dit > threshold) {
-      CheckMessage message = new CheckMessage(this, "Depth of inheritance exceeds " + threshold + ".");
+    if (dit > max) {
+      CheckMessage message = new CheckMessage(this, "This class has " + dit
+          + " parents which makes it complex to understand and to maintain.");
       message.setLine(sourceClass.getStartAtLine());
+      message.setCost(dit - max);
       getSourceFile(asmClass).log(message);
     }
   }
 
-  public void setThreshold(int threshold) {
-    this.threshold = threshold;
+  public void setMax(int max) {
+    this.max = max;
   }
 }
index ad7865b373a0db751915ccc2771d45d54cd49dc3..bbe16d511170a0b5fff409e4021085b7162a87a1 100644 (file)
@@ -22,13 +22,13 @@ public class DITCheckTest {
     squid = new Squid(new JavaSquidConfiguration());
     squid.register(JavaAstScanner.class).scanDirectory(getFile("/bytecode/unusedProtectedMethod/src"));
     DITCheck check = new DITCheck();
-    check.setThreshold(1);
+    check.setMax(1);
     squid.registerVisitor(check);
     squid.register(BytecodeScanner.class).scanDirectory(getFile("/bytecode/unusedProtectedMethod/bin"));
   }
 
   @Test
-  public void testDepthOfInheritanceExceedsThreshold() {
+  public void testDepthOfInheritanceGreaterThanMaximum() {
     SourceFile file = (SourceFile) squid.search("UnusedProtectedMethod.java");
     assertThat(file.getCheckMessages().size(), is(1));
     CheckMessage message = file.getCheckMessages().iterator().next();
@@ -36,7 +36,7 @@ public class DITCheckTest {
   }
 
   @Test
-  public void testDepthOfInheritanceNotExceedsThreshold() {
+  public void testDepthOfInheritanceLowerThanMaximum() {
     SourceFile file = (SourceFile) squid.search("Job.java");
     assertThat(file.getCheckMessages().size(), is(0));
   }