001/***
002 * ASM: a very small and fast Java bytecode manipulation framework
003 * Copyright (c) 2000-2011 INRIA, France Telecom
004 * All rights reserved.
005 *
006 * Redistribution and use in source and binary forms, with or without
007 * modification, are permitted provided that the following conditions
008 * are met:
009 * 1. Redistributions of source code must retain the above copyright
010 *    notice, this list of conditions and the following disclaimer.
011 * 2. Redistributions in binary form must reproduce the above copyright
012 *    notice, this list of conditions and the following disclaimer in the
013 *    documentation and/or other materials provided with the distribution.
014 * 3. Neither the name of the copyright holders nor the names of its
015 *    contributors may be used to endorse or promote products derived from
016 *    this software without specific prior written permission.
017 *
018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
022 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
028 * THE POSSIBILITY OF SUCH DAMAGE.
029 */
030package io.ebean.enhance.asm.tree;
031
032import io.ebean.enhance.asm.MethodVisitor;
033
034import java.util.List;
035
036/**
037 * A node that represents a try catch block.
038 * 
039 * @author Eric Bruneton
040 */
041public class TryCatchBlockNode {
042
043    /**
044     * Beginning of the exception handler's scope (inclusive).
045     */
046    public LabelNode start;
047
048    /**
049     * End of the exception handler's scope (exclusive).
050     */
051    public LabelNode end;
052
053    /**
054     * Beginning of the exception handler's code.
055     */
056    public LabelNode handler;
057
058    /**
059     * Internal name of the type of exceptions handled by the handler. May be
060     * <tt>null</tt> to catch any exceptions (for "finally" blocks).
061     */
062    public String type;
063
064    /**
065     * The runtime visible type annotations on the exception handler type. This
066     * list is a list of {@link TypeAnnotationNode} objects. May be
067     * <tt>null</tt>.
068     * 
069     * @associates org.objectweb.asm.tree.TypeAnnotationNode
070     * @label visible
071     */
072    public List<TypeAnnotationNode> visibleTypeAnnotations;
073
074    /**
075     * The runtime invisible type annotations on the exception handler type.
076     * This list is a list of {@link TypeAnnotationNode} objects. May be
077     * <tt>null</tt>.
078     * 
079     * @associates org.objectweb.asm.tree.TypeAnnotationNode
080     * @label invisible
081     */
082    public List<TypeAnnotationNode> invisibleTypeAnnotations;
083
084    /**
085     * Constructs a new {@link TryCatchBlockNode}.
086     * 
087     * @param start
088     *            beginning of the exception handler's scope (inclusive).
089     * @param end
090     *            end of the exception handler's scope (exclusive).
091     * @param handler
092     *            beginning of the exception handler's code.
093     * @param type
094     *            internal name of the type of exceptions handled by the
095     *            handler, or <tt>null</tt> to catch any exceptions (for
096     *            "finally" blocks).
097     */
098    public TryCatchBlockNode(final LabelNode start, final LabelNode end,
099                             final LabelNode handler, final String type) {
100        this.start = start;
101        this.end = end;
102        this.handler = handler;
103        this.type = type;
104    }
105
106    /**
107     * Updates the index of this try catch block in the method's list of try
108     * catch block nodes. This index maybe stored in the 'target' field of the
109     * type annotations of this block.
110     * 
111     * @param index
112     *            the new index of this try catch block in the method's list of
113     *            try catch block nodes.
114     */
115    public void updateIndex(final int index) {
116        int newTypeRef = 0x42000000 | (index << 8);
117        if (visibleTypeAnnotations != null) {
118            for (TypeAnnotationNode tan : visibleTypeAnnotations) {
119                tan.typeRef = newTypeRef;
120            }
121        }
122        if (invisibleTypeAnnotations != null) {
123            for (TypeAnnotationNode tan : invisibleTypeAnnotations) {
124                tan.typeRef = newTypeRef;
125            }
126        }
127    }
128
129    /**
130     * Makes the given visitor visit this try catch block.
131     * 
132     * @param mv
133     *            a method visitor.
134     */
135    public void accept(final MethodVisitor mv) {
136        mv.visitTryCatchBlock(start.getLabel(), end.getLabel(),
137                handler == null ? null : handler.getLabel(), type);
138        int n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations
139                .size();
140        for (int i = 0; i < n; ++i) {
141            TypeAnnotationNode an = visibleTypeAnnotations.get(i);
142            an.accept(mv.visitTryCatchAnnotation(an.typeRef, an.typePath,
143                    an.desc, true));
144        }
145        n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations
146                .size();
147        for (int i = 0; i < n; ++i) {
148            TypeAnnotationNode an = invisibleTypeAnnotations.get(i);
149            an.accept(mv.visitTryCatchAnnotation(an.typeRef, an.typePath,
150                    an.desc, false));
151        }
152    }
153}