Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License.
* This product includes software developed at Datadog (https://www.datadoghq.com/).
* Copyright 2025-Present Datadog, Inc.
*/

package datadog.instrument.classmatch;

import java.lang.reflect.Modifier;
import java.util.function.IntPredicate;

/**
* Predicate for matching access modifiers defined in <a
* href="https://docs.oracle.com/javase/specs/jvms/se24/html/jvms-4.html">class-files</a>.
*/
@FunctionalInterface
public interface AccessMatcher extends IntPredicate {

/** Matches public access. */
AccessMatcher PUBLIC = Modifier::isPublic;

/** Matches private access. */
AccessMatcher PRIVATE = Modifier::isPrivate;

/** Matches protected access. */
AccessMatcher PROTECTED = Modifier::isProtected;

/** Matches package-private access. */
AccessMatcher PACKAGE_PRIVATE =
acc -> (acc & (Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE)) == 0;

/** Matches static methods/fields. */
AccessMatcher STATIC = Modifier::isStatic;

/** Matches non-static methods/fields. */
AccessMatcher INSTANCE = acc -> (acc & Modifier.STATIC) == 0;

/** Matches final classes/methods/fields. */
AccessMatcher FINAL = Modifier::isFinal;

/** Matches non-final classes/methods/fields. */
AccessMatcher NON_FINAL = acc -> (acc & Modifier.FINAL) == 0;

/** Matches synchronized methods. */
AccessMatcher SYNCHRONIZED = Modifier::isSynchronized;

/** Matches varargs methods. */
AccessMatcher VARARGS = acc -> (acc & 0x0080) != 0;

/** Matches volatile fields. */
AccessMatcher VOLATILE = Modifier::isVolatile;

/** Matches transient fields. */
AccessMatcher TRANSIENT = Modifier::isTransient;

/** Matches interface classes. */
AccessMatcher INTERFACE = Modifier::isInterface;

/** Matches non-interface classes. */
AccessMatcher CLASS = acc -> (acc & Modifier.INTERFACE) == 0;

/** Matches abstract classes/methods. */
AccessMatcher ABSTRACT = Modifier::isAbstract;

/** Matches non-abstract classes/methods. */
AccessMatcher CONCRETE = acc -> (acc & Modifier.ABSTRACT) == 0;

/**
* Conjunction of this matcher AND another.
*
* @param other the other matcher
* @return conjunction of both matchers
*/
default AccessMatcher and(AccessMatcher other) {
// simple approach as we don't expect many access-matcher unions
return acc -> test(acc) && other.test(acc);
}

/**
* Disjunction of this matcher OR another.
*
* @param other the other matcher
* @return disjunction of both matchers
*/
default AccessMatcher or(AccessMatcher other) {
// simple approach as we don't expect many access-matcher unions
return acc -> test(acc) || other.test(acc);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import static java.util.Arrays.asList;

import java.util.Collection;
import java.util.function.IntPredicate;
import java.util.function.Predicate;

/** Fluent-API for building {@link ClassOutline} predicates. */
Expand All @@ -36,7 +35,7 @@ static ClassMatcher declares(FieldMatcher fieldMatcher) {
* @param fieldMatcher the field matcher
* @return matcher of classes with a matching field
*/
static ClassMatcher declares(IntPredicate accessMatcher, FieldMatcher fieldMatcher) {
static ClassMatcher declares(AccessMatcher accessMatcher, FieldMatcher fieldMatcher) {
FieldMatcher combinedMatcher = fieldMatcher.access(accessMatcher);
return c -> anyMatch(c.fields, combinedMatcher);
}
Expand All @@ -58,7 +57,7 @@ static ClassMatcher declares(MethodMatcher methodMatcher) {
* @param methodMatcher the method matcher
* @return matcher of classes with a matching method
*/
static ClassMatcher declares(IntPredicate accessMatcher, MethodMatcher methodMatcher) {
static ClassMatcher declares(AccessMatcher accessMatcher, MethodMatcher methodMatcher) {
MethodMatcher combinedMatcher = methodMatcher.access(accessMatcher);
return c -> anyMatch(c.methods, combinedMatcher);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

import static datadog.instrument.classmatch.InternalMatchers.descriptor;

import java.util.function.IntPredicate;
import java.util.function.Predicate;

/** Fluent-API for building {@link FieldOutline} predicates. */
Expand Down Expand Up @@ -41,7 +40,7 @@ static FieldMatcher field(Predicate<String> nameMatcher) {
* @param accessMatcher the access matcher
* @return matcher of fields with matching access
*/
default FieldMatcher access(IntPredicate accessMatcher) {
default FieldMatcher access(AccessMatcher accessMatcher) {
return f -> test(f) && accessMatcher.test(f.access);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
import static java.util.Arrays.asList;

import java.util.Collection;
import java.util.function.IntPredicate;
import java.util.function.Predicate;

/** Fluent-API for building {@link MethodOutline} predicates. */
Expand Down Expand Up @@ -76,7 +75,7 @@ static MethodMatcher staticInitializer() {
* @param accessMatcher the access matcher
* @return matcher of methods with matching access
*/
default MethodMatcher access(IntPredicate accessMatcher) {
default MethodMatcher access(AccessMatcher accessMatcher) {
return and(m -> accessMatcher.test(m.access));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,58 +8,63 @@

import static java.util.Arrays.asList;

import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.HashSet;
import java.util.function.IntPredicate;
import java.util.function.Predicate;

/** Standard matchers, part of the public API. */
public final class StandardMatchers {

/** Matches public access. */
public static final IntPredicate PUBLIC = Modifier::isPublic;

/** Matches private access. */
public static final IntPredicate PRIVATE = Modifier::isPrivate;

/** Matches protected access. */
public static final IntPredicate PROTECTED = Modifier::isProtected;

/** Matches static access. */
public static final IntPredicate STATIC = Modifier::isStatic;

/** Matches final classes/methods/fields. */
public static final IntPredicate FINAL = Modifier::isFinal;

/** Matches synchronized methods. */
public static final IntPredicate SYNCHRONIZED = Modifier::isSynchronized;

/** Matches volatile fields. */
public static final IntPredicate VOLATILE = Modifier::isVolatile;

/** Matches transient fields. */
public static final IntPredicate TRANSIENT = Modifier::isTransient;
private StandardMatchers() {}

/** Matches native methods. */
public static final IntPredicate NATIVE = Modifier::isNative;
/**
* Negates the given type matcher.
*
* @param matcher the matcher to negate
* @return negation of the matcher
*/
public static TypeMatcher not(TypeMatcher matcher) {
return cs -> !matcher.test(cs);
}

/** Matches interface classes. */
public static final IntPredicate INTERFACE = Modifier::isInterface;
/**
* Negates the given class matcher.
*
* @param matcher the matcher to negate
* @return negation of the matcher
*/
public static ClassMatcher not(ClassMatcher matcher) {
return c -> !matcher.test(c);
}

/** Matches abstract classes. */
public static final IntPredicate ABSTRACT = Modifier::isAbstract;
/**
* Negates the given field matcher.
*
* @param matcher the matcher to negate
* @return negation of the matcher
*/
public static FieldMatcher not(FieldMatcher matcher) {
return f -> !matcher.test(f);
}

private StandardMatchers() {}
/**
* Negates the given method matcher.
*
* @param matcher the matcher to negate
* @return negation of the matcher
*/
public static MethodMatcher not(MethodMatcher matcher) {
return m -> !matcher.test(m);
}

/**
* Syntactic sugar around {@link IntPredicate#negate()}.
* Negates the given access matcher.
*
* @param predicate the predicate to negate
* @return negated predicate
* @param matcher the matcher to negate
* @return negation of the matcher
*/
public static IntPredicate not(IntPredicate predicate) {
return predicate.negate();
public static AccessMatcher not(AccessMatcher matcher) {
return acc -> !matcher.test(acc);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import java.util.function.Predicate;

/** Fluent-API for building type hierarchy predicates. */
@FunctionalInterface
public interface TypeMatcher extends Predicate<CharSequence> {

/**
Expand Down