From 2a213aa4a054bbe22925cb2a679d38a537ad88a4 Mon Sep 17 00:00:00 2001 From: Oleg Panashchenko Date: Mon, 24 Apr 2017 14:22:41 +0300 Subject: [PATCH] Use fully qualified static field name in conflict #541 --- .../main/collectors/ImportCollector.java | 36 ++++++ .../modules/decompiler/exps/FieldExprent.java | 2 +- .../decompiler/exps/InvocationExprent.java | 4 +- .../java/decompiler/SingleClassesTest.java | 5 + testData/classes/ext/TestClashNameIface.class | Bin 0 -> 141 bytes .../classes/ext/TestClashNameParent.class | Bin 0 -> 261 bytes testData/classes/pkg/NonSharedName.class | Bin 0 -> 339 bytes testData/classes/pkg/SharedName1.class | Bin 0 -> 337 bytes testData/classes/pkg/SharedName2.class | Bin 0 -> 282 bytes testData/classes/pkg/SharedName3.class | Bin 0 -> 282 bytes testData/classes/pkg/SharedName4.class | Bin 0 -> 148 bytes testData/classes/pkg/SharedName5.class | Bin 0 -> 265 bytes testData/classes/pkg/TestClashName.class | Bin 0 -> 1171 bytes testData/classes/pkg/TestClashNameIface.class | Bin 0 -> 134 bytes .../classes/pkg/TestClashNameParent.class | Bin 0 -> 210 bytes testData/classes/pkg/TestSwitchOnEnum$1.class | Bin 0 -> 618 bytes testData/classes/pkg/TestSwitchOnEnum.class | Bin 0 -> 557 bytes testData/results/InvalidMethodSignature.dec | 2 +- testData/results/TestClashName.dec | 108 ++++++++++++++++++ testData/results/TestSwitchOnEnum.dec | 31 +++++ testData/src/ext/TestClashNameIface.java | 4 + testData/src/ext/TestClashNameParent.java | 5 + testData/src/pkg/TestClashName.java | 83 ++++++++++++++ testData/src/pkg/TestSwitchOnEnum.java | 20 ++++ 24 files changed, 296 insertions(+), 4 deletions(-) create mode 100644 testData/classes/ext/TestClashNameIface.class create mode 100644 testData/classes/ext/TestClashNameParent.class create mode 100644 testData/classes/pkg/NonSharedName.class create mode 100644 testData/classes/pkg/SharedName1.class create mode 100644 testData/classes/pkg/SharedName2.class create mode 100644 testData/classes/pkg/SharedName3.class create mode 100644 testData/classes/pkg/SharedName4.class create mode 100644 testData/classes/pkg/SharedName5.class create mode 100644 testData/classes/pkg/TestClashName.class create mode 100644 testData/classes/pkg/TestClashNameIface.class create mode 100644 testData/classes/pkg/TestClashNameParent.class create mode 100644 testData/classes/pkg/TestSwitchOnEnum$1.class create mode 100644 testData/classes/pkg/TestSwitchOnEnum.class create mode 100644 testData/results/TestClashName.dec create mode 100644 testData/results/TestSwitchOnEnum.dec create mode 100644 testData/src/ext/TestClashNameIface.java create mode 100644 testData/src/ext/TestClashNameParent.java create mode 100644 testData/src/pkg/TestClashName.java create mode 100644 testData/src/pkg/TestSwitchOnEnum.java diff --git a/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java b/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java index 3bc5383..f5cd16d 100644 --- a/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java +++ b/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java @@ -15,10 +15,13 @@ */ package org.jetbrains.java.decompiler.main.collectors; +import org.jetbrains.java.decompiler.main.ClassesProcessor; 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.struct.StructClass; import org.jetbrains.java.decompiler.struct.StructContext; +import org.jetbrains.java.decompiler.struct.StructField; import java.util.*; import java.util.stream.Collectors; @@ -28,6 +31,8 @@ public class ImportCollector { private final Map mapSimpleNames = new HashMap<>(); private final Set setNotImportedNames = new HashSet<>(); + // set of field names in this class and all its predecessors. + private final Set setFieldNames = new HashSet<>(); private final String currentPackageSlash; private final String currentPackagePoint; @@ -43,6 +48,37 @@ public class ImportCollector { currentPackageSlash = ""; currentPackagePoint = ""; } + + Map mapRootCases = DecompilerContext.getClassProcessor().getMapRootClasses(); + for(StructClass sClass = root.classStruct; + sClass!=null; + ){ + // all field names for current class .. + for(StructField f: sClass.getFields()) { + setFieldNames.add(f.getName()); + } + + // .. and traverse through parent. + ClassNode classNode; + if(sClass.superClass==null || (classNode = (mapRootCases.get(sClass.superClass.getString())))==null) + break; + sClass = classNode.classStruct; + } + } + + /** + * Check whether the package-less name ClassName is shaded by variable in a context of + * the decompiled class + * @param classToName - pkg.name.ClassName - class to find shortname for + * @return ClassName if the name is not shaded by local field, pkg.name.ClassName otherwise + */ + public String getShortNameInClassContext(String classToName) { + String shortName = getShortName(classToName); + if(setFieldNames.contains(shortName)) { + return classToName; + } else { + return shortName; + } } public String getShortName(String fullName) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java index 472823f..6d549b1 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java @@ -102,7 +102,7 @@ public class FieldExprent extends Exprent { if (isStatic) { ClassNode node = (ClassNode)DecompilerContext.getProperty(DecompilerContext.CURRENT_CLASS_NODE); if (node == null || !classname.equals(node.classStruct.qualifiedName) || isAmbiguous()) { - buf.append(DecompilerContext.getImportCollector().getShortName(ExprProcessor.buildJavaClassName(classname))); + buf.append(DecompilerContext.getImportCollector().getShortNameInClassContext(ExprProcessor.buildJavaClassName(classname))); buf.append("."); } } 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 dd8e26e..f56a805 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.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. @@ -225,7 +225,7 @@ public class InvocationExprent extends Exprent { ClassNode node = (ClassNode)DecompilerContext.getProperty(DecompilerContext.CURRENT_CLASS_NODE); if (node == null || !classname.equals(node.classStruct.qualifiedName)) { - buf.append(DecompilerContext.getImportCollector().getShortName(ExprProcessor.buildJavaClassName(classname))); + buf.append(DecompilerContext.getImportCollector().getShortNameInClassContext(ExprProcessor.buildJavaClassName(classname))); } } else { diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index ba2429f..b4567e0 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -102,6 +102,11 @@ public class SingleClassesTest { @Test public void testAccessReplace() { doTest("pkg/TestAccessReplace"); } @Test public void testStringLiterals() { doTest("pkg/TestStringLiterals"); } @Test public void testPrimitives() { doTest("pkg/TestPrimitives"); } + @Test public void testClashName() { doTest("pkg/TestClashName", "pkg/SharedName1", + "pkg/SharedName2", "pkg/SharedName3", "pkg/SharedName4", "pkg/NonSharedName", + "pkg/TestClashNameParent", "ext/TestClashNameParent","pkg/TestClashNameIface", "ext/TestClashNameIface"); } + @Test public void testSwitchOnEnum() { doTest("pkg/TestSwitchOnEnum","pkg/TestSwitchOnEnum$1");} + private void doTest(String testFile, String... companionFiles) { ConsoleDecompiler decompiler = fixture.getDecompiler(); diff --git a/testData/classes/ext/TestClashNameIface.class b/testData/classes/ext/TestClashNameIface.class new file mode 100644 index 0000000000000000000000000000000000000000..6a725cf41f104b9a4d9dc36078905834837f45f6 GIT binary patch literal 141 zcmX^0Z`VEs1_l!bPId-%b_Nbc2IjQ9 SS%9`Muz*+$tU!{9feip5QWbqsnKiv>B?@qDXj~$s7rAZ5DLW>lHH)*@%nA1E+YiAB z@+}hvpK->^Dh;_<>o5^Vt@5ha@FK3o)0#^YB)W|1q;HAL%w(tc+JlR>hX=F>BR&}a zACNGtQ9seyum2V9cw_J^Pdf56Ny%|DQJp1DN7M_fW~aty(AYk~IyQ`wu4ISi-VvrN Hvjy)CYo0P~ literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/NonSharedName.class b/testData/classes/pkg/NonSharedName.class new file mode 100644 index 0000000000000000000000000000000000000000..e3d09dd0fb7af0847b96294e4f9dd062a7664038 GIT binary patch literal 339 zcmZ9Gy-veG5QJy_n;1iWpa3aIlt6(S%7`XXBqU^tMD%Cpa2y;PIZmF61}KnHi0&7&vw4n2l z<~m$2BVA5al+m#gU5y)xL#<(){f&8(VqM01oYqi(s#n!0Q>%HXmilI)Hp+*KmJb__ zp!fQc1Ywa+=Bm`Q8WD7BD9BWv1dq`|#}zJkrp2?lrXHg*SxlkRraEUAcKiAZ@=hV} q_&SYwO6&kWb&U=h53oL9yzP+#l86673BWc#VeE&VG3JP$20Fiq#xdOh literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/SharedName1.class b/testData/classes/pkg/SharedName1.class new file mode 100644 index 0000000000000000000000000000000000000000..fbd917ffe1cb6ec44ef5891e3b5ff96bec0edd21 GIT binary patch literal 337 zcmZ9Gy-veG5QJy#^Dl;kKnW5hP+%cZMl_KkMM9xSM1OV;$H8%sK}Th#9<~&h{C-;et%Z}-rb^8)Z=l}Ptm{Fc*YmMnnyZC=(GfiO5gfQo zeSXT~$y`@v*37R3-3EyZU1srpvM_0lGajjUG(TyUsB9K9=mb=!?85F`enQ?T1R-Cy nHGN`xh^QO%r1b#x4(oM?j7aYP3nc)@{(!X`8ZhR7Lkpc>h3qh~ literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/SharedName2.class b/testData/classes/pkg/SharedName2.class new file mode 100644 index 0000000000000000000000000000000000000000..275ab11a87dd7543ef3cba1c57c7c28536fc5ead GIT binary patch literal 282 zcmZ9G&1%9>5QWd=S7TbEd%>l;XrOc{-3WqE>_TyW6R#Q@qr}+vk}e7^d;lLxdLnM@ zV(uKy`DX51uBS7AH#9w1c&@@k-9_M{A&>=YByjpkmK5&-v(udktig7!1@(_4)8oS? z()mVR?;4?Jv^alq)EWiK& literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/SharedName3.class b/testData/classes/pkg/SharedName3.class new file mode 100644 index 0000000000000000000000000000000000000000..f24863d6bdacb885e89b7b5d3cf8192c360d91bb GIT binary patch literal 282 zcmZ9Gy>7xl5QJy_3eC1oVaK!FP=5e*Vjq=*!t^k;JcgE7b$-V3FOM8N~_P*KK+ zCMouIH1qA=UVqLP0DUw)Sg4g@qVA&M;z1yvtXF|Eh|@S93e1=Ghrk+b=UPyIi&H&0 zY(kyQRG82y4Wi^udeiM8i}W}y{N_yW^HHMq%Zb|P?n)h%4;LjLHXJV6trx*`sWLq; z@}8hkAVH$iMerW3bd;mTyDZ+xPl_QbgT)~#I$jKreU6p*M1BZB})LO&-lFJ0e1DJwO(gpolWA(WVxmtT@tl9`{U a?+9nAF)%PPFaa?$&;=ki3y@@DUSg1gwdzWKq ydk3D1y^^L3?O%WNP@>0GFiKh@)T!$dDn=VU!0v@?P}K{vPfJyrN~pmsu>J)M6*%7j literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/TestClashName.class b/testData/classes/pkg/TestClashName.class new file mode 100644 index 0000000000000000000000000000000000000000..73b047dce894050717fe3a79c812d66f650c2f6c GIT binary patch literal 1171 zcmZWo+foxj5IsXe!iME8AOutp6;=fU3Acm*M!`Uc6i`01zyb?ogUN>SYy1LV6t}c| z@B{oP%hMYWLMqkg^z`)f^qk)O`TOfPfH*cI=s{dVHxdHV0y6@$0&^PXkrXebVWH}! zH7r)WB@N3}?{$QE8OeJSVV>{3mF0@SY8dar$cC||(6wWg-OQO;KF*s3Ytt-Qj;o-u z3Y|4O*+X;RQfS^jX3Bx&#%fmanpJ`&Y}yI!ly*id&>Y&iLPzfW^l0K%sU+hc>*EQ= zwQc*zG2Kduw~yR8mq^_S#FA+q38ieucGC)h(XkH-!A$XhhudPyKHk~*>Q@l>Doo7T;Eb$T0K;VY!@q~eQU**LbXzjpO_b>4g=41 z+((~|eu1dKfWRR7!dTZ4lf?sBAS%nWDx=mb=2HyZQC96}0eU=G%#o z=le_re5MFKQwN_ZfzOn{XG-8RCGeR7_)HCarVKt)3EnkIzX4+i(5K|Y7mR#nOp&*Y zA5ccXLxVs-ASlo%5Hh|Y?4gOId5DmjJ?Nws53R;ew0USJb$IABl!q>XdtX^q;U#e% zt;9HjNI=6hS2O6sEZ;rH87Dce6#H4gB+`s5Vu`<1{zG%fu);9L*`xHjK@O6KjPGbl z5h9levzG~u5vQQLxOmHW}yjOm9?7t); Vo=Bo@ULa}Ii1$yD8!&bI@IUhU(USlG literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/TestClashNameIface.class b/testData/classes/pkg/TestClashNameIface.class new file mode 100644 index 0000000000000000000000000000000000000000..eeb153ce5d52081c3c9667bd107c608763146e39 GIT binary patch literal 134 zcmX^0Z`VEs1_l!bPId-%b_Nbc2F5f-24)S-Fh&Nh;QZ2}b^1}=66ZgvJ9Mg}&U%)HDJJ4Oa(4b3n{1{UZ1lvG9rexJ;| zRKL>Pq|~C2#H1Xc2v=}^X;E^jTPBDj6p~t8;+&IMoZ*+4o2r+USeD4cz{0@F$RJ*j zovx1}8<1F(npeWeAOKROpOcuEuJ50em6}|_puoTcbO{JB0x?iKkY)q2WPvnDgjH)h X1LH=pG&_)F0}HAFNe&>7iGdRUtR*T& literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/TestSwitchOnEnum$1.class b/testData/classes/pkg/TestSwitchOnEnum$1.class new file mode 100644 index 0000000000000000000000000000000000000000..a3f6924427ab5cdb2e3ff4e01e70e4a567a02156 GIT binary patch literal 618 zcmah{U2oGc6g^Hu-G+<>*v2*(`yfc&3lY-ZK)jSzs@U3x6nNNE>RPQg*O{DT{3M+d@31M zkClKuo>pSsS5i-V*5;OBW_WV&{J5be=>a(Z7DZ8}R_Mlrx$iXovs8k7NBU%_s_2VdY_yV1CT z?~gvie|JU4^?$$}cvvB7vn~j6k8%$0BgZO8B_inIJ|0l?@sQTXGy@_xDI#k90vtD! AnE(I) literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/TestSwitchOnEnum.class b/testData/classes/pkg/TestSwitchOnEnum.class new file mode 100644 index 0000000000000000000000000000000000000000..c377fe7c382803b81ffc793e521f9077c157208a GIT binary patch literal 557 zcmaJ-O;5r=5Pe%d3bg_%;1_5#J)kBuCf+n&2u2c=1L(z5DH|-bTT)t$zsVCGH1XgM z@JAVEi^jwlcQbEhcW2(dnfH&^HvmW2){w$V7HJeUlu%Z&s$xyWI)mO4f(H%PnojwY zA>}=^M99Ee4Cxa`IN>QnqPBOQqpe(MR!!7~!|M>^0dkx2?^#hK(#VvZaV6zixEM->IyATdfszAwdD O%TUQ{RGB7^Lgo|YFLYo4 literal 0 HcmV?d00001 diff --git a/testData/results/InvalidMethodSignature.dec b/testData/results/InvalidMethodSignature.dec index e2a15b3..e4b567c 100644 --- a/testData/results/InvalidMethodSignature.dec +++ b/testData/results/InvalidMethodSignature.dec @@ -17,7 +17,7 @@ class i implements bg { public void a(c var1, k var2, boolean var3) { File var4 = this.a.b().a(var1);// 2 - b.a(this.b).add(var4);// 3 + a.a.a.a.e.f.b.a(this.b).add(var4);// 3 }// 4 public void a(a.a.a.a.c.b var1) { diff --git a/testData/results/TestClashName.dec b/testData/results/TestClashName.dec new file mode 100644 index 0000000..2a9a731 --- /dev/null +++ b/testData/results/TestClashName.dec @@ -0,0 +1,108 @@ +package pkg; + +@SharedName4 +public class TestClashName extends ext.TestClashNameParent implements TestClashNameIface { + int TestClashNameParent = 0; + int TestClashNameIface = 0; + int SharedName1 = 0; + int SharedName4 = 0; + int SharedName5 = 0; + int i; + int j; + int k; + int l; + int m; + int n; + SharedName1 p; + SharedName5 q; + + public TestClashName() { + this.i = pkg.SharedName1.f;// 59 + this.j = NonSharedName.f;// 60 + this.k = SharedName2.f;// 61 + this.l = pkg.SharedName3.f;// 62 + this.m = pkg.SharedName1.getF();// 63 + this.n = NonSharedName.getF();// 64 + this.p = null;// 65 + this.q = null;// 67 + } + + @SharedName4 + public int m() { + int var1 = this.i;// 73 + pkg.SharedName1.f = this.j;// 74 + int var2 = SharedName2.f;// 75 + NonSharedName.f = this.k;// 76 + int var3 = NonSharedName.f;// 77 + return var1 + var2 + var3;// 78 + } + + public void f() { + }// 82 +} + +class 'pkg/TestClashName' { + method ' ()V' { + 1e 19 + 21 19 + 25 20 + 28 20 + 2c 21 + 2f 21 + 33 22 + 36 22 + 3a 23 + 3d 23 + 41 24 + 44 24 + 48 25 + 49 25 + 4d 26 + 4e 26 + 51 27 + } + + method 'm ()I' { + 1 31 + 4 31 + 6 32 + 9 32 + c 33 + f 33 + 11 34 + 14 34 + 17 35 + 1a 35 + 1d 36 + 1f 36 + 20 36 + } + + method 'f ()V' { + 0 40 + } +} + +Lines mapping: +59 <-> 20 +60 <-> 21 +61 <-> 22 +62 <-> 23 +63 <-> 24 +64 <-> 25 +65 <-> 26 +67 <-> 27 +73 <-> 32 +74 <-> 33 +75 <-> 34 +76 <-> 35 +77 <-> 36 +78 <-> 37 +82 <-> 41 +Not mapped: +52 +53 +54 +55 +56 +57 diff --git a/testData/results/TestSwitchOnEnum.dec b/testData/results/TestSwitchOnEnum.dec new file mode 100644 index 0000000..4a6d980 --- /dev/null +++ b/testData/results/TestSwitchOnEnum.dec @@ -0,0 +1,31 @@ +package pkg; + +import java.util.concurrent.TimeUnit; + +public class TestSwitchOnEnum { + int myInt; + + public void testSOE(TimeUnit var1) { + switch(null.$SwitchMap$java$util$concurrent$TimeUnit[var1.ordinal()]) {// 12 + case 1: + return;// 14 + default: + } + }// 16 +} + +class 'pkg/TestSwitchOnEnum' { + method 'testSOE (Ljava/util/concurrent/TimeUnit;)V' { + 0 8 + 4 8 + 7 8 + 8 8 + 1c 10 + 1d 13 + } +} + +Lines mapping: +12 <-> 9 +14 <-> 11 +16 <-> 14 diff --git a/testData/src/ext/TestClashNameIface.java b/testData/src/ext/TestClashNameIface.java new file mode 100644 index 0000000..9d7630b --- /dev/null +++ b/testData/src/ext/TestClashNameIface.java @@ -0,0 +1,4 @@ +package ext; +interface TestClashNameIface { + public void foo(); +} diff --git a/testData/src/ext/TestClashNameParent.java b/testData/src/ext/TestClashNameParent.java new file mode 100644 index 0000000..7691344 --- /dev/null +++ b/testData/src/ext/TestClashNameParent.java @@ -0,0 +1,5 @@ +package ext; + +public class TestClashNameParent { + int SharedName3 = 0; +} diff --git a/testData/src/pkg/TestClashName.java b/testData/src/pkg/TestClashName.java new file mode 100644 index 0000000..3b13448 --- /dev/null +++ b/testData/src/pkg/TestClashName.java @@ -0,0 +1,83 @@ +package pkg; + +/* + * The names SharedName[123] are shared between variables in local|parent class and class names. + * Where approprate, the classes have to be referenced by fully qualified names + */ + +class SharedName1 { + static int f = 0; + + static int getF() { + return f; + } +} + +class SharedName2 { + static int f = 0; +} + +class SharedName3 { + static int f = 0; +} + +class NonSharedName { + static int f = 0; + + static int getF() { + return f; + } +} + +@interface SharedName4 { +} + +class SharedName5{ +} + +class TestClashNameParent { + +} + +interface TestClashNameIface { + public void f(); +} +// *** Legend for first sentence in comments below: +// (+) or (-) indicate whether 'pkg' prefix is or is not required when referencing *SharedName*. +// The sign is optionally followed by decompiler class name that generates the line that is being commented +// in a call of getShortName() + +@SharedName4 // (-)AnnotationExprent. While a variable named SharedName4 does exist in the annotated class, + // lookup process for annotation names never includes variable names. +public class TestClashName extends ext.TestClashNameParent implements /*pkg.*/TestClashNameIface { // (+)(-)TextUtil + int TestClashNameParent = 0; + int TestClashNameIface = 0; + int SharedName1 = 0; + int SharedName4 = 0; + int SharedName5 = 0; + + int i = pkg.SharedName1.f; // (+)FieldExprent. SharedName1 class name is shadowed by a variable in this class + int j = NonSharedName.f; // (-)FieldExprent. The NonSharedName is not used for other objects in the current scope + int k = SharedName2.f; // (-)FieldExprent. SharedName2 variable is not the current scope + int l = pkg.SharedName3.f; // (+)FieldExprent. SharedName3 class name is shadowed by a variable in parent class + int m = pkg.SharedName1.getF();// (+)InvocationExprent. SharedName1 class name is shadowed by a variable in this class + int n = NonSharedName.getF(); // (-)InvocationExprent. The NonSharedName is not used for other objects in the current scope + SharedName1 p = null; // (-)ExprProcessor. While a variable named SharedName1 in current scope does exist, + // namespace in type declaration does not include variable names in a scope + SharedName5 q = null;//(-)(-)GenericMain (both names). While a variable named SharedName1 does exist in current scope, + // lookup for generic parameters never includes variable names + + @SharedName4 // (-)AnnotationExprent. While a variable named SharedName4 does exist in current scope, + // lookup process for annotation names never includes variable names. + public int m() { + int SharedName2 = i; + pkg.SharedName1.f = j; // (+)FieldExprent. SharedName1 class name is shadowed by a variable in this class + int x = pkg.SharedName2.f; // (+)FieldExprent. SharedName2 class name is shadowed by a variable in this method + NonSharedName.f = k; // (-)ExprProcessor. The NonSharedName is not used for other objects in the current scope + int y = NonSharedName.f; // (-)FieldExprent. The NonSharedName is not used for other objects in the current scope + return SharedName2 + x + y; + } + + @Override + public void f() {} +} diff --git a/testData/src/pkg/TestSwitchOnEnum.java b/testData/src/pkg/TestSwitchOnEnum.java new file mode 100644 index 0000000..ec07604 --- /dev/null +++ b/testData/src/pkg/TestSwitchOnEnum.java @@ -0,0 +1,20 @@ +package pkg; + +import java.util.concurrent.TimeUnit; + +/** + * This illustrates a bug in fernflower as of 20170421. Decompiled output of this class does not compile back. + */ +public class TestSwitchOnEnum { + + int myInt; + + public int testSOE(TimeUnit t) { + // This creates anonymous SwitchMap inner class. + switch (t) { + case SECONDS: + return 1; + } + return 0; + } +}