From 66bb9d7d0894e72050c4bf4516ba4fbd8149f005 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 30 Oct 2024 22:19:06 -0400 Subject: [PATCH 1/4] remove exports limitation --- .../src/main/java/module-info.java | 1 - .../inject/generator/ExternalProvider.java | 102 +++++++++++------- 2 files changed, 61 insertions(+), 42 deletions(-) diff --git a/blackbox-aspect/src/main/java/module-info.java b/blackbox-aspect/src/main/java/module-info.java index 3c23981d..eb365cdf 100644 --- a/blackbox-aspect/src/main/java/module-info.java +++ b/blackbox-aspect/src/main/java/module-info.java @@ -1,7 +1,6 @@ module blackbox.aspect { exports org.example.external.aspect; - exports org.example.external.aspect.sub; requires io.avaje.inject; requires io.avaje.inject.aop; diff --git a/inject-generator/src/main/java/io/avaje/inject/generator/ExternalProvider.java b/inject-generator/src/main/java/io/avaje/inject/generator/ExternalProvider.java index b84a8594..8e9e947b 100644 --- a/inject-generator/src/main/java/io/avaje/inject/generator/ExternalProvider.java +++ b/inject-generator/src/main/java/io/avaje/inject/generator/ExternalProvider.java @@ -15,6 +15,7 @@ import java.util.Optional; import java.util.Set; import java.util.TreeSet; +import java.util.stream.Stream; import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; @@ -171,50 +172,69 @@ static void scanTheWorld(Collection providedTypes) { if (!externalMeta.isEmpty()) { return; } + var allModules = + APContext.elements().getAllModuleElements().stream() + .filter(m -> !m.getQualifiedName().toString().startsWith("java")) + .filter(m -> !m.getQualifiedName().toString().startsWith("jdk")) + // for whatever reason, compilation breaks if we don't filter out the current module + .filter(m -> m != APContext.getProjectModuleElement()) + .collect(toList()); var types = APContext.types(); var spi = APContext.typeElement("io.avaje.inject.spi.AvajeModule").asType(); - APContext.elements().getAllModuleElements().stream() - .filter(m -> !m.getQualifiedName().toString().startsWith("java")) - .filter(m -> !m.getQualifiedName().toString().startsWith("jdk")) - // for whatever reason, compilation breaks if we don't filter out the current module - .filter(m -> m != APContext.getProjectModuleElement()) - .flatMap(m -> m.getEnclosedElements().stream()) - .flatMap(p -> p.getEnclosedElements().stream()) - .map(TypeElement.class::cast) - .filter(t -> t.getKind() == ElementKind.CLASS) - .filter(t -> t.getModifiers().contains(Modifier.PUBLIC)) - .filter(t -> t.getInterfaces().stream().anyMatch(i -> types.isAssignable(i, spi))) - .forEach(t -> { - final var provides = new HashSet(); - final var requires = new HashSet(); - Optional.of(t) - .map(TypeElement::getEnclosedElements) - .map(ElementFilter::methodsIn) - .stream() - .flatMap(List::stream) - .map(DependencyMetaPrism::getInstanceOn) - .filter(Objects::nonNull) - .map(MetaData::new) - .forEach(m -> { - externalMeta.add(m); - provides.addAll(m.autoProvides()); - provides.addAll(m.provides()); - m.dependsOn().stream() - .filter(d -> !d.isSoftDependency()) - .map(Dependency::name) - .forEach(requires::add); - - providedTypes.add(m.key()); - providedTypes.add(m.type()); - providedTypes.addAll(Util.addQualifierSuffix(m.provides(), m.name())); - providedTypes.addAll(Util.addQualifierSuffix(m.autoProvides(), m.name())); - }); - - final var name = t.getQualifiedName().toString(); - APContext.logNote("Detected Module: %s", name); - ProcessingContext.addModule(new ModuleData(name, List.copyOf(provides), List.copyOf(requires))); - }); + final var checkEnclosing = + allModules.stream() + .flatMap(m -> m.getEnclosedElements().stream()) + .flatMap(p -> p.getEnclosedElements().stream()) + .map(TypeElement.class::cast) + .filter(t -> t.getKind() == ElementKind.CLASS) + .filter(t -> t.getModifiers().contains(Modifier.PUBLIC)); + + final var checkDirectives = + allModules.stream() + .flatMap(m -> ElementFilter.providesIn(m.getDirectives()).stream()) + .filter( + p -> + "io.avaje.inject.spi.InjectExtension" + .equals(p.getService().getQualifiedName().toString())) + .flatMap(p -> p.getImplementations().stream()); + + Stream.concat(checkEnclosing, checkDirectives) + .filter(t -> t.getInterfaces().stream().anyMatch(i -> types.isAssignable(i, spi))) + .distinct() + .forEach( + t -> { + final var provides = new HashSet(); + final var requires = new HashSet(); + Optional.of(t) + .map(TypeElement::getEnclosedElements) + .map(ElementFilter::methodsIn) + .stream() + .flatMap(List::stream) + .map(DependencyMetaPrism::getInstanceOn) + .filter(Objects::nonNull) + .map(MetaData::new) + .forEach( + m -> { + externalMeta.add(m); + provides.addAll(m.autoProvides()); + provides.addAll(m.provides()); + m.dependsOn().stream() + .filter(d -> !d.isSoftDependency()) + .map(Dependency::name) + .forEach(requires::add); + + providedTypes.add(m.key()); + providedTypes.add(m.type()); + providedTypes.addAll(Util.addQualifierSuffix(m.provides(), m.name())); + providedTypes.addAll(Util.addQualifierSuffix(m.autoProvides(), m.name())); + }); + + final var name = t.getQualifiedName().toString(); + APContext.logNote("Detected Module: %s", name); + ProcessingContext.addModule( + new ModuleData(name, List.copyOf(provides), List.copyOf(requires))); + }); if (externalMeta.isEmpty()) { APContext.logNote("No external modules detected"); } From d27a2a3515dfdc5150572f9b0f58f198167c37a8 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 30 Oct 2024 22:22:43 -0400 Subject: [PATCH 2/4] Update module-info.java --- blackbox-aspect/src/main/java/module-info.java | 1 + 1 file changed, 1 insertion(+) diff --git a/blackbox-aspect/src/main/java/module-info.java b/blackbox-aspect/src/main/java/module-info.java index eb365cdf..3c23981d 100644 --- a/blackbox-aspect/src/main/java/module-info.java +++ b/blackbox-aspect/src/main/java/module-info.java @@ -1,6 +1,7 @@ module blackbox.aspect { exports org.example.external.aspect; + exports org.example.external.aspect.sub; requires io.avaje.inject; requires io.avaje.inject.aop; From 41d60df5393bd11edfd78ab19faafcd8567f04c3 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 30 Oct 2024 23:59:36 -0400 Subject: [PATCH 3/4] Update ExternalProvider.java --- .../java/io/avaje/inject/generator/ExternalProvider.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/inject-generator/src/main/java/io/avaje/inject/generator/ExternalProvider.java b/inject-generator/src/main/java/io/avaje/inject/generator/ExternalProvider.java index 8e9e947b..874be995 100644 --- a/inject-generator/src/main/java/io/avaje/inject/generator/ExternalProvider.java +++ b/inject-generator/src/main/java/io/avaje/inject/generator/ExternalProvider.java @@ -206,11 +206,8 @@ static void scanTheWorld(Collection providedTypes) { t -> { final var provides = new HashSet(); final var requires = new HashSet(); - Optional.of(t) - .map(TypeElement::getEnclosedElements) - .map(ElementFilter::methodsIn) - .stream() - .flatMap(List::stream) + + ElementFilter.methodsIn(t.getEnclosedElements()).stream() .map(DependencyMetaPrism::getInstanceOn) .filter(Objects::nonNull) .map(MetaData::new) From 6e7cd7b9a9b1ab0992b508f4d2107ea7fe095fbf Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 31 Oct 2024 18:05:55 +1300 Subject: [PATCH 4/4] Format only --- .../inject/generator/ExternalProvider.java | 104 +++++++++--------- 1 file changed, 51 insertions(+), 53 deletions(-) diff --git a/inject-generator/src/main/java/io/avaje/inject/generator/ExternalProvider.java b/inject-generator/src/main/java/io/avaje/inject/generator/ExternalProvider.java index 874be995..0b8c6a17 100644 --- a/inject-generator/src/main/java/io/avaje/inject/generator/ExternalProvider.java +++ b/inject-generator/src/main/java/io/avaje/inject/generator/ExternalProvider.java @@ -17,9 +17,9 @@ import java.util.TreeSet; import java.util.stream.Stream; -import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; import javax.lang.model.element.Modifier; +import javax.lang.model.element.ModuleElement; import javax.lang.model.element.TypeElement; import javax.lang.model.util.ElementFilter; @@ -118,7 +118,7 @@ static void registerPluginProvidedTypes(ScopeInfo defaultScope) { if (!INJECT_AVAILABLE) { if (!pluginExists("avaje-module-dependencies.csv")) { APContext.logNote( - "Unable to detect Avaje Inject in Annotation Processor ClassPath, use the Avaje Inject Maven/Gradle plugin for detecting Inject Plugins from dependencies"); + "Unable to detect Avaje Inject in Annotation Processor ClassPath, use the Avaje Inject Maven/Gradle plugin for detecting Inject Plugins from dependencies"); } return; } @@ -173,67 +173,65 @@ static void scanTheWorld(Collection providedTypes) { return; } var allModules = - APContext.elements().getAllModuleElements().stream() - .filter(m -> !m.getQualifiedName().toString().startsWith("java")) - .filter(m -> !m.getQualifiedName().toString().startsWith("jdk")) - // for whatever reason, compilation breaks if we don't filter out the current module - .filter(m -> m != APContext.getProjectModuleElement()) - .collect(toList()); + APContext.elements().getAllModuleElements().stream() + .filter(m -> !m.getQualifiedName().toString().startsWith("java")) + .filter(m -> !m.getQualifiedName().toString().startsWith("jdk")) + // for whatever reason, compilation breaks if we don't filter out the current module + .filter(m -> m != APContext.getProjectModuleElement()) + .collect(toList()); var types = APContext.types(); var spi = APContext.typeElement("io.avaje.inject.spi.AvajeModule").asType(); final var checkEnclosing = - allModules.stream() - .flatMap(m -> m.getEnclosedElements().stream()) - .flatMap(p -> p.getEnclosedElements().stream()) - .map(TypeElement.class::cast) - .filter(t -> t.getKind() == ElementKind.CLASS) - .filter(t -> t.getModifiers().contains(Modifier.PUBLIC)); + allModules.stream() + .flatMap(m -> m.getEnclosedElements().stream()) + .flatMap(p -> p.getEnclosedElements().stream()) + .map(TypeElement.class::cast) + .filter(t -> t.getKind() == ElementKind.CLASS) + .filter(t -> t.getModifiers().contains(Modifier.PUBLIC)); final var checkDirectives = - allModules.stream() - .flatMap(m -> ElementFilter.providesIn(m.getDirectives()).stream()) - .filter( - p -> - "io.avaje.inject.spi.InjectExtension" - .equals(p.getService().getQualifiedName().toString())) - .flatMap(p -> p.getImplementations().stream()); + allModules.stream() + .flatMap(m -> ElementFilter.providesIn(m.getDirectives()).stream()) + .filter(ExternalProvider::isInjectExtension) + .flatMap(p -> p.getImplementations().stream()); Stream.concat(checkEnclosing, checkDirectives) - .filter(t -> t.getInterfaces().stream().anyMatch(i -> types.isAssignable(i, spi))) - .distinct() - .forEach( - t -> { - final var provides = new HashSet(); - final var requires = new HashSet(); - - ElementFilter.methodsIn(t.getEnclosedElements()).stream() - .map(DependencyMetaPrism::getInstanceOn) - .filter(Objects::nonNull) - .map(MetaData::new) - .forEach( - m -> { - externalMeta.add(m); - provides.addAll(m.autoProvides()); - provides.addAll(m.provides()); - m.dependsOn().stream() - .filter(d -> !d.isSoftDependency()) - .map(Dependency::name) - .forEach(requires::add); - - providedTypes.add(m.key()); - providedTypes.add(m.type()); - providedTypes.addAll(Util.addQualifierSuffix(m.provides(), m.name())); - providedTypes.addAll(Util.addQualifierSuffix(m.autoProvides(), m.name())); - }); - - final var name = t.getQualifiedName().toString(); - APContext.logNote("Detected Module: %s", name); - ProcessingContext.addModule( - new ModuleData(name, List.copyOf(provides), List.copyOf(requires))); - }); + .filter(t -> t.getInterfaces().stream().anyMatch(i -> types.isAssignable(i, spi))) + .distinct() + .forEach(t -> { + final var provides = new HashSet(); + final var requires = new HashSet(); + + ElementFilter.methodsIn(t.getEnclosedElements()).stream() + .map(DependencyMetaPrism::getInstanceOn) + .filter(Objects::nonNull) + .map(MetaData::new) + .forEach(m -> { + externalMeta.add(m); + provides.addAll(m.autoProvides()); + provides.addAll(m.provides()); + m.dependsOn().stream() + .filter(d -> !d.isSoftDependency()) + .map(Dependency::name) + .forEach(requires::add); + + providedTypes.add(m.key()); + providedTypes.add(m.type()); + providedTypes.addAll(Util.addQualifierSuffix(m.provides(), m.name())); + providedTypes.addAll(Util.addQualifierSuffix(m.autoProvides(), m.name())); + }); + + final var name = t.getQualifiedName().toString(); + APContext.logNote("Detected Module: %s", name); + ProcessingContext.addModule(new ModuleData(name, List.copyOf(provides), List.copyOf(requires))); + }); if (externalMeta.isEmpty()) { APContext.logNote("No external modules detected"); } } + + private static boolean isInjectExtension(ModuleElement.ProvidesDirective p) { + return "io.avaje.inject.spi.InjectExtension".equals(p.getService().getQualifiedName().toString()); + } }