From b142c593512c9ef1179f4254ec406c23d180ed2f Mon Sep 17 00:00:00 2001
From: Oliver Burn
Date: Thu, 7 Oct 2010 12:19:35 +1100
Subject: [PATCH 1/2] Fix HideUtilityClassConstructor to handle empty and inner
classes. Thanks to Roman Ivanov for patch #3045720.
---
.../HideUtilityClassConstructorCheck.java | 37 ++++++++++++--
.../HideUtilityClassContructor3041574_1.java | 8 ++++
.../HideUtilityClassContructor3041574_2.java | 8 ++++
.../HideUtilityClassContructor3041574_3.java | 48 +++++++++++++++++++
.../HideUtilityClassConstructorCheckTest.java | 30 ++++++++++++
src/xdocs/config_design.xml | 3 +-
src/xdocs/releasenotes.xml | 6 +++
7 files changed, 135 insertions(+), 5 deletions(-)
create mode 100644 src/testinputs/com/puppycrawl/tools/checkstyle/design/HideUtilityClassContructor3041574_1.java
create mode 100644 src/testinputs/com/puppycrawl/tools/checkstyle/design/HideUtilityClassContructor3041574_2.java
create mode 100644 src/testinputs/com/puppycrawl/tools/checkstyle/design/HideUtilityClassContructor3041574_3.java
diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/design/HideUtilityClassConstructorCheck.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/design/HideUtilityClassConstructorCheck.java
index a008a7004..783c1f4a5 100755
--- a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/design/HideUtilityClassConstructorCheck.java
+++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/design/HideUtilityClassConstructorCheck.java
@@ -31,7 +31,6 @@ import com.puppycrawl.tools.checkstyle.api.DetailAST;
*
*
* @author lkuehne
- * @version $Revision: 1.12 $
*/
public class HideUtilityClassConstructorCheck extends Check
{
@@ -44,10 +43,17 @@ public class HideUtilityClassConstructorCheck extends Check
@Override
public void visitToken(DetailAST aAST)
{
+ if (isAbstract(aAST)) {
+ // abstract class could not have private constructor
+ return;
+ }
+
final DetailAST objBlock = aAST.findFirstToken(TokenTypes.OBJBLOCK);
DetailAST child = objBlock.getFirstChild();
+ final boolean hasStaticModifier = isStatic(aAST);
boolean hasMethodOrField = false;
boolean hasNonStaticMethodOrField = false;
+ boolean hasNonPrivateStaticMethodOrField = false;
boolean hasDefaultCtor = true;
boolean hasPublicCtor = false;
@@ -67,6 +73,9 @@ public class HideUtilityClassConstructorCheck extends Check
if (!isStatic && !isPrivate) {
hasNonStaticMethodOrField = true;
}
+ if (isStatic && !isPrivate) {
+ hasNonPrivateStaticMethodOrField = true;
+ }
}
if (type == TokenTypes.CTOR_DEF) {
hasDefaultCtor = false;
@@ -93,11 +102,31 @@ public class HideUtilityClassConstructorCheck extends Check
final boolean extendsJLO = // J.Lo even made it into in our sources :-)
aAST.findFirstToken(TokenTypes.EXTENDS_CLAUSE) == null;
- final boolean isUtilClass =
- extendsJLO && hasMethodOrField && !hasNonStaticMethodOrField;
+ final boolean isUtilClass = extendsJLO && hasMethodOrField
+ && !hasNonStaticMethodOrField && hasNonPrivateStaticMethodOrField;
- if (isUtilClass && hasAccessibleCtor) {
+ if (isUtilClass && (hasAccessibleCtor && !hasStaticModifier)) {
log(aAST.getLineNo(), aAST.getColumnNo(), "hide.utility.class");
}
}
+
+ /**
+ * @param aAST class definition for check.
+ * @return true if a given class declared as abstract.
+ */
+ private boolean isAbstract(DetailAST aAST)
+ {
+ return aAST.findFirstToken(TokenTypes.MODIFIERS)
+ .branchContains(TokenTypes.ABSTRACT);
+ }
+
+ /**
+ * @param aAST class definition for check.
+ * @return true if a given class declared as static.
+ */
+ private boolean isStatic(DetailAST aAST)
+ {
+ return aAST.findFirstToken(TokenTypes.MODIFIERS)
+ .branchContains(TokenTypes.LITERAL_STATIC);
+ }
}
diff --git a/src/testinputs/com/puppycrawl/tools/checkstyle/design/HideUtilityClassContructor3041574_1.java b/src/testinputs/com/puppycrawl/tools/checkstyle/design/HideUtilityClassContructor3041574_1.java
new file mode 100644
index 000000000..dc80fb3ff
--- /dev/null
+++ b/src/testinputs/com/puppycrawl/tools/checkstyle/design/HideUtilityClassContructor3041574_1.java
@@ -0,0 +1,8 @@
+package com.puppycrawl.tools.checkstyle.design;
+
+import java.io.Serializable;
+
+public abstract class HideUtilityClassContructor3041574_1 implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+}
\ No newline at end of file
diff --git a/src/testinputs/com/puppycrawl/tools/checkstyle/design/HideUtilityClassContructor3041574_2.java b/src/testinputs/com/puppycrawl/tools/checkstyle/design/HideUtilityClassContructor3041574_2.java
new file mode 100644
index 000000000..af76f0d87
--- /dev/null
+++ b/src/testinputs/com/puppycrawl/tools/checkstyle/design/HideUtilityClassContructor3041574_2.java
@@ -0,0 +1,8 @@
+package com.puppycrawl.tools.checkstyle.design;
+
+import java.io.Serializable;
+
+public class HideUtilityClassContructor3041574_2 implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+}
\ No newline at end of file
diff --git a/src/testinputs/com/puppycrawl/tools/checkstyle/design/HideUtilityClassContructor3041574_3.java b/src/testinputs/com/puppycrawl/tools/checkstyle/design/HideUtilityClassContructor3041574_3.java
new file mode 100644
index 000000000..2fc8da047
--- /dev/null
+++ b/src/testinputs/com/puppycrawl/tools/checkstyle/design/HideUtilityClassContructor3041574_3.java
@@ -0,0 +1,48 @@
+package com.puppycrawl.tools.checkstyle.design;
+
+import java.io.Serializable;
+
+public class HideUtilityClassContructor3041574_3 implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ public HideUtilityClassContructor3041574_3(int i) {
+ // no code
+ }
+
+ public String getValue() {
+ return "";
+ }
+
+ // It is NOT Utility Inner class
+ @SuppressWarnings("unused")
+ public static class Event {
+ // Top level class have access to fields - no need in public getters
+ private String ind;
+ private String ind1;
+
+ public Event(String value){
+ // do a lot of calculations
+ }
+
+ // static because this method is utility
+ public static String getEmptyString() {
+ return "";
+ }
+ }
+
+ // It is Utility Inner class
+ @SuppressWarnings("unused")
+ public static class Event1 {
+ private String ind;
+ private String ind1;
+
+ private Event1(){
+ // do a lot of calculations
+ }
+
+ // static because this method is utility
+ public static String getEmptyString() {
+ return "";
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/tests/com/puppycrawl/tools/checkstyle/checks/design/HideUtilityClassConstructorCheckTest.java b/src/tests/com/puppycrawl/tools/checkstyle/checks/design/HideUtilityClassConstructorCheckTest.java
index cd4a48051..130fbe7c8 100755
--- a/src/tests/com/puppycrawl/tools/checkstyle/checks/design/HideUtilityClassConstructorCheckTest.java
+++ b/src/tests/com/puppycrawl/tools/checkstyle/checks/design/HideUtilityClassConstructorCheckTest.java
@@ -69,4 +69,34 @@ public class HideUtilityClassConstructorCheckTest
verify(checkConfig, getPath("design" + File.separator + "InputRegression1762702.java"), expected);
}
+ @Test
+ public void testEmptyAbstractClass() throws Exception
+ {
+ final DefaultConfiguration checkConfig =
+ createCheckConfig(HideUtilityClassConstructorCheck.class);
+ final String[] expected = {
+ };
+ verify(checkConfig, getPath("design" + File.separator + "HideUtilityClassContructor3041574_1.java"), expected);
+ }
+
+ @Test
+ public void testEmptyClassWithOnlyPrivateFields() throws Exception
+ {
+ final DefaultConfiguration checkConfig =
+ createCheckConfig(HideUtilityClassConstructorCheck.class);
+ final String[] expected = {
+ };
+ verify(checkConfig, getPath("design" + File.separator + "HideUtilityClassContructor3041574_2.java"), expected);
+ }
+
+ @Test
+ public void testClassWithStaticInnerClass() throws Exception
+ {
+ final DefaultConfiguration checkConfig =
+ createCheckConfig(HideUtilityClassConstructorCheck.class);
+ final String[] expected = {
+ };
+ verify(checkConfig, getPath("design" + File.separator + "HideUtilityClassContructor3041574_3.java"), expected);
+ }
+
}
diff --git a/src/xdocs/config_design.xml b/src/xdocs/config_design.xml
index 5d42c58c8..ccb4e3d9e 100755
--- a/src/xdocs/config_design.xml
+++ b/src/xdocs/config_design.xml
@@ -219,7 +219,8 @@
public class StringUtils // not final to allow subclassing
{
protected StringUtils() {
- throw new UnsupportedOperationException(); // prevents calls from subclass
+ // prevents calls from subclass
+ throw new UnsupportedOperationException();
}
public static int count(char c, String s) {
diff --git a/src/xdocs/releasenotes.xml b/src/xdocs/releasenotes.xml
index 4a40d7087..ea2810b3d 100755
--- a/src/xdocs/releasenotes.xml
+++ b/src/xdocs/releasenotes.xml
@@ -65,6 +65,12 @@
checking of @throws tags for methods that throw multiple
non-runtime exceptions. Thanks to Daan Kets for patch #3039869.
+
+ Fix
+ HideUtilityClassConstructor
+ to handle empty and inner classes. Thanks to Roman Ivanov for
+ patch #3045720.
+
Notes:
From 76e4d6d691ec5c4654d8f6ce7bef5b3b51987cc0 Mon Sep 17 00:00:00 2001
From: Oliver Burn
Date: Thu, 7 Oct 2010 12:37:29 +1100
Subject: [PATCH 2/2] eating our own dog food.
---
checkstyle_checks.xml | 1 +
src/checkstyle/com/puppycrawl/tools/checkstyle/Main.java | 5 +++++
.../tools/checkstyle/doclets/CheckDocsDoclet.java | 5 +++++
.../tools/checkstyle/doclets/TokenTypesDoclet.java | 7 ++++++-
4 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/checkstyle_checks.xml b/checkstyle_checks.xml
index 2838a2e72..9602d1e2f 100755
--- a/checkstyle_checks.xml
+++ b/checkstyle_checks.xml
@@ -181,5 +181,6 @@
+
diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/Main.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/Main.java
index d64c2f86e..4e2d6bae6 100755
--- a/src/checkstyle/com/puppycrawl/tools/checkstyle/Main.java
+++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/Main.java
@@ -58,6 +58,11 @@ public final class Main
"Sets the output format. (plain|xml). Defaults to plain");
}
+ /** Stop instances being created. */
+ private Main()
+ {
+ }
+
/**
* Loops over the files specified checking them for errors. The exit code
* is the number of errors found in all the files.
diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/doclets/CheckDocsDoclet.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/doclets/CheckDocsDoclet.java
index 9594b33d5..af18a8cac 100755
--- a/src/checkstyle/com/puppycrawl/tools/checkstyle/doclets/CheckDocsDoclet.java
+++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/doclets/CheckDocsDoclet.java
@@ -41,6 +41,11 @@ public final class CheckDocsDoclet
/** javadoc command line option for dest dir. */
private static final String DEST_DIR_OPT = "-d";
+ /** Stop instances being created. */
+ private CheckDocsDoclet()
+ {
+ }
+
/**
* Comparator that compares the {@link ClassDoc ClassDocs} of two checks
* by their check name.
diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/doclets/TokenTypesDoclet.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/doclets/TokenTypesDoclet.java
index f083d1314..1ccd1e9ba 100755
--- a/src/checkstyle/com/puppycrawl/tools/checkstyle/doclets/TokenTypesDoclet.java
+++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/doclets/TokenTypesDoclet.java
@@ -33,11 +33,16 @@ import com.sun.javadoc.RootDoc;
*
* @author o_sukhodolsky
*/
-public class TokenTypesDoclet
+public final class TokenTypesDoclet
{
/** Command line option to specify file to write output of the doclet. */
private static final String DEST_FILE_OPT = "-destfile";
+ /** Stop instances being created. */
+ private TokenTypesDoclet()
+ {
+ }
+
/**
* The doclet's starter method.
* @param aRoot RootDoc given to the doclet