Skip to content

Commit

Permalink
Simplified code, added non-overridden methods.
Browse files Browse the repository at this point in the history
  • Loading branch information
Rafael Winterhalter committed Apr 21, 2015
1 parent 53ed8e7 commit ab52153
Show file tree
Hide file tree
Showing 15 changed files with 170 additions and 289 deletions.
14 changes: 12 additions & 2 deletions byte-buddy-dep/src/main/java/net/bytebuddy/ByteBuddy.java
Expand Up @@ -27,8 +27,8 @@
import net.bytebuddy.implementation.bytecode.Duplication;
import net.bytebuddy.implementation.bytecode.StackManipulation;
import net.bytebuddy.implementation.bytecode.TypeCreation;
import net.bytebuddy.implementation.bytecode.assign.Assigner;
import net.bytebuddy.implementation.bytecode.assign.TypeCasting;
import net.bytebuddy.implementation.bytecode.assign.reference.ReferenceTypeAwareAssigner;
import net.bytebuddy.implementation.bytecode.collection.ArrayFactory;
import net.bytebuddy.implementation.bytecode.constant.IntegerConstant;
import net.bytebuddy.implementation.bytecode.constant.TextConstant;
Expand Down Expand Up @@ -522,7 +522,7 @@ public DynamicType.Builder<? extends Enum<?>> makeEnumeration(String... value) {
.intercept(MethodCall.invoke(TypeDescription.ENUM.getDeclaredMethods()
.filter(named(EnumerationImplementation.ENUM_VALUE_OF_METHOD_NAME).and(takesArguments(Class.class, String.class))).getOnly())
.withOwnType().withArgument(0)
.withAssigner(ReferenceTypeAwareAssigner.INSTANCE, true))
.withAssigner(Assigner.DEFAULT, Assigner.DYNAMICALLY_TYPED))
.defineMethod(EnumerationImplementation.ENUM_VALUES_METHOD_NAME,
TargetType[].class,
Collections.<Class<?>>emptyList(),
Expand Down Expand Up @@ -1799,6 +1799,11 @@ public MethodAttributeAppender.Factory getDefaultMethodAttributeAppenderFactory(
return materialize().getDefaultMethodAttributeAppenderFactory();
}

@Override
public AuxiliaryType.NamingStrategy getAuxiliaryTypeNamingStrategy() {
return materialize().getAuxiliaryTypeNamingStrategy();
}

@Override
public <T> DynamicType.Builder<T> subclass(Class<T> superType) {
return materialize().subclass(superType);
Expand Down Expand Up @@ -1968,6 +1973,11 @@ public DynamicType.Builder<? extends Annotation> makeAnnotation() {
return materialize().makeAnnotation();
}

@Override
public DynamicType.Builder<? extends Enum<?>> makeEnumeration(String... value) {
return materialize().makeEnumeration(value);
}

@Override
public ByteBuddy withTypeAnnotation(AnnotationDescription... annotation) {
return materialize().withTypeAnnotation(annotation);
Expand Down
Expand Up @@ -24,7 +24,7 @@ public interface MethodLookupEngine {

/**
* Retrieves all methods that can be called on a given type. The resulting list of methods must not contain
* any duplicates when considering byte code signatures. Furthermore, if a method is overriden, a method must
* any duplicates when considering byte code signatures. Furthermore, if a method is overridden, a method must
* be contained in its most specific version. In the process, class methods must shadow interface methods of
* identical signature. As an only deviation from the JVM's {@link Class#getMethods()}, methods of identical
* signature of incompatible interfaces must only be returned once. These methods should be represented by some
Expand Down Expand Up @@ -167,7 +167,7 @@ public String toString() {
* This method description represents a method that is defined in a non-interface type and overrides a method
* in another class it directly or indirectly extends.
*/
class OverridenClassMethod extends MethodDescription.AbstractMethodDescription {
class OverriddenClassMethod extends MethodDescription.AbstractMethodDescription {

/**
* Describes the index of the most specific method in the method chain in order to improve
Expand All @@ -186,32 +186,32 @@ class OverridenClassMethod extends MethodDescription.AbstractMethodDescription {
* @param methodChain A list of overridden methods starting with the most specific method going down to the
* least specific.
*/
protected OverridenClassMethod(List<MethodDescription> methodChain) {
protected OverriddenClassMethod(List<MethodDescription> methodChain) {
this.methodChain = methodChain;
}

/**
* Creates a new method description of an overriding method to an overriden method. The overriding method is
* considered to be a {@link MethodLookupEngine.OverridenClassMethod}
* Creates a new method description of an overriding method to an overridden method. The overriding method is
* considered to be a {@link net.bytebuddy.dynamic.scaffold.MethodLookupEngine.OverriddenClassMethod}
* itself and is resolved appropriately.
*
* @param overridingMethod The most specific method that is overriding another method.
* @param overriddenMethod The method that is overridden by the {@code overridingMethod}.
* @return A method description that represents the overriding method while considering how to properly
* specialize on invoking the overriden method.
* specialize on invoking the overridden method.
*/
public static MethodDescription of(MethodDescription overridingMethod, MethodDescription overriddenMethod) {
List<MethodDescription> methodChain;
if (overridingMethod instanceof OverridenClassMethod) {
OverridenClassMethod overridenClassMethod = (OverridenClassMethod) overridingMethod;
methodChain = new ArrayList<MethodDescription>(overridenClassMethod.methodChain.size() + 1);
methodChain.addAll(overridenClassMethod.methodChain);
if (overridingMethod instanceof OverriddenClassMethod) {
OverriddenClassMethod overriddenClassMethod = (OverriddenClassMethod) overridingMethod;
methodChain = new ArrayList<MethodDescription>(overriddenClassMethod.methodChain.size() + 1);
methodChain.addAll(overriddenClassMethod.methodChain);
} else {
methodChain = new ArrayList<MethodDescription>(2);
methodChain.add(overridingMethod);
}
methodChain.add(overriddenMethod);
return new OverridenClassMethod(methodChain);
return new OverriddenClassMethod(methodChain);
}

@Override
Expand Down Expand Up @@ -339,7 +339,7 @@ protected ConflictingInterfaceMethod(TypeDescription virtualHost, List<MethodDes
* similar properties to the latter classes resolution algorithm:
* <ul>
* <li>It is illegal to add a method of identical byte code signature after already adding this method for a
* sub interface where this method was overriden. It is however legal to add a method of a super interface
* sub interface where this method was overridden. It is however legal to add a method of a super interface
* before adding a method of a sub interface.</li>
* <li>The first argument is checked for being a
* {@link MethodLookupEngine.ConflictingInterfaceMethod} and is resolved
Expand Down Expand Up @@ -459,21 +459,33 @@ public Object getDefaultValue() {
* However, conflicting interface methods are represented by
* {@link MethodLookupEngine.ConflictingInterfaceMethod} instances.
*/
class Default implements MethodLookupEngine {
enum Default implements MethodLookupEngine {

/**
* Determines if default method lookup is enabled.
* A default implementation of a method lookup engine that looks up Java 8 default methods.
*/
private final DefaultMethodLookup defaultMethodLookup;
DEFAULT_LOOKUP_ENABLED {
@Override
protected Map<TypeDescription, Set<MethodDescription>> apply(MethodBucket methodBucket,
Collection<TypeDescription> interfaces,
Collection<TypeDescription> defaultMethodRelevantInterfaces) {
interfaces.removeAll(defaultMethodRelevantInterfaces);
return Collections.unmodifiableMap(methodBucket.pushInterfacesAndExtractDefaultMethods(defaultMethodRelevantInterfaces));
}
},

/**
* Creates a new default method lookup engine.
*
* @param defaultMethodLookup Determines if default method lookup is enabled.
* A default implementation of a method lookup engine that does not look up Java 8 default methods.
*/
public Default(DefaultMethodLookup defaultMethodLookup) {
this.defaultMethodLookup = defaultMethodLookup;
}
DEFAULT_LOOKUP_DISABLED {
@Override
protected Map<TypeDescription, Set<MethodDescription>> apply(MethodBucket methodBucket,
Collection<TypeDescription> interfaces,
Collection<TypeDescription> defaultMethodRelevantInterfaces) {
interfaces.addAll(defaultMethodRelevantInterfaces);
return Collections.emptyMap();
}
};

@Override
public Finding process(TypeDescription typeDescription) {
Expand All @@ -484,7 +496,7 @@ public Finding process(TypeDescription typeDescription) {
methodBucket.pushClass(typeDescription);
interfaces.addAll(typeDescription.getInterfaces());
}
Map<TypeDescription, Set<MethodDescription>> defaultMethods = defaultMethodLookup.apply(methodBucket,
Map<TypeDescription, Set<MethodDescription>> defaultMethods = apply(methodBucket,
interfaces,
defaultMethodRelevantInterfaces);
methodBucket.pushInterfaces(interfaces);
Expand All @@ -493,74 +505,23 @@ public Finding process(TypeDescription typeDescription) {
defaultMethods);
}

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

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

@Override
public String toString() {
return "MethodLookupEngine.Default{" +
"defaultMethodLookup=" + defaultMethodLookup +
'}';
}

/**
* Determines if default methods are extracted when analyzing a given type. This might not be relevant in
* some contexts and is normally fully irrelevant when writing types in class file formats that do not
* support default methods.
* Applies default method extraction.
*
* @param methodBucket The method bucket that is used for performing a method extraction.
* @param interfaces The interfaces of the instrumented type.
* @param defaultMethodRelevantInterfaces The interfaces of the instrumented type that are relevant for
* default method extraction.
* @return A map containing all extracted default methods.
*/
public enum DefaultMethodLookup {
protected abstract Map<TypeDescription, Set<MethodDescription>> apply(MethodBucket methodBucket,
Collection<TypeDescription> interfaces,
Collection<TypeDescription> defaultMethodRelevantInterfaces);

/**
* Enables the extraction of default methods.
*/
ENABLED {
@Override
public Map<TypeDescription, Set<MethodDescription>> apply(MethodBucket methodBucket,
Collection<TypeDescription> interfaces,
Collection<TypeDescription> defaultMethodRelevantInterfaces) {
interfaces.removeAll(defaultMethodRelevantInterfaces);
return Collections.unmodifiableMap(methodBucket.pushInterfacesAndExtractDefaultMethods(defaultMethodRelevantInterfaces));
}
},

/**
* Disables the extraction of default methods.
*/
DISABLED {
@Override
public Map<TypeDescription, Set<MethodDescription>> apply(MethodBucket methodBucket,
Collection<TypeDescription> interfaces,
Collection<TypeDescription> defaultMethodRelevantInterfaces) {
interfaces.addAll(defaultMethodRelevantInterfaces);
return Collections.emptyMap();
}
};

/**
* Applies default method extraction.
*
* @param methodBucket The method bucket that is used for performing a method extraction.
* @param interfaces The interfaces of the instrumented type.
* @param defaultMethodRelevantInterfaces The interfaces of the instrumented type that are relevant for
* default method extraction.
* @return A map containing all extracted default methods.
*/
public abstract Map<TypeDescription, Set<MethodDescription>> apply(MethodBucket methodBucket,
Collection<TypeDescription> interfaces,
Collection<TypeDescription> defaultMethodRelevantInterfaces);

@Override
public String toString() {
return "MethodLookupEngine.Default.DefaultMethodLookup." + name();
}
@Override
public String toString() {
return "MethodLookupEngine.Default." + name();
}

/**
Expand All @@ -576,9 +537,9 @@ public enum Factory implements MethodLookupEngine.Factory {

@Override
public MethodLookupEngine make(boolean extractDefaultMethods) {
return new Default(extractDefaultMethods
? DefaultMethodLookup.ENABLED
: DefaultMethodLookup.DISABLED);
return extractDefaultMethods
? Default.DEFAULT_LOOKUP_ENABLED
: Default.DEFAULT_LOOKUP_DISABLED;
}

@Override
Expand Down Expand Up @@ -679,7 +640,7 @@ private void pushClass(TypeDescription typeDescription, ElementMatcher<? super M
MethodDescription overridingMethod = classMethods.get(uniqueSignature);
classMethods.put(uniqueSignature, overridingMethod == null
? methodDescription
: OverridenClassMethod.of(overridingMethod, methodDescription));
: OverriddenClassMethod.of(overridingMethod, methodDescription));
}
}
}
Expand Down
Expand Up @@ -10,8 +10,6 @@
import net.bytebuddy.implementation.bytecode.ByteCodeAppender;
import net.bytebuddy.implementation.bytecode.StackManipulation;
import net.bytebuddy.implementation.bytecode.assign.Assigner;
import net.bytebuddy.implementation.bytecode.assign.primitive.PrimitiveTypeAwareAssigner;
import net.bytebuddy.implementation.bytecode.assign.reference.ReferenceTypeAwareAssigner;
import net.bytebuddy.implementation.bytecode.member.FieldAccess;
import net.bytebuddy.implementation.bytecode.member.MethodReturn;
import net.bytebuddy.implementation.bytecode.member.MethodVariableAccess;
Expand Down Expand Up @@ -62,7 +60,7 @@ protected FieldAccessor(Assigner assigner, boolean dynamicallyTyped) {
* @return A field accessor for a field of a given name.
*/
public static FieldDefinable ofField(String name) {
return new ForNamedField(defaultAssigner(), defaultConsiderRuntimeType(), isValidIdentifier(name));
return new ForNamedField(Assigner.DEFAULT, Assigner.STATICALLY_TYPED, isValidIdentifier(name));
}

/**
Expand All @@ -83,27 +81,7 @@ public static OwnerTypeLocatable ofBeanProperty() {
* @return A field accessor using the given field name extractor.
*/
public static OwnerTypeLocatable of(FieldNameExtractor fieldNameExtractor) {
return new ForUnnamedField(defaultAssigner(),
defaultConsiderRuntimeType(),
nonNull(fieldNameExtractor));
}

/**
* Returns the default assigner that is to be used if no explicit assigner is specified.
*
* @return The default assigner that is to be used if no explicit assigner is specified.
*/
private static Assigner defaultAssigner() {
return new PrimitiveTypeAwareAssigner(ReferenceTypeAwareAssigner.INSTANCE);
}

/**
* Returns the default value for considering the runtime type when using an assigner.
*
* @return The default value for considering the runtime type when using an assigner.
*/
private static boolean defaultConsiderRuntimeType() {
return false;
return new ForUnnamedField(Assigner.DEFAULT, Assigner.STATICALLY_TYPED, nonNull(fieldNameExtractor));
}

/**
Expand Down

0 comments on commit ab52153

Please sign in to comment.