[*] Migrate to jspecify annotations

This commit is contained in:
2025-04-24 21:52:33 +02:00
parent cef5227bf1
commit c97f711c0b
100 changed files with 553 additions and 369 deletions

View File

@@ -4,7 +4,10 @@ import de.siphalor.tweed5.patchwork.impl.ByteArrayClassLoader;
import de.siphalor.tweed5.patchwork.impl.PatchworkClass;
import de.siphalor.tweed5.patchwork.impl.PatchworkClassGenerator;
import de.siphalor.tweed5.patchwork.impl.PatchworkClassPart;
import lombok.*;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.Value;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
@@ -16,17 +19,18 @@ import java.util.stream.Collectors;
@Value
public class PatchworkClassCreator<P extends Patchwork<P>> {
@NonNull
Class<P> patchworkInterface;
@NonNull
PatchworkClassGenerator.Config generatorConfig;
public static <P extends Patchwork<P>> Builder<P> builder() {
return new Builder<>();
}
public PatchworkClass<P> createClass(Collection<Class<?>> partInterfaces) throws PatchworkClassGenerator.GenerationException {
List<PatchworkClassPart> parts = partInterfaces.stream().map(PatchworkClassPart::new).collect(Collectors.toList());
public PatchworkClass<P> createClass(Collection<Class<?>> partInterfaces) throws
PatchworkClassGenerator.GenerationException {
List<PatchworkClassPart> parts = partInterfaces.stream()
.map(PatchworkClassPart::new)
.collect(Collectors.toList());
PatchworkClassGenerator generator = new PatchworkClassGenerator(generatorConfig, parts);
try {
@@ -45,7 +49,10 @@ public class PatchworkClassCreator<P extends Patchwork<P>> {
MethodHandle setterHandle = lookup.findSetter(patchworkClass, part.fieldName(), part.partInterface());
part.fieldSetter(setterHandle);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new IllegalStateException("Failed to access setter for patchwork part " + part.partInterface().getName(), e);
throw new IllegalStateException(
"Failed to access setter for patchwork part " + part.partInterface().getName(),
e
);
}
}
try {
@@ -67,9 +74,7 @@ public class PatchworkClassCreator<P extends Patchwork<P>> {
@Setter
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public static class Builder<P extends Patchwork<P>> {
@NonNull
private Class<P> patchworkInterface;
@NonNull
private String classPackage;
private String classPrefix = "";

View File

@@ -0,0 +1,4 @@
@NullMarked
package de.siphalor.tweed5.patchwork.api;
import org.jspecify.annotations.NullMarked;

View File

@@ -1,8 +1,10 @@
package de.siphalor.tweed5.patchwork.impl;
import org.jspecify.annotations.Nullable;
public class ByteArrayClassLoader extends ClassLoader {
public static Class<?> loadClass(String binaryClassName, byte[] byteCode) {
public static Class<?> loadClass(@Nullable String binaryClassName, byte[] byteCode) {
return new ByteArrayClassLoader(ByteArrayClassLoader.class.getClassLoader())
.createClass(binaryClassName, byteCode);
}
@@ -11,7 +13,7 @@ public class ByteArrayClassLoader extends ClassLoader {
super(parent);
}
public Class<?> createClass(String binaryClassName, byte[] byteCode) {
public Class<?> createClass(@Nullable String binaryClassName, byte[] byteCode) {
Class<?> clazz = defineClass(binaryClassName, byteCode, 0, byteCode.length);
resolveClass(clazz);
return clazz;

View File

@@ -4,6 +4,8 @@ import de.siphalor.tweed5.patchwork.api.Patchwork;
import de.siphalor.tweed5.patchwork.api.PatchworkPartIsNullException;
import de.siphalor.tweed5.patchwork.impl.util.StreamUtils;
import lombok.*;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
import org.objectweb.asm.*;
import org.objectweb.asm.commons.GeneratorAdapter;
@@ -21,7 +23,8 @@ public class PatchworkClassGenerator {
*/
private static final int CLASS_VERSION = Opcodes.V1_8;
private static final String TARGET_PACKAGE = "de.siphalor.tweed5.core.generated.contextextensions";
private static final List<Type> DEFAULT_PATHWORK_INTERFACES = Collections.singletonList(Type.getType(Patchwork.class));
private static final List<Type> DEFAULT_PATHWORK_INTERFACES
= Collections.singletonList(Type.getType(Patchwork.class));
private static final String INNER_EQUALS_METHOD_NAME = "patchwork$innerEquals";
@@ -458,7 +461,13 @@ public class PatchworkClassGenerator {
}
// </editor-fold>
private GeneratorAdapter createMethod(int access, String name, String desc, String signature, String[] exceptions) {
private GeneratorAdapter createMethod(
int access,
String name,
String desc,
@Nullable String signature,
String @Nullable [] exceptions
) {
MethodVisitor methodVisitor = classWriter.visitMethod(access, name, desc, signature, exceptions);
return new GeneratorAdapter(methodVisitor, access, name, desc);
}
@@ -502,7 +511,13 @@ public class PatchworkClassGenerator {
}
@Override
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
public MethodVisitor visitMethod(
int access,
String name,
String descriptor,
String signature,
String[] exceptions
) {
GeneratorAdapter methodWriter = createMethod(Opcodes.ACC_PUBLIC, name, descriptor, signature, exceptions);
return new PartMethodVisitor(api, methodWriter, descriptor, extensionClass);
}
@@ -513,7 +528,12 @@ public class PatchworkClassGenerator {
private final String methodDescriptor;
private final PatchworkClassPart patchworkPart;
protected PartMethodVisitor(int api, GeneratorAdapter methodWriter, String methodDescriptor, PatchworkClassPart patchworkPart) {
protected PartMethodVisitor(
int api,
GeneratorAdapter methodWriter,
String methodDescriptor,
PatchworkClassPart patchworkPart
) {
super(api);
this.methodWriter = methodWriter;
this.patchworkPart = patchworkPart;
@@ -531,7 +551,12 @@ public class PatchworkClassGenerator {
methodWriter.visitCode();
methodWriter.visitVarInsn(Opcodes.ALOAD, 0);
methodWriter.visitFieldInsn(Opcodes.GETFIELD, internalClassName(), patchworkPart.fieldName(), Type.getDescriptor(patchworkPart.partInterface()));
methodWriter.visitFieldInsn(
Opcodes.GETFIELD,
internalClassName(),
patchworkPart.fieldName(),
Type.getDescriptor(patchworkPart.partInterface())
);
methodWriter.dup();
methodWriter.ifNull(nullLabel);
methodWriter.loadArgs();
@@ -563,11 +588,9 @@ public class PatchworkClassGenerator {
@Data
public static class Config {
@NonNull
private String classPackage;
@NonNull
@lombok.NonNull
private @NonNull String classPackage;
private String classPrefix = "";
@NonNull
private Collection<Class<?>> markerInterfaces = Collections.emptyList();
}
@@ -594,12 +617,16 @@ public class PatchworkClassGenerator {
transient Collection<Method> signatures;
private DuplicateMethodsException(Collection<Method> methods) {
super("Duplicate method signatures:\n" + methods.stream().map(DuplicateMethodsException::getMethodMessage).collect(Collectors.joining("\n")));
super("Duplicate method signatures:\n" + methods.stream()
.map(DuplicateMethodsException::getMethodMessage)
.collect(Collectors.joining("\n")));
this.signatures = methods;
}
private static String getMethodMessage(Method method) {
StringBuilder stringBuilder = new StringBuilder("\t- " + method.getDeclaringClass().getCanonicalName() + "#(");
StringBuilder stringBuilder = new StringBuilder("\t- "
+ method.getDeclaringClass().getCanonicalName()
+ "#(");
for (Class<?> parameterType : method.getParameterTypes()) {
stringBuilder.append(parameterType.getCanonicalName());
stringBuilder.append(", ");

View File

@@ -0,0 +1,6 @@
@ApiStatus.Internal
@NullMarked
package de.siphalor.tweed5.patchwork.impl;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;