Skip to content

Commit 41e1860

Browse files
JDLogicLexManos
authored andcommitted
Update to Srg2Source V5 (#619)
1 parent 7764e3e commit 41e1860

File tree

3 files changed

+143
-43
lines changed

3 files changed

+143
-43
lines changed

build.gradle

Lines changed: 119 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ buildscript {
77
dependencies {
88
classpath "com.gradle.publish:plugin-publish-plugin:0.9.1"
99
classpath 'nl.javadude.gradle.plugins:license-gradle-plugin:0.11.0'
10+
classpath 'org.ow2.asm:asm:6.2.1'
11+
classpath 'org.ow2.asm:asm-tree:6.2.1'
1012
}
1113
}
1214

@@ -87,9 +89,10 @@ dependencies {
8789
shade('de.oceanlabs.mcp:mcinjector:3.4-SNAPSHOT'){
8890
exclude group: 'org.ow2.asm', module: 'asm-debug-all'
8991
}
90-
shade('net.minecraftforge.srg2source:Srg2Source:4.0-SNAPSHOT'){
92+
shade('net.minecraftforge:Srg2Source:5.0.+'){
9193
exclude group: 'org.ow2.asm', module: 'asm-debug-all'
9294
exclude group: 'org.eclipse.equinox', module: 'org.eclipse.equinox.common'
95+
exclude group: 'cpw.mods', module: 'modlauncher'
9396
}
9497

9598
//Stuff used in the GradleStart classes
@@ -129,7 +132,118 @@ processResources {
129132
}
130133
}
131134

135+
import java.util.zip.*
136+
import org.objectweb.asm.*
137+
import org.objectweb.asm.tree.*
138+
139+
//TODO: Eclipse complains about unused messages. Find a way to make it shut up.
140+
class PatchJDTClasses extends DefaultTask {
141+
static def COMPILATION_UNIT_RESOLVER = 'org/eclipse/jdt/core/dom/CompilationUnitResolver'
142+
static def RANGE_EXTRACTOR = 'net/minecraftforge/srg2source/ast/RangeExtractor'
143+
def RESOLVE_METHOD = 'resolve([Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;Lorg/eclipse/jdt/core/dom/FileASTRequestor;ILjava/util/Map;I)V'
144+
def GET_CONTENTS = 'org/eclipse/jdt/internal/compiler/util/Util.getFileCharContent(Ljava/io/File;Ljava/lang/String;)[C'
145+
def HOOK_DESC_RESOLVE = '(Ljava/lang/String;Ljava/lang/String;)[C'
146+
147+
@Input def targets = [] as Set
148+
@Input def libraries = [] as Set
149+
@OutputFile File output
150+
151+
void target(String value) {
152+
targets.add(value)
153+
}
154+
155+
void library(File value) {
156+
libraries.add(value)
157+
}
158+
159+
@TaskAction
160+
void patchClass() {
161+
def toProcess = targets.collect()
162+
new ZipOutputStream(new FileOutputStream(output)).withCloseable{ zout ->
163+
libraries.stream().filter{ !it.isDirectory() }.each { lib ->
164+
new ZipFile(lib).withCloseable { zin ->
165+
def remove = []
166+
toProcess.each{ target ->
167+
def entry = zin.getEntry(target+'.class')
168+
if (entry == null)
169+
return
170+
171+
def node = new ClassNode()
172+
def reader = new ClassReader(zin.getInputStream(entry))
173+
reader.accept(node, 0)
174+
175+
//CompilationUnitResolver allows batch compiling, the problem is it is hardcoded to read the contents from a File.
176+
//So we patch this call to redirect to us, so we can get the contents from our InputSupplier
177+
if (COMPILATION_UNIT_RESOLVER.equals(target)) {
178+
logger.lifecycle('Transforming: ' + target + ' From: ' + lib)
179+
def resolve = node.methods.find{ RESOLVE_METHOD.equals(it.name + it.desc) }
180+
if (resolve == null)
181+
throw new RuntimeException('Failed to patch ' + target + ': Could not find method ' + RESOLVE_METHOD)
182+
for (int x = 0; x < resolve.instructions.size(); x++) {
183+
def insn = resolve.instructions.get(x)
184+
if (insn.type == AbstractInsnNode.METHOD_INSN) {
185+
if (GET_CONTENTS.equals(insn.owner + '.' + insn.name + insn.desc)) {
186+
if (
187+
resolve.instructions.get(x - 5).opcode == Opcodes.NEW &&
188+
resolve.instructions.get(x - 4).opcode == Opcodes.DUP &&
189+
resolve.instructions.get(x - 3).opcode == Opcodes.ALOAD &&
190+
resolve.instructions.get(x - 2).opcode == Opcodes.INVOKESPECIAL &&
191+
resolve.instructions.get(x - 1).opcode == Opcodes.ALOAD
192+
) {
193+
resolve.instructions.set(resolve.instructions.get(x - 5), new InsnNode(Opcodes.NOP)); // NEW File
194+
resolve.instructions.set(resolve.instructions.get(x - 4), new InsnNode(Opcodes.NOP)); // DUP
195+
resolve.instructions.set(resolve.instructions.get(x - 2), new InsnNode(Opcodes.NOP)); // INVOKESTATIC <init>
196+
insn.owner = RANGE_EXTRACTOR
197+
insn.desc = HOOK_DESC_RESOLVE
198+
logger.lifecycle('Patched ' + node.name)
199+
} else {
200+
throw new IllegalStateException('Found Util.getFileCharContents call, with unexpected context')
201+
}
202+
}
203+
}
204+
}
205+
} else if (RANGE_EXTRACTOR.equals(target)) {
206+
logger.lifecycle('Tansforming: ' + target + ' From: ' + lib)
207+
def marker = node.methods.find{ 'hasBeenASMPatched()Z'.equals(it.name + it.desc) }
208+
if (marker == null)
209+
throw new RuntimeException('Failed to patch ' + target + ': Could not find method hasBeenASMPatched()Z')
210+
marker.instructions.clear()
211+
marker.instructions.add(new InsnNode(Opcodes.ICONST_1))
212+
marker.instructions.add(new InsnNode(Opcodes.IRETURN))
213+
logger.lifecycle('Patched: ' + node.name)
214+
}
215+
216+
def writer = new ClassWriter(0)
217+
node.accept(writer)
218+
219+
remove.add(target)
220+
def nentry = new ZipEntry(entry.name)
221+
nentry.time = 0
222+
zout.putNextEntry(nentry)
223+
zout.write(writer.toByteArray())
224+
zout.closeEntry()
225+
}
226+
toProcess.removeAll(remove)
227+
}
228+
}
229+
if (!toProcess.isEmpty())
230+
throw new IllegalStateException('Patching class failed: ' + toProcess)
231+
}
232+
}
233+
}
234+
235+
task patchJDT(type: PatchJDTClasses) {
236+
target PatchJDTClasses.COMPILATION_UNIT_RESOLVER
237+
target PatchJDTClasses.RANGE_EXTRACTOR
238+
configurations.shade.resolvedConfiguration.resolvedArtifacts.stream().filter { dep ->
239+
dep.name.equals('org.eclipse.jdt.core') || dep.name.equals('Srg2Source')
240+
}
241+
.forEach { dep -> library dep.file }
242+
output file('build/patchJDT/patch_jdt.jar')
243+
}
244+
132245
jar {
246+
dependsOn('patchJDT')
133247

134248
configurations.shade.each { dep ->
135249
/* I can use this again to find where dupes come from, so.. gunna just keep it here.
@@ -148,6 +262,10 @@ jar {
148262
}
149263
}
150264

265+
from(zipTree(patchJDT.output)){
266+
duplicatesStrategy 'include'
267+
}
268+
151269
manifest {
152270
attributes 'version':project.version
153271
attributes 'javaCompliance': project.targetCompatibility

src/main/java/net/minecraftforge/gradle/tasks/ApplyS2STask.java

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
import net.minecraftforge.gradle.common.Constants;
3131
import net.minecraftforge.gradle.util.SequencedInputSupplier;
3232
import net.minecraftforge.gradle.util.SourceDirSetSupplier;
33-
import net.minecraftforge.srg2source.rangeapplier.RangeApplier;
33+
import net.minecraftforge.srg2source.api.RangeApplierBuilder;
3434
import net.minecraftforge.srg2source.util.io.FolderSupplier;
3535
import net.minecraftforge.srg2source.util.io.InputSupplier;
3636
import net.minecraftforge.srg2source.util.io.OutputSupplier;
@@ -96,24 +96,17 @@ public void doTask() throws IOException
9696
((SequencedInputSupplier) inSup).add(getInput(o));
9797
}
9898

99-
OutputSupplier outSup;
100-
if (in.size() == 1 && in.get(0).equals(out) && in instanceof FolderSupplier)
101-
outSup = (OutputSupplier) inSup;
102-
else
103-
outSup = getOutput(out);
104-
10599
if (getExcModifiers() != null)
106100
{
107101
getLogger().lifecycle("creating default param names");
108102
exc = generateDefaultExc(getExcModifiers(), exc, srg);
109103
}
110104

111105
getLogger().lifecycle("remapping source...");
112-
applyRangeMap(inSup, outSup, srg, exc, rangemap, rangelog);
106+
applyRangeMap(inSup, out, srg, exc, rangemap, rangelog);
113107

114108

115109
inSup.close();
116-
outSup.close();
117110
}
118111

119112
private InputSupplier getInput(Object o) throws IOException
@@ -149,23 +142,24 @@ else if (f.getPath().endsWith(".jar") || f.getPath().endsWith(".zip"))
149142
throw new IllegalArgumentException("Can only make suppliers out of directories and zips right now!");
150143
}
151144

152-
private void applyRangeMap(InputSupplier inSup, OutputSupplier outSup, FileCollection srg, FileCollection exc, File rangeMap, File rangeLog) throws IOException
145+
private void applyRangeMap(InputSupplier inSup, File out, FileCollection srg, FileCollection exc, File rangeMap, File rangeLog) throws IOException
153146
{
154-
RangeApplier app = new RangeApplier().readSrg(srg.getFiles());
147+
RangeApplierBuilder builder = new RangeApplierBuilder()
148+
.input(inSup)
149+
.output(out)
150+
.range(rangeMap)
151+
.annotate(false)
152+
.logger(Constants.getTaskLogStream(getProject(), this.getName() + ".log"));
155153

156-
app.setOutLogger(Constants.getTaskLogStream(getProject(), this.getName() + ".log"));
154+
srg.forEach(builder::srg);
155+
exc.forEach(builder::exc);
157156

158-
app.setKeepImports(this.isS2sKeepImports());
159-
160-
if (!exc.isEmpty())
157+
if (this.isS2sKeepImports())
161158
{
162-
app.readParamMap(exc);
159+
builder.keepImports();
163160
}
164161

165-
// for debugging.
166-
app.dumpRenameMap();
167-
168-
app.remapSources(inSup, outSup, rangeMap, false);
162+
builder.build().run();
169163
}
170164

171165

src/main/java/net/minecraftforge/gradle/tasks/ExtractS2SRangeTask.java

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,14 @@
2020
package net.minecraftforge.gradle.tasks;
2121

2222
import java.io.File;
23-
import java.io.FileInputStream;
2423
import java.io.IOException;
25-
import java.io.PrintStream;
2624
import java.util.List;
2725

2826
import net.minecraftforge.gradle.common.Constants;
2927
import net.minecraftforge.gradle.util.SequencedInputSupplier;
3028
import net.minecraftforge.gradle.util.SourceDirSetSupplier;
31-
import net.minecraftforge.srg2source.ast.RangeExtractor;
29+
import net.minecraftforge.srg2source.api.RangeExtractorBuilder;
30+
import net.minecraftforge.srg2source.api.SourceVersion;
3231
import net.minecraftforge.srg2source.util.io.FolderSupplier;
3332
import net.minecraftforge.srg2source.util.io.InputSupplier;
3433
import net.minecraftforge.srg2source.util.io.ZipInputSupplier;
@@ -82,31 +81,20 @@ public void doTask() throws IOException
8281

8382
private void generateRangeMap(InputSupplier inSup, File rangeMap) throws IOException
8483
{
85-
RangeExtractor extractor = new RangeExtractor(RangeExtractor.JAVA_1_8);
84+
RangeExtractorBuilder builder = new RangeExtractorBuilder()
85+
.sourceCompatibility(SourceVersion.JAVA_1_8)
86+
.input(inSup)
87+
.output(rangeMap)
88+
.logger(Constants.getTaskLogStream(getProject(), this.getName() + ".log"));
8689

87-
for (File f : getLibs())
88-
{
89-
//System.out.println("lib: "+f);
90-
extractor.addLibs(f);
91-
}
90+
getLibs().forEach(builder::library);
9291

9392
if (rangeMap.exists())
9493
{
95-
extractor.loadCache(new FileInputStream(rangeMap));
94+
builder.cache(rangeMap);
9695
}
9796

98-
extractor.setSrc(inSup);
99-
100-
//extractor.addLibs(getLibs().getAsPath()).setSrc(inSup);
101-
102-
PrintStream stream = new PrintStream(Constants.getTaskLogStream(getProject(), this.getName() + ".log"));
103-
extractor.setOutLogger(stream);
104-
105-
boolean worked = extractor.generateRangeMap(rangeMap);
106-
107-
stream.close();
108-
109-
if (!worked)
97+
if (!builder.build().run())
11098
throw new RuntimeException("RangeMap generation Failed!!!");
11199
}
112100

0 commit comments

Comments
 (0)