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