From 5c3762cef2a69a10241801916a815f9066bca5f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20K=C3=BChne?= Date: Sat, 8 Nov 2003 12:29:19 +0000 Subject: [PATCH] fixed bug 837012, false alarms for abstract classes --- docs/releasenotes.html | 5 +- .../checks/design/FinalClassCheck.java | 46 +++++++++---- .../tools/checkstyle/InputFinalClass.java | 67 +++++++++++++++++++ 3 files changed, 104 insertions(+), 14 deletions(-) diff --git a/docs/releasenotes.html b/docs/releasenotes.html index e558129a3..c867c6744 100644 --- a/docs/releasenotes.html +++ b/docs/releasenotes.html @@ -286,8 +286,9 @@
  • Changed HideUtiliyConstructor behaviour for classes that do not extend java.lang.Object directly (partial fix for bug 824754)
  • -
  • Added Checker.removeListener() (fix for - 834367)
  • +
  • False alarms for abstract classes from FinalClass (bug 837012)
  • + +
  • Added Checker.removeListener() (fix for 834367)
  • diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/design/FinalClassCheck.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/design/FinalClassCheck.java index be4c22c55..746934ade 100644 --- a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/design/FinalClassCheck.java +++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/design/FinalClassCheck.java @@ -54,10 +54,11 @@ public class FinalClassCheck final DetailAST modifiers = aAST.findFirstToken(TokenTypes.MODIFIERS); if (aAST.getType() == TokenTypes.CLASS_DEF) { - final boolean isFinal = - (modifiers != null) + final boolean isFinal = (modifiers != null) && modifiers.branchContains(TokenTypes.FINAL); - mClasses.push(new ClassDesc(isFinal)); + final boolean isAbstract = (modifiers != null) + && modifiers.branchContains(TokenTypes.ABSTRACT); + mClasses.push(new ClassDesc(isFinal, isAbstract)); } else { final ClassDesc desc = (ClassDesc) mClasses.peek(); @@ -81,6 +82,7 @@ public class FinalClassCheck final ClassDesc desc = (ClassDesc) mClasses.pop(); if (!desc.isDeclaredAsFinal() + && !desc.isDeclaredAsAbstract() && desc.hasPrivateCtor() && !desc.hasNonPrivateCtor()) { @@ -96,6 +98,9 @@ public class FinalClassCheck /** is class declared as final */ private final boolean mDeclaredAsFinal; + /** is class declared as abstract */ + private final boolean mDeclaredAsAbstract; + /** does class have non-provate ctors */ private boolean mHasNonPrivateCtor; @@ -103,29 +108,32 @@ public class FinalClassCheck private boolean mHasPrivateCtor; /** - * create a new ClassDesc instance + * create a new ClassDesc instance. * @param aDeclaredAsFinal indicates if the * class declared as final + * @param aDeclaredAsAbstract indicates if the + * class declared as abstract */ - ClassDesc(boolean aDeclaredAsFinal) + ClassDesc(boolean aDeclaredAsFinal, boolean aDeclaredAsAbstract) { mDeclaredAsFinal = aDeclaredAsFinal; + mDeclaredAsAbstract = aDeclaredAsAbstract; } - /** adds private ctor */ + /** adds private ctor. */ void reportPrivateCtor() { mHasPrivateCtor = true; } - /** adds non-private ctor */ + /** adds non-private ctor. */ void reportNonPrivateCtor() { mHasNonPrivateCtor = true; } /** - * does class have private ctors + * does class have private ctors. * @return true if class has private ctors */ boolean hasPrivateCtor() @@ -134,7 +142,7 @@ public class FinalClassCheck } /** - * does class have non-private ctors + * does class have non-private ctors. * @return true if class has non-private ctors */ boolean hasNonPrivateCtor() @@ -143,7 +151,7 @@ public class FinalClassCheck } /** - * is class declared as final + * is class declared as final. * @return true if class is declared as final */ boolean isDeclaredAsFinal() @@ -151,14 +159,28 @@ public class FinalClassCheck return mDeclaredAsFinal; } + /** + * is class declared as abstract. + * @return true if class is declared as final + */ + boolean isDeclaredAsAbstract() + { + return mDeclaredAsAbstract; + } + /** * Returns a string representation of the object. * @return a string representation of the object */ public String toString() { - return "decl=" + mDeclaredAsFinal + "; pctor=" + mHasPrivateCtor - + "; ctor=" + mHasNonPrivateCtor; + return this.getClass().getName() + + "[" + + "final=" + mDeclaredAsFinal + + " abstract=" + mDeclaredAsAbstract + + " pctor=" + mHasPrivateCtor + + " ctor=" + mHasNonPrivateCtor + + "]"; } } } diff --git a/src/testinputs/com/puppycrawl/tools/checkstyle/InputFinalClass.java b/src/testinputs/com/puppycrawl/tools/checkstyle/InputFinalClass.java index b80c3be7e..92dda2745 100644 --- a/src/testinputs/com/puppycrawl/tools/checkstyle/InputFinalClass.java +++ b/src/testinputs/com/puppycrawl/tools/checkstyle/InputFinalClass.java @@ -28,3 +28,70 @@ class test6 { public test6() {} } + +// Typesafe enum with operation +// abstract classes cannot be final, see bug #837012 +abstract class Operation +{ + abstract double eval(double a, double b); + + public static final Operation PLUS = + new Operation("+") + { + double eval(double a, double b) + { + return a + b; + } + }; + + public static final Operation MINUS = + new Operation("-") + { + double eval(double a, double b) + { + return a - b; + } + }; + + private String _name; + private Operation(String name) + { + this._name = name; + } +} + +// Typesafe enum with operation +// abstract classes cannot be final, see bug #837012 +interface Evaluatable +{ + double eval(double a, double b); +} + +// abstract class without it's own abstract method decl +abstract class Operation2 implements Evaluatable +{ + + public static final Operation2 PLUS = + new Operation2("+") + { + double eval(double a, double b) + { + return a + b; + } + }; + + public static final Operation2 MINUS = + new Operation2("-") + { + double eval(double a, double b) + { + return a - b; + } + }; + + private String _name; + private Operation2(String name) + { + this._name = name; + } +}