Skip to content

Commit

Permalink
Nullability refinements (no IntelliJ warnings, fewer null checks)
Browse files Browse the repository at this point in the history
Includes consistent ignoring of all java.lang (meta-)annotations.

Closes gh-22586
  • Loading branch information
jhoeller committed Mar 23, 2019
1 parent 75b5230 commit 5e15338
Show file tree
Hide file tree
Showing 33 changed files with 439 additions and 801 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@
* @since 5.2
* @param <A> the annotation type
*/
abstract class AbstractMergedAnnotation<A extends Annotation>
implements MergedAnnotation<A> {
abstract class AbstractMergedAnnotation<A extends Annotation> implements MergedAnnotation<A> {

@Nullable
private volatile A synthesizedAnnotation;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -828,13 +828,13 @@ private static <A extends Annotation> Comparator<MergedAnnotation<A>> highAggreg
}

@Nullable
private static AnnotationAttributes getAnnotationAttributes(
MergedAnnotation<?> annotation, boolean classValuesAsString,
boolean nestedAnnotationsAsMap) {
private static AnnotationAttributes getAnnotationAttributes(MergedAnnotation<?> annotation,
boolean classValuesAsString, boolean nestedAnnotationsAsMap) {

if (!annotation.isPresent()) {
return null;
}
return annotation.asMap((mergedAnnotation) -> new AnnotationAttributes(),
return annotation.asMap(mergedAnnotation -> new AnnotationAttributes(),
MapValues.of(classValuesAsString, nestedAnnotationsAsMap));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,12 @@ protected Integer findOrder(Object obj) {
return findOrderFromAnnotation(obj);
}

@Nullable
private Integer findOrderFromAnnotation(Object obj) {
AnnotatedElement element = obj instanceof AnnotatedElement
? (AnnotatedElement) obj
: obj.getClass();
MergedAnnotations annotations = MergedAnnotations.from(element,
SearchStrategy.EXHAUSTIVE);
AnnotatedElement element = (obj instanceof AnnotatedElement ? (AnnotatedElement) obj : obj.getClass());
MergedAnnotations annotations = MergedAnnotations.from(element, SearchStrategy.EXHAUSTIVE);
Integer order = OrderUtils.getOrderFromAnnotations(element, annotations);
if (order == null && obj instanceof DecoratingProxy) {
if (order == null && obj instanceof DecoratingProxy) {
return findOrderFromAnnotation(((DecoratingProxy) obj).getDecoratedClass());
}
return order;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import java.util.Arrays;
import java.util.Collection;

import org.springframework.lang.Nullable;
import org.springframework.util.Assert;

/**
Expand All @@ -37,31 +36,27 @@ public interface AnnotationFilter {
* {@code java.lang.*} or in the
* {@code org.springframework.lang.*} package.
*/
static final AnnotationFilter PLAIN = packages("java.lang",
"org.springframework.lang");
AnnotationFilter PLAIN = packages("java.lang", "org.springframework.lang");

/**
* {@link AnnotationFilter} that matches annotations in the
* {@code java.lang.*} package.
*/
static final AnnotationFilter JAVA = packages("java.lang");
AnnotationFilter JAVA = packages("java.lang");

/**
* {@link AnnotationFilter} that never matches and can be used when no
* filtering is needed.
*/
static final AnnotationFilter NONE = new AnnotationFilter() {

AnnotationFilter NONE = new AnnotationFilter() {
@Override
public boolean matches(@Nullable String typeName) {
public boolean matches(String typeName) {
return false;
}

@Override
public String toString() {
return "No annotation filtering";
}

};


Expand All @@ -70,25 +65,26 @@ public String toString() {
* @param annotation the annotation to test
* @return {@code true} if the annotation matches
*/
default boolean matches(@Nullable Annotation annotation) {
return matches(annotation != null ? annotation.annotationType() : null);
default boolean matches(Annotation annotation) {
return matches(annotation.annotationType());
}

/**
* Test if the given type matches the filter.
* @param type the annotation type to test
* @return {@code true} if the annotation matches
*/
default boolean matches(@Nullable Class<?> type) {
return matches(type != null ? type.getName() : null);
default boolean matches(Class<?> type) {
return matches(type.getName());
}

/**
* Test if the given type name matches the filter.
* @param typeName the annotation type to test
* @return {@code true} if the annotation matches
*/
boolean matches(@Nullable String typeName);
boolean matches(String typeName);


/**
* Return a new {@link AnnotationFilter} that matches annotations in the
Expand All @@ -107,8 +103,8 @@ static AnnotationFilter packages(String... packages) {
* @param annotationType the annotation type to check
* @return the most appropriate annotation filter
*/
static AnnotationFilter mostAppropriateFor(@Nullable Class<?> annotationType) {
return PLAIN.matches(annotationType) ? NONE : PLAIN;
static AnnotationFilter mostAppropriateFor(Class<?> annotationType) {
return (PLAIN.matches(annotationType) ? NONE : PLAIN);
}

/**
Expand All @@ -119,30 +115,6 @@ static AnnotationFilter mostAppropriateFor(@Nullable Class<?> annotationType) {
* @return the most appropriate annotation filter
*/
static AnnotationFilter mostAppropriateFor(Class<?>... annotationTypes) {
Assert.notNull(annotationTypes, "AnnotationTypes must not be null");
return mostAppropriateFor(Arrays.asList(annotationTypes));
}

/**
* Return an {@link AnnotationFilter} that is the most appropriate for, and
* will always match all the given annotation type. Whenever possible,
* {@link AnnotationFilter#PLAIN} will be returned.
* @param annotationType the annotation type to check
* @return the most appropriate annotation filter
*/
static AnnotationFilter mostAppropriateFor(@Nullable String annotationType) {
return PLAIN.matches(annotationType) ? NONE : PLAIN;
}

/**
* Return an {@link AnnotationFilter} that is the most appropriate for, and
* will always match all the given annotation types. Whenever possible,
* {@link AnnotationFilter#PLAIN} will be returned.
* @param annotationTypes the annotation types to check
* @return the most appropriate annotation filter
*/
static AnnotationFilter mostAppropriateFor(String... annotationTypes) {
Assert.notNull(annotationTypes, "AnnotationTypes must not be null");
return mostAppropriateFor(Arrays.asList(annotationTypes));
}

Expand All @@ -156,20 +128,16 @@ static AnnotationFilter mostAppropriateFor(String... annotationTypes) {
*/
@SuppressWarnings("unchecked")
static AnnotationFilter mostAppropriateFor(Collection<?> annotationTypes) {
Assert.notNull(annotationTypes, "AnnotationTypes must not be null");
for (Object annotationType : annotationTypes) {
if (annotationType == null) {
continue;
}
Assert.isTrue(
annotationType instanceof Class || annotationType instanceof String,
Assert.isTrue(annotationType instanceof Class || annotationType instanceof String,
"AnnotationType must be a Class or String");
if (annotationType instanceof Class
&& PLAIN.matches((Class<Annotation>) annotationType)) {
if (annotationType instanceof Class && PLAIN.matches((Class<Annotation>) annotationType)) {
return NONE;
}
if (annotationType instanceof String
&& PLAIN.matches((String) annotationType)) {
if (annotationType instanceof String && PLAIN.matches((String) annotationType)) {
return NONE;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
* @since 5.2
* @see AnnotationTypeMappings
*/
class AnnotationTypeMapping {
final class AnnotationTypeMapping {

@Nullable
private final AnnotationTypeMapping parent;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import java.util.Map;

import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ConcurrentReferenceHashMap;

/**
Expand Down Expand Up @@ -75,11 +74,9 @@ private void addAllMappings(Class<? extends Annotation> annotationType) {
}
}

private void addMetaAnnotationsToQueue(Deque<AnnotationTypeMapping> queue,
AnnotationTypeMapping parent) {

Annotation[] metaAnnotations = AnnotationsScanner.getDeclaredAnnotations(
parent.getAnnotationType(), false);
private void addMetaAnnotationsToQueue(Deque<AnnotationTypeMapping> queue, AnnotationTypeMapping parent) {
Annotation[] metaAnnotations =
AnnotationsScanner.getDeclaredAnnotations(parent.getAnnotationType(), false);
for (Annotation metaAnnotation : metaAnnotations) {
if (!isMappable(parent, metaAnnotation)) {
continue;
Expand Down Expand Up @@ -125,19 +122,17 @@ private void addIfPossible(Deque<AnnotationTypeMapping> queue,
}
}

private boolean isMappable(AnnotationTypeMapping parent, Annotation metaAnnotation) {
return !this.filter.matches(metaAnnotation) &&
private boolean isMappable(AnnotationTypeMapping parent, @Nullable Annotation metaAnnotation) {
return (metaAnnotation != null && !this.filter.matches(metaAnnotation) &&
!AnnotationFilter.PLAIN.matches(parent.getAnnotationType()) &&
!isAlreadyMapped(parent, metaAnnotation);
!isAlreadyMapped(parent, metaAnnotation));
}

private boolean isAlreadyMapped(AnnotationTypeMapping parent,
Annotation metaAnnotation) {

private boolean isAlreadyMapped(AnnotationTypeMapping parent, Annotation metaAnnotation) {
Class<? extends Annotation> annotationType = metaAnnotation.annotationType();
AnnotationTypeMapping mapping = parent;
while (mapping != null) {
if (mapping.getAnnotationType().equals(annotationType)) {
if (mapping.getAnnotationType() == annotationType) {
return true;
}
mapping = mapping.getParent();
Expand Down Expand Up @@ -171,11 +166,8 @@ AnnotationTypeMapping get(int index) {
* @param annotationType the source annotation type
* @return type mappings for the annotation type
*/
static AnnotationTypeMappings forAnnotationType(
Class<? extends Annotation> annotationType) {

return forAnnotationType(annotationType,
AnnotationFilter.mostAppropriateFor(annotationType));
static AnnotationTypeMappings forAnnotationType(Class<? extends Annotation> annotationType) {
return forAnnotationType(annotationType, AnnotationFilter.mostAppropriateFor(annotationType));
}

/**
Expand All @@ -186,11 +178,8 @@ static AnnotationTypeMappings forAnnotationType(
* @return type mappings for the annotation type
*/
static AnnotationTypeMappings forAnnotationType(
Class<? extends Annotation> annotationType,
AnnotationFilter annotationFilter) {
Class<? extends Annotation> annotationType, AnnotationFilter annotationFilter) {

Assert.notNull(annotationType, "AnnotationType must not be null");
Assert.notNull(annotationFilter, "AnnotationFilter must not be null");
return cache.computeIfAbsent(annotationFilter, Cache::new).get(annotationType);
}

Expand Down
Loading

0 comments on commit 5e15338

Please sign in to comment.