diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/checks/coding/DeclarationOrderCheck.java b/src/main/java/com/puppycrawl/tools/checkstyle/checks/coding/DeclarationOrderCheck.java
index 25fc07be0..1103a3a07 100644
--- a/src/main/java/com/puppycrawl/tools/checkstyle/checks/coding/DeclarationOrderCheck.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/checks/coding/DeclarationOrderCheck.java
@@ -18,6 +18,9 @@
////////////////////////////////////////////////////////////////////////////////
package com.puppycrawl.tools.checkstyle.checks.coding;
+import java.util.HashMap;
+import java.util.Map;
+
import com.puppycrawl.tools.checkstyle.api.Check;
import com.puppycrawl.tools.checkstyle.api.DetailAST;
import com.puppycrawl.tools.checkstyle.api.FastStack;
@@ -46,13 +49,29 @@ import com.puppycrawl.tools.checkstyle.api.TokenTypes;
*
*
*
+ * It can check that overload methods are grouped together. Example:
+ *
+ *
+ * public void foo(int i) {}
+ * public void foo(String s) {}
+ * public void notFoo() {} // Have to be after foo(int i, String s)
+ * public void foo(int i, String s) {}
+ *
+ *
* An example of how to configure the check is:
*
*
* <module name="DeclarationOrder"/>
*
+ * An example of a check's configuration for grouping overload methods:
+ *
+ * <module name="DeclarationOrder">
+ * <property name="groupOverloadMethods" value="true">
+ * </module>
+ *
*
* @author r_auckenthaler
+ * @author maxvetrenko
*/
public class DeclarationOrderCheck extends Check
{
@@ -92,6 +111,8 @@ public class DeclarationOrderCheck extends Check
private boolean mIgnoreMethods;
/** If true, ignore the check to modifiers (fields, ...). */
private boolean mIgnoreModifiers;
+ /** If true, avoid splitting overload methods */
+ private boolean mGroupOverloadMethods;
@Override
public int[] getDefaultTokens()
@@ -113,6 +134,12 @@ public class DeclarationOrderCheck extends Check
switch(aAST.getType()) {
case TokenTypes.OBJBLOCK:
mScopeStates.push(new ScopeState());
+ if (mGroupOverloadMethods && (parentType == TokenTypes.CLASS_DEF
+ || parentType == TokenTypes.ENUM_DEF
+ || parentType == TokenTypes.INTERFACE_DEF))
+ {
+ checkOverloadMethodsGrouping(aAST);
+ }
break;
case TokenTypes.CTOR_DEF:
@@ -205,6 +232,35 @@ public class DeclarationOrderCheck extends Check
}
}
+ /**
+ * Checks that if overload methods are grouped together they
+ * should not be separated from each other.
+ * @param aObjectBlock is a class, interface or enum object block.
+ */
+ private void checkOverloadMethodsGrouping(DetailAST aObjectBlock)
+ {
+ final int allowedDistance = 1;
+ DetailAST currentToken = aObjectBlock.getFirstChild();
+ final Map methodIndexMap =
+ new HashMap();
+ int currentIndex = 0;
+ while (currentToken != null) {
+ if (currentToken.getType() == TokenTypes.METHOD_DEF) {
+ currentIndex++;
+ final String methodName =
+ currentToken.findFirstToken(TokenTypes.IDENT).getText();
+ if (methodIndexMap.containsKey(methodName)) {
+ final int priviousIndex = methodIndexMap.get(methodName);
+ if (currentIndex - priviousIndex > allowedDistance) {
+ log(currentToken, "declaration.order.overloads");
+ }
+ }
+ methodIndexMap.put(methodName, currentIndex);
+ }
+ currentToken = currentToken.getNextSibling();
+ }
+ }
+
/**
* Sets whether to ignore constructors.
* @param aIgnoreConstructors whether to ignore constructors.
@@ -231,4 +287,13 @@ public class DeclarationOrderCheck extends Check
{
mIgnoreModifiers = aIgnoreModifiers;
}
+
+ /**
+ * Sets whether to group overload methods.
+ * @param aGroupOverloadMethods whether to group overload methods.
+ */
+ public void setGroupOverloadMethods(boolean aGroupOverloadMethods)
+ {
+ mGroupOverloadMethods = aGroupOverloadMethods;
+ }
}
diff --git a/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages.properties b/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages.properties
index 239d7354c..871722a71 100644
--- a/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages.properties
+++ b/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages.properties
@@ -8,6 +8,7 @@ declaration.order.method=Method definition in wrong order.
declaration.order.static=Static variable definition in wrong order.
declaration.order.instance=Instance variable definition in wrong order.
declaration.order.access=Variable access definition in wrong order.
+declaration.order.overloads=Overload methods should not be split.
default.comes.last=Default should be last label in the switch.
empty.statement=Empty statement.
equals.avoid.null=String literal expressions should be on the left side of an equals comparison.
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/checks/coding/DeclarationOrderCheckTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/checks/coding/DeclarationOrderCheckTest.java
index bd4bf0242..0534d16f7 100644
--- a/src/test/java/com/puppycrawl/tools/checkstyle/checks/coding/DeclarationOrderCheckTest.java
+++ b/src/test/java/com/puppycrawl/tools/checkstyle/checks/coding/DeclarationOrderCheckTest.java
@@ -70,6 +70,7 @@ public class DeclarationOrderCheckTest
checkConfig.addAttribute("ignoreConstructors", "false");
checkConfig.addAttribute("ignoreMethods", "true");
checkConfig.addAttribute("ignoreModifiers", "true");
+ checkConfig.addAttribute("groupOverloadMethods", "false");
final String[] expected = {
"45:9: Static variable definition in wrong order.",
@@ -91,6 +92,7 @@ public class DeclarationOrderCheckTest
checkConfig.addAttribute("ignoreConstructors", "true");
checkConfig.addAttribute("ignoreMethods", "true");
checkConfig.addAttribute("ignoreModifiers", "false");
+ checkConfig.addAttribute("groupOverloadMethods", "false");
final String[] expected = {
"8:5: Variable access definition in wrong order.",
@@ -120,4 +122,47 @@ public class DeclarationOrderCheckTest
};
verify(checkConfig, getPath("coding/InputDeclarationOrder.java"), expected);
}
+
+ @Test
+ public void testOverloadMethodsGrouping() throws Exception
+ {
+ final DefaultConfiguration checkConfig =
+ createCheckConfig(DeclarationOrderCheck.class);
+ checkConfig.addAttribute("ignoreConstructors", "false");
+ checkConfig.addAttribute("ignoreMethods", "false");
+ checkConfig.addAttribute("ignoreModifiers", "false");
+ checkConfig.addAttribute("groupOverloadMethods", "true");
+
+ final String[] expected = {
+ "8:5: Variable access definition in wrong order.",
+ "13:5: Variable access definition in wrong order.",
+ "18:5: Variable access definition in wrong order.",
+ "21:5: Variable access definition in wrong order.",
+ "27:5: Static variable definition in wrong order.",
+ "27:5: Variable access definition in wrong order.",
+ "34:9: Variable access definition in wrong order.",
+ "45:9: Static variable definition in wrong order.",
+ "45:9: Variable access definition in wrong order.",
+ "54:5: Constructor definition in wrong order.",
+ "80:5: Instance variable definition in wrong order.",
+
+ "92:9: Variable access definition in wrong order.",
+ "100:9: Static variable definition in wrong order.",
+ "100:9: Variable access definition in wrong order.",
+ "106:5: Variable access definition in wrong order.",
+ "111:5: Variable access definition in wrong order.",
+ "116:5: Variable access definition in wrong order.",
+ "119:5: Variable access definition in wrong order.",
+ "125:5: Static variable definition in wrong order.",
+ "125:5: Variable access definition in wrong order.",
+ "132:9: Variable access definition in wrong order.",
+ "143:9: Static variable definition in wrong order.",
+ "143:9: Variable access definition in wrong order.",
+ "152:5: Constructor definition in wrong order.",
+ "178:5: Instance variable definition in wrong order.",
+ "203:9: Overload methods should not be split.",
+ "215:9: Overload methods should not be split.",
+ };
+ verify(checkConfig, getPath("coding/InputDeclarationOrder.java"), expected);
+ }
}
diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/coding/InputDeclarationOrder.java b/src/test/resources/com/puppycrawl/tools/checkstyle/coding/InputDeclarationOrder.java
index 502749946..9d0219597 100644
--- a/src/test/resources/com/puppycrawl/tools/checkstyle/coding/InputDeclarationOrder.java
+++ b/src/test/resources/com/puppycrawl/tools/checkstyle/coding/InputDeclarationOrder.java
@@ -176,4 +176,41 @@ enum InputDeclarationOrderEnum
// error member variables should be before methods or ctors
private int mFoo = 0;
+
+ class overloadInput
+ {
+ public void overloadMethod(int i)
+ {
+ //some foo code
+ }
+
+ public void overloadMethod(String s)
+ {
+ //some foo code
+ }
+
+ public void overloadMethod(boolean b)
+ {
+ //some foo code
+ }
+
+ public void fooMethod()
+ {
+
+ }
+
+ //error because overloads never split
+ public void overloadMethod(String s, Boolean b, int i)
+ {
+ //some foo code
+ }
+ }
}
+
+interface Fooable
+{
+ public abstract void foo(int i);
+ public abstract void foo(String s);
+ public abstract void noFoo();
+ public abstract void foo(String s, Boolean b, int i);
+}
\ No newline at end of file
diff --git a/src/xdocs/config_coding.xml b/src/xdocs/config_coding.xml
index b301b000d..1dd733480 100644
--- a/src/xdocs/config_coding.xml
+++ b/src/xdocs/config_coding.xml
@@ -2002,6 +2002,15 @@ if ("something".equals(x))
Constructors
Methods
+
+ It can check that overload methods are grouped together. Example:
+
+
+public void foo(int i) {}
+public void foo(String s) {}
+public void notFoo() {} // Have to be after foo(int i, String s)
+public void foo(int i, String s) {}
+
@@ -2030,6 +2039,12 @@ if ("something".equals(x))
Boolean
false
+
+ groupOverloadMethods
+ whether to avoid splitting overload methods
+ Boolean
+ false
+
@@ -2040,6 +2055,14 @@ if ("something".equals(x))
<module name="DeclarationOrder"/>
+
+ An example of a check's configuration for grouping overload methods
+
+
+<module name="DeclarationOrder">
+ <property name="groupOverloadMethods" value="true">
+</module>
+