DeriveUtilsImpl implements DeriveUtils { @Override public List<ExecutableElement> allAbstractMethods(DeclaredType declaredType) { return asTypeElement.visit(declaredType.asElement()).map(typeElement -> { List<P2<ExecutableElement, ExecutableType>> unorderedAbstractMethods = getMethods( Elements.getAllMembers(typeElement)).filter(this::abstractMethod) .map(e -> p2(e, (ExecutableType) Types.asMemberOf(declaredType, e))) .collect(toList()); Set<ExecutableElement> deduplicatedUnorderedAbstractMethods = IntStream.range(0, unorderedAbstractMethods.size()) .filter(i -> unorderedAbstractMethods.subList(0, i) .stream() .noneMatch(m -> m.match((predExecutableElement, predExecutableType) -> unorderedAbstractMethods.get(i) .match((executableElement, executableType) -> predExecutableElement.getSimpleName().equals(executableElement.getSimpleName()) && Types.isSubsignature(predExecutableType, executableType))))) .mapToObj(i -> unorderedAbstractMethods.get(i).match((executableElement, __) -> executableElement)) .collect(toSet()); return Stream.concat(getSuperTypeElements(typeElement), Stream.of(typeElement)) .flatMap(te -> te.getEnclosedElements().stream()) .map(asExecutableElement::visit) .flatMap(Utils::optionalAsStream) .filter(deduplicatedUnorderedAbstractMethods::contains) .collect(toList()); }).orElse(emptyList()); } DeriveUtilsImpl(
      Elements Elements, Types Types, SourceVersion SourceVersion, DeriveConfigBuilder deriveConfigBuilder); @Override Types types(); @Override Elements elements(); @Override TypeName resolveToTypeName(TypeMirror typeMirror, Function<TypeVariable, Optional<TypeName>> typeArgs); @Override Function<TypeVariable, Optional<TypeMirror>> typeRestrictions(List<TypeRestriction> typeRestrictions); @Override TypeMirror resolve(TypeMirror typeMirror, Function<TypeVariable, Optional<TypeMirror>> typeArgs); Optional<Map<TypeVariable, TypeMirror>> unify(TypeMirror from, TypeMirror to); @Override DeclaredType resolve(DeclaredType declaredType, Function<TypeVariable, Optional<TypeMirror>> typeArgs); @Override MethodSpec.Builder overrideMethodBuilder(ExecutableElement abstractMethod, DeclaredType declaredType); @Override List<TypeVariable> typeVariablesIn(TypeMirror typeMirror); @Override List<ExecutableElement> allAbstractMethods(DeclaredType declaredType); @Override List<ExecutableElement> allAbstractMethods(TypeElement typeElement); @Override Stream<ExecutableElement> allStaticMethods(TypeElement typeElement); @Override Stream<VariableElement> allStaticFields(TypeElement typeElement); @Override Optional<DeclaredType> asDeclaredType(TypeMirror typeMirror); @Override Optional<TypeElement> asTypeElement(TypeMirror typeMirror); Optional<TypeElement> generatedAnnotation(); @Override boolean isWildcarded(TypeMirror typeMirror); @Override ObjectModel object(); @Override Optional<SamInterface> samInterface(String qualifiedClassName); @Override SamInterface function0Model(Flavour flavour); @Override SamInterface function1Model(Flavour flavour); @Override OptionModel optionModel(Flavour flavour); @Override Optional<EitherModel> eitherModel(Flavour flavour); @Override String uncapitalize(CharSequence string); @Override String capitalize(CharSequence string); @Override Optional<InstanceLocation> findInstance(TypeElement typeElementContext, ClassName typeClassContext,
      ClassName typeClass, TypeElement typeElement, DeclaredType declaredType, List<TypeElement> lowPriorityProviders); @Override DeriveResult<BoundExpression> instanceInitializer(TypeElement typeElementContext, ClassName typeClassContext,
      ClassName typeClass, TypeMirror type, List<TypeElement> lowPriorityProviders); @Override DeriveResult<FieldsTypeClassInstanceBindingMap> resolveFieldInstances(AlgebraicDataType adt,
      ClassName typeClass, List<TypeElement> lowPriorityProviders); @Override CodeBlock lambdaImpl(DataConstructor constructor, CodeBlock impl); @Override CodeBlock lambdaImpl(DataConstructor constructor, String suffix, CodeBlock impl); @Override DeriveResult<DerivedCodeSpec> generateInstance(AlgebraicDataType adt, ClassName typeClass,
      List<TypeElement> lowPriorityProviders, Function<InstanceUtils, DerivedCodeSpec> generateInstance); @Override CodeBlock parameterList(DataConstructor constructor); @Override CodeBlock parameterList(DataConstructor constructor, String suffix); @Override Optional<TypeElement> findTypeElement(ClassName cn);  }
@Test public void allAbstractMethods_should_return_abstract_override() { Truth.assert_() .about(javaSource()) .that(JavaFileObjects.forSourceString("org.derive4j.processor.TestF", "public abstract class TestF<A,B> implements com.google.common.base.Function<A,B>, java.util.function.Function<A,B> {}")) .processedWith(new AbstractProcessor() { @Override public Set<String> getSupportedAnnotationTypes() { return Sets.newHashSet("*"); } @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { if (!roundEnv.processingOver()) { DeriveUtilsImpl deriveUtils = new DeriveUtilsImpl( processingEnv.getElementUtils(), processingEnv.getTypeUtils(), processingEnv.getSourceVersion(), new DeriveConfigBuilder(processingEnv.getElementUtils())); for (TypeElement typeElement : ElementFilter.typesIn(roundEnv.getRootElements())) { List<ExecutableElement> abstractMethods = deriveUtils .allAbstractMethods((DeclaredType) typeElement.asType()); Truth.assertThat(abstractMethods).hasSize(1); } } return false; } }) .compilesWithoutError(); }