Skip to content

Commit

Permalink
Refactored field record.
Browse files Browse the repository at this point in the history
  • Loading branch information
raphw committed Jan 3, 2016
1 parent 8a20aa8 commit 46f240e
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 48 deletions.
15 changes: 11 additions & 4 deletions byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/Builder.java
Expand Up @@ -162,6 +162,8 @@ interface Valuable<U> extends FieldDefinition<U> {
FieldDefinition.Optional<U> value(double value);

FieldDefinition.Optional<U> value(String value);

FieldDefinition.Optional<U> withoutValue();
}

interface Optional<U> extends FieldDefinition<U>, Builder<U> {
Expand Down Expand Up @@ -233,6 +235,11 @@ protected FieldDefinition.Optional<V> defaultValue(Object defaultValue) {
return materialize(fieldAttributeAppenderFactory, transformer, defaultValue);
}

@Override
public Optional<V> withoutValue() {
return materialize(fieldAttributeAppenderFactory, transformer, FieldDescription.NO_DEFAULT_VALUE);
}

protected abstract FieldDefinition.Optional<V> materialize(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
Transformer<FieldDescription> transformer,
Object defaultValue);
Expand Down Expand Up @@ -1185,8 +1192,8 @@ protected Builder<U> materialize() {

@Override
protected Optional<U> materialize(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
Transformer<FieldDescription> transformer,
Object defaultValue) {
Transformer<FieldDescription> transformer,
Object defaultValue) {
return new FieldDefinitionAdapter(fieldAttributeAppenderFactory, transformer, defaultValue, token);
}
}
Expand Down Expand Up @@ -1226,8 +1233,8 @@ protected Builder<U> materialize() {

@Override
protected Optional<U> materialize(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
Transformer<FieldDescription> transformer,
Object defaultValue) {
Transformer<FieldDescription> transformer,
Object defaultValue) {
return new FieldMatchAdapter(fieldAttributeAppenderFactory, transformer, defaultValue, matcher);
}
}
Expand Down
Expand Up @@ -74,20 +74,16 @@ interface FieldPool {
*/
interface Record {

FieldDescription getField();

/**
* Returns the field attribute appender for a given field.
*
* @return The attribute appender to be applied on the given field.
*/
FieldAttributeAppender getFieldAppender();

/**
* Returns the default value for the field that is represented by this entry. This value might be
* {@code null} if no such value is set.
*
* @return The default value for the field that is represented by this entry.
*/
Object getDefaultValue();
Object resolveDefault(Object defaultValue);

/**
* Writes this entry to a given class visitor.
Expand All @@ -96,6 +92,8 @@ interface Record {
*/
void apply(ClassVisitor classVisitor);

void apply(FieldVisitor fieldVisitor);

/**
* A record for a simple field without a default value where all of the field's declared annotations are appended.
*/
Expand All @@ -115,14 +113,19 @@ public ForSimpleField(FieldDescription fieldDescription) {
this.fieldDescription = fieldDescription;
}

@Override
public FieldDescription getField() {
return fieldDescription;
}

@Override
public FieldAttributeAppender getFieldAppender() {
return new FieldAttributeAppender.ForField(fieldDescription, AnnotationAppender.ValueFilter.AppendDefaults.INSTANCE);
}

@Override
public Object getDefaultValue() {
return FieldDescription.NO_DEFAULT_VALUE;
public Object resolveDefault(Object defaultValue) {
return defaultValue;
}

@Override
Expand All @@ -136,6 +139,11 @@ public void apply(ClassVisitor classVisitor) {
fieldVisitor.visitEnd();
}

@Override
public void apply(FieldVisitor fieldVisitor) {
/* do nothing */
}

@Override
public boolean equals(Object other) {
if (this == other) return true;
Expand Down Expand Up @@ -190,14 +198,19 @@ public ForRichField(FieldAttributeAppender attributeAppender, Object defaultValu
this.fieldDescription = fieldDescription;
}

@Override
public FieldDescription getField() {
return fieldDescription;
}

@Override
public FieldAttributeAppender getFieldAppender() {
return attributeAppender;
}

@Override
public Object getDefaultValue() {
return defaultValue;
public Object resolveDefault(Object defaultValue) {
return this.defaultValue;
}

@Override
Expand All @@ -206,11 +219,16 @@ public void apply(ClassVisitor classVisitor) {
fieldDescription.getInternalName(),
fieldDescription.getDescriptor(),
fieldDescription.getGenericSignature(),
getDefaultValue());
resolveDefault(FieldDescription.NO_DEFAULT_VALUE));
attributeAppender.apply(fieldVisitor, fieldDescription);
fieldVisitor.visitEnd();
}

@Override
public void apply(FieldVisitor fieldVisitor) {
attributeAppender.apply(fieldVisitor, fieldDescription);
}

@Override
public boolean equals(Object other) {
if (this == other) return true;
Expand Down Expand Up @@ -274,7 +292,7 @@ interface Record {
*
* @return The implemented method.
*/
MethodDescription getImplementedMethod();
MethodDescription getMethod();

/**
* Prepends the given method appender to this entry.
Expand Down Expand Up @@ -400,7 +418,7 @@ public void applyHead(MethodVisitor methodVisitor) {
}

@Override
public MethodDescription getImplementedMethod() {
public MethodDescription getMethod() {
throw new IllegalStateException("A method that is not defined cannot be extracted");
}

Expand All @@ -427,12 +445,12 @@ abstract class ForDefinedMethod implements Record {

@Override
public void apply(ClassVisitor classVisitor, Implementation.Context implementationContext) {
MethodVisitor methodVisitor = classVisitor.visitMethod(getImplementedMethod().getAdjustedModifiers(getSort().isImplemented()),
getImplementedMethod().getInternalName(),
getImplementedMethod().getDescriptor(),
getImplementedMethod().getGenericSignature(),
getImplementedMethod().getExceptionTypes().asErasures().toInternalNames());
ParameterList<?> parameterList = getImplementedMethod().getParameters();
MethodVisitor methodVisitor = classVisitor.visitMethod(getMethod().getAdjustedModifiers(getSort().isImplemented()),
getMethod().getInternalName(),
getMethod().getDescriptor(),
getMethod().getGenericSignature(),
getMethod().getExceptionTypes().asErasures().toInternalNames());
ParameterList<?> parameterList = getMethod().getParameters();
if (parameterList.hasExplicitMetaData()) {
for (ParameterDescription parameterDescription : parameterList) {
methodVisitor.visitParameter(parameterDescription.getName(), parameterDescription.getModifiers());
Expand Down Expand Up @@ -487,7 +505,7 @@ public WithBody(MethodDescription methodDescription, ByteCodeAppender byteCodeAp
}

@Override
public MethodDescription getImplementedMethod() {
public MethodDescription getMethod() {
return methodDescription;
}

Expand Down Expand Up @@ -569,7 +587,7 @@ public WithoutBody(MethodDescription methodDescription, MethodAttributeAppender
}

@Override
public MethodDescription getImplementedMethod() {
public MethodDescription getMethod() {
return methodDescription;
}

Expand Down Expand Up @@ -654,7 +672,7 @@ public WithAnnotationDefaultValue(MethodDescription methodDescription,
}

@Override
public MethodDescription getImplementedMethod() {
public MethodDescription getMethod() {
return methodDescription;
}

Expand Down Expand Up @@ -773,7 +791,7 @@ public static Record of(TypeDescription instrumentedType, MethodDescription brid
}

@Override
public MethodDescription getImplementedMethod() {
public MethodDescription getMethod() {
return visibilityBridge;
}

Expand Down Expand Up @@ -983,7 +1001,7 @@ public Sort getSort() {
}

@Override
public MethodDescription getImplementedMethod() {
public MethodDescription getMethod() {
return bridgeTarget;
}

Expand Down Expand Up @@ -2835,8 +2853,19 @@ public FieldVisitor visitField(int modifiers,
String descriptor,
String genericSignature,
Object defaultValue) {
declaredFields.remove(internalName); // Ignore in favor of the class file definition.
return super.visitField(modifiers, internalName, descriptor, genericSignature, defaultValue);
FieldDescription fieldDescription = declaredFields.remove(internalName);
return fieldDescription == null
? super.visitField(modifiers, internalName, descriptor, genericSignature, defaultValue)
: redefine(fieldDescription, defaultValue);
}

protected FieldVisitor redefine(FieldDescription fieldDescription, Object defaultValue) {
FieldPool.Record record = fieldPool.target(fieldDescription);
return new AttributeObtainingFieldVisitor(super.visitField(fieldDescription.getModifiers(),
fieldDescription.getInternalName(),
fieldDescription.getDescriptor(),
fieldDescription.getGenericSignature(),
record.resolveDefault(defaultValue)), record);
}

@Override
Expand Down Expand Up @@ -2882,7 +2911,7 @@ protected MethodVisitor redefine(MethodDescription methodDescription, boolean ab
methodDescription.getGenericSignature(),
methodDescription.getExceptionTypes().asErasures().toInternalNames());
}
MethodDescription implementedMethod = record.getImplementedMethod();
MethodDescription implementedMethod = record.getMethod();
MethodVisitor methodVisitor = super.visitMethod(implementedMethod.getAdjustedModifiers(record.getSort().isImplemented()),
implementedMethod.getInternalName(),
implementedMethod.getDescriptor(),
Expand Down Expand Up @@ -2989,6 +3018,22 @@ public String toString() {
}
}

protected class AttributeObtainingFieldVisitor extends FieldVisitor {

private final FieldPool.Record record;

public AttributeObtainingFieldVisitor(FieldVisitor fieldVisitor, FieldPool.Record record) {
super(Opcodes.ASM5, fieldVisitor);
this.record = record;
}

@Override
public void visitEnd() {
record.apply(fv);
super.visitEnd();
}
}

/**
* A method visitor that obtains all attributes and annotations of a method that is found in the
* class file but discards all code.
Expand Down
Expand Up @@ -1270,7 +1270,7 @@ protected AbstractDelegationRecord(MethodDescription methodDescription) {
}

@Override
public MethodDescription getImplementedMethod() {
public MethodDescription getMethod() {
return methodDescription;
}

Expand All @@ -1287,7 +1287,7 @@ public void applyHead(MethodVisitor methodVisitor) {
@Override
public void applyBody(MethodVisitor methodVisitor, Context implementationContext) {
methodVisitor.visitCode();
Size size = apply(methodVisitor, implementationContext, getImplementedMethod());
Size size = apply(methodVisitor, implementationContext, getMethod());
methodVisitor.visitMaxs(size.getOperandStackSize(), size.getLocalVariableSize());
}

Expand Down
Expand Up @@ -12,6 +12,7 @@

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Mockito.mock;

public class FieldRegistryCompiledNoOpTest {

Expand All @@ -21,10 +22,13 @@ public class FieldRegistryCompiledNoOpTest {
@Mock
private FieldDescription fieldDescription;

@Mock
private Object defaultValue;

@Test
public void testReturnsNullDefaultValue() throws Exception {
TypeWriter.FieldPool.Record record = FieldRegistry.Compiled.NoOp.INSTANCE.target(fieldDescription);
assertThat(record.getDefaultValue(), is(FieldDescription.NO_DEFAULT_VALUE));
assertThat(record.resolveDefault(defaultValue), is(defaultValue));
}

@Test
Expand Down
Expand Up @@ -36,7 +36,7 @@ public class FieldRegistryDefaultTest {
private FieldDescription.Token knownFieldToken;

@Mock
private Object defaultValue;
private Object defaultValue, otherDefaultValue;

@Before
public void setUp() throws Exception {
Expand All @@ -49,7 +49,7 @@ public void testNoFieldsRegistered() throws Exception {
TypeWriter.FieldPool.Record record = new FieldRegistry.Default()
.compile(instrumentedType)
.target(unknownField);
assertThat(record.getDefaultValue(), is(FieldDescription.NO_DEFAULT_VALUE));
assertThat(record.resolveDefault(defaultValue), is(defaultValue));
assertThat(record.getFieldAppender(), is((FieldAttributeAppender) new FieldAttributeAppender.ForField(unknownField,
AnnotationAppender.ValueFilter.AppendDefaults.INSTANCE)));
}
Expand All @@ -60,8 +60,8 @@ public void testKnownFieldRegistered() throws Exception {
.include(knownFieldToken, distinctFactory, defaultValue)
.compile(instrumentedType);
assertThat(fieldPool.target(knownField).getFieldAppender(), is(distinct));
assertThat(fieldPool.target(knownField).getDefaultValue(), is(defaultValue));
assertThat(fieldPool.target(unknownField).getDefaultValue(), is(FieldDescription.NO_DEFAULT_VALUE));
assertThat(fieldPool.target(knownField).resolveDefault(otherDefaultValue), is(defaultValue));
assertThat(fieldPool.target(unknownField).resolveDefault(otherDefaultValue), is(otherDefaultValue));
assertThat(fieldPool.target(unknownField).getFieldAppender(), is((FieldAttributeAppender) new FieldAttributeAppender.ForField(unknownField,
AnnotationAppender.ValueFilter.AppendDefaults.INSTANCE)));
}
Expand Down

0 comments on commit 46f240e

Please sign in to comment.