Skip to content

Commit

Permalink
Added additional documentation.
Browse files Browse the repository at this point in the history
  • Loading branch information
raphw committed Jan 4, 2016
1 parent 01bbc32 commit 1d3b0cd
Show file tree
Hide file tree
Showing 8 changed files with 264 additions and 50 deletions.
Expand Up @@ -1395,7 +1395,10 @@ public Optional<U> annotateField(Collection<? extends AnnotationDescription> ann
@Override @Override
protected Builder<U> materialize() { protected Builder<U> materialize() {
return Builder.AbstractBase.Adapter.this.materialize(instrumentedType.withField(token), return Builder.AbstractBase.Adapter.this.materialize(instrumentedType.withField(token),
fieldRegistry.prepend(new LatentMatcher.ForFieldToken(token), fieldAttributeAppenderFactory, defaultValue, FieldTransformer.NoOp.INSTANCE), fieldRegistry.prepend(new LatentMatcher.ForFieldToken(token),
fieldAttributeAppenderFactory,
defaultValue,
FieldTransformer.NoOp.INSTANCE),
methodRegistry, methodRegistry,
typeAttributeAppender, typeAttributeAppender,
asmVisitorWrapper, asmVisitorWrapper,
Expand Down Expand Up @@ -1774,7 +1777,10 @@ protected MethodDefinition<U> materialize(MethodRegistry.Handler handler, Method
protected Builder<U> materialize() { protected Builder<U> materialize() {
return Builder.AbstractBase.Adapter.this.materialize(instrumentedType.withMethod(token), return Builder.AbstractBase.Adapter.this.materialize(instrumentedType.withMethod(token),
fieldRegistry, fieldRegistry,
methodRegistry.prepend(new LatentMatcher.ForMethodToken(token), handler, methodAttributeAppenderFactory, methodTransformer), methodRegistry.prepend(new LatentMatcher.ForMethodToken(token),
handler,
methodAttributeAppenderFactory,
methodTransformer),
typeAttributeAppender, typeAttributeAppender,
asmVisitorWrapper, asmVisitorWrapper,
classFileVersion, classFileVersion,
Expand Down

Large diffs are not rendered by default.

Expand Up @@ -6,7 +6,6 @@
import net.bytebuddy.dynamic.MethodTransformer; import net.bytebuddy.dynamic.MethodTransformer;
import net.bytebuddy.implementation.Implementation; import net.bytebuddy.implementation.Implementation;
import net.bytebuddy.implementation.LoadedTypeInitializer; import net.bytebuddy.implementation.LoadedTypeInitializer;
import net.bytebuddy.implementation.attribute.AnnotationAppender;
import net.bytebuddy.implementation.attribute.MethodAttributeAppender; import net.bytebuddy.implementation.attribute.MethodAttributeAppender;
import net.bytebuddy.implementation.bytecode.ByteCodeAppender; import net.bytebuddy.implementation.bytecode.ByteCodeAppender;
import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatcher;
Expand All @@ -25,11 +24,11 @@ public interface MethodRegistry {
/** /**
* Prepends the given method definition to this method registry, i.e. this configuration is applied first. * Prepends the given method definition to this method registry, i.e. this configuration is applied first.
* *
* @param methodMatcher A matcher to identify all entries that are to be matched. * @param methodMatcher A matcher to identify any method that this definition concerns.
* @param handler The handler to instrument any matched method. * @param handler The handler to instrument any matched method.
* @param attributeAppenderFactory A method attribute appender to apply to any matched method. * @param attributeAppenderFactory A method attribute appender to apply to any matched method.
* @param methodTransformer The method transformer to be applied to implemented methods. * @param methodTransformer The method transformer to be applied to implemented methods.
* @return A mutated version of this method registry. * @return An adapted version of this method registry.
*/ */
MethodRegistry prepend(LatentMatcher<? super MethodDescription> methodMatcher, MethodRegistry prepend(LatentMatcher<? super MethodDescription> methodMatcher,
Handler handler, Handler handler,
Expand All @@ -43,7 +42,7 @@ MethodRegistry prepend(LatentMatcher<? super MethodDescription> methodMatcher,
* @param handler The handler to instrument any matched method. * @param handler The handler to instrument any matched method.
* @param attributeAppenderFactory A method attribute appender to apply to any matched method. * @param attributeAppenderFactory A method attribute appender to apply to any matched method.
* @param methodTransformer The method transformer to be applied to implemented methods. * @param methodTransformer The method transformer to be applied to implemented methods.
* @return A mutated version of this method registry. * @return An adapted version of this method registry.
*/ */
MethodRegistry append(LatentMatcher<? super MethodDescription> methodMatcher, MethodRegistry append(LatentMatcher<? super MethodDescription> methodMatcher,
Handler handler, Handler handler,
Expand Down
Expand Up @@ -4,19 +4,44 @@
import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.description.type.TypeDescription;


import java.util.Arrays;
import java.util.List; import java.util.List;


import static net.bytebuddy.matcher.ElementMatchers.none; import static net.bytebuddy.matcher.ElementMatchers.none;
import static net.bytebuddy.matcher.ElementMatchers.representedBy; import static net.bytebuddy.matcher.ElementMatchers.representedBy;


/**
* A latent matcher that resolves an {@link ElementMatcher} after supplying the instrumented type.
*
* @param <T> The type of the matched element.
*/
public interface LatentMatcher<T> { public interface LatentMatcher<T> {


/**
* Resolves the element matcher this instance represents for the instrumented type.
*
* @param instrumentedType The instrumented type.
* @return An {@link ElementMatcher} that represents this matcher's resolved form.
*/
ElementMatcher<? super T> resolve(TypeDescription instrumentedType); ElementMatcher<? super T> resolve(TypeDescription instrumentedType);


/**
* A latent matcher representing an already resolved {@link ElementMatcher}.
*
* @param <S> The type of the matched element.
*/
class Resolved<S> implements LatentMatcher<S> { class Resolved<S> implements LatentMatcher<S> {


/**
* The resolved matcher.
*/
private final ElementMatcher<? super S> matcher; private final ElementMatcher<? super S> matcher;


/**
* Creates a new resolved latent matcher.
*
* @param matcher The resolved matcher.
*/
public Resolved(ElementMatcher<? super S> matcher) { public Resolved(ElementMatcher<? super S> matcher) {
this.matcher = matcher; this.matcher = matcher;
} }
Expand Down Expand Up @@ -45,6 +70,9 @@ public String toString() {
} }
} }


/**
* A latent matcher representing a field token that is attached to the instrumented type
*/
class ForFieldToken implements LatentMatcher<FieldDescription> { class ForFieldToken implements LatentMatcher<FieldDescription> {


private final FieldDescription.Token token; private final FieldDescription.Token token;
Expand Down Expand Up @@ -115,6 +143,10 @@ class Compound<S> implements LatentMatcher<S> {


private final List<? extends LatentMatcher<? super S>> matchers; private final List<? extends LatentMatcher<? super S>> matchers;


public Compound(LatentMatcher<? super S>... matcher) {
this(Arrays.asList(matcher));
}

public Compound(List<? extends LatentMatcher<? super S>> matchers) { public Compound(List<? extends LatentMatcher<? super S>> matchers) {
this.matchers = matchers; this.matchers = matchers;
} }
Expand All @@ -127,6 +159,23 @@ public ElementMatcher<? super S> resolve(TypeDescription instrumentedType) {
} }
return matcher; return matcher;
} }
}


@Override
public boolean equals(Object other) {
return this == other || !(other == null || getClass() != other.getClass())
&& matchers.equals(((Compound) other).matchers);
}

@Override
public int hashCode() {
return matchers.hashCode();
}

@Override
public String toString() {
return "LatentMatcher.Compound{" +
"matchers=" + matchers +
'}';
}
}
} }
Expand Up @@ -81,6 +81,7 @@ public void testKnownFieldRegistered() throws Exception {
public void testObjectProperties() throws Exception { public void testObjectProperties() throws Exception {
ObjectPropertyAssertion.of(FieldRegistry.Default.class).apply(); ObjectPropertyAssertion.of(FieldRegistry.Default.class).apply();
ObjectPropertyAssertion.of(FieldRegistry.Default.Entry.class).apply(); ObjectPropertyAssertion.of(FieldRegistry.Default.Entry.class).apply();
ObjectPropertyAssertion.of(FieldRegistry.Default.Compiled.class).apply();
ObjectPropertyAssertion.of(FieldRegistry.Default.Compiled.Entry.class).apply(); ObjectPropertyAssertion.of(FieldRegistry.Default.Compiled.Entry.class).apply();
} }
} }
@@ -0,0 +1,49 @@
package net.bytebuddy.matcher;

import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.test.utility.MockitoRule;
import net.bytebuddy.test.utility.ObjectPropertyAssertion;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.mockito.Mock;

import static net.bytebuddy.matcher.ElementMatchers.none;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Mockito.when;

public class LatentMatcherCompoundTest {

@Rule
public TestRule mockitoRule = new MockitoRule(this);

@Mock
private LatentMatcher<?> left, right;

@Mock
private ElementMatcher<?> leftMatcher, rightMatcher;

@Mock
private TypeDescription instrumentedType;

@Before
@SuppressWarnings("unchecked")
public void setUp() throws Exception {
when(left.resolve(instrumentedType)).thenReturn((ElementMatcher) leftMatcher);
when(right.resolve(instrumentedType)).thenReturn((ElementMatcher) rightMatcher);
}

@Test
@SuppressWarnings("unchecked")
public void testManifestation() throws Exception {
assertThat(new LatentMatcher.Compound(left, right).resolve(instrumentedType),
is((ElementMatcher) none().and((ElementMatcher) leftMatcher).and((ElementMatcher) rightMatcher)));
}

@Test
public void testObjectProperties() throws Exception {
ObjectPropertyAssertion.of(LatentMatcher.Compound.class).apply();
}
}
@@ -0,0 +1,56 @@
package net.bytebuddy.matcher;


import net.bytebuddy.description.field.FieldDescription;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.test.utility.MockitoRule;
import net.bytebuddy.test.utility.ObjectPropertyAssertion;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.mockito.Mock;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.when;

public class LatentMatcherForFieldTokenTest {

@Rule
public TestRule mockitoRule = new MockitoRule(this);

@Mock
private FieldDescription.Token token, otherToken;

@Mock
private TypeDescription instrumentedType;

@Mock
private FieldDescription fieldDescription;

@Before
@SuppressWarnings("unchecked")
public void setUp() throws Exception {
when(token.accept(any(TypeDescription.Generic.Visitor.class))).thenReturn(token);
}

@Test
public void testMatch() throws Exception {
when(fieldDescription.asToken()).thenReturn(token);
assertThat(new LatentMatcher.ForFieldToken(token).resolve(instrumentedType).matches(fieldDescription), is(true));
}

@Test
public void testNoMatch() throws Exception {
when(fieldDescription.asToken()).thenReturn(otherToken);
assertThat(new LatentMatcher.ForFieldToken(token).resolve(instrumentedType).matches(fieldDescription), is(false));
}

@Test
public void testObjectProperties() throws Exception {
ObjectPropertyAssertion.of(LatentMatcher.ForFieldToken.class).apply();
}
}
Expand Up @@ -22,7 +22,7 @@ public class LatentMatcherForMethodTokenTest {
public TestRule mockitoRule = new MockitoRule(this); public TestRule mockitoRule = new MockitoRule(this);


@Mock @Mock
private MethodDescription.Token methodToken, otherToken; private MethodDescription.Token token, otherToken;


@Mock @Mock
private TypeDescription instrumentedType; private TypeDescription instrumentedType;
Expand All @@ -33,19 +33,19 @@ public class LatentMatcherForMethodTokenTest {
@Before @Before
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void setUp() throws Exception { public void setUp() throws Exception {
when(methodToken.accept(any(TypeDescription.Generic.Visitor.class))).thenReturn(methodToken); when(token.accept(any(TypeDescription.Generic.Visitor.class))).thenReturn(token);
} }


@Test @Test
public void testMatch() throws Exception { public void testMatch() throws Exception {
when(methodDescription.asToken()).thenReturn(methodToken); when(methodDescription.asToken()).thenReturn(token);
assertThat(new LatentMatcher.ForMethodToken(methodToken).resolve(instrumentedType).matches(methodDescription), is(true)); assertThat(new LatentMatcher.ForMethodToken(token).resolve(instrumentedType).matches(methodDescription), is(true));
} }


@Test @Test
public void testNoMatch() throws Exception { public void testNoMatch() throws Exception {
when(methodDescription.asToken()).thenReturn(otherToken); when(methodDescription.asToken()).thenReturn(otherToken);
assertThat(new LatentMatcher.ForMethodToken(methodToken).resolve(instrumentedType).matches(methodDescription), is(false)); assertThat(new LatentMatcher.ForMethodToken(token).resolve(instrumentedType).matches(methodDescription), is(false));
} }


@Test @Test
Expand Down

0 comments on commit 1d3b0cd

Please sign in to comment.