Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions FernFlower-Patches/0016-Add-better-debug-logging.patch
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,32 @@ Date: Mon, 25 Sep 2017 13:46:14 -0700
Subject: [PATCH] Add better debug logging


diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java
index 632a12c7bee16de80b5edc011d4aac783b4dc76a..490c01566b62aab791ef7be41ec0852fbb966ccc 100644
--- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java
+++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java
@@ -939,7 +939,7 @@ public class ClassWriter {
tracer.addTracer(codeTracer);
}
catch (Throwable t) {
- String message = "Method " + mt.getName() + " " + mt.getDescriptor() + " couldn't be written.";
+ String message = "Method " + mt.getName() + " " + mt.getDescriptor() + " in class " + node.classStruct.qualifiedName + " couldn't be written.";
DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN, t);
methodWrapper.decompiledWithErrors = true;
}
diff --git a/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java b/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java
index 438b04c518f193ac3b229701ddfdaf7cde5cad6e..9ce662b88d6a7406784b8aa1b4e1dc6700cebaa6 100644
--- a/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java
+++ b/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java
@@ -122,7 +122,7 @@ public class ClassWrapper {
}
}
catch (Throwable t) {
- String message = "Method " + mt.getName() + " " + mt.getDescriptor() + " couldn't be decompiled.";
+ String message = "Method " + mt.getName() + " " + mt.getDescriptor() + " in class " + classStruct.qualifiedName + " couldn't be decompiled.";
DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN, t);
isError = true;
}
diff --git a/src/org/jetbrains/java/decompiler/struct/StructContext.java b/src/org/jetbrains/java/decompiler/struct/StructContext.java
index 36d1d6c4ae8e3b9f1a64dae514d9efa65722033a..7c91206d1b64b9873fa24d6d3ad38e736413c0a3 100644
--- a/src/org/jetbrains/java/decompiler/struct/StructContext.java
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Subject: [PATCH] Add a metadata file named
Format: ClassName MethodName Descriptor Param1[ Param2...]

diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java
index 632a12c7bee16de80b5edc011d4aac783b4dc76a..124cdd01c4b531937373127576b7f6db90ed48ed 100644
index 490c01566b62aab791ef7be41ec0852fbb966ccc..dda37ca0513494ca951c1cff0d363c1dcb36b6e1 100644
--- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java
+++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java
@@ -870,7 +870,9 @@ public class ClassWriter {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,30 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Justin <jrd2558@gmail.com>
Date: Thu, 26 Jul 2018 13:28:40 -0700
Subject: [PATCH] Synthetic getClass cleanup
Subject: [PATCH] Synthetic getClass/Objects.requireNonNull cleanup


diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java
index 474ffda1b9d610968bd12160f2153713b37f2db9..4933b5c1d375b7beacbb521bc8770cf295e7d98c 100644
index 474ffda1b9d610968bd12160f2153713b37f2db9..eef5cdaf7fa5c425abddea9ab0717f6844c97460 100644
--- a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java
+++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java
@@ -617,6 +617,20 @@ public class ExprProcessor implements CodeConstants {
@@ -617,6 +617,23 @@ public class ExprProcessor implements CodeConstants {
break;
case opc_pop:
stack.pop();
+ // check for synthetic getClass calls added by the compiler
+ // check for synthetic getClass (J8) / Objects.requireNonNull() (J9+) calls added by the compiler
+ // see https://stackoverflow.com/a/20130641
+ if (i > 0) {
+ Exprent last = exprlist.get(exprlist.size() - 1);
+ if (last.type == Exprent.EXPRENT_ASSIGNMENT && ((AssignmentExprent)last).getRight().type == Exprent.EXPRENT_INVOCATION) {
+ InvocationExprent invocation = (InvocationExprent)((AssignmentExprent)last).getRight();
+ if (i + 1 < seq.length() && !invocation.isStatic() && invocation.getName().equals("getClass") && invocation.getStringDescriptor().equals("()Ljava/lang/Class;")) {
+ int nextOpc = seq.getInstr(i + 1).opcode;
+ if (nextOpc >= opc_aconst_null && nextOpc <= opc_ldc2_w) {
+ invocation.setSyntheticGetClass();
+ InvocationExprent invocation = (InvocationExprent) ((AssignmentExprent) last).getRight();
+ if (i + 1 < seq.length()) {
+ if ((!invocation.isStatic() && invocation.getName().equals("getClass") && invocation.getStringDescriptor().equals("()Ljava/lang/Class;")) // J8
+ || (invocation.isStatic() && invocation.getClassname().equals("java/util/Objects") && invocation.getName().equals("requireNonNull") && invocation.getStringDescriptor().equals("(Ljava/lang/Object;)Ljava/lang/Object;"))) { // J9+
+ int nextOpc = seq.getInstr(i + 1).opcode;
+ if (nextOpc >= opc_aconst_null && nextOpc <= opc_ldc2_w) {
+ invocation.setSyntheticNullCheck();
+ }
+ }
+ }
+ }
Expand All @@ -30,7 +33,7 @@ index 474ffda1b9d610968bd12160f2153713b37f2db9..4933b5c1d375b7beacbb521bc8770cf2
case opc_pop2:
if (stack.getByOffset(-1).getExprType().stackSize == 1) {
diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java
index 986a8a72ec138ea637d3446ed2e823f6100c31cc..767f6bdb92ecf0ba0bc4a437b8bf8482fa47bdea 100644
index 986a8a72ec138ea637d3446ed2e823f6100c31cc..fa48cab3cb2b7da418322db7c10952f2f965e495 100644
--- a/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java
+++ b/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java
@@ -71,6 +71,10 @@ public class SimplifyExprentsHelper {
Expand All @@ -44,7 +47,7 @@ index 986a8a72ec138ea637d3446ed2e823f6100c31cc..767f6bdb92ecf0ba0bc4a437b8bf8482
}

res |= changed;
@@ -505,21 +509,43 @@ public class SimplifyExprentsHelper {
@@ -505,21 +509,53 @@ public class SimplifyExprentsHelper {
return false;
}

Expand All @@ -69,10 +72,12 @@ index 986a8a72ec138ea637d3446ed2e823f6100c31cc..767f6bdb92ecf0ba0bc4a437b8bf8482

- if (!invocation.isStatic() && invocation.getInstance().type == Exprent.EXPRENT_VAR && invocation.getName().equals("getClass") &&
- invocation.getStringDescriptor().equals("()Ljava/lang/Class;")) {
+ if (!invocation.isStatic() &&
+ invocation.getName().equals("getClass") && invocation.getStringDescriptor().equals("()Ljava/lang/Class;")) {
+ if ((!invocation.isStatic() &&
+ invocation.getName().equals("getClass") && invocation.getStringDescriptor().equals("()Ljava/lang/Class;")) // J8
+ || (invocation.isStatic() && invocation.getClassname().equals("java/util/Objects") && invocation.getName().equals("requireNonNull")
+ && invocation.getStringDescriptor().equals("(Ljava/lang/Object;)Ljava/lang/Object;"))) { // J9+
+
+ if (invocation.isSyntheticGetClass()) {
+ if (invocation.isSyntheticNullCheck()) {
+ return true;
+ }

Expand All @@ -81,48 +86,56 @@ index 986a8a72ec138ea637d3446ed2e823f6100c31cc..767f6bdb92ecf0ba0bc4a437b8bf8482
lstExprents.add(second);

- for (Exprent expr : lstExprents) {
+ while (!lstExprents.isEmpty()){
+ final Exprent target;
+ if (invocation.isStatic()) { // Objects.requireNonNull(target) (J9+)
+ // detect target type
+ target = invocation.getLstParameters().get(0);
+ } else { // target.getClass() (J8)
+ target = invocation.getInstance();
+ }
+
+ while (!lstExprents.isEmpty()) {
+ Exprent expr = lstExprents.removeFirst();
+ lstExprents.addAll(expr.getAllExprents());
if (expr.type == Exprent.EXPRENT_NEW) {
NewExprent newExpr = (NewExprent)expr;
if (newExpr.getConstructor() != null && !newExpr.getConstructor().getLstParameters().isEmpty() &&
- newExpr.getConstructor().getLstParameters().get(0).equals(invocation.getInstance())) {
+ (newExpr.getConstructor().getLstParameters().get(0).equals(invocation.getInstance()) ||
+ newExpr.getConstructor().getLstParameters().get(0).getExprType().equals(invocation.getInstance().getExprType()))) {
+ (newExpr.getConstructor().getLstParameters().get(0).equals(target) ||
+ newExpr.getConstructor().getLstParameters().get(0).getExprType().equals(target.getExprType()))) {

String classname = newExpr.getNewType().value;
ClassNode node = DecompilerContext.getClassProcessor().getMapRootClasses().get(classname);
diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java
index 9d4eae94966f13ef56e710f53f67f84ef5a50cd3..c5152f9053b274870b5da08acbddb89b12ac0516 100644
index 9d4eae94966f13ef56e710f53f67f84ef5a50cd3..16158a3d134c7af2ecdf58a539ff1d33ba80c6b9 100644
--- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java
+++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java
@@ -61,6 +61,7 @@ public class InvocationExprent extends Exprent {
private List<VarType> genericArgs = new ArrayList<>();
private boolean forceBoxing = false;
private boolean forceUnboxing = false;
+ private boolean isSyntheticGetClass = false;
+ private boolean isSyntheticNullCheck = false;

public InvocationExprent() {
super(EXPRENT_INVOCATION);
@@ -161,6 +162,7 @@ public class InvocationExprent extends Exprent {

addBytecodeOffsets(expr.bytecode);
bootstrapArguments = expr.getBootstrapArguments();
+ isSyntheticGetClass = expr.isSyntheticGetClass();
+ isSyntheticNullCheck = expr.isSyntheticNullCheck();
}

@Override
@@ -970,6 +972,14 @@ public class InvocationExprent extends Exprent {
return bootstrapArguments;
}

+ public void setSyntheticGetClass() {
+ isSyntheticGetClass = true;
+ public void setSyntheticNullCheck() {
+ isSyntheticNullCheck = true;
+ }
+
+ public boolean isSyntheticGetClass() {
+ return isSyntheticGetClass;
+ public boolean isSyntheticNullCheck() {
+ return isSyntheticNullCheck;
+ }
+
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,23 @@ Subject: [PATCH] Prioritize self and enclosing class when encountering
The compiler encodes all REFERENCED inner classes into the class. The first found used to win, but now ThisClass > EnclosingClass > Others AccessTransformers only edit the targeted class as it can't find all references.
Fixes AccessTransformers.

Add -win option to suppress warnings on inconsistent inner class
information.

diff --git a/README.md b/README.md
index 225b42bcbd388c395fe51d2c5edda8d1cb1127b2..c41dd217b88663552b02ceac510ae13199b64b3c 100644
--- a/README.md
+++ b/README.md
@@ -64,6 +64,7 @@ The rest of options can be left as they are: they are aimed at professional reve
- inn (1): check for IntelliJ IDEA-specific @NotNull annotation and remove inserted code if found
- lac (0): decompile lambda expressions to anonymous classes
- nls (0): define new line character to be used for output. 0 - '\r\n' (Windows), 1 - '\n' (Unix), default is OS-dependent
+- win (1): Whether to warn on inconsistent inner class entries
- ind: indentation string (default is 3 spaces)
- log (INFO): a logging level, possible values are TRACE, INFO, WARN, ERROR

diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java
index 124cdd01c4b531937373127576b7f6db90ed48ed..908ec69d788adf63487106715f82141cc1c43dac 100644
index dda37ca0513494ca951c1cff0d363c1dcb36b6e1..6f22466edd1c87e6786ff08498b69005aca41e3e 100644
--- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java
+++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java
@@ -1180,6 +1180,10 @@ public class ClassWriter {
Expand All @@ -23,7 +38,7 @@ index 124cdd01c4b531937373127576b7f6db90ed48ed..908ec69d788adf63487106715f82141c
buffer.append('<');

diff --git a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java
index 26ccf4b2124ab617bfeec45ebbf3451ab2e7aa6d..8ce3a2575b4c9c8268ba9956ea008027982a03fb 100644
index 26ccf4b2124ab617bfeec45ebbf3451ab2e7aa6d..80b8fd01286f90c3f194385edef47df805611c98 100644
--- a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java
+++ b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java
@@ -42,10 +42,20 @@ public class ClassesProcessor implements CodeConstants {
Expand Down Expand Up @@ -55,12 +70,18 @@ index 26ccf4b2124ab617bfeec45ebbf3451ab2e7aa6d..8ce3a2575b4c9c8268ba9956ea008027

// nested class type
if (entry.innerName != null) {
@@ -132,6 +143,13 @@ public class ClassesProcessor implements CodeConstants {
@@ -130,8 +141,17 @@ public class ClassesProcessor implements CodeConstants {
mapInnerClasses.put(innerName, rec);
}
else if (!Inner.equal(existingRec, rec)) {
String message = "Inconsistent inner class entries for " + innerName + "!";
DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN);
+ DecompilerContext.getLogger().writeMessage(" Old: " + existingRec.toString(), IFernflowerLogger.Severity.WARN);
+ DecompilerContext.getLogger().writeMessage(" New: " + rec.toString(), IFernflowerLogger.Severity.WARN);
- String message = "Inconsistent inner class entries for " + innerName + "!";
- DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN);
+ if (DecompilerContext.getOption(IFernflowerPreferences.WARN_INCONSISTENT_INNER_CLASSES)) {
+ String message = "Inconsistent inner class entries for " + innerName + "!";
+ DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN);
+ DecompilerContext.getLogger().writeMessage(" Old: " + existingRec.toString(), IFernflowerLogger.Severity.WARN);
+ DecompilerContext.getLogger().writeMessage(" New: " + rec.toString(), IFernflowerLogger.Severity.WARN);
+ }
+ int oldPriority = existingRec.source.equals(innerName) ? 1 : existingRec.source.equals(enclClassName) ? 2 : 3;
+ int newPriority = rec.source.equals(innerName) ? 1 : rec.source.equals(enclClassName) ? 2 : 3;
+ if (newPriority < oldPriority) {
Expand All @@ -69,3 +90,24 @@ index 26ccf4b2124ab617bfeec45ebbf3451ab2e7aa6d..8ce3a2575b4c9c8268ba9956ea008027
}

// reference to the nested class
diff --git a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
index d91d9faebf718192a679c436792a54c24bed8c63..9c6dd387cce2377ffb3eefd7e55aa4b5a04953e7 100644
--- a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
+++ b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
@@ -55,6 +55,8 @@ public interface IFernflowerPreferences {

String SKIP_EXTRA_FILES = "sef";

+ String WARN_INCONSISTENT_INNER_CLASSES = "win";
+
Map<String, Object> DEFAULTS = getDefaults();

static Map<String, Object> getDefaults() {
@@ -99,6 +101,7 @@ public interface IFernflowerPreferences {
defaults.put(DUMP_ORIGINAL_LINES, "0");
defaults.put(USE_JAD_VARNAMING, "0");
defaults.put(SKIP_EXTRA_FILES, "0");
+ defaults.put(WARN_INCONSISTENT_INNER_CLASSES, "1");

return Collections.unmodifiableMap(defaults);
}
10 changes: 5 additions & 5 deletions FernFlower-Patches/0028-Fix-ambiguous-lambdas.patch
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ Subject: [PATCH] Fix ambiguous lambdas


diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java
index 4933b5c1d375b7beacbb521bc8770cf295e7d98c..cc67f34aeede9a41bd78aeefdf6ac4a88d79348c 100644
index eef5cdaf7fa5c425abddea9ab0717f6844c97460..7b554126313ad7abc3c1a6773a8f1ee69549ca93 100644
--- a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java
+++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java
@@ -910,6 +910,9 @@ public class ExprProcessor implements CodeConstants {
@@ -913,6 +913,9 @@ public class ExprProcessor implements CodeConstants {
(castNull && rightType.type == CodeConstants.TYPE_NULL && !UNDEFINED_TYPE_STRING.equals(getTypeName(leftType))) ||
(castNarrowing && isIntConstant(exprent) && isNarrowedIntType(leftType));

Expand All @@ -18,7 +18,7 @@ index 4933b5c1d375b7beacbb521bc8770cf295e7d98c..cc67f34aeede9a41bd78aeefdf6ac4a8
boolean quote = cast && exprent.getPrecedence() >= FunctionExprent.getPrecedence(FunctionExprent.FUNCTION_CAST);

// cast instead to 'byte' / 'short' when int constant is used as a value for 'Byte' / 'Short'
@@ -924,6 +927,8 @@ public class ExprProcessor implements CodeConstants {
@@ -927,6 +930,8 @@ public class ExprProcessor implements CodeConstants {

if (cast) buffer.append('(').append(getCastTypeName(leftType)).append(')');

Expand All @@ -27,7 +27,7 @@ index 4933b5c1d375b7beacbb521bc8770cf295e7d98c..cc67f34aeede9a41bd78aeefdf6ac4a8
if (quote) buffer.append('(');

if (exprent.type == Exprent.EXPRENT_CONST) {
@@ -956,4 +961,12 @@ public class ExprProcessor implements CodeConstants {
@@ -959,4 +964,12 @@ public class ExprProcessor implements CodeConstants {
return VarType.VARTYPE_INT.isStrictSuperset(type) ||
type.equals(VarType.VARTYPE_BYTE_OBJ) || type.equals(VarType.VARTYPE_SHORT_OBJ);
}
Expand All @@ -41,7 +41,7 @@ index 4933b5c1d375b7beacbb521bc8770cf295e7d98c..cc67f34aeede9a41bd78aeefdf6ac4a8
+ }
}
diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java
index c5152f9053b274870b5da08acbddb89b12ac0516..ebb845dff674965ff3e0e8011db33dae5270e24d 100644
index 16158a3d134c7af2ecdf58a539ff1d33ba80c6b9..4dc461a2da1073a74d9df787ff21d9f27a5a59f2 100644
--- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java
+++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java
@@ -806,7 +806,8 @@ public class InvocationExprent extends Exprent {
Expand Down
Loading