private boolean missingMethod( CalledMethod calledMethod, DeclaredClass calledClass, Map<ClassTypeDescriptor, DeclaredClass> classMap) { final MethodDescriptor descriptor = calledMethod.descriptor(); final DeclaredMethod method = calledClass.methods().get(descriptor); if (method != null) { if (calledMethod.isStatic() != method.isStatic()) { return true; } // TODO: also validate return type return false; } // Might be defined in a super class for (ClassTypeDescriptor parentClass : calledClass.parents()) { final DeclaredClass declaredClass = classMap.get(parentClass); // ignore null parents - this means that the parent cannot be found, and this error gets // reported since the class's constructor tries to call its parent's constructor. if (declaredClass != null) { if (!missingMethod(calledMethod, declaredClass, classMap)) { return false; } } } return true; }
private void checkForBrokenMethodCalls( CheckerState state, Artifact artifact, DeclaredClass clazz, DeclaredMethod method, ImmutableList.Builder<Conflict> builder) { for (CalledMethod calledMethod : method.methodCalls()) { final ClassTypeDescriptor owningClass = calledMethod.owner(); final DeclaredClass calledClass = state.knownClasses().get(owningClass); if (calledClass == null) { builder.add( conflict( ConflictCategory.CLASS_NOT_FOUND, "Class not found: " + owningClass, dependency(clazz, method, calledMethod), artifact.name(), state.sourceMappings().get(owningClass))); } else if (missingMethod(calledMethod, calledClass, state.knownClasses())) { builder.add( conflict( ConflictCategory.METHOD_SIGNATURE_NOT_FOUND, "Method not found: " + calledMethod.pretty(), dependency(clazz, method, calledMethod), artifact.name(), state.sourceMappings().get(owningClass))); } } }
private Dependency dependency( DeclaredClass clazz, DeclaredMethod method, CalledMethod calledMethod) { return new MethodDependencyBuilder() .fromClass(clazz.className()) .fromMethod(method.descriptor()) .fromLineNumber(calledMethod.lineNumber()) .targetMethod(calledMethod.descriptor()) .targetClass(calledMethod.owner()) .build(); }