aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Herzig <jonas@spark-squared.com>2021-11-11 20:59:47 +0100
committerJonas Herzig <jonas@spark-squared.com>2021-11-12 15:23:25 +0100
commitf1224518f86b0160149544dc8d56505a37a186e2 (patch)
tree23d3a40362df3dde498e69ad9ac8ee7727cbd8fd
parent1aa8b425982a6d30a177bc25a70a325652209ee0 (diff)
downloadRemap-f1224518f86b0160149544dc8d56505a37a186e2.tar.gz
Remap-f1224518f86b0160149544dc8d56505a37a186e2.tar.bz2
Remap-f1224518f86b0160149544dc8d56505a37a186e2.zip
Fix loss of changes when multiple target the same start point
While one might at first think that multiple changes should conflict if they target that same start point, that is not necessarily true as long as no more than one of them includes deletions: There may be an arbitrary number of insertions at the same position (regular remapping never just inserts but patterns can).
-rw-r--r--src/main/kotlin/com/replaymod/gradle/remap/PsiMapper.kt10
-rw-r--r--src/test/java/a/pkg/A.java2
-rw-r--r--src/test/java/b/pkg/B.java2
-rw-r--r--src/test/kotlin/com/replaymod/gradle/remap/pattern/TestChangeMerging.kt36
-rw-r--r--src/test/kotlin/com/replaymod/gradle/remap/util/TestData.kt8
5 files changed, 55 insertions, 3 deletions
diff --git a/src/main/kotlin/com/replaymod/gradle/remap/PsiMapper.kt b/src/main/kotlin/com/replaymod/gradle/remap/PsiMapper.kt
index a8d9f2a..c620c4c 100644
--- a/src/main/kotlin/com/replaymod/gradle/remap/PsiMapper.kt
+++ b/src/main/kotlin/com/replaymod/gradle/remap/PsiMapper.kt
@@ -31,7 +31,7 @@ internal class PsiMapper(
) {
private val mixinMappings = mutableMapOf<String, ClassMapping<*, *>>()
private val errors = mutableListOf<Pair<Int, String>>()
- private val changes = TreeMap<TextRange, String>(Comparator.comparing<TextRange, Int> { it.startOffset })
+ private val changes = TreeMap<TextRange, String>(compareBy<TextRange> { it.startOffset }.thenBy { it.endOffset })
private fun error(at: PsiElement, message: String) {
val line = StringUtil.offsetToLineNumber(file.text, at.textOffset)
@@ -40,7 +40,13 @@ internal class PsiMapper(
private fun replace(e: PsiElement, with: String) = replace(e.textRange, with)
private fun replace(textRange: TextRange, with: String) {
- changes[textRange] = with
+ changes.compute(textRange) { _, replacement ->
+ if (replacement != null) {
+ replacement + with
+ } else {
+ with
+ }
+ }
}
private fun replaceIdentifier(parent: PsiElement, with: String) {
diff --git a/src/test/java/a/pkg/A.java b/src/test/java/a/pkg/A.java
index b5480d4..32fa2a9 100644
--- a/src/test/java/a/pkg/A.java
+++ b/src/test/java/a/pkg/A.java
@@ -10,6 +10,8 @@ public class A extends AParent implements AInterface {
public A(A arg) {
}
+ public static A create() { return new A(); }
+
public void aMethod() {
aInterfaceMethod();
}
diff --git a/src/test/java/b/pkg/B.java b/src/test/java/b/pkg/B.java
index 88f46cf..3af7381 100644
--- a/src/test/java/b/pkg/B.java
+++ b/src/test/java/b/pkg/B.java
@@ -10,6 +10,8 @@ public class B extends BParent implements BInterface {
public B(B arg) {
}
+ public static B create() { return new B(); }
+
public void bMethod() {
bInterfaceMethod();
}
diff --git a/src/test/kotlin/com/replaymod/gradle/remap/pattern/TestChangeMerging.kt b/src/test/kotlin/com/replaymod/gradle/remap/pattern/TestChangeMerging.kt
new file mode 100644
index 0000000..e8b86d2
--- /dev/null
+++ b/src/test/kotlin/com/replaymod/gradle/remap/pattern/TestChangeMerging.kt
@@ -0,0 +1,36 @@
+package com.replaymod.gradle.remap.pattern
+
+import com.replaymod.gradle.remap.util.TestData
+import io.kotest.matchers.collections.shouldHaveSize
+import io.kotest.matchers.shouldBe
+import io.kotest.matchers.string.shouldContain
+import org.junit.jupiter.api.Test
+
+class TestChangeMerging {
+ @Test
+ fun `should work when mixed with remapping`() {
+ TestData.remap("""
+ class Test {
+ private void test() {
+ a.pkg.A.create().aMethod();
+ }
+ }
+ """.trimIndent(), """
+ @remap.Pattern
+ private void addWrapping(a.pkg.A a) {
+ a.aMethod();
+ }
+ """.trimIndent(), """
+ @remap.Pattern
+ private void addWrapping(a.pkg.A a) {
+ (((a.bMethod())));
+ }
+ """.trimIndent()) shouldBe """
+ class Test {
+ private void test() {
+ (((b.pkg.B.create().bMethod())));
+ }
+ }
+ """.trimIndent()
+ }
+} \ No newline at end of file
diff --git a/src/test/kotlin/com/replaymod/gradle/remap/util/TestData.kt b/src/test/kotlin/com/replaymod/gradle/remap/util/TestData.kt
index 0f83373..adb6f52 100644
--- a/src/test/kotlin/com/replaymod/gradle/remap/util/TestData.kt
+++ b/src/test/kotlin/com/replaymod/gradle/remap/util/TestData.kt
@@ -41,9 +41,15 @@ object TestData {
findClasspathEntry("org.spongepowered.asm.mixin.Mixin"),
findClasspathEntry("a.pkg.A"),
)
+ patternAnnotation = "remap.Pattern"
}
- fun remap(content: String): String = transformer.remap(mapOf("test.java" to content))["test.java"]!!.first
+ fun remap(content: String, patternsBefore: String = "", patternsAfter: String = ""): String = transformer.remap(mapOf(
+ "test.java" to content,
+ "pattern.java" to "class Patterns {\n$patternsBefore\n}",
+ ), mapOf(
+ "pattern.java" to "class Patterns {\n$patternsAfter\n}",
+ ))["test.java"]!!.first
fun remapWithErrors(content: String) = transformer.remap(mapOf("test.java" to content))["test.java"]!!
fun remapKt(content: String): String = transformer.remap(mapOf("test.kt" to content))["test.kt"]!!.first