From 95215dc2e288013281baff74e2b2ae1cfe1c8871 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Mon, 28 Mar 2016 13:57:29 +0300 Subject: [PATCH] replace increment / decrement synthetic access method, pull-request #373 --- .../main/rels/NestedMemberAccess.java | 44 +++++++-- .../java/decompiler/SingleClassesTest.java | 5 +- .../pkg/TestSyntheticAccess$Assigner.class | Bin 0 -> 753 bytes .../pkg/TestSyntheticAccess$Incrementer.class | Bin 0 -> 928 bytes .../classes/pkg/TestSyntheticAccess.class | Bin 0 -> 1012 bytes testData/results/TestSyntheticAccess.dec | 85 ++++++++++++++++++ testData/src/pkg/TestSyntheticAccess.java | 44 +++++++++ 7 files changed, 169 insertions(+), 9 deletions(-) create mode 100644 testData/classes/pkg/TestSyntheticAccess$Assigner.class create mode 100644 testData/classes/pkg/TestSyntheticAccess$Incrementer.class create mode 100644 testData/classes/pkg/TestSyntheticAccess.class create mode 100644 testData/results/TestSyntheticAccess.dec create mode 100644 testData/src/pkg/TestSyntheticAccess.java diff --git a/src/org/jetbrains/java/decompiler/main/rels/NestedMemberAccess.java b/src/org/jetbrains/java/decompiler/main/rels/NestedMemberAccess.java index 3fa8128..2ea32bd 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/NestedMemberAccess.java +++ b/src/org/jetbrains/java/decompiler/main/rels/NestedMemberAccess.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -29,10 +29,7 @@ import org.jetbrains.java.decompiler.struct.StructMethod; import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor; import org.jetbrains.java.decompiler.util.InterpreterUtil; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.Map; +import java.util.*; public class NestedMemberAccess { @@ -40,6 +37,7 @@ public class NestedMemberAccess { private static final int METHOD_ACCESS_FIELD_GET = 2; private static final int METHOD_ACCESS_FIELD_SET = 3; private static final int METHOD_ACCESS_METHOD = 4; + private static final int METHOD_ACCESS_FUNCTION = 5; private boolean noSynthFlag; private final Map mapMethodType = new HashMap(); @@ -117,6 +115,16 @@ public class NestedMemberAccess { } } + break; + case Exprent.EXPRENT_FUNCTION: + // for now detect only increment/decrement + FunctionExprent functionExprent = (FunctionExprent)exprCore; + if (functionExprent.getFuncType() >= FunctionExprent.FUNCTION_IMM && + functionExprent.getFuncType() <= FunctionExprent.FUNCTION_PPI) { + if (functionExprent.getLstOperands().get(0).type == Exprent.EXPRENT_FIELD) { + type = METHOD_ACCESS_FUNCTION; + } + } break; case Exprent.EXPRENT_INVOCATION: type = METHOD_ACCESS_METHOD; @@ -139,7 +147,6 @@ public class NestedMemberAccess { } } - if (type == METHOD_ACCESS_METHOD) { // FIXME: check for private flag of the method type = METHOD_ACCESS_NORMAL; @@ -323,7 +330,6 @@ public class NestedMemberAccess { } private Exprent replaceAccessExprent(ClassNode caller, MethodWrapper methdest, InvocationExprent invexpr) { - ClassNode node = DecompilerContext.getClassProcessor().getMapRootClasses().get(invexpr.getClassname()); MethodWrapper methsource = null; @@ -408,6 +414,9 @@ public class NestedMemberAccess { } retexprent = ret; break; + case METHOD_ACCESS_FUNCTION: + retexprent = replaceFunction(invexpr, source); + break; case METHOD_ACCESS_METHOD: if (source.type == Exprent.EXPRENT_EXIT) { source = ((ExitExprent)source).getValue(); @@ -446,4 +455,25 @@ public class NestedMemberAccess { return retexprent; } + + private static Exprent replaceFunction(final InvocationExprent invexpr, final Exprent source) { + FunctionExprent functionExprent = (FunctionExprent)((ExitExprent)source).getValue().copy(); + + List lstParameters = invexpr.getLstParameters(); + + FieldExprent fieldExprent = (FieldExprent)functionExprent.getLstOperands().get(0); + if (fieldExprent.isStatic()) { + if (!lstParameters.isEmpty()) { + return null; + } + return functionExprent; + } + + if (lstParameters.size() != 1) { + return null; + } + + fieldExprent.replaceExprent(fieldExprent.getInstance(), lstParameters.get(0)); + return functionExprent; + } } diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index 100deeb..5bdbdc5 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -85,8 +85,9 @@ public class SingleClassesTest { @Test public void testMemberAnnotations() { doTest("pkg/TestMemberAnnotations"); } @Test public void testStaticNameClash() { doTest("pkg/TestStaticNameClash"); } @Test public void testExtendingSubclass() { doTest("pkg/TestExtendingSubclass"); } + @Test public void testSyntheticAccess() { doTest("pkg/TestSyntheticAccess"); } - protected void doTest(String testFile, String... companionFiles) { + private void doTest(String testFile, String... companionFiles) { ConsoleDecompiler decompiler = fixture.getDecompiler(); File classFile = new File(fixture.getTestDataDir(), "/classes/" + testFile + ".class"); @@ -131,4 +132,4 @@ public class SingleClassesTest { return files; } -} \ No newline at end of file +} diff --git a/testData/classes/pkg/TestSyntheticAccess$Assigner.class b/testData/classes/pkg/TestSyntheticAccess$Assigner.class new file mode 100644 index 0000000000000000000000000000000000000000..c15e644dbe8e817ab9b3a02a21438b287b356ff2 GIT binary patch literal 753 zcmZ{iT`vPc6o%ikt=(EntG>UBtrUrtxFZrIl1&;eDs??wlUmkRx?AFBNeFS_2l!Fq z%&L;GH#2i)-t(OI%*^}8>l=V=tn{M~Qzmpwo0!3@8s-el8(1Ld(S;Y<6~a{Y=Bimf zm0?u7526bhdG5aJ$}rqv(XJPG(H>#8l&D&*6VivRb4kcny+9s!t{bv_DjGiT`p$`)ZR`FfpI?&Vv&sl=*X2L*mxou8Rl+)T(U-o1&A#F8}2(yU0cs$xw=jv?-~EH|$+ z%+?<6Zpsbedi7`9YYERXPfSy|?ja=|S+?aJGb|KBvx=7t(bLYgU`W<1Tbw`MH-*zM znr%8s*E*)rzBC+5`rX5*e41gjYMYL@7q%xH2CZt_!Z~dlt}7_G9`;^7aElaj>km?8 zh!mt4el5COI_k&k!H9I~okzzMXO`4CGo=3QTjR;lkO0>(iYXO&4eQv@uqjOeMGYks z8FC^03o2zuNm{vW*f-^i=B+S2hHS`1(q{NyAg}8O|My;2*vsAPI~9G`Z$}_rspwdt z(HNmAVX2g?i*_+6RGbEeF@Jg#@&R7jdIKxHLwO-j!8qAC<$yAizLk596f(2|lbGrf z_Gy)|MCldm1Cgsffcxli5|9i)52LN*fm>&XAFiX`dm_wRYP8wAD>n5Q50*HiQV~*B2`N$p53MStPj#GCx+Qgx*G2G8 zyl@i|4}1V0g_yNdY9uUSX?JGVXU?3Nv48&h{sX`cS~uWe(`JG?3p^5N5UTrH zt5GZyg5QnV9*je+r50!sX1Z~d$O{>#<~?a%U0#adK2xzupA+mx^O)cqOooy$+f%W8 zd3iCA$x%2M^G&TciNf)5m?(3eUOMTSVy>m$o7bcEk<{to`#3$5sfzZaNNT-D@WRZi z2fyyUU-L-%OsL7 zlqq!aA9XxF58sA9X5jm{X|`LKB`lOwO_($I_Bf13?N@_y8Ks2v5^()`Y@20}!tk)p zv#;>CV8JtbGLI#(6}(s%I6Zr9w#2s5`Ud+WI~H#9?q-()HTL}+fIGMg%vEs@^L%51 zcR7g(_FMfguuh!QudqJwxs1cd!jxmNz+o3SoZ-oTb1Y$bs$+vQn#cPDa!&i7K}H1? zD`DL$1-$(S-*<*3_*JY;`S)OF8ANNPT;6;R$xCE 19 +15 <-> 20 +18 <-> 23 +19 <-> 24 +22 <-> 27 +23 <-> 27 +26 <-> 31 +27 <-> 32 +32 <-> 9 +33 <-> 10 +36 <-> 13 +37 <-> 14 diff --git a/testData/src/pkg/TestSyntheticAccess.java b/testData/src/pkg/TestSyntheticAccess.java new file mode 100644 index 0000000..0c4e3ea --- /dev/null +++ b/testData/src/pkg/TestSyntheticAccess.java @@ -0,0 +1,44 @@ +package pkg; + +/** + * @author Alexandru-Constantin Bledea + * @since March 20, 2016 + */ +class TestSyntheticAccess { + + private static int s; + private int i; + + private class Incrementer { + void orI() { + i|=1; + } + + void incrementI() { + i++; + } + + void decrementI() { + --i; + } + + void incrementS() { + ++s; + } + + void decrementS() { + s--; + } + } + + private class Assigner { + void assignI(int newValue) { + i = newValue; + } + + void assignS(int newValue) { + s = newValue; + } + } + +}