@SupportedOptions(value={"suppressWarnings","skipUses","onlyUses","skipDefs","onlyDefs","assumeSideEffectFree","assumeDeterministic","assumePure","assumeAssertionsAreEnabled","assumeAssertionsAreDisabled","warns","checkPurityAnnotations","invariantArrays","checkCastElementType","useConservativeDefaultsForUncheckedCode","useDefaultsForUncheckedCode","concurrentSemantics","conservativeUninferredTypeArguments","ignoreRawTypeArguments","lint","suggestPureMethods","resolveReflection","infer","inferOutputOriginal","showSuppressWarningsStrings","warnUnneededSuppressions","warnUnneededSuppressionsExceptions","requirePrefixInWarningSuppressions","ignoreInvalidAnnotationLocations","stubs","ajava","stubWarnIfNotFound","stubNoWarnIfNotFound","stubWarnIfNotFoundIgnoresClasses","stubWarnIfOverwritesBytecode","stubWarnIfRedundantWithBytecode","stubWarnNote","mergeStubsWithSource","version","printGitProperties","printAllQualifiers","printVerboseGenerics","noPrintErrorStack","noWarnMemoryConstraints","nomsgtext","detailedmsgtext","ignorejdkastub","permitMissingJdk","nocheckjdk","parseAllJdk","stubDebug","filenames","showchecks","showInferenceSteps","dumpOnErrors","cfgviz","flowdotdir","verbosecfg","atfCacheSize","atfDoNotCache","resourceStats","parseAllJdk","ajavaChecks"}) public abstract class SourceChecker extends AbstractTypeProcessor implements OptionConfiguration
javac
's annotation processing
API, routines for error reporting via the JSR 199 compiler API, and an implementation for using a
SourceVisitor
to perform the type-checking.
Most type-checker plug-ins should extend BaseTypeChecker
, instead of this class. Only
checkers that require annotated types but not subtype checking (e.g. for testing purposes) should
extend this. Non-type checkers (e.g. for enforcing coding styles) may extend AbstractProcessor
(or even this class).
Modifier and Type | Field and Description |
---|---|
protected @InternedDistinct CompilationUnitTree |
currentRoot
The source tree that is being scanned.
|
static String |
DETAILS_SEPARATOR
Separates parts of a "detailed message", to permit easier parsing.
|
protected Elements |
elements
Element utilities.
|
protected Set<Element> |
elementsWithSuppressedWarnings
Elements with a
@SuppressWarnings that actually suppressed a warning for this checker. |
protected int |
errsOnLastExit
The number of errors at the last exit of the type processor.
|
protected boolean |
javacErrored
If true, javac failed to compile the code or a previously-run annotation processor issued an
error.
|
protected @MonotonicNonNull Messager |
messager
Used to report error messages and warnings via the compiler.
|
protected @MonotonicNonNull Properties |
messagesProperties
Maps error keys to localized/custom error messages.
|
protected static String |
MSGS_FILE
File name of the localized messages.
|
protected static String |
OPTION_SEPARATOR
The string that separates the checker name from the option name in a "-A" command-line
argument.
|
protected @Nullable SourceChecker |
parentChecker
The checker that called this one, whether that be a BaseTypeChecker (used as a compound
checker) or an AggregateChecker.
|
static String |
SUPPRESS_ALL_MESSAGE_KEY
The message key that will suppress all warnings (it matches any message key).
|
static String |
SUPPRESS_ALL_PREFIX
The SuppressWarnings prefix that will suppress warnings for all checkers.
|
protected Trees |
trees
Tree utilities; used as a helper for the
SourceVisitor . |
protected Types |
types
Type utilities.
|
static @CompilerMessageKey String |
UNNEEDED_SUPPRESSION_KEY
The message key emitted when an unused warning suppression is found.
|
protected @MonotonicNonNull List<String> |
upstreamCheckerNames
List of upstream checker names.
|
protected boolean |
useAllcheckersPrefix
If true, use the "allcheckers:" warning string prefix.
|
protected SourceVisitor<?,?> |
visitor
The visitor to use.
|
processingEnv
Constructor and Description |
---|
SourceChecker() |
Modifier and Type | Method and Description |
---|---|
protected void |
addOptions(Map<String,String> moreOpts)
Add additional active options.
|
protected abstract SourceVisitor<?,?> |
createSourceVisitor()
Provides the
SourceVisitor that the checker should use to scan input source trees. |
protected Set<String> |
createSupportedLintOptions()
Compute the set of supported lint options.
|
protected Collection<String> |
expandCFOptions(List<? extends Class<?>> clazzPrefixes,
String[] options)
Generate the possible command-line option names by prefixing each class name from
classPrefixes to options , separated by OPTION_SEPARATOR . |
protected String |
fullMessageOf(String messageKey,
String defaultValue)
Returns the localized long message corresponding to this key.
|
AnnotationProvider |
getAnnotationProvider()
Returns the AnnotationProvider (the type factory) associated with this.
|
boolean |
getBooleanOption(String name)
Determines the boolean value of the option with the given name.
|
boolean |
getBooleanOption(String name,
boolean defaultValue)
Determines the boolean value of the option with the given name.
|
Elements |
getElementUtils()
Returns the element utilities associated with this.
|
boolean |
getLintOption(String name)
Determines the value of the lint option with the given name.
|
boolean |
getLintOption(String name,
boolean def)
Determines the value of the lint option with the given name.
|
Properties |
getMessagesProperties()
Provides a mapping of error keys to custom error messages.
|
String |
getOption(String name)
Determines the value of the option with the given name.
|
String |
getOption(String name,
String defaultValue)
Determines the value of the lint option with the given name and returns the default value if
nothing is specified.
|
OptionConfiguration |
getOptionConfiguration()
Returns the OptionConfiguration associated with this.
|
Map<String,String> |
getOptions()
Return all active options for this checker.
|
@Nullable SourceChecker |
getParentChecker()
Returns the immediate parent checker of the current checker.
|
TreePath |
getPathToCompilationUnit()
Return the path to the current compilation unit.
|
ProcessingEnvironment |
getProcessingEnvironment()
Returns the
ProcessingEnvironment that was supplied to this checker. |
protected Properties |
getProperties(Class<?> cls,
String filePath,
boolean permitNonExisting)
A helper function to parse a Properties file.
|
protected NavigableSet<String> |
getStandardSuppressWarningsPrefixes()
Returns a sorted set of SuppressWarnings prefixes read from the
SuppressWarningsPrefix
meta-annotation on the checker class. |
Set<String> |
getSupportedAnnotationTypes()
Overrides the default implementation to always return a singleton set containing only "*".
|
Set<String> |
getSupportedLintOptions()
Returns the lint options recognized by this checker.
|
Set<String> |
getSupportedOptions()
Map the Checker Framework version of
SupportedOptions to the standard annotation
provided version SupportedOptions . |
SourceVersion |
getSupportedSourceVersion() |
SortedSet<String> |
getSuppressWarningsPrefixes()
Returns a modifiable set of lower-case strings that are prefixes for SuppressWarnings strings.
|
Trees |
getTreeUtils()
Returns the tree utilities associated with this.
|
Types |
getTypeUtils()
Returns the type utilities associated with this.
|
List<String> |
getUpstreamCheckerNames()
Returns a list containing this checker name and all checkers it is a part of (that is, checkers
that called it).
|
SourceVisitor<?,?> |
getVisitor()
Returns the SourceVisitor associated with this.
|
boolean |
hasOption(String name)
Check whether the given option is provided.
|
void |
init(ProcessingEnvironment env) |
void |
initChecker()
Initialize the checker.
|
void |
message(Diagnostic.Kind kind,
String msg)
Print a non-localized message using the javac messager.
|
void |
message(Diagnostic.Kind kind,
String msg,
Object... args)
Print a non-localized message using the javac messager.
|
protected void |
printOrStoreMessage(Diagnostic.Kind kind,
String message,
Tree source,
CompilationUnitTree root)
Do not call this method.
|
protected void |
printOrStoreMessage(Diagnostic.Kind kind,
String message,
Tree source,
CompilationUnitTree root,
StackTraceElement[] trace)
Do not call this method.
|
protected void |
printStats()
Print resource usage statistics.
|
protected Object |
processArg(Object arg)
Process an argument to an error message before it is passed to String.format.
|
void |
report(Object source,
DiagMessage d)
Reports a diagnostic message.
|
void |
reportError(Object source,
@CompilerMessageKey String messageKey,
Object... args)
Reports an error.
|
protected void |
reportJavacError(TreePath p)
Report "type.checking.not.run" error.
|
void |
reportWarning(Object source,
@CompilerMessageKey String messageKey,
Object... args)
Reports a warning.
|
protected void |
setLintOption(String name,
boolean val)
Set the value of the lint option with the given name.
|
protected void |
setParentChecker(SourceChecker parentChecker)
Set the parent checker of the current checker.
|
protected void |
setProcessingEnvironment(ProcessingEnvironment env)
Set the processing environment of the current checker.
|
protected void |
setRoot(CompilationUnitTree newRoot)
Invoked when the current compilation unit root changes.
|
protected void |
setSupportedLintOptions(Set<String> newLints)
Set the supported lint options.
|
protected boolean |
shouldAddShutdownHook()
Return true to indicate that method
shutdownHook() should be added as a shutdownHook of
the JVM. |
boolean |
shouldSkipDefs(ClassTree node)
Tests whether the class definition should not be checked because it matches the
checker.skipDefs property. |
boolean |
shouldSkipDefs(ClassTree cls,
MethodTree meth)
Tests whether the method definition should not be checked because it matches the
checker.skipDefs property. |
boolean |
shouldSkipUses(@Nullable Element element)
Tests whether the class owner of the passed element is an unannotated class and matches the
pattern specified in the
checker.skipUses property. |
boolean |
shouldSkipUses(@FullyQualifiedName String typeName)
Tests whether the class owner of the passed type matches the pattern specified in the
checker.skipUses property. |
boolean |
shouldSuppressWarnings(@Nullable Element elt,
String errKey)
Determines whether all the warnings pertaining to a given element should be suppressed.
|
boolean |
shouldSuppressWarnings(@Nullable TreePath path,
String errKey)
Determines whether all the warnings pertaining to a given tree path should be suppressed.
|
boolean |
shouldSuppressWarnings(Tree tree,
String errKey)
Determines whether all the warnings pertaining to a given tree should be suppressed.
|
protected void |
shutdownHook()
Method that gets called exactly once at shutdown time of the JVM.
|
void |
typeProcess(TypeElement e,
TreePath p)
Type-check the code using this checker's visitor.
|
void |
typeProcessingStart()
A method to be called once before the first call to typeProcess.
|
boolean |
useConservativeDefault(String kindOfCode)
Should conservative defaults be used for the kind of unchecked code indicated by the parameter?
|
protected void |
warnUnneededSuppressions()
Issues a warning about any
@SuppressWarnings that didn't suppress a warning, but starts
with this checker name or "allcheckers". |
protected void |
warnUnneededSuppressions(Set<Element> elementsSuppress,
Set<String> prefixes,
Set<String> allErrorKeys)
Issues a warning about any
@SuppressWarnings string that didn't suppress a warning, but
starts with one of the given prefixes (checker names). |
getCompilerLog, process, typeProcessingOver
getCompletions, isInitialized
public static final String SUPPRESS_ALL_MESSAGE_KEY
public static final String SUPPRESS_ALL_PREFIX
public static final @CompilerMessageKey String UNNEEDED_SUPPRESSION_KEY
protected static final String MSGS_FILE
protected @MonotonicNonNull Properties messagesProperties
fullMessageOf(java.lang.String, java.lang.String)
or processArg(java.lang.Object)
.protected @MonotonicNonNull Messager messager
protected Elements elements
protected Trees trees
SourceVisitor
.protected Types types
protected @InternedDistinct CompilationUnitTree currentRoot
protected SourceVisitor<?,?> visitor
protected boolean useAllcheckersPrefix
Checkers that never issue any error messages should set this to false. That prevents -AwarnUnneededSuppressions
from issuing warnings about
@SuppressWarnings("allcheckers:...")
.
protected static final String OPTION_SEPARATOR
protected @Nullable SourceChecker parentChecker
protected @MonotonicNonNull List<String> upstreamCheckerNames
protected boolean javacErrored
protected int errsOnLastExit
public static final String DETAILS_SEPARATOR
public final void init(ProcessingEnvironment env)
AbstractTypeProcessor
Register a TaskListener that will get called after FLOW.
init
in interface Processor
init
in class AbstractTypeProcessor
public ProcessingEnvironment getProcessingEnvironment()
ProcessingEnvironment
that was supplied to this checker.ProcessingEnvironment
that was supplied to this checkerprotected void setProcessingEnvironment(ProcessingEnvironment env)
env
- the new processing environmentprotected void setParentChecker(SourceChecker parentChecker)
public @Nullable SourceChecker getParentChecker()
protected void setRoot(CompilationUnitTree newRoot)
newRoot
- the new compilation unit rootpublic List<String> getUpstreamCheckerNames()
public OptionConfiguration getOptionConfiguration()
public Elements getElementUtils()
public Types getTypeUtils()
public Trees getTreeUtils()
public SourceVisitor<?,?> getVisitor()
protected abstract SourceVisitor<?,?> createSourceVisitor()
SourceVisitor
that the checker should use to scan input source trees.SourceVisitor
to use to scan source treespublic AnnotationProvider getAnnotationProvider()
public Properties getMessagesProperties()
As a default, this implementation builds a Properties
out of file messages.properties
. It accumulates all the properties files in the Java class hierarchy from
the checker up to SourceChecker
. This permits subclasses to inherit default messages
while being able to override them.
Properties
that maps error keys to error message textpublic void typeProcessingStart()
Subclasses may override this method to do any initialization work.
Type-checkers are not supposed to override this. Instead override initChecker. This allows us to handle BugInCF only here and doesn't require all overriding implementations to be aware of BugInCF.
typeProcessingStart
in class AbstractTypeProcessor
AbstractProcessor.init(ProcessingEnvironment)
,
initChecker()
public void initChecker()
protected void reportJavacError(TreePath p)
p
- error is reported at the leaf of the pathpublic void typeProcess(TypeElement e, TreePath p)
typeProcess
in class AbstractTypeProcessor
e
- element of the analyzed classp
- the tree path to the element, with the leaf being a ClassTree
Processor.process(Set, RoundEnvironment)
public void reportError(Object source, @CompilerMessageKey String messageKey, Object... args)
source
- the source position information; may be an Element, a Tree, or nullmessageKey
- the message keyargs
- arguments for interpolation in the string corresponding to the given message keypublic void reportWarning(Object source, @CompilerMessageKey String messageKey, Object... args)
source
- the source position information; may be an Element, a Tree, or nullmessageKey
- the message keyargs
- arguments for interpolation in the string corresponding to the given message keypublic void report(Object source, DiagMessage d)
Most clients should use reportError(java.lang.Object, java.lang.String, java.lang.Object...)
or reportWarning(java.lang.Object, java.lang.String, java.lang.Object...)
.
source
- the source position information; may be an Element, a Tree, or nulld
- the diagnostic message@FormatMethod public void message(Diagnostic.Kind kind, String msg, Object... args)
reportError(java.lang.Object, java.lang.String, java.lang.Object...)
, reportWarning(java.lang.Object, java.lang.String, java.lang.Object...)
,
etc.kind
- the kind of message to printmsg
- the message textargs
- optional arguments to substitute in the messagereport(Object, DiagMessage)
public void message(Diagnostic.Kind kind, String msg)
reportError(java.lang.Object, java.lang.String, java.lang.Object...)
, reportWarning(java.lang.Object, java.lang.String, java.lang.Object...)
,
etc.kind
- the kind of message to printmsg
- the message textreport(Object, DiagMessage)
protected void printOrStoreMessage(Diagnostic.Kind kind, String message, Tree source, CompilationUnitTree root)
reportError(java.lang.Object, java.lang.String, java.lang.Object...)
or reportWarning(java.lang.Object, java.lang.String, java.lang.Object...)
instead.
This method exists so that the BaseTypeChecker can override it. For compound checkers, it stores all messages and sorts them by location before outputting them.
kind
- the kind of message to printmessage
- the message textsource
- the source code position of the diagnostic messageroot
- the compilation unitprotected void printOrStoreMessage(Diagnostic.Kind kind, String message, Tree source, CompilationUnitTree root, StackTraceElement[] trace)
reportError(java.lang.Object, java.lang.String, java.lang.Object...)
or reportWarning(java.lang.Object, java.lang.String, java.lang.Object...)
instead.
This method exists so that the BaseTypeChecker can override it. For compound checkers, it stores all messages and sorts them by location before outputting them.
kind
- the kind of message to printmessage
- the message textsource
- the source code position of the diagnostic messageroot
- the compilation unittrace
- the stack trace where the checker encountered an error. It is printed when the
dumpOnErrors option is enabled.protected String fullMessageOf(String messageKey, String defaultValue)
defaultValue
.messageKey
- a message keydefaultValue
- a default value to use if messageKey
is not a message keydefaultValue
protected Object processArg(Object arg)
This implementation expands the argument if it is exactly a message key.
By contrast, fullMessageOf(java.lang.String, java.lang.String)
processes the message key itself but not the arguments,
and tries suffixes.
arg
- the argumentpublic final boolean getLintOption(String name)
name
- the name of the lint option to check forIllegalArgumentException
- if the option name is not recognized via the SupportedLintOptions
annotation or the getSupportedLintOptions()
methodgetLintOption(String, boolean)
public final boolean getLintOption(String name, boolean def)
name
- the name of the lint option to check fordef
- the default option value, returned if the option was not givendef
if it was not given at allIllegalArgumentException
- if the option name is not recognized via the SupportedLintOptions
annotation or the getSupportedLintOptions()
methodgetLintOption(String)
,
getOption(String)
protected final void setLintOption(String name, boolean val)
name
- the name of the lint option to setval
- the option valueIllegalArgumentException
- if the option name is not recognized via the SupportedLintOptions
annotation or the getSupportedLintOptions()
methodgetLintOption(String)
,
getLintOption(String,boolean)
public Set<String> getSupportedLintOptions()
getLintOption(java.lang.String)
.Set
of the lint options recognized by this checkerprotected Set<String> createSupportedLintOptions()
protected void setSupportedLintOptions(Set<String> newLints)
newLints
- the new supported lint options, which replace any existing onesprotected void addOptions(Map<String,String> moreOpts)
moreOpts
- the active options to addpublic final boolean hasOption(String name)
Note that getOption(String)
can still return null even if hasOption
returns
true: this happens e.g. for -Amyopt
hasOption
in interface OptionConfiguration
name
- the name of the option to checkpublic final String getOption(String name)
getOption
in interface OptionConfiguration
name
- the name of the option to checkgetLintOption(String,boolean)
public final boolean getBooleanOption(String name)
getBooleanOption
in interface OptionConfiguration
name
- the name of the option to checkgetLintOption(String,boolean)
public final boolean getBooleanOption(String name, boolean defaultValue)
getBooleanOption
in interface OptionConfiguration
name
- the name of the option to checkdefaultValue
- the default value to use if the option is not setgetLintOption(String,boolean)
public Map<String,String> getOptions()
getOptions
in interface OptionConfiguration
public final String getOption(String name, String defaultValue)
getOption
in interface OptionConfiguration
name
- the name of the option to checkdefaultValue
- the default value to use if the option is not setgetOption(String)
,
getLintOption(String)
public Set<String> getSupportedOptions()
SupportedOptions
to the standard annotation
provided version SupportedOptions
.getSupportedOptions
in interface Processor
getSupportedOptions
in interface OptionConfiguration
getSupportedOptions
in class AbstractProcessor
protected Collection<String> expandCFOptions(List<? extends Class<?>> clazzPrefixes, String[] options)
classPrefixes
to options
, separated by OPTION_SEPARATOR
.clazzPrefixes
- the classes to prefixoptions
- the option namespublic final Set<String> getSupportedAnnotationTypes()
javac uses this list to determine which classes process; javac only runs an annotation
processor on classes that contain at least one of the mentioned annotations. Thus, the effect
of returning "*" is as if the checker were annotated by @SupportedAnnotationTypes("*")
:
javac runs the checker on every class mentioned on the javac command line. This method also
checks that subclasses do not contain a SupportedAnnotationTypes
annotation.
To specify the annotations that a checker recognizes as type qualifiers, see AnnotatedTypeFactory.createSupportedTypeQualifiers()
.
getSupportedAnnotationTypes
in interface Processor
getSupportedAnnotationTypes
in class AbstractProcessor
Error
- if a subclass is annotated with SupportedAnnotationTypes
protected void warnUnneededSuppressions()
@SuppressWarnings
that didn't suppress a warning, but starts
with this checker name or "allcheckers".protected void warnUnneededSuppressions(Set<Element> elementsSuppress, Set<String> prefixes, Set<String> allErrorKeys)
@SuppressWarnings
string that didn't suppress a warning, but
starts with one of the given prefixes (checker names). Does nothing if the string doesn't start
with a checker name.elementsSuppress
- elements with a @SuppressWarnings
that actually suppressed a
warningprefixes
- the SuppressWarnings prefixes that suppress all warnings from this checkerallErrorKeys
- all error keys that can be issued by this checkerpublic boolean shouldSuppressWarnings(Tree tree, String errKey)
errKey
matches a string in
-AsuppressWarnings
.tree
- the tree that might be a source of a warningerrKey
- the error key the checker is emittingpublic boolean shouldSuppressWarnings(@Nullable TreePath path, String errKey)
path
- the TreePath that might be a source of, or related to, a warningerrKey
- the error key the checker is emitting@SuppressWarnings
annotation; false
otherwisepublic boolean useConservativeDefault(String kindOfCode)
kindOfCode
- source or bytecodepublic boolean shouldSuppressWarnings(@Nullable Element elt, String errKey)
elt
- the Element that might be a source of, or related to, a warningerrKey
- the error key the checker is emitting@SuppressWarnings
annotation; false
otherwisepublic SortedSet<String> getSuppressWarningsPrefixes()
The collection must not be empty and must not contain only SUPPRESS_ALL_PREFIX
.
protected final NavigableSet<String> getStandardSuppressWarningsPrefixes()
SuppressWarningsPrefix
meta-annotation on the checker class. Or if no SuppressWarningsPrefix
is used, the
checker name is used. SUPPRESS_ALL_PREFIX
is also added, at the end, unless useAllcheckersPrefix
is false.public final boolean shouldSkipUses(@Nullable Element element)
checker.skipUses
property.element
- an elementpublic boolean shouldSkipUses(@FullyQualifiedName String typeName)
checker.skipUses
property. In contrast to shouldSkipUses(Element)
this version can
also be used from primitive types, which don't have an element.
Checkers that require their annotations not to be checked on certain JDK classes may
override this method to skip them. They shall call super.shouldSkipUses(typeName)
to
also skip the classes matching the pattern.
typeName
- the fully-qualified name of a typepublic final boolean shouldSkipDefs(ClassTree node)
checker.skipDefs
property.node
- class to potentially skippublic final boolean shouldSkipDefs(ClassTree cls, MethodTree meth)
checker.skipDefs
property.
TODO: currently only uses the class definition. Refine pattern. Same for skipUses.
cls
- class to potentially skipmeth
- method to potentially skipprotected boolean shouldAddShutdownHook()
shutdownHook()
should be added as a shutdownHook of
the JVM.shutdownHook()
as a shutdown hook of the JVMprotected void shutdownHook()
protected void printStats()
protected Properties getProperties(Class<?> cls, String filePath, boolean permitNonExisting)
cls
- the class whose location is the base of the file pathfilePath
- the name/path of the file to be readpermitNonExisting
- if true, return an empty Properties if the file does not exist or
cannot be parsed; if false, issue an errorpublic final SourceVersion getSupportedSourceVersion()
getSupportedSourceVersion
in interface Processor
getSupportedSourceVersion
in class AbstractProcessor
public TreePath getPathToCompilationUnit()