package sds.assemble;

import sds.classfile.ConstantPool;
import sds.classfile.MemberInfo;
import sds.classfile.attributes.AttributeInfo;
import sds.classfile.attributes.Code;
import sds.classfile.attributes.Exceptions;
import sds.classfile.attributes.LineNumberTable;
import sds.classfile.attributes.LocalVariableTable;
import sds.classfile.attributes.LocalVariableTypeTable;
import sds.classfile.attributes.MethodParameters;
import sds.classfile.attributes.annotation.AnnotationDefault;
import sds.classfile.attributes.annotation.RuntimeInvisibleAnnotations;
import sds.classfile.attributes.annotation.RuntimeVisibleAnnotations;
import sds.classfile.attributes.annotation.RuntimeInvisibleParameterAnnotations;
import sds.classfile.attributes.annotation.RuntimeVisibleParameterAnnotations;
import sds.classfile.attributes.stackmap.StackMapTable;
import sds.classfile.bytecode.OpcodeInfo;
import sds.classfile.bytecode.Opcodes;
import sds.util.Utf8ValueExtractor;

/**
 * This class is for contents of method.
 * @author inagaki
 */
public class MethodContent extends MemberContent {
	private String args;
	private String[] exceptions;
	private int maxStack;
	private int maxLocals;
	private LineInstructions[] inst;
	private Opcodes opcodes;

	/**
	 * constructor.
	 * @param info method info
	 * @param pool constant-pool
	 */
	public MethodContent(MemberInfo info, ConstantPool pool) {
		super(info, pool);
		for(AttributeInfo attr : info.getAttr().getAll()) {
			investigateAttribute(attr, pool);
		}
	}

	@Override
	public void investigateAttribute(AttributeInfo info, ConstantPool pool) {
		switch(info.getType()) {
			case AnnotationDefault:
				AnnotationDefault ad = (AnnotationDefault)info;
				break;
			case Code:
				Code code = (Code)info;
				this.maxStack  = code.getMaxStack();
				this.maxLocals = code.maxLocals();
				this.opcodes = code.getCode();
//				code.getExceptionTable();
				for(AttributeInfo ai : code.getAttr().getAll()) {
					investigateAttribute(ai, pool);
				}
				break;
			case Exceptions:
				int[] exp = ((Exceptions)info).getExceptionIndexTable();
				this.exceptions = new String[exp.length];
				for(int i = 0; i < exp.length; i++) {
					exceptions[i] = Utf8ValueExtractor.extract(pool.get(exp[i]-1), pool)
									.replace("/", ".");
				}
				break;
			case LineNumberTable:
				LineNumberTable.LNTable[] table = ((LineNumberTable)info).getLineNumberTable();
				this.inst = new LineInstructions[table.length];
				int index = 0;
				for(OpcodeInfo op : opcodes.getAll()) {
					if(op.getPc() != table[index].getEndPc()) {
						inst[index].addOpcode(op);
					} else {
						index++;
					}
				}
				break;
			case LocalVariableTable:
				LocalVariableTable lvt = (LocalVariableTable)info;
				break;
			case LocalVariableTypeTable:
				LocalVariableTypeTable lvtt = (LocalVariableTypeTable)info;
				break;
			case MethodParameters:
				MethodParameters mp = (MethodParameters)info;
				break;
			case RuntimeInvisibleParameterAnnotations:
				RuntimeInvisibleParameterAnnotations ripa
					= (RuntimeInvisibleParameterAnnotations)info;
				break;
			case RuntimeVisibleParameterAnnotations:
				RuntimeVisibleParameterAnnotations rvpa
					= (RuntimeVisibleParameterAnnotations)info;
				break;
			case StackMapTable:
				StackMapTable smt = (StackMapTable)info;
				break;
			default:
				super.investigateAttribute(info, pool);
				break;
		}
	}
}
@@ -16,16 +16,100 @@
 emble;%0A%0A
+import sds.assemble.controlflow.CFGBuilder;%0Aimport sds.assemble.controlflow.CFNode;%0A
 import s
@@ -135,16 +135,16 @@
 ntPool;%0A
-
 import s
@@ -570,150 +570,8 @@
 lt;%0A
-import sds.classfile.attributes.annotation.RuntimeInvisibleAnnotations;%0Aimport sds.classfile.attributes.annotation.RuntimeVisibleAnnotations;%0A
 impo
@@ -1440,16 +1440,172 @@
 l);%0A%09%09%7D%0A
+%09%09CFGBuilder builder = CFGBuilder.getInstance();%0A%09%09CFNode%5B%5D nodes = builder.build(inst);%0A%09%09for(CFNode n : nodes) %7B%0A%09%09%09System.out.println(n.toString());%0A%09%09%7D%0A
 %09%7D%0A%0A%09@Ov
@@ -2546,24 +2546,120 @@
 le.length%5D;%0A
+%09%09%09%09for(int i = 0; i %3C inst.length; i++) %7B%0A%09%09%09%09%09inst%5Bi%5D = new LineInstructions(table%5Bi%5D);%0A%09%09%09%09%7D%0A
 %09%09%09%09int inde
@@ -2805,16 +2805,16 @@
  else %7B%0A
-
 %09%09%09%09%09%09in
@@ -2820,16 +2820,90 @@
 ndex++;%0A
+%09%09%09%09%09%09if(index %3C inst.length) %7B%0A%09%09%09%09%09%09%09inst%5Bindex%5D.addOpcode(op);%0A%09%09%09%09%09%09%7D%0A
 %09%09%09%09%09%7D%0A%09

modify part of processing LineNumberTable attribute.