private void checkMethodForModifier(MethodNode node, boolean condition, String modifierName) { if (!condition) return; addError("The " + getDescription(node) + " has an incorrect modifier " + modifierName + ".", node); }
private void checkClassForModifier(ClassNode node, boolean condition, String modifierName) { if (!condition) return; addError("The " + getDescription(node) + " has an incorrect modifier " + modifierName + ".", node); }
private void addInvalidUseOfFinalError(MethodNode method, Parameter[] parameters, ClassNode superCN) { StringBuilder msg = new StringBuilder(); msg.append("You are not allowed to override the final method ").append(method.getName()); appendParamsDescription(parameters, msg); msg.append(" from ").append(getDescription(superCN)); msg.append("."); addError(msg.toString(), method); }
private void checkMethodsForIncorrectModifiers(ClassNode cn) { if (!cn.isInterface()) return; for (MethodNode method : cn.getMethods()) { if (method.isFinal()) { addError("The " + getDescription(method) + " from " + getDescription(cn) + " must not be final. It is by definition abstract.", method); } if (method.isStatic() && !isConstructor(method)) { addError("The " + getDescription(method) + " from " + getDescription(cn) + " must not be static. Only fields may be static in an interface.", method); } } }
private void checkClassForAbstractAndFinal(ClassNode node) { if (!isAbstract(node.getModifiers())) return; if (!isFinal(node.getModifiers())) return; if (node.isInterface()) { addError("The " + getDescription(node) + " must not be final. It is by definition abstract.", node); } else { addError("The " + getDescription(node) + " must not be both final and abstract.", node); } }
private void checkInterfaceFieldModifiers(FieldNode node) { if (!currentClass.isInterface()) return; if ((node.getModifiers() & (ACC_PUBLIC | ACC_STATIC | ACC_FINAL)) == 0 || (node.getModifiers() & (ACC_PRIVATE | ACC_PROTECTED)) != 0) { addError("The " + getDescription(node) + " is not 'public static final' but is defined in " + getDescription(currentClass) + ".", node); } }
private void checkClassForOverwritingFinal(ClassNode cn) { ClassNode superCN = cn.getSuperClass(); if (superCN == null) return; if (!isFinal(superCN.getModifiers())) return; String msg = "You are not allowed to overwrite the final " + getDescription(superCN) + "."; addError(msg, cn); }
private void checkClassExtendsAllSelfTypes(ClassNode node) { int modifiers = node.getModifiers(); if (!isInterface(modifiers)) { for (ClassNode anInterface : GeneralUtils.getInterfacesAndSuperInterfaces(node)) { if (Traits.isTrait(anInterface)) { LinkedHashSet<ClassNode> selfTypes = new LinkedHashSet<ClassNode>(); for (ClassNode type : Traits.collectSelfTypes(anInterface, selfTypes, true, false)) { if (type.isInterface() && !node.implementsInterface(type)) { addError(getDescription(node) + " implements " + getDescription(anInterface) + " but does not implement self type " + getDescription(type), anInterface); } else if (!type.isInterface() && !node.isDerivedFrom(type)) { addError(getDescription(node) + " implements " + getDescription(anInterface) + " but does not extend self type " + getDescription(type), anInterface); } } } } } }
private void checkAbstractMethodVisibility(ClassNode node) { // we only do check abstract classes (including enums), no interfaces or non-abstract classes if (!isAbstract(node.getModifiers()) || isInterface(node.getModifiers())) return; List<MethodNode> abstractMethods = node.getAbstractMethods(); if (abstractMethods == null || abstractMethods.isEmpty()) return; for (MethodNode method : abstractMethods) { if (method.isPrivate()) { addError("Method '" + method.getName() + "' from " + getDescription(node) + " must not be private as it is declared as an abstract method.", method); } } }
private void checkAbstractDeclaration(MethodNode methodNode) { if (!methodNode.isAbstract()) return; if (isAbstract(currentClass.getModifiers())) return; addError("Can't have an abstract method in a non-abstract class." + " The " + getDescription(currentClass) + " must be declared abstract or the method '" + methodNode.getTypeDescriptor() + "' must not be abstract.", methodNode); }
private void checkNoAbstractMethodsNonabstractClass(ClassNode node) { if (isAbstract(node.getModifiers())) return; List<MethodNode> abstractMethods = node.getAbstractMethods(); if (abstractMethods == null) return; for (MethodNode method : abstractMethods) { MethodNode sameArgsMethod = node.getMethod(method.getName(), method.getParameters()); if (sameArgsMethod==null || method.getReturnType().equals(sameArgsMethod.getReturnType())) { addError("Can't have an abstract method in a non-abstract class." + " The " + getDescription(node) + " must be declared abstract or" + " the " + getDescription(method) + " must be implemented.", node); } else { addError("Abstract "+getDescription(method)+" is not implemented but a " + "method of the same name but different return type is defined: "+ (sameArgsMethod.isStatic()?"static ":"")+ getDescription(sameArgsMethod), method ); } } }
private void checkImplementsAndExtends(ClassNode node) { ClassNode cn = node.getSuperClass(); if (cn.isInterface() && !node.isInterface()) { addError("You are not allowed to extend the " + getDescription(cn) + ", use implements instead.", node); } for (ClassNode anInterface : node.getInterfaces()) { cn = anInterface; if (!cn.isInterface()) { addError("You are not allowed to implement the " + getDescription(cn) + ", use extends instead.", node); } } }
private void checkInterfaceMethodVisibility(ClassNode node) { if (!node.isInterface()) return; for (MethodNode method : node.getMethods()) { if (method.isPrivate()) { addError("Method '" + method.getName() + "' is private but should be public in " + getDescription(currentClass) + ".", method); } else if (method.isProtected()) { addError("Method '" + method.getName() + "' is protected but should be public in " + getDescription(currentClass) + ".", method); } } }
private void addErrorIfParamsAndReturnTypeEqual(Parameter[] p2, Parameter[] p1, MethodNode node, MethodNode element) { boolean isEqual = true; for (int i = 0; i < p2.length; i++) { isEqual &= p1[i].getType().equals(p2[i].getType()); if (!isEqual) break; } isEqual &= node.getReturnType().equals(element.getReturnType()); if (isEqual) { addError("Repetitive method name/signature for " + getDescription(node) + " in " + getDescription(currentClass) + ".", node); } }
public void visitField(FieldNode node) { if (currentClass.getDeclaredField(node.getName()) != node) { addError("The " + getDescription(node) + " is declared multiple times.", node); } checkInterfaceFieldModifiers(node); checkGenericsUsage(node, node.getType()); if (node.getType().equals(VOID_TYPE)) { addError("The " + getDescription(node) + " has invalid type void", node); } super.visitField(node); }
addError("The " + getDescription(methodNode) + " is already defined in " + getDescription(node) + ". You cannot have both a static and an instance method with the same signature", errorNode);
public void visitMethod(MethodNode node) { inConstructor = false; inStaticConstructor = node.isStaticConstructor(); checkAbstractDeclaration(node); checkRepetitiveMethod(node); checkOverloadingPrivateAndPublic(node); checkMethodModifiers(node); checkGenericsUsage(node, node.getParameters()); checkGenericsUsage(node, node.getReturnType()); for (Parameter param : node.getParameters()) { if (param.getType().equals(VOID_TYPE)) { addError("The " + getDescription(param) + " in " + getDescription(node) + " has invalid type void", param); } } super.visitMethod(node); }
private void checkClassForAbstractAndFinal(ClassNode node) { if (!Modifier.isAbstract(node.getModifiers())) return; if (!Modifier.isFinal(node.getModifiers())) return; if (node.isInterface()) { addError("The " + getDescription(node) +" must not be final. It is by definition abstract.", node); } else { addError("The " + getDescription(node) + " must not be both final and abstract.", node); } }
public void visitConstructorCallExpression(ConstructorCallExpression call) { ClassNode type = call.getType(); if (Modifier.isAbstract(type.getModifiers())) { addError("You cannot create an instance from the abstract " + getDescription(type) + ".", call); } super.visitConstructorCallExpression(call); }
private void checkImplementsAndExtends(ClassNode node) { ClassNode cn = node.getSuperClass(); if (cn.isInterface() && !node.isInterface()) { addError("You are not allowed to extend the " + getDescription(cn) + ", use implements instead.", node); } for (ClassNode anInterface : node.getInterfaces()) { cn = anInterface; if (!cn.isInterface()) { addError("You are not allowed to implement the " + getDescription(cn) + ", use extends instead.", node); } } }