1674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen/* 2674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * Copyright 2003 The Apache Software Foundation 3674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * 4674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * Licensed under the Apache License, Version 2.0 (the "License"); 5674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * you may not use this file except in compliance with the License. 6674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * You may obtain a copy of the License at 7674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * 8674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * http://www.apache.org/licenses/LICENSE-2.0 9674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * 10674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * Unless required by applicable law or agreed to in writing, software 11674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * distributed under the License is distributed on an "AS IS" BASIS, 12674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * See the License for the specific language governing permissions and 14674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * limitations under the License. 15674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen */ 16674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenpackage org.mockito.cglib.core; 17674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 18674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenimport java.io.*; 19674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenimport java.util.*; 20674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 21674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenimport org.mockito.asm.*; 22674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 23674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen/** 24674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @author Juozas Baliuka, Chris Nokleberg 25674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen */ 26674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenpublic class ClassEmitter extends ClassAdapter { 27674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen private ClassInfo classInfo; 28674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen private Map fieldInfo; 29674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 30674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen private static int hookCounter; 31674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen private MethodVisitor rawStaticInit; 32674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen private CodeEmitter staticInit; 33674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen private CodeEmitter staticHook; 34674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen private Signature staticHookSig; 35674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 36674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public ClassEmitter(ClassVisitor cv) { 37674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen super(null); 38674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen setTarget(cv); 39674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 40674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 41674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public ClassEmitter() { 42674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen super(null); 43674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 44674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 45674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public void setTarget(ClassVisitor cv) { 46674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen this.cv = cv; 47674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen fieldInfo = new HashMap(); 48674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 49674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen // just to be safe 50674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen staticInit = staticHook = null; 51674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen staticHookSig = null; 52674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 53674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 54674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen synchronized private static int getNextHook() { 55674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return ++hookCounter; 56674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 57674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 58674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public ClassInfo getClassInfo() { 59674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return classInfo; 60674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 61674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 62674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public void begin_class(int version, final int access, String className, final Type superType, final Type[] interfaces, String source) { 63674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen final Type classType = Type.getType("L" + className.replace('.', '/') + ";"); 64674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen classInfo = new ClassInfo() { 65674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public Type getType() { 66674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return classType; 67674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 68674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public Type getSuperType() { 69674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return (superType != null) ? superType : Constants.TYPE_OBJECT; 70674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 71674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public Type[] getInterfaces() { 72674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return interfaces; 73674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 74674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public int getModifiers() { 75674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return access; 76674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 77674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen }; 78674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen cv.visit(version, 79674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen access, 80674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen classInfo.getType().getInternalName(), 81674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen null, 82674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen classInfo.getSuperType().getInternalName(), 83674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen TypeUtils.toInternalNames(interfaces)); 84674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (source != null) 85674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen cv.visitSource(source, null); 86674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen init(); 87674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 88674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 89674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public CodeEmitter getStaticHook() { 90674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (TypeUtils.isInterface(getAccess())) { 91674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen throw new IllegalStateException("static hook is invalid for this class"); 92674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 93674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (staticHook == null) { 94674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen staticHookSig = new Signature("CGLIB$STATICHOOK" + getNextHook(), "()V"); 95674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen staticHook = begin_method(Constants.ACC_STATIC, 96674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen staticHookSig, 97674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen null); 98674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (staticInit != null) { 99674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen staticInit.invoke_static_this(staticHookSig); 100674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 101674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 102674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return staticHook; 103674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 104674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 105674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen protected void init() { 106674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 107674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 108674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public int getAccess() { 109674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return classInfo.getModifiers(); 110674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 111674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 112674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public Type getClassType() { 113674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return classInfo.getType(); 114674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 115674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 116674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public Type getSuperType() { 117674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return classInfo.getSuperType(); 118674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 119674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 120674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public void end_class() { 121674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (staticHook != null && staticInit == null) { 122674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen // force creation of static init 123674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen begin_static(); 124674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 125674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (staticInit != null) { 126674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen staticHook.return_value(); 127674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen staticHook.end_method(); 128674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen rawStaticInit.visitInsn(Constants.RETURN); 129674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen rawStaticInit.visitMaxs(0, 0); 130674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen staticInit = staticHook = null; 131674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen staticHookSig = null; 132674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 133674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen cv.visitEnd(); 134674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 135674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 136674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public CodeEmitter begin_method(int access, Signature sig, Type[] exceptions) { 137674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (classInfo == null) 138674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen throw new IllegalStateException("classInfo is null! " + this); 139674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen MethodVisitor v = cv.visitMethod(access, 140674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen sig.getName(), 141674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen sig.getDescriptor(), 142674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen null, 143674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen TypeUtils.toInternalNames(exceptions)); 144674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (sig.equals(Constants.SIG_STATIC) && !TypeUtils.isInterface(getAccess())) { 145674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen rawStaticInit = v; 146674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen MethodVisitor wrapped = new MethodAdapter(v) { 147674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public void visitMaxs(int maxStack, int maxLocals) { 148674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen // ignore 149674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 150674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public void visitInsn(int insn) { 151674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (insn != Constants.RETURN) { 152674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen super.visitInsn(insn); 153674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 154674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 155674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen }; 156674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen staticInit = new CodeEmitter(this, wrapped, access, sig, exceptions); 157674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (staticHook == null) { 158674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen // force static hook creation 159674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen getStaticHook(); 160674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } else { 161674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen staticInit.invoke_static_this(staticHookSig); 162674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 163674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return staticInit; 164674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } else if (sig.equals(staticHookSig)) { 165674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return new CodeEmitter(this, v, access, sig, exceptions) { 166674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public boolean isStaticHook() { 167674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return true; 168674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 169674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen }; 170674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } else { 171674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return new CodeEmitter(this, v, access, sig, exceptions); 172674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 173674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 174674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 175674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public CodeEmitter begin_static() { 176674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return begin_method(Constants.ACC_STATIC, Constants.SIG_STATIC, null); 177674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 178674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 179674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public void declare_field(int access, String name, Type type, Object value) { 180674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen FieldInfo existing = (FieldInfo)fieldInfo.get(name); 181674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen FieldInfo info = new FieldInfo(access, name, type, value); 182674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (existing != null) { 183674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (!info.equals(existing)) { 184674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen throw new IllegalArgumentException("Field \"" + name + "\" has been declared differently"); 185674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 186674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } else { 187674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen fieldInfo.put(name, info); 188674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen cv.visitField(access, name, type.getDescriptor(), null, value); 189674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 190674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 191674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 192674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen // TODO: make public? 193674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen boolean isFieldDeclared(String name) { 194674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return fieldInfo.get(name) != null; 195674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 196674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 197674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen FieldInfo getFieldInfo(String name) { 198674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen FieldInfo field = (FieldInfo)fieldInfo.get(name); 199674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (field == null) { 200674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen throw new IllegalArgumentException("Field " + name + " is not declared in " + getClassType().getClassName()); 201674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 202674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return field; 203674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 204674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 205674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen static class FieldInfo { 206674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen int access; 207674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen String name; 208674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen Type type; 209674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen Object value; 210674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 211674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public FieldInfo(int access, String name, Type type, Object value) { 212674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen this.access = access; 213674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen this.name = name; 214674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen this.type = type; 215674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen this.value = value; 216674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 217674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 218674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public boolean equals(Object o) { 219674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (o == null) 220674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return false; 221674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (!(o instanceof FieldInfo)) 222674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return false; 223674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen FieldInfo other = (FieldInfo)o; 224674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (access != other.access || 225674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen !name.equals(other.name) || 226674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen !type.equals(other.type)) { 227674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return false; 228674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 229674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if ((value == null) ^ (other.value == null)) 230674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return false; 231674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (value != null && !value.equals(other.value)) 232674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return false; 233674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return true; 234674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 235674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 236674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public int hashCode() { 237674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return access ^ name.hashCode() ^ type.hashCode() ^ ((value == null) ? 0 : value.hashCode()); 238674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 239674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 240674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 241674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public void visit(int version, 242674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen int access, 243674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen String name, 244674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen String signature, 245674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen String superName, 246674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen String[] interfaces) { 247674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen begin_class(version, 248674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen access, 249674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen name.replace('/', '.'), 250674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen TypeUtils.fromInternalName(superName), 251674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen TypeUtils.fromInternalNames(interfaces), 252674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen null); // TODO 253674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 254674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 255674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public void visitEnd() { 256674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen end_class(); 257674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 258674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 259674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public FieldVisitor visitField(int access, 260674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen String name, 261674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen String desc, 262674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen String signature, 263674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen Object value) { 264674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen declare_field(access, name, Type.getType(desc), value); 265674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return null; // TODO 266674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 267674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 268674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public MethodVisitor visitMethod(int access, 269674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen String name, 270674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen String desc, 271674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen String signature, 272674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen String[] exceptions) { 273674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return begin_method(access, 274674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen new Signature(name, desc), 275674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen TypeUtils.fromInternalNames(exceptions)); 276674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 277674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen} 278