feat(weaver-pojo): Proper API for POJO weaving

This commit is contained in:
2025-12-14 16:23:00 +01:00
parent f5c8b1aa50
commit 03b07591df
12 changed files with 207 additions and 89 deletions

View File

@@ -9,7 +9,7 @@ import de.siphalor.tweed5.core.api.container.ConfigContainer;
import de.siphalor.tweed5.data.hjson.HjsonSerde;
import de.siphalor.tweed5.data.hjson.HjsonWriter;
import de.siphalor.tweed5.fabric.helper.api.FabricConfigContainerHelper;
import de.siphalor.tweed5.weaver.pojo.impl.weaving.TweedPojoWeaverBootstrapper;
import de.siphalor.tweed5.weaver.pojo.api.TweedPojoWeaver;
import lombok.CustomLog;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
@@ -35,7 +35,7 @@ public class TweedCoatBridgeTestMod implements ClientModInitializer {
@Override
public void onInitializeClient() {
configContainer = TweedPojoWeaverBootstrapper.create(TweedCoatBridgeTestModConfig.class).weave();
configContainer = TweedPojoWeaver.forClass(TweedCoatBridgeTestModConfig.class).weave();
configCoatBridgeExtension = configContainer.extension(TweedCoatBridgeExtension.class)
.orElseThrow(() -> new IllegalStateException("TweedCoatBridgeExtension not found"));
Arrays.asList(

View File

@@ -6,7 +6,7 @@ import de.siphalor.tweed5.data.hjson.HjsonSerde;
import de.siphalor.tweed5.data.hjson.HjsonWriter;
import de.siphalor.tweed5.fabric.helper.api.FabricConfigCommentLoader;
import de.siphalor.tweed5.fabric.helper.api.FabricConfigContainerHelper;
import de.siphalor.tweed5.weaver.pojo.impl.weaving.TweedPojoWeaverBootstrapper;
import de.siphalor.tweed5.weaver.pojo.api.TweedPojoWeaver;
import lombok.CustomLog;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
@@ -22,7 +22,7 @@ public class FabricHelperTestMod implements ModInitializer {
@Override
public void onInitialize() {
configContainer = TweedPojoWeaverBootstrapper.create(TestModConfig.class).weave();
configContainer = TweedPojoWeaver.forClass(TestModConfig.class).weave();
configFilterExtension = configContainer.extension(AttributesReadWriteFilterExtension.class)
.orElseThrow(() -> new IllegalStateException("AttributesReadWriteFilterExtension not found"));
configFilterExtension.markAttributeForFiltering("reload");

View File

@@ -4,8 +4,8 @@ import de.siphalor.tweed5.attributesextension.api.AttributesExtension;
import de.siphalor.tweed5.core.api.container.ConfigContainer;
import de.siphalor.tweed5.core.api.entry.CompoundConfigEntry;
import de.siphalor.tweed5.core.api.entry.ConfigEntry;
import de.siphalor.tweed5.weaver.pojo.api.TweedPojoWeaver;
import de.siphalor.tweed5.weaver.pojo.api.annotation.*;
import de.siphalor.tweed5.weaver.pojo.impl.weaving.TweedPojoWeaverBootstrapper;
import org.junit.jupiter.api.Test;
import java.util.List;
@@ -16,7 +16,7 @@ import static org.assertj.core.api.InstanceOfAssertFactories.type;
class AttributesPojoWeavingProcessorTest {
@Test
void test() {
ConfigContainer<Config> configContainer = TweedPojoWeaverBootstrapper.create(Config.class).weave();
ConfigContainer<Config> configContainer = TweedPojoWeaver.forClass(Config.class).weave();
configContainer.initialize();
AttributesExtension attributesExtension = configContainer.extension(AttributesExtension.class).orElseThrow();

View File

@@ -4,8 +4,8 @@ import de.siphalor.tweed5.core.api.container.ConfigContainer;
import de.siphalor.tweed5.core.api.entry.CompoundConfigEntry;
import de.siphalor.tweed5.core.api.entry.ConfigEntry;
import de.siphalor.tweed5.defaultextensions.presets.api.PresetsExtension;
import de.siphalor.tweed5.weaver.pojo.api.TweedPojoWeaver;
import de.siphalor.tweed5.weaver.pojo.api.annotation.*;
import de.siphalor.tweed5.weaver.pojo.impl.weaving.TweedPojoWeaverBootstrapper;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@@ -20,7 +20,7 @@ class PresetsWeavingProcessorTest {
@Test
void test() {
ConfigContainer<Config> configContainer = TweedPojoWeaverBootstrapper.create(Config.class).weave();
ConfigContainer<Config> configContainer = TweedPojoWeaver.forClass(Config.class).weave();
configContainer.initialize();
PresetsExtension presetsExtension = configContainer.extension(PresetsExtension.class).orElseThrow();

View File

@@ -3,14 +3,18 @@ package de.siphalor.tweed5.weaver.pojoext.serde.api;
import com.google.auto.service.AutoService;
import de.siphalor.tweed5.core.api.container.ConfigContainer;
import de.siphalor.tweed5.core.api.entry.ConfigEntry;
import de.siphalor.tweed5.data.extension.api.*;
import de.siphalor.tweed5.data.extension.api.ReadWriteExtension;
import de.siphalor.tweed5.data.extension.api.TweedEntryWriter;
import de.siphalor.tweed5.data.extension.api.TweedReaderWriterProvider;
import de.siphalor.tweed5.data.extension.api.TweedWriteContext;
import de.siphalor.tweed5.data.hjson.HjsonLexer;
import de.siphalor.tweed5.data.hjson.HjsonReader;
import de.siphalor.tweed5.data.hjson.HjsonWriter;
import de.siphalor.tweed5.dataapi.api.TweedDataVisitor;
import de.siphalor.tweed5.dataapi.api.TweedDataWriteException;
import de.siphalor.tweed5.weaver.pojo.api.TweedPojoWeaver;
import de.siphalor.tweed5.weaver.pojo.api.annotation.*;
import de.siphalor.tweed5.weaver.pojo.impl.weaving.TweedPojoWeaverBootstrapper;
import de.siphalor.tweed5.weaver.pojo.impl.weaving.TweedPojoWeaverImpl;
import lombok.*;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test;
@@ -27,10 +31,7 @@ class ReadWritePojoWeavingProcessorTest {
@Test
@SneakyThrows
void testAnnotated() {
TweedPojoWeaverBootstrapper<AnnotatedConfig> weaverBootstrapper = TweedPojoWeaverBootstrapper.create(
AnnotatedConfig.class);
ConfigContainer<AnnotatedConfig> configContainer = weaverBootstrapper.weave();
ConfigContainer<AnnotatedConfig> configContainer = TweedPojoWeaver.forClass(AnnotatedConfig.class).weave();
configContainer.initialize();
AnnotatedConfig config = new AnnotatedConfig(123, "test", new TestClass(987));

View File

@@ -9,9 +9,10 @@ import de.siphalor.tweed5.data.extension.api.ReadWriteExtension;
import de.siphalor.tweed5.data.extension.api.readwrite.TweedEntryReaderWriter;
import de.siphalor.tweed5.data.extension.impl.TweedEntryReaderWriterImpls;
import de.siphalor.tweed5.data.hjson.HjsonWriter;
import de.siphalor.tweed5.weaver.pojo.api.TweedPojoWeaver;
import de.siphalor.tweed5.weaver.pojo.api.annotation.*;
import de.siphalor.tweed5.weaver.pojo.api.weaving.NullablePojoWeaver;
import de.siphalor.tweed5.weaver.pojo.impl.weaving.TweedPojoWeaverBootstrapper;
import de.siphalor.tweed5.weaver.pojo.impl.weaving.TweedPojoWeaverImpl;
import lombok.Data;
import org.jspecify.annotations.NullUnmarked;
import org.jspecify.annotations.Nullable;
@@ -33,9 +34,7 @@ class AutoReadWritePojoWeavingProcessorTest {
@BeforeEach
void setUp() {
var bootstrapper = TweedPojoWeaverBootstrapper.create(AnnotatedConfig.class);
container = bootstrapper.weave();
container = TweedPojoWeaver.forClass(AnnotatedConfig.class).weave();
container.initialize();
readWriteExtension = container.extension(ReadWriteExtension.class).orElseThrow();
@@ -77,9 +76,7 @@ class AutoReadWritePojoWeavingProcessorTest {
@Test
void testUsage() {
var bootstrapper = TweedPojoWeaverBootstrapper.create(AnnotatedConfig.class);
var container = bootstrapper.weave();
var container = TweedPojoWeaver.forClass(AnnotatedConfig.class).weave();
container.initialize();
AnnotatedConfig config = new AnnotatedConfig()

View File

@@ -8,8 +8,9 @@ import de.siphalor.tweed5.data.extension.api.TweedEntryWriteException;
import de.siphalor.tweed5.data.extension.impl.TweedEntryReaderWriterImpls;
import de.siphalor.tweed5.data.hjson.HjsonWriter;
import de.siphalor.tweed5.defaultextensions.pather.api.PatherExtension;
import de.siphalor.tweed5.weaver.pojo.api.TweedPojoWeaver;
import de.siphalor.tweed5.weaver.pojo.api.annotation.*;
import de.siphalor.tweed5.weaver.pojo.impl.weaving.TweedPojoWeaverBootstrapper;
import de.siphalor.tweed5.weaver.pojo.impl.weaving.TweedPojoWeaverImpl;
import de.siphalor.tweed5.weaver.pojoext.serde.api.ReadWritePojoWeavingProcessor;
import de.siphalor.tweed5.weaver.pojoext.serde.api.auto.AutoReadWritePojoWeavingProcessor;
import de.siphalor.tweed5.weaver.pojoext.serde.api.auto.DefaultReadWriteMappings;
@@ -34,9 +35,7 @@ class AutoNullableReadWritePojoWeavingProcessorTest {
@BeforeEach
void setUp() {
var bootstrapper = TweedPojoWeaverBootstrapper.create(AnnotatedConfig.class);
container = bootstrapper.weave();
container = TweedPojoWeaver.forClass(AnnotatedConfig.class).weave();
container.initialize();
readWriteExtension = container.extension(ReadWriteExtension.class).orElseThrow();

View File

@@ -3,8 +3,9 @@ package de.siphalor.tweed5.weaver.pojoext.validation.api;
import de.siphalor.tweed5.core.api.container.ConfigContainer;
import de.siphalor.tweed5.defaultextensions.validation.api.ValidationExtension;
import de.siphalor.tweed5.defaultextensions.validation.api.result.ValidationIssues;
import de.siphalor.tweed5.weaver.pojo.api.TweedPojoWeaver;
import de.siphalor.tweed5.weaver.pojo.api.annotation.*;
import de.siphalor.tweed5.weaver.pojo.impl.weaving.TweedPojoWeaverBootstrapper;
import de.siphalor.tweed5.weaver.pojo.impl.weaving.TweedPojoWeaverImpl;
import de.siphalor.tweed5.weaver.pojoext.validation.api.validators.WeavableNumberRangeValidator;
import lombok.AllArgsConstructor;
import lombok.Data;
@@ -19,8 +20,7 @@ class ValidatorsPojoWeavingProcessorTest {
@ParameterizedTest
@CsvSource({"-1,true", "0,false", "50,false", "99,false", "100,true", "101,true"})
void test(int value, boolean issuesExpected) {
var bootstrapper = TweedPojoWeaverBootstrapper.create(Config.class);
ConfigContainer<Config> configContainer = bootstrapper.weave();
ConfigContainer<Config> configContainer = TweedPojoWeaver.forClass(Config.class).weave();
configContainer.initialize();
var validationExtension = configContainer.extension(ValidationExtension.class).orElseThrow();

View File

@@ -0,0 +1,43 @@
package de.siphalor.tweed5.weaver.pojo.api;
import de.siphalor.tweed5.core.api.container.ConfigContainer;
import de.siphalor.tweed5.core.api.extension.TweedExtension;
import de.siphalor.tweed5.weaver.pojo.api.weaving.TweedPojoWeavingExtension;
import de.siphalor.tweed5.weaver.pojo.impl.weaving.TweedPojoWeaverImpl;
import org.jetbrains.annotations.Contract;
public interface TweedPojoWeaver<T> {
static <T> TweedPojoWeaver<T> forClass(Class<T> pojoClass) {
return TweedPojoWeaverImpl.implForClass(pojoClass);
}
Class<T> pojoClass();
ConfigContainer<T> configContainer();
@Contract("_ -> this")
default TweedPojoWeaver<T> withWeavingExtensions(Class<? extends TweedPojoWeavingExtension>... weavingExtensions) {
for (Class<? extends TweedPojoWeavingExtension> weavingExtension : weavingExtensions) {
withWeavingExtension(weavingExtension);
}
return this;
}
@Contract("_ -> this")
TweedPojoWeaver<T> withWeavingExtension(Class<? extends TweedPojoWeavingExtension> weavingExtension);
@Contract("_ -> this")
default TweedPojoWeaver<T> withExtensions(Class<? extends TweedExtension>... extensions) {
for (Class<? extends TweedExtension> extension : extensions) {
withExtension(extension);
}
return this;
}
@Contract("_ -> this")
TweedPojoWeaver<T> withExtension(Class<? extends TweedExtension> extension);
@Contract("_ -> this")
TweedPojoWeaver<T> withConfigContainer(ConfigContainer<T> container);
ConfigContainer<T> weave();
}

View File

@@ -2,10 +2,12 @@ package de.siphalor.tweed5.weaver.pojo.impl.weaving;
import de.siphalor.tweed5.annotationinheritance.api.AnnotationInheritanceAwareAnnotatedElement;
import de.siphalor.tweed5.core.api.container.ConfigContainer;
import de.siphalor.tweed5.core.api.container.ConfigContainerSetupPhase;
import de.siphalor.tweed5.core.api.entry.ConfigEntry;
import de.siphalor.tweed5.patchwork.api.Patchwork;
import de.siphalor.tweed5.patchwork.api.PatchworkFactory;
import de.siphalor.tweed5.typeutils.api.type.ActualType;
import de.siphalor.tweed5.weaver.pojo.api.TweedPojoWeaver;
import de.siphalor.tweed5.weaver.pojo.api.annotation.PojoWeaving;
import de.siphalor.tweed5.weaver.pojo.api.annotation.PojoWeavingExtension;
import de.siphalor.tweed5.weaver.pojo.api.annotation.TweedExtension;
@@ -13,6 +15,7 @@ import de.siphalor.tweed5.weaver.pojo.api.weaving.ProtoWeavingContext;
import de.siphalor.tweed5.weaver.pojo.api.weaving.TweedPojoWeavingExtension;
import de.siphalor.tweed5.weaver.pojo.api.weaving.WeavingContext;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.apachecommons.CommonsLog;
import org.jspecify.annotations.Nullable;
@@ -21,6 +24,8 @@ import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
/**
@@ -29,11 +34,18 @@ import java.util.stream.Collectors;
*/
@CommonsLog
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public class TweedPojoWeaverBootstrapper<T> {
public class TweedPojoWeaverImpl<T> implements TweedPojoWeaver<T> {
@Getter
private final Class<T> pojoClass;
private final AnnotatedElement pojoAnnotations;
private final ConfigContainer<T> configContainer;
private final Collection<TweedPojoWeavingExtension> weavingExtensions;
private final PojoWeaving rootWeavingConfig;
private final Set<Class<? extends TweedPojoWeavingExtension>> weavingExtensionClasses = new HashSet<>();
private @Nullable Collection<TweedPojoWeavingExtension> weavingExtensions;
private @Nullable ConfigContainer<T> configContainer;
private final Set<Class<? extends de.siphalor.tweed5.core.api.extension.TweedExtension>> extensionClasses = new HashSet<>();
private final WeavingContext.WeavingFn weavingContextFn = new WeavingContext.WeavingFn() {
@Override
public <U> ConfigEntry<U> weaveEntry(
@@ -41,61 +53,21 @@ public class TweedPojoWeaverBootstrapper<T> {
Patchwork extensionsData,
ProtoWeavingContext context
) {
return TweedPojoWeaverBootstrapper.this.weaveEntry(valueType, extensionsData, context);
return TweedPojoWeaverImpl.this.weaveEntry(valueType, extensionsData, context);
}
@Override
public <U> ConfigEntry<U> weavePseudoEntry(WeavingContext parentContext, String pseudoEntryName, Patchwork extensionsData) {
return TweedPojoWeaverBootstrapper.this.weavePseudoEntry(parentContext, pseudoEntryName, extensionsData);
return TweedPojoWeaverImpl.this.weavePseudoEntry(parentContext, pseudoEntryName, extensionsData);
}
};
@Nullable
private PatchworkFactory weavingExtensionsPatchworkFactory;
public static <T> TweedPojoWeaverBootstrapper<T> create(Class<T> pojoClass) {
private @Nullable PatchworkFactory weavingExtensionsPatchworkFactory;
public static <T> TweedPojoWeaverImpl<T> implForClass(Class<T> pojoClass) {
AnnotatedElement pojoAnnotations = new AnnotationInheritanceAwareAnnotatedElement(pojoClass);
PojoWeaving rootWeavingConfig = expectAnnotation(pojoAnnotations, PojoWeaving.class);
PojoWeavingExtension[] extensionAnnotations = pojoAnnotations.getAnnotationsByType(PojoWeavingExtension.class);
//noinspection unchecked
ConfigContainer<T>
configContainer
= (ConfigContainer<T>) createConfigContainer((Class<? extends ConfigContainer<?>>) rootWeavingConfig.container());
TweedExtension[] tweedExtensions = pojoAnnotations.getAnnotationsByType(TweedExtension.class);
//noinspection unchecked
configContainer.registerExtensions(
Arrays.stream(tweedExtensions).map(TweedExtension::value).toArray(Class[]::new)
);
configContainer.finishExtensionSetup();
Collection<TweedPojoWeavingExtension> extensions = loadWeavingExtensions(
Arrays.stream(extensionAnnotations).map(PojoWeavingExtension::value).collect(Collectors.toList()),
configContainer
);
return new TweedPojoWeaverBootstrapper<>(pojoClass, pojoAnnotations, configContainer, extensions);
}
private static Collection<TweedPojoWeavingExtension> loadWeavingExtensions(
Collection<Class<? extends TweedPojoWeavingExtension>> weaverClasses,
ConfigContainer<?> configContainer
) {
return weaverClasses.stream()
.map(weaverClass ->
TweedPojoWeavingExtension.FACTORY.construct(weaverClass)
.typedArg(ConfigContainer.class, configContainer)
.finish()
)
.collect(Collectors.toList());
}
private static ConfigContainer<?> createConfigContainer(Class<? extends ConfigContainer<?>> containerClass) {
try {
return ConfigContainer.FACTORY.construct(containerClass).finish();
} catch (Exception e) {
throw new PojoWeavingException("Failed to instantiate config container");
}
return new TweedPojoWeaverImpl<>(pojoClass, pojoAnnotations, rootWeavingConfig);
}
private static <A extends Annotation> A expectAnnotation(AnnotatedElement element, Class<A> annotationClass) {
@@ -110,14 +82,84 @@ public class TweedPojoWeaverBootstrapper<T> {
}
}
public ConfigContainer<T> weave() {
setupWeavingExtensions();
@Override
public TweedPojoWeaver<T> withConfigContainer(ConfigContainer<T> container) {
if (configContainer != null) {
throw new IllegalStateException("Config container already set");
}
this.configContainer = container;
return this;
}
assert weavingExtensionsPatchworkFactory != null;
@Override
public ConfigContainer<T> configContainer() {
if (configContainer != null) {
return configContainer;
}
//noinspection unchecked
this.configContainer
= (ConfigContainer<T>) createConfigContainer((Class<? extends ConfigContainer<?>>) rootWeavingConfig.container());
for (TweedExtension annotation : pojoAnnotations.getAnnotationsByType(TweedExtension.class)) {
extensionClasses.add(annotation.value());
}
//noinspection unchecked
configContainer.registerExtensions(extensionClasses.toArray(new Class[0]));
return configContainer;
}
private static ConfigContainer<?> createConfigContainer(Class<? extends ConfigContainer<?>> containerClass) {
try {
return ConfigContainer.FACTORY.construct(containerClass).finish();
} catch (Exception e) {
throw new PojoWeavingException("Failed to instantiate config container");
}
}
@Override
public TweedPojoWeaver<T> withWeavingExtension(Class<? extends TweedPojoWeavingExtension> weavingExtension) {
if (configContainer != null
&& configContainer.setupPhase().compareTo(ConfigContainerSetupPhase.TREE_ATTACHED) >= 0) {
throw new IllegalStateException("Cannot add weaving extensions after the tree has been attached");
}
weavingExtensionClasses.add(weavingExtension);
return this;
}
@Override
public TweedPojoWeaver<T> withExtension(Class<? extends de.siphalor.tweed5.core.api.extension.TweedExtension> extension) {
if (configContainer != null
&& configContainer.setupPhase().compareTo(ConfigContainerSetupPhase.EXTENSIONS_SETUP) > 0) {
throw new IllegalStateException("Cannot add extensions after the extensions have been finalized");
}
extensionClasses.add(extension);
if (configContainer != null) {
configContainer.registerExtension(extension);
}
return this;
}
public ConfigContainer<T> weave() {
ConfigContainer<T> configContainer = configContainer();
if (configContainer.setupPhase().compareTo(ConfigContainerSetupPhase.TREE_ATTACHED) >= 0) {
throw new IllegalStateException("Cannot weave twice");
}
if (configContainer.setupPhase() == ConfigContainerSetupPhase.EXTENSIONS_SETUP) {
configContainer.finishExtensionSetup();
}
ConfigEntry<T> rootEntry = this.weaveEntry(
ActualType.ofClass(pojoClass),
weavingExtensionsPatchworkFactory.create(),
weavingExtensionsPatchworkFactory().create(),
ProtoWeavingContext.create(configContainer, pojoAnnotations)
);
@@ -128,16 +170,41 @@ public class TweedPojoWeaverBootstrapper<T> {
return configContainer;
}
private void setupWeavingExtensions() {
private PatchworkFactory weavingExtensionsPatchworkFactory() {
if (weavingExtensionsPatchworkFactory != null) {
return weavingExtensionsPatchworkFactory;
}
PatchworkFactory.Builder weavingExtensionsPatchworkFactoryBuilder = PatchworkFactory.builder();
TweedPojoWeavingExtension.SetupContext setupContext = weavingExtensionsPatchworkFactoryBuilder::registerPart;
for (TweedPojoWeavingExtension weaver : weavingExtensions) {
weaver.setup(setupContext);
for (TweedPojoWeavingExtension weavingExtension : weavingExtensions()) {
weavingExtension.setup(setupContext);
}
weavingExtensionsPatchworkFactory = weavingExtensionsPatchworkFactoryBuilder.build();
return weavingExtensionsPatchworkFactory;
}
private Collection<TweedPojoWeavingExtension> weavingExtensions() {
if (weavingExtensions != null) {
return weavingExtensions;
}
for (PojoWeavingExtension annotation : pojoAnnotations.getAnnotationsByType(PojoWeavingExtension.class)) {
weavingExtensionClasses.add(annotation.value());
}
weavingExtensions = weavingExtensionClasses.stream()
.map(weavingExtensionClass ->
TweedPojoWeavingExtension.FACTORY.construct(weavingExtensionClass)
.typedArg(ConfigContainer.class, configContainer)
.finish()
)
.collect(Collectors.toList());
return weavingExtensions;
}
private <U> ConfigEntry<U> weaveEntry(
@@ -145,6 +212,8 @@ public class TweedPojoWeaverBootstrapper<T> {
Patchwork extensionsData,
ProtoWeavingContext protoContext
) {
assert configContainer != null && weavingExtensions != null;
extensionsData = extensionsData.copy();
runBeforeWeaveEntryHooks(valueType, extensionsData, protoContext);
@@ -191,6 +260,8 @@ public class TweedPojoWeaverBootstrapper<T> {
String pseudoEntryName,
Patchwork extensionsData
) {
assert configContainer != null && weavingExtensions != null;
extensionsData = extensionsData.copy();
//noinspection unchecked
@@ -237,6 +308,8 @@ public class TweedPojoWeaverBootstrapper<T> {
Patchwork extensionsData,
ProtoWeavingContext protoContext
) {
assert weavingExtensions != null;
for (TweedPojoWeavingExtension weavingExtension : weavingExtensions) {
try {
weavingExtension.beforeWeaveEntry(dataClass, extensionsData, protoContext);
@@ -251,6 +324,8 @@ public class TweedPojoWeaverBootstrapper<T> {
}
private <U> void runAfterWeaveEntryHooks(ActualType<U> dataClass, ConfigEntry<U> configEntry, WeavingContext context) {
assert weavingExtensions != null;
for (TweedPojoWeavingExtension weavingExtension : weavingExtensions) {
try {
weavingExtension.afterWeaveEntry(dataClass, configEntry, context);
@@ -265,6 +340,8 @@ public class TweedPojoWeaverBootstrapper<T> {
}
private void runAfterWeaveHooks() {
assert weavingExtensions != null;
for (TweedPojoWeavingExtension weavingExtension : weavingExtensions) {
weavingExtension.afterWeave();
}

View File

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

View File

@@ -1,6 +1,7 @@
package de.siphalor.tweed5.weaver.pojo.impl.weaving;
import de.siphalor.tweed5.core.api.container.ConfigContainer;
import de.siphalor.tweed5.weaver.pojo.api.TweedPojoWeaver;
import de.siphalor.tweed5.weaver.pojo.api.annotation.*;
import de.siphalor.tweed5.weaver.pojo.api.weaving.CollectionPojoWeaver;
import lombok.Data;
@@ -12,11 +13,10 @@ import static de.siphalor.tweed5.weaver.pojo.test.ConfigEntryAssertions.*;
import static org.assertj.core.api.Assertions.assertThat;
@SuppressWarnings("unused")
class TweedPojoWeaverBootstrapperTest {
class TweedPojoWeaverImplTest {
@Test
void defaultWeaving() {
TweedPojoWeaverBootstrapper<MainCompound> bootstrapper = TweedPojoWeaverBootstrapper.create(MainCompound.class);
ConfigContainer<MainCompound> configContainer = bootstrapper.weave();
ConfigContainer<MainCompound> configContainer = TweedPojoWeaver.forClass(MainCompound.class).weave();
assertThat(configContainer.rootEntry()).satisfies(isCompoundEntryForClassWith(MainCompound.class, rootCompound ->
assertThat(rootCompound.subEntries())
@@ -39,8 +39,7 @@ class TweedPojoWeaverBootstrapperTest {
@Test
void weavingWithList() {
TweedPojoWeaverBootstrapper<CompoundWithList> bootstrapper = TweedPojoWeaverBootstrapper.create(CompoundWithList.class);
ConfigContainer<CompoundWithList> configContainer = bootstrapper.weave();
ConfigContainer<CompoundWithList> configContainer = TweedPojoWeaver.forClass(CompoundWithList.class).weave();
assertThat(configContainer.rootEntry()).satisfies(isCompoundEntryForClassWith(CompoundWithList.class, rootCompound ->
assertThat(rootCompound.subEntries())