diff options
Diffstat (limited to 'src/org/jetbrains/java/decompiler/modules')
-rw-r--r-- | src/org/jetbrains/java/decompiler/modules/decompiler/stats/SwitchStatement.java | 54 |
1 files changed, 52 insertions, 2 deletions
diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/SwitchStatement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/SwitchStatement.java index b0ec5e3..694baae 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/SwitchStatement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/SwitchStatement.java @@ -24,6 +24,7 @@ import org.jetbrains.java.decompiler.modules.decompiler.DecHelper; import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; import org.jetbrains.java.decompiler.modules.decompiler.StatEdge; import org.jetbrains.java.decompiler.modules.decompiler.exps.*; +import org.jetbrains.java.decompiler.struct.StructClass; import org.jetbrains.java.decompiler.struct.gen.VarType; import org.jetbrains.java.decompiler.util.InterpreterUtil; import org.jetbrains.java.decompiler.util.Util; @@ -137,7 +138,12 @@ public class SwitchStatement extends Statement { tracer.incrementCurrentSourceLine(); } - buf.append(indstr).append(headexprent.get(0).toJava(indent, tracer)).append(" {").append(new_line_separator); + // Doesn't seem to be a better place to put it so enhance things here + Map<Integer, String> remaps = enhanceHead(headexprent.get(0), buf, indent, tracer); + + if (remaps == null) { + buf.append(indstr).append(headexprent.get(0).toJava(indent, tracer)).append(" {").append(new_line_separator); + } tracer.incrementCurrentSourceLine(); VarType switch_type = headexprent.get(0).getExprType(); @@ -157,7 +163,13 @@ public class SwitchStatement extends Statement { ConstExprent value = (ConstExprent)values.get(j).copy(); value.setConsttype(switch_type); - buf.append(indstr).append("case ").append(value.toJava(indent, tracer)).append(":").append(new_line_separator); + buf.append(indstr).append("case "); + if (remaps == null) { + buf.append(value.toJava(indent, tracer)); + } else { + buf.append(remaps.get(value.getValue())); + } + buf.append(":").append(new_line_separator); tracer.incrementCurrentSourceLine(); } } @@ -176,6 +188,44 @@ public class SwitchStatement extends Statement { return buf.toString(); } + private Map<Integer, String> enhanceHead(Exprent exprent, StringBuilder buf, int indent, BytecodeMappingTracer tracer) { + if (exprent.type != Exprent.EXPRENT_SWITCH) return null; + + SwitchExprent swtch = (SwitchExprent)exprent; + if (swtch.getValue().type != Exprent.EXPRENT_ARRAY) return null; + + ArrayExprent array = (ArrayExprent)swtch.getValue(); + if (array.getArray().type != Exprent.EXPRENT_FIELD || array.getIndex().type != Exprent.EXPRENT_INVOCATION) return null; + + FieldExprent field = (FieldExprent)array.getArray(); + InvocationExprent invoc = (InvocationExprent)array.getIndex(); + StructClass cls = DecompilerContext.getStructContext().getClass(field.getClassname()); + if (cls == null || !field.isStatic() || !"ordinal".equals(invoc.getName()) || !"()I".equals(invoc.getStringDescriptor())) return null; + + Map<Integer, String> ret = cls.enumSwitchMap.get(field.getName()); + if (ret == null) return null; + + for (List<ConstExprent> lst : getCaseValues()) { + if (lst != null) { + for (ConstExprent cst : lst) { + if (cst != null && (!(cst.getValue() instanceof Integer) || !ret.containsKey(cst.getValue()))) { + return null; + } + } + } + } + + tracer.addMapping(swtch.bytecode); + tracer.addMapping(field.bytecode); + tracer.addMapping(invoc.bytecode); + + String indstr = InterpreterUtil.getIndentString(indent); + String new_line_separator = DecompilerContext.getNewLineSeparator(); + + buf.append(indstr).append("switch (").append((invoc.getInstance().toJava(indent, tracer))).append(") {").append(new_line_separator); + return ret; + } + public void initExprents() { SwitchExprent swexpr = (SwitchExprent)first.getExprents().remove(first.getExprents().size() - 1); swexpr.setCaseValues(caseValues); |