Skip to content

Commit

Permalink
Add javadoc.
Browse files Browse the repository at this point in the history
  • Loading branch information
raphw committed Aug 11, 2018
1 parent dd4ced8 commit e431066
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 30 deletions.
Expand Up @@ -332,12 +332,35 @@ public interface TypeDescription extends TypeDefinition, ByteCodeElement, TypeVa
*/
Object getDefaultValue();

/**
* Returns the nest host of this type. For types prior to Java 11, this type is returned which is the default nest host.
*
* @return The nest host of this type.
*/
TypeDescription getNestHost();

/**
* Returns a list of members that are part of a nesting group. Prior to Java 11, a list that only contains this type is returned which is
* the default nest group.
*
* @return A list of members of this nest group.
*/
TypeList getNestMembers();

/**
* Checks if this type and the supplied type are members of the same nest group.
*
* @param type The type for which to check if it is a member of the same nest group.
* @return {@code true} if this type and the supplied type are members of the same nest group.
*/
boolean isNestMateOf(Class<?> type);

/**
* Checks if this type and the supplied type are members of the same nest group.
*
* @param typeDescription The type for which to check if it is a member of the same nest group.
* @return {@code true} if this type and the supplied type are members of the same nest group.
*/
boolean isNestMateOf(TypeDescription typeDescription);

/**
Expand Down Expand Up @@ -7180,6 +7203,9 @@ class ForLoadedType extends AbstractBase implements Serializable {
*/
private static final long serialVersionUID = 1L;

/**
* A dispatcher for invking methods on {@link Class} reflectively.
*/
private static final Dispatcher DISPATCHER = AccessController.doPrivileged(Dispatcher.CreationAction.INSTANCE);

/**
Expand Down Expand Up @@ -7510,75 +7536,129 @@ public TypeList getNestMembers() {

@Override
public boolean isNestMateOf(Class<?> type) {
return DISPATCHER.isNestmateOf(this.type, type) || super.isNestMateOf(type);
return DISPATCHER.isNestmateOf(this.type, type) || super.isNestMateOf(ForLoadedType.of(type));
}

@Override
public boolean isNestMateOf(TypeDescription typeDescription) {
return typeDescription instanceof ForLoadedType && DISPATCHER.isNestmateOf(type, ((ForLoadedType) typeDescription).type) || super.isNestMateOf(typeDescription);
}

/**
* A dispatcher for using methods of {@link Class} that are not declared for Java 6.
*/
protected interface Dispatcher {

Class<?> getNestHost(Class<?> self);
/**
* Returns the specified class's nest host.
*
* @param type The class for which to locate the nest host.
* @return The nest host of the specified class.
*/
Class<?> getNestHost(Class<?> type);

Class<?>[] getNestMembers(Class<?> self);
/**
* Returns the nest members of the other class.
*
* @param type The type to get the nest members for.
* @return An array containing all nest members of the specified type's nest group.
*/
Class<?>[] getNestMembers(Class<?> type);

boolean isNestmateOf(Class<?> self, Class<?> type);
/**
* Returns {@code true} if the specified type is a nest mate of the other type.
*
* @param type The type to evaluate for being a nest mate of another type.
* @param candidate The candidate type.
* @return {@code true} if the specified type is a nest mate of the other class.
*/
boolean isNestmateOf(Class<?> type, Class<?> candidate);

/**
* An action to resolve the dispatcher for invoking methods of {@link Class} reflectively.
*/
enum CreationAction implements PrivilegedAction<Dispatcher> {

/**
* The singleton instance.
*/
INSTANCE;

@Override
public Dispatcher run() {
try {
return ForJava11CapableVm.make();
return new ForJava11CapableVm(Class.class.getMethod("getNestHost"),
Class.class.getMethod("getNestMembers"),
Class.class.getMethod("isNestmateOf", Class.class));
} catch (NoSuchMethodException ignored) {
return Disabled.INSTANCE;
return ForLegacyVm.INSTANCE;
}
}
}

enum Disabled implements Dispatcher {
/**
* A dispatcher for a legacy VM.
*/
enum ForLegacyVm implements Dispatcher {

/**
* The singleton instance.
*/
INSTANCE;

@Override
public Class<?> getNestHost(Class<?> self) {
return self;
public Class<?> getNestHost(Class<?> type) {
return type;
}

@Override
public Class<?>[] getNestMembers(Class<?> self) {
return new Class<?>[]{self};
public Class<?>[] getNestMembers(Class<?> type) {
return new Class<?>[]{type};
}

@Override
public boolean isNestmateOf(Class<?> self, Class<?> type) {
return self == type;
public boolean isNestmateOf(Class<?> type, Class<?> candidate) {
return type == candidate;
}
}

/**
* A dispatcher for a Java 11-capable VM.
*/
class ForJava11CapableVm implements Dispatcher {

/**
* The {@code java.lang.Class#getNestHost} method.
*/
private final Method getNestHost;

/**
* The {@code java.lang.Class#getNestMembers} method.
*/
private final Method getNestMembers;

/**
* The {@code java.lang.Class#isNestmateOf} method.
*/
private final Method isNestmateOf;

/**
* Creates a dispatcher for a Java 11-capable VM.
*
* @param getNestHost The {@code java.lang.Class#getNestHost} method.
* @param getNestMembers The {@code java.lang.Class#getNestMembers} method.
* @param isNestmateOf The {@code java.lang.Class#isNestmateOf} method.
*/
protected ForJava11CapableVm(Method getNestHost, Method getNestMembers, Method isNestmateOf) {
this.getNestHost = getNestHost;
this.getNestMembers = getNestMembers;
this.isNestmateOf = isNestmateOf;
}

protected static Dispatcher make() throws NoSuchMethodException {
return new ForJava11CapableVm(Class.class.getMethod("getNestHost"),
Class.class.getMethod("getNestMembers"),
Class.class.getMethod("isNestmateOf", Class.class));
}

@Override
public Class<?> getNestHost(Class<?> self) {
public Class<?> getNestHost(Class<?> type) {
try {
return (Class<?>) getNestHost.invoke(self);
return (Class<?>) getNestHost.invoke(type);
} catch (IllegalAccessException exception) {
throw new IllegalStateException("Could not access Class::getNestHost", exception);
} catch (InvocationTargetException exception) {
Expand All @@ -7587,9 +7667,9 @@ public Class<?> getNestHost(Class<?> self) {
}

@Override
public Class<?>[] getNestMembers(Class<?> self) {
public Class<?>[] getNestMembers(Class<?> type) {
try {
return (Class<?>[]) getNestMembers.invoke(self);
return (Class<?>[]) getNestMembers.invoke(type);
} catch (IllegalAccessException exception) {
throw new IllegalStateException("Could not access Class::getNestMembers", exception);
} catch (InvocationTargetException exception) {
Expand All @@ -7598,9 +7678,9 @@ public Class<?>[] getNestMembers(Class<?> self) {
}

@Override
public boolean isNestmateOf(Class<?> self, Class<?> type) {
public boolean isNestmateOf(Class<?> type, Class<?> candidate) {
try {
return (Boolean) isNestmateOf.invoke(self, type);
return (Boolean) isNestmateOf.invoke(type, candidate);
} catch (IllegalAccessException exception) {
throw new IllegalStateException("Could not access Class::isNestmateOf", exception);
} catch (InvocationTargetException exception) {
Expand Down
Expand Up @@ -376,8 +376,14 @@ class Default extends AbstractBase.OfSimpleType implements InstrumentedType.With
*/
private final boolean localClass;

/**
* The nest host of this instrumented type or a description of {@link TargetType} if this type is its own nest host.
*/
private final TypeDescription nestHost;

/**
* A list of all members of this types nest group excluding this type.
*/
private final List<? extends TypeDescription> nestMembers;

/**
Expand All @@ -400,6 +406,8 @@ class Default extends AbstractBase.OfSimpleType implements InstrumentedType.With
* @param memberClass {@code true} if this type is a member class.
* @param anonymousClass {@code true} if this type is a anonymous class.
* @param localClass {@code true} if this type is a local class.
* @param nestHost The nest host of this instrumented type or a description of {@link TargetType} if this type is its own nest host.
* @param nestMembers A list of all members of this types nest group excluding this type.
*/
protected Default(String name,
int modifiers,
Expand Down
49 changes: 49 additions & 0 deletions byte-buddy-dep/src/main/java/net/bytebuddy/pool/TypePool.java
Expand Up @@ -2587,8 +2587,14 @@ protected static class LazyTypeDescription extends TypeDescription.AbstractBase.
*/
private final boolean anonymousType;

/**
* The binary name of the nest host or {@code null} if no nest host was specified.
*/
private final String nestHost;

/**
* A list of binary names of all specified nest members.
*/
private final List<String> nestMembers;

/**
Expand Down Expand Up @@ -2635,6 +2641,8 @@ protected static class LazyTypeDescription extends TypeDescription.AbstractBase.
* @param declaringTypeInternalName The internal name of this type's declaring type or {@code null} if no such type exists.
* @param declaredTypes A list of descriptors representing the types that are declared by this type.
* @param anonymousType {@code true} if this type is an anonymous type.
* @param nestHostInternalName The internal name of the nest host or {@code null} if no nest host was specified.
* @param nestMemberInternalNames A list of internal names of the nest members.
* @param superTypeAnnotationTokens A mapping of type annotations for this type's super type and interface types by their indices.
* @param typeVariableAnnotationTokens A mapping of type annotations of the type variables' type annotations by their indices.
* @param typeVariableBoundsAnnotationTokens A mapping of type annotations of the type variables' bounds' type annotations by their indices
Expand Down Expand Up @@ -5778,14 +5786,33 @@ public int getStackSize() {
}
}

/**
* A lazy list that represents all nest members of the represented type.
*/
protected static class LazyNestMemberList extends TypeList.AbstractBase {

/**
* The type for which the nest members are represented.
*/
private final TypeDescription typeDescription;

/**
* The type pool to use for looking up types.
*/
private final TypePool typePool;

/**
* The binary names of all nest members of this nest mate group excluding the represented type.
*/
private final List<String> nestMembers;

/**
* Creates a new lazy type list of all nest members of this group.
*
* @param typeDescription The type for which the nest members are represented.
* @param typePool The type pool to use for looking up types.
* @param nestMembers The binary names of all nest members of this nest mate group excluding the represented type.
*/
protected LazyNestMemberList(TypeDescription typeDescription, TypePool typePool, List<String> nestMembers) {
this.typeDescription = typeDescription;
this.typePool = typePool;
Expand All @@ -5803,6 +5830,22 @@ public TypeDescription get(int index) {
public int size() {
return nestMembers.size() + 1;
}

@Override
public String[] toInternalNames() {
String[] internalName = new String[nestMembers.size() + 1];
internalName[0] = typeDescription.getInternalName();
int index = 1;
for (String name : nestMembers) {
internalName[index++] = name.replace('.', '/');
}
return internalName;
}

@Override
public int getStackSize() {
return nestMembers.size() + 1;
}
}

/**
Expand Down Expand Up @@ -6849,8 +6892,14 @@ protected class TypeExtractor extends ClassVisitor {
*/
private boolean anonymousType;

/**
* The nest host that was found in the class file or {@code null} if no nest host was specified.
*/
private String nestHost;

/**
* A list of nest members that were found in the class file.
*/
private final List<String> nestMembers;

/**
Expand Down
Expand Up @@ -679,6 +679,15 @@ public void testUnboxed() throws Exception {
assertThat(describe(Object.class).asUnboxed(), is(describe(Object.class)));
}

@Test
public void testNestMatesPreJava() {
assertThat(describe(Object.class).getNestHost(), is(TypeDescription.OBJECT));
assertThat(describe(Object.class).getNestMembers().size(), is(1));
assertThat(describe(Object.class).getNestMembers(), hasItem(TypeDescription.OBJECT));
assertThat(describe(Object.class).isNestMateOf(Object.class), is(true));
assertThat(describe(Object.class).isNestMateOf(TypeDescription.STRING), is(false));
}

private Class<?> inMethodClass() {
class InMethod {
/* empty */
Expand Down
Expand Up @@ -1275,7 +1275,7 @@ public void testTypeVariableOutOfScopeIsErased() throws Exception {
false,
false,
TargetType.DESCRIPTION,
Collections.singletonList(TargetType.DESCRIPTION));
Collections.<TypeDescription>emptyList());
MethodDescription methodDescription = typeDescription.getSuperClass().getSuperClass().getDeclaredMethods().filter(named(FOO)).getOnly();
assertThat(methodDescription.getReturnType(), is(TypeDescription.Generic.OBJECT));
}
Expand Down
Expand Up @@ -1058,7 +1058,7 @@ public void testVisibilityExtension() throws Exception {
false,
false,
TargetType.DESCRIPTION,
Collections.singletonList(TargetType.DESCRIPTION));
Collections.<TypeDescription>emptyList());
MethodDescription.SignatureToken signatureToken = new MethodDescription.SignatureToken("foo",
TypeDescription.ForLoadedType.of(void.class),
Collections.<TypeDescription>emptyList());
Expand Down Expand Up @@ -1098,7 +1098,7 @@ public void testOrphanedBridge() throws Exception {
false,
false,
TargetType.DESCRIPTION,
Collections.singletonList(TargetType.DESCRIPTION));
Collections.<TypeDescription>emptyList());
MethodGraph.Linked methodGraph = MethodGraph.Compiler.Default.forJavaHierarchy().compile(typeDescription);
assertThat(methodGraph.listNodes().size(), is(1 + TypeDescription.OBJECT.getDeclaredMethods().filter(ElementMatchers.isVirtual()).size()));
MethodGraph.Node node = methodGraph.locate(bridgeMethod);
Expand Down

0 comments on commit e431066

Please sign in to comment.