Skip to content

Commit 3e86f6e

Browse files
committed
feat: meta-annotation that allows annotations to propagate multiple times
This is useful when we want some mutators for types with common ancestors (or even all types in the fuzz test method) to share common annotations. E.g. we can annotate the fuzz test method with an annotation that will be used by all String mutators, but in addition we also want that some String mutators have the same annotation but with different data.
1 parent 490ed81 commit 3e86f6e

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

src/main/java/com/code_intelligence/jazzer/mutation/support/TypeSupport.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
import com.code_intelligence.jazzer.mutation.annotation.NotNull;
2929
import com.code_intelligence.jazzer.mutation.annotation.WithLength;
30+
import com.code_intelligence.jazzer.mutation.utils.IgnoreRecursiveConflicts;
3031
import com.code_intelligence.jazzer.mutation.utils.PropertyConstraint;
3132
import java.lang.annotation.Annotation;
3233
import java.lang.annotation.Inherited;
@@ -578,6 +579,9 @@ private static Annotation[] checkExtraAnnotations(
578579
.collect(Collectors.toCollection(HashSet::new));
579580
for (Annotation annotation : extraAnnotations) {
580581
boolean added = existingAnnotationTypes.add(annotation.annotationType());
582+
if (annotation.annotationType().isAnnotationPresent(IgnoreRecursiveConflicts.class)) {
583+
continue;
584+
}
581585
require(added, annotation + " already directly present on " + base);
582586
}
583587
return extraAnnotations;
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright 2025 Code Intelligence GmbH
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.code_intelligence.jazzer.mutation.utils;
18+
19+
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
20+
import static java.lang.annotation.RetentionPolicy.RUNTIME;
21+
22+
import java.lang.annotation.Documented;
23+
import java.lang.annotation.Retention;
24+
import java.lang.annotation.Target;
25+
26+
/**
27+
* A meta-annotation to turn off the check in {@code checkExtraAnnotations} that throws if some
28+
* annotation is present multiple times on a type. This allows annotations like e.g.
29+
* {@code @DictionaryProvider} to be propagated down the type hierarchy and accumulated alone the
30+
* way. <br>
31+
* E.g. {@code @A("data1") List<@A("data2") String> arg} - the String mutator will can make use of
32+
* {@code @A("data1")} and {@code @A("data1")}, but the List mutator can only see
33+
* {@code @A("data1")}.
34+
*/
35+
@Target(ANNOTATION_TYPE)
36+
@Retention(RUNTIME)
37+
@Documented
38+
public @interface IgnoreRecursiveConflicts {}

0 commit comments

Comments
 (0)