OSDN Git Service

initial version (daily commit), not work yet
[stigmata/stigmata-plugins.git] / wsp / src / main / java / jp / sourceforge / stigmata / birthmarks / wsp / StackPatternBasedBirthmarkExtractor.java
1 package jp.sourceforge.stigmata.birthmarks.wsp;
2
3 /*
4  * $Id$
5  */
6
7 import java.util.ArrayList;
8 import java.util.HashMap;
9 import java.util.Iterator;
10 import java.util.List;
11 import java.util.Map;
12
13 import jp.sourceforge.stigmata.Birthmark;
14 import jp.sourceforge.stigmata.BirthmarkElement;
15 import jp.sourceforge.stigmata.BirthmarkEnvironment;
16 import jp.sourceforge.stigmata.ExtractionUnit;
17 import jp.sourceforge.stigmata.birthmarks.ASMBirthmarkExtractor;
18 import jp.sourceforge.stigmata.birthmarks.BirthmarkExtractVisitor;
19 import jp.sourceforge.stigmata.spi.BirthmarkSpi;
20
21 import org.objectweb.asm.ClassVisitor;
22 import org.objectweb.asm.ClassWriter;
23 import org.objectweb.asm.Label;
24 import org.objectweb.asm.MethodVisitor;
25
26 /**
27  * 
28  * @author Haruaki Tamada
29  * @version $Revision$
30  */
31 public class StackPatternBasedBirthmarkExtractor extends ASMBirthmarkExtractor{
32
33     @Override
34     public BirthmarkExtractVisitor createExtractVisitor(ClassWriter writer, Birthmark birthmark, BirthmarkEnvironment environment){
35         return new Visitor(writer, birthmark, environment);
36     }
37
38     public StackPatternBasedBirthmarkExtractor(BirthmarkSpi service){
39         super(service);
40     }
41
42     @Override
43     public ExtractionUnit[] getAcceptableUnits(){
44         return new ExtractionUnit[] {
45             ExtractionUnit.ARCHIVE, ExtractionUnit.PACKAGE, ExtractionUnit.CLASS,
46         };
47     }
48
49     private BirthmarkElement[] buildElement(List<Opcode> opcodes){
50         List<BirthmarkElement> elements = new ArrayList<BirthmarkElement>();
51         Map<Label, Integer> tableMap = new HashMap<Label, Integer>();
52
53         int currentDepth = 0;
54         for(Opcode opcode: opcodes){
55             Integer forwardedStatus = null;
56             if(opcode.getCategory() != Opcode.Category.TARGETER){
57                 forwardedStatus = tableMap.get(((LabelOpcode)opcode).getLabel());
58             }
59             if(forwardedStatus == null){
60                 currentDepth += opcode.getAct();
61             }
62             else{
63                 currentDepth = forwardedStatus + opcode.getAct(); 
64             }
65             if(opcode.getCategory() == Opcode.Category.BRANCH){
66                 for(Iterator<Label> i = opcode.labels(); i.hasNext(); ){
67                     Label label = i.next();
68                     tableMap.put(label, currentDepth);
69                 }
70             }
71         }
72
73         return elements.toArray(new BirthmarkElement[elements.size()]);
74     }
75
76     private class Visitor extends BirthmarkExtractVisitor{
77         public Visitor(ClassVisitor visitor, Birthmark birthmark, BirthmarkEnvironment environment){
78             super(visitor, birthmark, environment);
79         }
80
81         public void visitEnd(){
82         }
83
84         @Override
85         public MethodVisitor visitMethod(int arg0, String arg1, String arg2, String arg3, String[] arg4){
86             MethodVisitor visitor = super.visitMethod(arg0, arg1, arg2, arg3, arg4);
87             OpcodeExtractionMethodVisitor opcodeVisitor = new OpcodeExtractionMethodVisitor(visitor);
88             opcodeVisitor.addOpcodeExtractionFinishListener(new OpcodeExtractionFinishListener(){
89                 @Override
90                 public void finishExtractionOpcodes(List<Opcode> opcodes){
91                     BirthmarkElement[] elements = buildElement(opcodes);
92
93                     for(BirthmarkElement be: elements){
94                         addElement(be);
95                     }
96                 }
97             });
98
99             return opcodeVisitor;
100         }
101     };
102
103
104 }