Home | History | Annotate | Download | only in util
      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.util;
     31 
     32 import org.mockito.asm.AnnotationVisitor;
     33 import org.mockito.asm.Attribute;
     34 import org.mockito.asm.Type;
     35 
     36 import java.util.Map;
     37 
     38 /**
     39  * An abstract ASMifier visitor.
     40  *
     41  * @author Eric Bruneton
     42  */
     43 public class ASMifierAbstractVisitor extends AbstractVisitor {
     44 
     45     /**
     46      * The name of the variable for this visitor in the produced code.
     47      */
     48     protected String name;
     49 
     50     /**
     51      * The label names. This map associates String values to Label keys. It is
     52      * used only in ASMifierMethodVisitor.
     53      */
     54     Map labelNames;
     55 
     56     /**
     57      * Constructs a new {@link ASMifierAbstractVisitor}.
     58      *
     59      * @param name the name of the variable for this visitor in the produced
     60      *        code.
     61      */
     62     protected ASMifierAbstractVisitor(final String name) {
     63         this.name = name;
     64     }
     65 
     66     /**
     67      * Prints the ASM code that generates the given annotation.
     68      *
     69      * @param desc the class descriptor of the annotation class.
     70      * @param visible <tt>true</tt> if the annotation is visible at runtime.
     71      * @return a visitor to visit the annotation values.
     72      */
     73     public AnnotationVisitor visitAnnotation(
     74         final String desc,
     75         final boolean visible)
     76     {
     77         buf.setLength(0);
     78         buf.append("{\n")
     79                 .append("av0 = ")
     80                 .append(name)
     81                 .append(".visitAnnotation(");
     82         appendConstant(desc);
     83         buf.append(", ").append(visible).append(");\n");
     84         text.add(buf.toString());
     85         ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(0);
     86         text.add(av.getText());
     87         text.add("}\n");
     88         return av;
     89     }
     90 
     91     /**
     92      * Prints the ASM code that generates the given attribute.
     93      *
     94      * @param attr an attribute.
     95      */
     96     public void visitAttribute(final Attribute attr) {
     97         buf.setLength(0);
     98         buf.append("// ATTRIBUTE ").append(attr.type).append('\n');
     99         if (attr instanceof ASMifiable) {
    100             buf.append("{\n");
    101             ((ASMifiable) attr).asmify(buf, "attr", labelNames);
    102             buf.append(name).append(".visitAttribute(attr);\n");
    103             buf.append("}\n");
    104         }
    105         text.add(buf.toString());
    106     }
    107 
    108     /**
    109      * Prints the ASM code to end the visit.
    110      */
    111     public void visitEnd() {
    112         buf.setLength(0);
    113         buf.append(name).append(".visitEnd();\n");
    114         text.add(buf.toString());
    115     }
    116 
    117     /**
    118      * Appends a string representation of the given constant to the given
    119      * buffer.
    120      *
    121      * @param cst an {@link Integer}, {@link Float}, {@link Long},
    122      *        {@link Double} or {@link String} object. May be <tt>null</tt>.
    123      */
    124     void appendConstant(final Object cst) {
    125         appendConstant(buf, cst);
    126     }
    127 
    128     /**
    129      * Appends a string representation of the given constant to the given
    130      * buffer.
    131      *
    132      * @param buf a string buffer.
    133      * @param cst an {@link Integer}, {@link Float}, {@link Long},
    134      *        {@link Double} or {@link String} object. May be <tt>null</tt>.
    135      */
    136     static void appendConstant(final StringBuffer buf, final Object cst) {
    137         if (cst == null) {
    138             buf.append("null");
    139         } else if (cst instanceof String) {
    140             appendString(buf, (String) cst);
    141         } else if (cst instanceof Type) {
    142             buf.append("Type.getType(\"");
    143             buf.append(((Type) cst).getDescriptor());
    144             buf.append("\")");
    145         } else if (cst instanceof Byte) {
    146             buf.append("new Byte((byte)").append(cst).append(')');
    147         } else if (cst instanceof Boolean) {
    148             buf.append(((Boolean) cst).booleanValue() ? "Boolean.TRUE" : "Boolean.FALSE");
    149         } else if (cst instanceof Short) {
    150             buf.append("new Short((short)").append(cst).append(')');
    151         } else if (cst instanceof Character) {
    152             int c = ((Character) cst).charValue();
    153             buf.append("new Character((char)").append(c).append(')');
    154         } else if (cst instanceof Integer) {
    155             buf.append("new Integer(").append(cst).append(')');
    156         } else if (cst instanceof Float) {
    157             buf.append("new Float(\"").append(cst).append("\")");
    158         } else if (cst instanceof Long) {
    159             buf.append("new Long(").append(cst).append("L)");
    160         } else if (cst instanceof Double) {
    161             buf.append("new Double(\"").append(cst).append("\")");
    162         } else if (cst instanceof byte[]) {
    163             byte[] v = (byte[]) cst;
    164             buf.append("new byte[] {");
    165             for (int i = 0; i < v.length; i++) {
    166                 buf.append(i == 0 ? "" : ",").append(v[i]);
    167             }
    168             buf.append('}');
    169         } else if (cst instanceof boolean[]) {
    170             boolean[] v = (boolean[]) cst;
    171             buf.append("new boolean[] {");
    172             for (int i = 0; i < v.length; i++) {
    173                 buf.append(i == 0 ? "" : ",").append(v[i]);
    174             }
    175             buf.append('}');
    176         } else if (cst instanceof short[]) {
    177             short[] v = (short[]) cst;
    178             buf.append("new short[] {");
    179             for (int i = 0; i < v.length; i++) {
    180                 buf.append(i == 0 ? "" : ",").append("(short)").append(v[i]);
    181             }
    182             buf.append('}');
    183         } else if (cst instanceof char[]) {
    184             char[] v = (char[]) cst;
    185             buf.append("new char[] {");
    186             for (int i = 0; i < v.length; i++) {
    187                 buf.append(i == 0 ? "" : ",")
    188                         .append("(char)")
    189                         .append((int) v[i]);
    190             }
    191             buf.append('}');
    192         } else if (cst instanceof int[]) {
    193             int[] v = (int[]) cst;
    194             buf.append("new int[] {");
    195             for (int i = 0; i < v.length; i++) {
    196                 buf.append(i == 0 ? "" : ",").append(v[i]);
    197             }
    198             buf.append('}');
    199         } else if (cst instanceof long[]) {
    200             long[] v = (long[]) cst;
    201             buf.append("new long[] {");
    202             for (int i = 0; i < v.length; i++) {
    203                 buf.append(i == 0 ? "" : ",").append(v[i]).append('L');
    204             }
    205             buf.append('}');
    206         } else if (cst instanceof float[]) {
    207             float[] v = (float[]) cst;
    208             buf.append("new float[] {");
    209             for (int i = 0; i < v.length; i++) {
    210                 buf.append(i == 0 ? "" : ",").append(v[i]).append('f');
    211             }
    212             buf.append('}');
    213         } else if (cst instanceof double[]) {
    214             double[] v = (double[]) cst;
    215             buf.append("new double[] {");
    216             for (int i = 0; i < v.length; i++) {
    217                 buf.append(i == 0 ? "" : ",").append(v[i]).append('d');
    218             }
    219             buf.append('}');
    220         }
    221     }
    222 }
    223