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 org.springframework.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. 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. 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 */ 123 public String getOwner() { 124 return owner; 125 } 126 127 /** 128 * Returns the name of the field or method designated by this handle. 129 * 130 * @return the name of the field or method designated by this handle. 131 */ 132 public String getName() { 133 return name; 134 } 135 136 /** 137 * Returns the descriptor of the field or method designated by this handle. 138 * 139 * @return the descriptor of the field or method designated by this handle. 140 */ 141 public String getDesc() { 142 return descriptor; 143 } 144 145 /** 146 * Returns true if the owner of the field or method designated by this handle is an interface. 147 * 148 * @return true if the owner of the field or method designated by this handle is an interface. 149 */ 150 public boolean isInterface() { 151 return isInterface; 152 } 153 154 @Override 155 public boolean equals(final Object object) { 156 if (object == this) { 157 return true; 158 } 159 if (!(object instanceof Handle)) { 160 return false; 161 } 162 Handle handle = (Handle) object; 163 return tag == handle.tag 164 && isInterface == handle.isInterface 165 && owner.equals(handle.owner) 166 && name.equals(handle.name) 167 && descriptor.equals(handle.descriptor); 168 } 169 170 @Override 171 public int hashCode() { 172 return tag 173 + (isInterface ? 64 : 0) 174 + owner.hashCode() * name.hashCode() * descriptor.hashCode(); 175 } 176 177 /** 178 * Returns the textual representation of this handle. The textual representation is: 179 * 180 * <ul> 181 * <li>for a reference to a class: owner "." name descriptor " (" tag ")", 182 * <li>for a reference to an interface: owner "." name descriptor " (" tag " itf)". 183 * </ul> 184 */ 185 @Override 186 public String toString() { 187 return owner + '.' + name + descriptor + " (" + tag + (isInterface ? " itf" : "") + ')'; 188 } 189}