diff --git a/byte-buddy-dep/src/main/java/net/bytebuddy/ByteBuddy.java b/byte-buddy-dep/src/main/java/net/bytebuddy/ByteBuddy.java index f907d75bbca..03bcb201f0d 100644 --- a/byte-buddy-dep/src/main/java/net/bytebuddy/ByteBuddy.java +++ b/byte-buddy-dep/src/main/java/net/bytebuddy/ByteBuddy.java @@ -944,7 +944,7 @@ public ByteBuddy withTypeAnnotation(Collection classVisitorWrapper, methodRegistry, modifiers, - new TypeAttributeAppender.ForAnnotation(new ArrayList(annotations), AnnotationAppender.ValueFilter.Default.APPEND_DEFAULTS), + new TypeAttributeAppender.Explicit(new ArrayList(annotations)), methodGraphCompiler, defaultFieldAttributeAppenderFactory, defaultMethodAttributeAppenderFactory); @@ -1524,8 +1524,7 @@ public MethodAnnotationTarget annotateMethod(AnnotationDescription... annotation * annotations added to the currently selected methods. */ public MethodAnnotationTarget annotateMethod(Collection annotations) { - return attribute(new MethodAttributeAppender.ForAnnotation(new ArrayList(annotations), - AnnotationAppender.ValueFilter.Default.APPEND_DEFAULTS)); + return attribute(new MethodAttributeAppender.Explicit(new ArrayList(annotations))); } /** @@ -1567,8 +1566,7 @@ public MethodAnnotationTarget annotateParameter(int parameterIndex, AnnotationDe * annotations added to the currently selected methods' parameters at the given index. */ public MethodAnnotationTarget annotateParameter(int parameterIndex, Collection annotations) { - return attribute(new MethodAttributeAppender.ForAnnotation(parameterIndex, new ArrayList(annotations), - AnnotationAppender.ValueFilter.Default.APPEND_DEFAULTS)); + return attribute(new MethodAttributeAppender.Explicit(parameterIndex, new ArrayList(annotations))); } @Override diff --git a/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/Builder.java b/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/Builder.java index 4902ebd9513..a0282c9d1f1 100644 --- a/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/Builder.java +++ b/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/Builder.java @@ -962,7 +962,7 @@ public abstract static class Adapter extends AbstractBase { protected final MethodVisitorWrapper methodVisitorWrapper; - protected final AnnotationAppender.ValueFilter valueFilter; + protected final AnnotationAppender.ValueFilter.Factory valueFilterFactory; protected Adapter(InstrumentedType.WithFlexibleName instrumentedType, FieldRegistry fieldRegistry, @@ -972,7 +972,7 @@ protected Adapter(InstrumentedType.WithFlexibleName instrumentedType, ClassVisitorWrapper classVisitorWrapper, FieldVisitorWrapper fieldVisitorWrapper, MethodVisitorWrapper methodVisitorWrapper, - AnnotationAppender.ValueFilter valueFilter) { + AnnotationAppender.ValueFilter.Factory valueFilterFactory) { this.instrumentedType = instrumentedType; this.fieldRegistry = fieldRegistry; this.methodRegistry = methodRegistry; @@ -981,7 +981,7 @@ protected Adapter(InstrumentedType.WithFlexibleName instrumentedType, this.classVisitorWrapper = classVisitorWrapper; this.fieldVisitorWrapper = fieldVisitorWrapper; this.methodVisitorWrapper = methodVisitorWrapper; - this.valueFilter = valueFilter; + this.valueFilterFactory = valueFilterFactory; } @Override @@ -1024,7 +1024,7 @@ public Builder ignore(ElementMatcher ignored) { classVisitorWrapper, fieldVisitorWrapper, methodVisitorWrapper, - valueFilter); + valueFilterFactory); } @Override @@ -1037,7 +1037,7 @@ public Builder initializer(ByteCodeAppender byteCodeAppender) { classVisitorWrapper, fieldVisitorWrapper, methodVisitorWrapper, - valueFilter); + valueFilterFactory); } @Override @@ -1050,7 +1050,7 @@ public Builder initializer(LoadedTypeInitializer loadedTypeInitializer) { classVisitorWrapper, fieldVisitorWrapper, methodVisitorWrapper, - valueFilter); + valueFilterFactory); } @Override @@ -1063,7 +1063,7 @@ public Builder name(String name) { classVisitorWrapper, fieldVisitorWrapper, methodVisitorWrapper, - valueFilter); + valueFilterFactory); } @Override @@ -1076,7 +1076,7 @@ public Builder modifiers(int modifiers) { classVisitorWrapper, fieldVisitorWrapper, methodVisitorWrapper, - valueFilter); + valueFilterFactory); } @Override @@ -1089,7 +1089,7 @@ public Builder typeVariable(String symbol, TypeDefinition bound) { classVisitorWrapper, fieldVisitorWrapper, methodVisitorWrapper, - valueFilter); + valueFilterFactory); } @Override @@ -1102,7 +1102,7 @@ public Builder attribute(TypeAttributeAppender typeAttributeAppender) { classVisitorWrapper, fieldVisitorWrapper, methodVisitorWrapper, - valueFilter); + valueFilterFactory); } @Override @@ -1115,7 +1115,7 @@ public Builder annotateType(Collection annot classVisitorWrapper, fieldVisitorWrapper, methodVisitorWrapper, - valueFilter); + valueFilterFactory); } @Override @@ -1128,7 +1128,7 @@ public Builder visit(ClassVisitorWrapper classVisitorWrapper) { new ClassVisitorWrapper.Compound(this.classVisitorWrapper, classVisitorWrapper), fieldVisitorWrapper, methodVisitorWrapper, - valueFilter); + valueFilterFactory); } @Override @@ -1141,7 +1141,7 @@ public Builder visit(FieldVisitorWrapper fieldVisitorWrapper) { classVisitorWrapper, new FieldVisitorWrapper.Compound(this.fieldVisitorWrapper, fieldVisitorWrapper), methodVisitorWrapper, - valueFilter); + valueFilterFactory); } @Override @@ -1154,7 +1154,7 @@ public Builder visit(MethodVisitorWrapper methodVisitorWrapper) { classVisitorWrapper, fieldVisitorWrapper, new MethodVisitorWrapper.Compound(this.methodVisitorWrapper, methodVisitorWrapper), - valueFilter); + valueFilterFactory); } protected abstract Builder materialize(InstrumentedType instrumentedType, @@ -1165,14 +1165,14 @@ protected abstract Builder materialize(InstrumentedType instrumentedType, ClassVisitorWrapper classVisitorWrapper, FieldVisitorWrapper fieldVisitorWrapper, MethodVisitorWrapper methodVisitorWrapper, - AnnotationAppender.ValueFilter valueFilter); + AnnotationAppender.ValueFilter.Factory valueFilterFactory); protected class FieldDefinitionAdapter extends FieldDefinition.Optional.Valuable.AbstractBase.Adapter { private final FieldDescription.Token token; protected FieldDefinitionAdapter(FieldDescription.Token token) { - this(FieldAttributeAppender.NoOp.INSTANCE, FieldTransformer.NoOp.INSTANCE, FieldDescription.NO_DEFAULT_VALUE, token); // TODO: Field appender + this(FieldAttributeAppender.ForInstrumentedField.INSTANCE, FieldTransformer.NoOp.INSTANCE, FieldDescription.NO_DEFAULT_VALUE, token); } protected FieldDefinitionAdapter(FieldAttributeAppender.Factory fieldAttributeAppenderFactory, @@ -1201,7 +1201,7 @@ protected Builder materialize() { classVisitorWrapper, fieldVisitorWrapper, methodVisitorWrapper, - valueFilter); + valueFilterFactory); } @Override @@ -1230,7 +1230,7 @@ protected FieldMatchAdapter(FieldAttributeAppender.Factory fieldAttributeAppende @Override public Optional annotateField(Collection annotations) { - return attribute(new FieldAttributeAppender.ForAnnotations(valueFilter, new ArrayList(annotations))); + return attribute(new FieldAttributeAppender.Explicit(new ArrayList(annotations))); } @Override @@ -1243,7 +1243,7 @@ protected Builder materialize() { classVisitorWrapper, fieldVisitorWrapper, methodVisitorWrapper, - valueFilter); + valueFilterFactory); } @Override @@ -1383,9 +1383,7 @@ protected MethodDefinition.ParameterDefinition.Simple materialize() { protected class AnnotationAdapter extends MethodDefinition.AbstractBase.Adapter { protected AnnotationAdapter(MethodRegistry.Handler handler) { - this(handler, - MethodAttributeAppender.NoOp.INSTANCE, // TODO - MethodTransformer.NoOp.INSTANCE); + this(handler, MethodAttributeAppender.ForInstrumentedMethod.INSTANCE, MethodTransformer.NoOp.INSTANCE); } protected AnnotationAdapter(MethodRegistry.Handler handler, MethodAttributeAppender.Factory methodAttributeAppenderFactory, MethodTransformer methodTransformer) { @@ -1430,13 +1428,13 @@ protected MethodDefinition materialize(MethodRegistry.Handler handler, Method protected Builder materialize() { return Builder.AbstractBase.Adapter.this.materialize(instrumentedType.withMethod(token), fieldRegistry, - methodRegistry.append(new LatentMatcher.ForMethodToken(token), handler, methodAttributeAppenderFactory, null), // TODO + methodRegistry.append(new LatentMatcher.ForMethodToken(token), handler, methodAttributeAppenderFactory, methodTransformer), ignored, typeAttributeAppender, classVisitorWrapper, fieldVisitorWrapper, methodVisitorWrapper, - valueFilter); + valueFilterFactory); } } } @@ -1481,14 +1479,14 @@ protected AnnotationAdapter(MethodRegistry.Handler handler, MethodAttributeAppen @Override public MethodDefinition annotateMethod(Collection annotations) { return new AnnotationAdapter(handler, - new MethodAttributeAppender.Factory.Compound(methodAttributeAppenderFactory, new MethodAttributeAppender.ForAnnotation(null)), // TODO + new MethodAttributeAppender.Factory.Compound(methodAttributeAppenderFactory, new MethodAttributeAppender.Explicit(new ArrayList(annotations))), methodTransformer); } @Override public MethodDefinition annotateParameter(int index, Collection annotations) { return new AnnotationAdapter(handler, - new MethodAttributeAppender.Factory.Compound(methodAttributeAppenderFactory, new MethodAttributeAppender.ForAnnotation(index, null)), // TODO + new MethodAttributeAppender.Factory.Compound(methodAttributeAppenderFactory, new MethodAttributeAppender.Explicit(index, new ArrayList(annotations))), methodTransformer); } @@ -1501,13 +1499,13 @@ protected MethodDefinition materialize(MethodRegistry.Handler handler, Method protected Builder materialize() { return Builder.AbstractBase.Adapter.this.materialize(instrumentedType, fieldRegistry, - methodRegistry.append(matcher, handler, methodAttributeAppenderFactory, null), // TODO + methodRegistry.append(matcher, handler, methodAttributeAppenderFactory, methodTransformer), ignored, typeAttributeAppender, classVisitorWrapper, fieldVisitorWrapper, methodVisitorWrapper, - valueFilter); + valueFilterFactory); } } } @@ -1530,7 +1528,7 @@ protected Builder materialize() { classVisitorWrapper, fieldVisitorWrapper, methodVisitorWrapper, - valueFilter); + valueFilterFactory); } // TODO: Inherited interface methods are not matched properly! diff --git a/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/DynamicType.java b/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/DynamicType.java index 67ba6ffe693..63a11005663 100644 --- a/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/DynamicType.java +++ b/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/DynamicType.java @@ -20,7 +20,6 @@ import net.bytebuddy.dynamic.scaffold.MethodRegistry; import net.bytebuddy.implementation.Implementation; import net.bytebuddy.implementation.LoadedTypeInitializer; -import net.bytebuddy.implementation.attribute.AnnotationAppender; import net.bytebuddy.implementation.attribute.FieldAttributeAppender; import net.bytebuddy.implementation.attribute.MethodAttributeAppender; import net.bytebuddy.implementation.attribute.TypeAttributeAppender; @@ -377,10 +376,10 @@ interface Builder { /** * Defines a new field for this type. * - * @param name The name of the method. + * @param name The name of the method. * @param fieldType The type of this field where the current type can be represented by - * {@link net.bytebuddy.dynamic.TargetType}. - * @param modifier The modifiers for this method. + * {@link net.bytebuddy.dynamic.TargetType}. + * @param modifier The modifiers for this method. * @return An interception delegate that exclusively matches the new method. */ FieldValueTarget defineField(String name, TypeDefinition fieldType, ModifierContributor.ForField... modifier); @@ -399,10 +398,10 @@ interface Builder { /** * Defines a new field for this type. * - * @param name The name of the method. + * @param name The name of the method. * @param fieldType The type of this field where the current type can be represented by - * {@link net.bytebuddy.dynamic.TargetType}. - * @param modifiers The modifiers for this method. + * {@link net.bytebuddy.dynamic.TargetType}. + * @param modifiers The modifiers for this method. * @return An interception delegate that exclusively matches the new method. */ FieldValueTarget defineField(String name, TypeDefinition fieldType, int modifiers); @@ -1618,8 +1617,7 @@ public Builder annotateType(AnnotationDescription... annotation) { @Override public Builder annotateType(Collection annotations) { - return attribute(new TypeAttributeAppender.ForAnnotation(new ArrayList(annotations), - AnnotationAppender.ValueFilter.Default.APPEND_DEFAULTS)); + return attribute(new TypeAttributeAppender.Explicit(new ArrayList(annotations))); } @Override @@ -2195,7 +2193,7 @@ protected class DefaultFieldValueTarget extends AbstractDelegatingBuilder imp /** * Creates a new subclass field annotation target for a field without a default value. * - * @param token A token representing the field that was recently defined. + * @param token A token representing the field that was recently defined. * @param attributeAppenderFactory The attribute appender factory that was defined for this field token. */ private DefaultFieldValueTarget(FieldDescription.Token token, @@ -2206,7 +2204,7 @@ private DefaultFieldValueTarget(FieldDescription.Token token, /** * Creates a new subclass field annotation target. * - * @param token A token representing the field that was recently defined. + * @param token A token representing the field that was recently defined. * @param attributeAppenderFactory The attribute appender factory that was defined for this field token. * @param defaultValue The default value to define for the recently defined field. */ @@ -2299,7 +2297,7 @@ private FieldAnnotationTarget makeFieldAnnotationTarget(Object defaultValue) @Override public FieldAnnotationTarget attribute(FieldAttributeAppender.Factory attributeAppenderFactory) { return new DefaultFieldValueTarget(token, - new FieldAttributeAppender.Factory.Compound(this.attributeAppenderFactory,attributeAppenderFactory)); + new FieldAttributeAppender.Factory.Compound(this.attributeAppenderFactory, attributeAppenderFactory)); } @Override @@ -2319,7 +2317,7 @@ public FieldAnnotationTarget annotateField(AnnotationDescription... annotatio @Override public FieldAnnotationTarget annotateField(Collection annotations) { - return attribute(new FieldAttributeAppender.ForAnnotations(AnnotationAppender.ValueFilter.Default.APPEND_DEFAULTS, new ArrayList(annotations))); + return attribute(new FieldAttributeAppender.Explicit(new ArrayList(annotations))); } @Override @@ -2712,8 +2710,7 @@ public MethodAnnotationTarget annotateMethod(AnnotationDescription... annotat @Override public MethodAnnotationTarget annotateMethod(Collection annotations) { - return attribute(new MethodAttributeAppender.ForAnnotation((new ArrayList(annotations)), - AnnotationAppender.ValueFilter.Default.APPEND_DEFAULTS)); + return attribute(new MethodAttributeAppender.Explicit((new ArrayList(annotations)))); } @Override @@ -2733,8 +2730,7 @@ public MethodAnnotationTarget annotateParameter(int parameterIndex, Annotatio @Override public MethodAnnotationTarget annotateParameter(int parameterIndex, Collection annotations) { - return attribute(new MethodAttributeAppender.ForAnnotation(parameterIndex, new ArrayList(annotations), - AnnotationAppender.ValueFilter.Default.APPEND_DEFAULTS)); + return attribute(new MethodAttributeAppender.Explicit(parameterIndex, new ArrayList(annotations))); } @Override diff --git a/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/scaffold/FieldRegistry.java b/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/scaffold/FieldRegistry.java index a43debc4e2e..67dfe493f11 100644 --- a/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/scaffold/FieldRegistry.java +++ b/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/scaffold/FieldRegistry.java @@ -45,7 +45,7 @@ enum NoOp implements Compiled { @Override public Record target(FieldDescription fieldDescription) { - return new Record.ForSimpleField(fieldDescription, AnnotationAppender.ValueFilter.Default.APPEND_DEFAULTS); // TODO + return new Record.ForSimpleField(fieldDescription); } @Override @@ -207,7 +207,7 @@ public Record target(FieldDescription fieldDescription) { return entry.bind(fieldDescription); } } - return new Record.ForSimpleField(fieldDescription, AnnotationAppender.ValueFilter.Default.APPEND_DEFAULTS); // TODO + return new Record.ForSimpleField(fieldDescription); } @Override @@ -285,7 +285,7 @@ public boolean equals(Object other) { @Override public int hashCode() { int result = matcher.hashCode(); - result = 31 * attributeAppender.hashCode(); + result = 31 * result + attributeAppender.hashCode(); result = 31 * result + (defaultValue != null ? defaultValue.hashCode() : 0); return result; } diff --git a/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/scaffold/MethodRegistry.java b/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/scaffold/MethodRegistry.java index 5ab327fa6d8..87b41734793 100644 --- a/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/scaffold/MethodRegistry.java +++ b/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/scaffold/MethodRegistry.java @@ -621,7 +621,7 @@ protected Prepared.Entry asPreparedEntry(TypeDescription instrumentedType, */ protected Prepared.Entry asSupplementaryEntry(MethodDescription methodDescription) { return new Prepared.Entry(handler, - new MethodAttributeAppender.ForMethod(methodDescription, AnnotationAppender.ValueFilter.Default.APPEND_DEFAULTS), + MethodAttributeAppender.Explicit.of(methodDescription), methodDescription, Collections.emptySet()); } @@ -851,7 +851,7 @@ protected Entry(Handler handler, */ protected static Entry forVisibilityBridge(MethodDescription bridgeTarget) { return new Entry(Handler.ForVisibilityBridge.INSTANCE, - new MethodAttributeAppender.ForMethod(bridgeTarget, AnnotationAppender.ValueFilter.Default.APPEND_DEFAULTS), + MethodAttributeAppender.Explicit.of(bridgeTarget), bridgeTarget, Collections.emptySet()); } diff --git a/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/scaffold/TypeWriter.java b/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/scaffold/TypeWriter.java index 966424ed5f6..4abe027cab4 100644 --- a/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/scaffold/TypeWriter.java +++ b/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/scaffold/TypeWriter.java @@ -104,16 +104,13 @@ class ForSimpleField implements Record { */ private final FieldDescription fieldDescription; - private final AnnotationAppender.ValueFilter valueFilter; - /** * Creates a new record for a simple field. * * @param fieldDescription The described field. */ - public ForSimpleField(FieldDescription fieldDescription, AnnotationAppender.ValueFilter valueFilter) { + public ForSimpleField(FieldDescription fieldDescription) { this.fieldDescription = fieldDescription; - this.valueFilter = valueFilter; } @Override @@ -123,7 +120,7 @@ public FieldDescription getField() { @Override public FieldAttributeAppender getFieldAppender() { - return new FieldAttributeAppender.ForInstrumentedField(valueFilter); + return FieldAttributeAppender.ForInstrumentedField.INSTANCE; } @Override @@ -149,23 +146,19 @@ public void apply(FieldVisitor fieldVisitor) { @Override public boolean equals(Object other) { - if (this == other) return true; - if (other == null || getClass() != other.getClass()) return false; - ForSimpleField that = (ForSimpleField) other; - return fieldDescription.equals(that.fieldDescription) - && valueFilter.equals(that.valueFilter); + return this == other || !(other == null || getClass() != other.getClass()) + && fieldDescription.equals(((ForSimpleField) other).fieldDescription); } @Override public int hashCode() { - return 31 * fieldDescription.hashCode() + valueFilter.hashCode(); + return fieldDescription.hashCode(); } @Override public String toString() { return "TypeWriter.FieldPool.Record.ForSimpleField{" + "fieldDescription=" + fieldDescription + - ", valueFilter=" + valueFilter + '}'; } } @@ -2840,7 +2833,7 @@ public void visit(int classFileVersionNumber, TypeDescription.OBJECT : instrumentedType.getSuperType().asErasure()).getInternalName(), instrumentedType.getInterfaces().asErasures().toInternalNames()); - attributeAppender.apply(this, instrumentedType, originalType.asGenericType()); + attributeAppender.apply(this, instrumentedType); if (!ClassFileVersion.ofMinorMajor(classFileVersionNumber).isAtLeast(ClassFileVersion.JAVA_V8) && instrumentedType.isInterface()) { implementationContext.prohibitTypeInitializer(); } @@ -3207,7 +3200,7 @@ public byte[] create(Implementation.Context.ExtractableView implementationContex ? TypeDescription.OBJECT : instrumentedType.getSuperType().asErasure()).getInternalName(), instrumentedType.getInterfaces().asErasures().toInternalNames()); - attributeAppender.apply(classVisitor, instrumentedType, instrumentedType.getSuperType()); + attributeAppender.apply(classVisitor, instrumentedType); for (FieldDescription fieldDescription : instrumentedType.getDeclaredFields()) { fieldPool.target(fieldDescription).apply(classVisitor); } diff --git a/byte-buddy-dep/src/main/java/net/bytebuddy/implementation/attribute/AnnotationAppender.java b/byte-buddy-dep/src/main/java/net/bytebuddy/implementation/attribute/AnnotationAppender.java index 6c0aedd429b..a0c9bff9fb2 100644 --- a/byte-buddy-dep/src/main/java/net/bytebuddy/implementation/attribute/AnnotationAppender.java +++ b/byte-buddy-dep/src/main/java/net/bytebuddy/implementation/attribute/AnnotationAppender.java @@ -2,6 +2,7 @@ import net.bytebuddy.description.annotation.AnnotationDescription; import net.bytebuddy.description.enumeration.EnumerationDescription; +import net.bytebuddy.description.field.FieldDescription; import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.description.type.TypeDescription; import org.objectweb.asm.*; @@ -28,7 +29,7 @@ public interface AnnotationAppender { * @return Usually {@code this} or any other annotation appender capable of writing another annotation to * the specified target. */ - AnnotationAppender append(AnnotationDescription annotation, AnnotationVisibility annotationVisibility); + AnnotationAppender append(AnnotationDescription annotation, AnnotationVisibility annotationVisibility, ValueFilter valueFilter); /** * Determines if an annotation should be written to a specified target and if the annotation should be marked @@ -327,7 +328,16 @@ interface ValueFilter { */ boolean isRelevant(AnnotationDescription annotationDescription, MethodDescription.InDefinedShape methodDescription); - enum Default implements ValueFilter { + interface Factory { + + ValueFilter on(TypeDescription instrumentedType); + + ValueFilter on(FieldDescription fieldDescription); + + ValueFilter on(MethodDescription methodDescription); + } + + enum Default implements ValueFilter, Factory { SKIP_DEFAULTS { @Override @@ -344,6 +354,21 @@ public boolean isRelevant(AnnotationDescription annotationDescription, MethodDes } }; + @Override + public ValueFilter on(TypeDescription instrumentedType) { + return this; + } + + @Override + public ValueFilter on(FieldDescription fieldDescription) { + return this; + } + + @Override + public ValueFilter on(MethodDescription methodDescription) { + return this; + } + @Override public String toString() { return "AnnotationAppender.ValueFilter.Default." + name(); @@ -362,20 +387,13 @@ class Default implements AnnotationAppender { */ private final Target target; - /** - * The value filter to apply for discovering which values of an annotation should be written. - */ - private final ValueFilter valueFilter; - /** * Creates a default annotation appender. * * @param target The target to which annotations are written to. - * @param valueFilter The value filter to apply for discovering which values of an annotation should be written. */ - public Default(Target target, ValueFilter valueFilter) { + public Default(Target target) { this.target = target; - this.valueFilter = valueFilter; } /** @@ -423,9 +441,9 @@ public static void apply(AnnotationVisitor annotationVisitor, TypeDescription va } @Override - public AnnotationAppender append(AnnotationDescription annotation, AnnotationVisibility annotationVisibility) { + public AnnotationAppender append(AnnotationDescription annotation, AnnotationVisibility annotationVisibility, ValueFilter valueFilter) { if (!annotationVisibility.isSuppressed()) { - doAppend(annotation, annotationVisibility.isVisible()); + doAppend(annotation, annotationVisibility.isVisible(), valueFilter); } return this; } @@ -436,25 +454,24 @@ public AnnotationAppender append(AnnotationDescription annotation, AnnotationVis * @param annotation The annotation to be written. * @param visible {@code true} if this annotation should be treated as visible at runtime. */ - private void doAppend(AnnotationDescription annotation, boolean visible) { + private void doAppend(AnnotationDescription annotation, boolean visible, ValueFilter valueFilter) { handle(target.visit(annotation.getAnnotationType().getDescriptor(), visible), annotation, valueFilter); } @Override public boolean equals(Object other) { return this == other || !(other == null || getClass() != other.getClass()) - && target.equals(((Default) other).target) - && valueFilter.equals(((Default) other).valueFilter); + && target.equals(((Default) other).target); } @Override public int hashCode() { - return target.hashCode() + 31 * valueFilter.hashCode(); + return target.hashCode(); } @Override public String toString() { - return "AnnotationAppender.Default{target=" + target + ", valueFilter=" + valueFilter + '}'; + return "AnnotationAppender.Default{target=" + target + '}'; } } } diff --git a/byte-buddy-dep/src/main/java/net/bytebuddy/implementation/attribute/FieldAttributeAppender.java b/byte-buddy-dep/src/main/java/net/bytebuddy/implementation/attribute/FieldAttributeAppender.java index f99e8b0f8dc..c2820cc5fc8 100644 --- a/byte-buddy-dep/src/main/java/net/bytebuddy/implementation/attribute/FieldAttributeAppender.java +++ b/byte-buddy-dep/src/main/java/net/bytebuddy/implementation/attribute/FieldAttributeAppender.java @@ -20,7 +20,7 @@ public interface FieldAttributeAppender { * are written to. * @param fieldDescription The description of the field to which the field visitor belongs to. */ - void apply(FieldVisitor fieldVisitor, FieldDescription fieldDescription); + void apply(FieldVisitor fieldVisitor, FieldDescription fieldDescription, AnnotationAppender.ValueFilter valueFilter); /** * A field attribute appender that does not append any attributes. @@ -38,7 +38,7 @@ public FieldAttributeAppender make(TypeDescription typeDescription) { } @Override - public void apply(FieldVisitor fieldVisitor, FieldDescription fieldDescription) { + public void apply(FieldVisitor fieldVisitor, FieldDescription fieldDescription, AnnotationAppender.ValueFilter valueFilter) { /* do nothing */ } @@ -110,38 +110,15 @@ public String toString() { } } - /** - * Appends an annotation to a field. The visibility of the annotation is determined by the annotation type's - * {@link java.lang.annotation.RetentionPolicy} annotation. - */ - class ForAnnotations implements FieldAttributeAppender, Factory { - - /** - * The value filter to apply for discovering which values of an annotation should be written. - */ - private final AnnotationAppender.ValueFilter valueFilter; + enum ForInstrumentedField implements FieldAttributeAppender, Factory { - /** - * The annotations that this appender appends. - */ - private final List annotations; - - /** - * Creates a new annotation attribute appender for explicit annotation values. All values, including default values, are copied. - * - * @param valueFilter The value filter to apply for discovering which values of an annotation should be written. - * @param annotations The annotations to be appended to the field. - */ - public ForAnnotations(AnnotationAppender.ValueFilter valueFilter, List annotations) { - this.annotations = annotations; - this.valueFilter = valueFilter; - } + INSTANCE; @Override - public void apply(FieldVisitor fieldVisitor, FieldDescription fieldDescription) { - AnnotationAppender annotationAppender = new AnnotationAppender.Default(new AnnotationAppender.Target.OnField(fieldVisitor), valueFilter); - for (AnnotationDescription annotation : annotations) { - annotationAppender.append(annotation, AnnotationAppender.AnnotationVisibility.of(annotation)); + public void apply(FieldVisitor fieldVisitor, FieldDescription fieldDescription, AnnotationAppender.ValueFilter valueFilter) { + AnnotationAppender appender = new AnnotationAppender.Default(new AnnotationAppender.Target.OnField(fieldVisitor)); + for (AnnotationDescription annotation : fieldDescription.getDeclaredAnnotations()) { + appender = appender.append(annotation, AnnotationAppender.AnnotationVisibility.of(annotation), valueFilter); } } @@ -150,40 +127,37 @@ public FieldAttributeAppender make(TypeDescription typeDescription) { return this; } - @Override - public boolean equals(Object other) { - return this == other || !(other == null || getClass() != other.getClass()) - && annotations.equals(((ForAnnotations) other).annotations) - && valueFilter.equals(((ForAnnotations) other).valueFilter); - } - - @Override - public int hashCode() { - return annotations.hashCode() + 31 * valueFilter.hashCode(); - } - @Override public String toString() { - return "FieldAttributeAppender.ForAnnotation{" + - "annotations=" + annotations + - ", valueFilter=" + valueFilter + - '}'; + return "FieldAttributeAppender.ForInstrumentedField." + name(); } } - class ForInstrumentedField implements FieldAttributeAppender, Factory { + /** + * Appends an annotation to a field. The visibility of the annotation is determined by the annotation type's + * {@link java.lang.annotation.RetentionPolicy} annotation. + */ + class Explicit implements FieldAttributeAppender, Factory { - private final AnnotationAppender.ValueFilter valueFilter; + /** + * The annotations that this appender appends. + */ + private final List annotations; - public ForInstrumentedField(AnnotationAppender.ValueFilter valueFilter) { - this.valueFilter = valueFilter; + /** + * Creates a new annotation attribute appender for explicit annotation values. All values, including default values, are copied. + * + * @param annotations The annotations to be appended to the field. + */ + public Explicit(List annotations) { + this.annotations = annotations; } @Override - public void apply(FieldVisitor fieldVisitor, FieldDescription fieldDescription) { - AnnotationAppender annotationAppender = new AnnotationAppender.Default(new AnnotationAppender.Target.OnField(fieldVisitor), valueFilter); - for (AnnotationDescription annotation : fieldDescription.getDeclaredAnnotations()) { - annotationAppender.append(annotation, AnnotationAppender.AnnotationVisibility.of(annotation)); + public void apply(FieldVisitor fieldVisitor, FieldDescription fieldDescription, AnnotationAppender.ValueFilter valueFilter) { + AnnotationAppender appender = new AnnotationAppender.Default(new AnnotationAppender.Target.OnField(fieldVisitor)); + for (AnnotationDescription annotation : annotations) { + appender = appender.append(annotation, AnnotationAppender.AnnotationVisibility.of(annotation), valueFilter); } } @@ -195,18 +169,18 @@ public FieldAttributeAppender make(TypeDescription typeDescription) { @Override public boolean equals(Object other) { return this == other || !(other == null || getClass() != other.getClass()) - && valueFilter.equals(((ForInstrumentedField) other).valueFilter); + && annotations.equals(((Explicit) other).annotations); } @Override public int hashCode() { - return valueFilter.hashCode(); + return annotations.hashCode(); } @Override public String toString() { - return "FieldAttributeAppender.ForInstrumentedField{" + - ", valueFilter=" + valueFilter + + return "FieldAttributeAppender.Explicit{" + + "annotations=" + annotations + '}'; } } @@ -220,7 +194,7 @@ class Compound implements FieldAttributeAppender { /** * The field attribute appenders this appender represents in their application order. */ - private final FieldAttributeAppender[] fieldAttributeAppender; + private final List fieldAttributeAppenders; /** * Creates a new compound field attribute appender. @@ -229,30 +203,34 @@ class Compound implements FieldAttributeAppender { * in the order of their application. */ public Compound(FieldAttributeAppender... fieldAttributeAppender) { - this.fieldAttributeAppender = fieldAttributeAppender; + this(Arrays.asList(fieldAttributeAppender)); + } + + public Compound(List fieldAttributeAppenders) { + this.fieldAttributeAppenders = fieldAttributeAppenders; } @Override - public void apply(FieldVisitor fieldVisitor, FieldDescription fieldDescription) { - for (FieldAttributeAppender fieldAttributeAppender : this.fieldAttributeAppender) { - fieldAttributeAppender.apply(fieldVisitor, fieldDescription); + public void apply(FieldVisitor fieldVisitor, FieldDescription fieldDescription, AnnotationAppender.ValueFilter valueFilter) { + for (FieldAttributeAppender fieldAttributeAppender : fieldAttributeAppenders) { + fieldAttributeAppender.apply(fieldVisitor, fieldDescription, valueFilter); } } @Override public boolean equals(Object other) { return this == other || !(other == null || getClass() != other.getClass()) - && Arrays.equals(fieldAttributeAppender, ((Compound) other).fieldAttributeAppender); + && fieldAttributeAppenders.equals(((Compound) other).fieldAttributeAppenders); } @Override public int hashCode() { - return Arrays.hashCode(fieldAttributeAppender); + return fieldAttributeAppenders.hashCode(); } @Override public String toString() { - return "FieldAttributeAppender.Compound{fieldAttributeAppender=" + Arrays.toString(fieldAttributeAppender) + '}'; + return "FieldAttributeAppender.Compound{fieldAttributeAppenders=" + fieldAttributeAppenders + '}'; } } } diff --git a/byte-buddy-dep/src/main/java/net/bytebuddy/implementation/attribute/MethodAttributeAppender.java b/byte-buddy-dep/src/main/java/net/bytebuddy/implementation/attribute/MethodAttributeAppender.java index 0f0ff5a2167..b0d99d83f5e 100644 --- a/byte-buddy-dep/src/main/java/net/bytebuddy/implementation/attribute/MethodAttributeAppender.java +++ b/byte-buddy-dep/src/main/java/net/bytebuddy/implementation/attribute/MethodAttributeAppender.java @@ -1,15 +1,13 @@ package net.bytebuddy.implementation.attribute; import net.bytebuddy.description.annotation.AnnotationDescription; -import net.bytebuddy.description.annotation.AnnotationList; import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.description.method.ParameterDescription; +import net.bytebuddy.description.method.ParameterList; import net.bytebuddy.description.type.TypeDescription; import org.objectweb.asm.MethodVisitor; -import java.lang.annotation.Annotation; -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -26,7 +24,7 @@ public interface MethodAttributeAppender { * @param methodDescription The description of the method for which the given method visitor creates an * instrumentation for. */ - void apply(MethodVisitor methodVisitor, MethodDescription methodDescription); + void apply(MethodVisitor methodVisitor, MethodDescription methodDescription, AnnotationAppender.ValueFilter valueFilter); /** * A method attribute appender that does not append any attributes. @@ -44,7 +42,7 @@ public MethodAttributeAppender make(TypeDescription typeDescription) { } @Override - public void apply(MethodVisitor methodVisitor, MethodDescription methodDescription) { + public void apply(MethodVisitor methodVisitor, MethodDescription methodDescription, AnnotationAppender.ValueFilter valueFilter) { /* do nothing */ } @@ -76,7 +74,7 @@ class Compound implements Factory { /** * The factories this compound factory represents in their application order. */ - private final Factory[] factory; + private final List factories; /** * Creates a new compound method attribute appender factory. @@ -85,33 +83,36 @@ class Compound implements Factory { * application. */ public Compound(Factory... factory) { - this.factory = factory; + this(Arrays.asList(factory)); + } + + public Compound(List factories) { + this.factories = factories; } @Override public MethodAttributeAppender make(TypeDescription typeDescription) { - MethodAttributeAppender[] methodAttributeAppender = new MethodAttributeAppender[factory.length]; - int index = 0; - for (Factory factory : this.factory) { - methodAttributeAppender[index++] = factory.make(typeDescription); + List methodAttributeAppenders = new ArrayList(factories.size()); + for (Factory factory : factories) { + methodAttributeAppenders.add(factory.make(typeDescription)); } - return new MethodAttributeAppender.Compound(methodAttributeAppender); + return new MethodAttributeAppender.Compound(methodAttributeAppenders); } @Override public boolean equals(Object other) { return this == other || !(other == null || getClass() != other.getClass()) - && Arrays.equals(factory, ((Compound) other).factory); + && factories.equals(((Compound) other).factories); } @Override public int hashCode() { - return Arrays.hashCode(factory); + return factories.hashCode(); } @Override public String toString() { - return "MethodAttributeAppender.Factory.Compound{factory=" + Arrays.toString(factory) + '}'; + return "MethodAttributeAppender.Factory.Compound{factories=" + factories + '}'; } } } @@ -120,113 +121,33 @@ public String toString() { * Implementation of a method attribute appender that writes all annotations of the instrumented method to the * method that is being created. This includes method and parameter annotations. */ - class ForInstrumentedMethod implements Factory { - - /** - * The value filter to apply for discovering which values of an annotation should be written. - */ - private final AnnotationAppender.ValueFilter valueFilter; + enum ForInstrumentedMethod implements MethodAttributeAppender, Factory { - /** - * Creates a new appender for appending the instrumented method's annotation to the created method. - * - * @param valueFilter The value filter to apply for discovering which values of an annotation should be written. - */ - public ForInstrumentedMethod(AnnotationAppender.ValueFilter valueFilter) { - this.valueFilter = valueFilter; - } + INSTANCE; @Override public MethodAttributeAppender make(TypeDescription typeDescription) { - return new Appender(typeDescription, valueFilter); - } - - @Override - public boolean equals(Object other) { - return this == other || !(other == null || getClass() != other.getClass()) - && valueFilter.equals(((ForInstrumentedMethod) other).valueFilter); - } - - @Override - public int hashCode() { - return valueFilter.hashCode(); + return this; } @Override - public String toString() { - return "MethodAttributeAppender.ForInstrumentedMethod{" + - "valueFilter=" + valueFilter + - '}'; - } - - /** - * An appender for an instrumented method that only appends the intercepted method's annotations if it is not already declared by the - * instrumented type, i.e. it is defined explicitly. - */ - protected static class Appender implements MethodAttributeAppender { - - /** - * The instrumented type. - */ - private final TypeDescription instrumentedType; - - /** - * The value filter to apply for discovering which values of an annotation should be written. - */ - private final AnnotationAppender.ValueFilter valueFilter; - - /** - * Creates a new appender. - * - * @param instrumentedType The instrumented type. - * @param valueFilter The value filter to apply for discovering which values of an annotation should be written. - */ - protected Appender(TypeDescription instrumentedType, AnnotationAppender.ValueFilter valueFilter) { - this.instrumentedType = instrumentedType; - this.valueFilter = valueFilter; + public void apply(MethodVisitor methodVisitor, MethodDescription methodDescription, AnnotationAppender.ValueFilter valueFilter) { + AnnotationAppender methodAppender = new AnnotationAppender.Default(new AnnotationAppender.Target.OnMethod(methodVisitor)); + for (AnnotationDescription annotation : methodDescription.getDeclaredAnnotations()) { + methodAppender = methodAppender.append(annotation, AnnotationAppender.AnnotationVisibility.of(annotation), valueFilter); } - - @Override - public void apply(MethodVisitor methodVisitor, MethodDescription methodDescription) { - if (methodDescription.getDeclaringType().equals(instrumentedType)) { - return; - } - AnnotationAppender methodAppender = new AnnotationAppender.Default(new AnnotationAppender.Target.OnMethod(methodVisitor), valueFilter); - for (AnnotationDescription annotation : methodDescription.getDeclaredAnnotations()) { - methodAppender.append(annotation, AnnotationAppender.AnnotationVisibility.of(annotation)); - } - int index = 0; - for (ParameterDescription parameterDescription : methodDescription.getParameters()) { - AnnotationAppender parameterAppender = new AnnotationAppender.Default(new AnnotationAppender.Target.OnMethodParameter(methodVisitor, index++), valueFilter); - for (AnnotationDescription annotation : parameterDescription.getDeclaredAnnotations()) { - parameterAppender.append(annotation, AnnotationAppender.AnnotationVisibility.of(annotation)); - } + int index = 0; + for (ParameterDescription parameterDescription : methodDescription.getParameters()) { + AnnotationAppender parameterAppender = new AnnotationAppender.Default(new AnnotationAppender.Target.OnMethodParameter(methodVisitor, index++)); + for (AnnotationDescription annotation : parameterDescription.getDeclaredAnnotations()) { + parameterAppender = parameterAppender.append(annotation, AnnotationAppender.AnnotationVisibility.of(annotation), valueFilter); } } + } - @Override - public boolean equals(Object other) { - if (this == other) return true; - if (other == null || getClass() != other.getClass()) return false; - Appender appender = (Appender) other; - return instrumentedType.equals(appender.instrumentedType) - && valueFilter.equals(appender.valueFilter); - } - - @Override - public int hashCode() { - int result = instrumentedType.hashCode(); - result = 31 * result + valueFilter.hashCode(); - return result; - } - - @Override - public String toString() { - return "MethodAttributeAppender.ForInstrumentedMethod.Appender{" + - "instrumentedType=" + instrumentedType + - ", valueFilter=" + valueFilter + - '}'; - } + @Override + public String toString() { + return "MethodAttributeAppender.ForInstrumentedMethod." + name(); } } @@ -234,7 +155,7 @@ public String toString() { * Appends an annotation to a method or method parameter. The visibility of the annotation is determined by the * annotation type's {@link java.lang.annotation.RetentionPolicy} annotation. */ - class ForAnnotation implements MethodAttributeAppender, Factory { + class Explicit implements MethodAttributeAppender, Factory { /** * the annotations this method attribute appender is writing to its target. @@ -246,63 +167,39 @@ class ForAnnotation implements MethodAttributeAppender, Factory { */ private final Target target; - /** - * The value filter to apply for discovering which values of an annotation should be written. - */ - private final AnnotationAppender.ValueFilter valueFilter; - - /** - * Creates a new appender for appending an annotation to a method parameter. - * - * @param parameterIndex The index of the parameter to which the annotations should be written. - * @param valueFilter The value filter to apply for discovering which values of an annotation should be written. - * @param annotation The annotations that should be written. - */ - public ForAnnotation(int parameterIndex, AnnotationAppender.ValueFilter valueFilter, Annotation... annotation) { - this(parameterIndex, new AnnotationList.ForLoadedAnnotation(annotation), valueFilter); - } - - /** - * Creates a new appender for appending an annotation to a method parameter. - * - * @param valueFilter The value filter to apply for discovering which values of an annotation should be written. - * @param annotation The annotations that should be written. - */ - public ForAnnotation(AnnotationAppender.ValueFilter valueFilter, Annotation... annotation) { - this(new AnnotationList.ForLoadedAnnotation(annotation), valueFilter); - } - /** * Creates a new appender for appending an annotation to a method. * * @param parameterIndex The index of the parameter to which the annotations should be written. * @param annotations The annotations that should be written. - * @param valueFilter The value filter to apply for discovering which values of an annotation should be written. */ - public ForAnnotation(int parameterIndex, List annotations, AnnotationAppender.ValueFilter valueFilter) { - this.annotations = annotations; - target = new Target.OnMethodParameter(parameterIndex); - this.valueFilter = valueFilter; + public Explicit(int parameterIndex, List annotations) { + this(annotations, new Target.OnMethodParameter(parameterIndex)); } /** * Creates a new appender for appending an annotation to a method. * * @param annotations The annotations that should be written. - * @param valueFilter The value filter to apply for discovering which values of an annotation should be written. */ - public ForAnnotation(List annotations, AnnotationAppender.ValueFilter valueFilter) { + public Explicit(List annotations) { + this(annotations, Target.OnMethod.INSTANCE); + } + + protected Explicit(List annotations, Target target) { this.annotations = annotations; - target = Target.OnMethod.INSTANCE; - this.valueFilter = valueFilter; + this.target = target; } - @Override - public void apply(MethodVisitor methodVisitor, MethodDescription methodDescription) { - AnnotationAppender appender = new AnnotationAppender.Default(target.make(methodVisitor, methodDescription), valueFilter); - for (AnnotationDescription annotation : this.annotations) { - appender.append(annotation, AnnotationAppender.AnnotationVisibility.of(annotation)); + + public static Factory of(MethodDescription methodDescription) { + ParameterList parameters = methodDescription.getParameters(); + List methodAttributeAppenders = new ArrayList(parameters.size() + 1); + methodAttributeAppenders.add(new Explicit(methodDescription.getDeclaredAnnotations())); + for (ParameterDescription parameter : parameters) { + methodAttributeAppenders.add(new Explicit(parameter.getIndex(), parameter.getDeclaredAnnotations())); } + return new Factory.Compound(methodAttributeAppenders); } @Override @@ -310,24 +207,30 @@ public MethodAttributeAppender make(TypeDescription typeDescription) { return this; } + @Override + public void apply(MethodVisitor methodVisitor, MethodDescription methodDescription, AnnotationAppender.ValueFilter valueFilter) { + AnnotationAppender appender = new AnnotationAppender.Default(target.make(methodVisitor, methodDescription)); + for (AnnotationDescription annotation : annotations) { + appender = appender.append(annotation, AnnotationAppender.AnnotationVisibility.of(annotation), valueFilter); + } + } + @Override public boolean equals(Object other) { return this == other || !(other == null || getClass() != other.getClass()) - && annotations.equals(((ForAnnotation) other).annotations) - && valueFilter.equals(((ForAnnotation) other).valueFilter) - && target.equals(((ForAnnotation) other).target); + && annotations.equals(((Explicit) other).annotations) + && target.equals(((Explicit) other).target); } @Override public int hashCode() { - return 31 * (31 * annotations.hashCode() + valueFilter.hashCode()) + target.hashCode(); + return 31 * annotations.hashCode() + target.hashCode(); } @Override public String toString() { return "MethodAttributeAppender.ForAnnotation{" + "annotations=" + annotations + - ", valueFilter=" + valueFilter + ", target=" + target + '}'; } @@ -415,99 +318,6 @@ public String toString() { } } - /** - * Implementation of a method attribute appender that writes all annotations of a given loaded method to the - * method that is being created. This includes method and parameter annotations. In order to being able to do so, - * the target method and the given method must have compatible signatures, i.e. an identical number of method - * parameters. Otherwise, an exception is thrown when this attribute appender is applied on a method. - */ - class ForMethod implements MethodAttributeAppender, Factory { - - /** - * The method of which the annotations are to be copied. - */ - private final MethodDescription methodDescription; - - /** - * The value filter to apply for discovering which values of an annotation should be written. - */ - private final AnnotationAppender.ValueFilter valueFilter; - - /** - * Creates an that copies the annotations of a given constructor to its target. - * - * @param constructor The constructor of which the annotations should be copied. - * @param valueFilter The value filter to apply for discovering which values of an annotation should be written. - */ - public ForMethod(Constructor constructor, AnnotationAppender.ValueFilter valueFilter) { - this(new MethodDescription.ForLoadedConstructor(constructor), valueFilter); - } - - /** - * Creates an that copies the annotations of a given method to its target. - * - * @param method The method of which the annotations should be copied. - * @param valueFilter The value filter to apply for discovering which values of an annotation should be written. - */ - public ForMethod(Method method, AnnotationAppender.ValueFilter valueFilter) { - this(new MethodDescription.ForLoadedMethod(method), valueFilter); - } - - /** - * Creates an that copies the annotations of a given method description to its target. - * - * @param methodDescription The method description of which the annotations should be copied. - * @param valueFilter The value filter to apply for discovering which values of an annotation should be written. - */ - public ForMethod(MethodDescription methodDescription, AnnotationAppender.ValueFilter valueFilter) { - this.methodDescription = methodDescription; - this.valueFilter = valueFilter; - } - - @Override - public void apply(MethodVisitor methodVisitor, MethodDescription methodDescription) { - if (this.methodDescription.getParameters().size() > methodDescription.getParameters().size()) { - throw new IllegalArgumentException(this.methodDescription + " has more parameters than the instrumented method " + methodDescription); - } - AnnotationAppender methodAppender = new AnnotationAppender.Default(new AnnotationAppender.Target.OnMethod(methodVisitor), valueFilter); - for (AnnotationDescription annotation : this.methodDescription.getDeclaredAnnotations()) { - methodAppender.append(annotation, AnnotationAppender.AnnotationVisibility.of(annotation)); - } - int index = 0; - for (ParameterDescription parameterDescription : this.methodDescription.getParameters()) { - AnnotationAppender parameterAppender = new AnnotationAppender.Default(new AnnotationAppender.Target.OnMethodParameter(methodVisitor, index++), valueFilter); - for (AnnotationDescription annotation : parameterDescription.getDeclaredAnnotations()) { - parameterAppender.append(annotation, AnnotationAppender.AnnotationVisibility.of(annotation)); - } - } - } - - @Override - public MethodAttributeAppender make(TypeDescription typeDescription) { - return this; - } - - @Override - public boolean equals(Object other) { - return this == other || !(other == null || getClass() != other.getClass()) - && methodDescription.equals(((ForMethod) other).methodDescription) - && valueFilter.equals(((ForMethod) other).valueFilter); - } - - @Override - public int hashCode() { - return 31 * methodDescription.hashCode() + valueFilter.hashCode(); - } - - @Override - public String toString() { - return "MethodAttributeAppender.ForMethod{" + - "methodDescription=" + methodDescription + - ", valueFilter=" + valueFilter + - '}'; - } - } - /** * A method attribute appender that combines several method attribute appenders to be represented as a single * method attribute appender. @@ -517,7 +327,7 @@ class Compound implements MethodAttributeAppender { /** * The method attribute appenders this compound appender represents in their application order. */ - private final MethodAttributeAppender[] methodAttributeAppender; + private final List methodAttributeAppenders; /** * Creates a new compound method attribute appender. @@ -526,30 +336,34 @@ class Compound implements MethodAttributeAppender { * in the order of their application. */ public Compound(MethodAttributeAppender... methodAttributeAppender) { - this.methodAttributeAppender = methodAttributeAppender; + this(Arrays.asList(methodAttributeAppender)); + } + + public Compound(List methodAttributeAppenders) { + this.methodAttributeAppenders = methodAttributeAppenders; } @Override - public void apply(MethodVisitor methodVisitor, MethodDescription methodDescription) { - for (MethodAttributeAppender methodAttributeAppender : this.methodAttributeAppender) { - methodAttributeAppender.apply(methodVisitor, methodDescription); + public void apply(MethodVisitor methodVisitor, MethodDescription methodDescription, AnnotationAppender.ValueFilter valueFilter) { + for (MethodAttributeAppender methodAttributeAppender : methodAttributeAppenders) { + methodAttributeAppender.apply(methodVisitor, methodDescription, valueFilter); } } @Override public boolean equals(Object other) { return this == other || !(other == null || getClass() != other.getClass()) - && Arrays.equals(methodAttributeAppender, ((Compound) other).methodAttributeAppender); + && methodAttributeAppenders.equals(((Compound) other).methodAttributeAppenders); } @Override public int hashCode() { - return Arrays.hashCode(methodAttributeAppender); + return methodAttributeAppenders.hashCode(); } @Override public String toString() { - return "MethodAttributeAppender.Compound{methodAttributeAppender=" + Arrays.toString(methodAttributeAppender) + '}'; + return "MethodAttributeAppender.Compound{methodAttributeAppenders=" + methodAttributeAppenders + '}'; } } } diff --git a/byte-buddy-dep/src/main/java/net/bytebuddy/implementation/attribute/TypeAttributeAppender.java b/byte-buddy-dep/src/main/java/net/bytebuddy/implementation/attribute/TypeAttributeAppender.java index 465a5e3dc00..f9154eea18b 100644 --- a/byte-buddy-dep/src/main/java/net/bytebuddy/implementation/attribute/TypeAttributeAppender.java +++ b/byte-buddy-dep/src/main/java/net/bytebuddy/implementation/attribute/TypeAttributeAppender.java @@ -17,10 +17,8 @@ public interface TypeAttributeAppender { * * @param classVisitor The class visitor to which the annotations of this visitor should be written to. * @param instrumentedType A description of the instrumented type that is target of the ongoing instrumentation. - * @param targetType The target type of the instrumentation, i.e. the super class type for a super class creation - * or the type being redefined. */ - void apply(ClassVisitor classVisitor, TypeDescription instrumentedType, TypeDescription.Generic targetType); + void apply(ClassVisitor classVisitor, TypeDescription instrumentedType, AnnotationAppender.ValueFilter valueFilter); /** * A type attribute appender that does not append any attributes. @@ -33,7 +31,7 @@ enum NoOp implements TypeAttributeAppender { INSTANCE; @Override - public void apply(ClassVisitor classVisitor, TypeDescription instrumentedType, TypeDescription.Generic targetType) { + public void apply(ClassVisitor classVisitor, TypeDescription instrumentedType, AnnotationAppender.ValueFilter valueFilter) { /* do nothing */ } @@ -48,111 +46,21 @@ public String toString() { * instrumented type this type attribute appender is applied onto. The visibility for the annotation * will be inferred from the annotations' {@link java.lang.annotation.RetentionPolicy}. */ - class ForInstrumentedType implements TypeAttributeAppender { + enum ForInstrumentedType implements TypeAttributeAppender { - /** - * The value filter to apply for discovering which values of an annotation should be written. - */ - private final AnnotationAppender.ValueFilter valueFilter; - - /** - * Creates an attribute appender that copies the super type's annotations to the instrumented type. - * - * @param valueFilter The value filter to apply for discovering which values of an annotation should be written. - */ - public ForInstrumentedType(AnnotationAppender.ValueFilter valueFilter) { - this.valueFilter = valueFilter; - } - - @Override - public void apply(ClassVisitor classVisitor, TypeDescription instrumentedType, TypeDescription.Generic targetType) { - if (!instrumentedType.getSuperType().equals(targetType)) { - return; // Takes into account that types can be renamed. This check is more reliable. - } - AnnotationAppender annotationAppender = new AnnotationAppender.Default(new AnnotationAppender.Target.OnType(classVisitor), valueFilter); - for (AnnotationDescription annotation : targetType.asErasure().getDeclaredAnnotations()) { - annotationAppender.append(annotation, AnnotationAppender.AnnotationVisibility.of(annotation)); - } - } - - @Override - public boolean equals(Object other) { - return this == other || !(other == null || getClass() != other.getClass()) && valueFilter.equals(((ForInstrumentedType) other).valueFilter); - } - - @Override - public int hashCode() { - return valueFilter.hashCode(); - } - - @Override - public String toString() { - return "TypeAttributeAppender.ForInstrumentedType{valueFilter=" + valueFilter + "}"; - } - } - - /** - * Writes all annotations that are declared for a given Java type to the target type. - */ - class ForType implements TypeAttributeAppender { - - /** - * The class of which the declared annotations are to be copied. - */ - private final TypeDescription typeDescription; - - /** - * The value filter to apply for discovering which values of an annotation should be written. - */ - private final AnnotationAppender.ValueFilter valueFilter; - - /** - * Creates a new attribute appender that writes all annotations declared for the given loaded type. - * - * @param type The loaded type. - * @param valueFilter The value filter to apply for discovering which values of an annotation should be written. - */ - public ForType(Class type, AnnotationAppender.ValueFilter valueFilter) { - this(new TypeDescription.ForLoadedType(type), valueFilter); - } - - /** - * Creates a new attribute appender that writes all annotations declared for the given type description. - * - * @param typeDescription The type description. - * @param valueFilter The value filter to apply for discovering which values of an annotation should be written. - */ - public ForType(TypeDescription typeDescription, AnnotationAppender.ValueFilter valueFilter) { - this.typeDescription = typeDescription; - this.valueFilter = valueFilter; - } + INSTANCE; @Override - public void apply(ClassVisitor classVisitor, TypeDescription instrumentedType, TypeDescription.Generic targetType) { - AnnotationAppender annotationAppender = new AnnotationAppender.Default(new AnnotationAppender.Target.OnType(classVisitor), valueFilter); - for (AnnotationDescription annotation : this.typeDescription.getDeclaredAnnotations()) { - annotationAppender.append(annotation, AnnotationAppender.AnnotationVisibility.of(annotation)); + public void apply(ClassVisitor classVisitor, TypeDescription instrumentedType, AnnotationAppender.ValueFilter valueFilter) { + AnnotationAppender appender = new AnnotationAppender.Default(new AnnotationAppender.Target.OnType(classVisitor)); + for (AnnotationDescription annotation : instrumentedType.asErasure().getDeclaredAnnotations()) { + appender = appender.append(annotation, AnnotationAppender.AnnotationVisibility.of(annotation), valueFilter); } } - @Override - public boolean equals(Object other) { - return this == other || !(other == null || getClass() != other.getClass()) - && typeDescription.equals(((ForType) other).typeDescription) - && valueFilter.equals(((ForType) other).valueFilter); - } - - @Override - public int hashCode() { - return typeDescription.hashCode() + 31 * valueFilter.hashCode(); - } - @Override public String toString() { - return "TypeAttributeAppender.ForType{" + - "typeDescription=" + typeDescription + - ", valueFilter=" + valueFilter + - '}'; + return "TypeAttributeAppender.ForInstrumentedType." + name(); } } @@ -160,54 +68,46 @@ public String toString() { * An attribute appender that appends a single annotation to a given type. The visibility for the annotation * will be inferred from the annotation's {@link java.lang.annotation.RetentionPolicy}. */ - class ForAnnotation implements TypeAttributeAppender { + class Explicit implements TypeAttributeAppender { /** * The annotations to write to the given type. */ private final List annotations; - /** - * The value filter to apply for discovering which values of an annotation should be written. - */ - private final AnnotationAppender.ValueFilter valueFilter; - /** * Creates a new annotation attribute appender for explicit annotation values. * * @param annotations The annotations to write to the given type. * @param valueFilter The value filter to apply for discovering which values of an annotation should be written. */ - public ForAnnotation(List annotations, AnnotationAppender.ValueFilter valueFilter) { + public Explicit(List annotations) { this.annotations = annotations; - this.valueFilter = valueFilter; } @Override - public void apply(ClassVisitor classVisitor, TypeDescription instrumentedType, TypeDescription.Generic targetType) { - AnnotationAppender annotationAppender = new AnnotationAppender.Default(new AnnotationAppender.Target.OnType(classVisitor), valueFilter); + public void apply(ClassVisitor classVisitor, TypeDescription instrumentedType, AnnotationAppender.ValueFilter valueFilter) { + AnnotationAppender appender = new AnnotationAppender.Default(new AnnotationAppender.Target.OnType(classVisitor)); for (AnnotationDescription annotation : annotations) { - annotationAppender.append(annotation, AnnotationAppender.AnnotationVisibility.of(annotation)); + appender = appender.append(annotation, AnnotationAppender.AnnotationVisibility.of(annotation), valueFilter); } } @Override public boolean equals(Object other) { return this == other || !(other == null || getClass() != other.getClass()) - && annotations.equals(((ForAnnotation) other).annotations) - && valueFilter.equals(((ForAnnotation) other).valueFilter); + && annotations.equals(((Explicit) other).annotations); } @Override public int hashCode() { - return annotations.hashCode() + 31 * valueFilter.hashCode(); + return annotations.hashCode(); } @Override public String toString() { - return "TypeAttributeAppender.ForAnnotation{" + + return "TypeAttributeAppender.Explicit{" + "annotations=" + annotations + - ", valueFilter=" + valueFilter + '}'; } } @@ -220,7 +120,7 @@ class Compound implements TypeAttributeAppender { /** * The type attribute appenders this compound appender represents in their application order. */ - private final TypeAttributeAppender[] typeAttributeAppender; + private final List typeAttributeAppenders; /** * Creates a new compound attribute appender. @@ -228,30 +128,34 @@ class Compound implements TypeAttributeAppender { * @param typeAttributeAppender The type attribute appenders to concatenate in the order of their application. */ public Compound(TypeAttributeAppender... typeAttributeAppender) { - this.typeAttributeAppender = typeAttributeAppender; + this(Arrays.asList(typeAttributeAppender)); + } + + public Compound(List typeAttributeAppenders) { + this.typeAttributeAppenders = typeAttributeAppenders; } @Override - public void apply(ClassVisitor classVisitor, TypeDescription instrumentedType, TypeDescription.Generic targetType) { - for (TypeAttributeAppender typeAttributeAppender : this.typeAttributeAppender) { - typeAttributeAppender.apply(classVisitor, instrumentedType, targetType); + public void apply(ClassVisitor classVisitor, TypeDescription instrumentedType, AnnotationAppender.ValueFilter valueFilter) { + for (TypeAttributeAppender typeAttributeAppender : typeAttributeAppenders) { + typeAttributeAppender.apply(classVisitor, instrumentedType, valueFilter); } } @Override public boolean equals(Object other) { return this == other || !(other == null || getClass() != other.getClass()) - && Arrays.equals(typeAttributeAppender, ((Compound) other).typeAttributeAppender); + && typeAttributeAppenders.equals(((Compound) other).typeAttributeAppenders); } @Override public int hashCode() { - return Arrays.hashCode(typeAttributeAppender); + return typeAttributeAppenders.hashCode(); } @Override public String toString() { - return "TypeAttributeAppender.Compound{typeAttributeAppender=" + Arrays.toString(typeAttributeAppender) + '}'; + return "TypeAttributeAppender.Compound{typeAttributeAppenders=" + typeAttributeAppenders + '}'; } } } diff --git a/byte-buddy-dep/src/test/java/net/bytebuddy/implementation/attribute/MethodAttributeAppenderForAnnotationTest.java b/byte-buddy-dep/src/test/java/net/bytebuddy/implementation/attribute/MethodAttributeAppenderExplicitTest.java similarity index 74% rename from byte-buddy-dep/src/test/java/net/bytebuddy/implementation/attribute/MethodAttributeAppenderForAnnotationTest.java rename to byte-buddy-dep/src/test/java/net/bytebuddy/implementation/attribute/MethodAttributeAppenderExplicitTest.java index 864e9fc1604..d98e5342bac 100644 --- a/byte-buddy-dep/src/test/java/net/bytebuddy/implementation/attribute/MethodAttributeAppenderForAnnotationTest.java +++ b/byte-buddy-dep/src/test/java/net/bytebuddy/implementation/attribute/MethodAttributeAppenderExplicitTest.java @@ -14,7 +14,7 @@ import static org.mockito.Mockito.*; -public class MethodAttributeAppenderForAnnotationTest extends AbstractMethodAttributeAppenderTest { +public class MethodAttributeAppenderExplicitTest extends AbstractMethodAttributeAppenderTest { private static final int PARAMETER_INDEX = 0; @@ -29,7 +29,7 @@ public void setUp() throws Exception { @Test public void testAnnotationAppenderNoRetention() throws Exception { - new MethodAttributeAppender.ForAnnotation(new AnnotationList.ForLoadedAnnotation(new Qux.Instance()), valueFilter) + new MethodAttributeAppender.Explicit(new AnnotationList.ForLoadedAnnotation(new Qux.Instance()), valueFilter) .apply(methodVisitor, methodDescription); verifyZeroInteractions(methodVisitor); verifyZeroInteractions(methodDescription); @@ -37,7 +37,7 @@ public void testAnnotationAppenderNoRetention() throws Exception { @Test public void testAnnotationAppenderRuntimeRetention() throws Exception { - new MethodAttributeAppender.ForAnnotation(new AnnotationList.ForLoadedAnnotation(new Baz.Instance()), valueFilter) + new MethodAttributeAppender.Explicit(new AnnotationList.ForLoadedAnnotation(new Baz.Instance()), valueFilter) .apply(methodVisitor, methodDescription); verify(methodVisitor).visitAnnotation(Type.getDescriptor(Baz.class), true); verifyNoMoreInteractions(methodVisitor); @@ -46,7 +46,7 @@ public void testAnnotationAppenderRuntimeRetention() throws Exception { @Test public void testAnnotationAppenderByteCodeRetention() throws Exception { - new MethodAttributeAppender.ForAnnotation(new AnnotationList.ForLoadedAnnotation(new QuxBaz.Instance()), valueFilter) + new MethodAttributeAppender.Explicit(new AnnotationList.ForLoadedAnnotation(new QuxBaz.Instance()), valueFilter) .apply(methodVisitor, methodDescription); verify(methodVisitor).visitAnnotation(Type.getDescriptor(QuxBaz.class), false); verifyNoMoreInteractions(methodVisitor); @@ -55,7 +55,7 @@ public void testAnnotationAppenderByteCodeRetention() throws Exception { @Test public void testAnnotationAppenderForParameterNoRetention() throws Exception { - new MethodAttributeAppender.ForAnnotation(PARAMETER_INDEX, new AnnotationList.ForLoadedAnnotation(new Qux.Instance()), valueFilter) + new MethodAttributeAppender.Explicit(PARAMETER_INDEX, new AnnotationList.ForLoadedAnnotation(new Qux.Instance()), valueFilter) .apply(methodVisitor, methodDescription); verifyZeroInteractions(methodVisitor); verify(methodDescription).getParameters(); @@ -64,7 +64,7 @@ public void testAnnotationAppenderForParameterNoRetention() throws Exception { @Test public void testAnnotationAppenderForParameterRuntimeRetention() throws Exception { - new MethodAttributeAppender.ForAnnotation(PARAMETER_INDEX, new AnnotationList.ForLoadedAnnotation(new Baz.Instance()), valueFilter) + new MethodAttributeAppender.Explicit(PARAMETER_INDEX, new AnnotationList.ForLoadedAnnotation(new Baz.Instance()), valueFilter) .apply(methodVisitor, methodDescription); verify(methodVisitor).visitParameterAnnotation(PARAMETER_INDEX, Type.getDescriptor(Baz.class), true); verifyNoMoreInteractions(methodVisitor); @@ -74,7 +74,7 @@ public void testAnnotationAppenderForParameterRuntimeRetention() throws Exceptio @Test public void testAnnotationAppenderForParameterByteCodeRetention() throws Exception { - new MethodAttributeAppender.ForAnnotation(PARAMETER_INDEX, new AnnotationList.ForLoadedAnnotation(new QuxBaz.Instance()), valueFilter) + new MethodAttributeAppender.Explicit(PARAMETER_INDEX, new AnnotationList.ForLoadedAnnotation(new QuxBaz.Instance()), valueFilter) .apply(methodVisitor, methodDescription); verify(methodVisitor).visitParameterAnnotation(PARAMETER_INDEX, Type.getDescriptor(QuxBaz.class), false); verifyNoMoreInteractions(methodVisitor); @@ -84,20 +84,20 @@ public void testAnnotationAppenderForParameterByteCodeRetention() throws Excepti @Test(expected = IllegalArgumentException.class) public void testAnnotationAppenderNotEnoughParameters() throws Exception { - new MethodAttributeAppender.ForAnnotation(PARAMETER_INDEX + 1, new AnnotationList.ForLoadedAnnotation(new Baz.Instance()), valueFilter) + new MethodAttributeAppender.Explicit(PARAMETER_INDEX + 1, new AnnotationList.ForLoadedAnnotation(new Baz.Instance()), valueFilter) .apply(methodVisitor, methodDescription); } @Test public void testObjectProperties() throws Exception { - ObjectPropertyAssertion.of(MethodAttributeAppender.ForAnnotation.class).create(new ObjectPropertyAssertion.Creator() { + ObjectPropertyAssertion.of(MethodAttributeAppender.Explicit.class).create(new ObjectPropertyAssertion.Creator() { @Override public Annotation create() { return new SimpleAnnotation.Instance(RandomString.make()); } }).apply(); - ObjectPropertyAssertion.of(MethodAttributeAppender.ForAnnotation.Target.OnMethod.class).apply(); - ObjectPropertyAssertion.of(MethodAttributeAppender.ForAnnotation.Target.OnMethodParameter.class).apply(); + ObjectPropertyAssertion.of(MethodAttributeAppender.Explicit.Target.OnMethod.class).apply(); + ObjectPropertyAssertion.of(MethodAttributeAppender.Explicit.Target.OnMethodParameter.class).apply(); } public @interface SimpleAnnotation { diff --git a/byte-buddy-dep/src/test/java/net/bytebuddy/implementation/attribute/TypeAttributeAppenderForAnnotationTest.java b/byte-buddy-dep/src/test/java/net/bytebuddy/implementation/attribute/TypeAttributeAppenderExplicitTest.java similarity index 96% rename from byte-buddy-dep/src/test/java/net/bytebuddy/implementation/attribute/TypeAttributeAppenderForAnnotationTest.java rename to byte-buddy-dep/src/test/java/net/bytebuddy/implementation/attribute/TypeAttributeAppenderExplicitTest.java index 4828855233a..a6ae5a8f360 100644 --- a/byte-buddy-dep/src/test/java/net/bytebuddy/implementation/attribute/TypeAttributeAppenderForAnnotationTest.java +++ b/byte-buddy-dep/src/test/java/net/bytebuddy/implementation/attribute/TypeAttributeAppenderExplicitTest.java @@ -9,7 +9,7 @@ import static org.mockito.Mockito.*; -public class TypeAttributeAppenderForAnnotationTest extends AbstractTypeAttributeAppenderTest { +public class TypeAttributeAppenderExplicitTest extends AbstractTypeAttributeAppenderTest { @Test public void testAnnotationAppenderNoRetention() throws Exception {