Skip to content

Commit

Permalink
feat: Support switch statement by char.
Browse files Browse the repository at this point in the history
  • Loading branch information
teletha committed Mar 21, 2023
1 parent c5dbcca commit dd640c7
Show file tree
Hide file tree
Showing 9 changed files with 59 additions and 10 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ The output method of the analyzed code is not limited to Java, but is designed t
- [x] break
- [x] continue
- [x] switch
- [x] by char
- [ ] by enum
- [ ] by String
- [ ] pattern matching
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/reincarnation/Operand.java
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,15 @@ protected boolean isNegatable() {
return false;
}

/**
* Get the associated class type.
*
* @return
*/
public final Class type() {
return type.v instanceof Class clazz ? clazz : Object.class;
}

/**
* Enclose myself.
*
Expand Down
13 changes: 9 additions & 4 deletions src/main/java/reincarnation/OperandSwitch.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
import reincarnation.structure.Switch;
import reincarnation.util.MultiMap;

/**
* Operand representing a switch statement.
*/
class OperandSwitch extends Operand {

/** The condition. */
Expand All @@ -33,10 +36,12 @@ class OperandSwitch extends Operand {
private Node follow;

/**
* @param condition
* @param keys
* @param caseNodes
* @param defaultNode
* Creates a new {@code OperandSwitch} instance.
*
* @param condition the condition operand
* @param keys the keys for each case
* @param caseNodes the nodes corresponding to each case
* @param defaultNode the default node
*/
OperandSwitch(Operand condition, int[] keys, List<Node> caseNodes, Node defaultNode) {
this.condition = condition;
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/reincarnation/coder/Coder.java
Original file line number Diff line number Diff line change
Expand Up @@ -727,9 +727,10 @@ public final void writeEnclose(Code code) {
*
* @param label A block label.
* @param condition
* @param conditionType TODO
* @param cases
* @param defaultCode
* @param follow
*/
public abstract void writeSwitch(Optional<String> label, Code condition, MultiMap<Code, Integer> cases, Code defaultCode, Code follow);
public abstract void writeSwitch(Optional<String> label, Code condition, Class conditionType, MultiMap<Code, Integer> cases, Code defaultCode, Code follow);
}
4 changes: 2 additions & 2 deletions src/main/java/reincarnation/coder/DelegatableCoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,7 @@ public void writeTryCatchFinally(Code tryBlock, List<Ⅲ<Class, String, Code>> c
* {@inheritDoc}
*/
@Override
public void writeSwitch(Optional<String> label, Code condition, MultiMap<Code, Integer> cases, Code defaultCode, Code follow) {
coder.writeSwitch(label, condition, cases, defaultCode, follow);
public void writeSwitch(Optional<String> label, Code condition, Class conditionType, MultiMap<Code, Integer> cases, Code defaultCode, Code follow) {
coder.writeSwitch(label, condition, conditionType, cases, defaultCode, follow);
}
}
14 changes: 12 additions & 2 deletions src/main/java/reincarnation/coder/java/JavaCoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -1046,12 +1046,12 @@ public void writeTryCatchFinally(Code tryBlock, List<Ⅲ<Class, String, Code>> c
* {@inheritDoc}
*/
@Override
public void writeSwitch(Optional<String> label, Code condition, MultiMap<Code, Integer> caseBlocks, Code defaultBlock, Code follow) {
public void writeSwitch(Optional<String> label, Code condition, Class conditionType, MultiMap<Code, Integer> caseBlocks, Code defaultBlock, Code follow) {
line(label(label), "switch", space, "(", condition, ")", space, "{");
indent(() -> {
caseBlocks.forEach((code, keys) -> {
for (int key : keys) {
line("case ", key, ":");
line("case ", conditionType == char.class ? writeChar(key) : key, ":");
}
indent(() -> write(code));
});
Expand All @@ -1067,6 +1067,16 @@ public void writeSwitch(Optional<String> label, Code condition, MultiMap<Code, I
write(follow);
}

/**
* Create char expression from int.
*
* @param value
* @return
*/
private String writeChar(int value) {
return "'" + (char) value + "'";
}

/**
* Write the given annotation out.
*
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/reincarnation/structure/Switch.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,6 @@ public Signal<Structure> follower() {
*/
@Override
protected void writeCode(Coder coder) {
coder.writeSwitch(label(), condition, cases, defaultCase, follow);
coder.writeSwitch(label(), condition, condition.type(), cases, defaultCase, follow);
}
}
1 change: 1 addition & 0 deletions src/project/java/reincarnation/Project.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ public class Project extends bee.api.Project {
- [x] break
- [x] continue
- [x] switch
- [x] by char
- [ ] by enum
- [ ] by String
- [ ] pattern matching
Expand Down
22 changes: 22 additions & 0 deletions src/test/java/reincarnation/decompiler/flow/SwitchTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.junit.jupiter.api.Test;

import reincarnation.CodeVerifier;
import reincarnation.Debuggable;
import reincarnation.TestCode;

class SwitchTest extends CodeVerifier {
Expand Down Expand Up @@ -1147,6 +1148,27 @@ public int run(@Param(from = 0, to = 10) int param) {
});
}

@Test
@Debuggable
void conditionChar() {
verify(new TestCode.CharParam() {

@Override
public char run(@Param(chars = {'a', 'b', 'c', 'd', 'e'}) char param) {
switch (param) {
case 'a':
return 'A';

case 'b':
return 'B';

default:
return param;
}
}
});
}

@Test
@Disabled
void switchExpression() {
Expand Down

0 comments on commit dd640c7

Please sign in to comment.