package com.github.blackrush.acara;

import java.lang.reflect.Method;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Stream;

public class JavaListenerBuilder implements ListenerBuilder {
    @Override
    public final Stream<Listener> build(Object o) {
        List<Method> methods = new LinkedList<>();
        Class<?> klass = o.getClass();
        while (klass != Object.class) {
            Collections.addAll(methods, klass.getDeclaredMethods());
            klass = klass.getSuperclass();
        }

        return methods.stream().flatMap(this::scan);
    }

    protected Stream<Listener> scan(Method method) {
        if (!method.isAnnotationPresent(Listen.class)) {
            return Stream.empty();
        }
        if (method.getParameterCount() != 1) {
            // TODO warn user
            return Stream.empty();
        }

        JavaEventMetadata<?> meta = new JavaEventMetadata<>(method.getParameterTypes()[0]);
        JavaListener<?> listener = new JavaListener<>(meta, method);
        return Stream.of(listener);
    }
}

@@ -302,24 +302,156 @@
 Object o) %7B%0A
+        Class%3C?%3E klass = o.getClass();%0A        return scanAll(klass);%0A    %7D%0A%0A    private Stream%3CListener%3E scanAll(Class%3C?%3E klass) %7B%0A
         List
@@ -489,32 +489,37 @@
 st%3C%3E();%0A        
+for (
 Class%3C?%3E klass =
@@ -515,66 +515,63 @@
 %3C?%3E 
-klass = o.getClass();%0A        while (klass != Object.
+it = klass; it != Object.class; it = it.getSuper
 class
+()
 ) %7B%0A
@@ -610,21 +610,18 @@
 ethods, 
-klass
+it
 .getDecl
@@ -640,51 +640,8 @@
 ));%0A
-            klass = klass.getSuperclass();%0A
     

Cut out cacheable computation