mirror of
https://github.com/PaperMC/Paper.git
synced 2024-11-27 04:55:47 +01:00
update typewriter and split experimental element ids per feature flag
This commit is contained in:
parent
5767cee34a
commit
ebf6610291
@ -30,7 +30,7 @@ dependencies {
|
||||
val generatedApiPath = file("generatedApi")
|
||||
val generatedServerPath = file("generatedServer")
|
||||
|
||||
tasks.register<JavaExec>("generate") {
|
||||
val generate by tasks.registering(JavaExec::class) {
|
||||
dependsOn(tasks.check)
|
||||
mainClass.set("io.papermc.generator.Main")
|
||||
classpath(sourceSets.main.map { it.runtimeClasspath })
|
||||
@ -40,6 +40,13 @@ tasks.register<JavaExec>("generate") {
|
||||
project(":paper-server").sourceSets["main"].java.srcDirs.first().toString())
|
||||
}
|
||||
|
||||
generate.configure {
|
||||
delete(generatedApiPath, generatedServerPath)
|
||||
// the module depends on paper-api but generate into the project which cause conflict
|
||||
// ideally this module would only depend on vanilla source in the long
|
||||
// run
|
||||
}
|
||||
|
||||
tasks.register<JavaExec>("scanOldGeneratedSourceCode") {
|
||||
mainClass.set("io.papermc.generator.rewriter.OldGeneratedCodeTest")
|
||||
classpath(sourceSets.test.map { it.runtimeClasspath })
|
||||
|
@ -5,7 +5,7 @@ import com.mojang.logging.LogUtils;
|
||||
import io.papermc.generator.rewriter.registration.PaperPatternSourceSetRewriter;
|
||||
import io.papermc.generator.rewriter.registration.PatternSourceSetRewriter;
|
||||
import io.papermc.generator.types.SourceGenerator;
|
||||
import io.papermc.generator.utils.experimental.TagCollector;
|
||||
import io.papermc.generator.utils.experimental.ExperimentalCollector;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@ -66,7 +66,7 @@ public final class Main {
|
||||
MoreExecutors.directExecutor()
|
||||
).join();
|
||||
reloadableServerResources.updateStaticRegistryTags();
|
||||
EXPERIMENTAL_TAGS = TagCollector.grabExperimental(resourceManager);
|
||||
EXPERIMENTAL_TAGS = ExperimentalCollector.collectTags(resourceManager);
|
||||
}
|
||||
|
||||
private Main() {
|
||||
|
@ -75,7 +75,7 @@ import org.jspecify.annotations.NullMarked;
|
||||
|
||||
import static io.papermc.generator.rewriter.registration.PaperPatternSourceSetRewriter.composite;
|
||||
import static io.papermc.generator.rewriter.registration.RewriterHolder.holder;
|
||||
import static io.papermc.typewriter.utils.Formatting.quoted;
|
||||
import static io.papermc.typewriter.util.Formatting.quoted;
|
||||
|
||||
@NullMarked
|
||||
public final class Rewriters {
|
||||
|
@ -6,6 +6,7 @@ import io.papermc.paper.registry.data.GameEventRegistryEntry;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
@ -13,6 +14,7 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
@ -38,6 +40,7 @@ import net.minecraft.world.item.equipment.trim.TrimPatterns;
|
||||
import net.minecraft.world.level.biome.Biomes;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.entity.BannerPatterns;
|
||||
import net.minecraft.world.level.levelgen.structure.BuiltinStructures;
|
||||
import net.minecraft.world.level.material.Fluids;
|
||||
import net.minecraft.world.level.saveddata.maps.MapDecorationTypes;
|
||||
import org.bukkit.Art;
|
||||
@ -70,36 +73,29 @@ import org.bukkit.map.MapCursor;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.potion.PotionType;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
@NullMarked
|
||||
public final class RegistryEntries {
|
||||
|
||||
private static <T> RegistryEntry<T> entry(ResourceKey<? extends Registry<T>> registryKey, @Nullable Class<?> registryConstantClass, Class<? extends Keyed> apiClass, String implClass) {
|
||||
return new RegistryEntry<>(registryKey, (RegistryKeyField<T>) REGISTRY_KEY_FIELDS.get(registryKey), registryConstantClass, apiClass, implClass);
|
||||
private static <T> RegistryEntry<T> entry(ResourceKey<? extends Registry<T>> registryKey, Class<?> holderElementsClass, Class<? extends Keyed> apiClass, String implClass) {
|
||||
return new RegistryEntry<>(registryKey, (RegistryKeyField<T>) REGISTRY_KEY_FIELDS.get(registryKey), holderElementsClass, apiClass, implClass);
|
||||
}
|
||||
|
||||
// CraftBukkit entry where implementation start by "Craft"
|
||||
private static <T> RegistryEntry<T> entry(ResourceKey<? extends Registry<T>> registryKey, @Nullable Class<?> registryConstantClass, Class<? extends Keyed> apiClass) {
|
||||
return entry(registryKey, registryConstantClass, "Craft", apiClass);
|
||||
private static <T> RegistryEntry<T> entry(ResourceKey<? extends Registry<T>> registryKey, Class<?> holderElementsClass, Class<? extends Keyed> apiClass) {
|
||||
return entry(registryKey, holderElementsClass, "Craft", apiClass);
|
||||
}
|
||||
|
||||
private static <T> RegistryEntry<T> entry(ResourceKey<? extends Registry<T>> registryKey, @Nullable Class<?> registryConstantClass, String implPrefix, Class<? extends Keyed> apiClass) {
|
||||
String name = io.papermc.typewriter.utils.ClassHelper.retrieveFullNestedName(apiClass);
|
||||
private static <T> RegistryEntry<T> entry(ResourceKey<? extends Registry<T>> registryKey, Class<?> holderElementsClass, String implPrefix, Class<? extends Keyed> apiClass) {
|
||||
String name = io.papermc.typewriter.util.ClassHelper.retrieveFullNestedName(apiClass);
|
||||
RegistryKeyField<T> registryKeyField = (RegistryKeyField<T>) REGISTRY_KEY_FIELDS.get(registryKey);
|
||||
String[] classes = name.split("\\.");
|
||||
if (classes.length == 0) {
|
||||
return new RegistryEntry<>(registryKey, registryKeyField, registryConstantClass, apiClass, implPrefix.concat(apiClass.getSimpleName()));
|
||||
return new RegistryEntry<>(registryKey, registryKeyField, holderElementsClass, apiClass, implPrefix.concat(apiClass.getSimpleName()));
|
||||
}
|
||||
|
||||
StringBuilder implName = new StringBuilder(name.length() + implPrefix.length() * classes.length);
|
||||
implName.append(implPrefix.concat(classes[0]));
|
||||
for (int i = 1; i < classes.length; i++) {
|
||||
implName.append('.');
|
||||
implName.append(implPrefix.concat(classes[i]));
|
||||
}
|
||||
|
||||
return new RegistryEntry<>(registryKey, registryKeyField, registryConstantClass, apiClass,implName.toString());
|
||||
String implName = Arrays.stream(classes).map(implPrefix::concat).collect(Collectors.joining("."));
|
||||
return new RegistryEntry<>(registryKey, registryKeyField, holderElementsClass, apiClass, implName);
|
||||
}
|
||||
|
||||
private static final Map<ResourceKey<? extends Registry<?>>, RegistryKeyField<?>> REGISTRY_KEY_FIELDS;
|
||||
@ -148,7 +144,7 @@ public final class RegistryEntries {
|
||||
|
||||
public static final List<RegistryEntry<?>> DATA_DRIVEN = List.of(
|
||||
entry(Registries.BIOME, Biomes.class, Biome.class).delayed(),
|
||||
entry(Registries.STRUCTURE, null, Structure.class).delayed(),
|
||||
entry(Registries.STRUCTURE, BuiltinStructures.class, Structure.class).delayed(),
|
||||
entry(Registries.TRIM_MATERIAL, TrimMaterials.class, TrimMaterial.class).delayed(),
|
||||
entry(Registries.TRIM_PATTERN, TrimPatterns.class, TrimPattern.class).delayed(),
|
||||
entry(Registries.DAMAGE_TYPE, DamageTypes.class, DamageType.class).delayed(),
|
||||
|
@ -22,8 +22,8 @@ public final class RegistryEntry<T> {
|
||||
|
||||
private final ResourceKey<? extends Registry<T>> registryKey;
|
||||
private final RegistryKeyField<T> registryKeyField;
|
||||
private final Class<T> registryElementClass;
|
||||
private final @Nullable Class<?> registryConstantClass;
|
||||
private final Class<T> elementClass;
|
||||
private final Class<?> holderElementsClass;
|
||||
|
||||
private final Class<? extends Keyed> apiClass; // TODO remove Keyed
|
||||
private final String implClass;
|
||||
@ -37,11 +37,11 @@ public final class RegistryEntry<T> {
|
||||
|
||||
private @Nullable Map<ResourceKey<T>, String> fieldNames;
|
||||
|
||||
public RegistryEntry(ResourceKey<? extends Registry<T>> registryKey, RegistryKeyField<T> registryKeyField, @Nullable Class<?> registryConstantClass, Class<? extends Keyed> apiClass, String implClass) {
|
||||
public RegistryEntry(ResourceKey<? extends Registry<T>> registryKey, RegistryKeyField<T> registryKeyField, Class<?> holderElementsClass, Class<? extends Keyed> apiClass, String implClass) {
|
||||
this.registryKey = registryKey;
|
||||
this.registryKeyField = registryKeyField;
|
||||
this.registryElementClass = registryKeyField.elementClass();
|
||||
this.registryConstantClass = registryConstantClass;
|
||||
this.elementClass = registryKeyField.elementClass();
|
||||
this.holderElementsClass = holderElementsClass;
|
||||
this.apiClass = apiClass;
|
||||
this.implClass = implClass;
|
||||
}
|
||||
@ -112,7 +112,7 @@ public final class RegistryEntry<T> {
|
||||
return this.apiClass.getSimpleName();
|
||||
}
|
||||
|
||||
return this.registryElementClass.getSimpleName();
|
||||
return this.elementClass.getSimpleName();
|
||||
}
|
||||
|
||||
public boolean allowCustomKeys() {
|
||||
@ -122,18 +122,18 @@ public final class RegistryEntry<T> {
|
||||
private <TO> Map<ResourceKey<T>, TO> getFields(Map<ResourceKey<T>, TO> map, Function<Field, @Nullable TO> transform) {
|
||||
Registry<T> registry = this.registry();
|
||||
try {
|
||||
for (Field field : this.registryConstantClass.getDeclaredFields()) {
|
||||
if (!ResourceKey.class.isAssignableFrom(field.getType()) && !Holder.Reference.class.isAssignableFrom(field.getType()) && !this.registryElementClass.isAssignableFrom(field.getType())) {
|
||||
for (Field field : this.holderElementsClass.getDeclaredFields()) {
|
||||
if (!ResourceKey.class.isAssignableFrom(field.getType()) && !Holder.Reference.class.isAssignableFrom(field.getType()) && !this.elementClass.isAssignableFrom(field.getType())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ClassHelper.isStaticConstant(field, Modifier.PUBLIC)) {
|
||||
ResourceKey<T> key = null;
|
||||
if (this.registryElementClass.isAssignableFrom(field.getType())) {
|
||||
key = registry.getResourceKey(this.registryElementClass.cast(field.get(null))).orElseThrow();
|
||||
if (this.elementClass.isAssignableFrom(field.getType())) {
|
||||
key = registry.getResourceKey(this.elementClass.cast(field.get(null))).orElseThrow();
|
||||
} else {
|
||||
if (field.getGenericType() instanceof ParameterizedType complexType && complexType.getActualTypeArguments().length == 1 &&
|
||||
complexType.getActualTypeArguments()[0] == this.registryElementClass) {
|
||||
complexType.getActualTypeArguments()[0] == this.elementClass) {
|
||||
|
||||
if (Holder.Reference.class.isAssignableFrom(field.getType())) {
|
||||
key = ((Holder.Reference<T>) field.get(null)).key();
|
||||
@ -164,10 +164,6 @@ public final class RegistryEntry<T> {
|
||||
}
|
||||
|
||||
public <TO> Map<ResourceKey<T>, TO> getFields(Function<Field, @Nullable TO> transform) {
|
||||
if (this.registryConstantClass == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
return Collections.unmodifiableMap(this.getFields(new IdentityHashMap<>(), transform));
|
||||
}
|
||||
|
||||
|
@ -4,12 +4,11 @@ import com.google.common.base.Suppliers;
|
||||
import io.papermc.generator.Main;
|
||||
import io.papermc.generator.rewriter.utils.Annotations;
|
||||
import io.papermc.generator.utils.Formatting;
|
||||
import io.papermc.generator.utils.RegistryUtils;
|
||||
import io.papermc.generator.utils.experimental.FlagHolders;
|
||||
import io.papermc.generator.utils.experimental.ExperimentalCollector;
|
||||
import io.papermc.generator.utils.experimental.SingleFlagHolder;
|
||||
import io.papermc.typewriter.preset.EnumRewriter;
|
||||
import io.papermc.typewriter.preset.model.EnumValue;
|
||||
import java.util.Set;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
@ -19,13 +18,13 @@ import net.minecraft.world.flag.FeatureFlags;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import static io.papermc.typewriter.utils.Formatting.quoted;
|
||||
import static io.papermc.typewriter.util.Formatting.quoted;
|
||||
|
||||
@NullMarked
|
||||
public class EnumRegistryRewriter<T> extends EnumRewriter<Holder.Reference<T>> {
|
||||
|
||||
private final Registry<T> registry;
|
||||
private final Supplier<Set<ResourceKey<T>>> experimentalKeys;
|
||||
private final Supplier<Map<ResourceKey<T>, SingleFlagHolder>> experimentalKeys;
|
||||
private final boolean isFilteredRegistry;
|
||||
private final boolean hasKeyArgument;
|
||||
|
||||
@ -35,7 +34,7 @@ public class EnumRegistryRewriter<T> extends EnumRewriter<Holder.Reference<T>> {
|
||||
|
||||
protected EnumRegistryRewriter(ResourceKey<? extends Registry<T>> registryKey, boolean hasKeyArgument) {
|
||||
this.registry = Main.REGISTRY_ACCESS.lookupOrThrow(registryKey);
|
||||
this.experimentalKeys = Suppliers.memoize(() -> RegistryUtils.collectExperimentalDataDrivenKeys(this.registry));
|
||||
this.experimentalKeys = Suppliers.memoize(() -> ExperimentalCollector.collectDataDrivenElementIds(this.registry));
|
||||
this.isFilteredRegistry = FeatureElement.FILTERED_REGISTRIES.contains(registryKey);
|
||||
this.hasKeyArgument = hasKeyArgument;
|
||||
}
|
||||
@ -74,9 +73,7 @@ public class EnumRegistryRewriter<T> extends EnumRewriter<Holder.Reference<T>> {
|
||||
}
|
||||
} else {
|
||||
// data-driven registry
|
||||
if (this.experimentalKeys.get().contains(reference.key())) {
|
||||
return FlagHolders.NEXT_UPDATE;
|
||||
}
|
||||
return this.experimentalKeys.get().get(reference.key());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ import org.jspecify.annotations.NullMarked;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import static io.papermc.generator.rewriter.utils.Annotations.annotation;
|
||||
import static io.papermc.typewriter.utils.Formatting.quoted;
|
||||
import static io.papermc.typewriter.util.Formatting.quoted;
|
||||
|
||||
@NullMarked
|
||||
public class FeatureFlagRewriter extends SearchReplaceRewriter {
|
||||
|
@ -14,7 +14,7 @@ public class PaperFeatureFlagMapping extends SearchReplaceRewriter {
|
||||
|
||||
@Override
|
||||
protected void insert(SearchMetadata metadata, StringBuilder builder) {
|
||||
Iterator<ResourceLocation> flagIterator = FeatureFlags.REGISTRY.toNames(FeatureFlags.REGISTRY.allFlags()).stream().sorted(Formatting.alphabeticKeyOrder(name -> name.getPath())).iterator();
|
||||
Iterator<ResourceLocation> flagIterator = FeatureFlags.REGISTRY.toNames(FeatureFlags.REGISTRY.allFlags()).stream().sorted(Formatting.alphabeticKeyOrder(ResourceLocation::getPath)).iterator();
|
||||
|
||||
while (flagIterator.hasNext()) {
|
||||
ResourceLocation name = flagIterator.next();
|
||||
|
@ -6,15 +6,14 @@ import com.mojang.logging.LogUtils;
|
||||
import io.papermc.generator.Main;
|
||||
import io.papermc.generator.rewriter.utils.Annotations;
|
||||
import io.papermc.generator.utils.Formatting;
|
||||
import io.papermc.generator.utils.RegistryUtils;
|
||||
import io.papermc.generator.utils.experimental.FlagHolders;
|
||||
import io.papermc.generator.utils.experimental.ExperimentalCollector;
|
||||
import io.papermc.generator.utils.experimental.SingleFlagHolder;
|
||||
import io.papermc.typewriter.ClassNamed;
|
||||
import io.papermc.typewriter.SourceFile;
|
||||
import io.papermc.typewriter.replace.SearchMetadata;
|
||||
import io.papermc.typewriter.replace.SearchReplaceRewriter;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
@ -26,7 +25,7 @@ import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import static io.papermc.typewriter.utils.Formatting.quoted;
|
||||
import static io.papermc.typewriter.util.Formatting.quoted;
|
||||
import static javax.lang.model.element.Modifier.FINAL;
|
||||
import static javax.lang.model.element.Modifier.PUBLIC;
|
||||
import static javax.lang.model.element.Modifier.STATIC;
|
||||
@ -37,7 +36,7 @@ public class RegistryFieldRewriter<T> extends SearchReplaceRewriter {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
private final Registry<T> registry;
|
||||
private final Supplier<Set<ResourceKey<T>>> experimentalKeys;
|
||||
private final Supplier<Map<ResourceKey<T>, SingleFlagHolder>> experimentalKeys;
|
||||
private final boolean isFilteredRegistry;
|
||||
private final @Nullable String fetchMethod;
|
||||
|
||||
@ -45,7 +44,7 @@ public class RegistryFieldRewriter<T> extends SearchReplaceRewriter {
|
||||
|
||||
public RegistryFieldRewriter(ResourceKey<? extends Registry<T>> registryKey, @Nullable String fetchMethod) {
|
||||
this.registry = Main.REGISTRY_ACCESS.lookupOrThrow(registryKey);
|
||||
this.experimentalKeys = Suppliers.memoize(() -> RegistryUtils.collectExperimentalDataDrivenKeys(this.registry));
|
||||
this.experimentalKeys = Suppliers.memoize(() -> ExperimentalCollector.collectDataDrivenElementIds(this.registry));
|
||||
this.isFilteredRegistry = FeatureElement.FILTERED_REGISTRIES.contains(registryKey);
|
||||
this.fetchMethod = fetchMethod;
|
||||
}
|
||||
@ -127,9 +126,7 @@ public class RegistryFieldRewriter<T> extends SearchReplaceRewriter {
|
||||
}
|
||||
} else {
|
||||
// data-driven registry
|
||||
if (this.experimentalKeys.get().contains(reference.key())) {
|
||||
return FlagHolders.NEXT_UPDATE;
|
||||
}
|
||||
return this.experimentalKeys.get().get(reference.key());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ import org.bukkit.Tag;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import static io.papermc.typewriter.utils.Formatting.quoted;
|
||||
import static io.papermc.typewriter.util.Formatting.quoted;
|
||||
import static javax.lang.model.element.Modifier.FINAL;
|
||||
import static javax.lang.model.element.Modifier.PUBLIC;
|
||||
import static javax.lang.model.element.Modifier.STATIC;
|
||||
|
@ -21,7 +21,7 @@ import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
import static io.papermc.typewriter.utils.Formatting.quoted;
|
||||
import static io.papermc.typewriter.util.Formatting.quoted;
|
||||
|
||||
@NullMarked
|
||||
public class TagRewriter extends SearchReplaceRewriter {
|
||||
|
@ -2,7 +2,7 @@ package io.papermc.generator.rewriter.types.simple;
|
||||
|
||||
import io.papermc.generator.rewriter.types.registry.RegistryFieldRewriter;
|
||||
import io.papermc.generator.utils.BlockStateMapping;
|
||||
import io.papermc.typewriter.utils.ClassHelper;
|
||||
import io.papermc.typewriter.util.ClassHelper;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
@ -20,7 +20,7 @@ import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
|
||||
import static io.papermc.typewriter.utils.Formatting.quoted;
|
||||
import static io.papermc.typewriter.util.Formatting.quoted;
|
||||
|
||||
public class EntityTypeRewriter extends EnumRegistryRewriter<EntityType<?>> {
|
||||
|
||||
@ -146,11 +146,11 @@ public class EntityTypeRewriter extends EnumRegistryRewriter<EntityType<?>> {
|
||||
@Override
|
||||
protected EnumValue.Builder rewriteEnumValue(Holder.Reference<EntityType<?>> reference) {
|
||||
String path = reference.key().location().getPath();
|
||||
List<String> arguments = Util.make(new ArrayList<>(), args -> {
|
||||
args.add(quoted(path));
|
||||
args.add(toBukkitClass(reference).concat(".class"));
|
||||
args.add(Integer.toString(LEGACY_ID.getOrDefault(reference.value(), -1)));
|
||||
});
|
||||
List<String> arguments = new ArrayList<>(4);
|
||||
arguments.add(quoted(path));
|
||||
arguments.add(toBukkitClass(reference).concat(".class"));
|
||||
arguments.add(Integer.toString(LEGACY_ID.getOrDefault(reference.value(), -1)));
|
||||
|
||||
if (!reference.value().canSummon()) {
|
||||
arguments.add(Boolean.FALSE.toString());
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package io.papermc.generator.rewriter.types.simple;
|
||||
|
||||
import io.papermc.generator.rewriter.types.registry.RegistryFieldRewriter;
|
||||
import io.papermc.typewriter.utils.ClassHelper;
|
||||
import io.papermc.typewriter.util.ClassHelper;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.world.item.Item;
|
||||
|
@ -25,7 +25,7 @@ import org.bukkit.Location;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
|
||||
import static io.papermc.typewriter.utils.Formatting.quoted;
|
||||
import static io.papermc.typewriter.util.Formatting.quoted;
|
||||
|
||||
public class MemoryKeyRewriter extends RegistryFieldRewriter<MemoryModuleType<?>> {
|
||||
|
||||
|
@ -22,7 +22,7 @@ import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import org.bukkit.Statistic;
|
||||
|
||||
import static io.papermc.typewriter.utils.Formatting.quoted;
|
||||
import static io.papermc.typewriter.util.Formatting.quoted;
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public class StatisticRewriter {
|
||||
@ -59,7 +59,8 @@ public class StatisticRewriter {
|
||||
.put("INTERACT_WITH_FURNACE", "FURNACE_INTERACTION")
|
||||
.put("INTERACT_WITH_CRAFTING_TABLE", "CRAFTING_TABLE_INTERACTION")
|
||||
.put("OPEN_CHEST", "CHEST_OPENED")
|
||||
.put("OPEN_SHULKER_BOX", "SHULKER_BOX_OPENED").build();
|
||||
.put("OPEN_SHULKER_BOX", "SHULKER_BOX_OPENED")
|
||||
.build();
|
||||
|
||||
public static class Custom extends EnumRegistryRewriter<ResourceLocation> {
|
||||
|
||||
|
@ -3,13 +3,11 @@ package io.papermc.generator.rewriter.types.simple;
|
||||
import io.papermc.generator.rewriter.types.registry.RegistryFieldRewriter;
|
||||
import io.papermc.generator.utils.Formatting;
|
||||
import io.papermc.typewriter.parser.Lexer;
|
||||
import io.papermc.typewriter.parser.exception.ParserException;
|
||||
import io.papermc.typewriter.parser.token.CharSequenceBlockToken;
|
||||
import io.papermc.typewriter.parser.token.CharSequenceToken;
|
||||
import io.papermc.typewriter.parser.token.Token;
|
||||
import io.papermc.typewriter.parser.token.TokenType;
|
||||
import io.papermc.typewriter.parser.SequenceTokens;
|
||||
import io.papermc.typewriter.replace.SearchMetadata;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@ -20,7 +18,6 @@ import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.world.entity.npc.VillagerProfession;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
@ApiStatus.Experimental
|
||||
public class VillagerProfessionRewriter extends RegistryFieldRewriter<VillagerProfession> {
|
||||
@ -37,108 +34,82 @@ public class VillagerProfessionRewriter extends RegistryFieldRewriter<VillagerPr
|
||||
|
||||
private @MonotonicNonNull Map<String, List<String>> javadocsPerConstant;
|
||||
|
||||
private static class ConstantInfo {
|
||||
private @MonotonicNonNull String constantName;
|
||||
private @MonotonicNonNull List<String> javadocs;
|
||||
|
||||
public void constantName(String name) {
|
||||
this.constantName = name;
|
||||
}
|
||||
|
||||
public void javadocs(List<String> javadocs) {
|
||||
this.javadocs = javadocs;
|
||||
}
|
||||
|
||||
public String constantName() {
|
||||
return this.constantName;
|
||||
}
|
||||
|
||||
public List<String> javadocs() {
|
||||
return this.javadocs;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return this.constantName == null || this.javadocs == null;
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, List<String>> parseConstantJavadocs(String content) {
|
||||
Map<String, List<String>> map = new HashMap<>();
|
||||
|
||||
Lexer lex = new Lexer(content.toCharArray());
|
||||
String constantName = null;
|
||||
List<String> javadocs = null;
|
||||
boolean firstId = true;
|
||||
while (lex.canRead()) {
|
||||
Token token = lex.readToken();
|
||||
if (token.type() == TokenType.EOI) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (token.type() == TokenType.SECO) {
|
||||
if (constantName != null && javadocs != null) {
|
||||
map.put(constantName, new ArrayList<>(javadocs));
|
||||
}
|
||||
firstId = true;
|
||||
constantName = null;
|
||||
javadocs = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (FORMAT_TOKENS.contains(token.type())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (token.type() == TokenType.LPAREN && constantName != null) {
|
||||
if (!this.skipClosure(lex)) {
|
||||
return map;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (token.type() == TokenType.JAVADOC) {
|
||||
javadocs = ((CharSequenceBlockToken) token).value();
|
||||
} else if (token.type() == TokenType.PUBLIC || token.type() == TokenType.STATIC || token.type() == TokenType.FINAL) {
|
||||
// should check duplicate per statement
|
||||
continue; // ignore
|
||||
} else if (token.type() == TokenType.IDENTIFIER && constantName == null) {
|
||||
if (firstId) {
|
||||
Token nextToken = this.skipTypeName(lex);
|
||||
if (nextToken != null && nextToken.type() == TokenType.IDENTIFIER) {
|
||||
token = nextToken;
|
||||
}
|
||||
firstId = false;
|
||||
}
|
||||
|
||||
constantName = ((CharSequenceToken) token).value();
|
||||
}
|
||||
}
|
||||
SequenceTokens.wrap(lex, FORMAT_TOKENS)
|
||||
.group(action -> {
|
||||
ConstantInfo info = new ConstantInfo();
|
||||
action
|
||||
.map(TokenType.JAVADOC, token -> {
|
||||
info.javadocs(((CharSequenceBlockToken) token).value());
|
||||
}, SequenceTokens.TokenTask::asOptional)
|
||||
.skipQualifiedName(Set.of(TokenType.JAVADOC))
|
||||
.map(TokenType.IDENTIFIER, token -> {
|
||||
info.constantName(((CharSequenceToken) token).value());
|
||||
})
|
||||
.skip(TokenType.IDENTIFIER)
|
||||
.skipClosure(TokenType.LPAREN, TokenType.RPAREN, true)
|
||||
.map(TokenType.SECO, $ -> {
|
||||
if (!info.isEmpty()) {
|
||||
map.put(info.constantName(), info.javadocs());
|
||||
}
|
||||
});
|
||||
}, SequenceTokens.TokenTask::asRepeatable)
|
||||
.execute();
|
||||
/*
|
||||
for enums:
|
||||
SequenceTokens.wrap(lex, FORMAT_TOKENS)
|
||||
.group(action -> {
|
||||
ConstantInfo info = new ConstantInfo();
|
||||
action
|
||||
.map(TokenType.JAVADOC, token -> {
|
||||
info.javadocs(((CharSequenceBlockToken) token).value());
|
||||
}, SequenceTokens.TokenTask::asOptional)
|
||||
.map(TokenType.IDENTIFIER, token -> {
|
||||
info.constantName(((CharSequenceToken) token).value());
|
||||
})
|
||||
.skipClosure(TokenType.LPAREN, TokenType.RPAREN, true)
|
||||
.skipClosure(TokenType.LSCOPE, TokenType.RSCOPE, true)
|
||||
.mapMulti(Set.of(TokenType.CO, TokenType.SECO), $ -> {
|
||||
// this part will probably fail for the last entry for enum without end (,;)
|
||||
if (!info.isEmpty()) {
|
||||
map.put(info.constantName(), info.javadocs());
|
||||
}
|
||||
});
|
||||
}, SequenceTokens.TokenTask::asRepeatable)
|
||||
.execute();
|
||||
*/
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
private boolean skipClosure(Lexer lex) {
|
||||
int parenDepth = 1;
|
||||
while (lex.canRead()) {
|
||||
Token nestedToken = lex.readToken();
|
||||
if (nestedToken.type() == TokenType.EOI) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (nestedToken.type() == TokenType.LPAREN) {
|
||||
parenDepth++;
|
||||
} else if (nestedToken.type() == TokenType.RPAREN) {
|
||||
parenDepth--;
|
||||
}
|
||||
|
||||
if (parenDepth == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (parenDepth < 0) {
|
||||
throw new ParserException("Unbalanced parenthesis", nestedToken);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private @Nullable Token skipTypeName(Lexer lex) {
|
||||
boolean expectDot = true;
|
||||
while (lex.canRead()) {
|
||||
Token token = lex.readToken();
|
||||
if (token.type() == TokenType.EOI) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (FORMAT_TOKENS.contains(token.type()) || token.type() == TokenType.JAVADOC) {
|
||||
continue; // ignore intrusive comments inside the name
|
||||
}
|
||||
|
||||
if (token.type() == (expectDot ? TokenType.DOT : TokenType.IDENTIFIER)) {
|
||||
expectDot = !expectDot;
|
||||
} else {
|
||||
return token;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void insert(SearchMetadata metadata, StringBuilder builder) {
|
||||
this.javadocsPerConstant = parseConstantJavadocs(metadata.replacedContent());
|
||||
|
@ -2,7 +2,7 @@ package io.papermc.generator.rewriter.utils;
|
||||
|
||||
import io.papermc.generator.utils.experimental.SingleFlagHolder;
|
||||
import io.papermc.typewriter.context.ImportCollector;
|
||||
import io.papermc.typewriter.utils.ClassHelper;
|
||||
import io.papermc.typewriter.util.ClassHelper;
|
||||
import java.lang.annotation.Annotation;
|
||||
import org.bukkit.MinecraftExperimental;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
@ -10,14 +10,14 @@ import org.slf4j.Logger;
|
||||
import static javax.lang.model.element.Modifier.PUBLIC;
|
||||
|
||||
@NullMarked
|
||||
public abstract class StructuredGenerator<T> extends SimpleGenerator {
|
||||
public abstract class OverriddenClassGenerator<T> extends SimpleGenerator {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
protected final Class<? extends T> baseClass;
|
||||
protected boolean printWarningOnMissingOverride;
|
||||
|
||||
protected StructuredGenerator(Class<T> baseClass, String className, String packageName) {
|
||||
protected OverriddenClassGenerator(Class<T> baseClass, String className, String packageName) {
|
||||
super(className, packageName);
|
||||
this.baseClass = baseClass;
|
||||
}
|
@ -8,7 +8,7 @@ import com.squareup.javapoet.FieldSpec;
|
||||
import com.squareup.javapoet.MethodSpec;
|
||||
import com.squareup.javapoet.ParameterSpec;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import io.papermc.generator.types.StructuredGenerator;
|
||||
import io.papermc.generator.types.OverriddenClassGenerator;
|
||||
import io.papermc.generator.types.Types;
|
||||
import io.papermc.generator.types.craftblockdata.property.PropertyMaker;
|
||||
import io.papermc.generator.types.craftblockdata.property.PropertyWriter;
|
||||
@ -46,7 +46,7 @@ import static javax.lang.model.element.Modifier.PUBLIC;
|
||||
import static javax.lang.model.element.Modifier.STATIC;
|
||||
|
||||
@NullMarked
|
||||
public class CraftBlockDataGenerator<T extends BlockData> extends StructuredGenerator<T> {
|
||||
public class CraftBlockDataGenerator<T extends BlockData> extends OverriddenClassGenerator<T> {
|
||||
|
||||
private final Class<? extends Block> blockClass;
|
||||
private final BlockStateMapping.BlockData blockData;
|
||||
@ -66,7 +66,7 @@ public class CraftBlockDataGenerator<T extends BlockData> extends StructuredGene
|
||||
.put(BlockStateProperties.EYE, keywordGet("has"))
|
||||
.put(BlockStateProperties.BERRIES, keywordGet("has")) // spigot method rename
|
||||
// data holder keywords is only needed for the first property they hold
|
||||
.put(ChiseledBookShelfBlock.SLOT_OCCUPIED_PROPERTIES.get(0), keywordGet("is"))
|
||||
.put(ChiseledBookShelfBlock.SLOT_OCCUPIED_PROPERTIES.getFirst(), keywordGet("is"))
|
||||
.build();
|
||||
|
||||
private static final Map<Property<?>, BiConsumer<ParameterSpec, MethodSpec.Builder>> SETTER_PRECONDITIONS = Map.of(
|
||||
|
@ -3,7 +3,7 @@ package io.papermc.generator.types.craftblockdata.property;
|
||||
import com.squareup.javapoet.FieldSpec;
|
||||
import com.squareup.javapoet.MethodSpec;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import io.papermc.generator.types.StructuredGenerator;
|
||||
import io.papermc.generator.types.craftblockdata.CraftBlockDataGenerator;
|
||||
import io.papermc.generator.types.craftblockdata.property.converter.Converters;
|
||||
import io.papermc.generator.utils.NamingManager;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
@ -18,7 +18,7 @@ public class IntegerPropertyWriter extends PropertyWriter<Integer> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addExtras(TypeSpec.Builder builder, FieldSpec field, StructuredGenerator<?> generator, NamingManager naming) {
|
||||
public void addExtras(TypeSpec.Builder builder, FieldSpec field, CraftBlockDataGenerator<?> generator, NamingManager naming) {
|
||||
if (Converters.has(this.property)) {
|
||||
return;
|
||||
}
|
||||
|
@ -1,15 +1,12 @@
|
||||
package io.papermc.generator.types.craftblockdata.property;
|
||||
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.primitives.Primitives;
|
||||
import com.squareup.javapoet.FieldSpec;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import io.papermc.generator.types.StructuredGenerator;
|
||||
import io.papermc.generator.types.craftblockdata.property.appender.AppenderBase;
|
||||
import io.papermc.generator.types.craftblockdata.property.appender.EnumValuesAppender;
|
||||
import io.papermc.generator.types.craftblockdata.property.appender.PropertyAppender;
|
||||
import io.papermc.generator.types.craftblockdata.CraftBlockDataGenerator;
|
||||
import io.papermc.generator.types.craftblockdata.property.appender.PropertyAppenders;
|
||||
import io.papermc.generator.utils.BlockStateMapping;
|
||||
import io.papermc.generator.utils.NamingManager;
|
||||
import it.unimi.dsi.fastutil.Pair;
|
||||
@ -20,9 +17,6 @@ import java.util.function.Supplier;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.level.block.state.properties.Property;
|
||||
import org.bukkit.Axis;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.Rail;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
@NullMarked
|
||||
@ -64,30 +58,9 @@ public class PropertyWriter<T extends Comparable<T>> implements PropertyMaker {
|
||||
return "this.get(%s)";
|
||||
}
|
||||
|
||||
private static final Map<Property<?>, AppenderBase> APPENDERS;
|
||||
private static final ImmutableMap.Builder<Property<?>, AppenderBase> builder = ImmutableMap.builder();
|
||||
|
||||
static {
|
||||
register(new EnumValuesAppender<>(BlockStateProperties.AXIS, Axis.class, "getAxes"));
|
||||
register(new EnumValuesAppender<>(BlockStateProperties.HORIZONTAL_AXIS, Axis.class, "getAxes"));
|
||||
register(new EnumValuesAppender<>(BlockStateProperties.FACING, BlockFace.class, "getFaces"));
|
||||
register(new EnumValuesAppender<>(BlockStateProperties.HORIZONTAL_FACING, BlockFace.class, "getFaces"));
|
||||
register(new EnumValuesAppender<>(BlockStateProperties.FACING_HOPPER, BlockFace.class, "getFaces"));
|
||||
register(new EnumValuesAppender<>(BlockStateProperties.RAIL_SHAPE, Rail.Shape.class, "getShapes"));
|
||||
register(new EnumValuesAppender<>(BlockStateProperties.RAIL_SHAPE_STRAIGHT, Rail.Shape.class, "getShapes"));
|
||||
register(new EnumValuesAppender<>(BlockStateProperties.VERTICAL_DIRECTION, BlockFace.class, "getVerticalDirections"));
|
||||
APPENDERS = builder.build();
|
||||
}
|
||||
|
||||
private static void register(PropertyAppender<? extends Comparable<?>, ?> converter) {
|
||||
builder.put(converter.getProperty(), converter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addExtras(TypeSpec.Builder builder, FieldSpec field, StructuredGenerator<?> generator, NamingManager naming) {
|
||||
if (APPENDERS.containsKey(this.property)) {
|
||||
APPENDERS.get(this.property).addExtras(builder, field, generator, naming);
|
||||
}
|
||||
public void addExtras(TypeSpec.Builder builder, FieldSpec field, CraftBlockDataGenerator<?> generator, NamingManager naming) {
|
||||
PropertyAppenders.ifPresent(this.property, appender -> appender.addExtras(builder, field, generator, naming));
|
||||
}
|
||||
|
||||
public static Pair<Class<?>, String> referenceField(Class<? extends Block> from, Property<?> property, Map<Property<?>, Field> fields) {
|
||||
|
@ -2,12 +2,12 @@ package io.papermc.generator.types.craftblockdata.property.appender;
|
||||
|
||||
import com.squareup.javapoet.FieldSpec;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import io.papermc.generator.types.StructuredGenerator;
|
||||
import io.papermc.generator.types.craftblockdata.CraftBlockDataGenerator;
|
||||
import io.papermc.generator.utils.NamingManager;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
@NullMarked
|
||||
public interface AppenderBase {
|
||||
|
||||
void addExtras(TypeSpec.Builder builder, FieldSpec field, StructuredGenerator<?> generator, NamingManager naming);
|
||||
void addExtras(TypeSpec.Builder builder, FieldSpec field, CraftBlockDataGenerator<?> generator, NamingManager naming);
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import com.squareup.javapoet.FieldSpec;
|
||||
import com.squareup.javapoet.MethodSpec;
|
||||
import com.squareup.javapoet.ParameterizedTypeName;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import io.papermc.generator.types.StructuredGenerator;
|
||||
import io.papermc.generator.types.craftblockdata.CraftBlockDataGenerator;
|
||||
import io.papermc.generator.utils.NamingManager;
|
||||
import java.util.Set;
|
||||
import net.minecraft.util.StringRepresentable;
|
||||
@ -35,7 +35,7 @@ public class EnumValuesAppender<T extends Enum<T> & StringRepresentable, A exten
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addExtras(TypeSpec.Builder builder, FieldSpec field, StructuredGenerator<?> generator, NamingManager naming) {
|
||||
public void addExtras(TypeSpec.Builder builder, FieldSpec field, CraftBlockDataGenerator<?> generator, NamingManager naming) {
|
||||
MethodSpec.Builder methodBuilder = generator.createMethod(this.methodName);
|
||||
methodBuilder.addStatement("return this.getValues($N, $T.class)", field, this.apiType);
|
||||
methodBuilder.returns(ParameterizedTypeName.get(Set.class, this.apiType));
|
||||
|
@ -0,0 +1,33 @@
|
||||
package io.papermc.generator.types.craftblockdata.property.appender;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.level.block.state.properties.Property;
|
||||
import org.bukkit.Axis;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.Rail;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
@NullMarked
|
||||
public final class PropertyAppenders {
|
||||
|
||||
private static final Map<Property<?>, AppenderBase> APPENDERS = Stream.of(
|
||||
new EnumValuesAppender<>(BlockStateProperties.AXIS, Axis.class, "getAxes"),
|
||||
new EnumValuesAppender<>(BlockStateProperties.HORIZONTAL_AXIS, Axis.class, "getAxes"),
|
||||
new EnumValuesAppender<>(BlockStateProperties.FACING, BlockFace.class, "getFaces"),
|
||||
new EnumValuesAppender<>(BlockStateProperties.HORIZONTAL_FACING, BlockFace.class, "getFaces"),
|
||||
new EnumValuesAppender<>(BlockStateProperties.FACING_HOPPER, BlockFace.class, "getFaces"),
|
||||
new EnumValuesAppender<>(BlockStateProperties.RAIL_SHAPE, Rail.Shape.class, "getShapes"),
|
||||
new EnumValuesAppender<>(BlockStateProperties.RAIL_SHAPE_STRAIGHT, Rail.Shape.class, "getShapes"),
|
||||
new EnumValuesAppender<>(BlockStateProperties.VERTICAL_DIRECTION, BlockFace.class, "getVerticalDirections")
|
||||
).collect(Collectors.toUnmodifiableMap(PropertyAppender::getProperty, key -> key));
|
||||
|
||||
public static void ifPresent(Property<?> property, Consumer<AppenderBase> callback) {
|
||||
if (APPENDERS.containsKey(property)) {
|
||||
callback.accept(APPENDERS.get(property));
|
||||
}
|
||||
}
|
||||
}
|
@ -8,5 +8,6 @@ public interface Converter<T extends Comparable<T>, A> extends ConverterBase {
|
||||
|
||||
Property<T> getProperty();
|
||||
|
||||
@Override
|
||||
Class<A> getApiType();
|
||||
}
|
||||
|
@ -1,22 +1,19 @@
|
||||
package io.papermc.generator.types.craftblockdata.property.converter;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import io.papermc.generator.types.craftblockdata.property.PropertyMaker;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import net.minecraft.world.level.block.state.properties.Property;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
@NullMarked
|
||||
public final class Converters {
|
||||
|
||||
private static final Map<Property<?>, ConverterBase> CONVERTERS;
|
||||
private static final ImmutableMap.Builder<Property<?>, ConverterBase> builder = ImmutableMap.builder();
|
||||
|
||||
static {
|
||||
register(new RotationConverter());
|
||||
register(new NoteConverter());
|
||||
CONVERTERS = builder.build();
|
||||
}
|
||||
private static final Map<Property<?>, ConverterBase> CONVERTERS = Stream.of(
|
||||
new RotationConverter(),
|
||||
new NoteConverter()
|
||||
).collect(Collectors.toUnmodifiableMap(Converter::getProperty, key -> key));
|
||||
|
||||
public static ConverterBase getOrDefault(Property<?> property, PropertyMaker maker) {
|
||||
return CONVERTERS.getOrDefault(property, maker);
|
||||
@ -25,8 +22,4 @@ public final class Converters {
|
||||
public static boolean has(Property<?> property) {
|
||||
return CONVERTERS.containsKey(property);
|
||||
}
|
||||
|
||||
private static void register(Converter<? extends Comparable<?>, ?> converter) {
|
||||
builder.put(converter.getProperty(), converter);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
package io.papermc.generator.types.craftblockdata.property.holder;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.squareup.javapoet.ClassName;
|
||||
import com.squareup.javapoet.CodeBlock;
|
||||
import com.squareup.javapoet.FieldSpec;
|
||||
@ -9,13 +7,10 @@ import com.squareup.javapoet.ParameterSpec;
|
||||
import com.squareup.javapoet.ParameterizedTypeName;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import io.papermc.generator.types.StructuredGenerator;
|
||||
import io.papermc.generator.types.Types;
|
||||
import io.papermc.generator.types.craftblockdata.CraftBlockDataGenerator;
|
||||
import io.papermc.generator.types.craftblockdata.property.converter.ConverterBase;
|
||||
import io.papermc.generator.types.craftblockdata.property.holder.appender.ArrayAppender;
|
||||
import io.papermc.generator.types.craftblockdata.property.holder.appender.DataAppender;
|
||||
import io.papermc.generator.types.craftblockdata.property.holder.appender.ListAppender;
|
||||
import io.papermc.generator.types.craftblockdata.property.holder.appender.MapAppender;
|
||||
import io.papermc.generator.types.craftblockdata.property.holder.appender.DataAppenders;
|
||||
import io.papermc.generator.utils.BlockStateMapping;
|
||||
import io.papermc.generator.utils.ClassHelper;
|
||||
import io.papermc.generator.utils.CommonVariable;
|
||||
@ -160,24 +155,8 @@ public class DataPropertyWriter extends DataPropertyWriterBase {
|
||||
return name;
|
||||
}
|
||||
|
||||
private static final Map<DataHolderType, DataAppender> APPENDERS;
|
||||
private static final ImmutableMap.Builder<DataHolderType, DataAppender> builder = ImmutableMap.builder();
|
||||
|
||||
static {
|
||||
register(new ArrayAppender());
|
||||
register(new ListAppender());
|
||||
register(new MapAppender());
|
||||
APPENDERS = Maps.immutableEnumMap(builder.build());
|
||||
}
|
||||
|
||||
private static void register(DataAppender converter) {
|
||||
builder.put(converter.getType(), converter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addExtras(TypeSpec.Builder builder, FieldSpec field, ParameterSpec indexParameter, ConverterBase childConverter, StructuredGenerator<?> generator, NamingManager naming) {
|
||||
if (APPENDERS.containsKey(this.type)) {
|
||||
APPENDERS.get(this.type).addExtras(builder, field, indexParameter, childConverter, generator, naming);
|
||||
}
|
||||
public void addExtras(TypeSpec.Builder builder, FieldSpec field, ParameterSpec indexParameter, ConverterBase childConverter, CraftBlockDataGenerator<?> generator, NamingManager naming) {
|
||||
DataAppenders.ifPresent(this.type, appender -> appender.addExtras(builder, field, indexParameter, childConverter, generator, naming));
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import com.squareup.javapoet.ParameterSpec;
|
||||
import com.squareup.javapoet.ParameterizedTypeName;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import io.papermc.generator.types.StructuredGenerator;
|
||||
import io.papermc.generator.types.craftblockdata.CraftBlockDataGenerator;
|
||||
import io.papermc.generator.types.craftblockdata.property.converter.ConverterBase;
|
||||
import io.papermc.generator.utils.BlockStateMapping;
|
||||
import io.papermc.generator.utils.NamingManager;
|
||||
@ -93,7 +93,7 @@ public class VirtualDataPropertyWriter extends DataPropertyWriterBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addExtras(TypeSpec.Builder builder, FieldSpec field, ParameterSpec indexParameter, ConverterBase converter, StructuredGenerator<?> generator, NamingManager naming) {
|
||||
public void addExtras(TypeSpec.Builder builder, FieldSpec field, ParameterSpec indexParameter, ConverterBase converter, CraftBlockDataGenerator<?> generator, NamingManager naming) {
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import com.squareup.javapoet.MethodSpec;
|
||||
import com.squareup.javapoet.ParameterSpec;
|
||||
import com.squareup.javapoet.ParameterizedTypeName;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import io.papermc.generator.types.StructuredGenerator;
|
||||
import io.papermc.generator.types.craftblockdata.CraftBlockDataGenerator;
|
||||
import io.papermc.generator.types.craftblockdata.property.converter.ConverterBase;
|
||||
import io.papermc.generator.types.craftblockdata.property.holder.DataHolderType;
|
||||
import io.papermc.generator.utils.CommonVariable;
|
||||
@ -23,7 +23,7 @@ public class ArrayAppender implements DataAppender {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addExtras(TypeSpec.Builder builder, FieldSpec field, ParameterSpec indexParameter, ConverterBase childConverter, StructuredGenerator<?> generator, NamingManager naming) {
|
||||
public void addExtras(TypeSpec.Builder builder, FieldSpec field, ParameterSpec indexParameter, ConverterBase childConverter, CraftBlockDataGenerator<?> generator, NamingManager naming) {
|
||||
if (childConverter.getApiType() == Boolean.TYPE) {
|
||||
String collectVarName = naming.getVariableNameWrapper().post("s").concat();
|
||||
MethodSpec.Builder methodBuilder = generator.createMethod(naming.getMethodNameWrapper().post("s").concat());
|
||||
|
@ -3,7 +3,7 @@ package io.papermc.generator.types.craftblockdata.property.holder.appender;
|
||||
import com.squareup.javapoet.FieldSpec;
|
||||
import com.squareup.javapoet.ParameterSpec;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import io.papermc.generator.types.StructuredGenerator;
|
||||
import io.papermc.generator.types.craftblockdata.CraftBlockDataGenerator;
|
||||
import io.papermc.generator.types.craftblockdata.property.converter.ConverterBase;
|
||||
import io.papermc.generator.types.craftblockdata.property.holder.DataHolderType;
|
||||
import io.papermc.generator.utils.NamingManager;
|
||||
@ -14,5 +14,5 @@ public interface DataAppender {
|
||||
|
||||
DataHolderType getType();
|
||||
|
||||
void addExtras(TypeSpec.Builder builder, FieldSpec field, ParameterSpec indexParameter, ConverterBase converter, StructuredGenerator<?> generator, NamingManager naming);
|
||||
void addExtras(TypeSpec.Builder builder, FieldSpec field, ParameterSpec indexParameter, ConverterBase converter, CraftBlockDataGenerator<?> generator, NamingManager naming);
|
||||
}
|
||||
|
@ -0,0 +1,24 @@
|
||||
package io.papermc.generator.types.craftblockdata.property.holder.appender;
|
||||
|
||||
import io.papermc.generator.types.craftblockdata.property.holder.DataHolderType;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
@NullMarked
|
||||
public final class DataAppenders {
|
||||
|
||||
private static final Map<DataHolderType, DataAppender> APPENDERS = Stream.of(
|
||||
new ArrayAppender(),
|
||||
new ListAppender(),
|
||||
new MapAppender()
|
||||
).collect(Collectors.toUnmodifiableMap(DataAppender::getType, key -> key));
|
||||
|
||||
public static void ifPresent(DataHolderType type, Consumer<DataAppender> callback) {
|
||||
if (APPENDERS.containsKey(type)) {
|
||||
callback.accept(APPENDERS.get(type));
|
||||
}
|
||||
}
|
||||
}
|
@ -6,7 +6,7 @@ import com.squareup.javapoet.MethodSpec;
|
||||
import com.squareup.javapoet.ParameterSpec;
|
||||
import com.squareup.javapoet.ParameterizedTypeName;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import io.papermc.generator.types.StructuredGenerator;
|
||||
import io.papermc.generator.types.craftblockdata.CraftBlockDataGenerator;
|
||||
import io.papermc.generator.types.craftblockdata.property.converter.ConverterBase;
|
||||
import io.papermc.generator.types.craftblockdata.property.holder.DataHolderType;
|
||||
import io.papermc.generator.utils.CommonVariable;
|
||||
@ -28,7 +28,7 @@ public class ListAppender implements DataAppender {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addExtras(TypeSpec.Builder builder, FieldSpec field, ParameterSpec indexParameter, ConverterBase childConverter, StructuredGenerator<?> generator, NamingManager naming) {
|
||||
public void addExtras(TypeSpec.Builder builder, FieldSpec field, ParameterSpec indexParameter, ConverterBase childConverter, CraftBlockDataGenerator<?> generator, NamingManager naming) {
|
||||
NamingManager.NameWrapper methodName = NamingManager.NameWrapper.wrap("get", METHOD_BASE_RENAMES.getOrDefault(naming.getMethodBaseName(), naming.getMethodBaseName()));
|
||||
|
||||
if (childConverter.getApiType() == Boolean.TYPE) {
|
||||
|
@ -7,7 +7,7 @@ import com.squareup.javapoet.MethodSpec;
|
||||
import com.squareup.javapoet.ParameterSpec;
|
||||
import com.squareup.javapoet.ParameterizedTypeName;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import io.papermc.generator.types.StructuredGenerator;
|
||||
import io.papermc.generator.types.craftblockdata.CraftBlockDataGenerator;
|
||||
import io.papermc.generator.types.craftblockdata.property.converter.ConverterBase;
|
||||
import io.papermc.generator.types.craftblockdata.property.holder.DataHolderType;
|
||||
import io.papermc.generator.utils.CommonVariable;
|
||||
@ -27,7 +27,7 @@ public class MapAppender implements DataAppender {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addExtras(TypeSpec.Builder builder, FieldSpec field, ParameterSpec indexParameter, ConverterBase childConverter, StructuredGenerator<?> generator, NamingManager naming) {
|
||||
public void addExtras(TypeSpec.Builder builder, FieldSpec field, ParameterSpec indexParameter, ConverterBase childConverter, CraftBlockDataGenerator<?> generator, NamingManager naming) {
|
||||
if (childConverter.getApiType() == Boolean.TYPE) {
|
||||
String collectVarName = naming.getVariableNameWrapper().post("s").concat();
|
||||
MethodSpec.Builder methodBuilder = generator.createMethod(naming.getMethodNameWrapper().post("s").concat());
|
||||
|
@ -1,32 +1,25 @@
|
||||
package io.papermc.generator.types.craftblockdata.property.holder.converter;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Maps;
|
||||
import io.papermc.generator.types.craftblockdata.property.holder.DataHolderType;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
@NullMarked
|
||||
public final class DataConverters {
|
||||
|
||||
private static final ImmutableMap<DataHolderType, DataConverter> CONVERTERS;
|
||||
private static final ImmutableMap.Builder<DataHolderType, DataConverter> builder = ImmutableMap.builder();
|
||||
|
||||
static {
|
||||
register(new ArrayConverter());
|
||||
register(new ListConverter());
|
||||
register(new MapConverter());
|
||||
CONVERTERS = Maps.immutableEnumMap(builder.build());
|
||||
}
|
||||
private static final Map<DataHolderType, DataConverter> CONVERTERS = Stream.of(
|
||||
new ArrayConverter(),
|
||||
new ListConverter(),
|
||||
new MapConverter()
|
||||
).collect(Collectors.toUnmodifiableMap(DataConverter::getType, key -> key));
|
||||
|
||||
public static DataConverter getOrThrow(DataHolderType type) {
|
||||
DataConverter converter = CONVERTERS.get(type);
|
||||
if (converter == null) {
|
||||
throw new IllegalStateException("Cannot handle " + type);
|
||||
throw new IllegalStateException("Cannot handle data holder type: " + type);
|
||||
}
|
||||
return converter;
|
||||
}
|
||||
|
||||
private static void register(DataConverter converter) {
|
||||
builder.put(converter.getType(), converter);
|
||||
}
|
||||
}
|
||||
|
@ -15,9 +15,10 @@ import io.papermc.generator.types.SimpleGenerator;
|
||||
import io.papermc.generator.utils.Annotations;
|
||||
import io.papermc.generator.utils.Formatting;
|
||||
import io.papermc.generator.utils.Javadocs;
|
||||
import io.papermc.typewriter.utils.ClassHelper;
|
||||
import io.papermc.typewriter.util.ClassHelper;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
import net.minecraft.world.entity.ai.goal.Goal;
|
||||
import net.minecraft.world.entity.ai.goal.GoalSelector;
|
||||
import net.minecraft.world.entity.ai.goal.WrappedGoal;
|
||||
@ -64,17 +65,16 @@ public class MobGoalGenerator extends SimpleGenerator {
|
||||
classes = scanResult.getSubclasses(Goal.class.getName()).loadClasses(Goal.class);
|
||||
}
|
||||
|
||||
List<GoalKey<Mob>> vanillaGoals = classes.stream()
|
||||
Stream<GoalKey<Mob>> vanillaGoals = classes.stream()
|
||||
.filter(clazz -> !java.lang.reflect.Modifier.isAbstract(clazz.getModifiers()))
|
||||
.filter(clazz -> !clazz.isAnonymousClass() || ClassHelper.getTopLevelClass(clazz) != GoalSelector.class)
|
||||
.filter(clazz -> !WrappedGoal.class.equals(clazz)) // TODO - properly fix
|
||||
.map(MobGoalNames::getKey)
|
||||
.sorted(Comparator.<GoalKey<?>, String>comparing(o -> o.getEntityClass().getSimpleName())
|
||||
.thenComparing(vanillaGoalKey -> vanillaGoalKey.getNamespacedKey().getKey())
|
||||
)
|
||||
.toList();
|
||||
);
|
||||
|
||||
for (GoalKey<?> goalKey : vanillaGoals) {
|
||||
vanillaGoals.forEach(goalKey -> {
|
||||
String keyPath = goalKey.getNamespacedKey().getKey();
|
||||
String fieldName = Formatting.formatKeyAsField(keyPath);
|
||||
|
||||
@ -82,7 +82,7 @@ public class MobGoalGenerator extends SimpleGenerator {
|
||||
FieldSpec.Builder fieldBuilder = FieldSpec.builder(typedKey, fieldName, PUBLIC, STATIC, FINAL)
|
||||
.initializer("$N($S, $T.class)", createMethod.build(), keyPath, goalKey.getEntityClass());
|
||||
typeBuilder.addField(fieldBuilder.build());
|
||||
}
|
||||
});
|
||||
|
||||
return typeBuilder.addMethod(createMethod.build()).build();
|
||||
}
|
||||
|
@ -13,12 +13,11 @@ import io.papermc.generator.types.SimpleGenerator;
|
||||
import io.papermc.generator.utils.Annotations;
|
||||
import io.papermc.generator.utils.Formatting;
|
||||
import io.papermc.generator.utils.Javadocs;
|
||||
import io.papermc.generator.utils.RegistryUtils;
|
||||
import io.papermc.generator.utils.experimental.FlagHolders;
|
||||
import io.papermc.generator.utils.experimental.ExperimentalCollector;
|
||||
import io.papermc.generator.utils.experimental.SingleFlagHolder;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import io.papermc.paper.registry.TypedKey;
|
||||
import java.util.Set;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
import javax.lang.model.SourceVersion;
|
||||
import net.kyori.adventure.key.Key;
|
||||
@ -43,14 +42,14 @@ public class GeneratedKeyType<T> extends SimpleGenerator {
|
||||
|
||||
private final RegistryEntry<T> entry;
|
||||
private final Registry<T> registry;
|
||||
private final Supplier<Set<ResourceKey<T>>> experimentalKeys;
|
||||
private final Supplier<Map<ResourceKey<T>, SingleFlagHolder>> experimentalKeys;
|
||||
private final boolean isFilteredRegistry;
|
||||
|
||||
public GeneratedKeyType(String packageName, RegistryEntry<T> entry) {
|
||||
super(entry.keyClassName().concat("Keys"), packageName);
|
||||
this.entry = entry;
|
||||
this.registry = entry.registry();
|
||||
this.experimentalKeys = Suppliers.memoize(() -> RegistryUtils.collectExperimentalDataDrivenKeys(this.registry));
|
||||
this.experimentalKeys = Suppliers.memoize(() -> ExperimentalCollector.collectDataDrivenElementIds(this.registry));
|
||||
this.isFilteredRegistry = FeatureElement.FILTERED_REGISTRIES.contains(entry.registryKey());
|
||||
}
|
||||
|
||||
@ -124,7 +123,7 @@ public class GeneratedKeyType<T> extends SimpleGenerator {
|
||||
return builder.addStaticImport(Key.class, "key");
|
||||
}
|
||||
|
||||
public @Nullable SingleFlagHolder getRequiredFeature(Holder.Reference<T> reference) {
|
||||
protected @Nullable SingleFlagHolder getRequiredFeature(Holder.Reference<T> reference) {
|
||||
if (this.isFilteredRegistry) {
|
||||
// built-in registry
|
||||
FeatureElement element = (FeatureElement) reference.value();
|
||||
@ -133,9 +132,7 @@ public class GeneratedKeyType<T> extends SimpleGenerator {
|
||||
}
|
||||
} else {
|
||||
// data-driven registry
|
||||
if (this.experimentalKeys.get().contains(reference.key())) {
|
||||
return FlagHolders.NEXT_UPDATE;
|
||||
}
|
||||
return this.experimentalKeys.get().get(reference.key());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import net.minecraft.SharedConstants;
|
||||
import org.bukkit.MinecraftExperimental;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
@NullMarked
|
||||
public final class Annotations {
|
||||
@ -23,24 +22,6 @@ public final class Annotations {
|
||||
);
|
||||
}
|
||||
|
||||
public static AnnotationSpec deprecatedVersioned(@Nullable String version, boolean forRemoval) {
|
||||
AnnotationSpec.Builder annotationSpec = AnnotationSpec.builder(Deprecated.class);
|
||||
if (forRemoval) {
|
||||
annotationSpec.addMember("forRemoval", "$L", true);
|
||||
}
|
||||
if (version != null) {
|
||||
annotationSpec.addMember("since", "$S", version);
|
||||
}
|
||||
|
||||
return annotationSpec.build();
|
||||
}
|
||||
|
||||
public static AnnotationSpec scheduledRemoval(String version) {
|
||||
return AnnotationSpec.builder(ApiStatus.ScheduledForRemoval.class)
|
||||
.addMember("inVersion", "$S", version)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static AnnotationSpec suppressWarnings(String... values) {
|
||||
AnnotationSpec.Builder builder = AnnotationSpec.builder(SuppressWarnings.class);
|
||||
for (String value : values) {
|
||||
@ -53,12 +34,11 @@ public final class Annotations {
|
||||
public static final AnnotationSpec EXPERIMENTAL_API_ANNOTATION = AnnotationSpec.builder(ApiStatus.Experimental.class).build();
|
||||
public static final AnnotationSpec NULL_MARKED = AnnotationSpec.builder(NullMarked.class).build();
|
||||
public static final AnnotationSpec OVERRIDE = AnnotationSpec.builder(Override.class).build();
|
||||
private static final AnnotationSpec SUPPRESS_WARNINGS = suppressWarnings("unused", "SpellCheckingInspection");
|
||||
public static final AnnotationSpec GENERATED_FROM = AnnotationSpec.builder(GeneratedFrom.class)
|
||||
.addMember("value", "$S", SharedConstants.getCurrentVersion().getName())
|
||||
.build();
|
||||
public static final Iterable<AnnotationSpec> CLASS_HEADER = List.of(
|
||||
SUPPRESS_WARNINGS,
|
||||
suppressWarnings("unused", "SpellCheckingInspection"),
|
||||
NULL_MARKED,
|
||||
GENERATED_FROM
|
||||
);
|
||||
|
@ -59,7 +59,7 @@ public final class ClassHelper {
|
||||
return (field.getModifiers() & flags) == flags;
|
||||
}
|
||||
|
||||
public static <T> Class<? extends T> classOr(String className, Class<? extends T> defaultClass) {
|
||||
public static <T> @Nullable Class<? extends T> classOr(String className, @Nullable Class<? extends T> defaultClass) {
|
||||
try {
|
||||
return (Class<? extends T>) Class.forName(className);
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
|
@ -4,7 +4,6 @@ import java.util.Optional;
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
import java.util.Comparator;
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Pattern;
|
||||
@ -12,7 +11,6 @@ import java.util.stream.IntStream;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
@NullMarked
|
||||
@ -75,7 +73,7 @@ public final class Formatting {
|
||||
return newName;
|
||||
}
|
||||
|
||||
public static Comparator<String> ALPHABETIC_KEY_ORDER = alphabeticKeyOrder(path -> path);
|
||||
public static final Comparator<String> ALPHABETIC_KEY_ORDER = alphabeticKeyOrder(path -> path);
|
||||
|
||||
public static <T> Comparator<T> alphabeticKeyOrder(Function<T, String> mapper) {
|
||||
return (o1, o2) -> {
|
||||
|
@ -1,46 +0,0 @@
|
||||
package io.papermc.generator.utils;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import io.papermc.generator.utils.experimental.CollectingContext;
|
||||
import java.util.Collections;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistrySetBuilder;
|
||||
import net.minecraft.data.registries.VanillaRegistries;
|
||||
import net.minecraft.data.registries.WinterDropRegistries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
@NullMarked
|
||||
public class RegistryUtils {
|
||||
|
||||
private static final Map<ResourceKey<? extends Registry<?>>, RegistrySetBuilder.RegistryBootstrap<?>> VANILLA_REGISTRY_ENTRIES = VanillaRegistries.BUILDER.entries.stream()
|
||||
.collect(Collectors.toMap(RegistrySetBuilder.RegistryStub::key, RegistrySetBuilder.RegistryStub::bootstrap));
|
||||
|
||||
private static final Map<ResourceKey<? extends Registry<?>>, RegistrySetBuilder.RegistryBootstrap<?>> EXPERIMENTAL_REGISTRY_ENTRIES = WinterDropRegistries.BUILDER.entries.stream()
|
||||
.collect(Collectors.toMap(RegistrySetBuilder.RegistryStub::key, RegistrySetBuilder.RegistryStub::bootstrap)); // Update for Experimental API
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Set<ResourceKey<T>> collectExperimentalDataDrivenKeys(Registry<T> registry) {
|
||||
RegistrySetBuilder.@Nullable RegistryBootstrap<T> experimentalBootstrap = (RegistrySetBuilder.RegistryBootstrap<T>) EXPERIMENTAL_REGISTRY_ENTRIES.get(registry.key());
|
||||
if (experimentalBootstrap == null) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
Set<ResourceKey<T>> experimental = Collections.newSetFromMap(new IdentityHashMap<>());
|
||||
CollectingContext<T> experimentalCollector = new CollectingContext<>(experimental, registry);
|
||||
experimentalBootstrap.run(experimentalCollector);
|
||||
|
||||
RegistrySetBuilder.@Nullable RegistryBootstrap<T> vanillaBootstrap = (RegistrySetBuilder.RegistryBootstrap<T>) VANILLA_REGISTRY_ENTRIES.get(registry.key());
|
||||
if (vanillaBootstrap != null) {
|
||||
Set<ResourceKey<T>> vanilla = Collections.newSetFromMap(new IdentityHashMap<>());
|
||||
CollectingContext<T> vanillaCollector = new CollectingContext<>(vanilla, registry);
|
||||
vanillaBootstrap.run(vanillaCollector);
|
||||
return Sets.difference(experimental, vanilla);
|
||||
}
|
||||
return experimental;
|
||||
}
|
||||
}
|
@ -0,0 +1,134 @@
|
||||
package io.papermc.generator.utils.experimental;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import io.papermc.generator.Main;
|
||||
import io.papermc.generator.utils.Formatting;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.stream.Collectors;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.RegistrySetBuilder;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.data.registries.TradeRebalanceRegistries;
|
||||
import net.minecraft.data.registries.VanillaRegistries;
|
||||
import net.minecraft.data.registries.WinterDropRegistries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.server.packs.PackResources;
|
||||
import net.minecraft.server.packs.PackType;
|
||||
import net.minecraft.server.packs.repository.BuiltInPackSource;
|
||||
import net.minecraft.server.packs.resources.MultiPackResourceManager;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@NullMarked
|
||||
public final class ExperimentalCollector {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
private static final Map<ResourceKey<? extends Registry<?>>, RegistrySetBuilder.RegistryBootstrap<?>> VANILLA_REGISTRY_ENTRIES = VanillaRegistries.BUILDER.entries.stream()
|
||||
.collect(Collectors.toMap(RegistrySetBuilder.RegistryStub::key, RegistrySetBuilder.RegistryStub::bootstrap));
|
||||
|
||||
private static final Map<RegistrySetBuilder, SingleFlagHolder> EXPERIMENTAL_REGISTRY_FLAGS = Map.of(
|
||||
// Update for Experimental API
|
||||
WinterDropRegistries.BUILDER, FlagHolders.WINTER_DROP,
|
||||
TradeRebalanceRegistries.BUILDER, FlagHolders.TRADE_REBALANCE
|
||||
);
|
||||
|
||||
private static final Multimap<ResourceKey<? extends Registry<?>>, Map.Entry<SingleFlagHolder, RegistrySetBuilder.RegistryBootstrap<?>>> EXPERIMENTAL_REGISTRY_ENTRIES;
|
||||
static {
|
||||
EXPERIMENTAL_REGISTRY_ENTRIES = HashMultimap.create();
|
||||
for (Map.Entry<RegistrySetBuilder, SingleFlagHolder> entry : EXPERIMENTAL_REGISTRY_FLAGS.entrySet()) {
|
||||
for (RegistrySetBuilder.RegistryStub<?> stub : entry.getKey().entries) {
|
||||
EXPERIMENTAL_REGISTRY_ENTRIES.put(stub.key(), Map.entry(entry.getValue(), stub.bootstrap()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Map<ResourceKey<T>, SingleFlagHolder> collectDataDrivenElementIds(Registry<T> registry) {
|
||||
Collection<Map.Entry<SingleFlagHolder, RegistrySetBuilder.RegistryBootstrap<?>>> experimentalEntries = EXPERIMENTAL_REGISTRY_ENTRIES.get(registry.key());
|
||||
if (experimentalEntries.isEmpty()) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
Map<ResourceKey<T>, SingleFlagHolder> result = new IdentityHashMap<>();
|
||||
for (Map.Entry<SingleFlagHolder, RegistrySetBuilder.RegistryBootstrap<?>> experimentalEntry : experimentalEntries) {
|
||||
RegistrySetBuilder.RegistryBootstrap<T> experimentalBootstrap = (RegistrySetBuilder.RegistryBootstrap<T>) experimentalEntry.getValue();
|
||||
Set<ResourceKey<T>> experimental = Collections.newSetFromMap(new IdentityHashMap<>());
|
||||
CollectingContext<T> experimentalCollector = new CollectingContext<>(experimental, registry);
|
||||
experimentalBootstrap.run(experimentalCollector);
|
||||
result.putAll(experimental.stream().collect(Collectors.toMap(key -> key, key -> experimentalEntry.getKey())));
|
||||
}
|
||||
|
||||
RegistrySetBuilder.@Nullable RegistryBootstrap<T> vanillaBootstrap = (RegistrySetBuilder.RegistryBootstrap<T>) VANILLA_REGISTRY_ENTRIES.get(registry.key());
|
||||
if (vanillaBootstrap != null) {
|
||||
Set<ResourceKey<T>> vanilla = Collections.newSetFromMap(new IdentityHashMap<>());
|
||||
CollectingContext<T> vanillaCollector = new CollectingContext<>(vanilla, registry);
|
||||
vanillaBootstrap.run(vanillaCollector);
|
||||
result.keySet().removeAll(vanilla);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// collect all the tags by grabbing the json from the data-packs
|
||||
// another (probably) way is to hook into the data generator like the typed keys generator
|
||||
public static Map<TagKey<?>, String> collectTags(MultiPackResourceManager resourceManager) {
|
||||
Map<TagKey<?>, String> result = new IdentityHashMap<>();
|
||||
|
||||
// collect all vanilla tags
|
||||
Multimap<ResourceKey<? extends Registry<?>>, String> vanillaTags = HashMultimap.create();
|
||||
PackResources vanillaPack = resourceManager.listPacks()
|
||||
.filter(packResources -> packResources.packId().equals(BuiltInPackSource.VANILLA_ID))
|
||||
.findFirst()
|
||||
.orElseThrow();
|
||||
collectTagsFromPack(vanillaPack, (entry, path) -> vanillaTags.put(entry.key(), path));
|
||||
|
||||
// then distinct with other data-pack tags to know for sure newly created tags and so experimental one
|
||||
resourceManager.listPacks().forEach(pack -> {
|
||||
String packId = pack.packId();
|
||||
if (packId.equals(BuiltInPackSource.VANILLA_ID)) return;
|
||||
|
||||
collectTagsFromPack(pack, (entry, path) -> {
|
||||
if (vanillaTags.get(entry.key()).contains(path)) {
|
||||
return;
|
||||
}
|
||||
|
||||
result.put(entry.value().listTagIds()
|
||||
.filter(tagKey -> tagKey.location().getPath().equals(path))
|
||||
.findFirst()
|
||||
.orElseThrow(), packId);
|
||||
});
|
||||
});
|
||||
return Collections.unmodifiableMap(result);
|
||||
}
|
||||
|
||||
private static void collectTagsFromPack(PackResources pack, BiConsumer<RegistryAccess.RegistryEntry<?>, String> output) {
|
||||
Set<String> namespaces = pack.getNamespaces(PackType.SERVER_DATA);
|
||||
|
||||
for (String namespace : namespaces) {
|
||||
Main.REGISTRY_ACCESS.registries().forEach(entry -> {
|
||||
// this is probably expensive but can't find another way around and data-pack loader has similar logic
|
||||
// the issue is that registry key can have parent/key but tag key can also have parent/key so parsing become a mess
|
||||
// without having at least one of the two values
|
||||
String tagDir = Registries.tagsDirPath(entry.key());
|
||||
pack.listResources(PackType.SERVER_DATA, namespace, tagDir, (id, supplier) -> {
|
||||
Formatting.formatTagKey(tagDir, id.getPath()).ifPresentOrElse(path -> output.accept(entry, path), () -> {
|
||||
LOGGER.warn("Unable to parse the path: {}/{}/{}.json in the data-pack {} into a tag key", namespace, tagDir, id.getPath(), pack.packId());
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private ExperimentalCollector() {
|
||||
}
|
||||
}
|
@ -8,18 +8,17 @@ import net.minecraft.world.flag.FeatureFlag;
|
||||
import net.minecraft.world.flag.FeatureFlags;
|
||||
import org.bukkit.MinecraftExperimental;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
@NullMarked
|
||||
public class FlagHolders {
|
||||
|
||||
public static final @Nullable SingleFlagHolder NEXT_UPDATE = SingleFlagHolder.fromValue(FeatureFlags.WINTER_DROP)/*SingleFlagHolder.fromValue(FeatureFlags.UPDATE_1_22)*/;
|
||||
public static final SingleFlagHolder WINTER_DROP = SingleFlagHolder.fromValue(FeatureFlags.WINTER_DROP);
|
||||
public static final SingleFlagHolder TRADE_REBALANCE = SingleFlagHolder.fromValue(FeatureFlags.TRADE_REBALANCE);
|
||||
public static final SingleFlagHolder REDSTONE_EXPERIMENTS = SingleFlagHolder.fromValue(FeatureFlags.REDSTONE_EXPERIMENTS);
|
||||
public static final SingleFlagHolder MINECART_IMPROVEMENTS = SingleFlagHolder.fromValue(FeatureFlags.MINECART_IMPROVEMENTS);
|
||||
|
||||
static final Map<FeatureFlag, MinecraftExperimental.Requires> ANNOTATION_EQUIVALENT = Util.make(new HashMap<SingleFlagHolder, MinecraftExperimental.Requires>(), map -> {
|
||||
map.put(NEXT_UPDATE, MinecraftExperimental.Requires.WINTER_DROP); //map.put(NEXT_UPDATE, MinecraftExperimental.Requires.UPDATE_1_22);
|
||||
map.put(WINTER_DROP, MinecraftExperimental.Requires.WINTER_DROP);
|
||||
map.put(TRADE_REBALANCE, MinecraftExperimental.Requires.TRADE_REBALANCE);
|
||||
map.put(REDSTONE_EXPERIMENTS, MinecraftExperimental.Requires.REDSTONE_EXPERIMENTS);
|
||||
map.put(MINECART_IMPROVEMENTS, MinecraftExperimental.Requires.MINECART_IMPROVEMENTS);
|
||||
|
@ -42,7 +42,7 @@ public record SingleFlagHolder(FeatureFlag flag) implements FlagHolder { // todo
|
||||
public MinecraftExperimental.Requires asAnnotationMember() {
|
||||
MinecraftExperimental.Requires annotationMember = FlagHolders.ANNOTATION_EQUIVALENT.get(this.flag);
|
||||
if (annotationMember == null) {
|
||||
throw new UnsupportedOperationException("Don't know that feature flag : " + FEATURE_FLAG_NAME.get(this.flag));
|
||||
throw new UnsupportedOperationException("Don't know that feature flag: " + FEATURE_FLAG_NAME.get(this.flag));
|
||||
}
|
||||
return annotationMember;
|
||||
}
|
||||
|
@ -1,82 +0,0 @@
|
||||
package io.papermc.generator.utils.experimental;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import io.papermc.generator.Main;
|
||||
import io.papermc.generator.utils.Formatting;
|
||||
import java.util.Collections;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.server.packs.PackResources;
|
||||
import net.minecraft.server.packs.PackType;
|
||||
import net.minecraft.server.packs.repository.BuiltInPackSource;
|
||||
import net.minecraft.server.packs.resources.MultiPackResourceManager;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
// collect all the tags by grabbing the json from the data-packs
|
||||
// another (probably) way is to hook into the data generator like the typed keys generator
|
||||
@NullMarked
|
||||
public final class TagCollector {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
public static Map<TagKey<?>, String> grabExperimental(MultiPackResourceManager resourceManager) {
|
||||
Map<TagKey<?>, String> result = new IdentityHashMap<>();
|
||||
|
||||
// collect all vanilla tags
|
||||
Multimap<ResourceKey<? extends Registry<?>>, String> vanillaTags = HashMultimap.create();
|
||||
PackResources vanillaPack = resourceManager.listPacks()
|
||||
.filter(packResources -> packResources.packId().equals(BuiltInPackSource.VANILLA_ID))
|
||||
.findFirst()
|
||||
.orElseThrow();
|
||||
collectFromPack(vanillaPack, (entry, path) -> vanillaTags.put(entry.key(), path));
|
||||
|
||||
// then distinct with other data-pack tags to know for sure newly created tags and so experimental one
|
||||
resourceManager.listPacks().forEach(pack -> {
|
||||
String packId = pack.packId();
|
||||
if (packId.equals(BuiltInPackSource.VANILLA_ID)) return;
|
||||
|
||||
collectFromPack(pack, (entry, path) -> {
|
||||
if (vanillaTags.get(entry.key()).contains(path)) {
|
||||
return;
|
||||
}
|
||||
|
||||
result.put(entry.value().listTagIds()
|
||||
.filter(tagKey -> tagKey.location().getPath().equals(path))
|
||||
.findFirst()
|
||||
.orElseThrow(), packId);
|
||||
});
|
||||
});
|
||||
return Collections.unmodifiableMap(result);
|
||||
}
|
||||
|
||||
private static void collectFromPack(PackResources pack, BiConsumer<RegistryAccess.RegistryEntry<?>, String> output) {
|
||||
Set<String> namespaces = pack.getNamespaces(PackType.SERVER_DATA);
|
||||
|
||||
for (String namespace : namespaces) {
|
||||
Main.REGISTRY_ACCESS.registries().forEach(entry -> {
|
||||
// this is probably expensive but can't find another way around and data-pack loader has similar logic
|
||||
// the issue is that registry key can have parent/key (and custom folder too) but tag key can also have parent/key so parsing become a mess
|
||||
// without having at least one of the two values
|
||||
String tagDir = Registries.tagsDirPath(entry.key());
|
||||
pack.listResources(PackType.SERVER_DATA, namespace, tagDir, (id, supplier) -> {
|
||||
Formatting.formatTagKey(tagDir, id.getPath()).ifPresentOrElse(path -> output.accept(entry, path), () -> {
|
||||
LOGGER.warn("Unable to parse the path: {}/{}/{}.json in the data-pack {} into a tag key", namespace, tagDir, id.getPath(), pack.packId());
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private TagCollector() {
|
||||
}
|
||||
}
|
@ -1,23 +1,26 @@
|
||||
package io.papermc.generator;
|
||||
|
||||
import io.papermc.generator.utils.BlockStateMapping;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.server.Bootstrap;
|
||||
import net.minecraft.world.level.block.ChiseledBookShelfBlock;
|
||||
import net.minecraft.world.level.block.MossyCarpetBlock;
|
||||
import net.minecraft.world.level.block.PipeBlock;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.level.block.state.properties.EnumProperty;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
public class BlockStatePropertyTest {
|
||||
|
||||
private static Set<Class<? extends Comparable<?>>> ENUM_PROPERTY_VALUES;
|
||||
@ -49,24 +52,24 @@ public class BlockStatePropertyTest {
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// reference test
|
||||
// if renamed should change DataPropertyWriter#FIELD_TO_BASE_NAME
|
||||
var a = ChiseledBookShelfBlock.SLOT_OCCUPIED_PROPERTIES;
|
||||
var b = PipeBlock.PROPERTY_BY_DIRECTION;
|
||||
@Test
|
||||
public void testReferences() throws NoSuchFieldException, IllegalAccessException {
|
||||
// if renamed should change DataPropertyWriter#FIELD_TO_BASE_NAME/FIELD_TO_BASE_NAME_SPECIFICS
|
||||
MethodHandles.Lookup lookup = MethodHandles.lookup();
|
||||
lookup.findStaticVarHandle(ChiseledBookShelfBlock.class, "SLOT_OCCUPIED_PROPERTIES", List.class);
|
||||
lookup.findStaticVarHandle(PipeBlock.class, "PROPERTY_BY_DIRECTION", Map.class);
|
||||
MethodHandles.privateLookupIn(MossyCarpetBlock.class, lookup).findStaticVarHandle(MossyCarpetBlock.class, "PROPERTY_BY_DIRECTION", Map.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBridge() {
|
||||
Set<String> missingApisEquivalent = new HashSet<>();
|
||||
Set<String> missingApiEquivalents = new HashSet<>();
|
||||
for (Class<? extends Comparable<?>> value : ENUM_PROPERTY_VALUES) {
|
||||
if (!BlockStateMapping.ENUM_BRIDGE.containsKey(value)) {
|
||||
missingApisEquivalent.add(value.getCanonicalName());
|
||||
missingApiEquivalents.add(value.getCanonicalName());
|
||||
}
|
||||
}
|
||||
|
||||
if (!missingApisEquivalent.isEmpty()) {
|
||||
fail("Missing some api equivalent in the blockstate mapping enum bridge (BlockStateMapping#ENUM_BRIDGE) : " + String.join(", ", missingApisEquivalent));
|
||||
}
|
||||
Assertions.assertTrue(missingApiEquivalents.isEmpty(), () -> "Missing some api equivalent in the block state mapping enum bridge (BlockStateMapping#ENUM_BRIDGE) : " + String.join(", ", missingApiEquivalents));
|
||||
}
|
||||
}
|
||||
|
@ -10,14 +10,14 @@ import net.minecraft.world.entity.Mob;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class MobGoalConverterTest {
|
||||
|
||||
@Test
|
||||
public void testBukkitMap() {
|
||||
final List<Class<Mob>> classes;
|
||||
try (ScanResult scanResult = new ClassGraph().enableAllInfo().whitelistPackages(Entity.class.getPackageName()).scan()) {
|
||||
try (ScanResult scanResult = new ClassGraph().enableClassInfo().whitelistPackages(Entity.class.getPackageName()).scan()) {
|
||||
classes = scanResult.getSubclasses(Mob.class.getName()).loadClasses(Mob.class);
|
||||
}
|
||||
|
||||
@ -30,8 +30,6 @@ public class MobGoalConverterTest {
|
||||
}
|
||||
}
|
||||
|
||||
if (!missingClasses.isEmpty()) {
|
||||
fail("Missing some entity classes in the bukkit map: " + String.join(", ", missingClasses));
|
||||
}
|
||||
assertTrue(missingClasses.isEmpty(), () -> "Missing some entity classes in the bukkit map: " + String.join(", ", missingClasses));
|
||||
}
|
||||
}
|
||||
|
@ -648,7 +648,7 @@ index a8d6d7054110b5d95830296699f004418dae10db..acc25b08ed3b9f978229fa017d23f9fa
|
||||
LOOK,
|
||||
JUMP,
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 6b042419af11730b0159c030ea1881dcfbb37dcd..8339da59b7a73411f45b77f6eb93e8ad65a1ef48 100644
|
||||
index 89a37c31c0376d66251fee36df4a78dac05c2031..b91dc9532380788f7b6b7a50a53625e1cb3889d2 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -2956,5 +2956,11 @@ public final class CraftServer implements Server {
|
||||
@ -663,46 +663,3 @@ index 6b042419af11730b0159c030ea1881dcfbb37dcd..8339da59b7a73411f45b77f6eb93e8ad
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
||||
diff --git a/src/test/java/io/papermc/paper/entity/ai/MobGoalConverterTest.java b/src/test/java/io/papermc/paper/entity/ai/MobGoalConverterTest.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..b020f795846d98f5464b390008be8815e892f9e8
|
||||
--- /dev/null
|
||||
+++ b/src/test/java/io/papermc/paper/entity/ai/MobGoalConverterTest.java
|
||||
@@ -0,0 +1,37 @@
|
||||
+package io.papermc.paper.entity.ai;
|
||||
+
|
||||
+import com.destroystokyo.paper.entity.ai.MobGoalHelper;
|
||||
+import io.github.classgraph.ClassGraph;
|
||||
+import io.github.classgraph.ScanResult;
|
||||
+import net.minecraft.world.entity.Entity;
|
||||
+import net.minecraft.world.entity.Mob;
|
||||
+import org.junit.jupiter.api.Test;
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.List;
|
||||
+
|
||||
+import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
+import static org.junit.jupiter.api.Assertions.fail;
|
||||
+
|
||||
+public class MobGoalConverterTest {
|
||||
+
|
||||
+ @Test
|
||||
+ public void testBukkitMap() {
|
||||
+ List<Class<Mob>> classes;
|
||||
+ try (ScanResult scanResult = new ClassGraph().enableAllInfo().whitelistPackages(Entity.class.getPackageName()).scan()) {
|
||||
+ classes = scanResult.getSubclasses(Mob.class.getName()).loadClasses(Mob.class);
|
||||
+ }
|
||||
+ assertFalse(classes.isEmpty(), "There are supposed to be more than 0 mob classes!");
|
||||
+
|
||||
+ List<String> missingClasses = new ArrayList<>();
|
||||
+ for (Class<Mob> nmsClass : classes) {
|
||||
+ Class<? extends org.bukkit.entity.Mob> bukkitClass = MobGoalHelper.toBukkitClass(nmsClass);
|
||||
+ if (bukkitClass == null) {
|
||||
+ missingClasses.add(nmsClass.getCanonicalName());
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!missingClasses.isEmpty()) {
|
||||
+ fail("Missing some entity classes in the bukkit map (MobGoalHelper): " + String.join(", ", missingClasses));
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
|
Loading…
Reference in New Issue
Block a user