[java-decompiler] synthetic inner class constructor parameter filtering (IDEA-147606)
This commit is contained in:
@@ -65,9 +65,9 @@ public class NestedClassProcessor {
|
||||
|
||||
int nameless = 0, synthetics = 0;
|
||||
for (ClassNode child : node.nested) {
|
||||
StructClass cl = child.classStruct;
|
||||
// ensure not-empty class name
|
||||
if ((child.type == ClassNode.CLASS_LOCAL || child.type == ClassNode.CLASS_MEMBER) && child.simpleName == null) {
|
||||
StructClass cl = child.classStruct;
|
||||
if ((child.access & CodeConstants.ACC_SYNTHETIC) != 0 || cl.isSynthetic()) {
|
||||
child.simpleName = "SyntheticClass_" + (++synthetics);
|
||||
}
|
||||
@@ -78,6 +78,9 @@ public class NestedClassProcessor {
|
||||
}
|
||||
child.namelessConstructorStub = !cl.hasModifier(CodeConstants.ACC_STATIC) && cl.getMethods().size() + cl.getFields().size() == 0;
|
||||
}
|
||||
else if (child.type == ClassNode.CLASS_ANONYMOUS && (child.access & CodeConstants.ACC_SYNTHETIC) != 0 || cl.isSynthetic()) {
|
||||
child.namelessConstructorStub = !cl.hasModifier(CodeConstants.ACC_STATIC) && cl.getMethods().size() + cl.getFields().size() == 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (ClassNode child : node.nested) {
|
||||
@@ -180,10 +183,14 @@ public class NestedClassProcessor {
|
||||
List<ClassNode> copy = new ArrayList<ClassNode>(node.nested);
|
||||
|
||||
for (ClassNode child : copy) {
|
||||
if (child.classStruct.hasModifier(CodeConstants.ACC_SYNTHETIC)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((child.type == ClassNode.CLASS_LOCAL || child.type == ClassNode.CLASS_ANONYMOUS) && child.enclosingMethod == null) {
|
||||
Set<String> setEnclosing = child.enclosingClasses;
|
||||
|
||||
if (setEnclosing.size() == 1) {
|
||||
if (!setEnclosing.isEmpty()) {
|
||||
StructEnclosingMethodAttribute attr =
|
||||
(StructEnclosingMethodAttribute)child.classStruct.getAttributes().getWithKey("EnclosingMethod");
|
||||
if (attr != null &&
|
||||
@@ -199,17 +206,12 @@ public class NestedClassProcessor {
|
||||
child.parent = null;
|
||||
setEnclosing.remove(node.classStruct.qualifiedName);
|
||||
|
||||
boolean hasEnclosing = !setEnclosing.isEmpty();
|
||||
if (hasEnclosing) {
|
||||
hasEnclosing = insertNestedClass(root, child);
|
||||
}
|
||||
boolean hasEnclosing = !setEnclosing.isEmpty() && insertNestedClass(root, child);
|
||||
|
||||
if (!hasEnclosing) {
|
||||
if (child.type == ClassNode.CLASS_ANONYMOUS) {
|
||||
if (!child.classStruct.hasModifier(CodeConstants.ACC_SYNTHETIC)) {
|
||||
String message = "Unreferenced anonymous class " + child.classStruct.qualifiedName + "!";
|
||||
DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN);
|
||||
}
|
||||
String message = "Unreferenced anonymous class " + child.classStruct.qualifiedName + "!";
|
||||
DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN);
|
||||
}
|
||||
else if (child.type == ClassNode.CLASS_LOCAL) {
|
||||
String message = "Unreferenced local class " + child.classStruct.qualifiedName + "!";
|
||||
@@ -251,6 +253,10 @@ public class NestedClassProcessor {
|
||||
int clTypes = 0;
|
||||
|
||||
for (ClassNode nd : node.nested) {
|
||||
if (nd.classStruct.hasModifier(CodeConstants.ACC_SYNTHETIC)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nd.type != ClassNode.CLASS_LAMBDA &&
|
||||
(nd.access & CodeConstants.ACC_STATIC) == 0 &&
|
||||
(nd.access & CodeConstants.ACC_INTERFACE) == 0) {
|
||||
@@ -258,10 +264,8 @@ public class NestedClassProcessor {
|
||||
|
||||
Map<String, List<VarFieldPair>> mask = getMaskLocalVars(nd.getWrapper());
|
||||
if (mask.isEmpty()) {
|
||||
if (!nd.classStruct.hasModifier(CodeConstants.ACC_SYNTHETIC)) {
|
||||
String message = "Nested class " + nd.classStruct.qualifiedName + " has no constructor!";
|
||||
DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN);
|
||||
}
|
||||
String message = "Nested class " + nd.classStruct.qualifiedName + " has no constructor!";
|
||||
DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN);
|
||||
}
|
||||
else {
|
||||
mapVarMasks.put(nd.classStruct.qualifiedName, mask);
|
||||
|
||||
Binary file not shown.
BIN
testData/classes/pkg/TestInnerClassConstructor$Another.class
Normal file
BIN
testData/classes/pkg/TestInnerClassConstructor$Another.class
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
testData/classes/v11/TestInnerClassConstructor$Another.class
Normal file
BIN
testData/classes/v11/TestInnerClassConstructor$Another.class
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,40 +1,65 @@
|
||||
package pkg;
|
||||
|
||||
class TestInnerClassConstructor {
|
||||
void m() {
|
||||
void l() {
|
||||
new TestInnerClassConstructor.Inner("text");// 5
|
||||
}// 6
|
||||
|
||||
void n(String var1) {
|
||||
System.out.println("n(): " + var1);// 9
|
||||
void m() {
|
||||
new TestInnerClassConstructor.Another(3, 4);// 9
|
||||
}// 10
|
||||
|
||||
void n(String var1) {
|
||||
System.out.println("n(): " + var1);// 13
|
||||
}// 14
|
||||
|
||||
private class Another {
|
||||
private Another(int var2, int var3) {
|
||||
TestInnerClassConstructor.this.n(var2 + "+" + var3);// 24
|
||||
}// 25
|
||||
}
|
||||
|
||||
final class Inner {
|
||||
private Inner(String var2) {
|
||||
TestInnerClassConstructor.this.n(var2);// 14
|
||||
}// 15
|
||||
TestInnerClassConstructor.this.n(var2);// 18
|
||||
}// 19
|
||||
}
|
||||
}
|
||||
|
||||
class 'pkg/TestInnerClassConstructor' {
|
||||
method 'm ()V' {
|
||||
method 'l ()V' {
|
||||
5 4
|
||||
c 5
|
||||
}
|
||||
|
||||
method 'm ()V' {
|
||||
5 8
|
||||
6 8
|
||||
c 9
|
||||
}
|
||||
|
||||
method 'n (Ljava/lang/String;)V' {
|
||||
0 8
|
||||
a 8
|
||||
13 8
|
||||
16 8
|
||||
19 9
|
||||
0 12
|
||||
a 12
|
||||
13 12
|
||||
16 12
|
||||
19 13
|
||||
}
|
||||
}
|
||||
|
||||
class 'pkg/TestInnerClassConstructor$Another' {
|
||||
method '<init> (Lpkg/TestInnerClassConstructor;II)V' {
|
||||
15 17
|
||||
1e 17
|
||||
21 17
|
||||
24 18
|
||||
}
|
||||
}
|
||||
|
||||
class 'pkg/TestInnerClassConstructor$Inner' {
|
||||
method '<init> (Lpkg/TestInnerClassConstructor;Ljava/lang/String;)V' {
|
||||
b 13
|
||||
e 14
|
||||
b 23
|
||||
e 24
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +68,12 @@ Lines mapping:
|
||||
6 <-> 6
|
||||
9 <-> 9
|
||||
10 <-> 10
|
||||
13 <-> 13
|
||||
14 <-> 14
|
||||
15 <-> 15
|
||||
18 <-> 24
|
||||
19 <-> 25
|
||||
24 <-> 18
|
||||
25 <-> 19
|
||||
Not mapped:
|
||||
13
|
||||
17
|
||||
23
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
package pkg;
|
||||
|
||||
class TestInnerClassConstructor {
|
||||
void m() {
|
||||
void l() {
|
||||
new Inner("text");
|
||||
}
|
||||
|
||||
void m() {
|
||||
new Another(3, 4);
|
||||
}
|
||||
|
||||
void n(String s) {
|
||||
System.out.println("n(): " + s);
|
||||
}
|
||||
@@ -14,4 +18,10 @@ class TestInnerClassConstructor {
|
||||
n(s);
|
||||
}
|
||||
}
|
||||
|
||||
private class Another {
|
||||
private Another(int a, int b) {
|
||||
n(a + "+" + b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user