Skip to content

Commit

Permalink
Support Jspecify Annotations (#650)
Browse files Browse the repository at this point in the history
* support jspecify annotations

* fix test

* make jakarta inject static transitive

* Update ExternalDeps.java

* Update ExternalDeps.java

* nullmarked

* Update pom.xml

* Update pom.xml

* Update DBeanScope.java

* bump prisms

* Revert "bump prisms"

This reverts commit 5c967b0.

* prisms 1.30

* Format, remove unused method

---------

Co-authored-by: Rob Bygrave <robin.bygrave@gmail.com>
  • Loading branch information
SentryMan and rbygrave authored Jul 24, 2024
1 parent f44bb79 commit 68be46b
Show file tree
Hide file tree
Showing 23 changed files with 94 additions and 78 deletions.
2 changes: 1 addition & 1 deletion inject-events/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-inject</artifactId>
<version>10.0-RC6</version>
<version>10.0</version>
<scope>provided</scope>
</dependency>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ private EventPublisherWriter(Element element) {
.toString()
.replaceFirst("java.", "")
+ ".events";
qualifier = Optional.ofNullable(Util.getNamed(element)).orElse("");
qualifier = Optional.ofNullable(Util.named(element)).orElse("");
var className =
packageName
+ "."
Expand All @@ -65,7 +65,7 @@ private EventPublisherWriter(Element element) {
if (GENERATED_PUBLISHERS.containsKey(originName)) {
//in super niche situations when compiling the same module, we need to tell avaje that these types already exist
//got this when running both my eclipse compiler and then the terminal build
ProcessingContext.addOptionalType(UType.parse(asType).fullWithoutAnnotations(), Util.getNamed(element));
ProcessingContext.addOptionalType(UType.parse(asType).fullWithoutAnnotations(), Util.named(element));
return;
}
importTypes.addAll(utype.importTypes());
Expand All @@ -77,7 +77,7 @@ private String getUniqueClassName(String className, Integer recursiveIndex) {
Optional.ofNullable(APContext.typeElement(className)).ifPresent(e ->
GENERATED_PUBLISHERS.put(
e.getQualifiedName().toString(),
Optional.ofNullable(Util.getNamed(e)).orElse("")));
Optional.ofNullable(Util.named(e)).orElse("")));

if (Optional.ofNullable(GENERATED_PUBLISHERS.get(className))
.filter(not(qualifier::equals))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ final class FieldReader {

FieldReader(Element element) {
this.element = element;
this.name = Util.getNamed(element);
this.name = Util.named(element);
this.nullable = Util.isNullable(element);
this.isBeanMap = QualifiedMapPrism.isPresent(element);
this.utype = Util.determineType(element.asType(), isBeanMap);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
.forEach(e -> {
var type = UType.parse(e.asType());
type = "java.util.List".equals(type.mainType()) ? type.param0() : type;
ProcessingContext.addOptionalType(type.fullWithoutAnnotations(), Util.getNamed(e));
ProcessingContext.addOptionalType(type.fullWithoutAnnotations(), Util.named(e));
ProcessingContext.addOptionalType(type.fullWithoutAnnotations(), null);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ static class MethodParam {
MethodParam(VariableElement param) {
this.element = param;
this.simpleName = param.getSimpleName().toString();
this.named = Util.getNamed(param);
this.named = Util.named(param);
this.nullable = Util.isNullable(param);
this.isBeanMap = QualifiedMapPrism.isPresent(param);
this.utilType = Util.determineType(param.asType(), isBeanMap);
Expand Down Expand Up @@ -572,7 +572,7 @@ void addImports(ImportTypeMap importTypes) {
importTypes.add("io.avaje.inject.events.ObserverManager");
}
importTypes.addAll(fullUType.importTypes());
Util.getNullableAnnotation(element).map(Object::toString).ifPresent(importTypes::add);
Util.nullableAnnotation(element).map(Object::toString).ifPresent(importTypes::add);
}

void checkRequest(BeanRequestParams requestParams) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ static boolean externallyProvided(String type) {

static void addOptionalType(String paramType, String name) {
if (!CTX.get().providedTypes.contains(paramType)) {
CTX.get().optionalTypes.add(Util.addQualifierSuffixTrim(name, paramType));
CTX.get().optionalTypes.add(ProcessorUtils.trimAnnotations(Util.addQualifierSuffixTrim(name, paramType)));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ private void checkForAspect(ExecutableElement methodElement) {


private void addFactoryMethod(ExecutableElement methodElement, BeanPrism bean) {
String qualifierName = Util.getNamed(methodElement);
String qualifierName = Util.named(methodElement);
factoryMethods.add(new MethodReader(methodElement, baseType, bean, qualifierName, importTypes).read());
}

Expand Down
23 changes: 8 additions & 15 deletions inject-generator/src/main/java/io/avaje/inject/generator/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -183,16 +183,6 @@ static String trimmedName(UType type) {
return shortName(type.mainType()).toLowerCase();
}

String trimExtends(UType uType) {
String type = uType.mainType();
if (type != null && type.startsWith("? extends ")) {
return type.substring(10);
} else if ("?".equals(type)) {
return "Wildcard";
}
return type;
}

static boolean isOptional(String rawType) {
return rawType.startsWith(OPTIONAL_PREFIX);
}
Expand Down Expand Up @@ -298,7 +288,7 @@ static String commonParent(String currentTop, String aPackage) {
/**
* Return the name via <code>@Named</code> or a Qualifier annotation.
*/
static String getNamed(Element p) {
static String named(Element p) {
final NamedPrism named = NamedPrism.getInstanceOn(p);
if (named != null) {
return named.value().replace("\"", "\\\"");
Expand All @@ -320,17 +310,20 @@ static String getNamed(Element p) {
/**
* Return true if the element has a Nullable annotation.
*/
static boolean isNullable(Element p) {
for (final AnnotationMirror mirror : p.getAnnotationMirrors()) {
static boolean isNullable(Element element) {
if (ProcessorUtils.hasAnnotationWithName(element, NULLABLE)) {
return true;
}
for (final AnnotationMirror mirror : UType.parse(element.asType()).annotations()) {
if (NULLABLE.equals(shortName(mirror.getAnnotationType().toString()))) {
return true;
}
}
return false;
}

static Optional<DeclaredType> getNullableAnnotation(Element p) {
for (final AnnotationMirror mirror : p.getAnnotationMirrors()) {
static Optional<DeclaredType> nullableAnnotation(Element element) {
for (final AnnotationMirror mirror : element.getAnnotationMirrors()) {
if (NULLABLE.equals(shortName(mirror.getAnnotationType().toString()))) {
return Optional.of(mirror.getAnnotationType());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@

import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

import org.jspecify.annotations.Nullable;

import io.avaje.inject.External;
import io.avaje.lang.Nullable;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;

@Singleton
public class ExternalDeps {
@Inject @Nullable AtomicLong longy;

public ExternalDeps(@External AtomicBoolean bool, @Nullable AtomicInteger inty) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import io.avaje.inject.BeanScope;
import io.avaje.inject.spi.AvajeModule;
import io.avaje.lang.Nullable;
import org.jspecify.annotations.Nullable;

import java.io.IOException;
import java.io.InputStream;
Expand Down
12 changes: 7 additions & 5 deletions inject-test/src/main/java/io/avaje/inject/test/PluginMgr.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package io.avaje.inject.test;

import io.avaje.inject.BeanScope;
import io.avaje.lang.Nullable;

import java.util.ServiceLoader;

import org.jspecify.annotations.Nullable;

import io.avaje.inject.BeanScope;
import io.avaje.inject.test.Plugin.Scope;

final class PluginMgr {

private PluginMgr() {}
Expand All @@ -23,8 +25,8 @@ static Plugin plugin() {
/**
* Return a new plugin scope (if there is a plugin).
*/
@Nullable
static Plugin.Scope scope(BeanScope beanScope) {
@Nullable
static Scope scope(BeanScope beanScope) {
return plugin == null ? null : plugin.createScope(beanScope);
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
package io.avaje.inject.test;

import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;

import io.avaje.inject.BeanScope;
import io.avaje.inject.BeanScopeBuilder;
import io.avaje.lang.NonNullApi;
import io.avaje.lang.Nullable;

/**
* Provides access to the global "test scope" and helper methods to use it.
*
*/
@NonNullApi
@NullMarked
public abstract class TestBeanScope {

/**
Expand Down
12 changes: 6 additions & 6 deletions inject/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@
<description>avaje-inject dependency injection library using source code generation</description>
<dependencies>

<dependency>
<groupId>org.jspecify</groupId>
<artifactId>jspecify</artifactId>
<version>1.0.0</version>
</dependency>

<dependency>
<groupId>jakarta.inject</groupId>
<artifactId>jakarta.inject-api</artifactId>
Expand All @@ -24,12 +30,6 @@
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-lang</artifactId>
<version>1.1</version>
</dependency>

<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-applog</artifactId>
Expand Down
3 changes: 0 additions & 3 deletions inject/src/main/java/io/avaje/inject/BeanEntry.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
package io.avaje.inject;

import io.avaje.lang.NonNullApi;

import java.util.Set;

/**
* A bean entry with priority and optional name.
*
* @see BeanScope#all()
*/
@NonNullApi
public interface BeanEntry {

/**
Expand Down
4 changes: 1 addition & 3 deletions inject/src/main/java/io/avaje/inject/BeanScope.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
import java.util.Map;
import java.util.Optional;

import io.avaje.lang.NonNullApi;
import io.avaje.lang.Nullable;
import org.jspecify.annotations.Nullable;

/**
* Holds beans created by dependency injection.
Expand Down Expand Up @@ -67,7 +66,6 @@
*
* }</pre>
*/
@NonNullApi
public interface BeanScope extends AutoCloseable {

/**
Expand Down
13 changes: 6 additions & 7 deletions inject/src/main/java/io/avaje/inject/BeanScopeBuilder.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package io.avaje.inject;

import io.avaje.inject.spi.AvajeModule;
import io.avaje.inject.spi.ConfigPropertyPlugin;
import io.avaje.inject.spi.PropertyRequiresPlugin;
import io.avaje.lang.NonNullApi;
import io.avaje.lang.Nullable;

import java.lang.reflect.Type;
import java.util.function.Consumer;
import java.util.function.Supplier;

import org.jspecify.annotations.Nullable;

import io.avaje.inject.spi.AvajeModule;
import io.avaje.inject.spi.ConfigPropertyPlugin;
import io.avaje.inject.spi.PropertyRequiresPlugin;

/**
* Build a bean scope with options for shutdown hook and supplying external dependencies.
* <p>
Expand All @@ -30,7 +30,6 @@
*
* }</pre>
*/
@NonNullApi
public interface BeanScopeBuilder {

/**
Expand Down
15 changes: 11 additions & 4 deletions inject/src/main/java/io/avaje/inject/DBeanScopeBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static java.lang.System.Logger.Level.DEBUG;
import static java.lang.System.Logger.Level.INFO;
import static java.util.Collections.emptySet;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
Expand All @@ -14,14 +15,20 @@
import java.util.function.Consumer;
import java.util.function.Supplier;

import org.jspecify.annotations.Nullable;

import io.avaje.applog.AppLog;
import io.avaje.inject.spi.*;
import io.avaje.lang.NonNullApi;
import io.avaje.lang.Nullable;
import io.avaje.inject.spi.AvajeModule;
import io.avaje.inject.spi.Builder;
import io.avaje.inject.spi.ClosePair;
import io.avaje.inject.spi.ConfigPropertyPlugin;
import io.avaje.inject.spi.EnrichBean;
import io.avaje.inject.spi.ModuleOrdering;
import io.avaje.inject.spi.PropertyRequiresPlugin;
import io.avaje.inject.spi.SuppliedBean;
import jakarta.inject.Provider;

/** Build a bean scope with options for shutdown hook and supplying test doubles. */
@NonNullApi
final class DBeanScopeBuilder implements BeanScopeBuilder.ForTesting {

private static final System.Logger log = AppLog.getLogger("io.avaje.inject");
Expand Down
1 change: 1 addition & 0 deletions inject/src/main/java/io/avaje/inject/package-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@
*
* }</pre>
*/
@org.jspecify.annotations.NullMarked
package io.avaje.inject;
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import java.util.Optional;

import io.avaje.lang.NonNullApi;
import org.jspecify.annotations.NullMarked;

/**
* Plugin interface which contains the application properties used for wiring. Used with
Expand All @@ -11,28 +11,33 @@
* <p>The plugin is loaded via ServiceLoader and defaults to an implementation that uses {@link
* System#getProperty(String)} and {@link System#getenv(String)}.
*/
@NonNullApi
@NullMarked
public interface ConfigPropertyPlugin extends InjectExtension, PropertyRequiresPlugin {

/**
* Return a configuration value that might not exist.
*/
@Override
Optional<String> get(String property);

/**
* Return true if the property is defined.
*/
@Override
boolean contains(String property);

/** Return true if the property is not defined. */
@Override
default boolean missing(String property) {
return !contains(property);
}

/** Return true if the property is equal to the given value. */
@Override
boolean equalTo(String property, String value);

/** Return true if the property is not defined or not equal to the given value. */
@Override
default boolean notEqualTo(String property, String value) {
return !equalTo(property, value);
}
Expand Down
Loading

0 comments on commit 68be46b

Please sign in to comment.