MultiInstructionVisitor.java revision b9cc48a43ed984587c939d02fba5316bf5c0df6e
1/*
2 * ProGuard -- shrinking, optimization, obfuscation, and preverification
3 *             of Java bytecode.
4 *
5 * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21package proguard.classfile.instruction.visitor;
22
23import proguard.classfile.*;
24import proguard.classfile.attribute.CodeAttribute;
25import proguard.classfile.instruction.*;
26
27
28/**
29 * This InstructionVisitor delegates all visits to each InstructionVisitor
30 * in a given list.
31 *
32 * @author Eric Lafortune
33 */
34public class MultiInstructionVisitor implements InstructionVisitor
35{
36    private static final int ARRAY_SIZE_INCREMENT = 5;
37
38
39    private InstructionVisitor[] instructionVisitors;
40    private int                  instructionVisitorCount;
41
42
43    public MultiInstructionVisitor()
44    {
45    }
46
47
48    public MultiInstructionVisitor(InstructionVisitor[] instructionVisitors)
49    {
50        this.instructionVisitors     = instructionVisitors;
51        this.instructionVisitorCount = instructionVisitors.length;
52    }
53
54
55    public void addInstructionVisitor(InstructionVisitor instructionVisitor)
56    {
57        ensureArraySize();
58
59        instructionVisitors[instructionVisitorCount++] = instructionVisitor;
60    }
61
62
63    private void ensureArraySize()
64    {
65        if (instructionVisitors == null)
66        {
67            instructionVisitors = new InstructionVisitor[ARRAY_SIZE_INCREMENT];
68        }
69        else if (instructionVisitors.length == instructionVisitorCount)
70        {
71            InstructionVisitor[] newInstructionVisitors =
72                new InstructionVisitor[instructionVisitorCount +
73                                     ARRAY_SIZE_INCREMENT];
74            System.arraycopy(instructionVisitors, 0,
75                             newInstructionVisitors, 0,
76                             instructionVisitorCount);
77            instructionVisitors = newInstructionVisitors;
78        }
79    }
80
81
82    // Implementations for InstructionVisitor.
83
84    public void visitSimpleInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SimpleInstruction simpleInstruction)
85    {
86        for (int index = 0; index < instructionVisitorCount; index++)
87        {
88            instructionVisitors[index].visitSimpleInstruction(clazz, method, codeAttribute, offset, simpleInstruction);
89        }
90    }
91
92    public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction)
93    {
94        for (int index = 0; index < instructionVisitorCount; index++)
95        {
96            instructionVisitors[index].visitVariableInstruction(clazz, method, codeAttribute, offset, variableInstruction);
97        }
98    }
99
100    public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
101    {
102        for (int index = 0; index < instructionVisitorCount; index++)
103        {
104            instructionVisitors[index].visitConstantInstruction(clazz, method, codeAttribute, offset, constantInstruction);
105        }
106    }
107
108    public void visitBranchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, BranchInstruction branchInstruction)
109    {
110        for (int index = 0; index < instructionVisitorCount; index++)
111        {
112            instructionVisitors[index].visitBranchInstruction(clazz, method, codeAttribute, offset, branchInstruction);
113        }
114    }
115
116    public void visitTableSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, TableSwitchInstruction tableSwitchInstruction)
117    {
118        for (int index = 0; index < instructionVisitorCount; index++)
119        {
120            instructionVisitors[index].visitTableSwitchInstruction(clazz, method, codeAttribute, offset, tableSwitchInstruction);
121        }
122    }
123
124    public void visitLookUpSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LookUpSwitchInstruction lookUpSwitchInstruction)
125    {
126        for (int index = 0; index < instructionVisitorCount; index++)
127        {
128            instructionVisitors[index].visitLookUpSwitchInstruction(clazz, method, codeAttribute, offset, lookUpSwitchInstruction);
129        }
130    }
131}
132