Skip to content

Commit

Permalink
Begin work on ASM-based remapper and gradle plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
lukebemish committed Nov 21, 2023
1 parent 32e03c1 commit 9ebb4d1
Show file tree
Hide file tree
Showing 18 changed files with 586 additions and 175 deletions.
7 changes: 7 additions & 0 deletions .github/workflows/build_pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ jobs:
./gradlew check --continue
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
- name: Test Plugin
if: (success() || failure()) && steps.assemble.conclusion == 'success'
working-directory: ./testplugin
run: |
./gradlew check --continue
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
- name: Upload Test Report
uses: actions/upload-artifact@v3
if: (success() || failure()) && steps.assemble.conclusion == 'success'
Expand Down
7 changes: 7 additions & 0 deletions .github/workflows/snapshot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ jobs:
./gradlew check --continue
env:
SNAPSHOT_MAVEN_URL: https://maven.lukebemish.dev/snapshots/
- name: Test Plugin
if: (success() || failure()) && steps.assemble.conclusion == 'success'
working-directory: ./testplugin
run: |
./gradlew check --continue
env:
SNAPSHOT_MAVEN_URL: https://maven.lukebemish.dev/snapshots/
- name: Upload Test Report
uses: actions/upload-artifact@v3
if: (success() || failure()) && steps.assemble.conclusion == 'success'
Expand Down
26 changes: 23 additions & 3 deletions compile/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,35 @@ tasks.named('compileTestJava', JavaCompile).configure {
destinationDirectory.set(tempClassesDir)
}

tasks.register('processTestClasses', JavaExec) {
var asmCompileTest = tasks.register('processTestClasses', JavaExec) {
dependsOn compileTestJava
dependsOn configurations.asmRuntimeClasspath
inputs.dir(tempClassesDir)
inputs.files(sourceSets.asm.runtimeClasspath)
outputs.dir(sourceSets.test.output.classesDirs)
classpath = sourceSets.asm.runtimeClasspath
mainClass.set 'dev.lukebemish.opensesame.compile.asm.Processor'
args = compileTestJava.outputs.files.files.collectMany { [it.canonicalPath, it.canonicalPath] }
mainClass.set 'dev.lukebemish.opensesame.compile.asm.VisitingOpenProcessor'
args = compileTestJava.outputs.files.files.collectMany { [tempClassesDir.get().asFile.canonicalPath, sourceSets.test.output.classesDirs.singleFile.canonicalPath] }

jacoco.applyTo(it)
extensions.configure(JacocoTaskExtension) {
it.excludes += 'dev/lukebemish/opensesame/test/target/*'
}
outputs.upToDateWhen { false }

finalizedBy tasks.named('testAsmCompileCodeCoverateReport')
}

var report = tasks.register('testAsmCompileCodeCoverateReport', JacocoReport) {
dependsOn asmCompileTest.get()
executionData asmCompileTest.get()
sourceSets sourceSets.main
}

artifacts {
add('coverageDataElementsForTest', report.get().executionData.singleFile) {
builtBy report.get()
}
}

tasks.testClasses.dependsOn processTestClasses
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@
import org.jetbrains.annotations.Nullable;
import org.objectweb.asm.*;

import java.io.IOException;
import java.lang.invoke.CallSite;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.stream.Collectors;

Expand All @@ -23,6 +26,50 @@ public class VisitingOpenProcessor extends ClassVisitor implements OpenProcessor
private final Set<String> annotationDescriptors;
private Type type;

public static void main(String[] args) {
if ((~args.length & 1) != 1) {
System.err.println("Usage: java dev.lukebemish.opensesame.compile.asm.Processor <input> <output> <input> <output> ...");
System.exit(1);
}
for (int i = 0; i < args.length; i += 2) {
var input = Path.of(args[0]);
var output = Path.of(args[1]);
try {
process(input, output);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

public static void process(Path input, Path output) throws IOException {
if (Files.isRegularFile(input)) {
processFile(input, output);
} else {
try (var paths = Files.walk(input)) {
paths.filter(Files::isRegularFile).forEach(file -> {
try {
var relative = input.relativize(file);
var out = output.resolve(relative);
Files.createDirectories(out.getParent());
processFile(file, out);
} catch (IOException e) {
throw new RuntimeException(e);
}
});
}
}
}

private static void processFile(Path file, Path out) throws IOException {
try (var inputStream = Files.newInputStream(file)) {
ClassReader reader = new ClassReader(inputStream);
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
reader.accept(new VisitingOpenProcessor(writer, VisitingOpenProcessor.ANNOTATIONS), 0);
Files.write(out, writer.toByteArray());
}
}

public VisitingOpenProcessor(ClassVisitor delegate, Set<Type> annotations) {
super(Opcodes.ASM9, delegate);
this.annotationDescriptors = annotations.stream().map(Type::getDescriptor).collect(Collectors.toSet());
Expand Down
5 changes: 5 additions & 0 deletions plugin/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ dependencies {
implementation libs.asm

implementation project(':opensesame-compile')
implementation(project(':opensesame-compile')) {
capabilities {
requireCapability 'dev.lukebemish.opensesame:opensesame-compile-asm'
}
}
}

gradlePlugin {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package dev.lukebemish.opensesame.plugin;

import dev.lukebemish.opensesame.plugin.task.ProcessAnnotationsTask;
import org.gradle.api.Project;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.compile.JavaCompile;

import javax.inject.Inject;

Expand All @@ -14,6 +16,17 @@ public OpenSesameExtension(Project project) {
}

public void apply(SourceSet sourceSet) {
// TODO: implement stuff
var unprocessedClasses = project.getLayout().getBuildDirectory().dir("opensesame/raw/" + sourceSet.getName());
var compileJava = project.getTasks().named(sourceSet.getCompileJavaTaskName(), JavaCompile.class, task -> {
task.getDestinationDirectory().set(unprocessedClasses);
});
var processOpenSesame = project.getTasks().register(sourceSet.getTaskName("process", "openSesame"), ProcessAnnotationsTask.class, task -> {
task.dependsOn(compileJava);
task.getInputClassesDir().set(unprocessedClasses);
});
sourceSet.getJava().compiledBy(processOpenSesame, ProcessAnnotationsTask::getOutputClassesDir);
project.getTasks().named(sourceSet.getClassesTaskName(), task -> {
task.dependsOn(processOpenSesame);
});
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
package dev.lukebemish.opensesame.plugin;

import dev.lukebemish.opensesame.plugin.loom.LoomExtension;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.plugins.ExtensionAware;

public class OpenSesamePlugin implements Plugin<Project> {
@Override
public void apply(Project target) {
var openSesameExtension = target.getExtensions().create("opensesame", OpenSesameExtension.class);
((ExtensionAware) openSesameExtension).getExtensions().create("loom", LoomExtension.class);
//((ExtensionAware) openSesameExtension).getExtensions().create("loom", LoomExtension.class);
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,7 @@
package dev.lukebemish.opensesame.plugin.loom;

import org.gradle.api.provider.Property;
import org.gradle.api.tasks.compile.JavaCompile;

public abstract class LoomExtension {
public abstract Property<String> getTargetNamespace();
public abstract Property<String> getSourceNamespace();

public LoomExtension() {
getSourceNamespace().convention("named");
getTargetNamespace().convention("intermediary");
}
public LoomExtension() {}

private void checkForLoom() {
try {
Expand All @@ -20,20 +11,8 @@ private void checkForLoom() {
}
}

public void targetNamespace(String namespace) {
getTargetNamespace().set(namespace);
}

public void sourceNamespace(String namespace) {
getSourceNamespace().set(namespace);
}

public void apply(JavaCompile compileTask) {
// TODO: We'll want to add a mapping thing instead
public void apply() {
checkForLoom();

compileTask.getOptions().getCompilerArgs().add("-Dopensesame.remap.source=" + getSourceNamespace().get());
compileTask.getOptions().getCompilerArgs().add("-Dopensesame.remap.target=" + getTargetNamespace().get());
compileTask.getOptions().getCompilerArgs().add("-Dopensesame.remap.mappings=" + LoomUtils.getMappingsFile(compileTask.getProject()));
// TODO: implement
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package dev.lukebemish.opensesame.plugin.task;

import dev.lukebemish.opensesame.compile.asm.VisitingOpenProcessor;
import org.gradle.api.DefaultTask;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.tasks.InputDirectory;
import org.gradle.api.tasks.OutputDirectory;
import org.gradle.api.tasks.TaskAction;

import java.io.IOException;
import java.nio.file.Path;

public abstract class ProcessAnnotationsTask extends DefaultTask {
@InputDirectory
public abstract DirectoryProperty getInputClassesDir();

@OutputDirectory
public abstract DirectoryProperty getOutputClassesDir();

@TaskAction
public void process() {
try {
Path inPath = getInputClassesDir().get().getAsFile().toPath();
Path outPath = getOutputClassesDir().get().getAsFile().toPath();
VisitingOpenProcessor.process(inPath, outPath);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
60 changes: 60 additions & 0 deletions testplugin/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
plugins {
id 'java'
id 'groovy'
id 'dev.lukebemish.opensesame'
}

group='dev.lukebemish.opensesame'

java.toolchain.languageVersion.set(JavaLanguageVersion.of(17))

configurations {
testSource {
canBeResolved = true
}
testModuleClasspath {
canBeResolved = true
}
}

repositories {
mavenCentral()
}

dependencies {
testSource('dev.lukebemish.opensesame:testtargets:testsources') {
attributes {
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage, 'java-source'))
}
}
testImplementation 'dev.lukebemish.opensesame:testtargets'
testModuleClasspath 'dev.lukebemish.opensesame:testtargets'
testImplementation 'dev.lukebemish.opensesame:opensesame-core'
testImplementation libs.asm
testImplementation libs.junit.api
testRuntimeOnly libs.junit.engine
}

opensesame.apply(sourceSets.test)

tasks.named('compileTestJava', JavaCompile).configure {
dependsOn(configurations.testSource)
source(configurations.testSource)
}

test {
useJUnitPlatform()

testLogging {
showStandardStreams = true
exceptionFormat = 'full'
events = ['passed', 'failed', 'skipped']
}

testClassesDirs += files(
sourceSets.test.output,
configurations.testModuleClasspath
)

outputs.upToDateWhen {false}
}
Binary file added testplugin/gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
7 changes: 7 additions & 0 deletions testplugin/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading

0 comments on commit 9ebb4d1

Please sign in to comment.