private String getCaughtExceptionsAsString(ASTCatchStatement stmt) { StringBuilder sb = new StringBuilder(); final String delim = " | "; for (ASTType type : stmt.getCaughtExceptionTypeNodes()) { sb.append(type.getTypeImage()).append(delim); } // remove the last delimiter sb.replace(sb.length() - 3, sb.length(), ""); return sb.toString(); }
private boolean isBooleanType(ASTType node) { return "boolean".equalsIgnoreCase(node.getTypeImage()) || TypeHelper.isA(node, "java.util.concurrent.atomic.AtomicBoolean"); }
/** Returns a normalized method name (not Java-canonical!). */ private static String getOperationName(String methodName, ASTFormalParameters params) { StringBuilder sb = new StringBuilder(); sb.append(methodName); sb.append('('); boolean first = true; for (ASTFormalParameter param : params) { if (!first) { sb.append(", "); } first = false; sb.append(param.getTypeNode().getTypeImage()); if (param.isVarargs()) { sb.append("..."); } } sb.append(')'); return sb.toString(); }
/** * This method checks the variable declaration if it is on a class we care * about. If it is, it returns the DeclaratorId * * @param node * The ASTLocalVariableDeclaration which is a problem * @return ASTVariableDeclaratorId */ private ASTVariableDeclaratorId getDeclaration(ASTLocalVariableDeclaration node) { ASTType type = node.getTypeNode(); if (type != null) { if (MAP_CLASSES.keySet().contains(type.getTypeImage())) { return node.getFirstDescendantOfType(ASTVariableDeclaratorId.class); } } return null; } }
private boolean isSerializationMethod(ASTMethodDeclaration node) { ASTMethodDeclarator declarator = node.getFirstDescendantOfType(ASTMethodDeclarator.class); List<ASTFormalParameter> parameters = declarator.findDescendantsOfType(ASTFormalParameter.class); if (node.isPrivate() && "readObject".equals(node.getMethodName()) && parameters.size() == 1 && throwsOneException(node, InvalidObjectException.class)) { ASTType type = parameters.get(0).getTypeNode(); if (type.getType() == ObjectInputStream.class || ObjectInputStream.class.getSimpleName().equals(type.getTypeImage()) || ObjectInputStream.class.getName().equals(type.getTypeImage())) { return true; } } return false; }
public String getParameterDisplaySignature() { StringBuilder sb = new StringBuilder("("); ASTFormalParameters params = (ASTFormalParameters) node.jjtGetChild(0); // TODO - this can be optimized - add [0] then ,[n] in a loop. // no need to trim at the end for (int i = 0; i < ((ASTMethodDeclarator) node).getParameterCount(); i++) { ASTFormalParameter p = (ASTFormalParameter) params.jjtGetChild(i); sb.append(p.getTypeNode().getTypeImage()); if (p.isVarargs()) { sb.append("..."); } sb.append(','); } if (sb.charAt(sb.length() - 1) == ',') { sb.deleteCharAt(sb.length() - 1); } sb.append(')'); return sb.toString(); }
private static boolean isGetterOrSetter(ASTMethodDeclaration node) { ClassScope scope = node.getScope().getEnclosingScope(ClassScope.class); // fields names mapped to their types Map<String, String> fieldNames = new HashMap<>(); for (Map.Entry<VariableNameDeclaration, List<NameOccurrence>> decl : scope.getVariableDeclarations().entrySet()) { ASTFieldDeclaration field = decl.getKey() .getNode() .getFirstParentOfType(ASTFieldDeclaration.class); Matcher matcher = FIELD_NAME_PATTERN.matcher(field.getVariableName()); String varName = matcher.find() ? matcher.group(1) : field.getVariableName(); fieldNames.put(varName, field.getFirstChildOfType(ASTType.class).getTypeImage()); } return isGetter(node, fieldNames) || isSetter(node, fieldNames); }
@Override public Object visit(ASTLocalVariableDeclaration node, Object data) { ASTVariableDeclaratorId var = getDeclaration(node); if (var == null) { return super.visit(node, data); } String variableName = var.getImage(); for (NameOccurrence no : var.getUsages()) { // FIXME - getUsages will return everything with the same name as // the variable, // see JUnit test, case 6. Changing to Node below, revisit when // getUsages is fixed Node sn = no.getLocation(); Node primaryExpression = sn.jjtGetParent().jjtGetParent(); Class<? extends Node> parentClass = primaryExpression.jjtGetParent().getClass(); if (parentClass.equals(ASTStatementExpression.class)) { String methodCall = sn.getImage().substring(variableName.length()); ASTType nodeType = node.getTypeNode(); if (nodeType != null) { if (MAP_CLASSES.get(nodeType.getTypeImage()).contains(methodCall)) { addViolation(data, sn); } } } } return super.visit(node, data); }
String typeImage = p.getTypeNode().getTypeImage();
private void checkField(ASTType typeNode, ASTVariableDeclarator node, Object data) { for (String prefix : getProperty(BOOLEAN_FIELD_PREFIXES_PROPERTY)) { if (hasPrefix(node.getName(), prefix) && !isBooleanType(typeNode)) { addViolationWithMessage(data, node, "Linguistics Antipattern - The field ''{0}'' indicates linguistically it is a boolean, but it is ''{1}''", new Object[] { node.getName(), typeNode.getTypeImage() }); } } }
private void checkVariable(ASTType typeNode, ASTVariableDeclarator node, Object data) { for (String prefix : getProperty(BOOLEAN_FIELD_PREFIXES_PROPERTY)) { if (hasPrefix(node.getName(), prefix) && !isBooleanType(typeNode)) { addViolationWithMessage(data, node, "Linguistics Antipattern - The variable ''{0}'' indicates linguistically it is a boolean, but it is ''{1}''", new Object[] { node.getName(), typeNode.getTypeImage() }); } } }
private void checkBooleanMethods(ASTMethodDeclaration node, Object data, String nameOfMethod) { ASTResultType resultType = node.getResultType(); ASTType t = node.getResultType().getFirstChildOfType(ASTType.class); if (!resultType.isVoid() && t != null) { for (String prefix : getProperty(BOOLEAN_METHOD_PREFIXES_PROPERTY)) { if (hasPrefix(nameOfMethod, prefix) && !isBooleanType(t)) { addViolationWithMessage(data, node, "Linguistics Antipattern - The method ''{0}'' indicates linguistically it returns a boolean, but it returns ''{1}''", new Object[] { nameOfMethod, t.getTypeImage() }); } } } }
private String getCaughtExceptionsAsString(ASTCatchStatement stmt) { StringBuilder sb = new StringBuilder(); final String delim = " | "; for (ASTType type : stmt.getCaughtExceptionTypeNodes()) { sb.append(type.getTypeImage()).append(delim); } // remove the last delimiter sb.replace(sb.length() - 3, sb.length(), ""); return sb.toString(); }
private boolean isBooleanType(ASTType node) { return "boolean".equalsIgnoreCase(node.getTypeImage()) || TypeHelper.isA(node, "java.util.concurrent.atomic.AtomicBoolean"); }
/** * This method checks the variable declaration if it is on a class we care * about. If it is, it returns the DeclaratorId * * @param node * The ASTLocalVariableDeclaration which is a problem * @return ASTVariableDeclaratorId */ private ASTVariableDeclaratorId getDeclaration(ASTLocalVariableDeclaration node) { ASTType type = node.getTypeNode(); if (type != null) { if (MAP_CLASSES.keySet().contains(type.getTypeImage())) { return node.getFirstDescendantOfType(ASTVariableDeclaratorId.class); } } return null; } }
private boolean isSerializationMethod(ASTMethodDeclaration node) { ASTMethodDeclarator declarator = node.getFirstDescendantOfType(ASTMethodDeclarator.class); List<ASTFormalParameter> parameters = declarator.findDescendantsOfType(ASTFormalParameter.class); if (node.isPrivate() && "readObject".equals(node.getMethodName()) && parameters.size() == 1 && throwsOneException(node, InvalidObjectException.class)) { ASTType type = parameters.get(0).getTypeNode(); if (type.getType() == ObjectInputStream.class || ObjectInputStream.class.getSimpleName().equals(type.getTypeImage()) || ObjectInputStream.class.getName().equals(type.getTypeImage())) { return true; } } return false; }
private static boolean isGetterOrSetter(ASTMethodDeclaration node) { ClassScope scope = node.getScope().getEnclosingScope(ClassScope.class); // fields names mapped to their types Map<String, String> fieldNames = new HashMap<>(); for (Map.Entry<VariableNameDeclaration, List<NameOccurrence>> decl : scope.getVariableDeclarations().entrySet()) { ASTFieldDeclaration field = decl.getKey() .getNode() .getFirstParentOfType(ASTFieldDeclaration.class); Matcher matcher = FIELD_NAME_PATTERN.matcher(field.getVariableName()); String varName = matcher.find() ? matcher.group(1) : field.getVariableName(); fieldNames.put(varName, field.getFirstChildOfType(ASTType.class).getTypeImage()); } return isGetter(node, fieldNames) || isSetter(node, fieldNames); }
private void checkVariable(ASTType typeNode, ASTVariableDeclarator node, Object data) { for (String prefix : getProperty(BOOLEAN_FIELD_PREFIXES_PROPERTY)) { if (hasPrefix(node.getName(), prefix) && !isBooleanType(typeNode)) { addViolationWithMessage(data, node, "Linguistics Antipattern - The variable ''{0}'' indicates linguistically it is a boolean, but it is ''{1}''", new Object[] { node.getName(), typeNode.getTypeImage() }); } } }
private void checkField(ASTType typeNode, ASTVariableDeclarator node, Object data) { for (String prefix : getProperty(BOOLEAN_FIELD_PREFIXES_PROPERTY)) { if (hasPrefix(node.getName(), prefix) && !isBooleanType(typeNode)) { addViolationWithMessage(data, node, "Linguistics Antipattern - The field ''{0}'' indicates linguistically it is a boolean, but it is ''{1}''", new Object[] { node.getName(), typeNode.getTypeImage() }); } } }
private void checkBooleanMethods(ASTMethodDeclaration node, Object data, String nameOfMethod) { ASTResultType resultType = node.getResultType(); ASTType t = node.getResultType().getFirstChildOfType(ASTType.class); if (!resultType.isVoid() && t != null) { for (String prefix : getProperty(BOOLEAN_METHOD_PREFIXES_PROPERTY)) { if (hasPrefix(nameOfMethod, prefix) && !isBooleanType(t)) { addViolationWithMessage(data, node, "Linguistics Antipattern - The method ''{0}'' indicates linguistically it returns a boolean, but it returns ''{1}''", new Object[] { nameOfMethod, t.getTypeImage() }); } } } }