replace increment / decrement synthetic access method, pull-request #373
This commit is contained in:
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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.struct.gen.MethodDescriptor;
|
||||||
import org.jetbrains.java.decompiler.util.InterpreterUtil;
|
import org.jetbrains.java.decompiler.util.InterpreterUtil;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class NestedMemberAccess {
|
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_GET = 2;
|
||||||
private static final int METHOD_ACCESS_FIELD_SET = 3;
|
private static final int METHOD_ACCESS_FIELD_SET = 3;
|
||||||
private static final int METHOD_ACCESS_METHOD = 4;
|
private static final int METHOD_ACCESS_METHOD = 4;
|
||||||
|
private static final int METHOD_ACCESS_FUNCTION = 5;
|
||||||
|
|
||||||
private boolean noSynthFlag;
|
private boolean noSynthFlag;
|
||||||
private final Map<MethodWrapper, Integer> mapMethodType = new HashMap<MethodWrapper, Integer>();
|
private final Map<MethodWrapper, Integer> mapMethodType = new HashMap<MethodWrapper, Integer>();
|
||||||
@@ -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;
|
break;
|
||||||
case Exprent.EXPRENT_INVOCATION:
|
case Exprent.EXPRENT_INVOCATION:
|
||||||
type = METHOD_ACCESS_METHOD;
|
type = METHOD_ACCESS_METHOD;
|
||||||
@@ -139,7 +147,6 @@ public class NestedMemberAccess {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (type == METHOD_ACCESS_METHOD) { // FIXME: check for private flag of the method
|
if (type == METHOD_ACCESS_METHOD) { // FIXME: check for private flag of the method
|
||||||
|
|
||||||
type = METHOD_ACCESS_NORMAL;
|
type = METHOD_ACCESS_NORMAL;
|
||||||
@@ -323,7 +330,6 @@ public class NestedMemberAccess {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Exprent replaceAccessExprent(ClassNode caller, MethodWrapper methdest, InvocationExprent invexpr) {
|
private Exprent replaceAccessExprent(ClassNode caller, MethodWrapper methdest, InvocationExprent invexpr) {
|
||||||
|
|
||||||
ClassNode node = DecompilerContext.getClassProcessor().getMapRootClasses().get(invexpr.getClassname());
|
ClassNode node = DecompilerContext.getClassProcessor().getMapRootClasses().get(invexpr.getClassname());
|
||||||
|
|
||||||
MethodWrapper methsource = null;
|
MethodWrapper methsource = null;
|
||||||
@@ -408,6 +414,9 @@ public class NestedMemberAccess {
|
|||||||
}
|
}
|
||||||
retexprent = ret;
|
retexprent = ret;
|
||||||
break;
|
break;
|
||||||
|
case METHOD_ACCESS_FUNCTION:
|
||||||
|
retexprent = replaceFunction(invexpr, source);
|
||||||
|
break;
|
||||||
case METHOD_ACCESS_METHOD:
|
case METHOD_ACCESS_METHOD:
|
||||||
if (source.type == Exprent.EXPRENT_EXIT) {
|
if (source.type == Exprent.EXPRENT_EXIT) {
|
||||||
source = ((ExitExprent)source).getValue();
|
source = ((ExitExprent)source).getValue();
|
||||||
@@ -446,4 +455,25 @@ public class NestedMemberAccess {
|
|||||||
|
|
||||||
return retexprent;
|
return retexprent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Exprent replaceFunction(final InvocationExprent invexpr, final Exprent source) {
|
||||||
|
FunctionExprent functionExprent = (FunctionExprent)((ExitExprent)source).getValue().copy();
|
||||||
|
|
||||||
|
List<Exprent> 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,8 +85,9 @@ public class SingleClassesTest {
|
|||||||
@Test public void testMemberAnnotations() { doTest("pkg/TestMemberAnnotations"); }
|
@Test public void testMemberAnnotations() { doTest("pkg/TestMemberAnnotations"); }
|
||||||
@Test public void testStaticNameClash() { doTest("pkg/TestStaticNameClash"); }
|
@Test public void testStaticNameClash() { doTest("pkg/TestStaticNameClash"); }
|
||||||
@Test public void testExtendingSubclass() { doTest("pkg/TestExtendingSubclass"); }
|
@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();
|
ConsoleDecompiler decompiler = fixture.getDecompiler();
|
||||||
|
|
||||||
File classFile = new File(fixture.getTestDataDir(), "/classes/" + testFile + ".class");
|
File classFile = new File(fixture.getTestDataDir(), "/classes/" + testFile + ".class");
|
||||||
|
|||||||
BIN
testData/classes/pkg/TestSyntheticAccess$Assigner.class
Normal file
BIN
testData/classes/pkg/TestSyntheticAccess$Assigner.class
Normal file
Binary file not shown.
BIN
testData/classes/pkg/TestSyntheticAccess$Incrementer.class
Normal file
BIN
testData/classes/pkg/TestSyntheticAccess$Incrementer.class
Normal file
Binary file not shown.
BIN
testData/classes/pkg/TestSyntheticAccess.class
Normal file
BIN
testData/classes/pkg/TestSyntheticAccess.class
Normal file
Binary file not shown.
85
testData/results/TestSyntheticAccess.dec
Normal file
85
testData/results/TestSyntheticAccess.dec
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
package pkg;
|
||||||
|
|
||||||
|
class TestSyntheticAccess {
|
||||||
|
private static int s;
|
||||||
|
private int i;
|
||||||
|
|
||||||
|
private class Assigner {
|
||||||
|
void assignI(int newValue) {
|
||||||
|
TestSyntheticAccess.this.i = newValue;// 32
|
||||||
|
}// 33
|
||||||
|
|
||||||
|
void assignS(int newValue) {
|
||||||
|
TestSyntheticAccess.s = newValue;// 36
|
||||||
|
}// 37
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Incrementer {
|
||||||
|
void incrementI() {
|
||||||
|
TestSyntheticAccess.this.i++;// 14
|
||||||
|
}// 15
|
||||||
|
|
||||||
|
void decrementI() {
|
||||||
|
--TestSyntheticAccess.this.i;// 18
|
||||||
|
}// 19
|
||||||
|
|
||||||
|
void incrementS() {
|
||||||
|
++TestSyntheticAccess.s;// 22 23
|
||||||
|
}
|
||||||
|
|
||||||
|
void decrementS() {
|
||||||
|
TestSyntheticAccess.s--;// 26
|
||||||
|
}// 27
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class 'pkg/TestSyntheticAccess$Assigner' {
|
||||||
|
method 'assignI (I)V' {
|
||||||
|
3 8
|
||||||
|
9 9
|
||||||
|
}
|
||||||
|
|
||||||
|
method 'assignS (I)V' {
|
||||||
|
2 12
|
||||||
|
5 13
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class 'pkg/TestSyntheticAccess$Incrementer' {
|
||||||
|
method 'incrementI ()V' {
|
||||||
|
2 18
|
||||||
|
7 18
|
||||||
|
8 19
|
||||||
|
}
|
||||||
|
|
||||||
|
method 'decrementI ()V' {
|
||||||
|
2 22
|
||||||
|
6 22
|
||||||
|
8 23
|
||||||
|
}
|
||||||
|
|
||||||
|
method 'incrementS ()V' {
|
||||||
|
0 26
|
||||||
|
4 26
|
||||||
|
}
|
||||||
|
|
||||||
|
method 'decrementS ()V' {
|
||||||
|
0 30
|
||||||
|
4 31
|
||||||
|
5 30
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Lines mapping:
|
||||||
|
14 <-> 19
|
||||||
|
15 <-> 20
|
||||||
|
18 <-> 23
|
||||||
|
19 <-> 24
|
||||||
|
22 <-> 27
|
||||||
|
23 <-> 27
|
||||||
|
26 <-> 31
|
||||||
|
27 <-> 32
|
||||||
|
32 <-> 9
|
||||||
|
33 <-> 10
|
||||||
|
36 <-> 13
|
||||||
|
37 <-> 14
|
||||||
44
testData/src/pkg/TestSyntheticAccess.java
Normal file
44
testData/src/pkg/TestSyntheticAccess.java
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user