Skip to content

Commit

Permalink
jooby apt: more logging ref #2968
Browse files Browse the repository at this point in the history
  • Loading branch information
jknack committed Jun 9, 2024
1 parent 7d28303 commit 1ea138e
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 114 deletions.
74 changes: 40 additions & 34 deletions modules/jooby-apt/src/main/java/io/jooby/apt/JoobyProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,64 +5,59 @@
*/
package io.jooby.apt;

import static io.jooby.apt.JoobyProcessor.Options.*;
import static java.util.Optional.ofNullable;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.*;
import javax.lang.model.type.DeclaredType;
import javax.tools.Diagnostic;
import javax.tools.StandardLocation;

import com.squareup.javapoet.JavaFile;
import io.jooby.internal.apt.*;

@SupportedOptions({
JoobyProcessor.Options.OPT_DEBUG,
JoobyProcessor.Options.OPT_INCREMENTAL,
JoobyProcessor.Options.OPT_SERVICES,
JoobyProcessor.Options.OPT_SKIP_ATTRIBUTE_ANNOTATIONS
})
@SupportedOptions({DEBUG, INCREMENTAL, SERVICES, SKIP_ATTRIBUTE_ANNOTATIONS})
@SupportedSourceVersion(SourceVersion.RELEASE_17)
public class JoobyProcessor extends AbstractProcessor {
public interface Options {
String OPT_ROUTER_PREFIX = "jooby.routerPrefix";
String OPT_ROUTER_SUFFIX = "jooby.routerSuffix";
String OPT_DEBUG = "jooby.debug";
String OPT_INCREMENTAL = "jooby.incremental";
String OPT_SERVICES = "jooby.services";
String OPT_SKIP_ATTRIBUTE_ANNOTATIONS = "jooby.skipAttributeAnnotations";
String DEBUG = "jooby.debug";
String ROUTER_PREFIX = "jooby.routerPrefix";
String ROUTER_SUFFIX = "jooby.routerSuffix";
String INCREMENTAL = "jooby.incremental";
String SERVICES = "jooby.services";
String SKIP_ATTRIBUTE_ANNOTATIONS = "jooby.skipAttributeAnnotations";

static boolean boolOpt(
ProcessingEnvironment processingEnvironment, String option, boolean defaultValue) {
static boolean boolOpt(ProcessingEnvironment environment, String option, boolean defaultValue) {
return Boolean.parseBoolean(
processingEnvironment.getOptions().getOrDefault(option, String.valueOf(defaultValue)));
environment.getOptions().getOrDefault(option, String.valueOf(defaultValue)));
}

static String[] stringListOpt(
ProcessingEnvironment processingEnvironment, String option, String defaultValue) {
String value = processingEnvironment.getOptions().getOrDefault(option, defaultValue);
return value == null || value.isEmpty() ? new String[0] : value.split(",");
static List<String> stringListOpt(ProcessingEnvironment environment, String option) {
String value = string(environment, option, null);
return value == null || value.isEmpty() ? List.of() : List.of(value.split(","));
}

static String string(
ProcessingEnvironment processingEnvironment, String option, String defaultValue) {
String value = processingEnvironment.getOptions().getOrDefault(option, defaultValue);
static String string(ProcessingEnvironment environment, String option, String defaultValue) {
String value = environment.getOptions().getOrDefault(option, defaultValue);
return value == null || value.isEmpty() ? defaultValue : value;
}
}

private MvcContext context;
private Messager messager;
private Consumer<String> output;
private final Set<Object> processed = new HashSet<>();

public JoobyProcessor(Messager messager) {
this.messager = messager;
public JoobyProcessor(Consumer<String> output) {
this.output = output;
}

public JoobyProcessor() {}
Expand All @@ -72,15 +67,21 @@ public synchronized void init(ProcessingEnvironment processingEnvironment) {
this.context =
new MvcContext(
processingEnvironment,
ofNullable(messager).orElse(processingEnvironment.getMessager()));
ofNullable(output)
.orElseGet(
() ->
message ->
processingEnvironment
.getMessager()
.printMessage(Diagnostic.Kind.OTHER, message)));
super.init(processingEnvironment);
}

@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
context.debug("round #%s", context.nextRound());

if (roundEnv.processingOver()) {
context.debug("Output:");
context.getRouters().forEach(it -> context.debug(" %s.java", it.getGeneratedType()));
if (context.generateServices()) {
doServices(context.getProcessingEnvironment().getFiler(), context.getRouters());
}
Expand All @@ -92,7 +93,8 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
try {
var javaFile = router.toSourceCode();
onGeneratedSource(javaFile);
context.debug("%s", router.getTargetType());
context.debug("router %s: %s", router.getTargetType(), router.getGeneratedType());
router.getRoutes().forEach(it -> context.debug(" %s", it));
javaFile.writeTo(filer);
context.add(router);
} catch (IOException cause) {
Expand All @@ -108,12 +110,12 @@ protected void onGeneratedSource(JavaFile source) {}
private void doServices(Filer filer, List<MvcRouter> routers) {
try {
var location = "META-INF/services/io.jooby.MvcFactory";
context.debug("%s", location);
context.debug(location);

var resource = filer.createResource(StandardLocation.CLASS_OUTPUT, "", location);
var content = new StringBuilder();
for (var router : routers) {
String classname = router.getGeneratedType();
var classname = router.getGeneratedType();
context.debug(" %s", classname);
content.append(classname).append(System.lineSeparator());
}
Expand All @@ -130,10 +132,12 @@ private Map<TypeElement, MvcRouter> buildRouteRegistry(
Map<TypeElement, MvcRouter> registry = new LinkedHashMap<>();

for (var annotation : annotations) {
context.debug("found annotation: %s", annotation);
var elements = roundEnv.getElementsAnnotatedWith(annotation);
// Element could be Class or Method, bc @Path can be applied to both of them
// Also we need to expand lookup to external jars see #2486
for (var element : elements) {
context.debug(" %s", element);
if (element instanceof TypeElement typeElement) {
buildRouteRegistry(registry, typeElement);
} else if (element instanceof ExecutableElement method) {
Expand Down Expand Up @@ -188,7 +192,7 @@ private void buildRouteRegistry(Map<TypeElement, MvcRouter> registry, TypeElemen
.forEach(
method -> {
if (method.getModifiers().contains(Modifier.ABSTRACT)) {
context.debug("ignoring abstract method %s", superType, method);
context.debug("ignoring abstract method: %s %s", superType, method);
} else {
method.getAnnotationMirrors().stream()
.map(AnnotationMirror::getAnnotationType)
Expand Down Expand Up @@ -220,8 +224,10 @@ private void buildRouteRegistry(Map<TypeElement, MvcRouter> registry, TypeElemen

@Override
public Set<String> getSupportedAnnotationTypes() {
return Stream.concat(HttpPath.PATH.getAnnotations().stream(), HttpMethod.annotations().stream())
.collect(Collectors.toSet());
var supportedTypes = new HashSet<String>();
supportedTypes.addAll(HttpPath.PATH.getAnnotations());
supportedTypes.addAll(HttpMethod.annotations());
return supportedTypes;
}

@Override
Expand Down
39 changes: 13 additions & 26 deletions modules/jooby-apt/src/main/java/io/jooby/apt/MvcContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@
package io.jooby.apt;

import java.util.*;
import java.util.function.Consumer;

import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.*;
import javax.tools.Diagnostic;

import io.jooby.apt.JoobyProcessor.Options;
import io.jooby.internal.apt.HttpMethod;
Expand All @@ -28,18 +27,17 @@ public class MvcContext {
private final boolean services;
private final String routerPrefix;
private final String routerSuffix;
private int round;
private final Messager messager;
private final Consumer<String> output;
private final List<MvcRouter> routers = new ArrayList<>();

public MvcContext(ProcessingEnvironment processingEnvironment, Messager messager) {
public MvcContext(ProcessingEnvironment processingEnvironment, Consumer<String> output) {
this.processingEnvironment = processingEnvironment;
this.messager = messager;
this.debug = Options.boolOpt(processingEnvironment, Options.OPT_DEBUG, false);
this.incremental = Options.boolOpt(processingEnvironment, Options.OPT_INCREMENTAL, true);
this.services = Options.boolOpt(processingEnvironment, Options.OPT_SERVICES, true);
this.routerPrefix = Options.string(processingEnvironment, Options.OPT_ROUTER_PREFIX, "");
this.routerSuffix = Options.string(processingEnvironment, Options.OPT_ROUTER_SUFFIX, "_");
this.output = output;
this.debug = Options.boolOpt(processingEnvironment, Options.DEBUG, false);
this.incremental = Options.boolOpt(processingEnvironment, Options.INCREMENTAL, true);
this.services = Options.boolOpt(processingEnvironment, Options.SERVICES, true);
this.routerPrefix = Options.string(processingEnvironment, Options.ROUTER_PREFIX, "");
this.routerSuffix = Options.string(processingEnvironment, Options.ROUTER_SUFFIX, "_");

debug("Incremental annotation processing is turned %s.", incremental ? "ON" : "OFF");
debug("Generation of service provider configuration is turned %s.", services ? "ON" : "OFF");
Expand Down Expand Up @@ -132,25 +130,14 @@ public boolean isServices() {
return services;
}

public int nextRound() {
return ++round;
}

public void debug(String message, Object... args) {
if (debug) {
print(Diagnostic.Kind.NOTE, message, args);
info(message, args);
}
}

private void print(Diagnostic.Kind kind, String message, Object... args) {
Element originatingElement = null;
Object[] arguments = args;
if (args.length > 0 && args[args.length - 1] instanceof Element element) {
originatingElement = element;
arguments = new Object[args.length - 1];
System.arraycopy(arguments, 0, arguments, 0, arguments.length);
}
var msg = message.formatted(arguments);
messager.printMessage(kind, msg, originatingElement);
public void info(String message, Object... args) {
var msg = args.length == 0 ? message : message.formatted(args);
output.accept(msg);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,12 @@ public String toString() {
}
buffer.append(") ");
}
buffer.append(method.getSimpleName()).append("()").append(" {}");
buffer
.append(method.getSimpleName())
.append("(")
.append(String.join(", ", getRawParameterTypes()))
.append("): ")
.append(getReturnType());
return buffer.toString();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
*/
package io.jooby.internal.apt;

import static io.jooby.apt.JoobyProcessor.Options.SKIP_ATTRIBUTE_ANNOTATIONS;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.*;
Expand Down Expand Up @@ -49,8 +51,7 @@ public RouteAttributesGenerator(MvcContext context) {
var environment = context.getProcessingEnvironment();
this.elements = environment.getElementUtils();
this.types = environment.getTypeUtils();
this.skip =
List.of(Options.stringListOpt(environment, Options.OPT_SKIP_ATTRIBUTE_ANNOTATIONS, ""));
this.skip = Options.stringListOpt(environment, SKIP_ATTRIBUTE_ANNOTATIONS);
}

public Optional<String> toSourceCode(MvcRoute route, String indent) {
Expand Down
55 changes: 5 additions & 50 deletions modules/jooby-apt/src/test/java/io/jooby/apt/ProcessorRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,9 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.function.Consumer;
import java.util.stream.Stream;

import javax.annotation.processing.Messager;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element;
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;

import com.google.common.truth.Truth;
Expand Down Expand Up @@ -64,8 +59,8 @@ protected Class<?> findClass(String name) throws ClassNotFoundException {
private static class HookJoobyProcessor extends JoobyProcessor {
private JavaFile source;

public HookJoobyProcessor() {
super(new ConsoleMessager());
public HookJoobyProcessor(Consumer<String> console) {
super(console);
}

public GeneratedSourceClassLoader createClassLoader() {
Expand All @@ -83,50 +78,14 @@ protected void onGeneratedSource(JavaFile source) {
}
}

private static class ConsoleMessager implements Messager {
@Override
public void printMessage(Diagnostic.Kind kind, CharSequence msg) {
println(kind, msg);
}

@Override
public void printMessage(Diagnostic.Kind kind, CharSequence msg, Element e) {
println(kind, msg, e);
}

@Override
public void printMessage(
Diagnostic.Kind kind, CharSequence msg, Element e, AnnotationMirror a) {
println(kind, msg, e, " @", a);
}

@Override
public void printMessage(
Diagnostic.Kind kind, CharSequence msg, Element e, AnnotationMirror a, AnnotationValue v) {
println(kind, msg, e, " @", a, "=", v);
}

private void println(Diagnostic.Kind kind, CharSequence message, Object... args) {
var out = kind == Diagnostic.Kind.ERROR ? System.err : System.out;
out.println(
kind
+ ": "
+ message
+ " "
+ Stream.of(args)
.filter(Objects::nonNull)
.map(Objects::toString)
.collect(Collectors.joining(" ")));
}
}

private final HookJoobyProcessor processor = new HookJoobyProcessor();
private final HookJoobyProcessor processor;

public ProcessorRunner(Object instance) throws IOException {
this(instance, Map.of());
}

public ProcessorRunner(Object instance, Map<String, Object> options) throws IOException {
this.processor = new HookJoobyProcessor(System.out::println);
var optionsArray =
options.entrySet().stream().map(e -> "-A" + e.getKey() + "=" + e.getValue()).toList();
Truth.assert_()
Expand All @@ -137,10 +96,6 @@ public ProcessorRunner(Object instance, Map<String, Object> options) throws IOEx
.compilesWithoutError();
}

public ProcessorRunner(Object instance, boolean debug) throws IOException {
this(instance, Map.of("jooby.debug", debug));
}

public ProcessorRunner withRouter(SneakyThrows.Consumer<Jooby> consumer) throws Exception {
return withRouter((app, source) -> consumer.accept(app));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.lang.reflect.Type;
import java.util.function.BiFunction;

import edu.umd.cs.findbugs.annotations.NonNull;
import io.jooby.Context;
import io.jooby.Reified;
import io.jooby.ResultHandler;
Expand Down Expand Up @@ -41,7 +42,7 @@ public boolean isReactive() {
}

@Override
public Filter create() {
public @NonNull Filter create() {
return new JStachioHandler(jstachio, buffer, contextFunction);
}
}

0 comments on commit 1ea138e

Please sign in to comment.