private void checkRepetitiveMethod(MethodNode node) {
   if (isConstructor(node)) return;
   for (MethodNode method : currentClass.getMethods(node.getName())) {
     if (method == node) continue;
     if (!method.getDeclaringClass().equals(node.getDeclaringClass())) continue;
     Parameter[] p1 = node.getParameters();
     Parameter[] p2 = method.getParameters();
     if (p1.length != p2.length) continue;
     addErrorIfParamsAndReturnTypeEqual(p2, p1, node, method);
   }
 }
 private void checkMethodForWeakerAccessPrivileges(MethodNode mn, ClassNode cn) {
   Parameter[] params = mn.getParameters();
   for (MethodNode superMethod : cn.getSuperClass().getMethods(mn.getName())) {
     Parameter[] superParams = superMethod.getParameters();
     if (!hasEqualParameterTypes(params, superParams)) continue;
     if ((mn.isPrivate() && !superMethod.isPrivate())
         || (mn.isProtected() && superMethod.isPublic())) {
       addWeakerAccessError(cn, mn, params, superMethod);
       return;
     }
   }
 }
 private void checkMethodsForOverridingFinal(ClassNode cn) {
   for (MethodNode method : cn.getMethods()) {
     Parameter[] params = method.getParameters();
     for (MethodNode superMethod : cn.getSuperClass().getMethods(method.getName())) {
       Parameter[] superParams = superMethod.getParameters();
       if (!hasEqualParameterTypes(params, superParams)) continue;
       if (!superMethod.isFinal()) break;
       addInvalidUseOfFinalError(method, params, superMethod.getDeclaringClass());
       return;
     }
   }
 }
 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 addWeakerAccessError(
     ClassNode cn, MethodNode method, Parameter[] parameters, MethodNode superMethod) {
   StringBuilder msg = new StringBuilder();
   msg.append(method.getName());
   msg.append("(");
   boolean needsComma = false;
   for (Parameter parameter : parameters) {
     if (needsComma) {
       msg.append(",");
     } else {
       needsComma = true;
     }
     msg.append(parameter.getType());
   }
   msg.append(") in ");
   msg.append(cn.getName());
   msg.append(" cannot override ");
   msg.append(superMethod.getName());
   msg.append(" in ");
   msg.append(superMethod.getDeclaringClass().getName());
   msg.append("; attempting to assign weaker access privileges; was ");
   msg.append(superMethod.isPublic() ? "public" : "protected");
   addError(msg.toString(), method);
 }
 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());
   msg.append("(");
   boolean needsComma = false;
   for (Parameter parameter : parameters) {
     if (needsComma) {
       msg.append(",");
     } else {
       needsComma = true;
     }
     msg.append(parameter.getType());
   }
   msg.append(") from ").append(getDescription(superCN));
   msg.append(".");
   addError(msg.toString(), method);
 }
 private void checkOverloadingPrivateAndPublic(MethodNode node) {
   if (isConstructor(node)) return;
   boolean hasPrivate = false;
   boolean hasPublic = false;
   for (MethodNode method : currentClass.getMethods(node.getName())) {
     if (method == node) continue;
     if (!method.getDeclaringClass().equals(node.getDeclaringClass())) continue;
     if (method.isPublic() || method.isProtected()) {
       hasPublic = true;
     } else {
       hasPrivate = true;
     }
   }
   if (hasPrivate && hasPublic) {
     addError(
         "Mixing private and public/protected methods of the same name causes multimethods to be disabled and is forbidden to avoid surprising behaviour. Renaming the private methods will solve the problem.",
         node);
   }
 }
 private boolean isConstructor(MethodNode method) {
   return method.getName().equals("<clinit>");
 }