fix: correct inline for enums in j$.time.temporal
This commit is contained in:
@@ -459,7 +459,7 @@ public class ClassGen {
|
||||
}
|
||||
if (f.getCls() != null) {
|
||||
code.add(' ');
|
||||
new ClassGen(f.getCls(), this).addClassBody(code);
|
||||
new ClassGen(f.getCls(), this).addClassBody(code, true);
|
||||
}
|
||||
if (it.hasNext()) {
|
||||
code.add(',');
|
||||
|
||||
@@ -71,7 +71,14 @@ public class EnumVisitor extends AbstractVisitor {
|
||||
|
||||
@Override
|
||||
public boolean visit(ClassNode cls) throws JadxException {
|
||||
if (!convertToEnum(cls)) {
|
||||
boolean converted;
|
||||
try {
|
||||
converted = convertToEnum(cls);
|
||||
} catch (Exception e) {
|
||||
cls.addWarnComment("Enum visitor error", e);
|
||||
converted = false;
|
||||
}
|
||||
if (!converted) {
|
||||
AccessInfo accessFlags = cls.getAccessFlags();
|
||||
if (accessFlags.isEnum()) {
|
||||
cls.setAccessFlags(accessFlags.remove(AccessFlags.ENUM));
|
||||
@@ -179,8 +186,7 @@ public class EnumVisitor extends AbstractVisitor {
|
||||
if (!enumClsInfo.equals(cls.getClassInfo())) {
|
||||
ClassNode enumCls = cls.root().resolveClass(enumClsInfo);
|
||||
if (enumCls != null) {
|
||||
processEnumCls(enumField, enumCls);
|
||||
cls.addInlinedClass(enumCls);
|
||||
processEnumCls(cls, enumField, enumCls);
|
||||
}
|
||||
}
|
||||
List<RegisterArg> regs = new ArrayList<>();
|
||||
@@ -381,7 +387,11 @@ public class EnumVisitor extends AbstractVisitor {
|
||||
if (constrCls == null) {
|
||||
return null;
|
||||
}
|
||||
if (!clsInfo.equals(cls.getClassInfo()) && !constrCls.getAccessFlags().isEnum()) {
|
||||
if (constrCls.equals(cls)) {
|
||||
// allow same class
|
||||
} else if (constrCls.contains(AFlag.ANONYMOUS_CLASS)) {
|
||||
// allow external class already marked as anonymous
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
MethodNode ctrMth = cls.root().resolveMethod(co.getCallMth());
|
||||
@@ -466,7 +476,7 @@ public class EnumVisitor extends AbstractVisitor {
|
||||
return InsnUtils.searchInsn(mth, InsnType.SGET, insnTest) != null;
|
||||
}
|
||||
|
||||
private static void processEnumCls(EnumField field, ClassNode innerCls) {
|
||||
private static void processEnumCls(ClassNode cls, EnumField field, ClassNode innerCls) {
|
||||
// remove constructor, because it is anonymous class
|
||||
for (MethodNode innerMth : innerCls.getMethods()) {
|
||||
if (innerMth.getAccessFlags().isConstructor()) {
|
||||
@@ -474,7 +484,11 @@ public class EnumVisitor extends AbstractVisitor {
|
||||
}
|
||||
}
|
||||
field.setCls(innerCls);
|
||||
innerCls.add(AFlag.DONT_GENERATE);
|
||||
if (!innerCls.getParentClass().equals(cls)) {
|
||||
// not inner
|
||||
cls.addInlinedClass(innerCls);
|
||||
innerCls.add(AFlag.DONT_GENERATE);
|
||||
}
|
||||
}
|
||||
|
||||
private ConstructorInsn getConstructorInsn(InsnNode insn) {
|
||||
|
||||
@@ -42,10 +42,7 @@ public class ProcessAnonymous extends AbstractVisitor {
|
||||
}
|
||||
|
||||
private static void markAnonymousClass(ClassNode cls) {
|
||||
boolean synthetic = cls.getAccessFlags().isSynthetic()
|
||||
|| cls.getClassInfo().getShortName().contains("$")
|
||||
|| Character.isDigit(cls.getClassInfo().getShortName().charAt(0));
|
||||
if (!synthetic) {
|
||||
if (!canBeAnonymous(cls)) {
|
||||
return;
|
||||
}
|
||||
MethodNode anonymousConstructor = checkUsage(cls);
|
||||
@@ -77,6 +74,22 @@ public class ProcessAnonymous extends AbstractVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean canBeAnonymous(ClassNode cls) {
|
||||
if (cls.getAccessFlags().isSynthetic()) {
|
||||
return true;
|
||||
}
|
||||
String shortName = cls.getClassInfo().getShortName();
|
||||
if (shortName.contains("$") || Character.isDigit(shortName.charAt(0))) {
|
||||
return true;
|
||||
}
|
||||
if (cls.getUseIn().size() == 1 && cls.getUseInMth().size() == 1) {
|
||||
MethodNode useMth = cls.getUseInMth().get(0);
|
||||
// allow use in enum class init
|
||||
return useMth.getMethodInfo().isClassInit() && useMth.getParentClass().isEnum();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks:
|
||||
* - class have only one constructor which used only once (allow common code for field init)
|
||||
|
||||
@@ -52,19 +52,18 @@ public class JadxCodeAssertions extends AbstractStringAssert<JadxCodeAssertions>
|
||||
}
|
||||
String indent = TestUtils.indent(commonIndent);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
boolean first = true;
|
||||
for (String line : lines) {
|
||||
if (!line.isEmpty()) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
sb.append(ICodeWriter.NL);
|
||||
}
|
||||
sb.append(indent);
|
||||
sb.append(line);
|
||||
sb.append(ICodeWriter.NL);
|
||||
if (line.isEmpty()) {
|
||||
// don't add common indent to empty lines
|
||||
continue;
|
||||
}
|
||||
String searchLine = indent + line;
|
||||
sb.append(searchLine);
|
||||
// check every line for easier debugging
|
||||
contains(searchLine);
|
||||
}
|
||||
return containsOnlyOnce(sb.toString());
|
||||
return containsOnlyOnce(sb.substring(ICodeWriter.NL.length()));
|
||||
}
|
||||
|
||||
public JadxCodeAssertions removeBlockComments() {
|
||||
|
||||
@@ -2,11 +2,10 @@ package jadx.tests.integration.enums;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
import jadx.api.CommentsLevel;
|
||||
import jadx.tests.api.IntegrationTest;
|
||||
import jadx.tests.api.utils.JadxMatchers;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;
|
||||
|
||||
public class TestEnums2 extends IntegrationTest {
|
||||
|
||||
@@ -32,25 +31,25 @@ public class TestEnums2 extends IntegrationTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
ClassNode cls = getClassNode(TestCls.class);
|
||||
String code = removeLineComments(cls);
|
||||
|
||||
assertThat(code, JadxMatchers.containsLines(1,
|
||||
"public enum Operation {",
|
||||
indent(1) + "PLUS {",
|
||||
indent(2) + "@Override",
|
||||
indent(2) + "public int apply(int x, int y) {",
|
||||
indent(3) + "return x + y;",
|
||||
indent(2) + '}',
|
||||
indent(1) + "},",
|
||||
indent(1) + "MINUS {",
|
||||
indent(2) + "@Override",
|
||||
indent(2) + "public int apply(int x, int y) {",
|
||||
indent(3) + "return x - y;",
|
||||
indent(2) + '}',
|
||||
indent(1) + "};",
|
||||
"",
|
||||
indent(1) + "public abstract int apply(int i, int i2);",
|
||||
"}"));
|
||||
getArgs().setCommentsLevel(CommentsLevel.WARN);
|
||||
assertThat(getClassNode(TestCls.class))
|
||||
.code()
|
||||
.containsLines(1,
|
||||
"public enum Operation {",
|
||||
indent(1) + "PLUS {",
|
||||
indent(2) + "@Override",
|
||||
indent(2) + "public int apply(int x, int y) {",
|
||||
indent(3) + "return x + y;",
|
||||
indent(2) + '}',
|
||||
indent(1) + "},",
|
||||
indent(1) + "MINUS {",
|
||||
indent(2) + "@Override",
|
||||
indent(2) + "public int apply(int x, int y) {",
|
||||
indent(3) + "return x - y;",
|
||||
indent(2) + '}',
|
||||
indent(1) + "};",
|
||||
"",
|
||||
indent(1) + "public abstract int apply(int i, int i2);",
|
||||
"}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,10 @@ package jadx.tests.integration.enums;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
import jadx.api.CommentsLevel;
|
||||
import jadx.tests.api.IntegrationTest;
|
||||
import jadx.tests.api.utils.JadxMatchers;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;
|
||||
|
||||
public class TestEnumsInterface extends IntegrationTest {
|
||||
|
||||
@@ -34,23 +33,23 @@ public class TestEnumsInterface extends IntegrationTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
ClassNode cls = getClassNode(TestCls.class);
|
||||
String code = removeLineComments(cls);
|
||||
|
||||
assertThat(code, JadxMatchers.containsLines(1,
|
||||
"public enum Operation implements IOperation {",
|
||||
indent(1) + "PLUS {",
|
||||
indent(2) + "@Override",
|
||||
indent(2) + "public int apply(int x, int y) {",
|
||||
indent(3) + "return x + y;",
|
||||
indent(2) + '}',
|
||||
indent(1) + "},",
|
||||
indent(1) + "MINUS {",
|
||||
indent(2) + "@Override",
|
||||
indent(2) + "public int apply(int x, int y) {",
|
||||
indent(3) + "return x - y;",
|
||||
indent(2) + '}',
|
||||
indent(1) + '}',
|
||||
"}"));
|
||||
getArgs().setCommentsLevel(CommentsLevel.WARN);
|
||||
assertThat(getClassNode(TestCls.class))
|
||||
.code()
|
||||
.containsLines(1,
|
||||
"public enum Operation implements IOperation {",
|
||||
indent(1) + "PLUS {",
|
||||
indent(2) + "@Override",
|
||||
indent(2) + "public int apply(int x, int y) {",
|
||||
indent(3) + "return x + y;",
|
||||
indent(2) + '}',
|
||||
indent(1) + "},",
|
||||
indent(1) + "MINUS {",
|
||||
indent(2) + "@Override",
|
||||
indent(2) + "public int apply(int x, int y) {",
|
||||
indent(3) + "return x - y;",
|
||||
indent(2) + '}',
|
||||
indent(1) + '}',
|
||||
"}");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user