未验证 提交 bd3e6261 编写于 作者: S Skylot

fix: correct inline for enums in `j$.time.temporal`

上级 00b48473
......@@ -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,8 +484,12 @@ public class EnumVisitor extends AbstractVisitor {
}
}
field.setCls(innerCls);
if (!innerCls.getParentClass().equals(cls)) {
// not inner
cls.addInlinedClass(innerCls);
innerCls.add(AFlag.DONT_GENERATE);
}
}
private ConstructorInsn getConstructorInsn(InsnNode insn) {
if (insn.getArgsCount() != 1) {
......
......@@ -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);
if (line.isEmpty()) {
// don't add common indent to empty lines
continue;
}
sb.append(indent);
sb.append(line);
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,10 +31,10 @@ public class TestEnums2 extends IntegrationTest {
@Test
public void test() {
ClassNode cls = getClassNode(TestCls.class);
String code = removeLineComments(cls);
assertThat(code, JadxMatchers.containsLines(1,
getArgs().setCommentsLevel(CommentsLevel.WARN);
assertThat(getClassNode(TestCls.class))
.code()
.containsLines(1,
"public enum Operation {",
indent(1) + "PLUS {",
indent(2) + "@Override",
......@@ -51,6 +50,6 @@ public class TestEnums2 extends IntegrationTest {
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,10 +33,10 @@ public class TestEnumsInterface extends IntegrationTest {
@Test
public void test() {
ClassNode cls = getClassNode(TestCls.class);
String code = removeLineComments(cls);
assertThat(code, JadxMatchers.containsLines(1,
getArgs().setCommentsLevel(CommentsLevel.WARN);
assertThat(getClassNode(TestCls.class))
.code()
.containsLines(1,
"public enum Operation implements IOperation {",
indent(1) + "PLUS {",
indent(2) + "@Override",
......@@ -51,6 +50,6 @@ public class TestEnumsInterface extends IntegrationTest {
indent(3) + "return x - y;",
indent(2) + '}',
indent(1) + '}',
"}"));
"}");
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册