diff --git a/its/ruling/src/test/resources/jdk6/squid-S1118.json b/its/ruling/src/test/resources/jdk6/squid-S1118.json index 09d622f4008..7cab43c9020 100644 --- a/its/ruling/src/test/resources/jdk6/squid-S1118.json +++ b/its/ruling/src/test/resources/jdk6/squid-S1118.json @@ -29,36 +29,6 @@ 'jdk6:java/io/ObjectStreamClass.java':[ 65, ], -'jdk6:java/lang/CharacterData00.java':[ -19, -], -'jdk6:java/lang/CharacterData01.java':[ -18, -], -'jdk6:java/lang/CharacterData02.java':[ -17, -], -'jdk6:java/lang/CharacterData0E.java':[ -16, -], -'jdk6:java/lang/CharacterDataLatin1.java':[ -17, -], -'jdk6:java/lang/CharacterDataPrivateUse.java':[ -16, -], -'jdk6:java/lang/CharacterDataUndefined.java':[ -16, -], -'jdk6:java/lang/ConditionalSpecialCasing.java':[ -29, -], -'jdk6:java/lang/Shutdown.java':[ -22, -], -'jdk6:java/lang/Terminator.java':[ -23, -], 'jdk6:java/lang/reflect/Modifier.java':[ 35, ], diff --git a/java-checks/src/main/java/org/sonar/java/checks/UtilityClassWithPublicConstructorCheck.java b/java-checks/src/main/java/org/sonar/java/checks/UtilityClassWithPublicConstructorCheck.java index be5ac22d455..378086bc927 100644 --- a/java-checks/src/main/java/org/sonar/java/checks/UtilityClassWithPublicConstructorCheck.java +++ b/java-checks/src/main/java/org/sonar/java/checks/UtilityClassWithPublicConstructorCheck.java @@ -20,6 +20,7 @@ package org.sonar.java.checks; import com.google.common.collect.ImmutableList; + import org.sonar.check.Rule; import org.sonar.java.model.ModifiersUtils; import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; @@ -43,26 +44,27 @@ public List nodesToVisit() { @Override public void visitNode(Tree tree) { ClassTree classTree = (ClassTree) tree; - if (!anonymousClass(classTree) && !extendsAnotherClass(classTree) && hasOnlyStaticMembers(classTree)) { - boolean hasImplicitPublicConstructor = true; - for (MethodTree explicitConstructor : getExplicitConstructors(classTree)) { - hasImplicitPublicConstructor = false; - if (isPublicConstructor(explicitConstructor)) { - reportIssue(explicitConstructor.simpleName(), "Hide this public constructor."); - } - } - if (hasImplicitPublicConstructor) { - reportIssue(classTree.simpleName(), "Add a private constructor to hide the implicit public one."); + if (!hasSemantic() || anonymousClass(classTree) || extendsAnotherClassOrImplementsSerializable(classTree) || !hasOnlyStaticMembers(classTree)) { + return; + } + boolean hasImplicitPublicConstructor = true; + for (MethodTree explicitConstructor : getExplicitConstructors(classTree)) { + hasImplicitPublicConstructor = false; + if (isPublicConstructor(explicitConstructor)) { + reportIssue(explicitConstructor.simpleName(), "Hide this public constructor."); } } + if (hasImplicitPublicConstructor) { + reportIssue(classTree.simpleName(), "Add a private constructor to hide the implicit public one."); + } } private static boolean anonymousClass(ClassTree classTree) { return classTree.simpleName() == null; } - private static boolean extendsAnotherClass(ClassTree classTree) { - return classTree.superClass() != null; + private static boolean extendsAnotherClassOrImplementsSerializable(ClassTree classTree) { + return classTree.superClass() != null || classTree.symbol().type().isSubtypeOf("java.io.Serializable"); } private static boolean hasOnlyStaticMembers(ClassTree classTree) { diff --git a/java-checks/src/test/files/checks/UtilityClassWithPublicConstructorCheck.java b/java-checks/src/test/files/checks/UtilityClassWithPublicConstructorCheck.java index 541e32ab561..a994761115d 100644 --- a/java-checks/src/test/files/checks/UtilityClassWithPublicConstructorCheck.java +++ b/java-checks/src/test/files/checks/UtilityClassWithPublicConstructorCheck.java @@ -1,3 +1,4 @@ +import java.io.Serializable; import java.lang.Object; class Foo1 { @@ -91,10 +92,10 @@ static class plop { } class Foo13 { - + private Foo13() { } - + ; } @@ -108,3 +109,7 @@ class Foo15 { public static void foo() {} }; } + +class Foo16 implements Serializable { // Compliant + private static final long serialVersionUID = 1L; +} diff --git a/java-checks/src/test/java/org/sonar/java/checks/UtilityClassWithPublicConstructorCheckTest.java b/java-checks/src/test/java/org/sonar/java/checks/UtilityClassWithPublicConstructorCheckTest.java index 8b1b6765221..3947d056e3e 100644 --- a/java-checks/src/test/java/org/sonar/java/checks/UtilityClassWithPublicConstructorCheckTest.java +++ b/java-checks/src/test/java/org/sonar/java/checks/UtilityClassWithPublicConstructorCheckTest.java @@ -27,6 +27,7 @@ public class UtilityClassWithPublicConstructorCheckTest { @Test public void test() { JavaCheckVerifier.verify("src/test/files/checks/UtilityClassWithPublicConstructorCheck.java", new UtilityClassWithPublicConstructorCheck()); + JavaCheckVerifier.verifyNoIssueWithoutSemantic("src/test/files/checks/UtilityClassWithPublicConstructorCheck.java", new UtilityClassWithPublicConstructorCheck()); } }