001//////////////////////////////////////////////////////////////////////////////// 002// checkstyle: Checks Java source code for adherence to a set of rules. 003// Copyright (C) 2001-2014 Oliver Burn 004// 005// This library is free software; you can redistribute it and/or 006// modify it under the terms of the GNU Lesser General Public 007// License as published by the Free Software Foundation; either 008// version 2.1 of the License, or (at your option) any later version. 009// 010// This library is distributed in the hope that it will be useful, 011// but WITHOUT ANY WARRANTY; without even the implied warranty of 012// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013// Lesser General Public License for more details. 014// 015// You should have received a copy of the GNU Lesser General Public 016// License along with this library; if not, write to the Free Software 017// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 018//////////////////////////////////////////////////////////////////////////////// 019 020package com.puppycrawl.tools.checkstyle.checks.sizes; 021 022import com.puppycrawl.tools.checkstyle.api.AnnotationUtility; 023import com.puppycrawl.tools.checkstyle.api.Check; 024import com.puppycrawl.tools.checkstyle.api.DetailAST; 025import com.puppycrawl.tools.checkstyle.api.TokenTypes; 026 027/** 028 * <p> 029 * Checks the number of parameters that a method or constructor has. 030 * The default allowable number of parameters is 7. 031 * To change the number of allowable parameters, set property max. 032 * Allows to ignore number of parameters for methods with 033 * @{@link java.lang.Override} annotation. 034 * </p> 035 * <p> 036 * An example of how to configure the check is: 037 * </p> 038 * <pre> 039 * <module name="ParameterNumber"/> 040 * </pre> 041 * <p> 042 * An example of how to configure the check to allow 10 parameters 043 * and ignoring parameters for methods with @{@link java.lang.Override} 044 * annotation is: 045 * </p> 046 * <pre> 047 * <module name="ParameterNumber"> 048 * <property name="max" value="10"/> 049 * <property name="ignoreOverriddenMethods" value="true"/> 050 * </module> 051 * </pre> 052 * Java code that will be ignored: 053 * <pre> 054 * <code> 055 * 056 * @Override 057 * public void needsLotsOfParameters(int a, 058 * int b, int c, int d, int e, int f, int g, int h) { 059 * ... 060 * } 061 * </code> 062 * </pre> 063 * @author Oliver Burn 064 * @version 1.0 065 */ 066public class ParameterNumberCheck 067 extends Check 068{ 069 /** {@link Override Override} annotation name */ 070 private static final String OVERRIDE = "Override"; 071 072 /** canonical {@link Override Override} annotation name */ 073 private static final String CANONICAL_OVERRIDE = "java.lang." + OVERRIDE; 074 075 /** default maximum number of allowed parameters */ 076 private static final int DEFAULT_MAX_PARAMETERS = 7; 077 078 /** the maximum number of allowed parameters */ 079 private int max = DEFAULT_MAX_PARAMETERS; 080 081 /** ignore overridden methods */ 082 private boolean ignoreOverriddenMethods; 083 084 /** 085 * Sets the maximum number of allowed parameters. 086 * @param max the max allowed parameters 087 */ 088 public void setMax(int max) 089 { 090 this.max = max; 091 } 092 093 /** 094 * Ignore number of parameters for methods with 095 * @{@link java.lang.Override} annotation. 096 * @param ignoreOverriddenMethods set ignore overridden methods 097 */ 098 public void setIgnoreOverriddenMethods(boolean ignoreOverriddenMethods) 099 { 100 this.ignoreOverriddenMethods = ignoreOverriddenMethods; 101 } 102 103 @Override 104 public int[] getDefaultTokens() 105 { 106 return new int[] {TokenTypes.METHOD_DEF, TokenTypes.CTOR_DEF}; 107 } 108 109 @Override 110 public void visitToken(DetailAST ast) 111 { 112 final DetailAST params = ast.findFirstToken(TokenTypes.PARAMETERS); 113 final int count = params.getChildCount(TokenTypes.PARAMETER_DEF); 114 if (count > max && !ignoreNumberOfParameters(ast)) { 115 final DetailAST name = ast.findFirstToken(TokenTypes.IDENT); 116 log(name.getLineNo(), name.getColumnNo(), "maxParam", max, count); 117 } 118 } 119 120 /** Determine whether to ignore number of parameters for the method. 121 * 122 * @param ast the token to process 123 * @return true if this is overridden method and number of parameters should be ignored 124 * false otherwise 125 */ 126 private boolean ignoreNumberOfParameters(DetailAST ast) 127 { 128 //if you override a method, you have no power over the number of parameters 129 return ignoreOverriddenMethods 130 && (AnnotationUtility.containsAnnotation(ast, OVERRIDE) 131 || AnnotationUtility.containsAnnotation(ast, CANONICAL_OVERRIDE)); 132 } 133}