Skip to content

Commit

Permalink
Move file to be per-mod, disallow "null" string, rename NumberedEnum …
Browse files Browse the repository at this point in the history
…annotation
  • Loading branch information
XFactHD committed May 27, 2024
1 parent 333842f commit 644e09c
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,9 @@ public int compareTo(EnumPrototype other) {
return comp != 0 ? comp : fieldName.compareTo(other.fieldName);
}

static List<EnumPrototype> load(Path path) {
static List<EnumPrototype> load(String modId, Path path) {
try {
JsonObject json = GSON.fromJson(Files.newBufferedReader(path), JsonObject.class);
String owner = json.get("modid").getAsString();

JsonArray entries = json.getAsJsonArray("entries");
List<EnumPrototype> prototypes = new ArrayList<>(entries.size());
Expand All @@ -39,8 +38,8 @@ static List<EnumPrototype> load(Path path) {
String enumName = entryObj.get("enum").getAsString();

String fieldName = entryObj.get("name").getAsString();
if (!fieldName.toLowerCase(Locale.ROOT).startsWith(owner)) {
fieldName = owner.toUpperCase(Locale.ROOT) + "_" + fieldName;
if (!fieldName.toLowerCase(Locale.ROOT).startsWith(modId)) {
fieldName = modId.toUpperCase(Locale.ROOT) + "_" + fieldName;
}

String ctorDesc = entryObj.get("constructor").getAsString();
Expand All @@ -60,7 +59,7 @@ static List<EnumPrototype> load(Path path) {

// Prepend source-invisible field name and ordinal parameters after checking user-provided parameters
ctorDesc = "(" + ENUM_CTOR_BASE_DESC + ctorDesc.substring(1);
prototypes.add(new EnumPrototype(owner, enumName, fieldName, ctorDesc, ctorParams));
prototypes.add(new EnumPrototype(modId, enumName, fieldName, ctorDesc, ctorParams));
}
return prototypes;
} catch (Throwable e) {
Expand Down Expand Up @@ -95,7 +94,7 @@ private static EnumParameters loadConstantParameters(String ctorDesc, JsonArray
case "D" -> element.getAsDouble();
case "Ljava/lang/String;" -> element.isJsonNull() ? null : element.getAsString();
default -> {
if (element.isJsonNull() || element.getAsString().equals("null")) {
if (element.isJsonNull()) {
yield null;
}
throw new IllegalArgumentException("Unsupported immediate argument type");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
public @interface NumberedEnum {
public @interface IndexedEnum {
/**
* {@return the parameter index of the ID parameter}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public class RuntimeEnumExtender implements ILaunchPluginService {
private static final EnumSet<Phase> YAY = EnumSet.of(Phase.AFTER);
private static final EnumSet<Phase> NAY = EnumSet.noneOf(Phase.class);
private static final Type MARKER_IFACE = Type.getType(IExtensibleEnum.class);
private static final Type NUMBERED_ANNOTATION = Type.getType(NumberedEnum.class);
private static final Type INDEXED_ANNOTATION = Type.getType(IndexedEnum.class);
private static final Type BLACKLIST_ANNOTATION = Type.getType(BlacklistedConstructor.class);
private static final Type ENUM_PROXY = Type.getType(EnumProxy.class);
private static final int ENUM_FLAGS = Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL | Opcodes.ACC_ENUM;
Expand Down Expand Up @@ -139,7 +139,7 @@ private static int getIdParameterIndex(ClassNode classNode) {
}

AnnotationNode annotation = classNode.invisibleAnnotations.stream()
.filter(anno -> anno.desc.equals(NUMBERED_ANNOTATION.getDescriptor()))
.filter(anno -> anno.desc.equals(INDEXED_ANNOTATION.getDescriptor()))
.findFirst()
.orElse(null);
if (annotation == null) {
Expand Down Expand Up @@ -286,9 +286,10 @@ private static void appendValuesArray(Type classType, InsnList insnList, List<Fi
}
}

public static void loadEnumPrototypes(List<Path> paths) {
prototypes = paths.stream()
.map(EnumPrototype::load)
public static void loadEnumPrototypes(Map<String, Path> paths) {
prototypes = paths.entrySet()
.stream()
.map(entry -> EnumPrototype.load(entry.getKey(), entry.getValue()))
.flatMap(List::stream)
.sorted()
.reduce(
Expand Down
21 changes: 16 additions & 5 deletions loader/src/main/java/net/neoforged/fml/loading/LoadingModList.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@

package net.neoforged.fml.loading;

import com.mojang.logging.LogUtils;
import cpw.mods.modlauncher.api.LambdaExceptionUtils;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
Expand All @@ -25,12 +27,14 @@
import net.neoforged.fml.loading.moddiscovery.ModInfo;
import net.neoforged.fml.loading.modscan.BackgroundScanHandler;
import net.neoforged.neoforgespi.language.IModInfo;
import org.slf4j.Logger;

/**
* Master list of all mods <em>in the loading context. This class cannot refer outside the
* loading package</em>
*/
public class LoadingModList {
private static final Logger LOGGER = LogUtils.getLogger();
private static LoadingModList INSTANCE;
private final List<ModFileInfo> modFiles;
private final List<ModInfo> sortedList;
Expand Down Expand Up @@ -89,12 +93,19 @@ public void addAccessTransformers() {
}

public void addEnumExtenders() {
List<Path> paths = modFiles.stream()
.map(ModFileInfo::getFile)
.map(ModFile::getEnumExtenders)
Map<String, Path> pathPerMod = new HashMap<>();
modFiles.stream()
.map(ModFileInfo::getMods)
.flatMap(List::stream)
.toList();
RuntimeEnumExtender.loadEnumPrototypes(paths);
.forEach(mod -> mod.getConfig().<String>getConfigElement("enumExtender").ifPresent(file -> {
Path path = mod.getOwningFile().getFile().findResource(file);
if (Files.notExists(path)) {
LOGGER.error(LogMarkers.LOADING, "Enum extender file {} provided by mod {} does not exist!", path, mod.getOwningFile().moduleName());
return;
}
pathPerMod.put(mod.getModId(), path);
}));
RuntimeEnumExtender.loadEnumPrototypes(pathPerMod);
}

public void addForScanning(BackgroundScanHandler backgroundScanHandler) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ public class ModFile implements IModFile {
private List<CoreModFile> coreMods;
private List<String> mixinConfigs;
private List<Path> accessTransformers;
private List<Path> enumExtenders;

public static final Attributes.Name TYPE = new Attributes.Name("FMLModType");
private SecureJar.Status securityStatus;
Expand Down Expand Up @@ -130,17 +129,6 @@ public boolean identifyMods() {
.orElseGet(() -> Stream.of(findResource("META-INF", "accesstransformer.cfg"))
.filter(Files::exists))
.toList();
this.enumExtenders = ModFileParser.getEnumExtenders(this.modFileInfo)
.map(list -> list.stream().map(this::findResource).filter(path -> {
if (Files.notExists(path)) {
LOGGER.error(LogMarkers.LOADING, "Enum extender file {} provided by mod {} does not exist!", path, modFileInfo.moduleName());
return false;
}
return true;
}))
.orElseGet(() -> Stream.of(findResource("META-INF", "enumextender.json"))
.filter(Files::exists))
.toList();
return true;
}

Expand All @@ -152,10 +140,6 @@ public List<String> getMixinConfigs() {
return mixinConfigs;
}

public List<Path> getEnumExtenders() {
return enumExtenders;
}

/**
* Run in an executor thread to harvest the class and annotation list
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import java.nio.charset.StandardCharsets;
import net.neoforged.fml.loading.IdentifiableContent;
import net.neoforged.fml.loading.LauncherTest;
import net.neoforged.fml.loading.SimulatedInstallation;
import net.neoforged.fml.test.RuntimeCompiler;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
Expand All @@ -21,7 +20,16 @@ public void testEnumExtension() throws Exception {

var testJar = installation.writeModJar(
"enum_ext_test.jar",
SimulatedInstallation.createModsToml("enumtestmod", "1.0"),
new IdentifiableContent("enumtestmod_MODS_TOML", "META-INF/neoforge.mods.toml", """
modLoader = "javafml"
loaderVersion = "[3,]"
license = "LICENSE"
[[mods]]
modId="enumtestmod"
version="1.0"
enumExtender="META-INF/enumextender.json"
""".getBytes(StandardCharsets.UTF_8)),
new IdentifiableContent("enumtestmod_ENUM_EXT_DATA", "META-INF/enumextender.json", """
{
"modid": "enumtestmod",
Expand Down Expand Up @@ -85,9 +93,9 @@ public enum ExtensibleEnum implements net.neoforged.fml.common.asm.enumextension
""")
.addClass("enumtestmod.EnumWithId", """
package enumtestmod;
@net.neoforged.fml.common.asm.enumextension.NumberedEnum
@net.neoforged.fml.common.asm.enumextension.IndexedEnum
public enum EnumWithId implements net.neoforged.fml.common.asm.enumextension.IExtensibleEnum {
TEST_THING(0, "test");
TEST_ID_THING(0, "test");
private final int id;
private final String name;
EnumWithId(int id, String name) {
Expand Down

0 comments on commit 644e09c

Please sign in to comment.