diff --git a/README.md b/README.md index 4d53261..c4e6e38 100644 --- a/README.md +++ b/README.md @@ -54,8 +54,9 @@ This produces the Vanilla artifacts in build/ | `--write-result=:` | This option can be passed multiple times. It tells NFRT to write a result of the execution graph to the given path, such as the recompiled Minecraft jar-file, or the sources. If you pass no such option, NFRT will print which results are available. | | `--access-transformer=` | Adds access transformers which will be applied to the source before recompiling it. | | `--interface-injection-data=` | Adds [interface injection data](https://github.com/neoforged/JavaSourceTransformer?tab=readme-ov-file#interface-injection) which will be applied to the source before recompiling it. | +| `--enum-extensions-data=` | Adds [enum extensions](https://docs.neoforged.net/docs/advanced/extensibleenums/) to apply to the sources before recompiling. | | `--repository=` | Adds additional repositories that NFRT will use when it downloads artifacts. By default, the NeoForge repository and local Maven are used. | -| `--launcher-meta-uri=` | Specifies a different URL to download the Launcher manifest from. The default is `https://launchermeta.mojang.com/mc/game/version_manifest_v2.json` | | +| `--launcher-meta-uri=` | Specifies a different URL to download the Launcher manifest from. The default is `https://launchermeta.mojang.com/mc/game/version_manifest_v2.json` | | `--disable-cache` | Disables use of the intermediate result cache. | | `--print-graph` | Prints information about the execution graph used to create the artifacts. | | `--use-eclipse-compiler` | When recompiling Minecraft sources, use the Eclipse compiler rather than javac. The Eclipse compiler is able to compile in parallel, while javac is single-threaded. | diff --git a/src/main/java/net/neoforged/neoform/runtime/actions/ApplyDevTransformsAction.java b/src/main/java/net/neoforged/neoform/runtime/actions/ApplyDevTransformsAction.java index d7132ab..eb4b52b 100644 --- a/src/main/java/net/neoforged/neoform/runtime/actions/ApplyDevTransformsAction.java +++ b/src/main/java/net/neoforged/neoform/runtime/actions/ApplyDevTransformsAction.java @@ -29,6 +29,11 @@ public class ApplyDevTransformsAction extends ExternalJavaToolAction { */ private List injectedInterfaces = List.of(); + /** + * Paths to enum extensions to apply. + */ + private List enumExtensions = List.of(); + public ApplyDevTransformsAction() { super(ToolCoordinate.INSTALLER_TOOLS); } @@ -64,6 +69,14 @@ public void run(ProcessingEnvironment environment) throws IOException, Interrupt args.add(environment.getPathArgument(path.toAbsolutePath())); } + for (var path : enumExtensions) { + args.add("--enum-extensions-data"); + args.add(environment.getPathArgument(path.toAbsolutePath())); + } + + args.add("--enum-extensions-marker"); + args.add(EnumExtensionDefaults.MARKER_ANNOTATION); + setArgs(args); super.run(environment); } @@ -74,6 +87,7 @@ public void computeCacheKey(CacheKeyBuilder ck) { ck.addStrings("access transformers data ids", accessTransformersData); ck.addPaths("additional access transformers", additionalAccessTransformers); ck.addPaths("injected interfaces", injectedInterfaces); + ck.addPaths("enum extensions", enumExtensions); } public void setAccessTransformersData(List accessTransformersData) { @@ -99,4 +113,12 @@ public void setInjectedInterfaces(List injectedInterfaces) { public List getInjectedInterfaces() { return injectedInterfaces; } + + public void setEnumExtensions(List enumExtensions) { + this.enumExtensions = List.copyOf(enumExtensions); + } + + public List getEnumExtensions() { + return enumExtensions; + } } diff --git a/src/main/java/net/neoforged/neoform/runtime/actions/ApplySourceTransformAction.java b/src/main/java/net/neoforged/neoform/runtime/actions/ApplySourceTransformAction.java index a6bd049..c5d8243 100644 --- a/src/main/java/net/neoforged/neoform/runtime/actions/ApplySourceTransformAction.java +++ b/src/main/java/net/neoforged/neoform/runtime/actions/ApplySourceTransformAction.java @@ -64,6 +64,11 @@ public class ApplySourceTransformAction extends ExternalJavaToolAction { */ private List injectedInterfaces = new ArrayList<>(); + /** + * Additional paths to enum extensions. + */ + private List enumExtensions = new ArrayList<>(); + /** * Path to a Parchment data archive. */ @@ -128,6 +133,24 @@ public void run(ProcessingEnvironment environment) throws IOException, Interrupt args.add("{stubs}"); } + if (!enumExtensions.isEmpty()) { + args.add("--enable-enum-extensions"); + for (var path : enumExtensions) { + args.add("--enum-extensions-data"); + args.add(environment.getPathArgument(path.toAbsolutePath())); + } + args.add("--enum-extensions-stubs"); + args.add("{stubs}"); + args.add("--enum-extensions-required-interface"); + args.add(EnumExtensionDefaults.REQUIRED_INTERFACE); + args.add("--enum-extensions-indexed-enum-annotation"); + args.add(EnumExtensionDefaults.INDEXED_ENUM); + args.add("--enum-extensions-marker"); + args.add(EnumExtensionDefaults.MARKER_ANNOTATION); + args.add("--enum-extensions-reserved-constructor-annotation"); + args.add(EnumExtensionDefaults.RESERVED_CONSTRUCTOR); + } + if (parchmentData != null) { args.add("--enable-parchment"); args.add("--parchment-mappings=" + environment.getPathArgument(parchmentData.toAbsolutePath())); @@ -188,7 +211,7 @@ public void run(ProcessingEnvironment environment) throws IOException, Interrupt // When no interface data is given, we still have to create an empty stubs zip to satisfy // the output - if (injectedInterfaces.isEmpty()) { + if (injectedInterfaces.isEmpty() && enumExtensions.isEmpty()) { var stubsPath = environment.getOutputPath("stubs"); try { new ZipOutputStream(Files.newOutputStream(stubsPath)).close(); @@ -210,6 +233,7 @@ public void computeCacheKey(CacheKeyBuilder ck) { ck.addPaths("additional access transformers", additionalAccessTransformers); ck.addPaths("validated access transformers", validatedAccessTransformers); ck.addPaths("injected interfaces", injectedInterfaces); + ck.addPaths("enum extensions", enumExtensions); if (parchmentData != null) { ck.addPath("parchment data", parchmentData); } @@ -250,6 +274,14 @@ public void setInjectedInterfaces(List injectedInterfaces) { this.injectedInterfaces = List.copyOf(injectedInterfaces); } + public List getInjectedInterfaces() { + return injectedInterfaces; + } + + public void setEnumExtensions(List enumExtensions) { + this.enumExtensions = List.copyOf(enumExtensions); + } + public @Nullable Path getParchmentData() { return parchmentData; } diff --git a/src/main/java/net/neoforged/neoform/runtime/actions/EnumExtensionDefaults.java b/src/main/java/net/neoforged/neoform/runtime/actions/EnumExtensionDefaults.java new file mode 100644 index 0000000..c0c0cf4 --- /dev/null +++ b/src/main/java/net/neoforged/neoform/runtime/actions/EnumExtensionDefaults.java @@ -0,0 +1,13 @@ +package net.neoforged.neoform.runtime.actions; + +/** + * Various defaults for JST or binary enum extension + */ +final class EnumExtensionDefaults { + private EnumExtensionDefaults() {} + + static final String REQUIRED_INTERFACE = "net/neoforged/fml/common/asm/enumextension/IExtensibleEnum"; + static final String INDEXED_ENUM = "net/neoforged/fml/common/asm/enumextension/IndexedEnum"; + static final String MARKER_ANNOTATION = "net/neoforged/fml/common/asm/enumextension/ExtensionEnumEntry"; + static final String RESERVED_CONSTRUCTOR = "net/neoforged/fml/common/asm/enumextension/ReservedConstructor"; +} diff --git a/src/main/java/net/neoforged/neoform/runtime/cli/RunNeoFormCommand.java b/src/main/java/net/neoforged/neoform/runtime/cli/RunNeoFormCommand.java index 89c32d4..94dde23 100644 --- a/src/main/java/net/neoforged/neoform/runtime/cli/RunNeoFormCommand.java +++ b/src/main/java/net/neoforged/neoform/runtime/cli/RunNeoFormCommand.java @@ -75,6 +75,9 @@ public class RunNeoFormCommand extends NeoFormEngineCommand { @CommandLine.Option(names = "--interface-injection-data", arity = "*", description = "path to an interface injection data file, which extends classes with implements/extends clauses.") List interfaceInjectionDataFiles = new ArrayList<>(); + @CommandLine.Option(names = "--enum-extensions-data", arity = "*", description = "path to an enum extension data file, which adds new enum constants to existing enums.") + List enumExtensionDataFiles = new ArrayList<>(); + @Deprecated @CommandLine.Option(names = "--validate-access-transformers", description = "[DEPRECATED] Use --validated-access-transformer instead") boolean validateAccessTransformers; @@ -143,9 +146,14 @@ protected void runWithNeoFormEngine(NeoFormEngine engine, List cl } } - if (!interfaceInjectionDataFiles.isEmpty()) { + if (!interfaceInjectionDataFiles.isEmpty() || !enumExtensionDataFiles.isEmpty()) { var transformNode = getOrAddTransformSourcesNode(engine); - ((ApplySourceTransformAction) transformNode.action()).setInjectedInterfaces(interfaceInjectionDataFiles); + if (!interfaceInjectionDataFiles.isEmpty()) { + ((ApplySourceTransformAction) transformNode.action()).setInjectedInterfaces(interfaceInjectionDataFiles); + } + if (!enumExtensionDataFiles.isEmpty()) { + ((ApplySourceTransformAction) transformNode.action()).setEnumExtensions(enumExtensionDataFiles); + } // Add the stub source jar to the recomp classpath engine.applyTransform(new ModifyAction<>( @@ -158,7 +166,7 @@ protected void runWithNeoFormEngine(NeoFormEngine engine, List cl } // Transformations for the binpatch pipeline - if (!additionalAccessTransformers.isEmpty() || !validatedAccessTransformers.isEmpty() || !interfaceInjectionDataFiles.isEmpty()) { + if (!additionalAccessTransformers.isEmpty() || !validatedAccessTransformers.isEmpty() || !interfaceInjectionDataFiles.isEmpty() || !enumExtensionDataFiles.isEmpty()) { var graph = engine.getGraph(); // The node can be created by the NeoForge process (see applyNeoForgeProcessTransforms) var transformNode = graph.getNode("applyDevTransforms"); @@ -175,6 +183,7 @@ protected void runWithNeoFormEngine(NeoFormEngine engine, List cl allAts.addAll(validatedAccessTransformers.stream().map(Paths::get).toList()); applyDevTransformsAction.setAdditionalAccessTransformers(allAts); applyDevTransformsAction.setInjectedInterfaces(interfaceInjectionDataFiles); + applyDevTransformsAction.setEnumExtensions(enumExtensionDataFiles); } execute(engine); diff --git a/src/main/resources/tools.properties b/src/main/resources/tools.properties index 6bb3e8e..37fef82 100644 --- a/src/main/resources/tools.properties +++ b/src/main/resources/tools.properties @@ -1,12 +1,12 @@ # https://projects.neoforged.net/neoforged/javasourcetransformer -JAVA_SOURCE_TRANSFORMER=net.neoforged.jst:jst-cli-bundle:2.0.6 +JAVA_SOURCE_TRANSFORMER=net.neoforged.jst:jst-cli-bundle:2.0.17-pr-62-enum-extension DIFF_PATCH=io.codechicken:DiffPatch:2.0.0.36:all # Uses the old MCF annotation stripper since this is only used for Minecraft versions 1.20.1 and lower MCF_SIDE_ANNOTATION_STRIPPER=net.minecraftforge:mergetool:1.1.7:fatjar -INSTALLER_TOOLS=net.neoforged.installertools:installertools:4.0.12:fatjar +INSTALLER_TOOLS=net.neoforged.installertools:installertools:4.0.20-pr-44-enum-extension:fatjar AUTO_RENAMING_TOOL=net.neoforged:AutoRenamingTool:2.0.17:all