OSDN Git Service

opcodesをcflibに変更した.コントロールフローを扱うことと,ライブラリであることを明示したかったため.
[stigmata/stigmata-plugins.git] / cflib / src / main / java / jp / sourceforge / stigmata / birthmarks / Opcode.java
1 package jp.sourceforge.stigmata.birthmarks;
2
3 import java.io.Serializable;
4 import java.util.ArrayList;
5 import java.util.Collections;
6 import java.util.Iterator;
7 import java.util.List;
8
9 import org.objectweb.asm.Label;
10
11 /**
12  *
13  * @author Haruaki Tamada
14  */
15 public class Opcode implements Serializable, Iterable<Label>{
16     private static final long serialVersionUID = -2349834745416345564L;
17
18     public static enum Category{
19         NORMAL, BRANCH, OBJECT, INVOKE, TARGETER,
20     };
21     private int opcode;
22     private String name;
23     private int argumentCount;
24     private int act;
25     private Category category;
26     private List<Label> labels = new ArrayList<Label>();
27
28     public Opcode(Opcode opcode){
29         this(opcode.getOpcode(), opcode.getName(), opcode.getArgumentCount(), opcode.getAct(), opcode.getCategory());
30     }
31
32     public Opcode(int opcode, String name, int argumentCount, int act, String category){
33         this(opcode, name, argumentCount, act, Category.valueOf(category));
34     }
35
36     public Opcode(int opcode, String name, int argumentCount, int act, Category category){
37         this.opcode = opcode;
38         this.name = name;
39         this.argumentCount = argumentCount;
40         this.act = act;
41         this.category = category;
42     }
43
44     public final int getOpcode(){
45         return opcode;
46     }
47
48     public final String getName(){
49         return name;
50     }
51
52     public int getArgumentCount(){
53         return argumentCount;
54     }
55
56     public void addLabel(Label label){
57         if(label == null){
58             throw new NullPointerException();
59         }
60         if(!(category == Category.TARGETER && labels.size() == 0) 
61                 && category != Category.BRANCH){
62             throw new IllegalStateException("this method allows only branch category");
63         }
64         labels.add(label);
65     }
66
67     public void setLabels(Label[] labelArray){
68         if(labelArray == null){
69             throw new NullPointerException();
70         }
71         if(category != Category.BRANCH){
72             throw new IllegalStateException("this method allows only branch category");
73         }
74         labels.clear();
75         for(Label label: labelArray){
76             if(label == null){
77                 throw new NullPointerException();
78             }
79             labels.add(label);
80         }
81     }
82
83     public boolean hasLabel(Label label){
84         return labels.contains(label);
85     }
86
87     public Label getLabel(int index){
88         return labels.get(index);
89     }
90
91     public synchronized Label[] getLabels(){
92         return labels.toArray(new Label[labels.size()]);
93     }
94
95     public Iterator<Label> iterator(){
96         return Collections.unmodifiableList(labels).iterator();
97     }
98
99     public void setAct(int act){
100         if(category != Category.OBJECT && category != Category.INVOKE){
101             throw new IllegalStateException("setAct can be called only object and invoke category.");
102         }
103         this.act = act;
104     }
105
106     public int getAct(){
107         return act;
108     }
109
110     public Category getCategory(){
111         return category;
112     }
113
114     public String toString(){
115         StringBuilder sb = new StringBuilder();
116         sb.append(String.format("%d:%s:%d(%s)", getOpcode(), getName(), getAct(), getCategory()));
117
118         if(getCategory() == Category.BRANCH || getCategory() == Category.TARGETER){
119             sb.append(labels);
120         }
121
122         return new String(sb);
123     }
124 }