| package org.checkerframework.checker.nullness; |
| |
| import java.util.LinkedHashSet; |
| import java.util.List; |
| import java.util.SortedSet; |
| import javax.annotation.processing.SupportedOptions; |
| import org.checkerframework.checker.initialization.InitializationChecker; |
| import org.checkerframework.checker.nullness.qual.MonotonicNonNull; |
| import org.checkerframework.common.basetype.BaseTypeChecker; |
| import org.checkerframework.common.basetype.BaseTypeVisitor; |
| import org.checkerframework.framework.source.SupportedLintOptions; |
| |
| /** |
| * An implementation of the nullness type-system, parameterized by an initialization type-system for |
| * safe initialization. It uses freedom-before-commitment, augmented by type frames (which are |
| * crucial to obtain acceptable precision), as its initialization type system. |
| * |
| * @checker_framework.manual #nullness-checker Nullness Checker |
| */ |
| @SupportedLintOptions({ |
| NullnessChecker.LINT_NOINITFORMONOTONICNONNULL, |
| NullnessChecker.LINT_REDUNDANTNULLCOMPARISON, |
| // Temporary option to forbid non-null array component types, which is allowed by default. |
| // Forbidding is sound and will eventually be the default. |
| // Allowing is unsound, as described in Section 3.3.4, "Nullness and arrays": |
| // https://checkerframework.org/manual/#nullness-arrays |
| // It is the default temporarily, until we improve the analysis to reduce false positives or we |
| // learn what advice to give programmers about avoid false positive warnings. |
| // See issue #986: https://github.com/typetools/checker-framework/issues/986 |
| "soundArrayCreationNullness", |
| // Old name for soundArrayCreationNullness, for backward compatibility; remove in January 2021. |
| "forbidnonnullarraycomponents", |
| NullnessChecker.LINT_TRUSTARRAYLENZERO, |
| NullnessChecker.LINT_PERMITCLEARPROPERTY, |
| }) |
| @SupportedOptions({"assumeKeyFor"}) |
| public class NullnessChecker extends InitializationChecker { |
| |
| /** Should we be strict about initialization of {@link MonotonicNonNull} variables? */ |
| public static final String LINT_NOINITFORMONOTONICNONNULL = "noInitForMonotonicNonNull"; |
| |
| /** Default for {@link #LINT_NOINITFORMONOTONICNONNULL}. */ |
| public static final boolean LINT_DEFAULT_NOINITFORMONOTONICNONNULL = false; |
| |
| /** |
| * Warn about redundant comparisons of an expression with {@code null}, if the expression is known |
| * to be non-null. |
| */ |
| public static final String LINT_REDUNDANTNULLCOMPARISON = "redundantNullComparison"; |
| |
| /** Default for {@link #LINT_REDUNDANTNULLCOMPARISON}. */ |
| public static final boolean LINT_DEFAULT_REDUNDANTNULLCOMPARISON = false; |
| |
| /** |
| * Should the Nullness Checker unsoundly trust {@code @ArrayLen(0)} annotations to improve |
| * handling of {@link java.util.Collection#toArray()} by {@link CollectionToArrayHeuristics}? |
| */ |
| public static final String LINT_TRUSTARRAYLENZERO = "trustArrayLenZero"; |
| |
| /** Default for {@link #LINT_TRUSTARRAYLENZERO}. */ |
| public static final boolean LINT_DEFAULT_TRUSTARRAYLENZERO = false; |
| |
| /** |
| * If true, client code may clear system properties. If false (the default), some calls to {@code |
| * System.getProperty} are refined to return @NonNull. |
| */ |
| public static final String LINT_PERMITCLEARPROPERTY = "permitClearProperty"; |
| |
| /** Default for {@link #LINT_PERMITCLEARPROPERTY}. */ |
| public static final boolean LINT_DEFAULT_PERMITCLEARPROPERTY = false; |
| |
| @Override |
| protected LinkedHashSet<Class<? extends BaseTypeChecker>> getImmediateSubcheckerClasses() { |
| LinkedHashSet<Class<? extends BaseTypeChecker>> checkers = |
| super.getImmediateSubcheckerClasses(); |
| if (!hasOptionNoSubcheckers("assumeKeyFor")) { |
| checkers.add(KeyForSubchecker.class); |
| } |
| return checkers; |
| } |
| |
| @Override |
| public SortedSet<String> getSuppressWarningsPrefixes() { |
| SortedSet<String> result = super.getSuppressWarningsPrefixes(); |
| result.add("nullness"); |
| return result; |
| } |
| |
| @Override |
| protected BaseTypeVisitor<?> createSourceVisitor() { |
| return new NullnessVisitor(this); |
| } |
| |
| @Override |
| public List<String> getExtraStubFiles() { |
| List<String> result = super.getExtraStubFiles(); |
| if (hasOption("assumeKeyFor")) { |
| result.add("map-assumeKeyFor.astub"); |
| } |
| return result; |
| } |
| } |