• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /***
2  * ASM: a very small and fast Java bytecode manipulation framework
3  * Copyright (c) 2000-2007 INRIA, France Telecom
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the copyright holders nor the names of its
15  *    contributors may be used to endorse or promote products derived from
16  *    this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 package org.mockito.asm.signature;
31 
32 /**
33  * A signature visitor that generates signatures in string format.
34  *
35  * @author Thomas Hallgren
36  * @author Eric Bruneton
37  */
38 public class SignatureWriter implements SignatureVisitor {
39 
40     /**
41      * Buffer used to construct the signature.
42      */
43     private final StringBuffer buf = new StringBuffer();
44 
45     /**
46      * Indicates if the signature contains formal type parameters.
47      */
48     private boolean hasFormals;
49 
50     /**
51      * Indicates if the signature contains method parameter types.
52      */
53     private boolean hasParameters;
54 
55     /**
56      * Stack used to keep track of class types that have arguments. Each element
57      * of this stack is a boolean encoded in one bit. The top of the stack is
58      * the lowest order bit. Pushing false = *2, pushing true = *2+1, popping =
59      * /2.
60      */
61     private int argumentStack;
62 
63     /**
64      * Constructs a new {@link SignatureWriter} object.
65      */
SignatureWriter()66     public SignatureWriter() {
67     }
68 
69     // ------------------------------------------------------------------------
70     // Implementation of the SignatureVisitor interface
71     // ------------------------------------------------------------------------
72 
visitFormalTypeParameter(final String name)73     public void visitFormalTypeParameter(final String name) {
74         if (!hasFormals) {
75             hasFormals = true;
76             buf.append('<');
77         }
78         buf.append(name);
79         buf.append(':');
80     }
81 
visitClassBound()82     public SignatureVisitor visitClassBound() {
83         return this;
84     }
85 
visitInterfaceBound()86     public SignatureVisitor visitInterfaceBound() {
87         buf.append(':');
88         return this;
89     }
90 
visitSuperclass()91     public SignatureVisitor visitSuperclass() {
92         endFormals();
93         return this;
94     }
95 
visitInterface()96     public SignatureVisitor visitInterface() {
97         return this;
98     }
99 
visitParameterType()100     public SignatureVisitor visitParameterType() {
101         endFormals();
102         if (!hasParameters) {
103             hasParameters = true;
104             buf.append('(');
105         }
106         return this;
107     }
108 
visitReturnType()109     public SignatureVisitor visitReturnType() {
110         endFormals();
111         if (!hasParameters) {
112             buf.append('(');
113         }
114         buf.append(')');
115         return this;
116     }
117 
visitExceptionType()118     public SignatureVisitor visitExceptionType() {
119         buf.append('^');
120         return this;
121     }
122 
visitBaseType(final char descriptor)123     public void visitBaseType(final char descriptor) {
124         buf.append(descriptor);
125     }
126 
visitTypeVariable(final String name)127     public void visitTypeVariable(final String name) {
128         buf.append('T');
129         buf.append(name);
130         buf.append(';');
131     }
132 
visitArrayType()133     public SignatureVisitor visitArrayType() {
134         buf.append('[');
135         return this;
136     }
137 
visitClassType(final String name)138     public void visitClassType(final String name) {
139         buf.append('L');
140         buf.append(name);
141         argumentStack *= 2;
142     }
143 
visitInnerClassType(final String name)144     public void visitInnerClassType(final String name) {
145         endArguments();
146         buf.append('.');
147         buf.append(name);
148         argumentStack *= 2;
149     }
150 
visitTypeArgument()151     public void visitTypeArgument() {
152         if (argumentStack % 2 == 0) {
153             ++argumentStack;
154             buf.append('<');
155         }
156         buf.append('*');
157     }
158 
visitTypeArgument(final char wildcard)159     public SignatureVisitor visitTypeArgument(final char wildcard) {
160         if (argumentStack % 2 == 0) {
161             ++argumentStack;
162             buf.append('<');
163         }
164         if (wildcard != '=') {
165             buf.append(wildcard);
166         }
167         return this;
168     }
169 
visitEnd()170     public void visitEnd() {
171         endArguments();
172         buf.append(';');
173     }
174 
175     /**
176      * Returns the signature that was built by this signature writer.
177      *
178      * @return the signature that was built by this signature writer.
179      */
toString()180     public String toString() {
181         return buf.toString();
182     }
183 
184     // ------------------------------------------------------------------------
185     // Utility methods
186     // ------------------------------------------------------------------------
187 
188     /**
189      * Ends the formal type parameters section of the signature.
190      */
endFormals()191     private void endFormals() {
192         if (hasFormals) {
193             hasFormals = false;
194             buf.append('>');
195         }
196     }
197 
198     /**
199      * Ends the type arguments of a class or inner class type.
200      */
endArguments()201     private void endArguments() {
202         if (argumentStack % 2 != 0) {
203             buf.append('>');
204         }
205         argumentStack /= 2;
206     }
207 }