From e005d46fdb5bb848b6ac2e26c1901be307f5f393 Mon Sep 17 00:00:00 2001 From: Stuart McCulloch Date: Fri, 30 Oct 2026 19:10:39 +0000 Subject: [PATCH] Exclude constructors and static initializers from the simple 'method()' matcher --- .../classmatch/InternalMatchers.java | 30 ++++++++++++++----- .../instrument/classmatch/MethodMatcher.java | 2 +- .../classmatch/MethodMatcherTest.java | 14 +++++++-- 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/class-match/src/main/java/datadog/instrument/classmatch/InternalMatchers.java b/class-match/src/main/java/datadog/instrument/classmatch/InternalMatchers.java index 33692eb..c308d2d 100644 --- a/class-match/src/main/java/datadog/instrument/classmatch/InternalMatchers.java +++ b/class-match/src/main/java/datadog/instrument/classmatch/InternalMatchers.java @@ -126,25 +126,39 @@ static boolean anyMatch(T[] candidates, Predicate matcher) { return false; } - /** Optimized for {@link MethodMatcher#method()} to avoid unnecessary object creation. */ + /** Matches all methods, excluding {@code } and {@code }. */ static final MethodMatcher ALL_METHODS = new MethodMatcher() { @Override public boolean test(MethodOutline outline) { - return true; + return outline.methodName.charAt(0) != '<'; } @Override public MethodMatcher and(MethodMatcher other) { - return other; // no need for MethodConjunction - } - - @Override - public MethodMatcher or(MethodMatcher other) { - return this; // no need for MethodDisjunction + return new RegularMethod(other); // make it easier to inline name check } }; + /** Matches regular methods that also match the given matcher. */ + static final class RegularMethod implements MethodMatcher { + private final MethodMatcher matcher; + + RegularMethod(MethodMatcher matcher) { + this.matcher = matcher; + } + + @Override + public boolean test(MethodOutline outline) { + return outline.methodName.charAt(0) != '<' && matcher.test(outline); + } + + @Override + public MethodMatcher and(MethodMatcher other) { + return new RegularMethod(matcher.and(other)); + } + } + /** Logical AND of two {@link ClassMatcher}s; nested conjunctions will be collapsed. */ static final class ClassConjunction extends MatcherUnion implements ClassMatcher { ClassConjunction(ClassMatcher lhs, ClassMatcher rhs) { diff --git a/class-match/src/main/java/datadog/instrument/classmatch/MethodMatcher.java b/class-match/src/main/java/datadog/instrument/classmatch/MethodMatcher.java index 00883f3..50b7003 100644 --- a/class-match/src/main/java/datadog/instrument/classmatch/MethodMatcher.java +++ b/class-match/src/main/java/datadog/instrument/classmatch/MethodMatcher.java @@ -24,7 +24,7 @@ public interface MethodMatcher extends Predicate { /** - * Matches all methods. + * Matches all methods, excluding constructors and static initializers. * * @return matcher of all methods */ diff --git a/class-match/src/test/java/datadog/instrument/classmatch/MethodMatcherTest.java b/class-match/src/test/java/datadog/instrument/classmatch/MethodMatcherTest.java index 8f83563..1e33792 100644 --- a/class-match/src/test/java/datadog/instrument/classmatch/MethodMatcherTest.java +++ b/class-match/src/test/java/datadog/instrument/classmatch/MethodMatcherTest.java @@ -153,11 +153,19 @@ void namesSpecialMethodsAndAccess() { assertMatches(staticInitializer(), clinit, true); assertMatches(constructor(), clinit, false); assertMatches(staticInitializer(), init, false); - assertMatches(method(), init, true); - assertMatches(method(), clinit, true); + assertMatches(method(), ordinary, true); + assertMatches(method(), init, false); + assertMatches(method(), clinit, false); + assertMatches(method().noParameters(), init, false); + assertMatches(method().noParameters(), clinit, false); + assertMatches(method().and(constructor()), init, false); + assertMatches(method().or(constructor()), init, true); + assertMatches(method().or(constructor()), clinit, false); + assertMatches(method().or(staticInitializer()), clinit, true); + assertMatches(method().or(staticInitializer()), init, false); MethodMatcher unexpected = m -> { - throw new AssertionError("all methods should short circuit"); + throw new AssertionError("ordinary methods should short circuit"); }; assertMatches(method().or(unexpected), ordinary, true); }