Skip to content

Commit 3482e13

Browse files
authored
Merge pull request #305 from Vineflower/develop/1.9.3
Release 1.9.3
2 parents c537d08 + 67267ee commit 3482e13

File tree

17 files changed

+232
-122
lines changed

17 files changed

+232
-122
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Vineflower's features include:
1010
Examples of Vineflower's output, compared to other decompilers, can be found on [the wiki.](https://github.com/Vineflower/vineflower/wiki)
1111

1212
## Use
13-
Want to use Vineflower? There are a few ways! For Fabric and Architectury projects, [Loom Quiltflower](https://github.com/Juuxel/LoomQuiltflower) allows you to run genSources with Vineflower.
13+
Want to use Vineflower? There are a few ways! For Minecraft modding, [Loom Vineflower](https://github.com/Juuxel/loom-vineflower) allows you to generate sources with Vineflower.
1414
The [Vineflower Intellij IDEA plugin](https://plugins.jetbrains.com/plugin/18032-quiltflower) replaces Fernflower in IDEA with Vineflower, and allows you to modify its settings.
1515

1616
If you want to run Vineflower from the commandline, head over to the [Releases tab](https://github.com/Vineflower/vineflower/releases) and grab the latest release.
@@ -19,7 +19,7 @@ You can then run Vineflower with `java -jar vineflower.jar <arguments> <source>
1919
`<source>` can be a jar, zip, folder, or class file, and `<destination>` can be a folder, zip, jar, or excluded, to print to the console.
2020

2121

22-
To use Vineflower as a library, you can find distributions on maven central.
22+
To use Vineflower as a library, you can find distributions on maven central. Vineflower 1.9+ requires Java 11 or higher to run.
2323
Vineflower can be imported with gradle with:
2424
```groovy
2525
dependencies {
@@ -45,4 +45,4 @@ Vineflower is a fork of both Jetbrains' Fernflower and MinecraftForge's ForgeFlo
4545

4646
* Jetbrains- For maintaining Fernflower
4747
* Forge Team- For maintaining ForgeFlower
48-
* CFR- For it's large suite of very useful tests
48+
* CFR- For its large suite of very useful tests

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ compileJava {
2323
group = 'org.vineflower'
2424
archivesBaseName = 'vineflower'
2525

26-
version = '1.9.2'
26+
version = '1.9.3'
2727

2828
def ENV = System.getenv()
2929
version = version + (ENV.GITHUB_ACTIONS ? "" : "+local")

src/org/jetbrains/java/decompiler/main/ClassWriter.java

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -115,25 +115,29 @@ private static boolean invokeProcessors(TextBuffer buffer, ClassNode node) {
115115
DecompilerContext.getLogger().writeMessage("Class " + node.simpleName + " couldn't be written.",
116116
IFernflowerLogger.Severity.WARN,
117117
t);
118-
buffer.append("// $VF: Couldn't be decompiled");
119-
buffer.appendLineSeparator();
120-
if (DecompilerContext.getOption(IFernflowerPreferences.DUMP_EXCEPTION_ON_ERROR)) {
121-
List<String> lines = new ArrayList<>();
122-
lines.addAll(ClassWriter.getErrorComment());
123-
collectErrorLines(t, lines);
124-
for (String line : lines) {
125-
buffer.append("//");
126-
if (!line.isEmpty()) buffer.append(' ').append(line);
127-
buffer.appendLineSeparator();
128-
}
129-
}
118+
writeException(buffer, t);
130119

131120
return false;
132121
}
133122

134123
return true;
135124
}
136125

126+
public static void writeException(TextBuffer buffer, Throwable t) {
127+
buffer.append("// $VF: Couldn't be decompiled");
128+
buffer.appendLineSeparator();
129+
if (DecompilerContext.getOption(IFernflowerPreferences.DUMP_EXCEPTION_ON_ERROR)) {
130+
List<String> lines = new ArrayList<>();
131+
lines.addAll(ClassWriter.getErrorComment());
132+
collectErrorLines(t, lines);
133+
for (String line : lines) {
134+
buffer.append("//");
135+
if (!line.isEmpty()) buffer.append(' ').append(line);
136+
buffer.appendLineSeparator();
137+
}
138+
}
139+
}
140+
137141
public void classLambdaToJava(ClassNode node, TextBuffer buffer, Exprent method_object, int indent) {
138142
ClassWrapper wrapper = node.getWrapper();
139143
if (wrapper == null) {

src/org/jetbrains/java/decompiler/main/ClassesProcessor.java

Lines changed: 37 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,38 @@ else if (cl.superClass == null) { // neither interface nor super class defined
398398
return true;
399399
}
400400

401+
public void processClass(StructClass cl) throws IOException {
402+
ClassNode root = mapRootClasses.get(cl.qualifiedName);
403+
if (root.type != ClassNode.Type.ROOT) {
404+
return;
405+
}
406+
407+
boolean packageInfo = cl.isSynthetic() && "package-info".equals(root.simpleName);
408+
boolean moduleInfo = cl.hasModifier(CodeConstants.ACC_MODULE) && cl.hasAttribute(StructGeneralAttribute.ATTRIBUTE_MODULE);
409+
410+
DecompilerContext.getLogger().startProcessingClass(cl.qualifiedName);
411+
ImportCollector importCollector = new ImportCollector(root);
412+
DecompilerContext.startClass(importCollector);
413+
try {
414+
if (!packageInfo && !moduleInfo) {
415+
new LambdaProcessor().processClass(root);
416+
417+
// add simple class names to implicit import
418+
addClassNameToImport(root, importCollector);
419+
420+
// build wrappers for all nested classes (that's where actual processing takes place)
421+
initWrappers(root);
422+
423+
// Java specific last minute processing
424+
new NestedClassProcessor().processClass(root, root);
425+
426+
new NestedMemberAccess().propagateMemberAccess(root);
427+
}
428+
} finally {
429+
DecompilerContext.getLogger().endProcessingClass();
430+
}
431+
}
432+
401433
public void writeClass(StructClass cl, TextBuffer buffer) throws IOException {
402434
ClassNode root = mapRootClasses.get(cl.qualifiedName);
403435
if (root.type != ClassNode.Type.ROOT) {
@@ -409,76 +441,25 @@ public void writeClass(StructClass cl, TextBuffer buffer) throws IOException {
409441

410442
DecompilerContext.getLogger().startReadingClass(cl.qualifiedName);
411443
try {
412-
ImportCollector importCollector = new ImportCollector(root);
413-
DecompilerContext.startClass(importCollector);
414-
415444
if (packageInfo) {
416445
ClassWriter.packageInfoToJava(cl, buffer);
417446

418-
importCollector.writeImports(buffer, false);
447+
DecompilerContext.getImportCollector().writeImports(buffer, false);
419448
}
420449
else if (moduleInfo) {
421450
TextBuffer moduleBuffer = new TextBuffer(AVERAGE_CLASS_SIZE);
422451
ClassWriter.moduleInfoToJava(cl, moduleBuffer);
423452

424-
importCollector.writeImports(buffer, true);
453+
DecompilerContext.getImportCollector().writeImports(buffer, true);
425454

426455
buffer.append(moduleBuffer);
427456
}
428457
else {
429-
try {
430-
new LambdaProcessor().processClass(root);
431-
} catch (Throwable t) {
432-
DecompilerContext.getLogger().writeMessage("Class " + root.simpleName + " couldn't be written.",
433-
IFernflowerLogger.Severity.WARN,
434-
t);
435-
buffer.append("// $VF: Couldn't be decompiled");
436-
buffer.appendLineSeparator();
437-
if (DecompilerContext.getOption(IFernflowerPreferences.DUMP_EXCEPTION_ON_ERROR)) {
438-
List<String> lines = new ArrayList<>();
439-
lines.addAll(ClassWriter.getErrorComment());
440-
ClassWriter.collectErrorLines(t, lines);
441-
for (String line : lines) {
442-
buffer.append("//");
443-
if (!line.isEmpty()) buffer.append(' ').append(line);
444-
buffer.appendLineSeparator();
445-
}
446-
}
447-
return;
448-
}
449-
450-
// add simple class names to implicit import
451-
addClassNameToImport(root, importCollector);
452-
453-
// build wrappers for all nested classes (that's where actual processing takes place)
454-
initWrappers(root);
455-
456-
try {
457-
new NestedClassProcessor().processClass(root, root);
458-
459-
new NestedMemberAccess().propagateMemberAccess(root);
460-
} catch (Throwable t) {
461-
DecompilerContext.getLogger().writeMessage("Class " + root.simpleName + " couldn't be written.",
462-
IFernflowerLogger.Severity.WARN,
463-
t);
464-
buffer.append("// $VF: Couldn't be decompiled");
465-
buffer.appendLineSeparator();
466-
if (DecompilerContext.getOption(IFernflowerPreferences.DUMP_EXCEPTION_ON_ERROR)) {
467-
List<String> lines = new ArrayList<>();
468-
lines.addAll(ClassWriter.getErrorComment());
469-
ClassWriter.collectErrorLines(t, lines);
470-
for (String line : lines) {
471-
buffer.append("//");
472-
if (!line.isEmpty()) buffer.append(' ').append(line);
473-
buffer.appendLineSeparator();
474-
}
475-
}
476-
return;
477-
}
478-
479458
TextBuffer classBuffer = new TextBuffer(AVERAGE_CLASS_SIZE);
459+
480460
new ClassWriter().classToJava(root, classBuffer, 0);
481461
classBuffer.reformat();
462+
482463
classBuffer.getTracers().forEach((classAndMethod, tracer) -> {
483464
// get the class by name
484465
StructClass clazz = DecompilerContext.getStructContext().getClass(classAndMethod.a);
@@ -500,7 +481,7 @@ else if (moduleInfo) {
500481
buffer.append("package ").append(packageName).append(';').appendLineSeparator().appendLineSeparator();
501482
}
502483

503-
importCollector.writeImports(buffer, true);
484+
DecompilerContext.getImportCollector().writeImports(buffer, true);
504485

505486
int offsetLines = buffer.countLines();
506487

src/org/jetbrains/java/decompiler/main/DecompilerContext.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,11 @@ public static DecompilerContext getCurrentContext() {
6464
}
6565

6666
public static void setCurrentContext(DecompilerContext context) {
67-
currentContext.set(context);
67+
if (context == null) {
68+
currentContext.remove();
69+
} else {
70+
currentContext.set(context);
71+
}
6872
}
6973

7074
public static void setProperty(String key, Object value) {

src/org/jetbrains/java/decompiler/main/Fernflower.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import org.jetbrains.java.decompiler.util.TextBuffer;
1717

1818
import java.io.File;
19+
import java.io.IOException;
1920
import java.util.ArrayList;
2021
import java.util.HashMap;
2122
import java.util.List;
@@ -168,15 +169,20 @@ else if (converter != null) {
168169
}
169170
}
170171

172+
@Override
173+
public void processClass(final StructClass cl) throws IOException {
174+
classProcessor.processClass(cl); // unhandled exceptions handled later on
175+
}
176+
171177
@Override
172178
public String getClassContent(StructClass cl) {
179+
TextBuffer buffer = new TextBuffer(ClassesProcessor.AVERAGE_CLASS_SIZE);
173180
try {
174-
TextBuffer buffer = new TextBuffer(ClassesProcessor.AVERAGE_CLASS_SIZE);
175181
buffer.append(DecompilerContext.getProperty(IFernflowerPreferences.BANNER).toString());
176182
classProcessor.writeClass(cl, buffer);
177183
String res = buffer.convertToStringAndAllowDataDiscard();
178184
if (res == null) {
179-
return "$ FF: Unable to decompile class " + cl.qualifiedName;
185+
return "$ VF: Unable to decompile class " + cl.qualifiedName;
180186
}
181187

182188
return res;
@@ -190,7 +196,7 @@ public String getClassContent(StructClass cl) {
190196
lines.addAll(ClassWriter.getErrorComment());
191197
ClassWriter.collectErrorLines(t, lines);
192198
lines.add("*/");
193-
return String.join("\n", lines);
199+
return String.join(DecompilerContext.getNewLineSeparator(), lines);
194200
} else {
195201
return null;
196202
}

src/org/jetbrains/java/decompiler/main/decompiler/PrintStreamLogger.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,21 @@ public void writeMessage(String message, Severity severity, Throwable t) {
3232
}
3333
}
3434

35+
public void startProcessingClass(String className) {
36+
if (accepts(Severity.INFO)) {
37+
writeMessage("Preprocessing class " + className, Severity.INFO);
38+
indent.get().incrementAndGet();
39+
}
40+
}
41+
42+
@Override
43+
public void endProcessingClass() {
44+
if (accepts(Severity.INFO)) {
45+
indent.get().decrementAndGet();
46+
writeMessage("... done", Severity.INFO);
47+
}
48+
}
49+
3550
@Override
3651
public void startReadingClass(String className) {
3752
if (accepts(Severity.INFO)) {

src/org/jetbrains/java/decompiler/main/extern/IFernflowerLogger.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ public void writeMessage(String message, Throwable t) {
3131
writeMessage(message, Severity.ERROR, t);
3232
}
3333

34+
public void startProcessingClass(String className) { }
35+
36+
public void endProcessingClass() { }
37+
3438
public void startReadingClass(String className) { }
3539

3640
public void endReadingClass() { }

src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ else if (UNINLINED_DOUBLES.containsKey(doubleVal)) {
319319
// This patch is based on work in ForgeFlower submitted by Pokechu22.
320320
float floatRepresentation = (float) doubleVal;
321321
if (floatRepresentation == doubleVal) {
322-
if (Float.toString(floatRepresentation).length() < Double.toString(doubleVal).length()) {
322+
if (trimFloat(Float.toString(floatRepresentation), floatRepresentation).length() < trimDouble(Double.toString(doubleVal), doubleVal).length()) {
323323
// Check the uninlined values to see if we have one of those
324324
if (UNINLINED_FLOATS.containsKey(floatRepresentation)) {
325325
return buf.append(UNINLINED_FLOATS.get(floatRepresentation).apply(bytecode));

0 commit comments

Comments
 (0)