/projects/checkstyle-5.6/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/naming/AbstractClassNameCheck.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus · Java · 137 lines · 64 code · 14 blank · 59 comment · 9 complexity · 20d44967305dbf6eb556f3b1ba688eff MD5 · raw file

  1. ////////////////////////////////////////////////////////////////////////////////
  2. // checkstyle: Checks Java source code for adherence to a set of rules.
  3. // Copyright (C) 2001-2012 Oliver Burn
  4. //
  5. // This library is free software; you can redistribute it and/or
  6. // modify it under the terms of the GNU Lesser General Public
  7. // License as published by the Free Software Foundation; either
  8. // version 2.1 of the License, or (at your option) any later version.
  9. //
  10. // This library is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. // Lesser General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU Lesser General Public
  16. // License along with this library; if not, write to the Free Software
  17. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. ////////////////////////////////////////////////////////////////////////////////
  19. package com.puppycrawl.tools.checkstyle.checks.naming;
  20. import com.puppycrawl.tools.checkstyle.api.DetailAST;
  21. import com.puppycrawl.tools.checkstyle.api.TokenTypes;
  22. import com.puppycrawl.tools.checkstyle.checks.AbstractFormatCheck;
  23. /**
  24. * <p>
  25. * Ensures that the names of abstract classes conforming to some
  26. * regular expression and check that <code>abstract</code> modifier exists.
  27. * </p>
  28. * <p>
  29. * Rationale: Abstract classes are convenience base class
  30. * implementations of interfaces, not types as such. As such
  31. * they should be named to indicate this. Also if names of classes
  32. * starts with 'Abstract' it's very convenient that they will
  33. * have abstract modifier.
  34. * </p>
  35. *
  36. * @author <a href="mailto:simon@redhillconsulting.com.au">Simon Harris</a>
  37. * @author <a href="mailto:solid.danil@gmail.com">Danil Lopatin</a>
  38. */
  39. public final class AbstractClassNameCheck extends AbstractFormatCheck
  40. {
  41. /** Default format for abstract class names */
  42. private static final String DEFAULT_FORMAT = "^Abstract.*$|^.*Factory$";
  43. /** whether to ignore checking the modifier */
  44. private boolean mIgnoreModifier;
  45. /** whether to ignore checking the name */
  46. private boolean mIgnoreName;
  47. /** Creates new instance of the check. */
  48. public AbstractClassNameCheck()
  49. {
  50. super(DEFAULT_FORMAT);
  51. }
  52. /**
  53. * Whether to ignore checking for the <code>abstract</code> modifier.
  54. * @param aValue new value
  55. */
  56. public void setIgnoreModifier(boolean aValue)
  57. {
  58. mIgnoreModifier = aValue;
  59. }
  60. /**
  61. * Whether to ignore checking the name.
  62. * @param aValue new value.
  63. */
  64. public void setIgnoreName(boolean aValue)
  65. {
  66. mIgnoreName = aValue;
  67. }
  68. @Override
  69. public int[] getDefaultTokens()
  70. {
  71. return new int[]{TokenTypes.CLASS_DEF};
  72. }
  73. @Override
  74. public int[] getRequiredTokens()
  75. {
  76. return getDefaultTokens();
  77. }
  78. @Override
  79. public void visitToken(DetailAST aAST)
  80. {
  81. if (TokenTypes.CLASS_DEF == aAST.getType()) {
  82. visitClassDef(aAST);
  83. }
  84. }
  85. /**
  86. * Checks class definition.
  87. * @param aAST class definition for check.
  88. */
  89. private void visitClassDef(DetailAST aAST)
  90. {
  91. final String className =
  92. aAST.findFirstToken(TokenTypes.IDENT).getText();
  93. if (isAbstract(aAST)) {
  94. // if class has abstract modifier
  95. if (!mIgnoreName && !isMatchingClassName(className)) {
  96. log(aAST.getLineNo(), aAST.getColumnNo(),
  97. "illegal.abstract.class.name", className, getFormat());
  98. }
  99. }
  100. else if (!mIgnoreModifier && isMatchingClassName(className)) {
  101. log(aAST.getLineNo(), aAST.getColumnNo(),
  102. "no.abstract.class.modifier", className);
  103. }
  104. }
  105. /**
  106. * @param aAST class definition for check.
  107. * @return true if a given class declared as abstract.
  108. */
  109. private boolean isAbstract(DetailAST aAST)
  110. {
  111. final DetailAST abstractAST = aAST.findFirstToken(TokenTypes.MODIFIERS)
  112. .findFirstToken(TokenTypes.ABSTRACT);
  113. return abstractAST != null;
  114. }
  115. /**
  116. * @param aClassName class name for check.
  117. * @return true if class name matches format of abstract class names.
  118. */
  119. private boolean isMatchingClassName(String aClassName)
  120. {
  121. return getRegexp().matcher(aClassName).find();
  122. }
  123. }