public abstract class SourceChecker extends AbstractTypeProcessor
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.
Subclasses must implement the following methods:
getMessages()
(for type-qualifier specific error messages)
createSourceVisitor(CompilationUnitTree)
(for a custom SourceVisitor
)
createFactory(com.sun.source.tree.CompilationUnitTree)
(for a custom AnnotatedTypeFactory
)
getSuppressWarningsKey()
(for honoring
SuppressWarnings
annotations)
BaseTypeChecker
,
instead of this class. Only checkers which require annotated types but not
subtype checking (e.g. for testing purposes) should extend this.
Non-type checkers (e.g. for enforcing coding styles) should extend
AbstractProcessor
(or even this class) as the Checker Framework is
not designed for such checkers.Modifier and Type | Class and Description |
---|---|
static class |
SourceChecker.CheckerError
Exception type used only internally to abort
processing.
|
Modifier and Type | Field and Description |
---|---|
@Nullable TreePath |
currentPath |
protected @Nullable CompilationUnitTree |
currentRoot
The source tree that's being scanned.
|
protected Messager |
messager
Used to report error messages and warnings via the compiler.
|
protected Properties |
messages
Maps error keys to localized/custom error messages.
|
protected Trees |
trees
Used as a helper for the
SourceVisitor . |
processingEnv
Constructor and Description |
---|
SourceChecker() |
Modifier and Type | Method and Description |
---|---|
AnnotatedTypeFactory |
createFactory(@Nullable CompilationUnitTree root) |
protected abstract SourceVisitor<?,?> |
createSourceVisitor(@Nullable CompilationUnitTree root)
Provides the
SourceVisitor that the checker should use to scan
input source trees. |
static void |
errorAbort(@ReadOnly String msg)
Log an error message and abort processing.
|
static void |
errorAbort(@ReadOnly String msg,
Throwable cause) |
protected @ReadOnly String |
formatStackTrace(StackTraceElement[] stackTrace)
Format a list of
StackTraceElement s to be printed out as an error
message. |
protected @ReadOnly String |
fullMessageOf(@ReadOnly String messageKey,
@ReadOnly String defValue)
Returns the localized long message corresponding for this key, and
returns the defValue if no localized message is found.
|
boolean |
getLintOption(@ReadOnly String name)
Determines the value of the lint option with the given name.
|
boolean |
getLintOption(@ReadOnly String name,
boolean def)
Determines the value of the lint option with the given name.
|
Properties |
getMessages()
Provides a mapping of error keys to custom error messages.
|
ProcessingEnvironment |
getProcessingEnvironment() |
protected Properties |
getProperties(Class<?> cls,
@ReadOnly String filePath)
A helper function to parse a Properties file
|
Set<@ReadOnly String> |
getSupportedAnnotationTypes()
Always returns a singleton set containing only "*".
|
Set<@ReadOnly String> |
getSupportedLintOptions()
Returns the lint options recognized by this checker.
|
Set<@ReadOnly String> |
getSupportedOptions() |
SourceVersion |
getSupportedSourceVersion() |
Collection<@ReadOnly String> |
getSuppressWarningsKey() |
void |
initChecker()
Initialize the checker.
|
protected void |
message(Diagnostic.Kind kind,
@NonNull Object source,
@ReadOnly String msgKey,
Object... args)
Prints a message (error, warning, note, etc.) via JSR-269.
|
void |
report(Result r,
@NonNull Object src)
Reports a result.
|
boolean |
shouldSkipDefs(@Nullable ClassTree node)
Tests whether the class definition should not be checked because it
matches the
checker.skipDefs property. |
boolean |
shouldSkipDefs(@Nullable ClassTree cls,
@Nullable 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. |
void |
typeProcess(TypeElement e,
@Nullable TreePath p)
Type-check the code with Java specifications and then runs the Checker
Rule Checking visitor on the processed source.
|
void |
typeProcessingStart()
A method to be called once before the first call to typeProcess.
|
init, process, typeProcessingOver
getCompletions, isInitialized, toString
protected Properties messages
protected Messager messager
protected Trees trees
SourceVisitor
.protected @Nullable CompilationUnitTree currentRoot
public ProcessingEnvironment getProcessingEnvironment()
ProcessingEnvironment
that was supplied to this
checkerpublic AnnotatedTypeFactory createFactory(@Nullable CompilationUnitTree root)
root
- the AST root for the factoryAnnotatedTypeFactory
for use by typecheckersprotected abstract SourceVisitor<?,?> createSourceVisitor(@Nullable CompilationUnitTree root)
SourceVisitor
that the checker should use to scan
input source trees.root
- the AST rootSourceVisitor
to use to scan source treespublic Properties getMessages()
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 static void errorAbort(@ReadOnly String msg)
msg
- The error message to log.public void typeProcessingStart()
Subclasses may override this method to do any initialization work. Type checkers are not supposed to override this. Instead use initChecker. This allows us to handle CheckerError only here and doesn't require all overriding implementations to be aware of CheckerError.
typeProcessingStart
in class AbstractTypeProcessor
AbstractProcessor.init(ProcessingEnvironment)
,
SourceChecker#initChecker(ProcessingEnvironment)
public void initChecker()
public void typeProcess(TypeElement e, @Nullable 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)
protected @ReadOnly String formatStackTrace(StackTraceElement[] stackTrace)
StackTraceElement
s to be printed out as an error
message.protected @ReadOnly String fullMessageOf(@ReadOnly String messageKey, @ReadOnly String defValue)
protected void message(Diagnostic.Kind kind, @NonNull Object source, @ReadOnly String msgKey, Object... args)
kind
- the type of message to printsource
- the object from which to obtain source position informationmsgKey
- the message key to printargs
- arguments for interpolation in the string corresponding to the
given message keyIllegalArgumentException
- if source
is neither a Tree
nor an
Element
Diagnostic
public void report(Result r, @NonNull Object src)
r
- the result to reportsrc
- the position object associated with the resultpublic final boolean getLintOption(@ReadOnly 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(@ReadOnly 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)
public Set<@ReadOnly String> getSupportedLintOptions()
getLintOption(java.lang.String)
.Set
of the lint options recognized by
this checkerpublic Set<@ReadOnly String> getSupportedOptions()
getSupportedOptions
in interface Processor
getSupportedOptions
in class AbstractProcessor
public final Set<@ReadOnly String> getSupportedAnnotationTypes()
SupportedAnnotationTypes
annotation, so 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,
use the TypeQualifiers
annotation on the declaration of
subclasses of this class or override the
BaseTypeChecker.getSupportedTypeQualifiers()
method.
getSupportedAnnotationTypes
in interface Processor
getSupportedAnnotationTypes
in class AbstractProcessor
Error
- if a subclass is annotated with
SupportedAnnotationTypes
TypeQualifiers
,
getSupportedAnnotationTypes()
public Collection<@ReadOnly String> getSuppressWarningsKey()
SuppressWarningsKey
public final boolean shouldSkipUses(@Nullable Element element)
checker.skipUses
property.element
- an elementpublic final boolean shouldSkipDefs(@Nullable ClassTree node)
checker.skipDefs
property.node
- class to potentially skippublic final boolean shouldSkipDefs(@Nullable ClassTree cls, @Nullable 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 Properties getProperties(Class<?> cls, @ReadOnly String filePath)
cls
- the class whose location is the base of the file pathfilePath
- the name/path of the file to be readpublic final SourceVersion getSupportedSourceVersion()
getSupportedSourceVersion
in interface Processor
getSupportedSourceVersion
in class AbstractProcessor