From 1794156473bf72a83dc5644333234d922f0d0a4f Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 11 Nov 2015 16:25:11 +0100 Subject: [PATCH] [java-decompiler] synthetic inner class constructor parameter filtering (IDEA-147606) --- .../main/rels/NestedClassProcessor.java | 32 ++++++---- .../pkg/TestInnerClassConstructor$1.class | Bin 234 -> 231 bytes .../TestInnerClassConstructor$Another.class | Bin 0 -> 856 bytes .../pkg/TestInnerClassConstructor$Inner.class | Bin 671 -> 668 bytes .../pkg/TestInnerClassConstructor.class | Bin 886 -> 1081 bytes .../v11/TestInnerClassConstructor$1.class | Bin 206 -> 224 bytes .../TestInnerClassConstructor$Another.class | Bin 0 -> 880 bytes .../v11/TestInnerClassConstructor$Inner.class | Bin 695 -> 695 bytes .../v11/TestInnerClassConstructor.class | Bin 880 -> 1086 bytes .../results/TestInnerClassConstructor.dec | 60 +++++++++++++----- .../src/pkg/TestInnerClassConstructor.java | 12 +++- 11 files changed, 74 insertions(+), 30 deletions(-) create mode 100644 testData/classes/pkg/TestInnerClassConstructor$Another.class create mode 100644 testData/classes/v11/TestInnerClassConstructor$Another.class diff --git a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java index 6963f1d..c529a44 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java @@ -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 copy = new ArrayList(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 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> 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); diff --git a/testData/classes/pkg/TestInnerClassConstructor$1.class b/testData/classes/pkg/TestInnerClassConstructor$1.class index 384ce5d4577bd4552a2b6956d2ae76ecf26ffa18..07172b9a8804ea82bb1ac365a26af77275b5879d 100644 GIT binary patch delta 54 zcmaFG_?%JT)W2Q(7#J8#7`WLP*x4C4Cki;Ra4|B-Pn;{uq+&R+BAK59D9y#d2!uc& GzySbo`U%?r delta 61 zcmaFP_=-{B)W2Q(7#J9g8F<(k*x4DlCJH!la5FN<7i6dFPgIa(RWW2_V3=5%%+Co_ O#l^q~glr590vrIt(hAuC diff --git a/testData/classes/pkg/TestInnerClassConstructor$Another.class b/testData/classes/pkg/TestInnerClassConstructor$Another.class new file mode 100644 index 0000000000000000000000000000000000000000..5178a8fb69c55046581f2e931144727cedd2c4f3 GIT binary patch literal 856 zcmah{?@QZI6g{`CO&X)d&fm7$&2&qfX(#MkhoD8FQ1pW$_%UrCH7<`!M$_Iu;^qt=Z`RaZ)pbfO?lJF!evG8w2iX*2a*C_{BZaJ?tE z-EQNSQ0T-%L0IX9Qd~|x^hI(L^dn)QPO#@DA|;$Zt(a};9=ElnbsbNVfw%}GHs1U1 zWsV+#kAaO9I5w8BtkFxtrvBQB0y%13t0a`8vq=~YMPlO>JOcR|G;B2C8+dKw5J!Z1 z=G5F%8LNAd5R5;_ncH0TAH+cM?6XCV33*RnuNaKSLJkQPuiNO&b^dCX|J0%P=&+r| zH&y&gg0SX2CbD8RvqK(^B&`3-^_G`yk@pcG$I-)Pl;ekI55g+Hog>d%3DleZXXKhQ zTaWrg7kd&t)=no*elv}YWl1ChMbJ4Bt(Q_f6>R* VqbWqJDG9QrP%cX1L@sJp#6RY#4+a1L diff --git a/testData/classes/pkg/TestInnerClassConstructor.class b/testData/classes/pkg/TestInnerClassConstructor.class index fb0d8989730ab54ff28ba8910d7d1e9ab98c7c4f..6a4810977c54f3006d49d15e74ff4e65928b43d7 100644 GIT binary patch delta 508 zcmZXQ%St0r5Qe|%PWp7(PK+_$O}uLo$IEyhXAneOWamoB(nUZ)q9oa8<6c6ZL>CF8 z-~+f(d>C;xSlx&tdf?Pw=kon^PQ5sP-NwVe+k0S*ZI5oUhB23M4~q%Iq(_vg7}Lxc zW<6Z8E^~qAf{^zpFmL!_STHOKez8(1SNG12YqfGsFuRrW`boJeM8gBY`Ey!1t?vkS zE`KOQ_RgCZ19H~9JaE$V2~({n$u?gTx>^!uf>rw6#3#+N;iu0EtF0cH?p&1^_L!XwQy$GoNy5l{frJ$%X-=1ygRr%3KB|+rj5PS7F4m2(AIPeYpmO2)hcbU zY1m?0vtuN`tfqe`cL&m3q+lv{CjLq9L`sL!ha<=9ifwONWLRIBpOoqpOB~WomCN+N0nGG5mt1$ KaVX3%LHq^e%q9>3 diff --git a/testData/classes/v11/TestInnerClassConstructor$1.class b/testData/classes/v11/TestInnerClassConstructor$1.class index b11a30e153220b083b2262397ec5df205ba94cff..fad6e4e7f4f46628e12b2c2e25d7ddcd25c00e1b 100644 GIT binary patch delta 75 zcmX@d_<&L1)W2Q(7?>G!8F<(k*x4DlCJN~BGcs@nSLT&uq?TkRvoml{bS#l)2C89T YU}9ilUG!8MxUQ*w`63Ckp5>voml_^evHO0*W&*Ffp(&Z~$p821X!c H1+o|bUF`?U diff --git a/testData/classes/v11/TestInnerClassConstructor$Another.class b/testData/classes/v11/TestInnerClassConstructor$Another.class new file mode 100644 index 0000000000000000000000000000000000000000..61d71db360eb86036f2920a316203a8f7e279245 GIT binary patch literal 880 zcmah|T~8WO5IwW3EUa6l)S@k*)-LS=D)LOz#1fm3koEy%(#Hj_xQchl?xl%8%ZEbJ zCjJ0_RMWYdh>3O0CiAs(=FFYB_vY{KYoxG)rj13swc((cWvgVNY{NuRi}egPwBFR> zosBKLx8Pd%KuD|8Aa?f%8{P5wuyH72)sa#}?U5hH?NG)lnhaDJwFueXrBtUv1p|hC z3S^)@6I|~ZT&Gh#BAD&)SP+)GffU~+7kv>O`u&lx@R0z5Gv^dB;o$kA$*gX(rCIG> zIEe=0YcOK&^(W7^d*=W29pvy*3(vs|ED;Ji+8FtA*yyP!ki##NlM@j+sG>%ox;9vB zW5>d-g9dnrmBbmk`!eJKMg;5L%FS86_s_&Y@g|asGzlqBpDyi>$3h+xie9JMo!5ET zEw63cd-SiBke*TDT>-+1_c)IWmJ|Eq(MZDU|B)VHlW(R2z45#rGV5jb0E0gs|7{#N z;0tYXv{IYFsMUWVRsRF?#|#UlDbjgsicFb}DY8@8SDZ+A#d3*Zz$&s>gNrw8=h!ot q3QTNbfpw-|3{ngN0Enywr~m)} delta 37 rcmdnax}9}HBoiku11AF?5b{q>V$xycncUAL&&j~R${@}l#UKCxhWrJP diff --git a/testData/classes/v11/TestInnerClassConstructor.class b/testData/classes/v11/TestInnerClassConstructor.class index 9cbad7f8e6e0ca2762bab8a9b4aae003965c3e4e..b203edf2f2b92bcc8d835a7af96e2be831d14eee 100644 GIT binary patch delta 486 zcmZ9J%T60X5JgXoJ=5dK*t|n9*gVX`HkfDZ@Q5OXC=2gcfmlY0C6K^Km^~Zz$eJ&K zg)L!;56A+<2k;LpSs|)p6r{A&eY?8q-n!lWs$maf@x_N;kqM zUG3%3Cy8qzjC9MRM<;v!o^=WFG@Je>R?ygrB|EtLMbAhZZ|{H6gwg^n8f8q2t%r&> zvhC8>m=6Aan?!%m;={bo7GaCzyGFU|EUBJSO3EnBAxpodt4yz+qTk{w4rs&cDtRB+`>*X|%XPIM52vK&;OBIXCVhZgs>QxHGf@CMZ zG}dTpO$T=K-gL~D#7-a{SfnaW13D3~>D1pSeBfM-(V?5+btE$UjG2G>l;Kg!X*HR$ Rs8bdVr78*A97}YL@*lWTDI5R* diff --git a/testData/results/TestInnerClassConstructor.dec b/testData/results/TestInnerClassConstructor.dec index 235d50f..f15701a 100644 --- a/testData/results/TestInnerClassConstructor.dec +++ b/testData/results/TestInnerClassConstructor.dec @@ -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 ' (Lpkg/TestInnerClassConstructor;II)V' { + 15 17 + 1e 17 + 21 17 + 24 18 } } class 'pkg/TestInnerClassConstructor$Inner' { method ' (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 diff --git a/testData/src/pkg/TestInnerClassConstructor.java b/testData/src/pkg/TestInnerClassConstructor.java index e42c319..ccc33ff 100644 --- a/testData/src/pkg/TestInnerClassConstructor.java +++ b/testData/src/pkg/TestInnerClassConstructor.java @@ -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); + } + } }