diff --git a/README.md b/README.md index 0bc8bbf..7550448 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,14 @@ we could implement `Supplier` using `java/util/function/Supplier`. > [!NOTE] > Generics are *copied verbatim*. If you need the generics to reference a class, please use its fully qualified name (e.g. `java/util/function/Supplier`). +### Custom transformers +Third parties can use JST to implement their source file own transformations. +To do so, you can depend on the `net.neoforged.jst:jst-api` artifact, and implement the `net.neoforged.jst.api.SourceTransformerPlugin` service: +- the `getName` method returns the unique CLI identifier of the transformer. It will generate `--[no]-enable-{name}` CLI options +- the `createTransformer` method creates a `SourceTransformer` that will handle the replacements. The transformer will also be given to picocli to intercept custom CLI arguments + +To create the executable jar with your custom transformer, you should shadow the `net.neoforged.jst:jst-cli` artifact and its dependencies, and set the main class to `net.neoforged.jst.cli.Main`. + ## Usage Note that this tool is not intended to be run by users directly. Rather it is integrated into diff --git a/api/build.gradle b/api/build.gradle index e641a1e..e71ea66 100644 --- a/api/build.gradle +++ b/api/build.gradle @@ -1,5 +1,6 @@ plugins { id 'java-library' + id 'net.neoforged.gradleutils' } group = 'net.neoforged.jst' @@ -9,3 +10,17 @@ dependencies { api "info.picocli:picocli:$picocli_version" compileOnly "org.jetbrains:annotations:$jetbrains_annotations_version" } + +publishing { + publications { + api(MavenPublication) { + artifactId = 'jst-api' + + from components.java + gradleutils.sign(it) + } + } + repositories { + maven gradleutils.publishingMaven + } +} diff --git a/api/src/main/java/net/neoforged/jst/api/SourceTransformer.java b/api/src/main/java/net/neoforged/jst/api/SourceTransformer.java index 984beb2..c595219 100644 --- a/api/src/main/java/net/neoforged/jst/api/SourceTransformer.java +++ b/api/src/main/java/net/neoforged/jst/api/SourceTransformer.java @@ -2,14 +2,41 @@ import com.intellij.psi.PsiFile; +/** + * Transformers are created through {@link SourceTransformerPlugin plugins}, and handle source replacements. + *

+ * Transformers will be given to picocli for option collection, so they can accept CLI parameters. + * It is strongly recommended that transformers prefix their options with the transformer name. + */ public interface SourceTransformer { + /** + * Invoked before source files are visited for transformation. + *

+ * Can be used for loading data from CLI parameters. + * + * @param context the transform context + */ default void beforeRun(TransformContext context) { } + /** + * Invoked after all source transformations are finished. + *

+ * Can be used for post-transformation validation. + * + * @param context the transform context + * @return {@code true} if the transformation was successful, {@code false} otherwise + */ default boolean afterRun(TransformContext context) { return true; } + /** + * Visit the given {@code psiFile} for transformation. + * + * @param psiFile the file being transformed + * @param replacements the replacement collector, used to replace the value of psi tree elements + */ void visitFile(PsiFile psiFile, Replacements replacements); } diff --git a/cli/build.gradle b/cli/build.gradle index 843b423..36e7382 100644 --- a/cli/build.gradle +++ b/cli/build.gradle @@ -15,14 +15,20 @@ jar { gradleutils.setupSigning(project: project, signAllPublications: true) +configurations { + shadow + shadow.extendsFrom(implementation) +} + dependencies { implementation project(":api") implementation "info.picocli:picocli:$picocli_version" - implementation project(":parchment") - implementation project(":accesstransformers") - implementation project(':interfaceinjection') implementation 'org.slf4j:slf4j-simple:2.0.13' + shadow project(":parchment") + shadow project(":accesstransformers") + shadow project(':interfaceinjection') + testImplementation platform("org.junit:junit-bom:$junit_version") testImplementation 'org.junit.jupiter:junit-jupiter' testImplementation "org.assertj:assertj-core:$assertj_version" @@ -33,6 +39,7 @@ test { } shadowJar { + configurations = [project.configurations.shadow] mergeServiceFiles() }