Skip to content

Commit

Permalink
Restructured Project
Browse files Browse the repository at this point in the history
  • Loading branch information
shartte committed Dec 29, 2023
1 parent 5b13dd5 commit 2f562fe
Show file tree
Hide file tree
Showing 74 changed files with 1,294 additions and 505 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.gradle
/build
build
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/
Expand Down
11 changes: 11 additions & 0 deletions api/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
plugins {
id 'java-library'
}

group = 'net.neoforged.jst'

dependencies {
api "com.jetbrains.intellij.java:java-psi-impl:$intellij_version"
api "info.picocli:picocli:$picocli_version"
compileOnly "org.jetbrains:annotations:$jetbrains_annotations_version"
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import com.intellij.openapi.util.Key;
package net.neoforged.jst.api;

import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiLambdaExpression;
import com.intellij.psi.PsiMethod;
Expand All @@ -11,65 +12,12 @@
import com.intellij.psi.util.ClassUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.containers.ObjectIntHashMap;
import namesanddocs.NamesAndDocsDatabase;
import namesanddocs.NamesAndDocsForClass;
import namesanddocs.NamesAndDocsForMethod;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Objects;
import java.util.Optional;

public final class PsiHelper {
// Keys for attaching mapping data to a PsiClass. Used to prevent multiple lookups for the same class/method.
private static final Key<Optional<NamesAndDocsForClass>> CLASS_DATA_KEY = Key.create("names_and_docs_for_class");
private static final Key<Optional<NamesAndDocsForMethod>> METHOD_DATA_KEY = Key.create("names_and_docs_for_method");

@SuppressWarnings("OptionalAssignedToNull")
@Nullable
public static NamesAndDocsForClass getClassData(NamesAndDocsDatabase namesAndDocs, @Nullable PsiClass psiClass) {
if (psiClass == null) {
return null;
}
var classData = psiClass.getUserData(CLASS_DATA_KEY);
if (classData != null) {
return classData.orElse(null);
} else {
var sb = new StringBuilder();
getBinaryClassName(psiClass, sb);
if (sb.isEmpty()) {
classData = Optional.empty();
} else {
classData = Optional.ofNullable(namesAndDocs.getClass(sb.toString()));
}
psiClass.putUserData(CLASS_DATA_KEY, classData);
return classData.orElse(null);
}
}

@SuppressWarnings("OptionalAssignedToNull")
@Nullable
public static NamesAndDocsForMethod getMethodData(NamesAndDocsDatabase namesAndDocs, @Nullable PsiMethod psiMethod) {
if (psiMethod == null) {
return null;
}
var methodData = psiMethod.getUserData(METHOD_DATA_KEY);
if (methodData != null) {
return methodData.orElse(null);
} else {
methodData = Optional.empty();
var classData = getClassData(namesAndDocs, psiMethod.getContainingClass());
if (classData != null) {
var methodName = getBinaryMethodName(psiMethod);
var methodSignature = getBinaryMethodSignature(psiMethod);
methodData = Optional.ofNullable(classData.getMethod(methodName, methodSignature));
}

psiMethod.putUserData(METHOD_DATA_KEY, methodData);
return methodData.orElse(null);
}
}

public static String getBinaryMethodName(PsiMethod psiMethod) {
return psiMethod.isConstructor() ? "<init>" : psiMethod.getName();
}
Expand Down
11 changes: 11 additions & 0 deletions api/src/main/java/net/neoforged/jst/api/Replacement.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package net.neoforged.jst.api;

import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;

import java.util.Comparator;

public record Replacement(TextRange range, String newText) {

public static final Comparator<Replacement> COMPARATOR = Comparator.comparingInt(replacement -> replacement.range.getStartOffset());
}
73 changes: 73 additions & 0 deletions api/src/main/java/net/neoforged/jst/api/Replacements.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package net.neoforged.jst.api;

import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;

import java.util.ArrayList;
import java.util.List;

public final class Replacements {
private final List<Replacement> replacements = new ArrayList<>();

public boolean isEmpty() {
return replacements.isEmpty();
}

public void replace(PsiElement element, String newText) {
add(new Replacement(element.getTextRange(), newText));
}

public void insertBefore(PsiElement element, String newText) {
var startOffset = element.getTextRange().getStartOffset();
add(new Replacement(new TextRange(
startOffset,
startOffset
), newText));
}

public void insertAfter(PsiElement element, String newText) {
var endOffset = element.getTextRange().getEndOffset();
add(new Replacement(new TextRange(
endOffset,
endOffset
), newText));
}

public void add(Replacement replacement) {
replacements.add(replacement);
}

public String apply(CharSequence originalContent) {
// We will assemble the resulting file by iterating all ranges (replaced or not)
// For this to work, the replacement ranges need to be in ascending order and non-overlapping
replacements.sort(Replacement.COMPARATOR);

var writer = new StringBuilder();
// Copy up until the first replacement

writer.append(originalContent, 0, replacements.get(0).range().getStartOffset());
for (int i = 0; i < replacements.size(); i++) {
var replacement = replacements.get(i);
var range = replacement.range();
if (i > 0) {
// Copy between previous and current replacement verbatim
var previousReplacement = replacements.get(i - 1);
// validate that replacement ranges are non-overlapping
if (previousReplacement.range().getEndOffset() > range.getStartOffset()) {
throw new IllegalStateException("Trying to replace overlapping ranges: "
+ replacement + " and " + previousReplacement);
}

writer.append(
originalContent,
previousReplacement.range().getEndOffset(),
range.getStartOffset()
);
}
writer.append(replacement.newText());
}
writer.append(originalContent, replacements.get(replacements.size() - 1).range().getEndOffset(), originalContent.length());
return writer.toString();
}

}
13 changes: 13 additions & 0 deletions api/src/main/java/net/neoforged/jst/api/SourceTransformer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package net.neoforged.jst.api;

import com.intellij.psi.PsiFile;

public interface SourceTransformer {
default void beforeRun() {
}

default void afterRun() {
}

void visitFile(PsiFile psiFile, Replacements replacements);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package net.neoforged.jst.api;

/**
* Accessed via {@link java.util.ServiceLoader}.
*/
public interface SourceTransformerPlugin {

/**
* Unique name used in command-line options to enable this plugin.
*/
String getName();

/**
* Creates a new transformer to be applied to source code.
*/
SourceTransformer createTransformer();

}

62 changes: 3 additions & 59 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,68 +1,12 @@
plugins {
id 'java'
id 'maven-publish'
id 'com.github.johnrengelman.shadow'
id 'net.neoforged.gradleutils'
}

group = "net.neoforged"
project.version = gradleutils.version

jar {
manifest {
attributes 'Main-Class': 'ApplyParchmentToSourceJar'
}
subprojects {
group = rootProject.group
version = rootProject.version
}

repositories {
mavenCentral()
maven {
url "https://www.jetbrains.com/intellij-repository/releases/"
}
maven {
url "https://cache-redirector.jetbrains.com/intellij-dependencies/"
}
maven {
url "https://maven.parchmentmc.org/"
}
}

dependencies {
implementation 'com.jetbrains.intellij.java:java-psi-impl:233.11799.300'

implementation 'org.parchmentmc.feather:io-gson:1.1.0'
implementation 'net.fabricmc:mapping-io:0.5.1'

testImplementation platform('org.junit:junit-bom:5.9.1')
testImplementation 'org.junit.jupiter:junit-jupiter'
}

test {
useJUnitPlatform()
}

assemble.configure {
dependsOn shadowJar
}

// This skips the shadowjar from being published as part of the normal publication
components.java.withVariantsFromConfiguration(configurations.shadowRuntimeElements) {
skip()
}

publishing {
publications {
// This publication only contains the unshaded jar with dependencies in the pom.xml
plain(MavenPublication) {
artifactId = 'apply-parchment'

from components.java
}
// This publication only contains the shaded standalone jar
bundle(MavenPublication) {
artifactId = 'apply-parchment-bundle'

project.shadow.component(bundle)
}
}
}
51 changes: 51 additions & 0 deletions cli/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
plugins {
id 'java'
id 'com.github.johnrengelman.shadow'
}

group = 'net.neoforged.jst'

jar {
manifest {
attributes 'Main-Class': 'net.neoforged.jst.cli.Main'
}
}

dependencies {
implementation project(":api")
implementation "info.picocli:picocli:$picocli_version"
implementation project(":parchment")

testImplementation platform("org.junit:junit-bom:$junit_version")
testImplementation 'org.junit.jupiter:junit-jupiter'
}

test {
useJUnitPlatform()
}

assemble.configure {
dependsOn shadowJar
}

// This skips the shadowjar from being published as part of the normal publication
components.java.withVariantsFromConfiguration(configurations.shadowRuntimeElements) {
skip()
}

publishing {
publications {
// This publication only contains the unshaded jar with dependencies in the pom.xml
plain(MavenPublication) {
artifactId = 'jst-cli'

from components.java
}
// This publication only contains the shaded standalone jar
bundle(MavenPublication) {
artifactId = 'jst-cli-bundle'

project.shadow.component(bundle)
}
}
}
Loading

0 comments on commit 2f562fe

Please sign in to comment.