001// ASM: a very small and fast Java bytecode manipulation framework 002// Copyright (c) 2000-2011 INRIA, France Telecom 003// All rights reserved. 004// 005// Redistribution and use in source and binary forms, with or without 006// modification, are permitted provided that the following conditions 007// are met: 008// 1. Redistributions of source code must retain the above copyright 009// notice, this list of conditions and the following disclaimer. 010// 2. Redistributions in binary form must reproduce the above copyright 011// notice, this list of conditions and the following disclaimer in the 012// documentation and/or other materials provided with the distribution. 013// 3. Neither the name of the copyright holders nor the names of its 014// contributors may be used to endorse or promote products derived from 015// this software without specific prior written permission. 016// 017// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 018// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 019// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 020// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 021// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 022// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 023// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 024// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 025// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 026// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 027// THE POSSIBILITY OF SUCH DAMAGE. 028 029package io.ebean.enhance.asm; 030 031/** 032 * A reference to a field or a method. 033 * 034 * @author Remi Forax 035 * @author Eric Bruneton 036 */ 037public final class Handle { 038 039 /** 040 * The kind of field or method designated by this Handle. Should be {@link Opcodes#H_GETFIELD}, 041 * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC}, {@link 042 * Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL}, 043 * {@link Opcodes#H_NEWINVOKESPECIAL} or {@link Opcodes#H_INVOKEINTERFACE}. 044 */ 045 private final int tag; 046 047 /** The internal name of the class that owns the field or method designated by this handle. */ 048 private final String owner; 049 050 /** The name of the field or method designated by this handle. */ 051 private final String name; 052 053 /** The descriptor of the field or method designated by this handle. */ 054 private final String descriptor; 055 056 /** Whether the owner is an interface or not. */ 057 private final boolean isInterface; 058 059 /** 060 * Constructs a new field or method handle. 061 * 062 * @param tag the kind of field or method designated by this Handle. Must be {@link 063 * Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, {@link 064 * Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC}, 065 * {@link Opcodes#H_INVOKESPECIAL}, {@link Opcodes#H_NEWINVOKESPECIAL} or {@link 066 * Opcodes#H_INVOKEINTERFACE}. 067 * @param owner the internal name of the class that owns the field or method designated by this 068 * handle (see {@link Type#getInternalName()}). 069 * @param name the name of the field or method designated by this handle. 070 * @param descriptor the descriptor of the field or method designated by this handle. 071 * @deprecated this constructor has been superseded by {@link #Handle(int, String, String, String, 072 * boolean)}. 073 */ 074 @Deprecated 075 public Handle(final int tag, final String owner, final String name, final String descriptor) { 076 this(tag, owner, name, descriptor, tag == Opcodes.H_INVOKEINTERFACE); 077 } 078 079 /** 080 * Constructs a new field or method handle. 081 * 082 * @param tag the kind of field or method designated by this Handle. Must be {@link 083 * Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, {@link 084 * Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC}, 085 * {@link Opcodes#H_INVOKESPECIAL}, {@link Opcodes#H_NEWINVOKESPECIAL} or {@link 086 * Opcodes#H_INVOKEINTERFACE}. 087 * @param owner the internal name of the class that owns the field or method designated by this 088 * handle (see {@link Type#getInternalName()}). 089 * @param name the name of the field or method designated by this handle. 090 * @param descriptor the descriptor of the field or method designated by this handle. 091 * @param isInterface whether the owner is an interface or not. 092 */ 093 public Handle( 094 final int tag, 095 final String owner, 096 final String name, 097 final String descriptor, 098 final boolean isInterface) { 099 this.tag = tag; 100 this.owner = owner; 101 this.name = name; 102 this.descriptor = descriptor; 103 this.isInterface = isInterface; 104 } 105 106 /** 107 * Returns the kind of field or method designated by this handle. 108 * 109 * @return {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, 110 * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL}, {@link 111 * Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL}, {@link 112 * Opcodes#H_NEWINVOKESPECIAL} or {@link Opcodes#H_INVOKEINTERFACE}. 113 */ 114 public int getTag() { 115 return tag; 116 } 117 118 /** 119 * Returns the internal name of the class that owns the field or method designated by this handle. 120 * 121 * @return the internal name of the class that owns the field or method designated by this handle 122 * (see {@link Type#getInternalName()}). 123 */ 124 public String getOwner() { 125 return owner; 126 } 127 128 /** 129 * Returns the name of the field or method designated by this handle. 130 * 131 * @return the name of the field or method designated by this handle. 132 */ 133 public String getName() { 134 return name; 135 } 136 137 /** 138 * Returns the descriptor of the field or method designated by this handle. 139 * 140 * @return the descriptor of the field or method designated by this handle. 141 */ 142 public String getDesc() { 143 return descriptor; 144 } 145 146 /** 147 * Returns true if the owner of the field or method designated by this handle is an interface. 148 * 149 * @return true if the owner of the field or method designated by this handle is an interface. 150 */ 151 public boolean isInterface() { 152 return isInterface; 153 } 154 155 @Override 156 public boolean equals(final Object object) { 157 if (object == this) { 158 return true; 159 } 160 if (!(object instanceof Handle)) { 161 return false; 162 } 163 Handle handle = (Handle) object; 164 return tag == handle.tag 165 && isInterface == handle.isInterface 166 && owner.equals(handle.owner) 167 && name.equals(handle.name) 168 && descriptor.equals(handle.descriptor); 169 } 170 171 @Override 172 public int hashCode() { 173 return tag 174 + (isInterface ? 64 : 0) 175 + owner.hashCode() * name.hashCode() * descriptor.hashCode(); 176 } 177 178 /** 179 * Returns the textual representation of this handle. The textual representation is: 180 * 181 * <ul> 182 * <li>for a reference to a class: owner "." name descriptor " (" tag ")", 183 * <li>for a reference to an interface: owner "." name descriptor " (" tag " itf)". 184 * </ul> 185 */ 186 @Override 187 public String toString() { 188 return owner + '.' + name + descriptor + " (" + tag + (isInterface ? " itf" : "") + ')'; 189 } 190}