/*
 * Copyright 2014 - 2020 Rafael Winterhalter
 *
 * 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 net.bytebuddy.asm;

import net.bytebuddy.build.HashCodeAndEqualsPlugin;
import net.bytebuddy.description.annotation.AnnotationDescription;
import net.bytebuddy.description.annotation.AnnotationList;
import net.bytebuddy.description.field.FieldDescription;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.implementation.Implementation;
import net.bytebuddy.implementation.attribute.AnnotationValueFilter;
import net.bytebuddy.implementation.attribute.FieldAttributeAppender;
import net.bytebuddy.implementation.attribute.MethodAttributeAppender;
import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.pool.TypePool;
import net.bytebuddy.utility.OpenedClassReader;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

A visitor that adds attributes to a class member.
Type parameters:
  • <T> – The type of the attribute appender factory.
/** * A visitor that adds attributes to a class member. * * @param <T> The type of the attribute appender factory. */
@HashCodeAndEqualsPlugin.Enhance public abstract class MemberAttributeExtension<T> {
The annotation value filter factory to apply.
/** * The annotation value filter factory to apply. */
protected final AnnotationValueFilter.Factory annotationValueFilterFactory;
The attribute appender factory to use.
/** * The attribute appender factory to use. */
protected final T attributeAppenderFactory;
Creates a new member attribute extension.
Params:
  • annotationValueFilterFactory – The annotation value filter factory to apply.
  • attributeAppenderFactory – The attribute appender factory to use.
/** * Creates a new member attribute extension. * * @param annotationValueFilterFactory The annotation value filter factory to apply. * @param attributeAppenderFactory The attribute appender factory to use. */
protected MemberAttributeExtension(AnnotationValueFilter.Factory annotationValueFilterFactory, T attributeAppenderFactory) { this.annotationValueFilterFactory = annotationValueFilterFactory; this.attributeAppenderFactory = attributeAppenderFactory; }
A visitor that adds attributes to a field.
/** * A visitor that adds attributes to a field. */
public static class ForField extends MemberAttributeExtension<FieldAttributeAppender.Factory> implements AsmVisitorWrapper.ForDeclaredFields.FieldVisitorWrapper {
Creates a field attribute extension that appends default values of annotations.
/** * Creates a field attribute extension that appends default values of annotations. */
public ForField() { this(AnnotationValueFilter.Default.APPEND_DEFAULTS); }
Creates a field attribute extension.
Params:
  • annotationValueFilterFactory – The annotation value filter factory to apply.
/** * Creates a field attribute extension. * * @param annotationValueFilterFactory The annotation value filter factory to apply. */
public ForField(AnnotationValueFilter.Factory annotationValueFilterFactory) { this(annotationValueFilterFactory, FieldAttributeAppender.NoOp.INSTANCE); }
Creates a field attribute extension.
Params:
  • annotationValueFilterFactory – The annotation value filter factory to apply.
  • attributeAppenderFactory – The field attribute appender factory to use.
/** * Creates a field attribute extension. * * @param annotationValueFilterFactory The annotation value filter factory to apply. * @param attributeAppenderFactory The field attribute appender factory to use. */
protected ForField(AnnotationValueFilter.Factory annotationValueFilterFactory, FieldAttributeAppender.Factory attributeAppenderFactory) { super(annotationValueFilterFactory, attributeAppenderFactory); }
Appends the supplied annotations.
Params:
  • annotation – The annotations to append.
Returns:A new field attribute extension that appends any previously registered attributes and the supplied annotations.
/** * Appends the supplied annotations. * * @param annotation The annotations to append. * @return A new field attribute extension that appends any previously registered attributes and the supplied annotations. */
public ForField annotate(Annotation... annotation) { return annotate(Arrays.asList(annotation)); }
Appends the supplied annotations.
Params:
  • annotations – The annotations to append.
Returns:A new field attribute extension that appends any previously registered attributes and the supplied annotations.
/** * Appends the supplied annotations. * * @param annotations The annotations to append. * @return A new field attribute extension that appends any previously registered attributes and the supplied annotations. */
public ForField annotate(List<? extends Annotation> annotations) { return annotate(new AnnotationList.ForLoadedAnnotations(annotations)); }
Appends the supplied annotations.
Params:
  • annotation – The annotations to append.
Returns:A new field attribute extension that appends any previously registered attributes and the supplied annotations.
/** * Appends the supplied annotations. * * @param annotation The annotations to append. * @return A new field attribute extension that appends any previously registered attributes and the supplied annotations. */
public ForField annotate(AnnotationDescription... annotation) { return annotate(Arrays.asList(annotation)); }
Appends the supplied annotations.
Params:
  • annotations – The annotations to append.
Returns:A new field attribute extension that appends any previously registered attributes and the supplied annotations.
/** * Appends the supplied annotations. * * @param annotations The annotations to append. * @return A new field attribute extension that appends any previously registered attributes and the supplied annotations. */
public ForField annotate(Collection<? extends AnnotationDescription> annotations) { return attribute(new FieldAttributeAppender.Explicit(new ArrayList<AnnotationDescription>(annotations))); }
Appends the supplied attribute appender factory.
Params:
  • attributeAppenderFactory – The attribute appender factory to append.
Returns:A new field attribute extension that appends any previously registered attributes and the supplied annotations.
/** * Appends the supplied attribute appender factory. * * @param attributeAppenderFactory The attribute appender factory to append. * @return A new field attribute extension that appends any previously registered attributes and the supplied annotations. */
public ForField attribute(FieldAttributeAppender.Factory attributeAppenderFactory) { return new ForField(annotationValueFilterFactory, new FieldAttributeAppender.Factory.Compound(this.attributeAppenderFactory, attributeAppenderFactory)); }
{@inheritDoc}
/** * {@inheritDoc} */
public FieldVisitor wrap(TypeDescription instrumentedType, FieldDescription.InDefinedShape fieldDescription, FieldVisitor fieldVisitor) { return new FieldAttributeVisitor(fieldVisitor, fieldDescription, attributeAppenderFactory.make(instrumentedType), annotationValueFilterFactory.on(fieldDescription)); }
Applies this attribute extension on any field that matches the supplied matcher.
Params:
  • matcher – The matcher that decides what fields the represented extension is applied to.
Returns:An appropriate ASM visitor wrapper.
/** * Applies this attribute extension on any field that matches the supplied matcher. * * @param matcher The matcher that decides what fields the represented extension is applied to. * @return An appropriate ASM visitor wrapper. */
public AsmVisitorWrapper on(ElementMatcher<? super FieldDescription.InDefinedShape> matcher) { return new AsmVisitorWrapper.ForDeclaredFields().field(matcher, this); }
A field visitor to apply an field attribute appender.
/** * A field visitor to apply an field attribute appender. */
private static class FieldAttributeVisitor extends FieldVisitor {
The field to add annotations to.
/** * The field to add annotations to. */
private final FieldDescription fieldDescription;
The field attribute appender to apply.
/** * The field attribute appender to apply. */
private final FieldAttributeAppender fieldAttributeAppender;
The annotation value filter to apply.
/** * The annotation value filter to apply. */
private final AnnotationValueFilter annotationValueFilter;
Creates a new field attribute visitor.
Params:
  • fieldVisitor – The field visitor to apply changes to.
  • fieldDescription – The field to add annotations to.
  • fieldAttributeAppender – The field attribute appender to apply.
  • annotationValueFilter – The annotation value filter to apply.
/** * Creates a new field attribute visitor. * * @param fieldVisitor The field visitor to apply changes to. * @param fieldDescription The field to add annotations to. * @param fieldAttributeAppender The field attribute appender to apply. * @param annotationValueFilter The annotation value filter to apply. */
private FieldAttributeVisitor(FieldVisitor fieldVisitor, FieldDescription fieldDescription, FieldAttributeAppender fieldAttributeAppender, AnnotationValueFilter annotationValueFilter) { super(OpenedClassReader.ASM_API, fieldVisitor); this.fieldDescription = fieldDescription; this.fieldAttributeAppender = fieldAttributeAppender; this.annotationValueFilter = annotationValueFilter; } @Override public void visitEnd() { fieldAttributeAppender.apply(fv, fieldDescription, annotationValueFilter); super.visitEnd(); } } }
A visitor that adds attributes to a method.
/** * A visitor that adds attributes to a method. */
public static class ForMethod extends MemberAttributeExtension<MethodAttributeAppender.Factory> implements AsmVisitorWrapper.ForDeclaredMethods.MethodVisitorWrapper {
Creates a method attribute extension.
/** * Creates a method attribute extension. */
public ForMethod() { this(AnnotationValueFilter.Default.APPEND_DEFAULTS); }
Creates a method attribute extension.
Params:
  • annotationValueFilterFactory – The annotation value filter factory to apply.
/** * Creates a method attribute extension. * * @param annotationValueFilterFactory The annotation value filter factory to apply. */
public ForMethod(AnnotationValueFilter.Factory annotationValueFilterFactory) { this(annotationValueFilterFactory, MethodAttributeAppender.NoOp.INSTANCE); }
Creates a method attribute extension.
Params:
  • annotationValueFilterFactory – The annotation value filter factory to apply.
  • attributeAppenderFactory – The method attribute appender factory to use.
/** * Creates a method attribute extension. * * @param annotationValueFilterFactory The annotation value filter factory to apply. * @param attributeAppenderFactory The method attribute appender factory to use. */
protected ForMethod(AnnotationValueFilter.Factory annotationValueFilterFactory, MethodAttributeAppender.Factory attributeAppenderFactory) { super(annotationValueFilterFactory, attributeAppenderFactory); }
Appends the supplied annotations.
Params:
  • annotation – The annotations to append.
Returns:A new method attribute extension that appends any previously registered attributes and the supplied annotations.
/** * Appends the supplied annotations. * * @param annotation The annotations to append. * @return A new method attribute extension that appends any previously registered attributes and the supplied annotations. */
public ForMethod annotateMethod(Annotation... annotation) { return annotateMethod(Arrays.asList(annotation)); }
Appends the supplied annotations.
Params:
  • annotations – The annotations to append.
Returns:A new method attribute extension that appends any previously registered attributes and the supplied annotations.
/** * Appends the supplied annotations. * * @param annotations The annotations to append. * @return A new method attribute extension that appends any previously registered attributes and the supplied annotations. */
public ForMethod annotateMethod(List<? extends Annotation> annotations) { return annotateMethod(new AnnotationList.ForLoadedAnnotations(annotations)); }
Appends the supplied annotations.
Params:
  • annotation – The annotations to append.
Returns:A new method attribute extension that appends any previously registered attributes and the supplied annotations.
/** * Appends the supplied annotations. * * @param annotation The annotations to append. * @return A new method attribute extension that appends any previously registered attributes and the supplied annotations. */
public ForMethod annotateMethod(AnnotationDescription... annotation) { return annotateMethod(Arrays.asList(annotation)); }
Appends the supplied annotations.
Params:
  • annotations – The annotations to append.
Returns:A new method attribute extension that appends any previously registered attributes and the supplied annotations.
/** * Appends the supplied annotations. * * @param annotations The annotations to append. * @return A new method attribute extension that appends any previously registered attributes and the supplied annotations. */
public ForMethod annotateMethod(Collection<? extends AnnotationDescription> annotations) { return attribute(new MethodAttributeAppender.Explicit(new ArrayList<AnnotationDescription>(annotations))); }
Appends the supplied annotations to the parameter at the given index.
Params:
  • index – The parameter index.
  • annotation – The annotations to append.
Returns:A new method attribute extension that appends any previously registered attributes and the supplied annotations.
/** * Appends the supplied annotations to the parameter at the given index. * * @param index The parameter index. * @param annotation The annotations to append. * @return A new method attribute extension that appends any previously registered attributes and the supplied annotations. */
public ForMethod annotateParameter(int index, Annotation... annotation) { return annotateParameter(index, Arrays.asList(annotation)); }
Appends the supplied annotations to the parameter at the given index.
Params:
  • index – The parameter index.
  • annotations – The annotations to append.
Returns:A new method attribute extension that appends any previously registered attributes and the supplied annotations.
/** * Appends the supplied annotations to the parameter at the given index. * * @param index The parameter index. * @param annotations The annotations to append. * @return A new method attribute extension that appends any previously registered attributes and the supplied annotations. */
public ForMethod annotateParameter(int index, List<? extends Annotation> annotations) { return annotateParameter(index, new AnnotationList.ForLoadedAnnotations(annotations)); }
Appends the supplied annotations to the parameter at the given index.
Params:
  • index – The parameter index.
  • annotation – The annotations to append.
Returns:A new method attribute extension that appends any previously registered attributes and the supplied annotations.
/** * Appends the supplied annotations to the parameter at the given index. * * @param index The parameter index. * @param annotation The annotations to append. * @return A new method attribute extension that appends any previously registered attributes and the supplied annotations. */
public ForMethod annotateParameter(int index, AnnotationDescription... annotation) { return annotateParameter(index, Arrays.asList(annotation)); }
Appends the supplied annotations to the parameter at the given index.
Params:
  • index – The parameter index.
  • annotations – The annotations to append.
Returns:A new method attribute extension that appends any previously registered attributes and the supplied annotations.
/** * Appends the supplied annotations to the parameter at the given index. * * @param index The parameter index. * @param annotations The annotations to append. * @return A new method attribute extension that appends any previously registered attributes and the supplied annotations. */
public ForMethod annotateParameter(int index, Collection<? extends AnnotationDescription> annotations) { if (index < 0) { throw new IllegalArgumentException("Parameter index cannot be negative: " + index); } return attribute(new MethodAttributeAppender.Explicit(index, new ArrayList<AnnotationDescription>(annotations))); }
Appends the supplied method attribute appender factory.
Params:
  • attributeAppenderFactory – The attribute appender factory to append.
Returns:A new method attribute extension that appends any previously registered attributes and the supplied annotations.
/** * Appends the supplied method attribute appender factory. * * @param attributeAppenderFactory The attribute appender factory to append. * @return A new method attribute extension that appends any previously registered attributes and the supplied annotations. */
public ForMethod attribute(MethodAttributeAppender.Factory attributeAppenderFactory) { return new ForMethod(annotationValueFilterFactory, new MethodAttributeAppender.Factory.Compound(this.attributeAppenderFactory, attributeAppenderFactory)); }
{@inheritDoc}
/** * {@inheritDoc} */
public MethodVisitor wrap(TypeDescription instrumentedType, MethodDescription instrumentedMethod, MethodVisitor methodVisitor, Implementation.Context implementationContext, TypePool typePool, int writerFlags, int readerFlags) { return new AttributeAppendingMethodVisitor(methodVisitor, instrumentedMethod, attributeAppenderFactory.make(instrumentedType), annotationValueFilterFactory.on(instrumentedMethod)); }
Applies this attribute extension on any method or constructor that matches the supplied matcher.
Params:
  • matcher – The matcher that decides what methods or constructors the represented extension is applied to.
Returns:An appropriate ASM visitor wrapper.
/** * Applies this attribute extension on any method or constructor that matches the supplied matcher. * * @param matcher The matcher that decides what methods or constructors the represented extension is applied to. * @return An appropriate ASM visitor wrapper. */
public AsmVisitorWrapper on(ElementMatcher<? super MethodDescription> matcher) { return new AsmVisitorWrapper.ForDeclaredMethods().invokable(matcher, this); }
A method visitor to apply a method attribute appender.
/** * A method visitor to apply a method attribute appender. */
private static class AttributeAppendingMethodVisitor extends MethodVisitor {
The instrumented method.
/** * The instrumented method. */
private final MethodDescription methodDescription;
The field to add annotations to.
/** * The field to add annotations to. */
private final MethodAttributeAppender methodAttributeAppender;
The annotation value filter to apply.
/** * The annotation value filter to apply. */
private final AnnotationValueFilter annotationValueFilter;
true if the attribute appender was not yet applied.
/** * {@code true} if the attribute appender was not yet applied. */
private boolean applicable;
Params:
  • methodVisitor – The method visitor to apply changes to.
  • methodDescription – The method to add annotations to.
  • methodAttributeAppender – The annotation value filter to apply.
  • annotationValueFilter – The annotation value filter to apply.
/** * @param methodVisitor The method visitor to apply changes to. * @param methodDescription The method to add annotations to. * @param methodAttributeAppender The annotation value filter to apply. * @param annotationValueFilter The annotation value filter to apply. */
private AttributeAppendingMethodVisitor(MethodVisitor methodVisitor, MethodDescription methodDescription, MethodAttributeAppender methodAttributeAppender, AnnotationValueFilter annotationValueFilter) { super(OpenedClassReader.ASM_API, methodVisitor); this.methodDescription = methodDescription; this.methodAttributeAppender = methodAttributeAppender; this.annotationValueFilter = annotationValueFilter; applicable = true; } @Override public void visitCode() { if (applicable) { methodAttributeAppender.apply(mv, methodDescription, annotationValueFilter); applicable = false; } super.visitCode(); } @Override public void visitEnd() { if (applicable) { methodAttributeAppender.apply(mv, methodDescription, annotationValueFilter); applicable = false; } super.visitEnd(); } } } }