/** * Determines whether or not the given AST is in a valid hash code method. A valid hash code * method is considered to be a method of the signature {@code public int hashCode()}. * * @param aAST the AST from which to search for an enclosing hash code method definition * @return {@code true} if {@code aAST} is in the scope of a valid hash code method */ private boolean isInHashCodeMethod(DetailAST aAST) { // if not in a code block, can't be in hashCode() if (!ScopeUtils.inCodeBlock(aAST)) { return false; } // find the method definition AST DetailAST methodDefAST = aAST.getParent(); while ((null != methodDefAST) && (TokenTypes.METHOD_DEF != methodDefAST.getType())) { methodDefAST = methodDefAST.getParent(); } if (null == methodDefAST) { return false; } // Check for 'hashCode' name. final DetailAST identAST = methodDefAST.findFirstToken(TokenTypes.IDENT); if (!"hashCode".equals(identAST.getText())) { return false; } // Check for no arguments. final DetailAST paramAST = methodDefAST.findFirstToken(TokenTypes.PARAMETERS); if (0 != paramAST.getChildCount()) { return false; } // we are in a 'public int hashCode()' method! The compiler will ensure // the method returns an 'int' and is public. return true; }
/** * Finds the constant definition that contains aAST. * * @param aAST the AST * @return the constant def or null if aAST is not contained in a constant definition */ private DetailAST findContainingConstantDef(DetailAST aAST) { DetailAST varDefAST = aAST; while ((varDefAST != null) && (varDefAST.getType() != TokenTypes.VARIABLE_DEF) && (varDefAST.getType() != TokenTypes.ENUM_CONSTANT_DEF)) { varDefAST = varDefAST.getParent(); } // no containing variable definition? if (varDefAST == null) { return null; } // implicit constant? if (ScopeUtils.inInterfaceOrAnnotationBlock(varDefAST) || (varDefAST.getType() == TokenTypes.ENUM_CONSTANT_DEF)) { return varDefAST; } // explicit constant final DetailAST modifiersAST = varDefAST.findFirstToken(TokenTypes.MODIFIERS); if (modifiersAST.branchContains(TokenTypes.FINAL)) { return varDefAST; } return null; }
/** * Determines whether an AST is a method definition for this check, with 0 parameters. * * @param aAST the method definition AST. * @return true if the method of aAST is a method for this check. */ private boolean isOverridingMethod(DetailAST aAST) { if ((aAST.getType() != TokenTypes.METHOD_DEF) || ScopeUtils.inInterfaceOrAnnotationBlock(aAST)) { return false; } final DetailAST nameAST = aAST.findFirstToken(TokenTypes.IDENT); final String name = nameAST.getText(); if (!getMethodName().equals(name)) { return false; } final DetailAST params = aAST.findFirstToken(TokenTypes.PARAMETERS); return (params.getChildCount() == 0); }
@Override protected final boolean mustCheckName(DetailAST aAST) { final DetailAST modifiersAST = aAST.findFirstToken(TokenTypes.MODIFIERS); final boolean isFinal = (modifiersAST != null) && modifiersAST.branchContains(TokenTypes.FINAL); return (!isFinal && ScopeUtils.isLocalVariableDef(aAST)); }
/** * Determine the visibility modifier and raise the corresponding counter. * * @param aMethod The method-subtree from the AbstractSyntaxTree. */ private void raiseCounter(DetailAST aMethod) { final MethodCounter actualCounter = mCounters.peek(); final DetailAST temp = aMethod.findFirstToken(TokenTypes.MODIFIERS); final Scope scope = ScopeUtils.getScopeFromMods(temp); actualCounter.increment(scope); }