package sds.assemble.controlflow;

import sds.classfile.bytecode.BranchOpcode;
import sds.classfile.bytecode.OpcodeInfo;
import sds.classfile.bytecode.SwitchOpcode;

/**
 * This enum class is for type of
 * {@link CFNode <code>CFNode</code>}.
 * @author inagaki
 */
public enum CFNodeType {
	Normal,
	Entry,
	Exit,
	LoopEntry,
	LoopExit,
	TryEntry,
	TryExit,
	Catch,
	Finally;

	/**
	 * returns type of control flow node.
	 * @param op opcodes
	 * @return node type
	 */
	public static CFNodeType getType(OpcodeInfo op) {
		if(op instanceof BranchOpcode) {
			BranchOpcode branch = (BranchOpcode)op;
			switch(branch.getOpcodeType()) {
				case jsr:
				case jsr_w:
					// todo
					break;
				case _goto:
				case goto_w:
					if(branch.getBranch() > 0)
						return Exit;
					else
						return LoopExit;
				default:
					return Entry;
			}
		} else if(op instanceof SwitchOpcode) {
			return Entry;
		}
		return Normal;
	}
}
@@ -114,16 +114,55 @@
 deInfo;%0A
+import sds.classfile.bytecode.Opcodes;%0A
 import s
@@ -347,16 +347,25 @@
 %0A%09Exit,%0A
+%09Switch,%0A
 %09LoopEnt
@@ -416,18 +416,25 @@
 %09Finally
+,%0A%09End
 ;%0A
+%09
 %0A%09/**%0A%09 
@@ -553,16 +553,393 @@
 getType(
+Opcodes opcodes, OpcodeInfo end) %7B%0A%09%09CFNodeType type;%0A%09%09if((type = searchType(end)) != Normal) %7B%0A%09%09%09return type;%0A%09%09%7D%0A%09%09%0A%09%09// processing for for-each statement.%0A%09%09int index = 0;%0A%09%09int%5B%5D keys = opcodes.getKeys();%0A%09%09while((index %3C keys.length) && (type = searchType(opcodes.get(keys%5Bindex%5D))) == Normal) %7B%0A%09%09%09index++;%0A%09%09%7D%0A%09%09return type;%0A%09%7D%0A%09%0A%09private static CFNodeType searchType(
 OpcodeIn
@@ -1180,23 +1180,17 @@
 h() %3E 0)
-%0A%09%09%09%09%09%09
+ 
 return E
@@ -1207,15 +1207,31 @@
 else
-%0A%09%09%09%09%09%09
+                       
 retu
@@ -1328,29 +1328,30 @@
 %7B%0A%09%09%09return 
-Entry
+Switch
 ;%0A%09%09%7D%0A%09%09retu
@@ -1357,15 +1357,272 @@
 urn 
-Normal;
+isReturn(op) ? End : Normal;%0A%09%7D%0A%09%0A%09private static boolean isReturn(OpcodeInfo op) %7B%0A%09%09switch(op.getOpcodeType()) %7B%0A%09%09%09case _return:%0A%09%09%09case areturn:%0A%09%09%09case ireturn:%0A%09%09%09case freturn:%0A%09%09%09case lreturn:%0A%09%09%09case dreturn: return true;%0A%09%09%09default:      return false;%0A%09%09%7D
 %0A%09%7D%0A

change to decide node type for searching all opcode of method.