Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@
*/
public enum TypeUseLocation {

/**
* Apply default annotations to unannotated top-level types of class, interfaces, enums and
* record *
Comment thread
aosen-xiong marked this conversation as resolved.
Outdated
*/
TYPE,

/** Apply default annotations to unannotated top-level types of fields. */
FIELD,

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,11 @@ public AnnotatedTypeFactory(BaseTypeChecker checker) {
mergeStubsWithSource = checker.hasOption("mergeStubsWithSource");
}

/** Get the element cache. */
public Map<Element, AnnotatedTypeMirror> getElementCache() {
return elementCache;
Comment thread
aosen-xiong marked this conversation as resolved.
Outdated
}

/**
* Parse a string in the format {@code
* FQN.canonical.Qualifier:FQN.alias1.Qual1,FQN.alias2.Qual2} to a pair of {@code
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1010,6 +1010,24 @@ public Void scan(@FindDistinct AnnotatedTypeMirror t, AnnotationMirror qual) {
// Some defaults only apply to the top level type.
boolean isTopLevelType = t == outer.type;
switch (outer.location) {
case TYPE:
if (outer.scope != null && outer.scope.getKind().isClass() && isTopLevelType) {
Comment thread
aosen-xiong marked this conversation as resolved.
AnnotationMirror annotation =
outer.qualHierarchy.findAnnotationInHierarchy(
atypeFactory
.getElementCache()
.get(outer.scope)
Comment thread
aosen-xiong marked this conversation as resolved.
Outdated
.getAnnotations(),
qual);
if (annotation == null
|| outer.qualHierarchy.isSubtypeQualifiersOnly(qual, annotation)) {
outer.addAnnotation(t, qual);
atypeFactory.getElementCache().put(outer.scope, t);
} else {
// should report error;
Comment thread
aosen-xiong marked this conversation as resolved.
Outdated
Comment thread
aosen-xiong marked this conversation as resolved.
Outdated
}
}
break;
case FIELD:
if (outer.scope != null
&& outer.scope.getKind() == ElementKind.FIELD
Expand Down
13 changes: 13 additions & 0 deletions framework/tests/viewpointtest/DefaultQualifierTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import org.checkerframework.framework.qual.DefaultQualifier;
import org.checkerframework.framework.qual.TypeUseLocation;

import viewpointtest.quals.*;

@DefaultQualifier(
value = A.class,
locations = {TypeUseLocation.TYPE})
public class DefaultQualifierTest {
// :: error: (type.invalid.annotations.on.use) :: error: (super.invocation.invalid) :: warning:
// (inconsistent.constructor.type)
Comment thread
aosen-xiong marked this conversation as resolved.
Outdated
@B DefaultQualifierTest() {}
}