[*] 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

@@ -5,13 +5,23 @@ import de.siphalor.tweed5.core.api.extension.TweedExtension;
import de.siphalor.tweed5.data.extension.api.extension.ReadWriteContextExtensionsData;
import de.siphalor.tweed5.dataapi.api.TweedDataReader;
import de.siphalor.tweed5.dataapi.api.TweedDataVisitor;
import org.jspecify.annotations.Nullable;
public interface ReadWriteExtension extends TweedExtension {
void setEntryReaderWriterDefinition(ConfigEntry<?> entry, EntryReaderWriterDefinition readerWriterDefinition);
ReadWriteContextExtensionsData createReadWriteContextExtensionsData();
<T> T read(TweedDataReader reader, ConfigEntry<T> entry, ReadWriteContextExtensionsData contextExtensionsData) throws TweedEntryReadException;
<T extends @Nullable Object> T read(
TweedDataReader reader,
ConfigEntry<T> entry,
ReadWriteContextExtensionsData contextExtensionsData
) throws TweedEntryReadException;
<T> void write(TweedDataVisitor writer, T value, ConfigEntry<T> entry, ReadWriteContextExtensionsData contextExtensionsData) throws TweedEntryWriteException;
<T extends @Nullable Object> void write(
TweedDataVisitor writer,
T value,
ConfigEntry<T> entry,
ReadWriteContextExtensionsData contextExtensionsData
) throws TweedEntryWriteException;
}

View File

@@ -3,8 +3,11 @@ package de.siphalor.tweed5.data.extension.api;
import de.siphalor.tweed5.core.api.entry.ConfigEntry;
import de.siphalor.tweed5.dataapi.api.TweedDataReadException;
import de.siphalor.tweed5.dataapi.api.TweedDataReader;
import org.jspecify.annotations.Nullable;
@FunctionalInterface
public interface TweedEntryReader<T, C extends ConfigEntry<T>> {
T read(TweedDataReader reader, C entry, TweedReadContext context) throws TweedEntryReadException, TweedDataReadException;
public interface TweedEntryReader<T extends @Nullable Object, C extends ConfigEntry<T>> {
T read(TweedDataReader reader, C entry, TweedReadContext context) throws
TweedEntryReadException,
TweedDataReadException;
}

View File

@@ -3,8 +3,9 @@ package de.siphalor.tweed5.data.extension.api;
import de.siphalor.tweed5.core.api.entry.ConfigEntry;
import de.siphalor.tweed5.dataapi.api.TweedDataWriteException;
import de.siphalor.tweed5.dataapi.api.TweedDataVisitor;
import org.jspecify.annotations.Nullable;
@FunctionalInterface
public interface TweedEntryWriter<T, C extends ConfigEntry<T>> {
void write(TweedDataVisitor writer, T value, C entry, TweedWriteContext context) throws TweedEntryWriteException, TweedDataWriteException;
public interface TweedEntryWriter<T extends @Nullable Object, C extends ConfigEntry<T>> {
void write(TweedDataVisitor writer, @Nullable T value, C entry, TweedWriteContext context) throws TweedEntryWriteException, TweedDataWriteException;
}

View File

@@ -3,7 +3,7 @@ package de.siphalor.tweed5.data.extension.api.extension;
import de.siphalor.tweed5.core.api.middleware.Middleware;
import de.siphalor.tweed5.data.extension.api.TweedEntryReader;
import de.siphalor.tweed5.data.extension.api.TweedEntryWriter;
import org.jetbrains.annotations.Nullable;
import org.jspecify.annotations.Nullable;
public interface ReadWriteRelatedExtension {
default void setupReadWriteExtension(ReadWriteExtensionSetupContext context) {

View File

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

View File

@@ -8,6 +8,7 @@ import de.siphalor.tweed5.data.extension.api.TweedEntryWriter;
import de.siphalor.tweed5.data.extension.impl.TweedEntryReaderWriterImpls;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.jspecify.annotations.NonNull;
import java.util.Collection;
@@ -55,11 +56,11 @@ public class TweedEntryReaderWriters {
public static <T, C extends Collection<T>> TweedEntryReaderWriter<C, CollectionConfigEntry<T, C>> collectionReaderWriter() {
//noinspection unchecked
return (TweedEntryReaderWriter<C, CollectionConfigEntry<T,C>>)(TweedEntryReaderWriter<?, ?>) TweedEntryReaderWriterImpls.COLLECTION_READER_WRITER;
return (TweedEntryReaderWriter<C, @NonNull CollectionConfigEntry<T, C>>) (TweedEntryReaderWriter<?, ?>) TweedEntryReaderWriterImpls.COLLECTION_READER_WRITER;
}
public static <T> TweedEntryReaderWriter<T, CompoundConfigEntry<T>> compoundReaderWriter() {
//noinspection unchecked
return (TweedEntryReaderWriter<T, CompoundConfigEntry<T>>)(TweedEntryReaderWriter<?, ?>) TweedEntryReaderWriterImpls.COMPOUND_READER_WRITER;
return (TweedEntryReaderWriter<T, @NonNull CompoundConfigEntry<T>>) (TweedEntryReaderWriter<?, ?>) TweedEntryReaderWriterImpls.COMPOUND_READER_WRITER;
}
}

View File

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

View File

@@ -22,6 +22,10 @@ import de.siphalor.tweed5.patchwork.impl.PatchworkClassGenerator;
import de.siphalor.tweed5.patchwork.impl.PatchworkClassPart;
import lombok.Setter;
import lombok.Value;
import lombok.val;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.NullUnmarked;
import org.jspecify.annotations.Nullable;
import java.lang.invoke.MethodHandle;
import java.util.Collection;
@@ -29,14 +33,16 @@ import java.util.HashMap;
import java.util.Map;
@AutoService(ReadWriteExtension.class)
@NullUnmarked
public class ReadWriteExtensionImpl implements ReadWriteExtension {
private RegisteredExtensionData<EntryExtensionsData, EntryReaderWriterDefinition> readerWriterDefinitionExtension;
private RegisteredExtensionData<EntryExtensionsData, ReadWriteEntryDataExtension> readWriteEntryDataExtension;
private DefaultMiddlewareContainer<TweedEntryReader<?, ?>> entryReaderMiddlewareContainer;
private DefaultMiddlewareContainer<TweedEntryWriter<?, ?>> entryWriterMiddlewareContainer;
private Map<Class<?>, RegisteredExtensionDataImpl<ReadWriteContextExtensionsData, ?>> readWriteContextExtensionsDataClasses;
private PatchworkClass<ReadWriteContextExtensionsData> readWriteContextExtensionsDataPatchwork;
private Map<Class<?>, RegisteredExtensionDataImpl<ReadWriteContextExtensionsData, ?>>
readWriteContextExtensionsDataClasses;
private PatchworkClass<@NonNull ReadWriteContextExtensionsData> readWriteContextExtensionsDataPatchwork;
@Override
public String getId() {
@@ -54,11 +60,17 @@ public class ReadWriteExtensionImpl implements ReadWriteExtension {
ReadWriteExtensionSetupContext setupContext = new ReadWriteExtensionSetupContext() {
@Override
public <E> RegisteredExtensionData<ReadWriteContextExtensionsData, E> registerReadWriteContextExtensionData(Class<E> extensionDataClass) {
public <E> RegisteredExtensionData<ReadWriteContextExtensionsData, E> registerReadWriteContextExtensionData(
Class<E> extensionDataClass
) {
if (readWriteContextExtensionsDataClasses.containsKey(extensionDataClass)) {
throw new IllegalArgumentException("Context extension " + extensionDataClass.getName() + " is already registered");
throw new IllegalArgumentException("Context extension "
+ extensionDataClass.getName()
+ " is already registered");
}
RegisteredExtensionDataImpl<ReadWriteContextExtensionsData, E> registeredExtensionData = new RegisteredExtensionDataImpl<>();
RegisteredExtensionDataImpl<ReadWriteContextExtensionsData, E>
registeredExtensionData
= new RegisteredExtensionDataImpl<>();
readWriteContextExtensionsDataClasses.put(extensionDataClass, registeredExtensionData);
return registeredExtensionData;
}
@@ -73,11 +85,13 @@ public class ReadWriteExtensionImpl implements ReadWriteExtension {
rwExtension.setupReadWriteExtension(setupContext);
if (rwExtension.entryReaderMiddleware() != null) {
entryReaderMiddlewareContainer.register(rwExtension.entryReaderMiddleware());
val readerMiddleware = rwExtension.entryReaderMiddleware();
if (readerMiddleware != null) {
entryReaderMiddlewareContainer.register(readerMiddleware);
}
if (rwExtension.entryWriterMiddleware() != null) {
entryWriterMiddlewareContainer.register(rwExtension.entryWriterMiddleware());
val writerMiddleware = rwExtension.entryWriterMiddleware();
if (writerMiddleware != null) {
entryWriterMiddlewareContainer.register(writerMiddleware);
}
}
}
@@ -85,20 +99,26 @@ public class ReadWriteExtensionImpl implements ReadWriteExtension {
entryReaderMiddlewareContainer.seal();
entryWriterMiddlewareContainer.seal();
PatchworkClassCreator<ReadWriteContextExtensionsData> patchworkClassCreator = PatchworkClassCreator.<ReadWriteContextExtensionsData>builder()
val patchworkClassCreator = PatchworkClassCreator.<ReadWriteContextExtensionsData>builder()
.patchworkInterface(ReadWriteContextExtensionsData.class)
.classPackage("de.siphalor.tweed5.data.extension.generated")
.classPrefix("ReadWriteContextExtensionsData$")
.build();
try {
readWriteContextExtensionsDataPatchwork = patchworkClassCreator.createClass(readWriteContextExtensionsDataClasses.keySet());
readWriteContextExtensionsDataPatchwork =
patchworkClassCreator.createClass(readWriteContextExtensionsDataClasses.keySet());
for (PatchworkClassPart patchworkClassPart : readWriteContextExtensionsDataPatchwork.parts()) {
RegisteredExtensionDataImpl<ReadWriteContextExtensionsData, ?> registeredExtension = readWriteContextExtensionsDataClasses.get(patchworkClassPart.partInterface());
RegisteredExtensionDataImpl<ReadWriteContextExtensionsData, ?>
registeredExtension
= readWriteContextExtensionsDataClasses.get(patchworkClassPart.partInterface());
registeredExtension.setter = patchworkClassPart.fieldSetter();
}
} catch (PatchworkClassGenerator.GenerationException e) {
throw new IllegalStateException("Failed to generate read write context extensions' data patchwork class", e);
throw new IllegalStateException(
"Failed to generate read write context extensions' data patchwork class",
e
);
}
}
@@ -115,14 +135,19 @@ public class ReadWriteExtensionImpl implements ReadWriteExtension {
baseWriter = TweedEntryReaderWriterImpls.NOOP_READER_WRITER;
}
readWriteEntryDataExtension.set(configEntry.extensionsData(), new ReadWriteEntryDataExtensionImpl(
entryReaderMiddlewareContainer.process(baseReader),
entryWriterMiddlewareContainer.process(baseWriter)
));
readWriteEntryDataExtension.set(
configEntry.extensionsData(), new ReadWriteEntryDataExtensionImpl(
entryReaderMiddlewareContainer.process(baseReader),
entryWriterMiddlewareContainer.process(baseWriter)
)
);
}
@Override
public void setEntryReaderWriterDefinition(ConfigEntry<?> entry, EntryReaderWriterDefinition readerWriterDefinition) {
public void setEntryReaderWriterDefinition(
@NonNull ConfigEntry<?> entry,
@NonNull EntryReaderWriterDefinition readerWriterDefinition
) {
readerWriterDefinitionExtension.set(entry.extensionsData(), readerWriterDefinition);
}
@@ -136,7 +161,11 @@ public class ReadWriteExtensionImpl implements ReadWriteExtension {
}
@Override
public <T> T read(TweedDataReader reader, ConfigEntry<T> entry, ReadWriteContextExtensionsData contextExtensionsData) throws TweedEntryReadException {
public <T> T read(
@NonNull TweedDataReader reader,
@NonNull ConfigEntry<T> entry,
@NonNull ReadWriteContextExtensionsData contextExtensionsData
) throws TweedEntryReadException {
try {
return getReaderChain(entry).read(reader, entry, new TweedReadWriteContextImpl(contextExtensionsData));
} catch (TweedDataReadException e) {
@@ -145,7 +174,12 @@ public class ReadWriteExtensionImpl implements ReadWriteExtension {
}
@Override
public <T> void write(TweedDataVisitor writer, T value, ConfigEntry<T> entry, ReadWriteContextExtensionsData contextExtensionsData) throws TweedEntryWriteException {
public <T> void write(
@NonNull TweedDataVisitor writer,
@Nullable T value,
@NonNull ConfigEntry<T> entry,
@NonNull ReadWriteContextExtensionsData contextExtensionsData
) throws TweedEntryWriteException {
try {
getWriterChain(entry).write(writer, value, entry, new TweedReadWriteContextImpl(contextExtensionsData));
} catch (TweedDataWriteException e) {
@@ -160,7 +194,8 @@ public class ReadWriteExtensionImpl implements ReadWriteExtension {
}
@Setter
private static class RegisteredExtensionDataImpl<U extends Patchwork<U>, E> implements RegisteredExtensionData<U, E> {
private static class RegisteredExtensionDataImpl<U extends Patchwork<@NonNull U>, E>
implements RegisteredExtensionData<U, E> {
private MethodHandle setter;
@Override
@@ -173,13 +208,13 @@ public class ReadWriteExtensionImpl implements ReadWriteExtension {
}
}
static <T> TweedEntryReader<T, ConfigEntry<T>> getReaderChain(ConfigEntry<T> elementEntry) {
static <T> TweedEntryReader<T, @NonNull ConfigEntry<T>> getReaderChain(ConfigEntry<T> elementEntry) {
//noinspection unchecked
return (TweedEntryReader<T, ConfigEntry<T>>) ((ReadWriteEntryDataExtension) elementEntry.extensionsData()).entryReaderChain();
return (TweedEntryReader<T, @NonNull ConfigEntry<T>>) ((ReadWriteEntryDataExtension) elementEntry.extensionsData()).entryReaderChain();
}
static <T> TweedEntryWriter<T, ConfigEntry<T>> getWriterChain(ConfigEntry<T> elementEntry) {
static <T> TweedEntryWriter<T, @NonNull ConfigEntry<T>> getWriterChain(ConfigEntry<T> elementEntry) {
//noinspection unchecked
return (TweedEntryWriter<T, ConfigEntry<T>>) ((ReadWriteEntryDataExtension) elementEntry.extensionsData()).entryWriterChain();
return (TweedEntryWriter<T, @NonNull ConfigEntry<T>>) ((ReadWriteEntryDataExtension) elementEntry.extensionsData()).entryWriterChain();
}
}

View File

@@ -9,6 +9,9 @@ import de.siphalor.tweed5.dataapi.api.*;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.Contract;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
import java.util.*;
import java.util.function.BiConsumer;
@@ -32,7 +35,7 @@ public class TweedEntryReaderWriterImpls {
public static final TweedEntryReaderWriter<Object, ConfigEntry<Object>> NOOP_READER_WRITER = new NoopReaderWriter();
@RequiredArgsConstructor
public static class NullableReader<T, C extends ConfigEntry<T>> implements TweedEntryReader<T, C> {
public static class NullableReader<T extends @Nullable Object, C extends ConfigEntry<T>> implements TweedEntryReader<T, C> {
private final TweedEntryReader<T, C> delegate;
@Override
@@ -46,7 +49,7 @@ public class TweedEntryReaderWriterImpls {
}
@RequiredArgsConstructor
public static class NullableWriter<T, C extends ConfigEntry<T>> implements TweedEntryWriter<T, C> {
public static class NullableWriter<T extends @Nullable Object, C extends ConfigEntry<T>> implements TweedEntryWriter<T, C> {
private final TweedEntryWriter<T, C> delegate;
@Override
@@ -60,7 +63,7 @@ public class TweedEntryReaderWriterImpls {
}
@RequiredArgsConstructor
private static class PrimitiveReaderWriter<T> implements TweedEntryReaderWriter<T, ConfigEntry<T>> {
private static class PrimitiveReaderWriter<T extends @NonNull Object> implements TweedEntryReaderWriter<T, ConfigEntry<T>> {
private final Function<TweedDataToken, T> readerCall;
private final BiConsumer<TweedDataVisitor, T> writerCall;
@@ -70,13 +73,13 @@ public class TweedEntryReaderWriterImpls {
}
@Override
public void write(TweedDataVisitor writer, T value, ConfigEntry<T> entry, TweedWriteContext context) throws TweedEntryWriteException, TweedDataWriteException {
public void write(TweedDataVisitor writer, @Nullable T value, ConfigEntry<T> entry, TweedWriteContext context) throws TweedEntryWriteException, TweedDataWriteException {
requireNonNullWriteValue(value);
writerCall.accept(writer, value);
}
}
public static class CollectionReaderWriter<T, C extends Collection<T>> implements TweedEntryReaderWriter<C, CollectionConfigEntry<T, C>> {
public static class CollectionReaderWriter<T extends @NonNull Object, C extends Collection<T>> implements TweedEntryReaderWriter<C, CollectionConfigEntry<T, C>> {
@Override
public C read(TweedDataReader reader, CollectionConfigEntry<T, C> entry, TweedReadContext context) throws TweedEntryReadException, TweedDataReadException {
assertIsToken(reader.readToken(), TweedDataToken::isListStart, "Expected list start");
@@ -126,7 +129,7 @@ public class TweedEntryReaderWriterImpls {
}
}
public static class CompoundReaderWriter<T> implements TweedEntryReaderWriter<T, CompoundConfigEntry<T>> {
public static class CompoundReaderWriter<T extends @NonNull Object> implements TweedEntryReaderWriter<T, CompoundConfigEntry<T>> {
@Override
public T read(TweedDataReader reader, CompoundConfigEntry<T> entry, TweedReadContext context) throws TweedEntryReadException, TweedDataReadException {
assertIsToken(reader.readToken(), TweedDataToken::isMapStart, "Expected map start");
@@ -143,10 +146,8 @@ public class TweedEntryReaderWriterImpls {
//noinspection unchecked
ConfigEntry<Object> subEntry = (ConfigEntry<Object>) compoundEntries.get(key);
TweedEntryReader<Object, ConfigEntry<Object>> subEntryReaderChain = ReadWriteExtensionImpl.getReaderChain(subEntry);
if (subEntryReaderChain != null) {
Object subEntryValue = subEntryReaderChain.read(reader, subEntry, context);
entry.set(compoundValue, key, subEntryValue);
}
Object subEntryValue = subEntryReaderChain.read(reader, subEntry, context);
entry.set(compoundValue, key, subEntryValue);
} else {
throw new TweedEntryReadException("Unexpected token " + token + ": Expected map key or map end");
}
@@ -155,7 +156,7 @@ public class TweedEntryReaderWriterImpls {
}
@Override
public void write(TweedDataVisitor writer, T value, CompoundConfigEntry<T> entry, TweedWriteContext context) throws TweedEntryWriteException, TweedDataWriteException {
public void write(TweedDataVisitor writer, @Nullable T value, CompoundConfigEntry<T> entry, TweedWriteContext context) throws TweedEntryWriteException, TweedDataWriteException {
requireNonNullWriteValue(value);
writer.visitMapStart();
@@ -168,19 +169,17 @@ public class TweedEntryReaderWriterImpls {
TweedEntryWriter<Object, ConfigEntry<Object>> subEntryWriterChain = ReadWriteExtensionImpl.getWriterChain(subEntry);
if (subEntryWriterChain != null) {
writer.visitMapEntryKey(key);
subEntryWriterChain.write(writer, entry.get(value, key), subEntry, context);
}
writer.visitMapEntryKey(key);
subEntryWriterChain.write(writer, entry.get(value, key), subEntry, context);
}
writer.visitMapEnd();
}
}
public static class NoopReaderWriter implements TweedEntryReaderWriter<Object, ConfigEntry<Object>> {
public static class NoopReaderWriter implements TweedEntryReaderWriter<@Nullable Object, ConfigEntry<Object>> {
@Override
public Object read(TweedDataReader reader, ConfigEntry<Object> entry, TweedReadContext context) throws TweedDataReadException {
public @Nullable Object read(TweedDataReader reader, ConfigEntry<Object> entry, TweedReadContext context) throws TweedDataReadException {
TweedDataToken token = reader.readToken();
if (!token.isListStart() && !token.isMapStart()) {
return null;
@@ -209,7 +208,7 @@ public class TweedEntryReaderWriterImpls {
}
@Override
public void write(TweedDataVisitor writer, Object value, ConfigEntry<Object> entry, TweedWriteContext context) throws TweedDataWriteException {
public void write(TweedDataVisitor writer, @Nullable Object value, ConfigEntry<Object> entry, TweedWriteContext context) throws TweedDataWriteException {
writer.visitNull();
}
@@ -218,7 +217,8 @@ public class TweedEntryReaderWriterImpls {
}
}
private static <T> void requireNonNullWriteValue(T value) throws TweedEntryWriteException {
@Contract("null -> fail")
private static <T> void requireNonNullWriteValue(@Nullable T value) throws TweedEntryWriteException {
if (value == null) {
throw new TweedEntryWriteException("Unable to write null value");
}

View File

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