Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright 2003 The Apache Software Foundation
   *
   *  Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
  *  Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 package org.mockito.cglib.core;
 
 import java.io.*;
 import java.util.*;
 

Author(s):
Juozas Baliuka, Chris Nokleberg
 
 public class ClassEmitter extends ClassAdapter {
     private ClassInfo classInfo;
     private Map fieldInfo;
 
     private static int hookCounter;
     private MethodVisitor rawStaticInit;
     private CodeEmitter staticInit;
     private CodeEmitter staticHook;
     private Signature staticHookSig;
 
     public ClassEmitter(ClassVisitor cv) {
         super(null);
         setTarget(cv);
     }
 
     public ClassEmitter() {
         super(null);
     }
 
     public void setTarget(ClassVisitor cv) {
         this. = cv;
          = new HashMap();
 
         // just to be safe
          =  = null;
          = null;
     }
 
     synchronized private static int getNextHook() {
         return ++;
     }
 
     public ClassInfo getClassInfo() {
         return ;
     }
 
     public void begin_class(int versionfinal int accessString classNamefinal Type superTypefinal Type[] interfacesString source) {
         final Type classType = Type.getType("L" + className.replace('.''/') + ";");
          = new ClassInfo() {
             public Type getType() {
                 return classType;
             }
             public Type getSuperType() {
                 return (superType != null) ? superType : .;
             }
             public Type[] getInterfaces() {
                 return interfaces;
             }
             public int getModifiers() {
                 return access;
             }
         };
         .visit(version,
                  access,
                  .getType().getInternalName(),
                  null,
                  .getSuperType().getInternalName(),
                  TypeUtils.toInternalNames(interfaces));
         if (source != null)
             .visitSource(sourcenull);
         init();
     }
 
     public CodeEmitter getStaticHook() {
          if (TypeUtils.isInterface(getAccess())) {
              throw new IllegalStateException("static hook is invalid for this class");
          }
          if ( == null) {
               = new Signature("CGLIB$STATICHOOK" + getNextHook(), "()V");
               = begin_method(.,
                                        ,
                                        null);
              if ( != null) {
                  .invoke_static_this();
             }
         }
         return ;
    }
    protected void init() {
    }
    public int getAccess() {
        return .getModifiers();
    }
    public Type getClassType() {
        return .getType();
    }
    public Type getSuperType() {
        return .getSuperType();
    }
    public void end_class() {
        if ( != null &&  == null) {
            // force creation of static init
            begin_static();
        }
        if ( != null) {
            .return_value();
            .end_method();
            .visitInsn(.);
            .visitMaxs(0, 0);
             =  = null;
             = null;
        }
        .visitEnd();
    }
    public CodeEmitter begin_method(int accessSignature sigType[] exceptions) {
        if ( == null)
            throw new IllegalStateException("classInfo is null! " + this);
        MethodVisitor v = .visitMethod(access,
                                         sig.getName(),
                                         sig.getDescriptor(),
                                         null,
                                         TypeUtils.toInternalNames(exceptions));
        if (sig.equals(.) && !TypeUtils.isInterface(getAccess())) {
             = v;
            MethodVisitor wrapped = new MethodAdapter(v) {
                public void visitMaxs(int maxStackint maxLocals) {
                    // ignore
                }
                public void visitInsn(int insn) {
                    if (insn != .) {
                        super.visitInsn(insn);
                    }
                }
            };
             = new CodeEmitter(thiswrappedaccesssigexceptions);
            if ( == null) {
                // force static hook creation
                getStaticHook();
            } else {
                .invoke_static_this();
            }
            return ;
        } else if (sig.equals()) {
            return new CodeEmitter(thisvaccesssigexceptions) {
                public boolean isStaticHook() {
                    return true;
                }
            };
        } else {
            return new CodeEmitter(thisvaccesssigexceptions);
        }
    }
    public CodeEmitter begin_static() {
        return begin_method(..null);
    }
    public void declare_field(int accessString nameType typeObject value) {
        FieldInfo existing = (FieldInfo).get(name);
        FieldInfo info = new FieldInfo(accessnametypevalue);
        if (existing != null) {
            if (!info.equals(existing)) {
                throw new IllegalArgumentException("Field \"" + name + "\" has been declared differently");
            }
        } else {
            .put(nameinfo);
            .visitField(accessnametype.getDescriptor(), nullvalue);
        }
    }
    // TODO: make public?
    boolean isFieldDeclared(String name) {
        return .get(name) != null;
    }
    FieldInfo getFieldInfo(String name) {
        FieldInfo field = (FieldInfo).get(name);
        if (field == null) {
            throw new IllegalArgumentException("Field " + name + " is not declared in " + getClassType().getClassName());
        }
        return field;
    }
    
    static class FieldInfo {
        int access;
        String name;
        Type type;
        Object value;
        
        public FieldInfo(int accessString nameType typeObject value) {
            this. = access;
            this. = name;
            this. = type;
            this. = value;
        }
        public boolean equals(Object o) {
            if (o == null)
                return false;
            if (!(o instanceof FieldInfo))
                return false;
            FieldInfo other = (FieldInfo)o;
            if ( != other.access ||
                !.equals(other.name) ||
                !.equals(other.type)) {
                return false;
            }
            if (( == null) ^ (other.value == null))
                return false;
            if ( != null && !.equals(other.value))
                return false;
            return true;
        }
        public int hashCode() {
            return  ^ .hashCode() ^ .hashCode() ^ (( == null) ? 0 : .hashCode());
        }
    }
    public void visit(int version,
                      int access,
                      String name,
                      String signature,
                      String superName,
                      String[] interfaces) {
        begin_class(version,
                    access,
                    name.replace('/''.'),
                    TypeUtils.fromInternalName(superName),
                    TypeUtils.fromInternalNames(interfaces),
                    null); // TODO
    }
    
    public void visitEnd() {
        end_class();
    }
    
    public FieldVisitor visitField(int access,
                                   String name,
                                   String desc,
                                   String signature,
                                   Object value) {
        declare_field(accessname, Type.getType(desc), value);
        return null// TODO
    }
    
    public MethodVisitor visitMethod(int access,
                                     String name,
                                     String desc,
                                     String signature,
                                     String[] exceptions) {
        return begin_method(access,
                            new Signature(namedesc),
                            TypeUtils.fromInternalNames(exceptions));        
    }
New to GrepCode? Check out our FAQ X