@Override
 public void visit(
     final int version,
     final int access,
     final String name,
     final String signature,
     final String superName,
     final String[] interfaces) {
   Set<String> interfacesSet = new LinkedHashSet<String>();
   if (interfaces != null) Collections.addAll(interfacesSet, interfaces);
   for (Class extraInterface : classList) {
     if (extraInterface.isInterface())
       interfacesSet.add(BytecodeHelper.getClassInternalName(extraInterface));
   }
   final boolean addGroovyObjectSupport = !GroovyObject.class.isAssignableFrom(superClass);
   if (addGroovyObjectSupport) interfacesSet.add("groovy/lang/GroovyObject");
   super.visit(
       V1_5,
       ACC_PUBLIC,
       proxyName,
       signature,
       BytecodeHelper.getClassInternalName(superClass),
       interfacesSet.toArray(new String[interfacesSet.size()]));
   addDelegateFields();
   if (addGroovyObjectSupport) {
     createGroovyObjectSupport();
   }
   for (Class clazz : classList) {
     visitClass(clazz);
   }
 }
Esempio n. 2
0
  /**
   * check whether a class should not be considered for transformation
   *
   * @param clazz the class to check
   * @return true if clazz should not be considered for transformation otherwise false
   */
  protected boolean isSkipClass(Class<?> clazz) {
    if (!inst.isModifiableClass(clazz)) {
      return true;
    }

    // we can safely skip array classes, interfaces and primitive classes

    if (clazz.isArray()) {
      return true;
    }

    if (clazz.isInterface()) {
      return true;
    }

    if (clazz.isPrimitive()) {
      return true;
    }

    String name = clazz.getName();

    if (isBytemanClass(name) || !isTransformable(name)) {
      return true;
    }

    return false;
  }
  private void writeSetter(ClassVisitor visitor, Type generatedType, ModelProperty<?> property) {
    WeaklyTypeReferencingMethod<?, Void> weakSetter = property.getSetter();
    // There is no setter for this property
    if (weakSetter == null) {
      return;
    }

    String propertyName = property.getName();
    Class<?> propertyClass = property.getType().getConcreteClass();
    Type propertyType = Type.getType(propertyClass);
    Label calledOutsideOfConstructor = new Label();

    Method setter = weakSetter.getMethod();

    // the regular typed setter
    String methodDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, propertyType);
    MethodVisitor methodVisitor =
        declareMethod(
            visitor, setter.getName(), methodDescriptor, AsmClassGeneratorUtils.signature(setter));

    putCanCallSettersFieldValueOnStack(methodVisitor, generatedType);
    jumpToLabelIfStackEvaluatesToTrue(methodVisitor, calledOutsideOfConstructor);
    throwExceptionBecauseCalledOnItself(methodVisitor);

    methodVisitor.visitLabel(calledOutsideOfConstructor);
    putStateFieldValueOnStack(methodVisitor, generatedType);
    putConstantOnStack(methodVisitor, propertyName);
    putFirstMethodArgumentOnStack(methodVisitor, propertyType);
    if (propertyClass.isPrimitive()) {
      boxType(methodVisitor, propertyClass);
    }
    invokeStateSetMethod(methodVisitor);

    finishVisitingMethod(methodVisitor);
  }
    public void addGetter(MetaBeanProperty property) throws Exception {
      MetaMethod getter = property.getGetter();

      // GENERATE private boolean <prop>Set;

      String flagName = String.format("%sSet", property.getName());
      visitor.visitField(
          Opcodes.ACC_PRIVATE, flagName, Type.BOOLEAN_TYPE.getDescriptor(), null, null);

      addConventionGetter(getter.getName(), flagName, property);

      String getterName = getter.getName();
      Class<?> returnType = getter.getReturnType();

      // If it's a boolean property, there can be get or is type variants.
      // If this class has both, decorate both.
      if (returnType.equals(Boolean.TYPE)) {
        boolean getterIsIsMethod = getterName.startsWith("is");
        String propertyNameComponent = getterName.substring(getterIsIsMethod ? 2 : 3);
        String alternativeGetterName =
            String.format("%s%s", getterIsIsMethod ? "get" : "is", propertyNameComponent);

        try {
          type.getMethod(alternativeGetterName);
          addConventionGetter(alternativeGetterName, flagName, property);
        } catch (NoSuchMethodException e) {
          // ignore, no method to override
        }
      }
    }
 @Test
 public void testEnclosingType() throws Exception {
   for (Class<?> type : standardTypes) {
     assertThat(
         describe(type).getEnclosingType(),
         type.getEnclosingClass() == null
             ? nullValue(TypeDescription.class)
             : is((TypeDescription) new TypeDescription.ForLoadedType(type.getEnclosingClass())));
   }
 }
 @Test
 public void testSourceName() throws Exception {
   for (Class<?> type : standardTypes) {
     if (type.isArray()) {
       assertThat(describe(type).getActualName(), is(type.getComponentType().getName() + "[]"));
     } else {
       assertThat(describe(type).getActualName(), is(type.getName()));
     }
   }
 }
Esempio n. 7
0
 /**
  * use the supplied bytes to define a class and try creating an instance via the empty
  * constructor printing details of any errors which occur
  *
  * @param classname
  * @param protectionDomain
  * @param bytes
  * @return the bytes if all goes well otherwise null
  */
 public byte[] verify(String classname, ProtectionDomain protectionDomain, byte[] bytes) {
   try {
     Class clazz = super.defineClass(classname, bytes, 0, bytes.length, protectionDomain);
     clazz.newInstance();
   } catch (Throwable th) {
     System.out.println("Transformer:verifyTransformedBytes " + th);
     return null;
   }
   return bytes;
 }
 private void visitType(java.lang.reflect.Type type, StringBuilder builder) {
   if (type instanceof Class) {
     Class<?> cl = (Class<?>) type;
     if (cl.isPrimitive()) {
       builder.append(Type.getType(cl).getDescriptor());
     } else {
       if (cl.isArray()) {
         builder.append(cl.getName().replace('.', '/'));
       } else {
         builder.append('L');
         builder.append(cl.getName().replace('.', '/'));
         builder.append(';');
       }
     }
   } else if (type instanceof ParameterizedType) {
     ParameterizedType parameterizedType = (ParameterizedType) type;
     visitNested(parameterizedType.getRawType(), builder);
     builder.append('<');
     for (java.lang.reflect.Type param : parameterizedType.getActualTypeArguments()) {
       visitType(param, builder);
     }
     builder.append(">;");
   } else if (type instanceof WildcardType) {
     WildcardType wildcardType = (WildcardType) type;
     if (wildcardType.getUpperBounds().length == 1
         && wildcardType.getUpperBounds()[0].equals(Object.class)) {
       if (wildcardType.getLowerBounds().length == 0) {
         builder.append('*');
         return;
       }
     } else {
       for (java.lang.reflect.Type upperType : wildcardType.getUpperBounds()) {
         builder.append('+');
         visitType(upperType, builder);
       }
     }
     for (java.lang.reflect.Type lowerType : wildcardType.getLowerBounds()) {
       builder.append('-');
       visitType(lowerType, builder);
     }
   } else if (type instanceof TypeVariable) {
     TypeVariable<?> typeVar = (TypeVariable) type;
     builder.append('T');
     builder.append(typeVar.getName());
     builder.append(';');
   } else if (type instanceof GenericArrayType) {
     GenericArrayType arrayType = (GenericArrayType) type;
     builder.append('[');
     visitType(arrayType.getGenericComponentType(), builder);
   } else {
     throw new IllegalArgumentException(
         String.format("Cannot generate signature for %s.", type));
   }
 }
  /**
   * Visit every class/interface this proxy should implement, and generate the appropriate bytecode
   * for delegation if available.
   *
   * @param clazz an class for which to generate bytecode
   */
  private void visitClass(final Class clazz) {
    Method[] methods = clazz.getDeclaredMethods();
    for (Method method : methods) {
      Class<?>[] exceptionTypes = method.getExceptionTypes();
      String[] exceptions = new String[exceptionTypes.length];
      for (int i = 0; i < exceptions.length; i++) {
        exceptions[i] = BytecodeHelper.getClassInternalName(exceptionTypes[i]);
      }
      // for each method defined in the class, generate the appropriate delegation bytecode
      visitMethod(
          method.getModifiers(),
          method.getName(),
          BytecodeHelper.getMethodDescriptor(method.getReturnType(), method.getParameterTypes()),
          null,
          exceptions);
    }
    Constructor[] constructors = clazz.getDeclaredConstructors();
    for (Constructor method : constructors) {
      Class<?>[] exceptionTypes = method.getExceptionTypes();
      String[] exceptions = new String[exceptionTypes.length];
      for (int i = 0; i < exceptions.length; i++) {
        exceptions[i] = BytecodeHelper.getClassInternalName(exceptionTypes[i]);
      }
      // for each method defined in the class, generate the appropriate delegation bytecode
      visitMethod(
          method.getModifiers(),
          "<init>",
          BytecodeHelper.getMethodDescriptor(Void.TYPE, method.getParameterTypes()),
          null,
          exceptions);
    }

    for (Class intf : clazz.getInterfaces()) {
      visitClass(intf);
    }
    Class superclass = clazz.getSuperclass();
    if (superclass != null) visitClass(superclass);

    // Ultimately, methods can be available in the closure map which are not defined by the
    // superclass
    // nor the interfaces
    for (Map.Entry<String, Boolean> entry : delegatedClosures.entrySet()) {
      Boolean visited = entry.getValue();
      if (!visited) {
        String name = entry.getKey();
        if (!"*".equals(name)) {
          // generate a new method
          visitMethod(ACC_PUBLIC, name, "([Ljava/lang/Object;)Ljava/lang/Object;", null, null);
        }
      }
    }
  }
 public static Class<?> malform(Class<?> type) throws Exception {
   ClassReader classReader = new ClassReader(type.getName());
   ClassWriter classWriter = new ClassWriter(classReader, 0);
   classReader.accept(new SignatureMalformer(classWriter), 0);
   ClassLoader classLoader =
       new ByteArrayClassLoader(
           null,
           Collections.singletonMap(type.getName(), classWriter.toByteArray()),
           null,
           ByteArrayClassLoader.PersistenceHandler.MANIFEST,
           PackageDefinitionStrategy.NoOp.INSTANCE);
   return classLoader.loadClass(type.getName());
 }
Esempio n. 11
0
 private void visitNested(java.lang.reflect.Type type, StringBuilder builder) {
   if (type instanceof Class) {
     Class<?> cl = (Class<?>) type;
     if (cl.isPrimitive()) {
       builder.append(Type.getType(cl).getDescriptor());
     } else {
       builder.append('L');
       builder.append(cl.getName().replace('.', '/'));
     }
   } else {
     visitType(type, builder);
   }
 }
  // the overload of type Object for Groovy coercions:  public void setFoo(Object foo)
  private void createTypeConvertingSetter(
      ClassVisitor visitor, Type generatedType, ModelProperty<?> property) {
    if (!property.isWritable() || !(property.getSchema() instanceof ScalarValueSchema)) {
      return;
    }

    Class<?> propertyClass = property.getType().getConcreteClass();
    Type propertyType = Type.getType(propertyClass);
    Class<?> boxedClass =
        propertyClass.isPrimitive() ? BOXED_TYPES.get(propertyClass) : propertyClass;
    Type boxedType = Type.getType(boxedClass);

    Method setter = property.getSetter().getMethod();
    MethodVisitor methodVisitor =
        declareMethod(
            visitor,
            setter.getName(),
            SET_OBJECT_PROPERTY_DESCRIPTOR,
            SET_OBJECT_PROPERTY_DESCRIPTOR);

    putThisOnStack(methodVisitor);
    putTypeConverterFieldValueOnStack(methodVisitor, generatedType);

    // Object converted = $typeConverter.convert(foo, Float.class, false);
    methodVisitor.visitVarInsn(ALOAD, 1); // put var #1 ('foo') on the stack
    methodVisitor.visitLdcInsn(boxedType); // push the constant Class onto the stack
    methodVisitor.visitInsn(
        propertyClass.isPrimitive()
            ? ICONST_1
            : ICONST_0); // push int 1 or 0 (interpreted as true or false) onto the stack
    methodVisitor.visitMethodInsn(
        INVOKEINTERFACE,
        TYPE_CONVERTER_TYPE.getInternalName(),
        "convert",
        COERCE_TO_SCALAR_DESCRIPTOR,
        true);
    methodVisitor.visitTypeInsn(CHECKCAST, boxedType.getInternalName());

    if (propertyClass.isPrimitive()) {
      unboxType(methodVisitor, propertyClass);
    }

    // invoke the typed setter, popping 'this' and 'converted' from the stack
    methodVisitor.visitMethodInsn(
        INVOKEVIRTUAL,
        generatedType.getInternalName(),
        setter.getName(),
        Type.getMethodDescriptor(Type.VOID_TYPE, propertyType),
        false);
    finishVisitingMethod(methodVisitor);
  }
 private static List<Method> getInheritedMethods(Class baseClass, List<Method> methods) {
   Collections.addAll(methods, baseClass.getMethods());
   Class currentClass = baseClass;
   while (currentClass != null) {
     Method[] protectedMethods = currentClass.getDeclaredMethods();
     for (Method method : protectedMethods) {
       if (method.getName().indexOf('$') != -1) continue;
       if (Modifier.isProtected(method.getModifiers())
           && !containsEquivalentMethod(methods, method)) methods.add(method);
     }
     currentClass = currentClass.getSuperclass();
   }
   return methods;
 }
 private Method getToStringMethod(Class<?> managedTypeClass) {
   try {
     return managedTypeClass.getMethod("toString");
   } catch (NoSuchMethodException e) {
     return null;
   }
 }
Esempio n. 15
0
  private boolean isTransformed(Class clazz, String name, boolean isInterface) {
    if (isBytemanClass(name) || !isTransformable(name)) {
      return false;
    }

    boolean found = false;
    List<RuleScript> scripts;
    if (isInterface) {
      scripts = scriptRepository.scriptsForInterfaceName(name);
    } else {
      scripts = scriptRepository.scriptsForClassName(name);
    }
    if (scripts != null) {
      for (RuleScript script : scripts) {
        if (!script.hasTransform(clazz)) {
          found = true;
          if (isVerbose()) {
            System.out.println("Retransforming loaded bootstrap class " + clazz.getName());
          }
          break;
        }
      }
    }

    return found;
  }
Esempio n. 16
0
    public Class<? extends T> generate() {
      visitor.visitEnd();

      byte[] bytecode = visitor.toByteArray();
      return DEFINE_CLASS_METHOD.invoke(
          type.getClassLoader(), typeName, bytecode, 0, bytecode.length);
    }
  protected void injectGetByIndex(
      ClassWriter classWriter, String targetClassName, List<Field> fields) {
    MethodVisitor methodVisitor =
        classWriter.visitMethod(
            ACC_PUBLIC,
            "get",
            "(Ljava/lang/Object;I)Ljava/lang/Object;",
            null,
            new String[] {getInternalName(ILLEGAL_ACCESS_EXCEPTION.getCanonicalName())});

    Boxer boxer = new Boxer(methodVisitor);

    methodVisitor.visitCode();
    methodVisitor.visitVarInsn(ILOAD, 2);

    int maxStack = 6;

    Label[] labels = new Label[fields.size()];
    Label errorLabel = new Label();

    for (int i = 0; i < fields.size(); i++) {
      labels[i] = new Label();
    }

    methodVisitor.visitTableSwitchInsn(0, labels.length - 1, errorLabel, labels);

    if (!fields.isEmpty()) {
      maxStack--;

      for (int i = 0; i < fields.size(); i++) {
        Field field = fields.get(i);
        Class<?> type = field.getType();
        String fieldDescriptor = Type.getDescriptor(type);

        methodVisitor.visitLabel(labels[i]);

        if (i == 0) methodVisitor.visitFrame(F_APPEND, 1, new Object[] {targetClassName}, 0, null);
        else methodVisitor.visitFrame(F_SAME, 0, null, 0, null);

        if (isPublic(field)) {
          methodVisitor.visitVarInsn(ALOAD, 1);
          methodVisitor.visitTypeInsn(CHECKCAST, targetClassName);
          methodVisitor.visitFieldInsn(GETFIELD, targetClassName, field.getName(), fieldDescriptor);

          boxer.box(Type.getType(type));
        } else {
          injectReflectiveGetter(methodVisitor);
        }

        methodVisitor.visitInsn(ARETURN);
      }

      methodVisitor.visitLabel(errorLabel);
      methodVisitor.visitFrame(F_SAME, 0, null, 0, null);
    }

    injectException(methodVisitor, IllegalAccessException.class);
    methodVisitor.visitMaxs(maxStack, 3);
    methodVisitor.visitEnd();
  }
 private void castFirstStackElement(MethodVisitor methodVisitor, Class<?> returnType) {
   if (returnType.isPrimitive()) {
     unboxType(methodVisitor, returnType);
   } else {
     methodVisitor.visitTypeInsn(CHECKCAST, Type.getInternalName(returnType));
   }
 }
Esempio n. 19
0
  public static Class getHelperAdapter(Rule rule, Class helperClass, boolean compileToBytecode)
      throws CompileException {
    Class adapterClass;
    // ok we have to create the adapter class

    // n.b. we don't bother synchronizing here -- if another rule is racing to create an adapter
    // in parallel we don't really care about generating two of them -- we can use whichever
    // one gets installed last

    try {
      String helperName = Type.getInternalName(helperClass);
      String compiledHelperName;

      // we put the helper in the
      if (compileToBytecode) {
        compiledHelperName = helperName + "_HelperAdapter_Compiled_" + nextId();
      } else {
        compiledHelperName = helperName + "_HelperAdapter_Interpreted_" + nextId();
      }

      byte[] classBytes =
          compileBytes(rule, helperClass, helperName, compiledHelperName, compileToBytecode);
      String externalName = compiledHelperName.replace('/', '.');
      // dump the compiled class bytes if required
      Transformer.maybeDumpClass(externalName, classBytes);
      // ensure the class is loaded
      // think we need to load the generated helper using the class loader of the trigger class
      ClassLoader loader = rule.getLoader();
      adapterClass = loadHelperAdapter(loader, externalName, classBytes);
    } catch (CompileException ce) {
      throw ce;
    } catch (Throwable th) {
      if (compileToBytecode) {
        throw new CompileException(
            "Compiler.createHelperAdapter : exception creating compiled helper adapter for "
                + helperClass.getName(),
            th);
      } else {
        throw new CompileException(
            "Compiler.createHelperAdapter : exception creating interpreted helper adapter for "
                + helperClass.getName(),
            th);
      }
    }

    return adapterClass;
  }
Esempio n. 20
0
    private ClassBuilderImpl(Class<T> type) {
      this.type = type;

      visitor = new ClassWriter(ClassWriter.COMPUTE_MAXS);
      typeName = type.getName() + "_Decorated";
      generatedType = Type.getType("L" + typeName.replaceAll("\\.", "/") + ";");
      superclassType = Type.getType(type);
    }
  private void writeDelegateMethods(
      final ClassVisitor visitor,
      final Type generatedType,
      StructSchema<?> delegateSchema,
      Set<Class<?>> typesToDelegate) {
    Class<?> delegateClass = delegateSchema.getType().getConcreteClass();
    Type delegateType = Type.getType(delegateClass);
    Map<Equivalence.Wrapper<Method>, Map<Class<?>, Method>> methodsToDelegate = Maps.newHashMap();
    for (Class<?> typeToDelegate : typesToDelegate) {
      for (Method methodToDelegate : typeToDelegate.getMethods()) {
        if (ModelSchemaUtils.isIgnoredMethod(methodToDelegate)) {
          continue;
        }
        Equivalence.Wrapper<Method> methodKey = METHOD_EQUIVALENCE.wrap(methodToDelegate);
        Map<Class<?>, Method> methodsByReturnType = methodsToDelegate.get(methodKey);
        if (methodsByReturnType == null) {
          methodsByReturnType = Maps.newHashMap();
          methodsToDelegate.put(methodKey, methodsByReturnType);
        }
        methodsByReturnType.put(methodToDelegate.getReturnType(), methodToDelegate);
      }
    }
    Set<Equivalence.Wrapper<Method>> delegateMethodKeys =
        ImmutableSet.copyOf(
            Iterables.transform(
                Arrays.asList(delegateClass.getMethods()),
                new Function<Method, Equivalence.Wrapper<Method>>() {
                  @Override
                  public Equivalence.Wrapper<Method> apply(Method method) {
                    return METHOD_EQUIVALENCE.wrap(method);
                  }
                }));
    for (Map.Entry<Equivalence.Wrapper<Method>, Map<Class<?>, Method>> entry :
        methodsToDelegate.entrySet()) {
      Equivalence.Wrapper<Method> methodKey = entry.getKey();
      if (!delegateMethodKeys.contains(methodKey)) {
        continue;
      }

      Map<Class<?>, Method> methodsByReturnType = entry.getValue();
      for (Method methodToDelegate : methodsByReturnType.values()) {
        writeDelegatedMethod(visitor, generatedType, delegateType, methodToDelegate);
      }
    }
  }
 @Test
 public void testEnclosingMethod() throws Exception {
   for (Class<?> type : standardTypes) {
     Matcher<MethodDescription> matcher;
     if (type.getEnclosingMethod() != null) {
       matcher =
           CoreMatchers.<MethodDescription>is(
               new MethodDescription.ForLoadedMethod(type.getEnclosingMethod()));
     } else if (type.getEnclosingConstructor() != null) {
       matcher =
           CoreMatchers.<MethodDescription>is(
               new MethodDescription.ForLoadedConstructor(type.getEnclosingConstructor()));
     } else {
       matcher = nullValue(MethodDescription.class);
     }
     assertThat(describe(type).getEnclosingMethod(), matcher);
   }
 }
  @Override
  public FieldAccessor build(ClassLoader classLoader) {
    String targetClassType = getInternalName(this.getTarget().getName());

    ClassWriter classWriter = this.getClassWriter();

    injectFieldTable(classWriter);
    injectConstructor(classWriter);
    injectGetTargetClass(classWriter, this.getTarget());

    List<Field> fields = new ArrayList<>();
    Class<?> current = this.getTarget();
    while (current != Object.class) {
      for (Field field : current.getDeclaredFields()) {
        fields.add(field);
      }
      current = current.getSuperclass();
    }

    injectGetByIndex(classWriter, targetClassType, fields);
    injectSetByIndex(classWriter, targetClassType, fields);

    injectGetByName(classWriter);
    injectSetByName(classWriter);

    injectGetFieldTable(classWriter);
    injectGetIndex(classWriter);

    classWriter.visitEnd();

    Class<?> result =
        CompilerService.create(classLoader)
            .defineClass(
                getExternalName(
                    getAccessorNameInternal(
                        this.getTarget(),
                        this
                            .getAccessorType())), // this is somewhat redundant but maybe in the
                                                  // future the class-name-format changes
                this.getClassWriter().toByteArray());

    return (FieldAccessor) instantiate(result);
  }
 /**
  * Creates a visitor which will be used as a base class for initiating the visit. It is not
  * necessary that the class is the superclass, any will do, as long as it can be loaded from a
  * byte[].
  *
  * @param baseClass
  * @return
  */
 private ClassReader createClassVisitor(final Class baseClass) {
   try {
     String name = baseClass.getName();
     String path = name.replace('.', '/') + ".class";
     InputStream in = loader.getResourceAsStream(path);
     return new ClassReader(in);
   } catch (IOException e) {
     throw new GroovyRuntimeException(
         "Unable to generate a proxy for " + baseClass + " from class loader " + loader, e);
   }
 }
 protected void injectException(
     MethodVisitor methodVisitor, Class<? extends Throwable> throwable) {
   methodVisitor.visitTypeInsn(NEW, getInternalName(throwable.getCanonicalName()));
   methodVisitor.visitInsn(DUP);
   methodVisitor.visitTypeInsn(NEW, "java/lang/StringBuilder");
   methodVisitor.visitInsn(DUP);
   methodVisitor.visitLdcInsn("Invalid index: ");
   methodVisitor.visitMethodInsn(
       INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V");
   methodVisitor.visitVarInsn(ILOAD, 2);
   methodVisitor.visitMethodInsn(
       INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;");
   methodVisitor.visitMethodInsn(
       INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;");
   methodVisitor.visitMethodInsn(
       INVOKESPECIAL,
       getInternalName(throwable.getCanonicalName()),
       "<init>",
       "(Ljava/lang/String;)V");
   methodVisitor.visitInsn(ATHROW);
 }
 @Test
 public void testIsPackageDescription() throws Exception {
   assertThat(
       describe(
               Class.forName(
                   Sample.class.getPackage().getName()
                       + "."
                       + PackageDescription.PACKAGE_CLASS_NAME))
           .isPackageType(),
       is(true));
   assertThat(describe(Object.class).isPackageType(), is(false));
 }
 private static void resetLambdaClassSequenceNumber() {
   try {
     Field counterField =
         Class.forName("java.lang.invoke.InnerClassLambdaMetafactory").getDeclaredField("counter");
     counterField.setAccessible(true);
     AtomicInteger counter = (AtomicInteger) counterField.get(null);
     counter.set(0);
   } catch (Throwable t) {
     // print to stdout to keep in sync with other log output
     System.out.println(
         "WARNING: Failed to start class numbering from one. Don't worry, it's cosmetic, "
             + "but please file a bug report and tell on which JDK version this happened.");
     t.printStackTrace(System.out);
   }
 }
 private void assertAnnotations(Class<?> type) {
   assertThat(
       describe(type).getDeclaredAnnotations(),
       hasItems(
           new AnnotationList.ForLoadedAnnotations(type.getDeclaredAnnotations())
               .toArray(new AnnotationDescription[type.getDeclaredAnnotations().length])));
   assertThat(
       describe(type).getDeclaredAnnotations().size(), is(type.getDeclaredAnnotations().length));
   assertThat(
       describe(type).getInheritedAnnotations(),
       hasItems(
           new AnnotationList.ForLoadedAnnotations(type.getAnnotations())
               .toArray(new AnnotationDescription[type.getAnnotations().length])));
   assertThat(describe(type).getInheritedAnnotations().size(), is(type.getAnnotations().length));
 }
 private void unboxType(MethodVisitor methodVisitor, Class<?> primitiveClass) {
   // Float f = (Float) tmp
   // f==null?0:f.floatValue()
   Class<?> boxedType = BOXED_TYPES.get(primitiveClass);
   Type primitiveType = Type.getType(primitiveClass);
   methodVisitor.visitTypeInsn(CHECKCAST, Type.getInternalName(boxedType));
   methodVisitor.visitInsn(DUP);
   Label exit = new Label();
   Label elseValue = new Label();
   methodVisitor.visitJumpInsn(IFNONNULL, elseValue);
   methodVisitor.visitInsn(POP);
   pushDefaultValue(methodVisitor, primitiveClass);
   methodVisitor.visitJumpInsn(GOTO, exit);
   methodVisitor.visitLabel(elseValue);
   methodVisitor.visitMethodInsn(
       INVOKEVIRTUAL,
       Type.getInternalName(boxedType),
       primitiveClass.getSimpleName() + "Value",
       Type.getMethodDescriptor(primitiveType),
       false);
   methodVisitor.visitLabel(exit);
 }
 private String proxyName() {
   String name = delegateClass != null ? delegateClass.getName() : superClass.getName();
   int index = name.lastIndexOf('.');
   if (index == -1) return name + pxyCounter.incrementAndGet() + "_groovyProxy";
   return name.substring(index + 1, name.length()) + pxyCounter.incrementAndGet() + "_groovyProxy";
 }