core: fix indent for 'break' in 'case' block, refactor tests
This commit is contained in:
@@ -50,30 +50,20 @@ public class CodeWriter {
|
||||
|
||||
public CodeWriter startLine() {
|
||||
addLine();
|
||||
addIndent();
|
||||
addLineIndent();
|
||||
return this;
|
||||
}
|
||||
|
||||
public CodeWriter startLine(char c) {
|
||||
addLine();
|
||||
addIndent();
|
||||
addLineIndent();
|
||||
add(c);
|
||||
return this;
|
||||
}
|
||||
|
||||
public CodeWriter startLine(String str) {
|
||||
addLine();
|
||||
addIndent();
|
||||
add(str);
|
||||
return this;
|
||||
}
|
||||
|
||||
public CodeWriter startLine(int ind, String str) {
|
||||
addLine();
|
||||
addIndent();
|
||||
for (int i = 0; i < ind; i++) {
|
||||
addIndent();
|
||||
}
|
||||
addLineIndent();
|
||||
add(str);
|
||||
return this;
|
||||
}
|
||||
@@ -118,12 +108,17 @@ public class CodeWriter {
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
public CodeWriter addIndent() {
|
||||
private CodeWriter addLineIndent() {
|
||||
buf.append(indentStr);
|
||||
offset += indentStr.length();
|
||||
return this;
|
||||
}
|
||||
|
||||
public CodeWriter addIndent() {
|
||||
add(INDENT);
|
||||
return this;
|
||||
}
|
||||
|
||||
private void updateIndent() {
|
||||
int curIndent = indent;
|
||||
if (curIndent < INDENT_CACHE.length) {
|
||||
@@ -137,14 +132,6 @@ public class CodeWriter {
|
||||
}
|
||||
}
|
||||
|
||||
public int getLine() {
|
||||
return line;
|
||||
}
|
||||
|
||||
public int getIndent() {
|
||||
return indent;
|
||||
}
|
||||
|
||||
public void incIndent() {
|
||||
incIndent(1);
|
||||
}
|
||||
@@ -167,6 +154,10 @@ public class CodeWriter {
|
||||
updateIndent();
|
||||
}
|
||||
|
||||
public int getLine() {
|
||||
return line;
|
||||
}
|
||||
|
||||
private static class DefinitionWrapper {
|
||||
private final LineAttrNode node;
|
||||
|
||||
|
||||
@@ -203,6 +203,7 @@ public class RegionGen extends InsnGen {
|
||||
code.startLine("switch (");
|
||||
addArg(code, arg);
|
||||
code.add(") {");
|
||||
code.incIndent();
|
||||
|
||||
int size = sw.getKeys().size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
@@ -223,18 +224,21 @@ public class RegionGen extends InsnGen {
|
||||
code.startLine("default:");
|
||||
makeCaseBlock(sw.getDefaultCase(), code);
|
||||
}
|
||||
code.decIndent();
|
||||
code.startLine('}');
|
||||
return code;
|
||||
}
|
||||
|
||||
private void makeCaseBlock(IContainer c, CodeWriter code) throws CodegenException {
|
||||
boolean addBreak = true;
|
||||
if (RegionUtils.notEmpty(c)) {
|
||||
makeRegionIndent(code, c);
|
||||
if (RegionUtils.hasExitEdge(c)) {
|
||||
code.startLine(1, "break;");
|
||||
if (!RegionUtils.hasExitEdge(c)) {
|
||||
addBreak = false;
|
||||
}
|
||||
} else {
|
||||
code.startLine(1, "break;");
|
||||
}
|
||||
if (addBreak) {
|
||||
code.startLine().addIndent().add("break;");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package jadx.api;
|
||||
|
||||
import jadx.core.Jadx;
|
||||
import jadx.core.codegen.CodeWriter;
|
||||
import jadx.core.dex.attributes.AttributeFlag;
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
import jadx.core.dex.nodes.MethodNode;
|
||||
@@ -25,7 +24,7 @@ import static junit.framework.Assert.assertFalse;
|
||||
import static junit.framework.Assert.assertNotNull;
|
||||
import static junit.framework.Assert.fail;
|
||||
|
||||
public abstract class InternalJadxTest {
|
||||
public abstract class InternalJadxTest extends TestUtils {
|
||||
|
||||
protected boolean outputCFG = false;
|
||||
protected boolean deleteTmpJar = true;
|
||||
@@ -151,14 +150,6 @@ public abstract class InternalJadxTest {
|
||||
}
|
||||
}
|
||||
|
||||
protected String makeIndent(int indent) {
|
||||
StringBuilder sb = new StringBuilder(indent * CodeWriter.INDENT.length());
|
||||
for (int i = 0; i < indent; i++) {
|
||||
sb.append(CodeWriter.INDENT);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
// Use only for debug purpose
|
||||
@Deprecated
|
||||
protected void setOutputCFG() {
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package jadx.api;
|
||||
|
||||
import jadx.core.codegen.CodeWriter;
|
||||
|
||||
public class TestUtils {
|
||||
|
||||
public static String indent(int indent) {
|
||||
StringBuilder sb = new StringBuilder(indent * CodeWriter.INDENT.length());
|
||||
for (int i = 0; i < indent; i++) {
|
||||
sb.append(CodeWriter.INDENT);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static int count(String string, String substring) {
|
||||
int count = 0;
|
||||
int idx = 0;
|
||||
while ((idx = string.indexOf(substring, idx)) != -1) {
|
||||
idx++;
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package jadx.tests.internal;
|
||||
|
||||
import jadx.api.InternalJadxTest;
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
public class TestSwitch extends InternalJadxTest {
|
||||
public static class TestCls {
|
||||
public String escape(String str) {
|
||||
int len = str.length();
|
||||
StringBuilder sb = new StringBuilder(len);
|
||||
for (int i = 0; i < len; i++) {
|
||||
char c = str.charAt(i);
|
||||
switch (c) {
|
||||
case '.':
|
||||
case '/':
|
||||
sb.append('_');
|
||||
break;
|
||||
|
||||
case ']':
|
||||
sb.append('A');
|
||||
break;
|
||||
|
||||
case '?':
|
||||
break;
|
||||
|
||||
default:
|
||||
sb.append(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
ClassNode cls = getClassNode(TestCls.class);
|
||||
String code = cls.getCode().toString();
|
||||
System.out.println(code);
|
||||
|
||||
assertThat(code, containsString("case '/':"));
|
||||
assertThat(code, containsString(indent(5) + "break;"));
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,6 @@ public class TestSynchronized extends InternalJadxTest {
|
||||
assertThat(code, containsString("return this.f"));
|
||||
assertThat(code, containsString("synchronized (this.o) {"));
|
||||
|
||||
assertThat(code, not(containsString(makeIndent(3) + ";")));
|
||||
assertThat(code, not(containsString(indent(3) + ";")));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ public class TestVariablesDefinitions extends InternalJadxTest {
|
||||
System.out.println(code);
|
||||
|
||||
// 'iterator' variable must be declared inside 'try' block
|
||||
assertThat(code, containsString(makeIndent(3) + "Iterator<IDexTreeVisitor> iterator = "));
|
||||
assertThat(code, containsString(indent(3) + "Iterator<IDexTreeVisitor> iterator = "));
|
||||
assertThat(code, not(containsString("iterator;")));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,8 +44,8 @@ public class TestAnonymousClass3 extends InternalJadxTest {
|
||||
String code = cls.getCode().toString();
|
||||
System.out.println(code);
|
||||
|
||||
assertThat(code, containsString(makeIndent(4) + "public void run() {"));
|
||||
assertThat(code, containsString(makeIndent(3) + "}.start();"));
|
||||
assertThat(code, containsString(indent(4) + "public void run() {"));
|
||||
assertThat(code, containsString(indent(3) + "}.start();"));
|
||||
|
||||
// assertThat(code, not(containsString("synthetic")));
|
||||
// assertThat(code, not(containsString("AnonymousClass_")));
|
||||
|
||||
Reference in New Issue
Block a user