From 962cb0f5e57ba793d38b0556bd2fb0b50b04fb08 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Thu, 31 Aug 2023 05:54:14 -0700 Subject: [PATCH] Improvements to AnnotatedTypeFactory (#6144) --- .../framework/type/AnnotatedTypeFactory.java | 26 +++++++++---------- .../util/DefaultQualifierKindHierarchy.java | 3 ++- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/framework/src/main/java/org/checkerframework/framework/type/AnnotatedTypeFactory.java b/framework/src/main/java/org/checkerframework/framework/type/AnnotatedTypeFactory.java index d5e1dbd8c00..ede4a0b4e90 100644 --- a/framework/src/main/java/org/checkerframework/framework/type/AnnotatedTypeFactory.java +++ b/framework/src/main/java/org/checkerframework/framework/type/AnnotatedTypeFactory.java @@ -320,14 +320,14 @@ public class AnnotatedTypeFactory implements AnnotationProvider { * Caches the supported type qualifier classes. Call {@link #getSupportedTypeQualifiers()} instead * of using this field directly, as it may not have been initialized. */ - private final Set> supportedQuals; + private @MonotonicNonNull Set> supportedQuals = null; /** * Caches the fully-qualified names of the classes in {@link #supportedQuals}. Call {@link * #getSupportedTypeQualifierNames()} instead of using this field directly, as it may not have * been initialized. */ - private final Set<@CanonicalName String> supportedQualNames; + private @MonotonicNonNull Set<@CanonicalName String> supportedQualNames = null; /** Parses stub files and stores annotations on public elements from stub files. */ public final AnnotationFileElementTypes stubTypes; @@ -567,8 +567,6 @@ public AnnotatedTypeFactory(BaseTypeChecker checker) { this.elements = processingEnv.getElementUtils(); this.types = processingEnv.getTypeUtils(); - this.supportedQuals = new HashSet<>(); - this.supportedQualNames = new HashSet<>(); this.stubTypes = new AnnotationFileElementTypes(this); this.ajavaTypes = new AnnotationFileElementTypes(this); this.currentFileAjavaTypes = null; @@ -709,14 +707,14 @@ public AnnotatedTypeFactory(BaseTypeChecker checker) { } /** - * Requires that supportedQuals is non-empty and each element is a type qualifier. That is, no - * element has a {@code @Target} meta-annotation that contains something besides TYPE_USE or - * TYPE_PARAMETER. (@Target({}) is allowed.) @ + * Requires that supportedQuals is non-null and non-empty and each element is a type qualifier. + * That is, no element has a {@code @Target} meta-annotation that contains something besides + * TYPE_USE or TYPE_PARAMETER. (@Target({}) is allowed.) @ * * @throws BugInCF If supportedQuals is empty or contaions a non-type qualifier */ private void checkSupportedQualsAreTypeQuals() { - if (supportedQuals.isEmpty()) { + if (supportedQuals == null || supportedQuals.isEmpty()) { throw new TypeSystemError("Found no supported qualifiers."); } for (Class annotationClass : supportedQuals) { @@ -1242,11 +1240,11 @@ public AnnotationFormatter getAnnotationFormatter() { * supported */ public final Set> getSupportedTypeQualifiers() { - if (this.supportedQuals.isEmpty()) { - supportedQuals.addAll(createSupportedTypeQualifiers()); + if (this.supportedQuals == null) { + supportedQuals = createSupportedTypeQualifiers(); checkSupportedQualsAreTypeQuals(); } - return Collections.unmodifiableSet(supportedQuals); + return supportedQuals; } /** @@ -1261,12 +1259,14 @@ public final Set> getSupportedTypeQualifiers() { * supported */ public final Set<@CanonicalName String> getSupportedTypeQualifierNames() { - if (this.supportedQualNames.isEmpty()) { + if (this.supportedQualNames == null) { + supportedQualNames = new HashSet<>(); for (Class clazz : getSupportedTypeQualifiers()) { supportedQualNames.add(clazz.getCanonicalName()); } + supportedQualNames = Collections.unmodifiableSet(supportedQualNames); } - return Collections.unmodifiableSet(supportedQualNames); + return supportedQualNames; } // ********************************************************************** diff --git a/framework/src/main/java/org/checkerframework/framework/util/DefaultQualifierKindHierarchy.java b/framework/src/main/java/org/checkerframework/framework/util/DefaultQualifierKindHierarchy.java index a71e86b12e4..9dce55fb748 100644 --- a/framework/src/main/java/org/checkerframework/framework/util/DefaultQualifierKindHierarchy.java +++ b/framework/src/main/java/org/checkerframework/framework/util/DefaultQualifierKindHierarchy.java @@ -286,7 +286,8 @@ protected Map> createDirectSuper DefaultQualifierKind superQualifier = nameToQualifierKind.get(superName); if (superQualifier == null) { throw new TypeSystemError( - "%s @Subtype argument %s isn't in the hierarchy. Qualifiers: [%s]", + "In %s, @SubtypeOf(%s) argument isn't in the hierarchy." + + " Have you mis-defined createSupportedTypeQualifiers()? Qualifiers: [%s]", qualifierKind, superName, StringsPlume.join(", ", qualifierKinds)); } directSupers.add(superQualifier);