All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.fitbur.bytebuddy.matcher.ElementMatchers Maven / Gradle / Ivy

There is a newer version: 1.0.0
Show newest version
package com.fitbur.bytebuddy.matcher;

import com.fitbur.bytebuddy.description.ByteCodeElement;
import com.fitbur.bytebuddy.description.ModifierReviewable;
import com.fitbur.bytebuddy.description.NamedElement;
import com.fitbur.bytebuddy.description.annotation.AnnotatedCodeElement;
import com.fitbur.bytebuddy.description.annotation.AnnotationDescription;
import com.fitbur.bytebuddy.description.annotation.AnnotationList;
import com.fitbur.bytebuddy.description.field.FieldDescription;
import com.fitbur.bytebuddy.description.field.FieldList;
import com.fitbur.bytebuddy.description.method.MethodDescription;
import com.fitbur.bytebuddy.description.method.MethodList;
import com.fitbur.bytebuddy.description.method.ParameterDescription;
import com.fitbur.bytebuddy.description.method.ParameterList;
import com.fitbur.bytebuddy.description.type.TypeDefinition;
import com.fitbur.bytebuddy.description.type.TypeDescription;
import com.fitbur.bytebuddy.description.type.TypeList;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * A utility class that contains a human-readable language for creating {@link com.fitbur.bytebuddy.matcher.ElementMatcher}s.
 */
public final class ElementMatchers {

    /**
     * A readable reference to the bootstrap class loader which is represented by {@code null}.
     */
    private static final ClassLoader BOOTSTRAP_CLASSLOADER = null;

    /**
     * A private constructor that must not be invoked.
     */
    private ElementMatchers() {
        throw new UnsupportedOperationException();
    }

    /**
     * Wraps another matcher to assure that an element is not matched in case that the matching causes an {@link Exception}.
     *
     * @param matcher The element matcher that potentially throws an exception.
     * @param             The type of the matched object.
     * @return A matcher that returns {@code false} in case that the given matcher throws an exception.
     */
    public static  ElementMatcher.Junction failSafe(ElementMatcher matcher) {
        return new FailSafeMatcher(matcher, false);
    }

    /**
     * Matches the given value which can also be {@code null} by the {@link java.lang.Object#equals(Object)} method or
     * by a null-check.
     *
     * @param value The value that is to be matched.
     * @param    The type of the matched object.
     * @return A matcher that matches an exact value.
     */
    public static  ElementMatcher.Junction is(Object value) {
        return value == null
                ? new NullMatcher()
                : new EqualityMatcher(value);
    }

    /**
     * Exactly matches a given field as a {@link FieldDescription}.
     *
     * @param field The field to match by its description
     * @param    The type of the matched object.
     * @return An element matcher that exactly matches the given field.
     */
    public static  ElementMatcher.Junction is(Field field) {
        return definedField(is(new FieldDescription.ForLoadedField(field)));
    }

    /**
     * Matches a field in its defined shape.
     *
     * @param matcher The matcher to apply to the matched field's defined shape.
     * @param      The matched object's type.
     * @return A matcher that matches a matched field's defined shape.
     */
    public static  ElementMatcher.Junction definedField(ElementMatcher matcher) {
        return new DefinedShapeMatcher(matcher);
    }

    /**
     * Exactly matches a given method as a {@link MethodDescription}.
     *
     * @param method The method to match by its description
     * @param     The type of the matched object.
     * @return An element matcher that exactly matches the given method.
     */
    public static  ElementMatcher.Junction is(Method method) {
        return definedMethod(is(new MethodDescription.ForLoadedMethod(method)));
    }

    /**
     * Exactly matches a given constructor as a {@link MethodDescription}.
     *
     * @param constructor The constructor to match by its description
     * @param          The type of the matched object.
     * @return An element matcher that exactly matches the given constructor.
     */
    public static  ElementMatcher.Junction is(Constructor constructor) {
        return definedMethod(is(new MethodDescription.ForLoadedConstructor(constructor)));
    }

    /**
     * Matches a method in its defined shape.
     *
     * @param matcher The matcher to apply to the matched method's defined shape.
     * @param      The matched object's type.
     * @return A matcher that matches a matched method's defined shape.
     */
    public static  ElementMatcher.Junction definedMethod(ElementMatcher matcher) {
        return new DefinedShapeMatcher(matcher);
    }

    /**
     * Matches a parameter in its defined shape.
     *
     * @param matcher The matcher to apply to the matched parameter's defined shape.
     * @param      The matched object's type.
     * @return A matcher that matches a matched parameter's defined shape.
     */
    public static  ElementMatcher.Junction definedParameter(ElementMatcher matcher) {
        return new DefinedShapeMatcher(matcher);
    }

    /**
     * Matches a parameter's type by the given matcher.
     *
     * @param matcher The matcher to apply to the parameter's type.
     * @param      The type of the matched object.
     * @return A matcher that matches a parameter's type by the given matcher.
     */
    public static  ElementMatcher.Junction hasType(ElementMatcher matcher) {
        return hasGenericType(rawType(matcher));
    }

    /**
     * Matches a method parameter by its generic type.
     *
     * @param matcher The matcher to apply to a parameter's generic type.
     * @param      The type of the matched object.
     * @return A matcher that matches the matched parameter's generic type.
     */
    public static  ElementMatcher.Junction hasGenericType(ElementMatcher matcher) {
        return new MethodParameterTypeMatcher(matcher);
    }

    /**
     * Exactly matches a given type as a {@link TypeDescription}.
     *
     * @param type The type to match by its description
     * @param   The type of the matched object.
     * @return An element matcher that exactly matches the given type.
     */
    public static  ElementMatcher.Junction is(Type type) {
        return is(TypeDefinition.Sort.describe(type));
    }

    /**
     * Exactly matches a given annotation as an {@link AnnotationDescription}.
     *
     * @param annotation The annotation to match by its description.
     * @param         The type of the matched object.
     * @return An element matcher that exactly matches the given annotation.
     */
    public static  ElementMatcher.Junction is(Annotation annotation) {
        return is(AnnotationDescription.ForLoadedAnnotation.of(annotation));
    }

    /**
     * Inverts another matcher.
     *
     * @param matcher The matcher to invert.
     * @param      The type of the matched object.
     * @return An inverted version of the given {@code matcher}.
     */
    public static  ElementMatcher.Junction not(ElementMatcher matcher) {
        return new NegatingMatcher(matcher);
    }

    /**
     * Creates a matcher that always returns {@code true}.
     *
     * @param  The type of the matched object.
     * @return A matcher that matches anything.
     */
    public static  ElementMatcher.Junction any() {
        return new BooleanMatcher(true);
    }

    /**
     * Creates a matcher that always returns {@code false}.
     *
     * @param  The type of the matched object.
     * @return A matcher that matches nothing.
     */
    public static  ElementMatcher.Junction none() {
        return new BooleanMatcher(false);
    }

    /**
     * Creates a matcher that matches any of the given objects by the {@link java.lang.Object#equals(Object)} method.
     * None of the values must be {@code null}.
     *
     * @param value The input values to be compared against.
     * @param    The type of the matched object.
     * @return A matcher that checks for the equality with any of the given objects.
     */
    public static  ElementMatcher.Junction anyOf(Object... value) {
        return anyOf(Arrays.asList(value));
    }

    /**
     * Creates a matcher that matches any of the given objects by the {@link java.lang.Object#equals(Object)} method.
     * None of the values must be {@code null}.
     *
     * @param values The input values to be compared against.
     * @param     The type of the matched object.
     * @return A matcher that checks for the equality with any of the given objects.
     */
    public static  ElementMatcher.Junction anyOf(Iterable values) {
        ElementMatcher.Junction matcher = none();
        for (Object value : values) {
            matcher = matcher.or(is(value));
        }
        return matcher;
    }

    /**
     * Creates a matcher that matches any of the given types as {@link TypeDescription}s
     * by the {@link java.lang.Object#equals(Object)} method. None of the values must be {@code null}.
     *
     * @param value The input values to be compared against.
     * @param    The type of the matched object.
     * @return A matcher that checks for the equality with any of the given objects.
     */
    public static  ElementMatcher.Junction anyOf(Type... value) {
        return anyOf(new TypeList.Generic.ForLoadedTypes(value));
    }

    /**
     * Creates a matcher that matches any of the given constructors as {@link MethodDescription}s
     * by the {@link java.lang.Object#equals(Object)} method. None of the values must be {@code null}.
     *
     * @param value The input values to be compared against.
     * @param    The type of the matched object.
     * @return A matcher that checks for the equality with any of the given objects.
     */
    public static  ElementMatcher.Junction anyOf(Constructor... value) {
        return definedMethod(anyOf(new MethodList.ForLoadedType(value, new Method[0])));
    }

    /**
     * Creates a matcher that matches any of the given methods as {@link MethodDescription}s
     * by the {@link java.lang.Object#equals(Object)} method. None of the values must be {@code null}.
     *
     * @param value The input values to be compared against.
     * @param    The type of the matched object.
     * @return A matcher that checks for the equality with any of the given objects.
     */
    public static  ElementMatcher.Junction anyOf(Method... value) {
        return definedMethod(anyOf(new MethodList.ForLoadedType(new Constructor[0], value)));
    }

    /**
     * Creates a matcher that matches any of the given fields as {@link FieldDescription}s
     * by the {@link java.lang.Object#equals(Object)} method. None of the values must be {@code null}.
     *
     * @param value The input values to be compared against.
     * @param    The type of the matched object.
     * @return A matcher that checks for the equality with any of the given objects.
     */
    public static  ElementMatcher.Junction anyOf(Field... value) {
        return definedField(anyOf(new FieldList.ForLoadedFields(value)));
    }

    /**
     * Creates a matcher that matches any of the given annotations as {@link AnnotationDescription}s
     * by the {@link java.lang.Object#equals(Object)} method. None of the values must be {@code null}.
     *
     * @param value The input values to be compared against.
     * @param    The type of the matched object.
     * @return A matcher that checks for the equality with any of the given objects.
     */
    public static  ElementMatcher.Junction anyOf(Annotation... value) {
        return anyOf(new AnnotationList.ForLoadedAnnotations(value));
    }

    /**
     * Creates a matcher that matches none of the given objects by the {@link java.lang.Object#equals(Object)} method.
     * None of the values must be {@code null}.
     *
     * @param value The input values to be compared against.
     * @param    The type of the matched object.
     * @return A matcher that checks for the equality with none of the given objects.
     */
    public static  ElementMatcher.Junction noneOf(Object... value) {
        return noneOf(Arrays.asList(value));
    }

    /**
     * Creates a matcher that matches none of the given objects by the {@link java.lang.Object#equals(Object)} method.
     * None of the values must be {@code null}.
     *
     * @param values The input values to be compared against.
     * @param     The type of the matched object.
     * @return A matcher that checks for the equality with none of the given objects.
     */
    public static  ElementMatcher.Junction noneOf(Iterable values) {
        ElementMatcher.Junction matcher = any();
        for (Object value : values) {
            matcher = matcher.and(not(is(value)));
        }
        return matcher;
    }

    /**
     * Creates a matcher that matches none of the given types as {@link TypeDescription}s
     * by the {@link java.lang.Object#equals(Object)} method. None of the values must be {@code null}.
     *
     * @param value The input values to be compared against.
     * @param    The type of the matched object.
     * @return A matcher that checks for the equality with none of the given objects.
     */
    public static  ElementMatcher.Junction noneOf(Type... value) {
        return noneOf(new TypeList.Generic.ForLoadedTypes(value));
    }

    /**
     * Creates a matcher that matches none of the given constructors as {@link MethodDescription}s
     * by the {@link java.lang.Object#equals(Object)} method. None of the values must be {@code null}.
     *
     * @param value The input values to be compared against.
     * @param    The type of the matched object.
     * @return A matcher that checks for the equality with none of the given objects.
     */
    public static  ElementMatcher.Junction noneOf(Constructor... value) {
        return definedMethod(noneOf(new MethodList.ForLoadedType(value, new Method[0])));
    }

    /**
     * Creates a matcher that matches none of the given methods as {@link MethodDescription}s
     * by the {@link java.lang.Object#equals(Object)} method. None of the values must be {@code null}.
     *
     * @param value The input values to be compared against.
     * @param    The type of the matched object.
     * @return A matcher that checks for the equality with none of the given objects.
     */
    public static  ElementMatcher.Junction noneOf(Method... value) {
        return definedMethod(noneOf(new MethodList.ForLoadedType(new Constructor[0], value)));
    }

    /**
     * Creates a matcher that matches none of the given methods as {@link FieldDescription}s
     * by the {@link java.lang.Object#equals(Object)} method. None of the values must be {@code null}.
     *
     * @param value The input values to be compared against.
     * @param    The type of the matched object.
     * @return A matcher that checks for the equality with none of the given objects.
     */
    public static  ElementMatcher.Junction noneOf(Field... value) {
        return definedField(noneOf(new FieldList.ForLoadedFields(value)));
    }

    /**
     * Creates a matcher that matches none of the given annotations as {@link AnnotationDescription}s
     * by the {@link java.lang.Object#equals(Object)} method. None of the values must be {@code null}.
     *
     * @param value The input values to be compared against.
     * @param    The type of the matched object.
     * @return A matcher that checks for the equality with any of the given objects.
     */
    public static  ElementMatcher.Junction noneOf(Annotation... value) {
        return noneOf(new AnnotationList.ForLoadedAnnotations(value));
    }

    /**
     * Matches an iterable by assuring that at least one element of the iterable collection matches the
     * provided matcher.
     *
     * @param matcher The matcher to apply to each element.
     * @param      The type of the matched object.
     * @return A matcher that matches an iterable if at least one element matches the provided matcher.
     */
    public static  ElementMatcher.Junction> whereAny(ElementMatcher matcher) {
        return new CollectionItemMatcher(matcher);
    }

    /**
     * Matches an iterable by assuring that no element of the iterable collection matches the provided matcher.
     *
     * @param matcher The matcher to apply to each element.
     * @param      The type of the matched object.
     * @return A matcher that matches an iterable if no element matches the provided matcher.
     */
    public static  ElementMatcher.Junction> whereNone(ElementMatcher matcher) {
        return not(whereAny(matcher));
    }

    /**
     * Matches a generic type's raw type against the provided raw type.
     *
     * @param type The type to match a generic type's erasure against.
     * @param   The type of the matched object.
     * @return A matcher that matches a generic type's raw type against the provided non-generic type.
     */
    public static  ElementMatcher.Junction rawType(Class type) {
        return rawType(is(type));
    }

    /**
     * Matches a generic type's raw type against the provided raw type.
     *
     * @param type The type to match a generic type's erasure against.
     * @param              The type of the matched object.
     * @return A matcher that matches a generic type's raw type against the provided non-generic type.
     */
    public static  ElementMatcher.Junction rawType(TypeDescription type) {
        return rawType(is(type));
    }

    /**
     * Converts a matcher for a type description into a matcher for a raw type of the matched generic type against the given matcher. A wildcard
     * type which does not define a raw type results in a negative match.
     *
     * @param matcher The matcher to match the matched object's raw type against.
     * @param      The type of the matched object.
     * @return A type matcher for a generic type that matches the matched type's raw type against the given type description matcher.
     */
    public static  ElementMatcher.Junction rawType(ElementMatcher matcher) {
        return new RawTypeMatcher(matcher);
    }

    /**
     * Matches an iteration of generic types' erasures against the provided raw types.
     *
     * @param type The types to match.
     * @param   The type of the matched object.
     * @return A matcher that matches an iteration of generic types' raw types against the provided non-generic types.
     */
    public static > ElementMatcher.Junction rawTypes(Class... type) {
        return rawTypes(new TypeList.ForLoadedTypes(type));
    }

    /**
     * Matches an iteration of generic types' erasures against the provided raw types.
     *
     * @param type The types to match.
     * @param              The type of the matched object.
     * @return A matcher that matches an iteration of generic types' raw types against the provided non-generic types.
     */
    public static > ElementMatcher.Junction rawTypes(TypeDescription... type) {
        return rawTypes(Arrays.asList(type));
    }

    /**
     * Matches an iteration of generic types' erasures against the provided raw types.
     *
     * @param types The types to match.
     * @param               The type of the matched object.
     * @return A matcher that matches an iteration of generic types' raw types against the provided non-generic types.
     */
    public static > ElementMatcher.Junction rawTypes(
            Iterable types) {
        List> typeMatchers = new ArrayList>();
        for (TypeDescription type : types) {
            typeMatchers.add(is(type));
        }
        return rawTypes(new CollectionOneToOneMatcher(typeMatchers));
    }

    /**
     * Applies the provided matcher to an iteration og generic types' generic types.
     *
     * @param matcher The matcher to apply at the erased types.
     * @param      The type of the matched object.
     * @return A matcher that matches an iteration of generic types' raw types against the provided matcher.
     */
    public static > ElementMatcher.Junction rawTypes(
            ElementMatcher> matcher) {
        return new CollectionRawTypeMatcher(matcher);
    }

    /**
     * Matches a type variable with the given name.
     *
     * @param symbol The name of the type variable to be match.
     * @param     The type of the matched object.
     * @return A matcher that matches type variables with the given name.
     */
    public static  ElementMatcher isVariable(String symbol) {
        return isVariable(named(symbol));
    }

    /**
     * Matches a type variable with the given name.
     *
     * @param matcher A matcher for the type variable's name.
     * @param      The type of the matched object.
     * @return A matcher that matches type variables with the given name.
     */
    public static  ElementMatcher isVariable(ElementMatcher matcher) {
        return new TypeSortMatcher(anyOf(TypeDefinition.Sort.VARIABLE, TypeDefinition.Sort.VARIABLE_SYMBOLIC)).and(matcher);
    }

    /**
     * Matches a {@link NamedElement} for its exact name.
     *
     * @param name The expected name.
     * @param   The type of the matched object.
     * @return An element matcher for a named element's exact name.
     */
    public static  ElementMatcher.Junction named(String name) {
        return new NameMatcher(new StringMatcher(name, StringMatcher.Mode.EQUALS_FULLY));
    }

    /**
     * Matches a {@link NamedElement} for its name. The name's
     * capitalization is ignored.
     *
     * @param name The expected name.
     * @param   The type of the matched object.
     * @return An element matcher for a named element's name.
     */
    public static  ElementMatcher.Junction namedIgnoreCase(String name) {
        return new NameMatcher(new StringMatcher(name, StringMatcher.Mode.EQUALS_FULLY_IGNORE_CASE));
    }

    /**
     * Matches a {@link NamedElement} for its name's prefix.
     *
     * @param prefix The expected name's prefix.
     * @param     The type of the matched object.
     * @return An element matcher for a named element's name's prefix.
     */
    public static  ElementMatcher.Junction nameStartsWith(String prefix) {
        return new NameMatcher(new StringMatcher(prefix, StringMatcher.Mode.STARTS_WITH));
    }

    /**
     * Matches a {@link NamedElement} for its name's prefix. The name's
     * capitalization is ignored.
     *
     * @param prefix The expected name's prefix.
     * @param     The type of the matched object.
     * @return An element matcher for a named element's name's prefix.
     */
    public static  ElementMatcher.Junction nameStartsWithIgnoreCase(String prefix) {
        return new NameMatcher(new StringMatcher(prefix, StringMatcher.Mode.STARTS_WITH_IGNORE_CASE));
    }

    /**
     * Matches a {@link NamedElement} for its name's suffix.
     *
     * @param suffix The expected name's suffix.
     * @param     The type of the matched object.
     * @return An element matcher for a named element's name's suffix.
     */
    public static  ElementMatcher.Junction nameEndsWith(String suffix) {
        return new NameMatcher(new StringMatcher(suffix, StringMatcher.Mode.ENDS_WITH));
    }

    /**
     * Matches a {@link NamedElement} for its name's suffix. The name's
     * capitalization is ignored.
     *
     * @param suffix The expected name's suffix.
     * @param     The type of the matched object.
     * @return An element matcher for a named element's name's suffix.
     */
    public static  ElementMatcher.Junction nameEndsWithIgnoreCase(String suffix) {
        return new NameMatcher(new StringMatcher(suffix, StringMatcher.Mode.ENDS_WITH_IGNORE_CASE));
    }

    /**
     * Matches a {@link NamedElement} for an infix of its name.
     *
     * @param infix The expected infix of the name.
     * @param    The type of the matched object.
     * @return An element matcher for a named element's name's infix.
     */
    public static  ElementMatcher.Junction nameContains(String infix) {
        return new NameMatcher(new StringMatcher(infix, StringMatcher.Mode.CONTAINS));
    }

    /**
     * Matches a {@link NamedElement} for an infix of its name. The name's
     * capitalization is ignored.
     *
     * @param infix The expected infix of the name.
     * @param    The type of the matched object.
     * @return An element matcher for a named element's name's infix.
     */
    public static  ElementMatcher.Junction nameContainsIgnoreCase(String infix) {
        return new NameMatcher(new StringMatcher(infix, StringMatcher.Mode.CONTAINS_IGNORE_CASE));
    }

    /**
     * Matches a {@link NamedElement} name against a regular expression.
     *
     * @param regex The regular expression to match the name against.
     * @param    The type of the matched object.
     * @return An element matcher for a named element's name's against the given regular expression.
     */
    public static  ElementMatcher.Junction nameMatches(String regex) {
        return new NameMatcher(new StringMatcher(regex, StringMatcher.Mode.MATCHES));
    }

    /**
     * Matches a {@link ByteCodeElement}'s descriptor against a given value.
     *
     * @param descriptor The expected descriptor.
     * @param         The type of the matched object.
     * @return A matcher for the given {@code descriptor}.
     */
    public static  ElementMatcher.Junction hasDescriptor(String descriptor) {
        return new DescriptorMatcher(new StringMatcher(descriptor, StringMatcher.Mode.EQUALS_FULLY));
    }

    /**
     * Matches a {@link ByteCodeElement} for being declared by a given {@link java.lang.Class}. This matcher matches
     * a declared element's raw declaring type.
     *
     * @param type The type that is expected to declare the matched byte code element.
     * @param   The type of the matched object.
     * @return A matcher for byte code elements being declared by the given {@code type}.
     */
    public static  ElementMatcher.Junction isDeclaredBy(Class type) {
        return isDeclaredBy(new TypeDescription.ForLoadedType(type));
    }

    /**
     * Matches a {@link ByteCodeElement} for being declared by a given {@link TypeDescription}. This matcher matches
     * a declared element's raw declaring type.
     *
     * @param type The type that is expected to declare the matched byte code element.
     * @param   The type of the matched object.
     * @return A matcher for byte code elements being declared by the given {@code type}.
     */
    public static  ElementMatcher.Junction isDeclaredBy(TypeDescription type) {
        return isDeclaredBy(is(type));
    }

    /**
     * Matches a {@link ByteCodeElement} for being declared by a {@link TypeDescription} that is matched by the given matcher. This matcher matches
     * a declared element's raw declaring type.
     *
     * @param matcher A matcher for the declaring type of the matched byte code element as long as it
     *                is not {@code null}.
     * @param      The type of the matched object.
     * @return A matcher for byte code elements being declared by a type matched by the given {@code matcher}.
     */
    public static  ElementMatcher.Junction isDeclaredBy(ElementMatcher matcher) {
        return isDeclaredByGeneric(rawType(matcher));
    }

    /**
     * Matches a {@link ByteCodeElement} for being declared by a given generic {@link Type}.
     *
     * @param type The type that is expected to declare the matched byte code element.
     * @param   The type of the matched object.
     * @return A matcher for byte code elements being declared by the given {@code type}.
     */
    public static  ElementMatcher.Junction isDeclaredByGeneric(Type type) {
        return isDeclaredByGeneric(TypeDefinition.Sort.describe(type));
    }

    /**
     * Matches a {@link ByteCodeElement} for being declared by a given {@link TypeDescription.Generic}.
     *
     * @param type The type that is expected to declare the matched byte code element.
     * @param   The type of the matched object.
     * @return A matcher for byte code elements being declared by the given {@code type}.
     */
    public static  ElementMatcher.Junction isDeclaredByGeneric(TypeDescription.Generic type) {
        return isDeclaredByGeneric(is(type));
    }

    /**
     * Matches a {@link ByteCodeElement} for being declared by a {@link TypeDescription.Generic} that is matched by the given matcher.
     *
     * @param matcher A matcher for the declaring type of the matched byte code element as long as it is not {@code null}.
     * @param      The type of the matched object.
     * @return A matcher for byte code elements being declared by a type matched by the given {@code matcher}.
     */
    public static  ElementMatcher.Junction isDeclaredByGeneric(ElementMatcher matcher) {
        return new DeclaringTypeMatcher(matcher);
    }

    /**
     * Matches a {@link ByteCodeElement} that is visible to a given {@link java.lang.Class}.
     *
     * @param type The type that a matched byte code element is expected to be visible to.
     * @param   The type of the matched object.
     * @return A matcher for a byte code element to be visible to a given {@code type}.
     */
    public static  ElementMatcher.Junction isVisibleTo(Class type) {
        return isVisibleTo(new TypeDescription.ForLoadedType(type));
    }

    /**
     * Matches a {@link ByteCodeElement} that is visible to a given
     * {@link TypeDescription}.
     *
     * @param type The type that a matched byte code element is expected to be visible to.
     * @param              The type of the matched object.
     * @return A matcher for a byte code element to be visible to a given {@code type}.
     */
    public static  ElementMatcher.Junction isVisibleTo(TypeDescription type) {
        return new VisibilityMatcher(type);
    }

    /**
     * Matches a {@link ModifierReviewable} that is {@code abstract}.
     *
     * @param  The type of the matched object.
     * @return A matcher for a {@code abstract} modifier reviewable.
     */
    public static  ElementMatcher.Junction isAbstract() {
        return new ModifierMatcher(ModifierMatcher.Mode.ABSTRACT);
    }

    /**
     * Matches an {@link com.fitbur.bytebuddy.description.annotation.AnnotatedCodeElement} for declared annotations.
     * This matcher does not match inherited annotations which only exist for classes. Use
     * {@link com.fitbur.bytebuddy.matcher.ElementMatchers#inheritsAnnotation(Class)} for matching inherited annotations.
     *
     * @param type The annotation type to match against.
     * @param   The type of the matched object.
     * @return A matcher that validates that an annotated element is annotated with an annotation of {@code type}.
     */
    public static  ElementMatcher.Junction isAnnotatedWith(Class type) {
        return isAnnotatedWith(new TypeDescription.ForLoadedType(type));
    }

    /**
     * Matches an {@link com.fitbur.bytebuddy.description.annotation.AnnotatedCodeElement} for declared annotations.
     * This matcher does not match inherited annotations which only exist for classes. Use
     * {@link com.fitbur.bytebuddy.matcher.ElementMatchers#inheritsAnnotation(TypeDescription)}
     * for matching inherited annotations.
     *
     * @param type The annotation type to match against.
     * @param              The type of the matched object.
     * @return A matcher that validates that an annotated element is annotated with an annotation of {@code type}.
     */
    public static  ElementMatcher.Junction isAnnotatedWith(TypeDescription type) {
        return isAnnotatedWith(is(type));
    }

    /**
     * Matches an {@link com.fitbur.bytebuddy.description.annotation.AnnotatedCodeElement} for declared annotations.
     * This matcher does not match inherited annotations which only exist for classes. Use
     * {@link com.fitbur.bytebuddy.matcher.ElementMatchers#inheritsAnnotation(com.fitbur.bytebuddy.matcher.ElementMatcher)}
     * for matching inherited annotations.
     *
     * @param matcher The matcher to apply to any annotation's type found on the matched annotated element.
     * @param      The type of the matched object.
     * @return A matcher that validates that an annotated element is annotated with an annotation of a type
     * that matches the given {@code matcher}.
     */
    public static  ElementMatcher.Junction isAnnotatedWith(ElementMatcher matcher) {
        return declaresAnnotation(new AnnotationTypeMatcher(matcher));
    }

    /**
     * Matches an {@link com.fitbur.bytebuddy.description.annotation.AnnotatedCodeElement} to declare any annotation
     * that matches the given matcher. Note that this matcher does not match inherited annotations that only exist
     * for types. Use {@link com.fitbur.bytebuddy.matcher.ElementMatchers#inheritsAnnotation(com.fitbur.bytebuddy.matcher.ElementMatcher)}
     * for matching inherited annotations.
     *
     * @param matcher A matcher to apply on any declared annotation of the matched annotated element.
     * @param      The type of the matched object.
     * @return A matcher that validates that an annotated element is annotated with an annotation that matches
     * the given {@code matcher}.
     */
    public static  ElementMatcher.Junction declaresAnnotation(ElementMatcher matcher) {
        return new DeclaringAnnotationMatcher(new CollectionItemMatcher(matcher));
    }

    /**
     * Matches a {@link ModifierReviewable} that is {@code public}.
     *
     * @param  The type of the matched object.
     * @return A matcher for a {@code public} modifier reviewable.
     */
    public static  ElementMatcher.Junction isPublic() {
        return new ModifierMatcher(ModifierMatcher.Mode.PUBLIC);
    }

    /**
     * Matches a {@link ModifierReviewable} that is {@code protected}.
     *
     * @param  The type of the matched object.
     * @return A matcher for a {@code protected} modifier reviewable.
     */
    public static  ElementMatcher.Junction isProtected() {
        return new ModifierMatcher(ModifierMatcher.Mode.PROTECTED);
    }

    /**
     * Matches a {@link ModifierReviewable} that is package-private.
     *
     * @param  The type of the matched object.
     * @return A matcher for a package-private modifier reviewable.
     */
    public static  ElementMatcher.Junction isPackagePrivate() {
        return not(isPublic().or(isProtected()).or(isPrivate()));
    }

    /**
     * Matches a {@link ModifierReviewable} that is {@code private}.
     *
     * @param  The type of the matched object.
     * @return A matcher for a {@code private} modifier reviewable.
     */
    public static  ElementMatcher.Junction isPrivate() {
        return new ModifierMatcher(ModifierMatcher.Mode.PRIVATE);
    }

    /**
     * Matches a {@link ModifierReviewable} that is {@code final}.
     *
     * @param  The type of the matched object.
     * @return A matcher for a {@code final} modifier reviewable.
     */
    public static  ElementMatcher.Junction isFinal() {
        return new ModifierMatcher(ModifierMatcher.Mode.FINAL);
    }

    /**
     * Matches a {@link ModifierReviewable} that is {@code static}.
     *
     * @param  The type of the matched object.
     * @return A matcher for a {@code static} modifier reviewable.
     */
    public static  ElementMatcher.Junction isStatic() {
        return new ModifierMatcher(ModifierMatcher.Mode.STATIC);
    }

    /**
     * Matches a {@link ModifierReviewable} that is synthetic.
     *
     * @param  The type of the matched object.
     * @return A matcher for a synthetic modifier reviewable.
     */
    public static  ElementMatcher.Junction isSynthetic() {
        return new ModifierMatcher(ModifierMatcher.Mode.SYNTHETIC);
    }

    /**
     * Matches a {@link MethodDescription} that is {@code synchronized}.
     *
     * @param  The type of the matched object.
     * @return A matcher for a {@code synchronized} method description.
     */
    public static  ElementMatcher.Junction isSynchronized() {
        return new ModifierMatcher(ModifierMatcher.Mode.SYNCHRONIZED);
    }

    /**
     * Matches a {@link MethodDescription} that is {@code native}.
     *
     * @param  The type of the matched object.
     * @return A matcher for a {@code native} method description.
     */
    public static  ElementMatcher.Junction isNative() {
        return new ModifierMatcher(ModifierMatcher.Mode.NATIVE);
    }

    /**
     * Matches a {@link MethodDescription} that is {@code strictfp}.
     *
     * @param  The type of the matched object.
     * @return A matcher for a {@code strictfp} method description.
     */
    public static  ElementMatcher.Junction isStrict() {
        return new ModifierMatcher(ModifierMatcher.Mode.STRICT);
    }

    /**
     * Matches a {@link MethodDescription} that is a var-args.
     *
     * @param  The type of the matched object.
     * @return A matcher for a var-args method description.
     */
    public static  ElementMatcher.Junction isVarArgs() {
        return new ModifierMatcher(ModifierMatcher.Mode.VAR_ARGS);
    }

    /**
     * Matches a {@link MethodDescription} that is a bridge.
     *
     * @param  The type of the matched object.
     * @return A matcher for a bridge method.
     */
    public static  ElementMatcher.Junction isBridge() {
        return new ModifierMatcher(ModifierMatcher.Mode.BRIDGE);
    }

    /**
     * Matches {@link MethodDescription}s that return a given generic type.
     *
     * @param type The generic type the matched method is expected to return.
     * @param   The type of the matched object.
     * @return An element matcher that matches a given generic return type for a method description.
     */
    public static  ElementMatcher.Junction returnsGeneric(Type type) {
        return returnsGeneric(TypeDefinition.Sort.describe(type));
    }

    /**
     * Matches {@link MethodDescription}s that returns a given
     * {@link TypeDescription}.
     *
     * @param type The type the matched method is expected to return.
     * @param              The type of the matched object.
     * @return An element matcher that matches a given return type for a method description.
     */
    public static  ElementMatcher.Junction returnsGeneric(TypeDescription.Generic type) {
        return returnsGeneric(is(type));
    }

    /**
     * Matches {@link MethodDescription}s that return a given erasure type.
     *
     * @param type The raw type the matched method is expected to return.
     * @param   The type of the matched object.
     * @return An element matcher that matches a given return type for a method description.
     */
    public static  ElementMatcher.Junction returns(Class type) {
        return returnsGeneric(rawType(type));
    }

    /**
     * Matches {@link MethodDescription}s that return a given erasure type.
     *
     * @param type The raw type the matched method is expected to return.
     * @param              The type of the matched object.
     * @return An element matcher that matches a given return type for a method description.
     */
    public static  ElementMatcher.Junction returns(TypeDescription type) {
        return returns(is(type));
    }

    /**
     * Matches a method's return type's erasure by the given matcher.
     *
     * @param matcher The matcher to apply to a method's return type's erasure.
     * @param      The type of the matched object.
     * @return A matcher that matches the matched method's return type's erasure.
     */
    public static  ElementMatcher.Junction returns(ElementMatcher matcher) {
        return returnsGeneric(rawType(matcher));
    }

    /**
     * Matches {@link MethodDescription}s that match a matched method's return type.
     *
     * @param matcher A matcher to apply onto a matched method's return type.
     * @param      The type of the matched object.
     * @return An element matcher that matches a given return type against another {@code matcher}.
     */
    public static  ElementMatcher.Junction returnsGeneric(ElementMatcher matcher) {
        return new MethodReturnTypeMatcher(matcher);
    }

    /**
     * Matches {@link MethodDescription}s that define a given generic type as a parameter at the given index.
     *
     * @param index The index of the parameter.
     * @param type  The generic type the matched method is expected to define as a parameter type.
     * @param    The type of the matched object.
     * @return An element matcher that matches a given generic return type for a method description.
     */
    public static  ElementMatcher.Junction takesGenericArgument(int index, Type type) {
        return takesGenericArgument(index, TypeDefinition.Sort.describe(type));
    }

    /**
     * Matches {@link MethodDescription}s that define a given generic type as a parameter at the given index.
     *
     * @param index           The index of the parameter.
     * @param type The generic type the matched method is expected to define as a parameter type.
     * @param              The type of the matched object.
     * @return An element matcher that matches a given generic return type for a method description.
     */
    public static  ElementMatcher.Junction takesGenericArgument(int index, TypeDescription.Generic type) {
        return takesGenericArgument(index, is(type));
    }

    /**
     * Matches {@link MethodDescription}s that define a given generic type as a parameter at the given index.
     *
     * @param index   The index of the parameter.
     * @param matcher A matcher for the generic type the matched method is expected to define as a parameter type.
     * @param      The type of the matched object.
     * @return An element matcher that matches a given generic return type for a method description.
     */
    public static  ElementMatcher.Junction takesGenericArgument(int index, ElementMatcher matcher) {
        return takesGenericArguments(new CollectionElementMatcher(index, matcher));
    }

    /**
     * Matches a method description that takes the provided generic arguments.
     *
     * @param type The arguments to match against the matched method.
     * @param   The type of the matched object.
     * @return A method matcher that matches a method's generic parameter types against the supplied arguments.
     */
    public static  ElementMatcher.Junction takesGenericArguments(Type... type) {
        return takesGenericArguments(new TypeList.Generic.ForLoadedTypes(type));
    }

    /**
     * Matches a method description that takes the provided generic arguments.
     *
     * @param type The arguments to match against the matched method.
     * @param             The type of the matched object.
     * @return A method matcher that matches a method's generic parameter types against the supplied arguments.
     */
    public static  ElementMatcher.Junction takesGenericArguments(TypeDefinition... type) {
        return takesGenericArguments((Arrays.asList(type)));
    }

    /**
     * Matches a method description that takes the provided generic arguments.
     *
     * @param types The arguments to match against the matched method.
     * @param              The type of the matched object.
     * @return A method matcher that matches a method's generic parameter types against the supplied arguments.
     */
    public static  ElementMatcher.Junction takesGenericArguments(List types) {
        List> typeMatchers = new ArrayList>();
        for (TypeDefinition type : types) {
            typeMatchers.add(is(type));
        }
        return takesGenericArguments(new CollectionOneToOneMatcher(typeMatchers));
    }

    /**
     * Matches a {@link MethodDescription} by applying an iterable collection of element matcher on any parameter's {@link TypeDescription}.
     *
     * @param matchers The matcher that are applied onto the parameter types of the matched method description.
     * @param       The type of the matched object.
     * @return A matcher that matches a method description by applying another element matcher onto each
     * parameter's type.
     */
    public static  ElementMatcher.Junction takesGenericArguments(ElementMatcher> matchers) {
        return new MethodParametersMatcher(new MethodParameterTypesMatcher>(matchers));
    }

    /**
     * Matches {@link MethodDescription}s that define a given generic type as a parameter at the given index.
     *
     * @param index The index of the parameter.
     * @param type  The erasure of the type the matched method is expected to define as a parameter type.
     * @param    The type of the matched object.
     * @return An element matcher that matches a given generic return type for a method description.
     */
    public static  ElementMatcher.Junction takesArgument(int index, Class type) {
        return takesGenericArgument(index, rawType(type));
    }

    /**
     * Matches {@link MethodDescription}s that define a given generic type as a parameter at the given index.
     *
     * @param index The index of the parameter.
     * @param type  The erasure of the type the matched method is expected to define as a parameter type.
     * @param    The type of the matched object.
     * @return An element matcher that matches a given generic return type for a method description.
     */
    public static  ElementMatcher.Junction takesArgument(int index, TypeDescription type) {
        return takesGenericArgument(index, rawType(type));
    }

    /**
     * Matches a method description that takes the provided raw arguments.
     *
     * @param type The arguments to match against the matched method.
     * @param   The type of the matched object.
     * @return A method matcher that matches a method's raw parameter types against the supplied arguments.
     */
    public static  ElementMatcher.Junction takesArguments(Class... type) {
        return takesGenericArguments(rawTypes(type));
    }

    /**
     * Matches a method description that takes the provided raw arguments.
     *
     * @param type The arguments to match against the matched method.
     * @param              The type of the matched object.
     * @return A method matcher that matches a method's raw parameter types against the supplied arguments.
     */
    public static  ElementMatcher.Junction takesArguments(TypeDescription... type) {
        return takesGenericArguments(rawTypes(type));
    }

    /**
     * Matches a method description that takes the provided raw arguments.
     *
     * @param types The arguments to match against the matched method.
     * @param               The type of the matched object.
     * @return A method matcher that matches a method's raw parameter types against the supplied arguments.
     */
    public static  ElementMatcher.Junction takesArguments(Iterable types) {
        List> typeMatchers = new ArrayList>();
        for (TypeDescription type : types) {
            typeMatchers.add(rawType(type));
        }
        return takesGenericArguments(new CollectionOneToOneMatcher(typeMatchers));
    }

    /**
     * Matches a {@link MethodDescription} by the number of its parameters.
     *
     * @param length The expected length.
     * @param     The type of the matched object.
     * @return A matcher that matches a method description by the number of its parameters.
     */
    public static  ElementMatcher.Junction takesArguments(int length) {
        return new MethodParametersMatcher(new CollectionSizeMatcher>(length));
    }

    /**
     * Matches a {@link MethodDescription} by validating that its parameters
     * fulfill a given constraint.
     *
     * @param matcher The matcher to apply for validating the parameters.
     * @param      The type of the matched object.
     * @return A matcher that matches a method description's parameters against the given constraint.
     */
    public static  ElementMatcher.Junction hasParameters(
            ElementMatcher> matcher) {
        return new MethodParametersMatcher(matcher);
    }

    /**
     * Matches a {@link MethodDescription} by its capability to throw a given
     * checked exception. For specifying a non-checked exception, any method is matched.
     *
     * @param exceptionType The type of the exception that should be declared by the method to be matched.
     * @param            The type of the matched object.
     * @return A matcher that matches a method description by its declaration of throwing a checked exception.
     */
    public static  ElementMatcher.Junction canThrow(Class exceptionType) {
        return canThrow(new TypeDescription.ForLoadedType(exceptionType));
    }

    /**
     * Matches a {@link MethodDescription} by its capability to throw a given
     * checked exception. For specifying a non-checked exception, any method is matched.
     *
     * @param exceptionType The type of the exception that should be declared by the method to be matched.
     * @param            The type of the matched object.
     * @return A matcher that matches a method description by its declaration of throwing a checked exception.
     */
    public static  ElementMatcher.Junction canThrow(TypeDescription exceptionType) {
        return exceptionType.isAssignableTo(RuntimeException.class) || exceptionType.isAssignableTo(Error.class)
                ? new BooleanMatcher(true)
                : ElementMatchers.declaresGenericException(new CollectionItemMatcher(rawType(isSuperTypeOf(exceptionType))));
    }

    /**
     * Matches a method that declares the given generic exception type. For non-generic type, this matcher behaves identically to
     * {@link ElementMatchers#declaresException(Class)}. For exceptions that are expressed as type variables, only exceptions
     * that are represented as this type variable are matched.
     *
     * @param exceptionType The generic exception type that is matched exactly.
     * @param            The type of the matched object.
     * @return A matcher that matches any method that exactly matches the provided generic exception.
     */
    public static  ElementMatcher.Junction declaresGenericException(Type exceptionType) {
        return declaresGenericException(TypeDefinition.Sort.describe(exceptionType));
    }

    /**
     * Matches a method that declares the given generic exception type. For non-generic type, this matcher behaves identically to
     * {@link ElementMatchers#declaresException(TypeDescription)}. For exceptions that are expressed as type variables, only exceptions
     * that are represented as this type variable are matched.
     *
     * @param exceptionType The generic exception type that is matched exactly.
     * @param            The type of the matched object.
     * @return A matcher that matches any method that exactly matches the provided generic exception.
     */
    public static  ElementMatcher.Junction declaresGenericException(TypeDescription.Generic exceptionType) {
        return !exceptionType.getSort().isWildcard() && exceptionType.asErasure().isAssignableTo(Throwable.class)
                ? ElementMatchers.declaresGenericException(new CollectionItemMatcher(is(exceptionType)))
                : new BooleanMatcher(false);
    }

    /**
     * Matches a method that declares the given generic exception type as a (erased) exception type.
     *
     * @param exceptionType The exception type that is matched.
     * @param            The type of the matched object.
     * @return A matcher that matches any method that exactly matches the provided exception.
     */
    public static  ElementMatcher.Junction declaresException(Class exceptionType) {
        return declaresException(new TypeDescription.ForLoadedType(exceptionType));
    }

    /**
     * Matches a method that declares the given generic exception type as a (erased) exception type.
     *
     * @param exceptionType The exception type that is matched.
     * @param            The type of the matched object.
     * @return A matcher that matches any method that exactly matches the provided exception.
     */
    public static  ElementMatcher.Junction declaresException(TypeDescription exceptionType) {
        return exceptionType.isAssignableTo(Throwable.class)
                ? ElementMatchers.declaresGenericException(new CollectionItemMatcher(rawType(exceptionType)))
                : new BooleanMatcher(false);
    }

    /**
     * Matches a method's generic exception types against the provided matcher.
     *
     * @param exceptionMatcher The exception matcher to apply onto the matched method's generic exceptions.
     * @param               The type of the matched object.
     * @return A matcher that applies the provided matcher to a method's generic exception types.
     */
    public static  ElementMatcher.Junction declaresGenericException(
            ElementMatcher> exceptionMatcher) {
        return new MethodExceptionTypeMatcher(exceptionMatcher);
    }

    /**
     * Matches a {@link TypeDescription} that is an interface.
     *
     * @param  The type of the matched object.
     * @return A matcher for an interface.
     */
    public static  ElementMatcher.Junction isInterface() {
        return new ModifierMatcher(ModifierMatcher.Mode.INTERFACE);
    }

    /**
     * Only matches method descriptions that represent a {@link java.lang.reflect.Method}.
     *
     * @param  The type of the matched object.
     * @return A matcher that only matches method descriptions that represent a Java method.
     */
    public static  ElementMatcher.Junction isMethod() {
        return new MethodSortMatcher(MethodSortMatcher.Sort.METHOD);
    }

    /**
     * Only matches method descriptions that represent a {@link java.lang.reflect.Constructor}.
     *
     * @param  The type of the matched object.
     * @return A matcher that only matches method descriptions that represent a Java constructor.
     */
    public static  ElementMatcher.Junction isConstructor() {
        return new MethodSortMatcher(MethodSortMatcher.Sort.CONSTRUCTOR);
    }

    /**
     * Only matches method descriptions that represent a {@link java.lang.Class} type initializer.
     *
     * @param  The type of the matched object.
     * @return A matcher that only matches method descriptions that represent the type initializer.
     */
    public static  ElementMatcher.Junction isTypeInitializer() {
        return new MethodSortMatcher(MethodSortMatcher.Sort.TYPE_INITIALIZER);
    }

    /**
     * Matches any method that is virtual, i.e. non-constructors that are non-static and non-private.
     *
     * @param  The type of the matched object.
     * @return A matcher for virtual methods.
     */
    public static  ElementMatcher.Junction isVirtual() {
        return new MethodSortMatcher(MethodSortMatcher.Sort.VIRTUAL);
    }

    /**
     * Only matches Java 8 default methods.
     *
     * @param  The type of the matched object.
     * @return A matcher that only matches Java 8 default methods.
     */
    public static  ElementMatcher.Junction isDefaultMethod() {
        return new MethodSortMatcher(MethodSortMatcher.Sort.DEFAULT_METHOD);
    }

    /**
     * Matches a default constructor, i.e. a constructor without arguments.
     *
     * @param  The type of the matched object.
     * @return A matcher that matches a default constructor.
     */
    public static  ElementMatcher.Junction isDefaultConstructor() {
        return isConstructor().and(takesArguments(0));
    }

    /**
     * Only matches the {@link Object#finalize()} method if it was not overridden.
     *
     * @param  The type of the matched object.
     * @return A matcher that only matches a non-overridden {@link Object#finalize()} method.
     */
    public static  ElementMatcher.Junction isDefaultFinalizer() {
        return isFinalizer().and(isDeclaredBy(TypeDescription.OBJECT));
    }

    /**
     * Only matches the {@link Object#finalize()} method, even if it was overridden.
     *
     * @param  The type of the matched object.
     * @return A matcher that only matches the {@link Object#finalize()} method.
     */
    public static  ElementMatcher.Junction isFinalizer() {
        return named("finalize").and(takesArguments(0)).and(returns(TypeDescription.VOID));
    }

    /**
     * Only matches the {@link Object#toString()} method, also if it was overridden.
     *
     * @param  The type of the matched object.
     * @return A matcher that only matches the {@link Object#toString()} method.
     */
    public static  ElementMatcher.Junction isHashCode() {
        return named("hashCode").and(takesArguments(0)).and(returns(int.class));
    }

    /**
     * Only matches the {@link Object#equals(Object)} method, also if it was overridden.
     *
     * @param  The type of the matched object.
     * @return A matcher that only matches the {@link Object#equals(Object)} method.
     */
    public static  ElementMatcher.Junction isEquals() {
        return named("equals").and(takesArguments(TypeDescription.OBJECT)).and(returns(boolean.class));
    }

    /**
     * Only matches the {@link Object#clone()} method, also if it was overridden.
     *
     * @param  The type of the matched object.
     * @return A matcher that only matches the {@link Object#clone()} method.
     */
    public static  ElementMatcher.Junction isClone() {
        return named("clone").and(takesArguments(0)).and(returns(TypeDescription.OBJECT));
    }

    /**
     * Only matches the {@link Object#toString()} method, also if it was overridden.
     *
     * @param  The type of the matched object.
     * @return A matcher that only matches the {@link Object#toString()} method.
     */
    public static  ElementMatcher.Junction isToString() {
        return named("toString").and(takesArguments(0)).and(returns(TypeDescription.STRING));
    }

    /**
     * Matches any Java bean setter method.
     *
     * @param  The type of the matched object.
     * @return A matcher that matches any setter method.
     */
    public static  ElementMatcher.Junction isSetter() {
        return nameStartsWith("set").and(takesArguments(1)).and(returns(TypeDescription.VOID));
    }

    /**
     * Matches any Java bean setter method which takes an argument the given type.
     *
     * @param type The required setter type.
     * @param   The type of the matched object.
     * @return A matcher that matches any setter method.
     */
    public static  ElementMatcher.Junction isSetter(Type type) {
        return isSetter(TypeDefinition.Sort.describe(type));
    }

    /**
     * Matches any Java bean setter method which takes an argument the given type.
     *
     * @param type The required setter type.
     * @param              The type of the matched object.
     * @return A matcher that matches a setter method with the specified argument type.
     */
    public static  ElementMatcher.Junction isSetter(TypeDescription.Generic type) {
        return isSetter(is(type));
    }

    /**
     * Matches any Java bean setter method which takes an argument that matches the supplied matcher.
     *
     * @param matcher A matcher to be allied to a setter method's argument type.
     * @param      The type of the matched object.
     * @return A matcher that matches a setter method with an argument type that matches the supplied matcher.
     */
    public static  ElementMatcher.Junction isSetter(ElementMatcher matcher) {
        return isSetter().and(takesGenericArguments(new CollectionOneToOneMatcher(Collections.singletonList(matcher))));
    }

    /**
     * Matches any Java bean getter method.
     *
     * @param  The type of the matched object.
     * @return A matcher that matches any getter method.
     */
    public static  ElementMatcher.Junction isGetter() {
        return takesArguments(0).and(not(returns(TypeDescription.VOID))).and(nameStartsWith("get")
                .or(nameStartsWith("is").and(returnsGeneric(anyOf(boolean.class, Boolean.class)))));
    }

    /**
     * Matches any Java bean getter method which returns the given type.
     *
     * @param type The required getter type.
     * @param   The type of the matched object.
     * @return A matcher that matches a getter method with the given type.
     */
    public static  ElementMatcher.Junction isGetter(Type type) {
        return isGetter(TypeDefinition.Sort.describe(type));
    }

    /**
     * Matches any Java bean getter method which returns the given type.
     *
     * @param type The required getter type.
     * @param              The type of the matched object.
     * @return A matcher that matches a getter method with the given type.
     */
    public static  ElementMatcher.Junction isGetter(TypeDescription.Generic type) {
        return isGetter(is(type));
    }

    /**
     * Matches any Java bean getter method which returns an value with a type matches the supplied matcher.
     *
     * @param matcher A matcher to be allied to a getter method's argument type.
     * @param      The type of the matched object.
     * @return A matcher that matches a getter method with a return type that matches the supplied matcher.
     */
    public static  ElementMatcher.Junction isGetter(ElementMatcher matcher) {
        return isGetter().and(returnsGeneric(matcher));
    }

    /**
     * Matches a method against its internal name such that constructors and type initializers are matched appropriately.
     *
     * @param internalName The internal name of the method.
     * @param           The type of the matched object.
     * @return A matcher for a method with the provided internal name.
     */
    public static  ElementMatcher.Junction hasMethodName(String internalName) {
        if (MethodDescription.CONSTRUCTOR_INTERNAL_NAME.equals(internalName)) {
            return isConstructor();
        } else if (MethodDescription.TYPE_INITIALIZER_INTERNAL_NAME.equals(internalName)) {
            return isTypeInitializer();
        } else {
            return named(internalName);
        }
    }

    /**
     * Matches any type description that is a subtype of the given type.
     *
     * @param type The type to be checked being a super type of the matched type.
     * @param   The type of the matched object.
     * @return A matcher that matches any type description that represents a sub type of the given type.
     */
    public static  ElementMatcher.Junction isSubTypeOf(Class type) {
        return isSubTypeOf(new TypeDescription.ForLoadedType(type));
    }

    /**
     * Matches any type description that is a subtype of the given type.
     *
     * @param type The type to be checked being a super type of the matched type.
     * @param              The type of the matched object.
     * @return A matcher that matches any type description that represents a sub type of the given type.
     */
    public static  ElementMatcher.Junction isSubTypeOf(TypeDescription type) {
        return new SubTypeMatcher(type);
    }

    /**
     * Matches any type description that is a super type of the given type.
     *
     * @param type The type to be checked being a subtype of the matched type.
     * @param   The type of the matched object.
     * @return A matcher that matches any type description that represents a super type of the given type.
     */
    public static  ElementMatcher.Junction isSuperTypeOf(Class type) {
        return isSuperTypeOf(new TypeDescription.ForLoadedType(type));
    }

    /**
     * Matches any type description that is a super type of the given type.
     *
     * @param type The type to be checked being a subtype of the matched type.
     * @param              The type of the matched object.
     * @return A matcher that matches any type description that represents a super type of the given type.
     */
    public static  ElementMatcher.Junction isSuperTypeOf(TypeDescription type) {
        return new SuperTypeMatcher(type);
    }

    /**
     * Matches any annotations by their type on a type that declared these annotations or inherited them from its
     * super classes.
     *
     * @param type The annotation type to be matched.
     * @param   The type of the matched object.
     * @return A matcher that matches any inherited annotation by their type.
     */
    public static  ElementMatcher.Junction inheritsAnnotation(Class type) {
        return inheritsAnnotation(new TypeDescription.ForLoadedType(type));
    }

    /**
     * Matches any annotations by their type on a type that declared these annotations or inherited them from its
     * super classes.
     *
     * @param type The annotation type to be matched.
     * @param              The type of the matched object.
     * @return A matcher that matches any inherited annotation by their type.
     */
    public static  ElementMatcher.Junction inheritsAnnotation(TypeDescription type) {
        return inheritsAnnotation(is(type));
    }

    /**
     * Matches any annotations by a given matcher on a type that declared these annotations or inherited them from its
     * super classes.
     *
     * @param matcher A matcher to apply onto the inherited annotations.
     * @param      The type of the matched object.
     * @return A matcher that matches any inherited annotation by a given matcher.
     */
    public static  ElementMatcher.Junction inheritsAnnotation(ElementMatcher matcher) {
        return hasAnnotation(new AnnotationTypeMatcher(matcher));
    }

    /**
     * Matches a list of annotations by a given matcher on a type that declared these annotations or inherited them
     * from its super classes.
     *
     * @param matcher A matcher to apply onto a list of inherited annotations.
     * @param      The type of the matched object.
     * @return A matcher that matches a list of inherited annotation by a given matcher.
     */
    public static  ElementMatcher.Junction hasAnnotation(ElementMatcher matcher) {
        return new InheritedAnnotationMatcher(new CollectionItemMatcher(matcher));
    }

    /**
     * Matches a type by a another matcher that is applied on any of its declared fields.
     *
     * @param fieldMatcher The matcher that is applied onto each declared field.
     * @param           The type of the matched object.
     * @return A matcher that matches any type where another matcher is matched positively on at least on declared field.
     */
    public static  ElementMatcher.Junction declaresField(ElementMatcher fieldMatcher) {
        return new DeclaringFieldMatcher(new CollectionItemMatcher(fieldMatcher));
    }

    /**
     * Matches a type by a another matcher that is applied on any of its declared methods.
     *
     * @param methodMatcher The matcher that is applied onto each declared method.
     * @param            The type of the matched object.
     * @return A matcher that matches any type where another matcher is matched positively on at least on declared methods.
     */
    public static  ElementMatcher.Junction declaresMethod(ElementMatcher methodMatcher) {
        return new DeclaringMethodMatcher(new CollectionItemMatcher(methodMatcher));
    }

    /**
     * Matches generic type descriptions of the given sort.
     *
     * @param sort The generic type sort to match.
     * @param   The type of the matched object.
     * @return A matcher that matches generic types of the given sort.
     */
    public static  ElementMatcher.Junction ofSort(TypeDefinition.Sort sort) {
        return ofSort(is(sort));
    }

    /**
     * Matches generic type descriptions of the given sort.
     *
     * @param matcher A matcher for a generic type's sort.
     * @param      The type of the matched object.
     * @return A matcher that matches generic types of the given sort.
     */
    public static  ElementMatcher.Junction ofSort(ElementMatcher matcher) {
        return new TypeSortMatcher(matcher);
    }

    /**
     * Matches a field's generic type against the provided matcher.
     *
     * @param fieldType The field type to match.
     * @param        The type of the matched object.
     * @return A matcher matching the provided field type.
     */
    public static  ElementMatcher.Junction genericFieldType(Type fieldType) {
        return genericFieldType(TypeDefinition.Sort.describe(fieldType));
    }

    /**
     * Matches a field's generic type against the provided matcher.
     *
     * @param fieldType The field type to match.
     * @param        The type of the matched object.
     * @return A matcher matching the provided field type.
     */
    public static  ElementMatcher.Junction genericFieldType(TypeDescription.Generic fieldType) {
        return genericFieldType(is(fieldType));
    }

    /**
     * Matches a field's generic type against the provided matcher.
     *
     * @param matcher The matcher to apply to the field's type.
     * @param      The type of the matched object.
     * @return A matcher matching the provided field type.
     */
    public static  ElementMatcher.Junction genericFieldType(ElementMatcher matcher) {
        return new FieldTypeMatcher(matcher);
    }

    /**
     * Matches a field's raw type against the provided matcher.
     *
     * @param fieldType The field type to match.
     * @param        The type of the matched object.
     * @return A matcher matching the provided field type.
     */
    public static  ElementMatcher.Junction fieldType(Class fieldType) {
        return fieldType(new TypeDescription.ForLoadedType(fieldType));
    }

    /**
     * Matches a field's raw type against the provided matcher.
     *
     * @param fieldType The field type to match.
     * @param        The type of the matched object.
     * @return A matcher matching the provided field type.
     */
    public static  ElementMatcher.Junction fieldType(TypeDescription fieldType) {
        return fieldType(is(fieldType));
    }

    /**
     * Matches a field's raw type against the provided matcher.
     *
     * @param matcher The matcher to apply to the field's type.
     * @param      The type of the matched object.
     * @return A matcher matching the provided field type.
     */
    public static  ElementMatcher.Junction fieldType(ElementMatcher matcher) {
        return genericFieldType(rawType(matcher));
    }

    /**
     * Matches exactly the bootstrap {@link java.lang.ClassLoader} . The returned matcher is a synonym to
     * a matcher matching {@code null}.
     *
     * @param  The type of the matched object.
     * @return A matcher that only matches the bootstrap class loader.
     */
    public static  ElementMatcher isBootstrapClassLoader() {
        return new NullMatcher();
    }

    /**
     * Matches exactly the system {@link java.lang.ClassLoader}. The returned matcher is a synonym to
     * a matcher matching {@code ClassLoader.gerSystemClassLoader()}.
     *
     * @param  The type of the matched object.
     * @return A matcher that only matches the system class loader.
     */
    public static  ElementMatcher isSystemClassLoader() {
        return new EqualityMatcher(ClassLoader.getSystemClassLoader());
    }

    /**
     * Matches exactly the extension {@link java.lang.ClassLoader}. The returned matcher is a synonym to
     * a matcher matching {@code ClassLoader.gerSystemClassLoader().getParent()}.
     *
     * @param  The type of the matched object.
     * @return A matcher that only matches the extension class loader.
     */
    public static  ElementMatcher isExtensionClassLoader() {
        return new EqualityMatcher(ClassLoader.getSystemClassLoader().getParent());
    }

    /**
     * Matches any class loader that is either the given class loader or a child of the given class loader.
     *
     * @param classLoader The class loader of which child class loaders are matched.
     * @param          The type of the matched object.
     * @return A matcher that matches the given class loader and any class loader that is a child of the given
     * class loader.
     */
    public static  ElementMatcher isChildOf(ClassLoader classLoader) {
        return classLoader == BOOTSTRAP_CLASSLOADER
                ? new BooleanMatcher(true)
                : ElementMatchers.hasChild(is(classLoader));
    }

    /**
     * Matches all class loaders in the hierarchy of the matched class loader against a given matcher.
     *
     * @param matcher The matcher to apply to all class loaders in the hierarchy of the matched class loader.
     * @param      The type of the matched object.
     * @return A matcher that matches all class loaders in the hierarchy of the matched class loader.
     */
    public static  ElementMatcher hasChild(ElementMatcher matcher) {
        return new ClassLoaderHierarchyMatcher(matcher);
    }

    /**
     * Matches any class loader that is either the given class loader or a parent of the given class loader.
     *
     * @param classLoader The class loader of which parent class loaders are matched.
     * @param          The type of the matched object.
     * @return A matcher that matches the given class loader and any class loader that is a parent of the given
     * class loader.
     */
    public static  ElementMatcher isParentOf(ClassLoader classLoader) {
        return classLoader == BOOTSTRAP_CLASSLOADER
                ? ElementMatchers.isBootstrapClassLoader()
                : new ClassLoaderParentMatcher(classLoader);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy