From 32693c314a77222b46bec900059257af741e8159 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Tue, 10 Jan 2017 12:03:26 +0300 Subject: [PATCH] IDEA-149813 Decompiler has lost generic parameter --- .../java/decompiler/main/ClassWriter.java | 23 ++++---- .../modules/decompiler/exps/NewExprent.java | 23 +++++++- .../java/decompiler/SingleClassesTest.java | 3 +- .../pkg/TestAnonymousSignature$1.class | Bin 0 -> 485 bytes .../pkg/TestAnonymousSignature$2.class | Bin 0 -> 680 bytes .../classes/pkg/TestAnonymousSignature.class | Bin 0 -> 575 bytes testData/results/TestAnonymousSignature.dec | 50 ++++++++++++++++++ testData/src/pkg/TestAnonymousSignature.java | 40 ++++++++++++++ 8 files changed, 126 insertions(+), 13 deletions(-) create mode 100644 testData/classes/pkg/TestAnonymousSignature$1.class create mode 100644 testData/classes/pkg/TestAnonymousSignature$2.class create mode 100644 testData/classes/pkg/TestAnonymousSignature.class create mode 100644 testData/results/TestAnonymousSignature.dec create mode 100644 testData/src/pkg/TestAnonymousSignature.java diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java index 2386798..d80090d 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java +++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -331,16 +331,9 @@ public class ClassWriter { buffer.append("class "); } - GenericClassDescriptor descriptor = null; - if (DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_GENERIC_SIGNATURES)) { - StructGenericSignatureAttribute attr = (StructGenericSignatureAttribute)cl.getAttributes().getWithKey("Signature"); - if (attr != null) { - descriptor = GenericMain.parseClassSignature(attr.getSignature()); - } - } - buffer.append(node.simpleName); + GenericClassDescriptor descriptor = getGenericClassDescriptor(cl); if (descriptor != null && !descriptor.fparameters.isEmpty()) { appendTypeParameters(buffer, descriptor.fparameters, descriptor.fbounds); } @@ -1051,7 +1044,17 @@ public class ClassWriter { } } - private static void appendTypeParameters(TextBuffer buffer, List parameters, List> bounds) { + public static GenericClassDescriptor getGenericClassDescriptor(StructClass cl) { + if (DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_GENERIC_SIGNATURES)) { + StructGenericSignatureAttribute attr = (StructGenericSignatureAttribute)cl.getAttributes().getWithKey("Signature"); + if (attr != null) { + return GenericMain.parseClassSignature(attr.getSignature()); + } + } + return null; + } + + public static void appendTypeParameters(TextBuffer buffer, List parameters, List> bounds) { buffer.append('<'); for (int i = 0; i < parameters.size(); i++) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java index b6a67d2..f72e764 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,12 +21,15 @@ import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.main.TextBuffer; import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer; +import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger; import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; import org.jetbrains.java.decompiler.modules.decompiler.vars.CheckTypesResult; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; import org.jetbrains.java.decompiler.struct.StructClass; import org.jetbrains.java.decompiler.struct.gen.VarType; +import org.jetbrains.java.decompiler.struct.gen.generics.GenericClassDescriptor; +import org.jetbrains.java.decompiler.struct.gen.generics.GenericMain; import org.jetbrains.java.decompiler.util.InterpreterUtil; import org.jetbrains.java.decompiler.util.ListStack; @@ -181,7 +184,23 @@ public class NewExprent extends Exprent { typename = typename.substring(typename.lastIndexOf('.') + 1); } } - buf.append(typename); + + GenericClassDescriptor descriptor = ClassWriter.getGenericClassDescriptor(child.classStruct); + if (descriptor != null) { + if (descriptor.superinterfaces.isEmpty()) { + buf.append(GenericMain.getGenericCastTypeName(descriptor.superclass)); + } + else { + if (descriptor.superinterfaces.size() > 1) { + DecompilerContext.getLogger().writeMessage("Inconsistent anonymous class signature: " + child.classStruct.qualifiedName, + IFernflowerLogger.Severity.WARN); + } + buf.append(GenericMain.getGenericCastTypeName(descriptor.superinterfaces.get(0))); + } + } + else { + buf.append(typename); + } } buf.append('('); diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index ac0e891..e7ede30 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -76,6 +76,7 @@ public class SingleClassesTest { @Test public void testInnerLocal() { doTest("pkg/TestInnerLocal"); } @Test public void testInnerLocalPkg() { doTest("pkg/TestInnerLocalPkg"); } @Test public void testInnerSignature() { doTest("pkg/TestInnerSignature"); } + @Test public void testAnonymousSignature() { doTest("pkg/TestAnonymousSignature"); } @Test public void testParameterizedTypes() { doTest("pkg/TestParameterizedTypes"); } @Test public void testShadowing() { doTest("pkg/TestShadowing", "pkg/Shadow", "ext/Shadow"); } @Test public void testStringConcat() { doTest("pkg/TestStringConcat"); } diff --git a/testData/classes/pkg/TestAnonymousSignature$1.class b/testData/classes/pkg/TestAnonymousSignature$1.class new file mode 100644 index 0000000000000000000000000000000000000000..e60ba5d7aa0a4025a3d899131b7d7ffe2f73f855 GIT binary patch literal 485 zcmZ`#u}%U(6r2aA2Y8B#q9Aq_VBu+E2O%Lu6B4w6&{!?7IaiN8b9-lk-(+KDV&Mn) zQO38LSRih)GcU96P3G;#=i57gb5sj(ux+8_V#h_9u-Z~uC2c~s-WU;_ZZwsIVqa-_ zozBKG9*S|uieuCh6L<9p`GE?wNYa>H*cWG>|hgH*yYOFWSN277Z0Lo ALI3~& literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/TestAnonymousSignature$2.class b/testData/classes/pkg/TestAnonymousSignature$2.class new file mode 100644 index 0000000000000000000000000000000000000000..6865a4933a279f16db5d2c259325611cfcba40e6 GIT binary patch literal 680 zcmZ`$O-n*S6g`t4PwkmjX5~jA7^y`@v{M9;0>NsbxM?*$2YdFMC+{QZKecI7&>~v* zqoVsv!jD?aJ$EkWp1Ei4=hxdifOG6e5Wtp#WCVU}E7(zxQjlf{R&}X6H3nay*k$lH z%)VfVwR9=2-BC|i9o{pjqG;x5%q_|e3#}o4;AMl$LAmW%x*SxNE5+sl^QJcxnlsCs zRy=07tq&x3Tu;9`BR1FMI=WGAOvd1jY0dJcW7H}Pk+$htnz+=xsnZ={J9TNw$C2sU zzmJ@F2FT@w)C|)m16RViGy4iMDzey9p&-N%U$m)W6)Hn!d_O4vEu24NP@7T;t6^~4 z7WSOVj~j->M0mjtL+XEBTFi*+k|9~Ro%x=r?P3?FwAKJMgzB9C*EYr1w zZFZx;5q3)!YF$4L2K>U2;%bkF(Yf%&*z@DC>)67I;(#B@N*&A4Rn&CUvB^*yJ=*5) z^4%j9TROJU_+NI+Q2DzHLw^3?>;8}rqJ>m<97fzD|9(sd#hE+DH*d&VL9r7_zi0(`1QCa>!FG zr7ikNDXqRB@s8x(1gTe~r$iy55}7y1k{BpcVFMNH(XFe*6DU9() {// 25 + public int size() { + return super.size();// 28 + } + }); + System.out.println(new Comparator() {// 33 + public int compare(String var1, String var2) { + return 0;// 36 + } + }); + }// 39 +} + +class 'pkg/TestAnonymousSignature$1' { + method 'size ()I' { + 1 9 + 4 9 + } +} + +class 'pkg/TestAnonymousSignature$2' { + method 'compare (Ljava/lang/String;Ljava/lang/String;)I' { + 0 14 + 1 14 + } +} + +class 'pkg/TestAnonymousSignature' { + method 'main ([Ljava/lang/String;)V' { + 0 7 + a 7 + d 12 + 17 12 + 1a 17 + } +} + +Lines mapping: +25 <-> 8 +28 <-> 10 +33 <-> 13 +36 <-> 15 +39 <-> 18 diff --git a/testData/src/pkg/TestAnonymousSignature.java b/testData/src/pkg/TestAnonymousSignature.java new file mode 100644 index 0000000..7837c75 --- /dev/null +++ b/testData/src/pkg/TestAnonymousSignature.java @@ -0,0 +1,40 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pkg; + +import java.util.ArrayList; +import java.util.Comparator; + +public class TestAnonymousSignature { + public static void main(String[] args) { + // anonymous from class + System.out.println(new ArrayList() { + @Override + public int size() { + return super.size(); + } + }); + + // anonymous from class + System.out.println(new Comparator() { + @Override + public int compare(String o1, String o2) { + return 0; + } + }); + } +} \ No newline at end of file