Skip to content

Commit

Permalink
Implement interface injection (#30)
Browse files Browse the repository at this point in the history
See neoforged/JavaSourceTransformer#33

Adds a new `--interface-injection-data` parameter used to specify the
location of interface injection data files.

---------

Co-authored-by: Sebastian Hartte <[email protected]>
  • Loading branch information
Matyrobbrt and shartte authored Jul 5, 2024
1 parent 8530597 commit 9248302
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,16 @@ public class ApplySourceTransformAction extends ExternalJavaToolAction {

/**
* Additional paths to access transformers.
* <p>
* A description of the format can be found in the <a href="https://docs.neoforged.net/docs/advanced/accesstransformers">NeoForge documentation</a>.
*/
private List<Path> additionalAccessTransformers = new ArrayList<>();

/**
* Additional paths to interface injection data files.
*/
private List<Path> injectedInterfaces = new ArrayList<>();

/**
* Path to a Parchment data archive.
*/
Expand Down Expand Up @@ -88,6 +95,16 @@ public void run(ProcessingEnvironment environment) throws IOException, Interrupt
}
}

if (!injectedInterfaces.isEmpty()) {
args.add("--enable-interface-injection");
for (var path : injectedInterfaces) {
args.add("--interface-injection-data");
args.add(environment.getPathArgument(path));
}
args.add("--interface-injection-stub-location");
args.add("{stubs}");
}

if (parchmentData != null) {
args.add("--enable-parchment");
args.add("--parchment-mappings=" + environment.getPathArgument(parchmentData.toAbsolutePath()));
Expand All @@ -114,6 +131,7 @@ public void computeCacheKey(CacheKeyBuilder ck) {
super.computeCacheKey(ck);
ck.addStrings("access transformers data ids", accessTransformersData);
ck.addPaths("additional access transformers", additionalAccessTransformers);
ck.addPaths("injected interfaces", injectedInterfaces);
if (parchmentData != null) {
ck.addPath("parchment data", parchmentData);
}
Expand All @@ -137,6 +155,10 @@ public void setAdditionalAccessTransformers(List<Path> additionalAccessTransform
this.additionalAccessTransformers = List.copyOf(additionalAccessTransformers);
}

public void setInjectedInterfaces(List<Path> injectedInterfaces) {
this.injectedInterfaces = List.copyOf(injectedInterfaces);
}

public @Nullable Path getParchmentData() {
return parchmentData;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import net.neoforged.neoform.runtime.artifacts.ClasspathItem;
import net.neoforged.neoform.runtime.cache.CacheKeyBuilder;
import net.neoforged.neoform.runtime.graph.NodeOutput;
import net.neoforged.neoform.runtime.manifests.MinecraftLibrary;
import net.neoforged.neoform.runtime.utils.MavenCoordinate;
import org.jetbrains.annotations.Nullable;
Expand Down Expand Up @@ -109,6 +110,7 @@ public void computeCacheKey(String prefix, CacheKeyBuilder ck) {
}
}
case ClasspathItem.PathItem(Path path) -> ck.addPath(component, path);
case ClasspathItem.NodeOutputItem(NodeOutput output) -> ck.addPath(component, output.getResultPath());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import net.neoforged.neoform.runtime.cli.LockManager;
import net.neoforged.neoform.runtime.downloads.DownloadManager;
import net.neoforged.neoform.runtime.downloads.DownloadSpec;
import net.neoforged.neoform.runtime.graph.NodeOutput;
import net.neoforged.neoform.runtime.manifests.LauncherManifest;
import net.neoforged.neoform.runtime.manifests.MinecraftLibrary;
import net.neoforged.neoform.runtime.manifests.MinecraftVersionManifest;
Expand Down Expand Up @@ -138,6 +139,7 @@ public List<Path> resolveClasspath(Collection<ClasspathItem> classpathItems) thr
}
case ClasspathItem.MinecraftLibraryItem(MinecraftLibrary library) -> get(library).path();
case ClasspathItem.PathItem(Path path) -> path;
case ClasspathItem.NodeOutputItem(NodeOutput output) -> output.getResultPath();
};
result.add(pathToAdd);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.neoforged.neoform.runtime.artifacts;

import net.neoforged.neoform.runtime.graph.NodeOutput;
import net.neoforged.neoform.runtime.manifests.MinecraftLibrary;
import net.neoforged.neoform.runtime.utils.MavenCoordinate;
import org.jetbrains.annotations.Nullable;
Expand Down Expand Up @@ -27,6 +28,10 @@ static ClasspathItem of(MavenCoordinate mavenLibrary, @Nullable URI repositoryBa
return new MavenCoordinateItem(mavenLibrary, repositoryBaseUrl);
}

static ClasspathItem of(NodeOutput output) {
return new NodeOutputItem(output);
}

record MavenCoordinateItem(MavenCoordinate coordinate, @Nullable URI repositoryBaseUrl) implements ClasspathItem {
@Override
public String toString() {
Expand All @@ -51,4 +56,11 @@ public String toString() {
return library.toString();
}
}

record NodeOutputItem(NodeOutput output) implements ClasspathItem {
@Override
public String toString() {
return output.getResultPath().toString();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
import net.neoforged.neoform.runtime.actions.MergeWithSourcesAction;
import net.neoforged.neoform.runtime.actions.PatchActionFactory;
import net.neoforged.neoform.runtime.actions.RecompileSourcesAction;
import net.neoforged.neoform.runtime.artifacts.ClasspathItem;
import net.neoforged.neoform.runtime.config.neoforge.NeoForgeConfig;
import net.neoforged.neoform.runtime.engine.NeoFormEngine;
import net.neoforged.neoform.runtime.graph.ExecutionGraph;
import net.neoforged.neoform.runtime.graph.ExecutionNode;
import net.neoforged.neoform.runtime.graph.NodeOutput;
import net.neoforged.neoform.runtime.graph.NodeOutputType;
import net.neoforged.neoform.runtime.graph.transforms.GraphTransform;
Expand All @@ -25,6 +27,7 @@
import java.io.StringWriter;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
Expand All @@ -37,9 +40,6 @@
public class RunNeoFormCommand extends NeoFormEngineCommand {
private static final Logger LOG = Logger.create();

@CommandLine.ParentCommand
Main commonOptions;

@CommandLine.ArgGroup(exclusive = false, multiplicity = "1")
SourceArtifacts sourceArtifacts;

Expand All @@ -49,9 +49,12 @@ public class RunNeoFormCommand extends NeoFormEngineCommand {
@CommandLine.Option(names = "--write-result", arity = "*")
List<String> writeResults = new ArrayList<>();

@CommandLine.Option(names = "--access-transformer", arity = "*")
@CommandLine.Option(names = "--access-transformer", arity = "*", description = "path to an access transformer file, which widens the access modifiers of classes/methods/fields")
List<String> additionalAccessTransformers = new ArrayList<>();

@CommandLine.Option(names = "--interface-injection-data", arity = "*", description = "path to an interface injection data file, which extends classes with implements/extends clauses")
List<Path> interfaceInjectionDataFiles = new ArrayList<>();

@CommandLine.Option(names = "--validate-access-transformers", description = "Whether access transformers should be validated and fatal errors should arise if they target members that do not exist")
boolean validateAccessTransformers;

Expand Down Expand Up @@ -99,7 +102,8 @@ protected void runWithNeoFormEngine(NeoFormEngine engine, List<AutoCloseable> cl
engine.addManagedResource(neoforgeSourcesZip);
engine.addManagedResource(neoforgeClassesZip);

var transformSources = getOrAddTransformSourcesNode(engine);
var transformSources = getOrAddTransformSourcesAction(engine);

transformSources.setAccessTransformersData(List.of("neoForgeAccessTransformers"));

// Add NeoForge libraries to the list of libraries
Expand Down Expand Up @@ -133,15 +137,15 @@ protected void runWithNeoFormEngine(NeoFormEngine engine, List<AutoCloseable> cl
}

if (!additionalAccessTransformers.isEmpty()) {
var transformSources = getOrAddTransformSourcesNode(engine);
var transformSources = getOrAddTransformSourcesAction(engine);
transformSources.setAdditionalAccessTransformers(additionalAccessTransformers.stream().map(Paths::get).toList());
if (validateAccessTransformers) {
transformSources.addArg("--access-transformer-validation=error");
}
}

if (parchmentData != null) {
var transformSources = getOrAddTransformSourcesNode(engine);
var transformSources = getOrAddTransformSourcesAction(engine);
var parchmentDataFile = artifactManager.get(parchmentData);
transformSources.setParchmentData(parchmentDataFile.path());

Expand All @@ -150,6 +154,20 @@ protected void runWithNeoFormEngine(NeoFormEngine engine, List<AutoCloseable> cl
}
}

if (!interfaceInjectionDataFiles.isEmpty()) {
var transformNode = getOrAddTransformSourcesNode(engine);
((ApplySourceTransformAction) transformNode.action()).setInjectedInterfaces(interfaceInjectionDataFiles);

// Add the stub source jar to the recomp classpath
engine.applyTransform(new ModifyAction<>(
"recompile",
RecompileSourcesAction.class,
action -> {
action.getClasspath().add(ClasspathItem.of(transformNode.getRequiredOutput("stubs")));
}
));
}

execute(engine);
}

Expand Down Expand Up @@ -197,7 +215,7 @@ private void execute(NeoFormEngine engine) throws InterruptedException, IOExcept
LOG.println(stringWriter.toString());
}

var neededResults = writeResults.stream().map(encodedResult -> {
var neededResults = writeResults.stream().<String[]>map(encodedResult -> {
var parts = encodedResult.split(":", 2);
if (parts.length != 2) {
throw new IllegalArgumentException("Specify a result destination in the form: <resultid>:<destination>");
Expand Down Expand Up @@ -235,12 +253,16 @@ private void execute(NeoFormEngine engine) throws InterruptedException, IOExcept
}
}

private static ApplySourceTransformAction getOrAddTransformSourcesNode(NeoFormEngine engine) {
private static ApplySourceTransformAction getOrAddTransformSourcesAction(NeoFormEngine engine) {
return (ApplySourceTransformAction) getOrAddTransformSourcesNode(engine).action();
}

private static ExecutionNode getOrAddTransformSourcesNode(NeoFormEngine engine) {
var graph = engine.getGraph();
var transformNode = graph.getNode("transformSources");
if (transformNode != null) {
if (transformNode.action() instanceof ApplySourceTransformAction action) {
return action;
if (transformNode.action() instanceof ApplySourceTransformAction) {
return transformNode;
} else {
throw new IllegalStateException("Node transformSources has a different action type than expected. Expected: "
+ ApplySourceTransformAction.class + " but got " + transformNode.action().getClass());
Expand All @@ -256,7 +278,8 @@ private static ApplySourceTransformAction getOrAddTransformSourcesNode(NeoFormEn
builder.inputFromNodeOutput("libraries", "listLibraries", "output");
var action = new ApplySourceTransformAction();
builder.action(action);
return builder.output("output", NodeOutputType.ZIP, "Sources with additional transforms (ATs, Parchment) applied");
builder.output("stubs", NodeOutputType.JAR, "Additional stubs (resulted as part of interface injection) to add to the recompilation classpath");
return builder.output("output", NodeOutputType.ZIP, "Sources with additional transforms (ATs, Parchment, Interface Injections) applied");
}
).apply(engine, graph);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,10 @@ public void applyTransforms(List<GraphTransform> transforms) {
}
}

public void applyTransform(GraphTransform transform) {
transform.apply(this, graph);
}

public ExecutionGraph getGraph() {
return graph;
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/tools.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

# https://projects.neoforged.net/neoforged/javasourcetransformer
JAVA_SOURCE_TRANSFORMER=net.neoforged.jst:jst-cli-bundle:1.0.50
JAVA_SOURCE_TRANSFORMER=net.neoforged.jst:jst-cli-bundle:1.0.58

DIFF_PATCH=codechicken:DiffPatch:1.5.0.29:all

0 comments on commit 9248302

Please sign in to comment.