switch to fernflower, add line number remapping
This commit is contained in:
		
							parent
							
								
									d40d886f57
								
							
						
					
					
						commit
						836b321107
					
				
					 6 changed files with 424 additions and 86 deletions
				
			
		|  | @ -35,10 +35,11 @@ dependencies { | |||
| 	implementation ('com.google.code.gson:gson:2.8.5') | ||||
| 	implementation ('com.google.guava:guava:27.0.1-jre') | ||||
| 	implementation ('net.fabricmc:stitch:0.1.0.17') | ||||
| 	implementation ('net.fabricmc:tiny-remapper:0.1.0.19') { | ||||
| 	implementation ('net.fabricmc:tiny-remapper:0.1.0.20') { | ||||
| 		transitive = false | ||||
| 	} | ||||
| 	implementation ('org.benf:cfr:0.136') | ||||
| //	implementation ('org.benf:cfr:0.136') | ||||
| 	implementation ('org.jetbrains:intellij-fernflower:1.0.0.2') | ||||
| 
 | ||||
| 	implementation ('net.fabricmc:sponge-mixin:0.7.11.3') { | ||||
| 		exclude module: 'launchwrapper' | ||||
|  | @ -50,6 +51,7 @@ jar { | |||
| 	manifest { | ||||
| 		attributes 'Implementation-Version': version + " Build(" + build + ")" | ||||
| 	} | ||||
| 	from { zipTree("/home/asie/intellij-fernflower-1.0.0.2.jar") } | ||||
| } | ||||
| 
 | ||||
| task sourcesJar(type: Jar, dependsOn: classes) { | ||||
|  |  | |||
							
								
								
									
										118
									
								
								src/main/java/net/fabricmc/loom/task/GenSourcesCfrTask.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								src/main/java/net/fabricmc/loom/task/GenSourcesCfrTask.java
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,118 @@ | |||
| /* | ||||
|  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||
|  * | ||||
|  * Copyright (c) 2016, 2017, 2018 FabricMC | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in all | ||||
|  * copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|  * SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| package net.fabricmc.loom.task; | ||||
| 
 | ||||
| import org.gradle.api.DefaultTask; | ||||
| 
 | ||||
| public class GenSourcesCfrTask extends DefaultTask { | ||||
| 	/* | ||||
| 	@TaskAction | ||||
| 	public void genSources() throws IOException { | ||||
| 		Project project = this.getProject(); | ||||
| 		LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); | ||||
| 		PomfProvider pomfProvider = extension.getPomfProvider(); | ||||
| 		File mappedJar = pomfProvider.mappedProvider.getMappedJar(); | ||||
| 		File sourcesJar = getSourcesJar(project); | ||||
| 
 | ||||
| 		Manifest manifest = new Manifest(); | ||||
| 		manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0"); | ||||
| 		Set<String> addedDirectories = new HashSet<>(); | ||||
| 
 | ||||
| 		try (FileOutputStream fos = new FileOutputStream(sourcesJar); | ||||
| 			JarOutputStream jos = new JarOutputStream(fos, manifest)) { | ||||
| 
 | ||||
| 			project.getLogger().lifecycle(":generating sources JAR"); | ||||
| 			CfrDriver driver = new CfrDriver.Builder() | ||||
| 					.withOptions(ImmutableMap.of("renameillegalidents","true")) | ||||
| 					.withOutputSink(new OutputSinkFactory() { | ||||
| 						@Override | ||||
| 						public List<SinkClass> getSupportedSinks(SinkType sinkType, Collection<SinkClass> collection) { | ||||
| 							switch (sinkType) { | ||||
| 								case PROGRESS: | ||||
| 									return Collections.singletonList(SinkClass.STRING); | ||||
| 								case JAVA: | ||||
| 									return Collections.singletonList(SinkClass.DECOMPILED); | ||||
| 								default: | ||||
| 									return Collections.emptyList(); | ||||
| 							} | ||||
| 						} | ||||
| 
 | ||||
| 						@Override | ||||
| 						public <T> Sink<T> getSink(SinkType sinkType, SinkClass sinkClass) { | ||||
| 							switch (sinkType) { | ||||
| 								case PROGRESS: | ||||
| 									return (t) -> getLogger().debug((String) t); | ||||
| 								case JAVA: | ||||
| 									//noinspection unchecked | ||||
| 									return (Sink<T>) new Sink<SinkReturns.Decompiled>() { | ||||
| 										@Override | ||||
| 										public void write(SinkReturns.Decompiled decompiled) { | ||||
| 											String filename = decompiled.getPackageName().replace('.', '/'); | ||||
| 											if (!filename.isEmpty()) filename += "/"; | ||||
| 											filename += decompiled.getClassName() + ".java"; | ||||
| 
 | ||||
| 											String[] path = filename.split("/"); | ||||
| 											String pathPart = ""; | ||||
| 											for (int i = 0; i < path.length - 1; i++) { | ||||
| 												pathPart += path[i] + "/"; | ||||
| 												if (addedDirectories.add(pathPart)) { | ||||
| 													JarEntry entry = new JarEntry(pathPart); | ||||
| 													entry.setTime(new Date().getTime()); | ||||
| 
 | ||||
| 													try { | ||||
| 														jos.putNextEntry(entry); | ||||
| 														jos.closeEntry(); | ||||
| 													} catch (IOException e) { | ||||
| 														throw new RuntimeException(e); | ||||
| 													} | ||||
| 												} | ||||
| 											} | ||||
| 
 | ||||
| 											byte[] data = decompiled.getJava().getBytes(Charsets.UTF_8); | ||||
| 											JarEntry entry = new JarEntry(filename); | ||||
| 											entry.setTime(new Date().getTime()); | ||||
| 											entry.setSize(data.length); | ||||
| 
 | ||||
| 											try { | ||||
| 												jos.putNextEntry(entry); | ||||
| 												jos.write(data); | ||||
| 												jos.closeEntry(); | ||||
| 											} catch (IOException e) { | ||||
| 												throw new RuntimeException(e); | ||||
| 											} | ||||
| 										} | ||||
| 									}; | ||||
| 								default: | ||||
| 									return (t) -> {}; | ||||
| 							} | ||||
| 						} | ||||
| 					}) | ||||
| 					.build(); | ||||
| 
 | ||||
| 			driver.analyse(Collections.singletonList(mappedJar.getAbsolutePath())); | ||||
| 		} | ||||
| 	} | ||||
| 	*/ | ||||
| } | ||||
|  | @ -24,33 +24,26 @@ | |||
| 
 | ||||
| package net.fabricmc.loom.task; | ||||
| 
 | ||||
| import com.google.common.base.Charsets; | ||||
| import com.google.common.collect.ImmutableMap; | ||||
| import com.google.common.io.ByteStreams; | ||||
| import net.fabricmc.loom.LoomGradleExtension; | ||||
| import net.fabricmc.loom.providers.MinecraftProvider; | ||||
| import net.fabricmc.loom.providers.MinecraftLibraryProvider; | ||||
| import net.fabricmc.loom.providers.PomfProvider; | ||||
| import net.fabricmc.loom.util.MinecraftVersionInfo; | ||||
| import org.benf.cfr.reader.api.CfrDriver; | ||||
| import org.benf.cfr.reader.api.ClassFileSource; | ||||
| import org.benf.cfr.reader.api.OutputSinkFactory; | ||||
| import org.benf.cfr.reader.api.SinkReturns; | ||||
| import org.benf.cfr.reader.entities.Method; | ||||
| import org.benf.cfr.reader.util.output.StreamDumper; | ||||
| import org.gradle.api.DefaultTask; | ||||
| import org.gradle.api.Project; | ||||
| import org.gradle.api.tasks.TaskAction; | ||||
| import org.xml.sax.SAXException; | ||||
| import org.jetbrains.java.decompiler.main.ClassReference14Processor; | ||||
| import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger; | ||||
| import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; | ||||
| import org.objectweb.asm.ClassReader; | ||||
| import org.objectweb.asm.ClassWriter; | ||||
| import org.objectweb.asm.Opcodes; | ||||
| 
 | ||||
| import javax.xml.parsers.ParserConfigurationException; | ||||
| import javax.xml.transform.TransformerException; | ||||
| import java.io.File; | ||||
| import java.io.FileInputStream; | ||||
| import java.io.FileOutputStream; | ||||
| import java.io.IOException; | ||||
| import java.util.*; | ||||
| import java.util.jar.Attributes; | ||||
| import java.util.jar.JarEntry; | ||||
| import java.util.jar.JarOutputStream; | ||||
| import java.util.jar.Manifest; | ||||
| import java.util.jar.*; | ||||
| 
 | ||||
| public class GenSourcesTask extends DefaultTask { | ||||
| 	public static File getSourcesJar(Project project) { | ||||
|  | @ -69,86 +62,82 @@ public class GenSourcesTask extends DefaultTask { | |||
| 	public void genSources() throws IOException { | ||||
| 		Project project = this.getProject(); | ||||
| 		LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); | ||||
| 		MinecraftLibraryProvider libraryProvider = extension.getMinecraftProvider().libraryProvider; | ||||
| 		PomfProvider pomfProvider = extension.getPomfProvider(); | ||||
| 		File mappedJar = pomfProvider.mappedProvider.getMappedJar(); | ||||
| 		File sourcesJar = getSourcesJar(project); | ||||
| 
 | ||||
| 		Manifest manifest = new Manifest(); | ||||
| 		manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0"); | ||||
| 		Set<String> addedDirectories = new HashSet<>(); | ||||
| 
 | ||||
| 		try (FileOutputStream fos = new FileOutputStream(sourcesJar); | ||||
| 			JarOutputStream jos = new JarOutputStream(fos, manifest)) { | ||||
| 		project.getLogger().lifecycle(":preparing sources JAR"); | ||||
| 		Map<String, Object> options = new HashMap<>(); | ||||
| 		options.put(IFernflowerPreferences.DECOMPILE_GENERIC_SIGNATURES, "1"); | ||||
| 		options.put(IFernflowerPreferences.BYTECODE_SOURCE_MAPPING, "1"); | ||||
| 
 | ||||
| 			project.getLogger().lifecycle(":generating sources JAR"); | ||||
| 			CfrDriver driver = new CfrDriver.Builder() | ||||
| 					.withOptions(ImmutableMap.of("renameillegalidents","true")) | ||||
| 					.withOutputSink(new OutputSinkFactory() { | ||||
| 						@Override | ||||
| 						public List<SinkClass> getSupportedSinks(SinkType sinkType, Collection<SinkClass> collection) { | ||||
| 							switch (sinkType) { | ||||
| 								case PROGRESS: | ||||
| 									return Collections.singletonList(SinkClass.STRING); | ||||
| 								case JAVA: | ||||
| 									return Collections.singletonList(SinkClass.DECOMPILED); | ||||
| 								default: | ||||
| 									return Collections.emptyList(); | ||||
| 							} | ||||
| 		LoomFernflowerDecompiler decompiler = new LoomFernflowerDecompiler(sourcesJar.getParentFile(), sourcesJar.getName(), options, new LoomFernflowerLogger()); | ||||
| 		decompiler.addSource(mappedJar); | ||||
| 		for (File lib : libraryProvider.getLibraries()) { | ||||
| 			try { | ||||
| 				decompiler.addLibrary(lib); | ||||
| 			} catch (Exception e) { | ||||
| 				// pass | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		project.getLogger().lifecycle(":generating sources JAR"); | ||||
| 		decompiler.decompileContext(); | ||||
| 
 | ||||
| 		Map<String, int[]> mapNumbers = decompiler.getDifferingMappings(); | ||||
| 		if (!mapNumbers.isEmpty()) { | ||||
| 			project.getLogger().lifecycle(":readjusting line numbers"); | ||||
| 
 | ||||
| 			File tmpJar = new File(mappedJar.getAbsolutePath() + ".tmp"); | ||||
| 			mappedJar.renameTo(tmpJar); | ||||
| 			try ( | ||||
| 					FileInputStream fis = new FileInputStream(tmpJar); | ||||
| 					JarInputStream jis = new JarInputStream(fis); | ||||
| 					FileOutputStream fos = new FileOutputStream(mappedJar); | ||||
| 					JarOutputStream jos = new JarOutputStream(fos) | ||||
| 					) { | ||||
| 				JarEntry entry; | ||||
| 
 | ||||
| 				while ((entry = jis.getNextJarEntry()) != null) { | ||||
| 					JarEntry outputEntry = new JarEntry(entry.getName()); | ||||
| 					outputEntry.setTime(entry.getTime()); | ||||
| 					outputEntry.setCreationTime(entry.getCreationTime()); | ||||
| 					outputEntry.setLastAccessTime(entry.getLastAccessTime()); | ||||
| 					outputEntry.setLastModifiedTime(entry.getLastModifiedTime()); | ||||
| 
 | ||||
| 					if (!entry.getName().endsWith(".class")) { | ||||
| 						jos.putNextEntry(outputEntry); | ||||
| 						ByteStreams.copy(jis, jos); | ||||
| 						jos.closeEntry(); | ||||
| 					} else { | ||||
| 						String idx = entry.getName().substring(0, entry.getName().length() - 6); | ||||
| 						int dollarPos = idx.indexOf('$'); | ||||
| 						if (dollarPos >= 0) { | ||||
| 							idx = idx.substring(0, dollarPos); | ||||
| 						} | ||||
| 
 | ||||
| 						@Override | ||||
| 						public <T> Sink<T> getSink(SinkType sinkType, SinkClass sinkClass) { | ||||
| 							switch (sinkType) { | ||||
| 								case PROGRESS: | ||||
| 									return (t) -> getLogger().debug((String) t); | ||||
| 								case JAVA: | ||||
| 									//noinspection unchecked | ||||
| 									return (Sink<T>) new Sink<SinkReturns.Decompiled>() { | ||||
| 										@Override | ||||
| 										public void write(SinkReturns.Decompiled decompiled) { | ||||
| 											String filename = decompiled.getPackageName().replace('.', '/'); | ||||
| 											if (!filename.isEmpty()) filename += "/"; | ||||
| 											filename += decompiled.getClassName() + ".java"; | ||||
| 						byte[] data = ByteStreams.toByteArray(jis); | ||||
| 						if (mapNumbers.containsKey(idx)) { | ||||
| 							ClassReader reader = new ClassReader(data); | ||||
| 							ClassWriter writer = new ClassWriter(0); | ||||
| 
 | ||||
| 											String[] path = filename.split("/"); | ||||
| 											String pathPart = ""; | ||||
| 											for (int i = 0; i < path.length - 1; i++) { | ||||
| 												pathPart += path[i] + "/"; | ||||
| 												if (addedDirectories.add(pathPart)) { | ||||
| 													JarEntry entry = new JarEntry(pathPart); | ||||
| 													entry.setTime(new Date().getTime()); | ||||
| 
 | ||||
| 													try { | ||||
| 														jos.putNextEntry(entry); | ||||
| 														jos.closeEntry(); | ||||
| 													} catch (IOException e) { | ||||
| 														throw new RuntimeException(e); | ||||
| 													} | ||||
| 												} | ||||
| 											} | ||||
| 
 | ||||
| 											byte[] data = decompiled.getJava().getBytes(Charsets.UTF_8); | ||||
| 											JarEntry entry = new JarEntry(filename); | ||||
| 											entry.setTime(new Date().getTime()); | ||||
| 											entry.setSize(data.length); | ||||
| 
 | ||||
| 											try { | ||||
| 												jos.putNextEntry(entry); | ||||
| 												jos.write(data); | ||||
| 												jos.closeEntry(); | ||||
| 											} catch (IOException e) { | ||||
| 												throw new RuntimeException(e); | ||||
| 											} | ||||
| 										} | ||||
| 									}; | ||||
| 								default: | ||||
| 									return (t) -> {}; | ||||
| 							} | ||||
| 							reader.accept(new LineNumberAdjustmentVisitor(Opcodes.ASM7, writer, mapNumbers.get(idx)), 0); | ||||
| 							data = writer.toByteArray(); | ||||
| 						} | ||||
| 					}) | ||||
| 					.build(); | ||||
| 
 | ||||
| 			driver.analyse(Collections.singletonList(mappedJar.getAbsolutePath())); | ||||
| 						jos.putNextEntry(outputEntry); | ||||
| 						jos.write(data); | ||||
| 						jos.closeEntry(); | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			//noinspection ResultOfMethodCallIgnored | ||||
| 			tmpJar.delete(); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,89 @@ | |||
| /* | ||||
|  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||
|  * | ||||
|  * Copyright (c) 2016, 2017, 2018 FabricMC | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in all | ||||
|  * copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|  * SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| package net.fabricmc.loom.task; | ||||
| 
 | ||||
| import org.objectweb.asm.ClassVisitor; | ||||
| import org.objectweb.asm.Label; | ||||
| import org.objectweb.asm.MethodVisitor; | ||||
| 
 | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| public class LineNumberAdjustmentVisitor extends ClassVisitor { | ||||
| 	public class Method extends MethodVisitor { | ||||
| 		public Method(int api, MethodVisitor methodVisitor) { | ||||
| 			super(api, methodVisitor); | ||||
| 		} | ||||
| 
 | ||||
| 		@Override | ||||
| 		public void visitLineNumber(final int line, final Label start) { | ||||
| 			int tLine = line; | ||||
| 			/* while (tLine >= 1 && !lineNumberMap.containsKey(tLine)) { | ||||
| 				tLine--; | ||||
| 			} */ | ||||
| 			while (tLine <= maxLine && !lineNumberMap.containsKey(tLine)) { | ||||
| 				tLine++; | ||||
| 			} | ||||
| 			if (tLine <= 0) { | ||||
| 				tLine = 1; | ||||
| 			} else if (tLine >= maxLine) { | ||||
| 				tLine = maxLineDst; | ||||
| 			} else { | ||||
| 				tLine = lineNumberMap.get(tLine); | ||||
| 			} | ||||
| 			super.visitLineNumber(tLine, start); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	private final Map<Integer, Integer> lineNumberMap; | ||||
| 	private int maxLine, maxLineDst; | ||||
| 
 | ||||
| 	public LineNumberAdjustmentVisitor(int api, ClassVisitor classVisitor, int[] mapping) { | ||||
| 		super(api, classVisitor); | ||||
| 
 | ||||
| 		lineNumberMap = new HashMap<>(); | ||||
| 		maxLine = 0; | ||||
| 
 | ||||
| 		for (int i = 0; i < mapping.length; i += 2) { | ||||
| 			lineNumberMap.put(mapping[i], mapping[i+1]); | ||||
| 			if (mapping[i] > maxLine) { | ||||
| 				maxLine = mapping[i]; | ||||
| 			} | ||||
| 			if (mapping[i+1] > maxLineDst) { | ||||
| 				maxLineDst = mapping[i+1]; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public MethodVisitor visitMethod( | ||||
| 			final int access, | ||||
| 			final String name, | ||||
| 			final String descriptor, | ||||
| 			final String signature, | ||||
| 			final String[] exceptions) { | ||||
| 		return new Method(api, super.visitMethod(access, name, descriptor, signature, exceptions)); | ||||
| 	} | ||||
| } | ||||
|  | @ -0,0 +1,96 @@ | |||
| /* | ||||
|  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||
|  * | ||||
|  * Copyright (c) 2016, 2017, 2018 FabricMC | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in all | ||||
|  * copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|  * SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| package net.fabricmc.loom.task; | ||||
| 
 | ||||
| import org.jetbrains.java.decompiler.main.decompiler.BaseDecompiler; | ||||
| import org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler; | ||||
| import org.jetbrains.java.decompiler.main.extern.IBytecodeProvider; | ||||
| import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger; | ||||
| import org.jetbrains.java.decompiler.main.extern.IResultSaver; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.util.*; | ||||
| import java.util.jar.JarEntry; | ||||
| import java.util.jar.JarOutputStream; | ||||
| import java.util.jar.Manifest; | ||||
| 
 | ||||
| public class LoomFernflowerDecompiler extends ConsoleDecompiler { | ||||
| 	private final Map<String, int[]> differingMappings = new HashMap<>(); | ||||
| 	private final String jarName; | ||||
| 
 | ||||
| 	public LoomFernflowerDecompiler(File destination, String jarName, Map<String, Object> options, IFernflowerLogger logger) { | ||||
| 		super(destination, options, logger); | ||||
| 		this.jarName = jarName; | ||||
| 	} | ||||
| 
 | ||||
| 	public Map<String, int[]> getDifferingMappings() { | ||||
| 		return differingMappings; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public void saveFolder(String s) { | ||||
| 		super.saveFolder(s); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public void copyFile(String s, String s1, String s2) { | ||||
| 		throw new RuntimeException("TODO copyFile " + s + " " + s1 + " " + s2); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public void saveClassFile(String s, String s1, String s2, String s3, int[] ints) { | ||||
| 		throw new RuntimeException("TODO saveClassFile " + s + " " + s1 + " " + s2 + " " + s3); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public void createArchive(String s, String s1, Manifest manifest) { | ||||
| 		super.createArchive(s, jarName, manifest); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public void saveDirEntry(String s, String s1, String s2) { | ||||
| 		super.saveDirEntry(s, jarName, s2); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public void copyEntry(String s, String s1, String s2, String s3) { | ||||
| 		super.copyEntry(s, s1, jarName, s3); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public void saveClassEntry(String s, String s1, String s2, String s3, String s4, int[] mapping) { | ||||
| 		if (mapping != null) { | ||||
| 			differingMappings.put(s2, mapping); | ||||
| 		} | ||||
| 
 | ||||
| 		super.saveClassEntry(s, jarName, s2, s3, s4, mapping); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public void closeArchive(String s, String s1) { | ||||
| 		super.closeArchive(s, jarName); | ||||
| 	} | ||||
| } | ||||
|  | @ -0,0 +1,44 @@ | |||
| /* | ||||
|  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||
|  * | ||||
|  * Copyright (c) 2016, 2017, 2018 FabricMC | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in all | ||||
|  * copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|  * SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| package net.fabricmc.loom.task; | ||||
| 
 | ||||
| import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger; | ||||
| 
 | ||||
| public class LoomFernflowerLogger extends IFernflowerLogger { | ||||
| 	@Override | ||||
| 	public void writeMessage(String s, Severity severity) { | ||||
| 		if (severity == Severity.WARN || severity == Severity.ERROR) { | ||||
| 			System.err.println(s); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public void writeMessage(String s, Severity severity, Throwable throwable) { | ||||
| 		if (severity == Severity.WARN || severity == Severity.ERROR) { | ||||
| 			System.err.println(s); | ||||
| 			throwable.printStackTrace(System.err); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
		Loading…
	
		Reference in a new issue