java-decompiler: post-import cleanup (common fixes and optimizations)

master
Roman Shevchenko 10 years ago
parent 63b8d35d08
commit f5431c3bb1
  1. 8
      src/org/jetbrains/java/decompiler/code/ExceptionHandler.java
  2. 2
      src/org/jetbrains/java/decompiler/code/InstructionSequence.java
  3. 2
      src/org/jetbrains/java/decompiler/code/cfg/BasicBlock.java
  4. 117
      src/org/jetbrains/java/decompiler/code/cfg/ControlFlowGraph.java
  5. 8
      src/org/jetbrains/java/decompiler/code/cfg/ExceptionRangeCFG.java
  6. 10
      src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java
  7. 8
      src/org/jetbrains/java/decompiler/main/ClassWriter.java
  8. 12
      src/org/jetbrains/java/decompiler/main/ClassesProcessor.java
  9. 4
      src/org/jetbrains/java/decompiler/main/Fernflower.java
  10. 3
      src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java
  11. 38
      src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java
  12. 6
      src/org/jetbrains/java/decompiler/main/rels/LambdaProcessor.java
  13. 26
      src/org/jetbrains/java/decompiler/main/rels/MethodProcessorThread.java
  14. 26
      src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java
  15. 2
      src/org/jetbrains/java/decompiler/main/rels/NestedMemberAccess.java
  16. 7
      src/org/jetbrains/java/decompiler/modules/code/DeadCodeHelper.java
  17. 5
      src/org/jetbrains/java/decompiler/modules/decompiler/DecHelper.java
  18. 9
      src/org/jetbrains/java/decompiler/modules/decompiler/DomHelper.java
  19. 20
      src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java
  20. 121
      src/org/jetbrains/java/decompiler/modules/decompiler/FinallyProcessor.java
  21. 21
      src/org/jetbrains/java/decompiler/modules/decompiler/LabelHelper.java
  22. 36
      src/org/jetbrains/java/decompiler/modules/decompiler/StackVarsProcessor.java
  23. 2
      src/org/jetbrains/java/decompiler/modules/decompiler/decompose/DominatorEngine.java
  24. 2
      src/org/jetbrains/java/decompiler/modules/decompiler/decompose/GenericDominatorEngine.java
  25. 68
      src/org/jetbrains/java/decompiler/modules/decompiler/deobfuscator/ExceptionDeobfuscator.java
  26. 4
      src/org/jetbrains/java/decompiler/modules/decompiler/exps/AnnotationExprent.java
  27. 4
      src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java
  28. 2
      src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java
  29. 2
      src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java
  30. 6
      src/org/jetbrains/java/decompiler/modules/decompiler/exps/IfExprent.java
  31. 6
      src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java
  32. 2
      src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java
  33. 2
      src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java
  34. 2
      src/org/jetbrains/java/decompiler/modules/decompiler/sforms/DirectGraph.java
  35. 15
      src/org/jetbrains/java/decompiler/modules/decompiler/sforms/FlattenStatementsHelper.java
  36. 4
      src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAConstructorSparseEx.java
  37. 6
      src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAUConstructorSparseEx.java
  38. 18
      src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchAllStatement.java
  39. 13
      src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchStatement.java
  40. 23
      src/org/jetbrains/java/decompiler/modules/decompiler/stats/DoStatement.java
  41. 8
      src/org/jetbrains/java/decompiler/modules/decompiler/stats/GeneralStatement.java
  42. 16
      src/org/jetbrains/java/decompiler/modules/decompiler/stats/IfStatement.java
  43. 4
      src/org/jetbrains/java/decompiler/modules/decompiler/stats/SequenceStatement.java
  44. 37
      src/org/jetbrains/java/decompiler/modules/decompiler/stats/Statement.java
  45. 10
      src/org/jetbrains/java/decompiler/modules/decompiler/stats/SwitchStatement.java
  46. 8
      src/org/jetbrains/java/decompiler/modules/decompiler/stats/SynchronizedStatement.java
  47. 2
      src/org/jetbrains/java/decompiler/modules/decompiler/vars/CheckTypesResult.java
  48. 13
      src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java
  49. 2
      src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarTypeProcessor.java
  50. 4
      src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsGraph.java
  51. 6
      src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsProcessor.java
  52. 5
      src/org/jetbrains/java/decompiler/modules/renamer/IdentifierConverter.java
  53. 7
      src/org/jetbrains/java/decompiler/struct/StructMethod.java
  54. 2
      src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java
  55. 4
      src/org/jetbrains/java/decompiler/struct/gen/VarType.java
  56. 2
      src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMain.java
  57. 6
      src/org/jetbrains/java/decompiler/struct/gen/generics/GenericType.java
  58. 2
      src/org/jetbrains/java/decompiler/struct/lazy/LazyLoader.java
  59. 2
      src/org/jetbrains/java/decompiler/util/FastSparseSetFactory.java
  60. 3
      src/org/jetbrains/java/decompiler/util/InterpreterUtil.java
  61. 15
      src/org/jetbrains/java/decompiler/util/SFormsFastMapDirect.java
  62. 2
      src/org/jetbrains/java/decompiler/util/VBStyleCollection.java

@ -54,10 +54,8 @@ public class ExceptionHandler {
String new_line_separator = DecompilerContext.getNewLineSeparator(); String new_line_separator = DecompilerContext.getNewLineSeparator();
StringBuffer buf = new StringBuffer(); return "from: " + from + " to: " + to + " handler: " + handler + new_line_separator +
buf.append("from: " + from + " to: " + to + " handler: " + handler + new_line_separator); "from_instr: " + from_instr + " to_instr: " + to_instr + " handler_instr: " + handler_instr + new_line_separator +
buf.append("from_instr: " + from_instr + " to_instr: " + to_instr + " handler_instr: " + handler_instr + new_line_separator); "exceptionClass: " + exceptionClass + new_line_separator;
buf.append("exceptionClass: " + exceptionClass + new_line_separator);
return buf.toString();
} }
} }

@ -140,7 +140,7 @@ public int getOffset(int index) {
String new_line_separator = DecompilerContext.getNewLineSeparator(); String new_line_separator = DecompilerContext.getNewLineSeparator();
StringBuffer buf = new StringBuffer(); StringBuilder buf = new StringBuilder();
for (int i = 0; i < collinstr.size(); i++) { for (int i = 0; i < collinstr.size(); i++) {
buf.append(InterpreterUtil.getIndentString(indent)); buf.append(InterpreterUtil.getIndentString(indent));

@ -169,7 +169,7 @@ public class BasicBlock implements IGraphNode {
String new_line_separator = DecompilerContext.getNewLineSeparator(); String new_line_separator = DecompilerContext.getNewLineSeparator();
StringBuffer buf = new StringBuffer(); StringBuilder buf = new StringBuilder();
for (int i = 0; i < seq.length(); i++) { for (int i = 0; i < seq.length(); i++) {
if (i < instrOldOffsets.size()) { if (i < instrOldOffsets.size()) {

@ -45,9 +45,9 @@ public class ControlFlowGraph implements CodeConstants {
private List<ExceptionRangeCFG> exceptions; private List<ExceptionRangeCFG> exceptions;
private HashMap<BasicBlock, BasicBlock> subroutines; private Map<BasicBlock, BasicBlock> subroutines;
private HashSet<BasicBlock> finallyExits = new HashSet<BasicBlock>(); private Set<BasicBlock> finallyExits = new HashSet<BasicBlock>();
// ***************************************************************************** // *****************************************************************************
// constructors // constructors
@ -85,16 +85,16 @@ public class ControlFlowGraph implements CodeConstants {
String new_line_separator = DecompilerContext.getNewLineSeparator(); String new_line_separator = DecompilerContext.getNewLineSeparator();
StringBuffer buf = new StringBuffer(); StringBuilder buf = new StringBuilder();
for (BasicBlock block : blocks) { for (BasicBlock block : blocks) {
buf.append("----- Block " + block.id + " -----" + new_line_separator); buf.append("----- Block ").append(block.id).append(" -----").append(new_line_separator);
buf.append(block.toString()); buf.append(block.toString());
buf.append("----- Edges -----" + new_line_separator); buf.append("----- Edges -----").append(new_line_separator);
List<BasicBlock> suc = block.getSuccs(); List<BasicBlock> suc = block.getSuccs();
for (int j = 0; j < suc.size(); j++) { for (int j = 0; j < suc.size(); j++) {
buf.append(">>>>>>>>(regular) Block " + suc.get(j).id + new_line_separator); buf.append(">>>>>>>>(regular) Block ").append(suc.get(j).id).append(new_line_separator);
} }
suc = block.getSuccExceptions(); suc = block.getSuccExceptions();
for (int j = 0; j < suc.size(); j++) { for (int j = 0; j < suc.size(); j++) {
@ -102,21 +102,22 @@ public class ControlFlowGraph implements CodeConstants {
ExceptionRangeCFG range = getExceptionRange(handler, block); ExceptionRangeCFG range = getExceptionRange(handler, block);
if (range == null) { if (range == null) {
buf.append(">>>>>>>>(exception) Block " + handler.id + "\t" + "ERROR: range not found!" + new_line_separator); buf.append(">>>>>>>>(exception) Block ").append(handler.id).append("\t").append("ERROR: range not found!")
.append(new_line_separator);
} }
else { else {
List<String> exceptionTypes = range.getExceptionTypes(); List<String> exceptionTypes = range.getExceptionTypes();
if (exceptionTypes == null) { if (exceptionTypes == null) {
buf.append(">>>>>>>>(exception) Block " + handler.id + "\t" + "NULL" + new_line_separator); buf.append(">>>>>>>>(exception) Block ").append(handler.id).append("\t").append("NULL").append(new_line_separator);
} }
else { else {
for (String exceptionType : exceptionTypes) { for (String exceptionType : exceptionTypes) {
buf.append(">>>>>>>>(exception) Block " + handler.id + "\t" + exceptionType + new_line_separator); buf.append(">>>>>>>>(exception) Block ").append(handler.id).append("\t").append(exceptionType).append(new_line_separator);
} }
} }
} }
} }
buf.append("----- ----- -----" + new_line_separator); buf.append("----- ----- -----").append(new_line_separator);
} }
return buf.toString(); return buf.toString();
@ -223,7 +224,7 @@ public class ControlFlowGraph implements CodeConstants {
short[] states = findStartInstructions(instrseq); short[] states = findStartInstructions(instrseq);
HashMap<Integer, BasicBlock> mapInstrBlocks = new HashMap<Integer, BasicBlock>(); Map<Integer, BasicBlock> mapInstrBlocks = new HashMap<Integer, BasicBlock>();
VBStyleCollection<BasicBlock, Integer> colBlocks = createBasicBlocks(states, instrseq, mapInstrBlocks); VBStyleCollection<BasicBlock, Integer> colBlocks = createBasicBlocks(states, instrseq, mapInstrBlocks);
blocks = colBlocks; blocks = colBlocks;
@ -237,12 +238,12 @@ public class ControlFlowGraph implements CodeConstants {
setFirstAndLastBlocks(); setFirstAndLastBlocks();
} }
private short[] findStartInstructions(InstructionSequence seq) { private static short[] findStartInstructions(InstructionSequence seq) {
int len = seq.length(); int len = seq.length();
short[] inststates = new short[len]; short[] inststates = new short[len];
HashSet<Integer> excSet = new HashSet<Integer>(); Set<Integer> excSet = new HashSet<Integer>();
for (ExceptionHandler handler : seq.getExceptionTable().getHandlers()) { for (ExceptionHandler handler : seq.getExceptionTable().getHandlers()) {
excSet.add(handler.from_instr); excSet.add(handler.from_instr);
@ -287,8 +288,9 @@ public class ControlFlowGraph implements CodeConstants {
} }
private VBStyleCollection<BasicBlock, Integer> createBasicBlocks(short[] startblock, InstructionSequence instrseq, private VBStyleCollection<BasicBlock, Integer> createBasicBlocks(short[] startblock,
HashMap<Integer, BasicBlock> mapInstrBlocks) { InstructionSequence instrseq,
Map<Integer, BasicBlock> mapInstrBlocks) {
VBStyleCollection<BasicBlock, Integer> col = new VBStyleCollection<BasicBlock, Integer>(); VBStyleCollection<BasicBlock, Integer> col = new VBStyleCollection<BasicBlock, Integer>();
@ -329,7 +331,7 @@ public class ControlFlowGraph implements CodeConstants {
} }
private void connectBlocks(List<BasicBlock> lstbb, HashMap<Integer, BasicBlock> mapInstrBlocks) { private static void connectBlocks(List<BasicBlock> lstbb, Map<Integer, BasicBlock> mapInstrBlocks) {
for (int i = 0; i < lstbb.size(); i++) { for (int i = 0; i < lstbb.size(); i++) {
@ -365,7 +367,7 @@ public class ControlFlowGraph implements CodeConstants {
} }
} }
private void setExceptionEdges(InstructionSequence instrseq, HashMap<Integer, BasicBlock> instrBlocks) { private void setExceptionEdges(InstructionSequence instrseq, Map<Integer, BasicBlock> instrBlocks) {
exceptions = new ArrayList<ExceptionRangeCFG>(); exceptions = new ArrayList<ExceptionRangeCFG>();
@ -404,7 +406,7 @@ public class ControlFlowGraph implements CodeConstants {
private void setSubroutineEdges() { private void setSubroutineEdges() {
final HashMap<BasicBlock, BasicBlock> subroutines = new HashMap<BasicBlock, BasicBlock>(); final Map<BasicBlock, BasicBlock> subroutines = new HashMap<BasicBlock, BasicBlock>();
for (BasicBlock block : blocks) { for (BasicBlock block : blocks) {
@ -413,7 +415,7 @@ public class ControlFlowGraph implements CodeConstants {
LinkedList<BasicBlock> stack = new LinkedList<BasicBlock>(); LinkedList<BasicBlock> stack = new LinkedList<BasicBlock>();
LinkedList<LinkedList<BasicBlock>> stackJsrStacks = new LinkedList<LinkedList<BasicBlock>>(); LinkedList<LinkedList<BasicBlock>> stackJsrStacks = new LinkedList<LinkedList<BasicBlock>>();
HashSet<BasicBlock> setVisited = new HashSet<BasicBlock>(); Set<BasicBlock> setVisited = new HashSet<BasicBlock>();
stack.add(block); stack.add(block);
stackJsrStacks.add(new LinkedList<BasicBlock>()); stackJsrStacks.add(new LinkedList<BasicBlock>());
@ -461,53 +463,64 @@ public class ControlFlowGraph implements CodeConstants {
} }
private void processJsr() { private void processJsr() {
while (true) {
if (processJsrRanges() == 0) break;
}
}
private static class JsrRecord {
private final BasicBlock jsr;
private final Set<BasicBlock> range;
private final BasicBlock ret;
while (processJsrRanges() != 0) ; private JsrRecord(BasicBlock jsr, Set<BasicBlock> range, BasicBlock ret) {
this.jsr = jsr;
this.range = range;
this.ret = ret;
}
} }
private int processJsrRanges() { private int processJsrRanges() {
List<Object[]> lstJsrAll = new ArrayList<Object[]>(); List<JsrRecord> lstJsrAll = new ArrayList<JsrRecord>();
// get all jsr ranges // get all jsr ranges
for (Entry<BasicBlock, BasicBlock> ent : subroutines.entrySet()) { for (Entry<BasicBlock, BasicBlock> ent : subroutines.entrySet()) {
BasicBlock jsr = ent.getKey(); BasicBlock jsr = ent.getKey();
BasicBlock ret = ent.getValue(); BasicBlock ret = ent.getValue();
lstJsrAll.add(new Object[]{jsr, getJsrRange(jsr, ret), ret}); lstJsrAll.add(new JsrRecord(jsr, getJsrRange(jsr, ret), ret));
} }
// sort ranges // sort ranges
// FIXME: better sort order // FIXME: better sort order
List<Object[]> lstJsr = new ArrayList<Object[]>(); List<JsrRecord> lstJsr = new ArrayList<JsrRecord>();
for (Object[] arr : lstJsrAll) { for (JsrRecord arr : lstJsrAll) {
int i = 0; int i = 0;
for (; i < lstJsr.size(); i++) { for (; i < lstJsr.size(); i++) {
Object[] arrJsr = lstJsr.get(i); JsrRecord arrJsr = lstJsr.get(i);
if (arrJsr.range.contains(arr.jsr)) {
if (((HashSet<BasicBlock>)arrJsr[1]).contains(arr[0])) {
break; break;
} }
} }
lstJsr.add(i, arr); lstJsr.add(i, arr);
} }
// find the first intersection // find the first intersection
for (int i = 0; i < lstJsr.size(); i++) { for (int i = 0; i < lstJsr.size(); i++) {
Object[] arr = lstJsr.get(i); JsrRecord arr = lstJsr.get(i);
HashSet<BasicBlock> set = (HashSet<BasicBlock>)arr[1]; Set<BasicBlock> set = arr.range;
for (int j = i + 1; j < lstJsr.size(); j++) { for (int j = i + 1; j < lstJsr.size(); j++) {
Object[] arr1 = lstJsr.get(j); JsrRecord arr1 = lstJsr.get(j);
HashSet<BasicBlock> set1 = (HashSet<BasicBlock>)arr1[1]; Set<BasicBlock> set1 = arr1.range;
if (!set.contains(arr1[0]) && !set1.contains(arr[0])) { // rang 0 doesn't contain entry 1 and vice versa if (!set.contains(arr1.jsr) && !set1.contains(arr.jsr)) { // rang 0 doesn't contain entry 1 and vice versa
HashSet<BasicBlock> setc = new HashSet<BasicBlock>(set); Set<BasicBlock> setc = new HashSet<BasicBlock>(set);
setc.retainAll(set1); setc.retainAll(set1);
if (!setc.isEmpty()) { if (!setc.isEmpty()) {
splitJsrRange((BasicBlock)arr[0], (BasicBlock)arr[2], setc); splitJsrRange(arr.jsr, arr.ret, setc);
return 1; return 1;
} }
} }
@ -517,11 +530,11 @@ public class ControlFlowGraph implements CodeConstants {
return 0; return 0;
} }
private HashSet<BasicBlock> getJsrRange(BasicBlock jsr, BasicBlock ret) { private Set<BasicBlock> getJsrRange(BasicBlock jsr, BasicBlock ret) {
HashSet<BasicBlock> blocks = new HashSet<BasicBlock>(); Set<BasicBlock> blocks = new HashSet<BasicBlock>();
LinkedList<BasicBlock> lstNodes = new LinkedList<BasicBlock>(); List<BasicBlock> lstNodes = new LinkedList<BasicBlock>();
lstNodes.add(jsr); lstNodes.add(jsr);
BasicBlock dom = jsr.getSuccs().get(0); BasicBlock dom = jsr.getSuccs().get(0);
@ -581,10 +594,10 @@ public class ControlFlowGraph implements CodeConstants {
return blocks; return blocks;
} }
private void splitJsrRange(BasicBlock jsr, BasicBlock ret, HashSet<BasicBlock> common_blocks) { private void splitJsrRange(BasicBlock jsr, BasicBlock ret, Set<BasicBlock> common_blocks) {
LinkedList<BasicBlock> lstNodes = new LinkedList<BasicBlock>(); List<BasicBlock> lstNodes = new LinkedList<BasicBlock>();
HashMap<Integer, BasicBlock> mapNewNodes = new HashMap<Integer, BasicBlock>(); Map<Integer, BasicBlock> mapNewNodes = new HashMap<Integer, BasicBlock>();
lstNodes.add(jsr); lstNodes.add(jsr);
mapNewNodes.put(jsr.id, jsr); mapNewNodes.put(jsr.id, jsr);
@ -662,7 +675,7 @@ public class ControlFlowGraph implements CodeConstants {
splitJsrExceptionRanges(common_blocks, mapNewNodes); splitJsrExceptionRanges(common_blocks, mapNewNodes);
} }
private void splitJsrExceptionRanges(HashSet<BasicBlock> common_blocks, HashMap<Integer, BasicBlock> mapNewNodes) { private void splitJsrExceptionRanges(Set<BasicBlock> common_blocks, Map<Integer, BasicBlock> mapNewNodes) {
for (int i = exceptions.size() - 1; i >= 0; i--) { for (int i = exceptions.size() - 1; i >= 0; i--) {
@ -696,7 +709,7 @@ public class ControlFlowGraph implements CodeConstants {
removeJsrInstructions(mt.getClassStruct().getPool(), first, DataPoint.getInitialDataPoint(mt)); removeJsrInstructions(mt.getClassStruct().getPool(), first, DataPoint.getInitialDataPoint(mt));
} }
private void removeJsrInstructions(ConstantPool pool, BasicBlock block, DataPoint data) { private static void removeJsrInstructions(ConstantPool pool, BasicBlock block, DataPoint data) {
ListStack<VarType> stack = data.getStack(); ListStack<VarType> stack = data.getStack();
@ -765,18 +778,18 @@ public class ControlFlowGraph implements CodeConstants {
public List<BasicBlock> getReversePostOrder() { public List<BasicBlock> getReversePostOrder() {
LinkedList<BasicBlock> res = new LinkedList<BasicBlock>(); List<BasicBlock> res = new LinkedList<BasicBlock>();
addToReversePostOrderListIterative(first, res); addToReversePostOrderListIterative(first, res);
return res; return res;
} }
private void addToReversePostOrderListIterative(BasicBlock root, List<BasicBlock> lst) { private static void addToReversePostOrderListIterative(BasicBlock root, List<BasicBlock> lst) {
LinkedList<BasicBlock> stackNode = new LinkedList<BasicBlock>(); LinkedList<BasicBlock> stackNode = new LinkedList<BasicBlock>();
LinkedList<Integer> stackIndex = new LinkedList<Integer>(); LinkedList<Integer> stackIndex = new LinkedList<Integer>();
HashSet<BasicBlock> setVisited = new HashSet<BasicBlock>(); Set<BasicBlock> setVisited = new HashSet<BasicBlock>();
stackNode.add(root); stackNode.add(root);
stackIndex.add(0); stackIndex.add(0);
@ -845,32 +858,26 @@ public class ControlFlowGraph implements CodeConstants {
this.exceptions = exceptions; this.exceptions = exceptions;
} }
public BasicBlock getLast() { public BasicBlock getLast() {
return last; return last;
} }
public void setLast(BasicBlock last) { public void setLast(BasicBlock last) {
this.last = last; this.last = last;
} }
public Map<BasicBlock, BasicBlock> getSubroutines() {
public HashMap<BasicBlock, BasicBlock> getSubroutines() {
return subroutines; return subroutines;
} }
public void setSubroutines(Map<BasicBlock, BasicBlock> subroutines) {
public void setSubroutines(HashMap<BasicBlock, BasicBlock> subroutines) {
this.subroutines = subroutines; this.subroutines = subroutines;
} }
public Set<BasicBlock> getFinallyExits() {
public HashSet<BasicBlock> getFinallyExits() {
return finallyExits; return finallyExits;
} }
public void setFinallyExits(HashSet<BasicBlock> finallyExits) { public void setFinallyExits(HashSet<BasicBlock> finallyExits) {
this.finallyExits = finallyExits; this.finallyExits = finallyExits;
} }

@ -47,18 +47,18 @@ public class ExceptionRangeCFG {
String new_line_separator = DecompilerContext.getNewLineSeparator(); String new_line_separator = DecompilerContext.getNewLineSeparator();
StringBuffer buf = new StringBuffer(); StringBuilder buf = new StringBuilder();
buf.append("exceptionType:"); buf.append("exceptionType:");
for (String exception_type : exceptionTypes) { for (String exception_type : exceptionTypes) {
buf.append(" " + exception_type); buf.append(" ").append(exception_type);
} }
buf.append(new_line_separator); buf.append(new_line_separator);
buf.append("handler: " + handler.id + new_line_separator); buf.append("handler: ").append(handler.id).append(new_line_separator);
buf.append("range: "); buf.append("range: ");
for (int i = 0; i < protectedRange.size(); i++) { for (int i = 0; i < protectedRange.size(); i++) {
buf.append(protectedRange.get(i).id + " "); buf.append(protectedRange.get(i).id).append(" ");
} }
buf.append(new_line_separator); buf.append(new_line_separator);

@ -122,9 +122,9 @@ public class ClassReference14Processor {
} }
} }
private void processClassRec(ClassNode node, private static void processClassRec(ClassNode node,
final HashMap<ClassWrapper, MethodWrapper> mapClassMeths, final HashMap<ClassWrapper, MethodWrapper> mapClassMeths,
final HashSet<ClassWrapper> setFound) { final HashSet<ClassWrapper> setFound) {
final ClassWrapper wrapper = node.wrapper; final ClassWrapper wrapper = node.wrapper;
@ -221,7 +221,7 @@ public class ClassReference14Processor {
} }
private boolean replaceInvocations(Exprent exprent, ClassWrapper wrapper, MethodWrapper meth) { private static boolean replaceInvocations(Exprent exprent, ClassWrapper wrapper, MethodWrapper meth) {
boolean res = false; boolean res = false;
@ -250,7 +250,7 @@ public class ClassReference14Processor {
} }
private String isClass14Invocation(Exprent exprent, ClassWrapper wrapper, MethodWrapper meth) { private static String isClass14Invocation(Exprent exprent, ClassWrapper wrapper, MethodWrapper meth) {
if (exprent.type == Exprent.EXPRENT_FUNCTION) { if (exprent.type == Exprent.EXPRENT_FUNCTION) {
FunctionExprent fexpr = (FunctionExprent)exprent; FunctionExprent fexpr = (FunctionExprent)exprent;

@ -1046,7 +1046,7 @@ public class ClassWriter {
return !hidemethod; return !hidemethod;
} }
private List<AnnotationExprent> getAllAnnotations(VBStyleCollection<StructGeneralAttribute, String> attributes) { private static List<AnnotationExprent> getAllAnnotations(VBStyleCollection<StructGeneralAttribute, String> attributes) {
String[] annattrnames = new String[]{StructGeneralAttribute.ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS, String[] annattrnames = new String[]{StructGeneralAttribute.ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS,
StructGeneralAttribute.ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS}; StructGeneralAttribute.ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS};
@ -1063,7 +1063,7 @@ public class ClassWriter {
return lst; return lst;
} }
private List<List<AnnotationExprent>> getAllParameterAnnotations(VBStyleCollection<StructGeneralAttribute, String> attributes) { private static List<List<AnnotationExprent>> getAllParameterAnnotations(VBStyleCollection<StructGeneralAttribute, String> attributes) {
String[] annattrnames = new String[]{StructGeneralAttribute.ATTRIBUTE_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS, String[] annattrnames = new String[]{StructGeneralAttribute.ATTRIBUTE_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS,
StructGeneralAttribute.ATTRIBUTE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS}; StructGeneralAttribute.ATTRIBUTE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS};
@ -1095,7 +1095,7 @@ public class ClassWriter {
return ret; return ret;
} }
private String getDescriptorPrintOut(String descriptor, int element) { private static String getDescriptorPrintOut(String descriptor, int element) {
switch (element) { switch (element) {
case 0: // class case 0: // class
@ -1125,7 +1125,7 @@ public class ClassWriter {
} }
} }
private String getTypePrintOut(VarType type) { private static String getTypePrintOut(VarType type) {
String strtype = ExprProcessor.getCastTypeName(type, false); String strtype = ExprProcessor.getCastTypeName(type, false);
if (ExprProcessor.UNDEFINED_TYPE_STRING.equals(strtype) && if (ExprProcessor.UNDEFINED_TYPE_STRING.equals(strtype) &&
DecompilerContext.getOption(IFernflowerPreferences.UNDEFINED_PARAM_TYPE_OBJECT)) { DecompilerContext.getOption(IFernflowerPreferences.UNDEFINED_PARAM_TYPE_OBJECT)) {

@ -303,7 +303,7 @@ public class ClassesProcessor {
} }
} }
private void initWrappers(ClassNode node) throws IOException { private static void initWrappers(ClassNode node) throws IOException {
if (node.type == ClassNode.CLASS_LAMBDA) { if (node.type == ClassNode.CLASS_LAMBDA) {
return; return;
@ -319,7 +319,7 @@ public class ClassesProcessor {
} }
} }
private void addClassnameToImport(ClassNode node, ImportCollector imp) { private static void addClassnameToImport(ClassNode node, ImportCollector imp) {
if (node.simpleName != null && node.simpleName.length() > 0) { if (node.simpleName != null && node.simpleName.length() > 0) {
imp.getShortName(node.type == ClassNode.CLASS_ROOT ? node.classStruct.qualifiedName : node.simpleName, false); imp.getShortName(node.type == ClassNode.CLASS_ROOT ? node.classStruct.qualifiedName : node.simpleName, false);
@ -330,7 +330,7 @@ public class ClassesProcessor {
} }
} }
private void destroyWrappers(ClassNode node) { private static void destroyWrappers(ClassNode node) {
node.wrapper = null; node.wrapper = null;
node.classStruct.releaseResources(); node.classStruct.releaseResources();
@ -345,7 +345,7 @@ public class ClassesProcessor {
} }
public class ClassNode { public static class ClassNode {
public static final int CLASS_ROOT = 0; public static final int CLASS_ROOT = 0;
public static final int CLASS_MEMBER = 1; public static final int CLASS_MEMBER = 1;
@ -436,9 +436,7 @@ public class ClassesProcessor {
return null; return null;
} }
public class LambdaInformation { public static class LambdaInformation {
public String class_name; public String class_name;
public String method_name; public String method_name;
public String method_descriptor; public String method_descriptor;

@ -50,9 +50,7 @@ public class Fernflower implements IDecompiledData {
public void decompileContext() { public void decompileContext() {
if (DecompilerContext.getOption(IFernflowerPreferences.RENAME_ENTITIES)) { if (DecompilerContext.getOption(IFernflowerPreferences.RENAME_ENTITIES)) {
IdentifierConverter ren = new IdentifierConverter(); new IdentifierConverter().rename(structcontext);
ren.rename(structcontext);
ren = null;
} }
clprocessor = new ClassesProcessor(structcontext); clprocessor = new ClassesProcessor(structcontext);

@ -311,8 +311,7 @@ public class ConsoleDecompiler implements IBytecodeProvider, IDecompilatSaver {
String filename = new File(getAbsolutePath(path), archivename).getAbsolutePath(); String filename = new File(getAbsolutePath(path), archivename).getAbsolutePath();
mapArchiveEntries.remove(filename); mapArchiveEntries.remove(filename);
ZipOutputStream out = mapArchiveStreams.remove(filename); OutputStream out = mapArchiveStreams.remove(filename);
out.flush(); out.flush();
out.close(); out.close();
} }

@ -67,6 +67,8 @@ public class ClassWrapper {
setFieldNames.add(fd.getName()); setFieldNames.add(fd.getName());
} }
int maxsec = Integer.parseInt(DecompilerContext.getProperty(IFernflowerPreferences.MAX_PROCESSING_METHOD).toString());
for (StructMethod mt : classStruct.getMethods()) { for (StructMethod mt : classStruct.getMethods()) {
DecompilerContext.getLogger().startMethod(mt.getName() + " " + mt.getDescriptor()); DecompilerContext.getLogger().startMethod(mt.getName() + " " + mt.getDescriptor());
@ -83,7 +85,6 @@ public class ClassWrapper {
VarProcessor varproc = new VarProcessor(); VarProcessor varproc = new VarProcessor();
DecompilerContext.setProperty(DecompilerContext.CURRENT_VAR_PROCESSOR, varproc); DecompilerContext.setProperty(DecompilerContext.CURRENT_VAR_PROCESSOR, varproc);
Thread mtthread = null;
RootStatement root = null; RootStatement root = null;
boolean isError = false; boolean isError = false;
@ -91,28 +92,25 @@ public class ClassWrapper {
try { try {
if (mt.containsCode()) { if (mt.containsCode()) {
int maxsec = 10 * Integer.parseInt(DecompilerContext.getProperty(IFernflowerPreferences.MAX_PROCESSING_METHOD).toString());
if (maxsec == 0) { // blocking wait if (maxsec == 0) { // blocking wait
root = MethodProcessorThread.codeToJava(mt, varproc); root = MethodProcessorThread.codeToJava(mt, varproc);
} }
else { else {
MethodProcessorThread mtproc = new MethodProcessorThread(mt, varproc, DecompilerContext.getCurrentContext()); MethodProcessorThread mtproc = new MethodProcessorThread(mt, varproc, DecompilerContext.getCurrentContext());
mtthread = new Thread(mtproc); Thread mtthread = new Thread(mtproc);
long stopAt = System.currentTimeMillis() + maxsec * 1000;
mtthread.start(); mtthread.start();
int sec = 0;
while (mtthread.isAlive()) { while (mtthread.isAlive()) {
synchronized (mtproc) { synchronized (mtproc.lock) {
mtproc.wait(100); mtproc.lock.wait(100);
} }
if (maxsec > 0 && ++sec > maxsec) { if (System.currentTimeMillis() >= stopAt) {
DecompilerContext.getLogger().writeMessage("Processing time limit (" + maxsec + " sec.) for method " + String message = "Processing time limit exceeded for method " + mt.getName() + ", execution interrupted.";
mt.getName() + " " + mt.getDescriptor() + " exceeded, execution interrupted.", DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.ERROR);
IFernflowerLogger.ERROR);
mtthread.stop(); mtthread.stop();
isError = true; isError = true;
break; break;
@ -120,12 +118,7 @@ public class ClassWrapper {
} }
if (!isError) { if (!isError) {
if (mtproc.getError() != null) { root = mtproc.getResult();
throw mtproc.getError();
}
else {
root = mtproc.getRoot();
}
} }
} }
} }
@ -158,17 +151,6 @@ public class ClassWrapper {
} }
} }
} }
catch (ThreadDeath ex) {
try {
if (mtthread != null) {
mtthread.stop();
}
}
catch (Throwable ignored) {
}
throw ex;
}
catch (Throwable ex) { catch (Throwable ex) {
DecompilerContext.getLogger().writeMessage("Method " + mt.getName() + " " + mt.getDescriptor() + " couldn't be decompiled.", ex); DecompilerContext.getLogger().writeMessage("Method " + mt.getName() + " " + mt.getDescriptor() + " couldn't be decompiled.", ex);
isError = true; isError = true;

@ -112,9 +112,9 @@ public class LambdaProcessor {
LinkConstant content_method_handle = (LinkConstant)bootstrap_arguments.get(1); LinkConstant content_method_handle = (LinkConstant)bootstrap_arguments.get(1);
ClassNode node_lambda = clprocessor.new ClassNode(content_method_handle.classname, content_method_handle.elementname, ClassNode node_lambda = new ClassNode(content_method_handle.classname, content_method_handle.elementname,
content_method_handle.descriptor, content_method_handle.index1, content_method_handle.descriptor, content_method_handle.index1,
lambda_class_name, lambda_method_name, lambda_method_descriptor, cl); lambda_class_name, lambda_method_name, lambda_method_descriptor, cl);
node_lambda.simpleName = cl.qualifiedName + "##Lambda_" + invoke_dynamic.index1 + "_" + invoke_dynamic.index2; node_lambda.simpleName = cl.qualifiedName + "##Lambda_" + invoke_dynamic.index1 + "_" + invoke_dynamic.index2;
node_lambda.enclosingMethod = InterpreterUtil.makeUniqueKey(mt.getName(), mt.getDescriptor()); node_lambda.enclosingMethod = InterpreterUtil.makeUniqueKey(mt.getName(), mt.getDescriptor());

@ -33,16 +33,16 @@ import java.io.IOException;
public class MethodProcessorThread implements Runnable { public class MethodProcessorThread implements Runnable {
private StructMethod method; public final Object lock = new Object();
private VarProcessor varproc;
private DecompilerContext parentContext;
private RootStatement root; private final StructMethod method;
private final VarProcessor varproc;
private final DecompilerContext parentContext;
private Throwable error; private volatile RootStatement root;
private volatile Throwable error;
public MethodProcessorThread(StructMethod method, VarProcessor varproc, public MethodProcessorThread(StructMethod method, VarProcessor varproc, DecompilerContext parentContext) {
DecompilerContext parentContext) {
this.method = method; this.method = method;
this.varproc = varproc; this.varproc = varproc;
this.parentContext = parentContext; this.parentContext = parentContext;
@ -58,11 +58,13 @@ public class MethodProcessorThread implements Runnable {
try { try {
root = codeToJava(method, varproc); root = codeToJava(method, varproc);
synchronized (this) { synchronized (lock) {
this.notify(); lock.notifyAll();
} }
} }
catch (ThreadDeath ignored) { } catch (ThreadDeath ex) {
throw ex;
}
catch (Throwable ex) { catch (Throwable ex) {
error = ex; error = ex;
} }
@ -248,7 +250,9 @@ public class MethodProcessorThread implements Runnable {
return root; return root;
} }
public RootStatement getRoot() { public RootStatement getResult() throws Throwable {
Throwable t = error;
if (t != null) throw t;
return root; return root;
} }

@ -101,7 +101,7 @@ public class NestedClassProcessor {
} }
} }
private void setLambdaVars(ClassNode parent, ClassNode child) { private static void setLambdaVars(ClassNode parent, ClassNode child) {
if (child.lambda_information.is_method_reference) { // method reference, no code and no parameters if (child.lambda_information.is_method_reference) { // method reference, no code and no parameters
return; return;
@ -187,7 +187,7 @@ public class NestedClassProcessor {
} }
} }
private void checkNotFoundClasses(ClassNode root, ClassNode node) { private static void checkNotFoundClasses(ClassNode root, ClassNode node) {
List<ClassNode> lstChildren = new ArrayList<ClassNode>(node.nested); List<ClassNode> lstChildren = new ArrayList<ClassNode>(node.nested);
@ -232,7 +232,7 @@ public class NestedClassProcessor {
} }
} }
private boolean insertNestedClass(ClassNode root, ClassNode child) { private static boolean insertNestedClass(ClassNode root, ClassNode child) {
Set<String> setEnclosing = child.enclosingClasses; Set<String> setEnclosing = child.enclosingClasses;
@ -258,7 +258,7 @@ public class NestedClassProcessor {
} }
private void computeLocalVarsAndDefinitions(final ClassNode node) { private static void computeLocalVarsAndDefinitions(final ClassNode node) {
// local var masks // local var masks
// class name, constructor descriptor, field mask // class name, constructor descriptor, field mask
@ -433,7 +433,7 @@ public class NestedClassProcessor {
} }
} }
private void insertLocalVars(final ClassNode parent, final ClassNode child) { private static void insertLocalVars(final ClassNode parent, final ClassNode child) {
// enclosing method, is null iff member class // enclosing method, is null iff member class
MethodWrapper encmeth = parent.wrapper.getMethods().getWithKey(child.enclosingMethod); MethodWrapper encmeth = parent.wrapper.getMethods().getWithKey(child.enclosingMethod);
@ -634,7 +634,7 @@ public class NestedClassProcessor {
} }
} }
private HashMap<String, List<VarFieldPair>> getMaskLocalVars(ClassWrapper wrapper) { private static HashMap<String, List<VarFieldPair>> getMaskLocalVars(ClassWrapper wrapper) {
HashMap<String, List<VarFieldPair>> mapMasks = new HashMap<String, List<VarFieldPair>>(); HashMap<String, List<VarFieldPair>> mapMasks = new HashMap<String, List<VarFieldPair>>();
@ -666,7 +666,7 @@ public class NestedClassProcessor {
return mapMasks; return mapMasks;
} }
private String getEnclosingVarField(StructClass cl, MethodWrapper meth, DirectGraph graph, final int index) { private static String getEnclosingVarField(StructClass cl, MethodWrapper meth, DirectGraph graph, final int index) {
String field = ""; String field = "";
@ -709,7 +709,7 @@ public class NestedClassProcessor {
return field; return field;
} }
private void mergeListSignatures(List<VarFieldPair> first, List<VarFieldPair> second, boolean both) { private static void mergeListSignatures(List<VarFieldPair> first, List<VarFieldPair> second, boolean both) {
int i = 1; int i = 1;
while (true) { while (true) {
@ -818,7 +818,7 @@ public class NestedClassProcessor {
} }
private void setLocalClassDefinition(MethodWrapper meth, ClassNode node) { private static void setLocalClassDefinition(MethodWrapper meth, ClassNode node) {
RootStatement root = meth.root; RootStatement root = meth.root;
@ -862,7 +862,7 @@ public class NestedClassProcessor {
} }
private Statement findFirstBlock(Statement stat, HashSet<Statement> setStats) { private static Statement findFirstBlock(Statement stat, HashSet<Statement> setStats) {
LinkedList<Statement> stack = new LinkedList<Statement>(); LinkedList<Statement> stack = new LinkedList<Statement>();
stack.add(stat); stack.add(stat);
@ -903,7 +903,7 @@ public class NestedClassProcessor {
} }
private Statement getDefStatement(Statement stat, VarType classtype, HashSet<Statement> setStats) { private static Statement getDefStatement(Statement stat, VarType classtype, HashSet<Statement> setStats) {
List<Exprent> condlst = new ArrayList<Exprent>(); List<Exprent> condlst = new ArrayList<Exprent>();
Statement retstat = null; Statement retstat = null;
@ -958,7 +958,7 @@ public class NestedClassProcessor {
return retstat; return retstat;
} }
private boolean searchForClass(Exprent exprent, VarType classtype) { private static boolean searchForClass(Exprent exprent, VarType classtype) {
List<Exprent> lst = exprent.getAllExprents(true); List<Exprent> lst = exprent.getAllExprents(true);
lst.add(exprent); lst.add(exprent);
@ -1004,7 +1004,7 @@ public class NestedClassProcessor {
} }
private class VarFieldPair { private static class VarFieldPair {
public String keyfield = ""; public String keyfield = "";
public VarVersionPaar varpaar; public VarVersionPaar varpaar;

@ -310,7 +310,7 @@ public class NestedMemberAccess {
return res; return res;
} }
private boolean sameTree(ClassNode caller, ClassNode callee) { private static boolean sameTree(ClassNode caller, ClassNode callee) {
if (caller.classStruct.qualifiedName.equals(callee.classStruct.qualifiedName)) { if (caller.classStruct.qualifiedName.equals(callee.classStruct.qualifiedName)) {
return false; return false;

@ -24,10 +24,7 @@ import org.jetbrains.java.decompiler.code.cfg.ExceptionRangeCFG;
import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences;
import java.util.ArrayList; import java.util.*;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
public class DeadCodeHelper { public class DeadCodeHelper {
@ -177,7 +174,7 @@ public class DeadCodeHelper {
} }
// finally exit edges // finally exit edges
HashSet<BasicBlock> setFinallyExits = graph.getFinallyExits(); Set<BasicBlock> setFinallyExits = graph.getFinallyExits();
if (setFinallyExits.contains(block)) { if (setFinallyExits.contains(block)) {
setFinallyExits.remove(block); setFinallyExits.remove(block);
setFinallyExits.add(setPreds.iterator().next()); setFinallyExits.add(setPreds.iterator().next());

@ -83,11 +83,8 @@ public class DecHelper {
boolean repeat = false; boolean repeat = false;
setDest.remove(post); setDest.remove(post);
Iterator<Statement> it = setDest.iterator();
while (it.hasNext()) {
Statement stat = it.next();
for (Statement stat : setDest) {
if (stat.getLastBasicType() != Statement.LASTBASICTYPE_GENERAL) { if (stat.getLastBasicType() != Statement.LASTBASICTYPE_GENERAL) {
if (post == null) { if (post == null) {
post = stat; post = stat;

@ -497,10 +497,7 @@ public class DomHelper {
while (true) { while (true) {
boolean hdfound = false; boolean hdfound = false;
Iterator<Statement> itHandlers = setHandlers.iterator(); for (Statement handler : setHandlers) {
while (itHandlers.hasNext()) {
Statement handler = itHandlers.next();
if (setNodes.contains(handler)) { if (setNodes.contains(handler)) {
continue; continue;
} }
@ -553,9 +550,7 @@ public class DomHelper {
setHandlers.removeAll(setNodes); setHandlers.removeAll(setNodes);
boolean excok = true; boolean excok = true;
Iterator<Statement> itt = setHandlers.iterator(); for (Statement handler : setHandlers) {
while (itt.hasNext()) {
Statement handler = itt.next();
if (!handler.getNeighbours(StatEdge.TYPE_EXCEPTION, Statement.DIRECTION_BACKWARD).containsAll(setNodes)) { if (!handler.getNeighbours(StatEdge.TYPE_EXCEPTION, Statement.DIRECTION_BACKWARD).containsAll(setNodes)) {
excok = false; excok = false;
break; break;

@ -259,7 +259,7 @@ public class ExprProcessor implements CodeConstants {
} }
// FIXME: Ugly code, to be rewritten. A tuple class is needed. // FIXME: Ugly code, to be rewritten. A tuple class is needed.
private String buildEntryPointKey(LinkedList<String> entrypoints) { private static String buildEntryPointKey(LinkedList<String> entrypoints) {
if (entrypoints.isEmpty()) { if (entrypoints.isEmpty()) {
return null; return null;
} }
@ -273,7 +273,7 @@ public class ExprProcessor implements CodeConstants {
} }
} }
private PrimitiveExprsList copyVarExprents(PrimitiveExprsList data) { private static PrimitiveExprsList copyVarExprents(PrimitiveExprsList data) {
ExprentStack stack = data.getStack(); ExprentStack stack = data.getStack();
for (int i = 0; i < stack.size(); i++) { for (int i = 0; i < stack.size(); i++) {
stack.set(i, stack.get(i).copy()); stack.set(i, stack.get(i).copy());
@ -281,7 +281,7 @@ public class ExprProcessor implements CodeConstants {
return data; return data;
} }
private void collectCatchVars(Statement stat, FlattenStatementsHelper flatthelper, Map<String, VarExprent> map) { private static void collectCatchVars(Statement stat, FlattenStatementsHelper flatthelper, Map<String, VarExprent> map) {
List<VarExprent> lst = null; List<VarExprent> lst = null;
@ -306,7 +306,7 @@ public class ExprProcessor implements CodeConstants {
} }
} }
private void initStatementExprents(Statement stat) { private static void initStatementExprents(Statement stat) {
stat.initExprents(); stat.initExprents();
for (Statement st : stat.getStats()) { for (Statement st : stat.getStats()) {
@ -754,7 +754,7 @@ public class ExprProcessor implements CodeConstants {
} }
public static String jmpWrapper(Statement stat, int indent, boolean semicolon) { public static String jmpWrapper(Statement stat, int indent, boolean semicolon) {
StringBuffer buf = new StringBuffer(stat.toJava(indent)); StringBuilder buf = new StringBuilder(stat.toJava(indent));
String new_line_separator = DecompilerContext.getNewLineSeparator(); String new_line_separator = DecompilerContext.getNewLineSeparator();
@ -773,14 +773,14 @@ public class ExprProcessor implements CodeConstants {
} }
if (edge.labeled) { if (edge.labeled) {
buf.append(" label" + edge.closure.id); buf.append(" label").append(edge.closure.id);
} }
buf.append(";" + new_line_separator); buf.append(";").append(new_line_separator);
} }
} }
if (buf.length() == 0 && semicolon) { if (buf.length() == 0 && semicolon) {
buf.append(InterpreterUtil.getIndentString(indent) + ";" + new_line_separator); buf.append(InterpreterUtil.getIndentString(indent)).append(";").append(new_line_separator);
} }
return buf.toString(); return buf.toString();
@ -789,7 +789,7 @@ public class ExprProcessor implements CodeConstants {
public static String buildJavaClassName(String name) { public static String buildJavaClassName(String name) {
String res = name.replace('/', '.'); String res = name.replace('/', '.');
if (res.indexOf("$") >= 0) { // attempt to invoke foreign member if (res.contains("$")) { // attempt to invoke foreign member
// classes correctly // classes correctly
StructClass cl = DecompilerContext.getStructcontext().getClass(name); StructClass cl = DecompilerContext.getStructcontext().getClass(name);
if (cl == null || !cl.isOwn()) { if (cl == null || !cl.isOwn()) {
@ -808,7 +808,7 @@ public class ExprProcessor implements CodeConstants {
String indstr = InterpreterUtil.getIndentString(indent); String indstr = InterpreterUtil.getIndentString(indent);
String new_line_separator = DecompilerContext.getNewLineSeparator(); String new_line_separator = DecompilerContext.getNewLineSeparator();
StringBuffer buf = new StringBuffer(); StringBuilder buf = new StringBuilder();
for (Exprent expr : lst) { for (Exprent expr : lst) {
String content = expr.toJava(indent); String content = expr.toJava(indent);

@ -46,9 +46,8 @@ import java.util.Map.Entry;
public class FinallyProcessor { public class FinallyProcessor {
private Map<Integer, Integer> finallyBlockIDs = new HashMap<Integer, Integer>();
private HashMap<Integer, Integer> finallyBlockIDs = new HashMap<Integer, Integer>(); private Map<Integer, Integer> catchallBlockIDs = new HashMap<Integer, Integer>();
private HashMap<Integer, Integer> catchallBlockIDs = new HashMap<Integer, Integer>();
private VarProcessor varprocessor; private VarProcessor varprocessor;
@ -92,7 +91,7 @@ public class FinallyProcessor {
} }
else { else {
Object[] inf = getFinallyInformation(mt, root, fin); Record inf = getFinallyInformation(mt, root, fin);
if (inf == null) { // inconsistent finally if (inf == null) { // inconsistent finally
catchallBlockIDs.put(handler.id, null); catchallBlockIDs.put(handler.id, null);
@ -181,10 +180,20 @@ public class FinallyProcessor {
// return res; // return res;
// } // }
private static class Record {
private final int firstCode;
private final Map<BasicBlock, Boolean> mapLast;
private Record(int firstCode, Map<BasicBlock, Boolean> mapLast) {
this.firstCode = firstCode;
this.mapLast = mapLast;
}
}
private Object[] getFinallyInformation(StructMethod mt, RootStatement root, CatchAllStatement fstat) { private static Record getFinallyInformation(StructMethod mt, RootStatement root, CatchAllStatement fstat) {
HashMap<BasicBlock, Boolean> mapLast = new HashMap<BasicBlock, Boolean>(); Map<BasicBlock, Boolean> mapLast = new HashMap<BasicBlock, Boolean>();
BasicBlockStatement firstBlockStatement = fstat.getHandler().getBasichead(); BasicBlockStatement firstBlockStatement = fstat.getHandler().getBasichead();
BasicBlock firstBasicBlock = firstBlockStatement.getBlock(); BasicBlock firstBasicBlock = firstBlockStatement.getBlock();
@ -216,7 +225,7 @@ public class FinallyProcessor {
LinkedList<DirectNode> stack = new LinkedList<DirectNode>(); LinkedList<DirectNode> stack = new LinkedList<DirectNode>();
stack.add(dgraph.first); stack.add(dgraph.first);
HashSet<DirectNode> setVisited = new HashSet<DirectNode>(); Set<DirectNode> setVisited = new HashSet<DirectNode>();
while (!stack.isEmpty()) { while (!stack.isEmpty()) {
@ -356,21 +365,21 @@ public class FinallyProcessor {
} }
} }
return new Object[]{firstcode, mapLast}; return new Record(firstcode, mapLast);
} }
private void insertSemaphore(ControlFlowGraph graph, private static void insertSemaphore(ControlFlowGraph graph,
HashSet<BasicBlock> setTry, Set<BasicBlock> setTry,
BasicBlock head, BasicBlock head,
BasicBlock handler, BasicBlock handler,
int var, int var,
Object[] information, Record information,
int bytecode_version) { int bytecode_version) {
HashSet<BasicBlock> setCopy = new HashSet<BasicBlock>(setTry); Set<BasicBlock> setCopy = new HashSet<BasicBlock>(setTry);
int finallytype = (Integer)information[0]; int finallytype = information.firstCode;
HashMap<BasicBlock, Boolean> mapLast = (HashMap<BasicBlock, Boolean>)information[1]; Map<BasicBlock, Boolean> mapLast = information.mapLast;
// first and last statements // first and last statements
removeExceptionInstructionsEx(handler, 1, finallytype); removeExceptionInstructionsEx(handler, 1, finallytype);
@ -468,7 +477,7 @@ public class FinallyProcessor {
} }
private void insertBlockBefore(ControlFlowGraph graph, BasicBlock oldblock, BasicBlock newblock) { private static void insertBlockBefore(ControlFlowGraph graph, BasicBlock oldblock, BasicBlock newblock) {
List<BasicBlock> lstTemp = new ArrayList<BasicBlock>(); List<BasicBlock> lstTemp = new ArrayList<BasicBlock>();
lstTemp.addAll(oldblock.getPreds()); lstTemp.addAll(oldblock.getPreds());
@ -501,7 +510,7 @@ public class FinallyProcessor {
} }
} }
private HashSet<BasicBlock> getAllBasicBlocks(Statement stat) { private static HashSet<BasicBlock> getAllBasicBlocks(Statement stat) {
List<Statement> lst = new LinkedList<Statement>(); List<Statement> lst = new LinkedList<Statement>();
lst.add(stat); lst.add(stat);
@ -530,13 +539,13 @@ public class FinallyProcessor {
} }
private boolean verifyFinallyEx(ControlFlowGraph graph, CatchAllStatement fstat, Object[] information) { private boolean verifyFinallyEx(ControlFlowGraph graph, CatchAllStatement fstat, Record information) {
HashSet<BasicBlock> tryBlocks = getAllBasicBlocks(fstat.getFirst()); HashSet<BasicBlock> tryBlocks = getAllBasicBlocks(fstat.getFirst());
HashSet<BasicBlock> catchBlocks = getAllBasicBlocks(fstat.getHandler()); HashSet<BasicBlock> catchBlocks = getAllBasicBlocks(fstat.getHandler());
int finallytype = (Integer)information[0]; int finallytype = information.firstCode;
HashMap<BasicBlock, Boolean> mapLast = (HashMap<BasicBlock, Boolean>)information[1]; Map<BasicBlock, Boolean> mapLast = information.mapLast;
BasicBlock first = fstat.getHandler().getBasichead().getBlock(); BasicBlock first = fstat.getHandler().getBasichead().getBlock();
boolean skippedFirst = false; boolean skippedFirst = false;
@ -571,16 +580,16 @@ public class FinallyProcessor {
startBlocks.remove(graph.getLast()); startBlocks.remove(graph.getLast());
startBlocks.removeAll(tryBlocks); startBlocks.removeAll(tryBlocks);
List<Object[]> lstAreas = new ArrayList<Object[]>(); List<Area> lstAreas = new ArrayList<Area>();
for (BasicBlock start : startBlocks) { for (BasicBlock start : startBlocks) {
Object[] arr = compareSubgraphsEx(graph, start, catchBlocks, first, finallytype, mapLast, skippedFirst); Area arr = compareSubgraphsEx(graph, start, catchBlocks, first, finallytype, mapLast, skippedFirst);
if (arr == null) { if (arr == null) {
return false; return false;
} }
lstAreas.add(new Object[]{start, arr[0], arr[1]}); lstAreas.add(arr);
} }
// try { // try {
@ -588,7 +597,7 @@ public class FinallyProcessor {
// } catch(Exception ex){ex.printStackTrace();} // } catch(Exception ex){ex.printStackTrace();}
// delete areas // delete areas
for (Object[] area : lstAreas) { for (Area area : lstAreas) {
deleteArea(graph, area); deleteArea(graph, area);
} }
@ -611,13 +620,25 @@ public class FinallyProcessor {
return true; return true;
} }
private Object[] compareSubgraphsEx(ControlFlowGraph graph, private static class Area {
BasicBlock startSample, private final BasicBlock start;
HashSet<BasicBlock> catchBlocks, private final Set<BasicBlock> sample;
BasicBlock startCatch, private final BasicBlock next;
int finallytype,
HashMap<BasicBlock, Boolean> mapLast, private Area(BasicBlock start, Set<BasicBlock> sample, BasicBlock next) {
boolean skippedFirst) { this.start = start;
this.sample = sample;
this.next = next;
}
}
private Area compareSubgraphsEx(ControlFlowGraph graph,
BasicBlock startSample,
HashSet<BasicBlock> catchBlocks,
BasicBlock startCatch,
int finallytype,
Map<BasicBlock, Boolean> mapLast,
boolean skippedFirst) {
class BlockStackEntry { class BlockStackEntry {
public BasicBlock blockCatch; public BasicBlock blockCatch;
@ -635,9 +656,9 @@ public class FinallyProcessor {
List<BlockStackEntry> stack = new LinkedList<BlockStackEntry>(); List<BlockStackEntry> stack = new LinkedList<BlockStackEntry>();
HashSet<BasicBlock> setSample = new HashSet<BasicBlock>(); Set<BasicBlock> setSample = new HashSet<BasicBlock>();
HashMap<String, BasicBlock[]> mapNext = new HashMap<String, BasicBlock[]>(); Map<String, BasicBlock[]> mapNext = new HashMap<String, BasicBlock[]>();
stack.add(new BlockStackEntry(startCatch, startSample, new ArrayList<int[]>())); stack.add(new BlockStackEntry(startCatch, startSample, new ArrayList<int[]>()));
@ -719,7 +740,7 @@ public class FinallyProcessor {
} }
if (isLastBlock) { if (isLastBlock) {
HashSet<BasicBlock> setSuccs = new HashSet<BasicBlock>(blockSample.getSuccs()); Set<BasicBlock> setSuccs = new HashSet<BasicBlock>(blockSample.getSuccs());
setSuccs.removeAll(setSample); setSuccs.removeAll(setSample);
for (BlockStackEntry stackent : stack) { for (BlockStackEntry stackent : stack) {
@ -734,10 +755,10 @@ public class FinallyProcessor {
} }
} }
return new Object[]{setSample, getUniqueNext(graph, new HashSet<BasicBlock[]>(mapNext.values()))}; return new Area(startSample, setSample, getUniqueNext(graph, new HashSet<BasicBlock[]>(mapNext.values())));
} }
private BasicBlock getUniqueNext(ControlFlowGraph graph, HashSet<BasicBlock[]> setNext) { private static BasicBlock getUniqueNext(ControlFlowGraph graph, Set<BasicBlock[]> setNext) {
// precondition: there is at most one true exit path in a finally statement // precondition: there is at most one true exit path in a finally statement
@ -784,7 +805,7 @@ public class FinallyProcessor {
return null; return null;
} }
for (int j = 0; i < instrNext.getOperands().length; j++) { for (int j = 0; j < instrNext.getOperands().length; j++) {
if (instrNext.getOperand(j) != instrBlock.getOperand(j)) { if (instrNext.getOperand(j) != instrBlock.getOperand(j)) {
return null; return null;
} }
@ -889,7 +910,7 @@ public class FinallyProcessor {
graph.getBlocks().addWithKey(newblock, newblock.id); graph.getBlocks().addWithKey(newblock, newblock.id);
HashSet<BasicBlock> setFinallyExits = graph.getFinallyExits(); Set<BasicBlock> setFinallyExits = graph.getFinallyExits();
if (setFinallyExits.contains(sample)) { if (setFinallyExits.contains(sample)) {
setFinallyExits.remove(sample); setFinallyExits.remove(sample);
setFinallyExits.add(newblock); setFinallyExits.add(newblock);
@ -939,10 +960,10 @@ public class FinallyProcessor {
return true; return true;
} }
private void deleteArea(ControlFlowGraph graph, Object[] area) { private static void deleteArea(ControlFlowGraph graph, Area area) {
BasicBlock start = (BasicBlock)area[0]; BasicBlock start = area.start;
BasicBlock next = (BasicBlock)area[2]; BasicBlock next = area.next;
if (start == next) { if (start == next) {
return; return;
@ -954,23 +975,23 @@ public class FinallyProcessor {
} }
// collect common exception ranges of predecessors and successors // collect common exception ranges of predecessors and successors
HashSet<BasicBlock> setCommonExceptionHandlers = new HashSet<BasicBlock>(next.getSuccExceptions()); Set<BasicBlock> setCommonExceptionHandlers = new HashSet<BasicBlock>(next.getSuccExceptions());
for (BasicBlock pred : start.getPreds()) { for (BasicBlock pred : start.getPreds()) {
setCommonExceptionHandlers.retainAll(pred.getSuccExceptions()); setCommonExceptionHandlers.retainAll(pred.getSuccExceptions());
} }
boolean is_outside_range = false; boolean is_outside_range = false;
HashSet<BasicBlock> setPredecessors = new HashSet<BasicBlock>(start.getPreds()); Set<BasicBlock> setPredecessors = new HashSet<BasicBlock>(start.getPreds());
// replace start with next // replace start with next
for (BasicBlock pred : setPredecessors) { for (BasicBlock pred : setPredecessors) {
pred.replaceSuccessor(start, next); pred.replaceSuccessor(start, next);
} }
HashSet<BasicBlock> setBlocks = (HashSet<BasicBlock>)area[1]; Set<BasicBlock> setBlocks = area.sample;
HashSet<ExceptionRangeCFG> setCommonRemovedExceptionRanges = null; Set<ExceptionRangeCFG> setCommonRemovedExceptionRanges = null;
// remove all the blocks inbetween // remove all the blocks inbetween
for (BasicBlock block : setBlocks) { for (BasicBlock block : setBlocks) {
@ -983,7 +1004,7 @@ public class FinallyProcessor {
is_outside_range = true; is_outside_range = true;
} }
HashSet<ExceptionRangeCFG> setRemovedExceptionRanges = new HashSet<ExceptionRangeCFG>(); Set<ExceptionRangeCFG> setRemovedExceptionRanges = new HashSet<ExceptionRangeCFG>();
for (BasicBlock handler : block.getSuccExceptions()) { for (BasicBlock handler : block.getSuccExceptions()) {
setRemovedExceptionRanges.add(graph.getExceptionRange(handler, block)); setRemovedExceptionRanges.add(graph.getExceptionRange(handler, block));
} }
@ -1036,7 +1057,7 @@ public class FinallyProcessor {
} }
} }
private void removeExceptionInstructionsEx(BasicBlock block, int blocktype, int finallytype) { private static void removeExceptionInstructionsEx(BasicBlock block, int blocktype, int finallytype) {
InstructionSequence seq = block.getSeq(); InstructionSequence seq = block.getSeq();

@ -223,10 +223,8 @@ public class LabelHelper {
processEdgesWithNext(ifstat.getFirst(), mapEdges, null); processEdgesWithNext(ifstat.getFirst(), mapEdges, null);
} }
else { else {
if (ifstat.getIfstat() != null) { mapEdges = setExplicitEdges(ifstat.getIfstat());
mapEdges = setExplicitEdges(ifstat.getIfstat()); processEdgesWithNext(ifstat.getIfstat(), mapEdges, null);
processEdgesWithNext(ifstat.getIfstat(), mapEdges, null);
}
HashMap<Statement, List<StatEdge>> mapEdges1 = null; HashMap<Statement, List<StatEdge>> mapEdges1 = null;
if (ifstat.getElsestat() != null) { if (ifstat.getElsestat() != null) {
@ -422,17 +420,14 @@ public class LabelHelper {
} }
} }
private static HashSet<Statement>[] processStatementLabel(Statement stat) { private static void processStatementLabel(Statement stat) {
processStatementLabel(stat, new HashSet<Statement>(), new HashSet<Statement>());
HashSet<Statement> setBreak = new HashSet<Statement>(); }
HashSet<Statement> setContinue = new HashSet<Statement>();
private static void processStatementLabel(Statement stat, Set<Statement> setBreak, Set<Statement> setContinue) {
if (stat.getExprents() == null) { if (stat.getExprents() == null) {
for (Statement st : stat.getStats()) { for (Statement st : stat.getStats()) {
HashSet<Statement>[] arr = processStatementLabel(st); processStatementLabel(st, setBreak, setContinue);
setBreak.addAll(arr[0]);
setContinue.addAll(arr[1]);
} }
boolean shieldtype = (stat.type == Statement.TYPE_DO || stat.type == Statement.TYPE_SWITCH); boolean shieldtype = (stat.type == Statement.TYPE_DO || stat.type == Statement.TYPE_SWITCH);
@ -456,8 +451,6 @@ public class LabelHelper {
setBreak.add(stat); setBreak.add(stat);
setContinue.add(stat); setContinue.add(stat);
return new HashSet[]{setBreak, setContinue};
} }
public static void replaceContinueWithBreak(Statement stat) { public static void replaceContinueWithBreak(Statement stat) {

@ -110,7 +110,7 @@ public class StackVarsProcessor {
setVersionsToNull(root); setVersionsToNull(root);
} }
private void setVersionsToNull(Statement stat) { private static void setVersionsToNull(Statement stat) {
if (stat.getExprents() == null) { if (stat.getExprents() == null) {
for (Object obj : stat.getSequentialObjects()) { for (Object obj : stat.getSequentialObjects()) {
@ -129,7 +129,7 @@ public class StackVarsProcessor {
} }
} }
private void setExprentVersionsToNull(Exprent exprent) { private static void setExprentVersionsToNull(Exprent exprent) {
List<Exprent> lst = exprent.getAllExprents(true); List<Exprent> lst = exprent.getAllExprents(true);
lst.add(exprent); lst.add(exprent);
@ -236,7 +236,7 @@ public class StackVarsProcessor {
} }
private Exprent isReplaceableVar(Exprent exprent, HashMap<VarVersionPaar, Exprent> mapVarValues, SSAUConstructorSparseEx ssau) { private static Exprent isReplaceableVar(Exprent exprent, HashMap<VarVersionPaar, Exprent> mapVarValues, SSAUConstructorSparseEx ssau) {
Exprent dest = null; Exprent dest = null;
@ -248,7 +248,7 @@ public class StackVarsProcessor {
return dest; return dest;
} }
private void replaceSingleVar(Exprent parent, VarExprent var, Exprent dest, SSAUConstructorSparseEx ssau) { private static void replaceSingleVar(Exprent parent, VarExprent var, Exprent dest, SSAUConstructorSparseEx ssau) {
parent.replaceExprent(var, dest); parent.replaceExprent(var, dest);
@ -438,7 +438,7 @@ public class StackVarsProcessor {
} }
} }
private HashSet<VarVersionPaar> getAllVersions(Exprent exprent) { private static HashSet<VarVersionPaar> getAllVersions(Exprent exprent) {
HashSet<VarVersionPaar> res = new HashSet<VarVersionPaar>(); HashSet<VarVersionPaar> res = new HashSet<VarVersionPaar>();
@ -455,11 +455,11 @@ public class StackVarsProcessor {
return res; return res;
} }
private Object[] iterateChildExprent(Exprent exprent, private static Object[] iterateChildExprent(Exprent exprent,
Exprent parent, Exprent parent,
Exprent next, Exprent next,
HashMap<VarVersionPaar, Exprent> mapVarValues, HashMap<VarVersionPaar, Exprent> mapVarValues,
SSAUConstructorSparseEx ssau) { SSAUConstructorSparseEx ssau) {
boolean changed = false; boolean changed = false;
@ -589,7 +589,7 @@ public class StackVarsProcessor {
return new Object[]{null, changed, false}; return new Object[]{null, changed, false};
} }
private boolean getUsedVersions(SSAUConstructorSparseEx ssa, VarVersionPaar var, List<VarVersionNode> res) { private static boolean getUsedVersions(SSAUConstructorSparseEx ssa, VarVersionPaar var, List<VarVersionNode> res) {
VarVersionsGraph ssuversions = ssa.getSsuversions(); VarVersionsGraph ssuversions = ssa.getSsuversions();
VarVersionNode varnode = ssuversions.nodes.getWithKey(var); VarVersionNode varnode = ssuversions.nodes.getWithKey(var);
@ -638,10 +638,10 @@ public class StackVarsProcessor {
return !setNotDoms.isEmpty(); return !setNotDoms.isEmpty();
} }
private boolean isVersionToBeReplaced(VarVersionPaar usedvar, private static boolean isVersionToBeReplaced(VarVersionPaar usedvar,
HashMap<Integer, HashSet<VarVersionPaar>> mapVars, HashMap<Integer, HashSet<VarVersionPaar>> mapVars,
SSAUConstructorSparseEx ssau, SSAUConstructorSparseEx ssau,
VarVersionPaar leftpaar) { VarVersionPaar leftpaar) {
VarVersionsGraph ssuversions = ssau.getSsuversions(); VarVersionsGraph ssuversions = ssau.getSsuversions();
@ -687,9 +687,9 @@ public class StackVarsProcessor {
return true; return true;
} }
private HashMap<Integer, HashSet<VarVersionPaar>> getAllVarVersions(VarVersionPaar leftvar, private static HashMap<Integer, HashSet<VarVersionPaar>> getAllVarVersions(VarVersionPaar leftvar,
Exprent exprent, Exprent exprent,
SSAUConstructorSparseEx ssau) { SSAUConstructorSparseEx ssau) {
HashMap<Integer, HashSet<VarVersionPaar>> map = new HashMap<Integer, HashSet<VarVersionPaar>>(); HashMap<Integer, HashSet<VarVersionPaar>> map = new HashMap<Integer, HashSet<VarVersionPaar>>();
SFormsFastMapDirect mapLiveVars = ssau.getLiveVarVersionsMap(leftvar); SFormsFastMapDirect mapLiveVars = ssau.getLiveVarVersionsMap(leftvar);

@ -43,7 +43,7 @@ public class DominatorEngine {
} }
} }
private Integer getCommonIDom(Integer key1, Integer key2, VBStyleCollection<Integer, Integer> orderedIDoms) { private static Integer getCommonIDom(Integer key1, Integer key2, VBStyleCollection<Integer, Integer> orderedIDoms) {
if (key1 == null) { if (key1 == null) {
return key2; return key2;

@ -45,7 +45,7 @@ public class GenericDominatorEngine {
} }
} }
private IGraphNode getCommonIDom(IGraphNode node1, IGraphNode node2, VBStyleCollection<IGraphNode, IGraphNode> orderedIDoms) { private static IGraphNode getCommonIDom(IGraphNode node1, IGraphNode node2, VBStyleCollection<IGraphNode, IGraphNode> orderedIDoms) {
IGraphNode nodeOld; IGraphNode nodeOld;

@ -32,16 +32,30 @@ import java.util.Map.Entry;
public class ExceptionDeobfuscator { public class ExceptionDeobfuscator {
private static class Range {
private final BasicBlock handler;
private final String uniqueStr;
private final Set<BasicBlock> protectedRange;
private final ExceptionRangeCFG rangeCFG;
private Range(BasicBlock handler, String uniqueStr, Set<BasicBlock> protectedRange, ExceptionRangeCFG rangeCFG) {
this.handler = handler;
this.uniqueStr = uniqueStr;
this.protectedRange = protectedRange;
this.rangeCFG = rangeCFG;
}
}
public static void restorePopRanges(ControlFlowGraph graph) { public static void restorePopRanges(ControlFlowGraph graph) {
List<Object[]> lstRanges = new ArrayList<Object[]>(); List<Range> lstRanges = new ArrayList<Range>();
// aggregate ranges // aggregate ranges
for (ExceptionRangeCFG range : graph.getExceptions()) { for (ExceptionRangeCFG range : graph.getExceptions()) {
boolean found = false; boolean found = false;
for (Object[] arr : lstRanges) { for (Range arr : lstRanges) {
if (arr[0] == range.getHandler() && InterpreterUtil.equalObjects(range.getUniqueExceptionsString(), arr[1])) { if (arr.handler == range.getHandler() && InterpreterUtil.equalObjects(range.getUniqueExceptionsString(), arr.uniqueStr)) {
((HashSet<BasicBlock>)arr[2]).addAll(range.getProtectedRange()); arr.protectedRange.addAll(range.getProtectedRange());
found = true; found = true;
break; break;
} }
@ -49,37 +63,36 @@ public class ExceptionDeobfuscator {
if (!found) { if (!found) {
// doesn't matter, which range chosen // doesn't matter, which range chosen
lstRanges.add( lstRanges.add(new Range(range.getHandler(), range.getUniqueExceptionsString(), new HashSet<BasicBlock>(range.getProtectedRange()), range));
new Object[]{range.getHandler(), range.getUniqueExceptionsString(), new HashSet<BasicBlock>(range.getProtectedRange()), range});
} }
} }
// process aggregated ranges // process aggregated ranges
for (Object[] range : lstRanges) { for (Range range : lstRanges) {
if (range[1] != null) { if (range.uniqueStr != null) {
BasicBlock handler = (BasicBlock)range[0]; BasicBlock handler = range.handler;
InstructionSequence seq = handler.getSeq(); InstructionSequence seq = handler.getSeq();
Instruction firstinstr = null; Instruction firstinstr;
if (seq.length() > 0) { if (seq.length() > 0) {
firstinstr = seq.getInstr(0); firstinstr = seq.getInstr(0);
if (firstinstr.opcode == CodeConstants.opc_pop || if (firstinstr.opcode == CodeConstants.opc_pop ||
firstinstr.opcode == CodeConstants.opc_astore) { firstinstr.opcode == CodeConstants.opc_astore) {
HashSet<BasicBlock> setrange = new HashSet<BasicBlock>((HashSet<BasicBlock>)range[2]); Set<BasicBlock> setrange = new HashSet<BasicBlock>(range.protectedRange);
for (Object[] range_super : lstRanges) { // finally or strict superset for (Range range_super : lstRanges) { // finally or strict superset
if (range != range_super) { if (range != range_super) {
HashSet<BasicBlock> setrange_super = new HashSet<BasicBlock>((HashSet<BasicBlock>)range_super[2]); Set<BasicBlock> setrange_super = new HashSet<BasicBlock>(range_super.protectedRange);
if (!setrange.contains(range_super[0]) && !setrange_super.contains(handler) if (!setrange.contains(range_super.handler) && !setrange_super.contains(handler)
&& (range_super[1] == null || setrange_super.containsAll(setrange))) { && (range_super.uniqueStr == null || setrange_super.containsAll(setrange))) {
if (range_super[1] == null) { if (range_super.uniqueStr == null) {
setrange_super.retainAll(setrange); setrange_super.retainAll(setrange);
} }
else { else {
@ -129,11 +142,10 @@ public class ExceptionDeobfuscator {
seq.removeInstruction(0); seq.removeInstruction(0);
} }
newblock.addSuccessorException(range_super.handler);
range_super.rangeCFG.getProtectedRange().add(newblock);
newblock.addSuccessorException((BasicBlock)range_super[0]); handler = range.rangeCFG.getHandler();
((ExceptionRangeCFG)range_super[3]).getProtectedRange().add(newblock);
handler = ((ExceptionRangeCFG)range[3]).getHandler();
seq = handler.getSeq(); seq = handler.getSeq();
} }
} }
@ -147,7 +159,7 @@ public class ExceptionDeobfuscator {
public static void insertEmptyExceptionHandlerBlocks(ControlFlowGraph graph) { public static void insertEmptyExceptionHandlerBlocks(ControlFlowGraph graph) {
HashSet<BasicBlock> setVisited = new HashSet<BasicBlock>(); Set<BasicBlock> setVisited = new HashSet<BasicBlock>();
for (ExceptionRangeCFG range : graph.getExceptions()) { for (ExceptionRangeCFG range : graph.getExceptions()) {
BasicBlock handler = range.getHandler(); BasicBlock handler = range.getHandler();
@ -255,7 +267,7 @@ public class ExceptionDeobfuscator {
List<BasicBlock> lstRes = new ArrayList<BasicBlock>(); List<BasicBlock> lstRes = new ArrayList<BasicBlock>();
LinkedList<BasicBlock> stack = new LinkedList<BasicBlock>(); LinkedList<BasicBlock> stack = new LinkedList<BasicBlock>();
HashSet<BasicBlock> setVisited = new HashSet<BasicBlock>(); Set<BasicBlock> setVisited = new HashSet<BasicBlock>();
BasicBlock handler = range.getHandler(); BasicBlock handler = range.getHandler();
stack.addFirst(handler); stack.addFirst(handler);
@ -285,22 +297,20 @@ public class ExceptionDeobfuscator {
public static boolean hasObfuscatedExceptions(ControlFlowGraph graph) { public static boolean hasObfuscatedExceptions(ControlFlowGraph graph) {
BasicBlock first = graph.getFirst(); Map<BasicBlock, Set<BasicBlock>> mapRanges = new HashMap<BasicBlock, Set<BasicBlock>>();
HashMap<BasicBlock, HashSet<BasicBlock>> mapRanges = new HashMap<BasicBlock, HashSet<BasicBlock>>();
for (ExceptionRangeCFG range : graph.getExceptions()) { for (ExceptionRangeCFG range : graph.getExceptions()) {
HashSet<BasicBlock> set = mapRanges.get(range.getHandler()); Set<BasicBlock> set = mapRanges.get(range.getHandler());
if (set == null) { if (set == null) {
mapRanges.put(range.getHandler(), set = new HashSet<BasicBlock>()); mapRanges.put(range.getHandler(), set = new HashSet<BasicBlock>());
} }
set.addAll(range.getProtectedRange()); set.addAll(range.getProtectedRange());
} }
for (Entry<BasicBlock, HashSet<BasicBlock>> ent : mapRanges.entrySet()) { for (Entry<BasicBlock, Set<BasicBlock>> ent : mapRanges.entrySet()) {
HashSet<BasicBlock> setEntries = new HashSet<BasicBlock>(); Set<BasicBlock> setEntries = new HashSet<BasicBlock>();
for (BasicBlock block : ent.getValue()) { for (BasicBlock block : ent.getValue()) {
HashSet<BasicBlock> setTemp = new HashSet<BasicBlock>(block.getPreds()); Set<BasicBlock> setTemp = new HashSet<BasicBlock>(block.getPreds());
setTemp.removeAll(ent.getValue()); setTemp.removeAll(ent.getValue());
if (!setTemp.isEmpty()) { if (!setTemp.isEmpty()) {

@ -65,7 +65,7 @@ public class AnnotationExprent extends Exprent {
String indstr1 = InterpreterUtil.getIndentString(indent + 1); String indstr1 = InterpreterUtil.getIndentString(indent + 1);
for (int i = 0; i < parnames.size(); i++) { for (int i = 0; i < parnames.size(); i++) {
buffer.append(new_line_separator + indstr1); buffer.append(new_line_separator).append(indstr1);
buffer.append(parnames.get(i)); buffer.append(parnames.get(i));
buffer.append(" = "); buffer.append(" = ");
buffer.append(parvalues.get(i).toJava(indent + 2)); buffer.append(parvalues.get(i).toJava(indent + 2));
@ -74,7 +74,7 @@ public class AnnotationExprent extends Exprent {
buffer.append(","); buffer.append(",");
} }
} }
buffer.append(new_line_separator + indstr); buffer.append(new_line_separator).append(indstr);
} }
buffer.append(")"); buffer.append(")");

@ -116,7 +116,7 @@ public class ConstExprent extends Exprent {
else { else {
switch (consttype.type) { switch (consttype.type) {
case CodeConstants.TYPE_BOOLEAN: case CodeConstants.TYPE_BOOLEAN:
return new Boolean(((Integer)value).intValue() != 0).toString(); return Boolean.toString(((Integer)value).intValue() != 0);
case CodeConstants.TYPE_CHAR: case CodeConstants.TYPE_CHAR:
Integer val = (Integer)value; Integer val = (Integer)value;
String ret = escapes.get(val); String ret = escapes.get(val);
@ -267,7 +267,7 @@ public class ConstExprent extends Exprent {
throw new RuntimeException("invalid constant type"); throw new RuntimeException("invalid constant type");
} }
private String convertStringToJava(String value, boolean ascii) { private static String convertStringToJava(String value, boolean ascii) {
char[] arr = value.toCharArray(); char[] arr = value.toCharArray();
StringBuilder buffer = new StringBuilder(arr.length); StringBuilder buffer = new StringBuilder(arr.length);

@ -94,7 +94,7 @@ public class FieldExprent extends Exprent {
} }
public String toJava(int indent) { public String toJava(int indent) {
StringBuffer buf = new StringBuffer(); StringBuilder buf = new StringBuilder();
if (isStatic) { if (isStatic) {

@ -568,7 +568,7 @@ public class FunctionExprent extends Exprent {
return res; return res;
} }
private VarType getMaxVarType(VarType[] arr) { private static VarType getMaxVarType(VarType[] arr) {
int[] types = new int[]{CodeConstants.TYPE_DOUBLE, CodeConstants.TYPE_FLOAT, CodeConstants.TYPE_LONG}; int[] types = new int[]{CodeConstants.TYPE_DOUBLE, CodeConstants.TYPE_FLOAT, CodeConstants.TYPE_LONG};
VarType[] vartypes = new VarType[]{VarType.VARTYPE_DOUBLE, VarType.VARTYPE_FLOAT, VarType.VARTYPE_LONG}; VarType[] vartypes = new VarType[]{VarType.VARTYPE_DOUBLE, VarType.VARTYPE_FLOAT, VarType.VARTYPE_LONG};

@ -112,11 +112,7 @@ public class IfExprent extends Exprent {
} }
public String toJava(int indent) { public String toJava(int indent) {
StringBuffer buf = new StringBuffer("if("); return "if(" + condition.toJava(indent) + ")";
buf.append(condition.toJava(indent));
buf.append(")");
return buf.toString();
} }
public boolean equals(Object o) { public boolean equals(Object o) {

@ -277,15 +277,15 @@ public class InvocationExprent extends Exprent {
VarType leftType = new VarType(CodeConstants.TYPE_OBJECT, 0, classname); VarType leftType = new VarType(CodeConstants.TYPE_OBJECT, 0, classname);
if (rightType.equals(VarType.VARTYPE_OBJECT) && !leftType.equals(rightType)) { if (rightType.equals(VarType.VARTYPE_OBJECT) && !leftType.equals(rightType)) {
buf.append("((" + ExprProcessor.getCastTypeName(leftType) + ")"); buf.append("((").append(ExprProcessor.getCastTypeName(leftType)).append(")");
if (instance.getPrecedence() >= FunctionExprent.getPrecedence(FunctionExprent.FUNCTION_CAST)) { if (instance.getPrecedence() >= FunctionExprent.getPrecedence(FunctionExprent.FUNCTION_CAST)) {
res = "(" + res + ")"; res = "(" + res + ")";
} }
buf.append(res + ")"); buf.append(res).append(")");
} }
else if (instance.getPrecedence() > getPrecedence()) { else if (instance.getPrecedence() > getPrecedence()) {
buf.append("(" + res + ")"); buf.append("(").append(res).append(")");
} }
else { else {
buf.append(res); buf.append(res);

@ -402,7 +402,7 @@ public class NewExprent extends Exprent {
return buf.toString(); return buf.toString();
} }
private String getQualifiedNewInstance(String classname, List<Exprent> lstParams, int indent) { private static String getQualifiedNewInstance(String classname, List<Exprent> lstParams, int indent) {
ClassNode node = DecompilerContext.getClassprocessor().getMapRootClasses().get(classname); ClassNode node = DecompilerContext.getClassprocessor().getMapRootClasses().get(classname);

@ -115,7 +115,7 @@ public class VarExprent extends Exprent {
if (processor != null && processor.getVarFinal(new VarVersionPaar(index, version)) == VarTypeProcessor.VAR_FINALEXPLICIT) { if (processor != null && processor.getVarFinal(new VarVersionPaar(index, version)) == VarTypeProcessor.VAR_FINALEXPLICIT) {
buf.append("final "); buf.append("final ");
} }
buf.append(ExprProcessor.getCastTypeName(getVartype()) + " "); buf.append(ExprProcessor.getCastTypeName(getVartype())).append(" ");
} }
buf.append(name == null ? ("var" + index + (version == 0 ? "" : "_" + version)) : name); buf.append(name == null ? ("var" + index + (version == 0 ? "" : "_" + version)) : name);

@ -53,7 +53,7 @@ public class DirectGraph {
} }
} }
private void addToReversePostOrderListIterative(DirectNode root, List<DirectNode> lst) { private static void addToReversePostOrderListIterative(DirectNode root, List<DirectNode> lst) {
LinkedList<DirectNode> stackNode = new LinkedList<DirectNode>(); LinkedList<DirectNode> stackNode = new LinkedList<DirectNode>();
LinkedList<Integer> stackIndex = new LinkedList<Integer>(); LinkedList<Integer> stackIndex = new LinkedList<Integer>();

@ -26,20 +26,19 @@ import java.util.Map.Entry;
public class FlattenStatementsHelper { public class FlattenStatementsHelper {
// statement.id, node.id(direct), node.id(continue) // statement.id, node.id(direct), node.id(continue)
private HashMap<Integer, String[]> mapDestinationNodes = new HashMap<Integer, String[]>(); private Map<Integer, String[]> mapDestinationNodes = new HashMap<Integer, String[]>();
// node.id(source), statement.id(destination), edge type // node.id(source), statement.id(destination), edge type
private List<Edge> listEdges = new ArrayList<Edge>(); private List<Edge> listEdges = new ArrayList<Edge>();
// node.id(exit), [node.id(source), statement.id(destination)] // node.id(exit), [node.id(source), statement.id(destination)]
public HashMap<String, List<String[]>> mapShortRangeFinallyPathIds = new HashMap<String, List<String[]>>(); private Map<String, List<String[]>> mapShortRangeFinallyPathIds = new HashMap<String, List<String[]>>();
// node.id(exit), [node.id(source), statement.id(destination)] // node.id(exit), [node.id(source), statement.id(destination)]
public HashMap<String, List<String[]>> mapLongRangeFinallyPathIds = new HashMap<String, List<String[]>>(); private Map<String, List<String[]>> mapLongRangeFinallyPathIds = new HashMap<String, List<String[]>>();
// positive if branches // positive if branches
public HashMap<String, String> mapPosIfBranch = new HashMap<String, String>(); private Map<String, Integer> mapPosIfBranch = new HashMap<String, Integer>();
private DirectGraph graph; private DirectGraph graph;
@ -99,7 +98,7 @@ public class FlattenStatementsHelper {
LinkedList<StackEntry> stackFinally = statEntry.stackFinally; LinkedList<StackEntry> stackFinally = statEntry.stackFinally;
int statementBreakIndex = statEntry.statementIndex; int statementBreakIndex = statEntry.statementIndex;
DirectNode node = null, nd = null; DirectNode node, nd;
List<StatEdge> lstSuccEdges = new ArrayList<StatEdge>(); List<StatEdge> lstSuccEdges = new ArrayList<StatEdge>();
DirectNode sourcenode = null; DirectNode sourcenode = null;
@ -133,7 +132,7 @@ public class FlattenStatementsHelper {
// 'if' statement: record positive branch // 'if' statement: record positive branch
if (stat.getLastBasicType() == Statement.LASTBASICTYPE_IF) { if (stat.getLastBasicType() == Statement.LASTBASICTYPE_IF) {
mapPosIfBranch.put(sourcenode.id, lstSuccEdges.get(0).getDestination().id.toString()); mapPosIfBranch.put(sourcenode.id, lstSuccEdges.get(0).getDestination().id);
} }
break; break;
@ -485,7 +484,7 @@ public class FlattenStatementsHelper {
} }
} }
public HashMap<Integer, String[]> getMapDestinationNodes() { public Map<Integer, String[]> getMapDestinationNodes() {
return mapDestinationNodes; return mapDestinationNodes;
} }

@ -416,7 +416,7 @@ public class SSAConstructorSparseEx {
return mapNew; return mapNew;
} }
private SFormsFastMapDirect mergeMaps(SFormsFastMapDirect mapTo, SFormsFastMapDirect map2) { private static SFormsFastMapDirect mergeMaps(SFormsFastMapDirect mapTo, SFormsFastMapDirect map2) {
if (map2 != null && !map2.isEmpty()) { if (map2 != null && !map2.isEmpty()) {
mapTo.union(map2); mapTo.union(map2);
@ -425,7 +425,7 @@ public class SSAConstructorSparseEx {
return mapTo; return mapTo;
} }
private boolean mapsEqual(SFormsFastMapDirect map1, SFormsFastMapDirect map2) { private static boolean mapsEqual(SFormsFastMapDirect map1, SFormsFastMapDirect map2) {
if (map1 == null) { if (map1 == null) {
return map2 == null; return map2 == null;

@ -683,7 +683,7 @@ public class SSAUConstructorSparseEx {
return mapNew; return mapNew;
} }
private SFormsFastMapDirect mergeMaps(SFormsFastMapDirect mapTo, SFormsFastMapDirect map2) { private static SFormsFastMapDirect mergeMaps(SFormsFastMapDirect mapTo, SFormsFastMapDirect map2) {
if (map2 != null && !map2.isEmpty()) { if (map2 != null && !map2.isEmpty()) {
mapTo.union(map2); mapTo.union(map2);
@ -692,7 +692,7 @@ public class SSAUConstructorSparseEx {
return mapTo; return mapTo;
} }
private boolean mapsEqual(SFormsFastMapDirect map1, SFormsFastMapDirect map2) { private static boolean mapsEqual(SFormsFastMapDirect map1, SFormsFastMapDirect map2) {
if (map1 == null) { if (map1 == null) {
return map2 == null; return map2 == null;
@ -789,7 +789,7 @@ public class SSAUConstructorSparseEx {
return map; return map;
} }
private Integer getFirstProtectedRange(Statement stat) { private static Integer getFirstProtectedRange(Statement stat) {
while (true) { while (true) {
Statement parent = stat.getParent(); Statement parent = stat.getParent();

@ -116,13 +116,13 @@ public class CatchAllStatement extends Statement {
String new_line_separator = DecompilerContext.getNewLineSeparator(); String new_line_separator = DecompilerContext.getNewLineSeparator();
StringBuffer buf = new StringBuffer(); StringBuilder buf = new StringBuilder();
buf.append(ExprProcessor.listToJava(varDefinitions, indent)); buf.append(ExprProcessor.listToJava(varDefinitions, indent));
boolean labeled = isLabeled(); boolean labeled = isLabeled();
if (labeled) { if (labeled) {
buf.append(indstr + "label" + this.id + ":" + new_line_separator); buf.append(indstr).append("label").append(this.id).append(":").append(new_line_separator);
} }
List<StatEdge> lstSuccs = first.getSuccessorEdges(STATEDGE_DIRECT_ALL); List<StatEdge> lstSuccs = first.getSuccessorEdges(STATEDGE_DIRECT_ALL);
@ -134,26 +134,26 @@ public class CatchAllStatement extends Statement {
buf.append(content); buf.append(content);
} }
else { else {
buf.append(indstr + "try {" + new_line_separator); buf.append(indstr).append("try {").append(new_line_separator);
buf.append(ExprProcessor.jmpWrapper(first, indent + 1, true)); buf.append(ExprProcessor.jmpWrapper(first, indent + 1, true));
buf.append(indstr + "}"); buf.append(indstr).append("}");
} }
buf.append((isFinally ? " finally" : buf.append(isFinally ? " finally" :
" catch (" + vars.get(0).toJava(indent) + ")") + " {" + new_line_separator); " catch (" + vars.get(0).toJava(indent) + ")").append(" {").append(new_line_separator);
if (monitor != null) { if (monitor != null) {
indstr1 = InterpreterUtil.getIndentString(indent + 1); indstr1 = InterpreterUtil.getIndentString(indent + 1);
buf.append(indstr1 + "if(" + monitor.toJava(indent) + ") {" + new_line_separator); buf.append(indstr1).append("if(").append(monitor.toJava(indent)).append(") {").append(new_line_separator);
} }
buf.append(ExprProcessor.jmpWrapper(handler, indent + 1 + (monitor != null ? 1 : 0), true)); buf.append(ExprProcessor.jmpWrapper(handler, indent + 1 + (monitor != null ? 1 : 0), true));
if (monitor != null) { if (monitor != null) {
buf.append(indstr1 + "}" + new_line_separator); buf.append(indstr1).append("}").append(new_line_separator);
} }
buf.append(indstr + "}" + new_line_separator); buf.append(indstr).append("}").append(new_line_separator);
return buf.toString(); return buf.toString();
} }

@ -151,19 +151,19 @@ public class CatchStatement extends Statement {
public String toJava(int indent) { public String toJava(int indent) {
String indstr = InterpreterUtil.getIndentString(indent); String indstr = InterpreterUtil.getIndentString(indent);
StringBuffer buf = new StringBuffer(); StringBuilder buf = new StringBuilder();
String new_line_separator = DecompilerContext.getNewLineSeparator(); String new_line_separator = DecompilerContext.getNewLineSeparator();
buf.append(ExprProcessor.listToJava(varDefinitions, indent)); buf.append(ExprProcessor.listToJava(varDefinitions, indent));
if (isLabeled()) { if (isLabeled()) {
buf.append(indstr + "label" + this.id + ":" + new_line_separator); buf.append(indstr).append("label").append(this.id).append(":").append(new_line_separator);
} }
buf.append(indstr + "try {" + new_line_separator); buf.append(indstr).append("try {").append(new_line_separator);
buf.append(ExprProcessor.jmpWrapper(first, indent + 1, true)); buf.append(ExprProcessor.jmpWrapper(first, indent + 1, true));
buf.append(indstr + "}"); buf.append(indstr).append("}");
for (int i = 1; i < stats.size(); i++) { for (int i = 1; i < stats.size(); i++) {
List<String> exception_types = exctstrings.get(i - 1); List<String> exception_types = exctstrings.get(i - 1);
@ -174,11 +174,12 @@ public class CatchStatement extends Statement {
VarType exc_type = new VarType(CodeConstants.TYPE_OBJECT, 0, exception_types.get(exc_index)); VarType exc_type = new VarType(CodeConstants.TYPE_OBJECT, 0, exception_types.get(exc_index));
String exc_type_name = ExprProcessor.getCastTypeName(exc_type); String exc_type_name = ExprProcessor.getCastTypeName(exc_type);
buf.append(exc_type_name + " | "); buf.append(exc_type_name).append(" | ");
} }
} }
buf.append(vars.get(i - 1).toJava(indent)); buf.append(vars.get(i - 1).toJava(indent));
buf.append(") {" + new_line_separator + ExprProcessor.jmpWrapper(stats.get(i), indent + 1, true) + indstr + "}"); buf.append(") {").append(new_line_separator).append(ExprProcessor.jmpWrapper(stats.get(i), indent + 1, true)).append(indstr)
.append("}");
} }
buf.append(new_line_separator); buf.append(new_line_separator);

@ -93,37 +93,38 @@ public class DoStatement extends Statement {
public String toJava(int indent) { public String toJava(int indent) {
String indstr = InterpreterUtil.getIndentString(indent); String indstr = InterpreterUtil.getIndentString(indent);
StringBuffer buf = new StringBuffer(); StringBuilder buf = new StringBuilder();
String new_line_separator = DecompilerContext.getNewLineSeparator(); String new_line_separator = DecompilerContext.getNewLineSeparator();
buf.append(ExprProcessor.listToJava(varDefinitions, indent)); buf.append(ExprProcessor.listToJava(varDefinitions, indent));
if (isLabeled()) { if (isLabeled()) {
buf.append(indstr + "label" + this.id + ":" + new_line_separator); buf.append(indstr).append("label").append(this.id).append(":").append(new_line_separator);
} }
switch (looptype) { switch (looptype) {
case LOOP_DO: case LOOP_DO:
buf.append(indstr + "while(true) {" + new_line_separator); buf.append(indstr).append("while(true) {").append(new_line_separator);
buf.append(ExprProcessor.jmpWrapper(first, indent + 1, true)); buf.append(ExprProcessor.jmpWrapper(first, indent + 1, true));
buf.append(indstr + "}" + new_line_separator); buf.append(indstr).append("}").append(new_line_separator);
break; break;
case LOOP_DOWHILE: case LOOP_DOWHILE:
buf.append(indstr + "do {" + new_line_separator); buf.append(indstr).append("do {").append(new_line_separator);
buf.append(ExprProcessor.jmpWrapper(first, indent + 1, true)); buf.append(ExprProcessor.jmpWrapper(first, indent + 1, true));
buf.append(indstr + "} while(" + conditionExprent.get(0).toJava(indent) + ");" + new_line_separator); buf.append(indstr).append("} while(").append(conditionExprent.get(0).toJava(indent)).append(");").append(new_line_separator);
break; break;
case LOOP_WHILE: case LOOP_WHILE:
buf.append(indstr + "while(" + conditionExprent.get(0).toJava(indent) + ") {" + new_line_separator); buf.append(indstr).append("while(").append(conditionExprent.get(0).toJava(indent)).append(") {").append(new_line_separator);
buf.append(ExprProcessor.jmpWrapper(first, indent + 1, true)); buf.append(ExprProcessor.jmpWrapper(first, indent + 1, true));
buf.append(indstr + "}" + new_line_separator); buf.append(indstr).append("}").append(new_line_separator);
break; break;
case LOOP_FOR: case LOOP_FOR:
buf.append(indstr + "for(" + (initExprent.get(0) == null ? "" : initExprent.get(0).toJava(indent)) + buf.append(indstr).append("for(").append(initExprent.get(0) == null ? "" : initExprent.get(0).toJava(indent)).append("; ")
"; " + conditionExprent.get(0).toJava(indent) + "; " + incExprent.get(0).toJava(indent) + ") {" + new_line_separator); .append(conditionExprent.get(0).toJava(indent)).append("; ").append(incExprent.get(0).toJava(indent)).append(") {")
.append(new_line_separator);
buf.append(ExprProcessor.jmpWrapper(first, indent + 1, true)); buf.append(ExprProcessor.jmpWrapper(first, indent + 1, true));
buf.append(indstr + "}" + new_line_separator); buf.append(indstr).append("}").append(new_line_separator);
} }
return buf.toString(); return buf.toString();

@ -55,19 +55,19 @@ public class GeneralStatement extends Statement {
public String toJava(int indent) { public String toJava(int indent) {
String indstr = InterpreterUtil.getIndentString(indent); String indstr = InterpreterUtil.getIndentString(indent);
StringBuffer buf = new StringBuffer(); StringBuilder buf = new StringBuilder();
String new_line_separator = DecompilerContext.getNewLineSeparator(); String new_line_separator = DecompilerContext.getNewLineSeparator();
if (isLabeled()) { if (isLabeled()) {
buf.append(indstr + "label" + this.id + ":" + new_line_separator); buf.append(indstr).append("label").append(this.id).append(":").append(new_line_separator);
} }
buf.append(indstr + "abstract statement {" + new_line_separator); buf.append(indstr).append("abstract statement {").append(new_line_separator);
for (int i = 0; i < stats.size(); i++) { for (int i = 0; i < stats.size(); i++) {
buf.append(stats.get(i).toJava(indent + 1)); buf.append(stats.get(i).toJava(indent + 1));
} }
buf.append(indstr + "}"); buf.append(indstr).append("}");
return buf.toString(); return buf.toString();
} }

@ -201,7 +201,7 @@ public class IfStatement extends Statement {
public String toJava(int indent) { public String toJava(int indent) {
String indstr = InterpreterUtil.getIndentString(indent); String indstr = InterpreterUtil.getIndentString(indent);
StringBuffer buf = new StringBuffer(); StringBuilder buf = new StringBuilder();
String new_line_separator = DecompilerContext.getNewLineSeparator(); String new_line_separator = DecompilerContext.getNewLineSeparator();
@ -209,10 +209,10 @@ public class IfStatement extends Statement {
buf.append(first.toJava(indent)); buf.append(first.toJava(indent));
if (isLabeled()) { if (isLabeled()) {
buf.append(indstr + "label" + this.id + ":" + new_line_separator); buf.append(indstr).append("label").append(this.id).append(":").append(new_line_separator);
} }
buf.append(indstr + headexprent.get(0).toJava(indent) + " {" + new_line_separator); buf.append(indstr).append(headexprent.get(0).toJava(indent)).append(" {").append(new_line_separator);
if (ifstat == null) { if (ifstat == null) {
buf.append(InterpreterUtil.getIndentString(indent + 1)); buf.append(InterpreterUtil.getIndentString(indent + 1));
@ -228,10 +228,10 @@ public class IfStatement extends Statement {
} }
if (ifedge.labeled) { if (ifedge.labeled) {
buf.append(" label" + ifedge.closure.id); buf.append(" label").append(ifedge.closure.id);
} }
} }
buf.append(";" + new_line_separator); buf.append(";").append(new_line_separator);
} }
else { else {
buf.append(ExprProcessor.jmpWrapper(ifstat, indent + 1, true)); buf.append(ExprProcessor.jmpWrapper(ifstat, indent + 1, true));
@ -248,7 +248,7 @@ public class IfStatement extends Statement {
String content = ExprProcessor.jmpWrapper(elsestat, indent, false); String content = ExprProcessor.jmpWrapper(elsestat, indent, false);
content = content.substring(indstr.length()); content = content.substring(indstr.length());
buf.append(indstr + "} else "); buf.append(indstr).append("} else ");
buf.append(content); buf.append(content);
elseif = true; elseif = true;
@ -257,14 +257,14 @@ public class IfStatement extends Statement {
String content = ExprProcessor.jmpWrapper(elsestat, indent + 1, false); String content = ExprProcessor.jmpWrapper(elsestat, indent + 1, false);
if (content.length() > 0) { if (content.length() > 0) {
buf.append(indstr + "} else {" + new_line_separator); buf.append(indstr).append("} else {").append(new_line_separator);
buf.append(content); buf.append(content);
} }
} }
} }
if (!elseif) { if (!elseif) {
buf.append(indstr + "}" + new_line_separator); buf.append(indstr).append("}").append(new_line_separator);
} }
return buf.toString(); return buf.toString();

@ -112,7 +112,7 @@ public class SequenceStatement extends Statement {
if (islabeled) { if (islabeled) {
indstr = InterpreterUtil.getIndentString(indent); indstr = InterpreterUtil.getIndentString(indent);
indent++; indent++;
buf.append(indstr + "label" + this.id + ": {" + new_line_separator); buf.append(indstr).append("label").append(this.id).append(": {").append(new_line_separator);
} }
boolean notempty = false; boolean notempty = false;
@ -132,7 +132,7 @@ public class SequenceStatement extends Statement {
} }
if (islabeled) { if (islabeled) {
buf.append(indstr + "}" + new_line_separator); buf.append(indstr).append("}").append(new_line_separator);
} }
return buf.toString(); return buf.toString();

@ -126,28 +126,21 @@ public class Statement {
isMonitorEnter = false; isMonitorEnter = false;
containsMonitorExit = false; containsMonitorExit = false;
for (Map<Integer, List<StatEdge>> map : new Map[]{mapSuccEdges, mapPredEdges}) { processMap(mapSuccEdges);
map.remove(StatEdge.TYPE_EXCEPTION); processMap(mapPredEdges);
processMap(mapSuccStates);
List<StatEdge> lst = map.get(STATEDGE_DIRECT_ALL); processMap(mapPredStates);
if (lst != null) { }
map.put(STATEDGE_ALL, new ArrayList<StatEdge>(lst));
}
else {
map.remove(STATEDGE_ALL);
}
}
for (Map<Integer, List<Statement>> map : new Map[]{mapSuccStates, mapPredStates}) { private static <T> void processMap(Map<Integer, List<T>> map) {
map.remove(StatEdge.TYPE_EXCEPTION); map.remove(StatEdge.TYPE_EXCEPTION);
List<Statement> lst = map.get(STATEDGE_DIRECT_ALL); List<T> lst = map.get(STATEDGE_DIRECT_ALL);
if (lst != null) { if (lst != null) {
map.put(STATEDGE_ALL, new ArrayList<Statement>(lst)); map.put(STATEDGE_ALL, new ArrayList<T>(lst));
} }
else { else {
map.remove(STATEDGE_ALL); map.remove(STATEDGE_ALL);
}
} }
} }
@ -579,7 +572,7 @@ public class Statement {
// private methods // private methods
// ***************************************************************************** // *****************************************************************************
private void addToReversePostOrderListIterative(Statement root, List<Statement> lst) { private static void addToReversePostOrderListIterative(Statement root, List<Statement> lst) {
LinkedList<Statement> stackNode = new LinkedList<Statement>(); LinkedList<Statement> stackNode = new LinkedList<Statement>();
LinkedList<Integer> stackIndex = new LinkedList<Integer>(); LinkedList<Integer> stackIndex = new LinkedList<Integer>();
@ -622,7 +615,7 @@ public class Statement {
} }
private void addToPostReversePostOrderList(Statement stat, List<Statement> lst, HashSet<Statement> setVisited) { private static void addToPostReversePostOrderList(Statement stat, List<Statement> lst, HashSet<Statement> setVisited) {
if (setVisited.contains(stat)) { // because of not considered exception edges, s. isExitComponent. Should be rewritten, if possible. if (setVisited.contains(stat)) { // because of not considered exception edges, s. isExitComponent. Should be rewritten, if possible.
return; return;

@ -117,10 +117,10 @@ public class SwitchStatement extends Statement {
buf.append(first.toJava(indent)); buf.append(first.toJava(indent));
if (isLabeled()) { if (isLabeled()) {
buf.append(indstr + "label" + this.id + ":" + new_line_separator); buf.append(indstr).append("label").append(this.id).append(":").append(new_line_separator);
} }
buf.append(indstr + headexprent.get(0).toJava(indent) + " {" + new_line_separator); buf.append(indstr).append(headexprent.get(0).toJava(indent)).append(" {").append(new_line_separator);
VarType switch_type = headexprent.get(0).getExprType(); VarType switch_type = headexprent.get(0).getExprType();
@ -132,20 +132,20 @@ public class SwitchStatement extends Statement {
for (int j = 0; j < edges.size(); j++) { for (int j = 0; j < edges.size(); j++) {
if (edges.get(j) == default_edge) { if (edges.get(j) == default_edge) {
buf.append(indstr + "default:" + new_line_separator); buf.append(indstr).append("default:").append(new_line_separator);
} }
else { else {
ConstExprent value = (ConstExprent)values.get(j).copy(); ConstExprent value = (ConstExprent)values.get(j).copy();
value.setConsttype(switch_type); value.setConsttype(switch_type);
buf.append(indstr + "case " + value.toJava(indent) + ":" + new_line_separator); buf.append(indstr).append("case ").append(value.toJava(indent)).append(":").append(new_line_separator);
} }
} }
buf.append(ExprProcessor.jmpWrapper(stat, indent + 1, false)); buf.append(ExprProcessor.jmpWrapper(stat, indent + 1, false));
} }
buf.append(indstr + "}" + new_line_separator); buf.append(indstr).append("}").append(new_line_separator);
return buf.toString(); return buf.toString();
} }

@ -73,17 +73,17 @@ public class SynchronizedStatement extends Statement {
String new_line_separator = DecompilerContext.getNewLineSeparator(); String new_line_separator = DecompilerContext.getNewLineSeparator();
StringBuffer buf = new StringBuffer(); StringBuilder buf = new StringBuilder();
buf.append(ExprProcessor.listToJava(varDefinitions, indent)); buf.append(ExprProcessor.listToJava(varDefinitions, indent));
buf.append(first.toJava(indent)); buf.append(first.toJava(indent));
if (isLabeled()) { if (isLabeled()) {
buf.append(indstr + "label" + this.id + ":" + new_line_separator); buf.append(indstr).append("label").append(this.id).append(":").append(new_line_separator);
} }
buf.append(indstr + headexprent.get(0).toJava(indent) + " {" + new_line_separator); buf.append(indstr).append(headexprent.get(0).toJava(indent)).append(" {").append(new_line_separator);
buf.append(ExprProcessor.jmpWrapper(body, indent + 1, true)); buf.append(ExprProcessor.jmpWrapper(body, indent + 1, true));
buf.append(indstr + "}" + new_line_separator); buf.append(indstr).append("}").append(new_line_separator);
return buf.toString(); return buf.toString();
} }

@ -43,7 +43,7 @@ public class CheckTypesResult {
return lstMinTypeExprents; return lstMinTypeExprents;
} }
public class ExprentTypePair { public static class ExprentTypePair {
public Exprent exprent; public Exprent exprent;
public VarType type; public VarType type;
public VarType desttype; public VarType desttype;

@ -125,10 +125,7 @@ public class VarDefinitionHelper {
VarNamesCollector vc = DecompilerContext.getVarncollector(); VarNamesCollector vc = DecompilerContext.getVarncollector();
Iterator<Entry<Integer, Statement>> it = mapVarDefStatements.entrySet().iterator(); for (Entry<Integer, Statement> en : mapVarDefStatements.entrySet()) {
while (it.hasNext()) {
Entry<Integer, Statement> en = it.next();
Statement stat = en.getValue(); Statement stat = en.getValue();
Integer index = en.getKey(); Integer index = en.getKey();
@ -312,9 +309,7 @@ public class VarDefinitionHelper {
HashSet<Integer> set = new HashSet<Integer>(mapCount.keySet()); HashSet<Integer> set = new HashSet<Integer>(mapCount.keySet());
// put all variables defined in this statement into the set // put all variables defined in this statement into the set
Iterator<Entry<Integer, Integer>> itMult = mapCount.entrySet().iterator(); for (Entry<Integer, Integer> en : mapCount.entrySet()) {
while (itMult.hasNext()) {
Entry<Integer, Integer> en = itMult.next();
if (en.getValue().intValue() > 1) { if (en.getValue().intValue() > 1) {
mapVarDefStatements.put(en.getKey(), stat); mapVarDefStatements.put(en.getKey(), stat);
} }
@ -325,7 +320,7 @@ public class VarDefinitionHelper {
return set; return set;
} }
private List<VarExprent> getAllVars(List<Exprent> lst) { private static List<VarExprent> getAllVars(List<Exprent> lst) {
List<VarExprent> res = new ArrayList<VarExprent>(); List<VarExprent> res = new ArrayList<VarExprent>();
List<Exprent> listTemp = new ArrayList<Exprent>(); List<Exprent> listTemp = new ArrayList<Exprent>();
@ -344,7 +339,7 @@ public class VarDefinitionHelper {
return res; return res;
} }
private boolean setDefinition(Exprent expr, Integer index) { private static boolean setDefinition(Exprent expr, Integer index) {
if (expr.type == Exprent.EXPRENT_ASSIGNMENT) { if (expr.type == Exprent.EXPRENT_ASSIGNMENT) {
Exprent left = ((AssignmentExprent)expr).getLeft(); Exprent left = ((AssignmentExprent)expr).getLeft();
if (left.type == Exprent.EXPRENT_VAR) { if (left.type == Exprent.EXPRENT_VAR) {

@ -102,7 +102,7 @@ public class VarTypeProcessor {
while (!processVarTypes(dgraph)) ; while (!processVarTypes(dgraph)) ;
} }
private void resetExprentTypes(DirectGraph dgraph) { private static void resetExprentTypes(DirectGraph dgraph) {
dgraph.iterateExprents(new DirectGraph.ExprentIterator() { dgraph.iterateExprents(new DirectGraph.ExprentIterator() {
public int processExprent(Exprent exprent) { public int processExprent(Exprent exprent) {

@ -106,7 +106,7 @@ public class VarVersionsGraph {
engine.initialize(); engine.initialize();
} }
private LinkedList<VarVersionNode> getReversedPostOrder(Collection<VarVersionNode> roots) { private static LinkedList<VarVersionNode> getReversedPostOrder(Collection<VarVersionNode> roots) {
LinkedList<VarVersionNode> lst = new LinkedList<VarVersionNode>(); LinkedList<VarVersionNode> lst = new LinkedList<VarVersionNode>();
HashSet<VarVersionNode> setVisited = new HashSet<VarVersionNode>(); HashSet<VarVersionNode> setVisited = new HashSet<VarVersionNode>();
@ -122,7 +122,7 @@ public class VarVersionsGraph {
return lst; return lst;
} }
private void addToReversePostOrderListIterative(VarVersionNode root, List<VarVersionNode> lst, HashSet<VarVersionNode> setVisited) { private static void addToReversePostOrderListIterative(VarVersionNode root, List<VarVersionNode> lst, HashSet<VarVersionNode> setVisited) {
HashMap<VarVersionNode, List<VarVersionEdge>> mapNodeSuccs = new HashMap<VarVersionNode, List<VarVersionEdge>>(); HashMap<VarVersionNode, List<VarVersionEdge>> mapNodeSuccs = new HashMap<VarVersionNode, List<VarVersionEdge>>();

@ -66,7 +66,7 @@ public class VarVersionsProcessor {
setNewVarIndices(typeproc, dgraph); setNewVarIndices(typeproc, dgraph);
} }
private void mergePhiVersions(SSAConstructorSparseEx ssa, DirectGraph dgraph) { private static void mergePhiVersions(SSAConstructorSparseEx ssa, DirectGraph dgraph) {
// collect phi versions // collect phi versions
List<HashSet<VarVersionPaar>> lst = new ArrayList<HashSet<VarVersionPaar>>(); List<HashSet<VarVersionPaar>> lst = new ArrayList<HashSet<VarVersionPaar>>();
@ -125,7 +125,7 @@ public class VarVersionsProcessor {
}); });
} }
private void eliminateNonJavaTypes(VarTypeProcessor typeproc) { private static void eliminateNonJavaTypes(VarTypeProcessor typeproc) {
HashMap<VarVersionPaar, VarType> mapExprentMaxTypes = typeproc.getMapExprentMaxTypes(); HashMap<VarVersionPaar, VarType> mapExprentMaxTypes = typeproc.getMapExprentMaxTypes();
HashMap<VarVersionPaar, VarType> mapExprentMinTypes = typeproc.getMapExprentMinTypes(); HashMap<VarVersionPaar, VarType> mapExprentMinTypes = typeproc.getMapExprentMinTypes();
@ -152,7 +152,7 @@ public class VarVersionsProcessor {
} }
} }
private void simpleMerge(VarTypeProcessor typeproc, DirectGraph dgraph, StructMethod mt) { private static void simpleMerge(VarTypeProcessor typeproc, DirectGraph dgraph, StructMethod mt) {
HashMap<VarVersionPaar, VarType> mapExprentMaxTypes = typeproc.getMapExprentMaxTypes(); HashMap<VarVersionPaar, VarType> mapExprentMaxTypes = typeproc.getMapExprentMaxTypes();
HashMap<VarVersionPaar, VarType> mapExprentMinTypes = typeproc.getMapExprentMinTypes(); HashMap<VarVersionPaar, VarType> mapExprentMinTypes = typeproc.getMapExprentMinTypes();

@ -193,11 +193,12 @@ public class IdentifierConverter {
} }
String classOldFullName = cl.qualifiedName; String classOldFullName = cl.qualifiedName;
String classNewFullName = classOldFullName;
// TODO: rename packages // TODO: rename packages
String clsimplename = ConverterHelper.getSimpleClassName(classOldFullName); String clsimplename = ConverterHelper.getSimpleClassName(classOldFullName);
if (helper.toBeRenamed(IIdentifierRenamer.ELEMENT_CLASS, clsimplename, null, null)) { if (helper.toBeRenamed(IIdentifierRenamer.ELEMENT_CLASS, clsimplename, null, null)) {
String classNewFullName;
do { do {
classNewFullName = ConverterHelper.replaceSimpleClassName(classOldFullName, classNewFullName = ConverterHelper.replaceSimpleClassName(classOldFullName,
helper.getNextClassname(classOldFullName, ConverterHelper helper.getNextClassname(classOldFullName, ConverterHelper
@ -339,7 +340,7 @@ public class IdentifierConverter {
return descriptor; return descriptor;
} }
private List<ClassWrapperNode> getReversePostOrderListIterative(List<ClassWrapperNode> roots) { private static List<ClassWrapperNode> getReversePostOrderListIterative(List<ClassWrapperNode> roots) {
List<ClassWrapperNode> res = new ArrayList<ClassWrapperNode>(); List<ClassWrapperNode> res = new ArrayList<ClassWrapperNode>();

@ -216,8 +216,11 @@ public class StructMethod implements CodeConstants {
} }
} }
private void readAttribute(DataInputFullStream in, ConstantPool pool, VBStyleCollection<StructGeneralAttribute, String> lstAttribute, private static void readAttribute(DataInputFullStream in,
int attr_nameindex, String attrname) throws IOException { ConstantPool pool,
VBStyleCollection<StructGeneralAttribute, String> lstAttribute,
int attr_nameindex,
String attrname) throws IOException {
StructGeneralAttribute attribute = StructGeneralAttribute.getMatchingAttributeInstance(attr_nameindex, attrname); StructGeneralAttribute attribute = StructGeneralAttribute.getMatchingAttributeInstance(attr_nameindex, attrname);

@ -252,7 +252,7 @@ public class ConstantPool {
buffer.append("["); buffer.append("[");
} }
buffer.append("L" + newname + ";"); buffer.append("L").append(newname).append(";");
} }
else { else {
buffer.append(newname); buffer.append(newname);

@ -306,7 +306,7 @@ public class VarType { // TODO: optimize switch
} }
} }
private int getType(char c) { private static int getType(char c) {
switch (c) { switch (c) {
case 'B': case 'B':
return CodeConstants.TYPE_BYTE; return CodeConstants.TYPE_BYTE;
@ -343,7 +343,7 @@ public class VarType { // TODO: optimize switch
} }
} }
private String getChar(int type) { private static String getChar(int type) {
switch (type) { switch (type) {
case CodeConstants.TYPE_BYTE: case CodeConstants.TYPE_BYTE:
return "B"; return "B";

@ -221,7 +221,7 @@ public class GenericMain {
String res = name.replace('/', '.'); String res = name.replace('/', '.');
if (res.indexOf("$") >= 0) { if (res.contains("$")) {
StructClass cl = DecompilerContext.getStructcontext().getClass(name); StructClass cl = DecompilerContext.getStructcontext().getClass(name);
if (cl == null || !cl.isOwn()) { if (cl == null || !cl.isOwn()) {
res = res.replace('$', '.'); res = res.replace('$', '.');

@ -105,7 +105,7 @@ public class GenericType {
} }
} }
private String getNextClassSignature(String value) { private static String getNextClassSignature(String value) {
int counter = 0; int counter = 0;
int index = 0; int index = 0;
@ -131,7 +131,7 @@ public class GenericType {
return value.substring(0, index); return value.substring(0, index);
} }
private void parseArgumentsList(String value, GenericType type) { private static void parseArgumentsList(String value, GenericType type) {
if (value == null) { if (value == null) {
return; return;
@ -214,7 +214,7 @@ public class GenericType {
return value.substring(0, index + 1); return value.substring(0, index + 1);
} }
private int getType(char c) { private static int getType(char c) {
switch (c) { switch (c) {
case 'B': case 'B':
return CodeConstants.TYPE_BYTE; return CodeConstants.TYPE_BYTE;

@ -158,7 +158,7 @@ public class LazyLoader {
return link == null ? null : getClassStream(link.externPath, link.internPath); return link == null ? null : getClassStream(link.externPath, link.internPath);
} }
private void skipAttributes(DataInputFullStream in) throws IOException { private static void skipAttributes(DataInputFullStream in) throws IOException {
int length = in.readUnsignedShort(); int length = in.readUnsignedShort();
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {

@ -253,7 +253,7 @@ public class FastSparseSetFactory<E> {
} }
} }
private void changeNext(int[] arrnext, int key, int oldnext, int newnext) { private static void changeNext(int[] arrnext, int key, int oldnext, int newnext) {
for (int i = key - 1; i >= 0; i--) { for (int i = key - 1; i >= 0; i--) {
if (arrnext[i] == oldnext) { if (arrnext[i] == oldnext) {
arrnext[i] = newnext; arrnext[i] = newnext;

@ -83,9 +83,8 @@ public class InterpreterUtil {
return false; return false;
} }
HashSet<?> set = new HashSet(c1); HashSet<Object> set = new HashSet<Object>(c1);
set.removeAll(c2); set.removeAll(c2);
return (set.size() == 0); return (set.size() == 0);
} }

@ -27,7 +27,7 @@ public class SFormsFastMapDirect {
private int size; private int size;
private FastSparseSet<Integer>[][] elements = new FastSparseSet[3][]; @SuppressWarnings("unchecked") private FastSparseSet<Integer>[][] elements = new FastSparseSet[3][];
private int[][] next = new int[3][]; private int[][] next = new int[3][];
@ -38,7 +38,8 @@ public class SFormsFastMapDirect {
private SFormsFastMapDirect(boolean initialize) { private SFormsFastMapDirect(boolean initialize) {
if (initialize) { if (initialize) {
for (int i = 2; i >= 0; i--) { for (int i = 2; i >= 0; i--) {
elements[i] = new FastSparseSet[0]; @SuppressWarnings("unchecked") FastSparseSet<Integer>[] empty = new FastSparseSet[0];
elements[i] = empty;
next[i] = new int[0]; next[i] = new int[0];
} }
} }
@ -50,7 +51,7 @@ public class SFormsFastMapDirect {
int[] arrnext = map.next[i]; int[] arrnext = map.next[i];
int length = arr.length; int length = arr.length;
FastSparseSet<Integer>[] arrnew = new FastSparseSet[length]; @SuppressWarnings("unchecked") FastSparseSet<Integer>[] arrnew = new FastSparseSet[length];
int[] arrnextnew = new int[length]; int[] arrnextnew = new int[length];
System.arraycopy(arr, 0, arrnew, 0, length); System.arraycopy(arr, 0, arrnew, 0, length);
@ -78,7 +79,7 @@ public class SFormsFastMapDirect {
if (length > 0) { if (length > 0) {
int[] arrnext = next[i]; int[] arrnext = next[i];
FastSparseSet<Integer>[] arrnew = new FastSparseSet[length]; @SuppressWarnings("unchecked") FastSparseSet<Integer>[] arrnew = new FastSparseSet[length];
int[] arrnextnew = new int[length]; int[] arrnextnew = new int[length];
System.arraycopy(arrnext, 0, arrnextnew, 0, length); System.arraycopy(arrnext, 0, arrnextnew, 0, length);
@ -174,7 +175,7 @@ public class SFormsFastMapDirect {
} }
} }
private void changeNext(int[] arrnext, int key, int oldnext, int newnext) { private static void changeNext(int[] arrnext, int key, int oldnext, int newnext) {
for (int i = key - 1; i >= 0; i--) { for (int i = key - 1; i >= 0; i--) {
if (arrnext[i] == oldnext) { if (arrnext[i] == oldnext) {
arrnext[i] = newnext; arrnext[i] = newnext;
@ -343,7 +344,7 @@ public class SFormsFastMapDirect {
} }
Set<Integer> set = entry.getValue().toPlainSet(); Set<Integer> set = entry.getValue().toPlainSet();
buffer.append(entry.getKey() + "={" + set.toString() + "}"); buffer.append(entry.getKey()).append("={").append(set.toString()).append("}");
} }
} }
@ -399,7 +400,7 @@ public class SFormsFastMapDirect {
} }
} }
FastSparseSet<Integer>[] arrnew = new FastSparseSet[minsize]; @SuppressWarnings("unchecked") FastSparseSet<Integer>[] arrnew = new FastSparseSet[minsize];
System.arraycopy(arr, 0, arrnew, 0, arr.length); System.arraycopy(arr, 0, arrnew, 0, arr.length);
int[] arrnextnew = new int[minsize]; int[] arrnextnew = new int[minsize];

@ -115,7 +115,7 @@ public class VBStyleCollection<E, K> extends ArrayList<E> {
public E remove(int index) { public E remove(int index) {
addToListIndex(index + 1, -1); addToListIndex(index + 1, -1);
Object obj = lstKeys.get(index); K obj = lstKeys.get(index);
if (obj != null) { if (obj != null) {
map.remove(obj); map.remove(obj);
} }

Loading…
Cancel
Save