public class JavariAnnotatedTypeFactory extends BaseAnnotatedTypeFactory
ReadOnly
in the source code.
Implicit Annotations:
All literals are implicitly treated as Mutable
, including the
null literal. While they are indeed immutable, this implicit type helps
interfacing with non-annotated libraries.
Default Annotations:
ReadOnly
annotation to a type if the
tree or element is
ReadOnly
, including a method receiver of a
ReadOnly class, or
ThisMutable
field using a ReadOnly
reference (e.g. readOnlyRef.thisMutableField
with the obvious
declarations)
ThisMutable
annotation to a type if the
input is a field of a mutable class.
Mutable
annotation is inserted by default.
GenericAnnotatedTypeFactory.ScanState
AnnotatedTypeFactory.InheritedFromClassAnnotator
Modifier and Type | Field and Description |
---|---|
protected javax.lang.model.element.AnnotationMirror |
ASSIGNABLE
The Javari annotations.
|
protected javax.lang.model.element.AnnotationMirror |
MUTABLE
The Javari annotations.
|
protected javax.lang.model.element.AnnotationMirror |
POLYREAD
The Javari annotations.
|
protected javax.lang.model.element.AnnotationMirror |
QREADONLY
The Javari annotations.
|
protected javax.lang.model.element.AnnotationMirror |
READONLY
The Javari annotations.
|
protected javax.lang.model.element.AnnotationMirror |
THISMUTABLE
The Javari annotations.
|
analyses, defaults, FLOW_BY_DEFAULT, flowResult, initializationStaticStore, initializationStore, methodInvocationStores, poly, regularExitStores, returnStatementStores, scannedClasses, treeAnnotator, typeAnnotator, useFlow
checker, elements, fromTreeCache, processingEnv, qualHierarchy, root, SHOULD_CACHE, SHOULD_READ_CACHE, shouldCache, shouldReadCache, trees, typeHierarchy, types, uid, visitorState
Constructor and Description |
---|
JavariAnnotatedTypeFactory(BaseTypeChecker checker)
Creates a new
JavariAnnotatedTypeFactory that operates on a
particular AST. |
Modifier and Type | Method and Description |
---|---|
void |
annotateImplicit(javax.lang.model.element.Element element,
@Mutable AnnotatedTypeMirror type)
Adds annotations to qualified types according to their provided
element, as follows:
1.
|
void |
annotateImplicit(com.sun.source.tree.Tree tree,
@Mutable AnnotatedTypeMirror type,
boolean useFlow)
Adds implicit annotations to a qualified type, based on its
tree, as follows:
1.
|
Pair<AnnotatedTypeMirror.AnnotatedExecutableType,java.util.List<AnnotatedTypeMirror>> |
constructorFromUse(com.sun.source.tree.NewClassTree tree)
Determines the type of the constructed object based on the
parameters passed to the constructor.
|
QualifierHierarchy |
createQualifierHierarchy(MultiGraphQualifierHierarchy.MultiGraphFactory factory)
Factory method to easily change what QualifierHierarchy is
created.
|
protected TypeHierarchy |
createTypeHierarchy()
Implements the
@QReadOnly behavior on generic types,
creating a new TypeHierarchy class that allows a
comparison of type arguments to succeed if the left hand side
is annotated with @QReadOnly or if the regular
comparison succeeds. |
AnnotatedTypeMirror.AnnotatedDeclaredType |
getSelfType(com.sun.source.tree.Tree tree)
Returns the type of
this in the current location, which can
be used if this has a special semantics (e.g. |
boolean |
hasImmutabilityAnnotation(@ReadOnly AnnotatedTypeMirror type) |
Pair<AnnotatedTypeMirror.AnnotatedExecutableType,java.util.List<AnnotatedTypeMirror>> |
methodFromUse(com.sun.source.tree.MethodInvocationTree tree)
Determines the type of the invoked method based on the passed method
invocation tree.
|
void |
postAsMemberOf(AnnotatedTypeMirror type,
AnnotatedTypeMirror owner,
javax.lang.model.element.Element element)
We modify this callback method to replace
@ThisMutable
implicit annotations with the qualified supertype annotation,
if the owner doesn't have a @ReadOnly annotation. |
protected void |
postDirectSuperTypes(AnnotatedTypeMirror type,
java.util.List<? extends AnnotatedTypeMirror> supertypes)
A callback method for the AnnotatedTypeFactory subtypes to customize
directSuperTypes().
|
createFlowAnalysis
analyze, annotateImplicit, annotateImplicitWithFlow, applyInferredAnnotations, createFlowTransferFunction, createQualifierDefaults, createQualifierPolymorphism, createTreeAnnotator, createTypeAnnotator, dotOutputFileName, getDefaultedAnnotatedType, getEmptyStore, getFinalLocalValues, getInferredValueFor, getNodeForTree, getRegularExitStore, getReturnStatementStores, getStoreAfter, getStoreBefore, getSupportedMonotonicTypeQualifiers, getUseFlow, performFlowAnalysis, postInit, setRoot, setUseFlow
addAliasedAnnotation, addAliasedDeclAnnotation, aliasedAnnotation, annotateInheritedFromClass, annotateInheritedFromClass, buildIndexTypes, createLRUCache, createQualifierHierarchy, createQualifierHierarchy, createQualifierHierarchyFactory, createSupportedTypeQualifiers, declarationFromElement, fromClass, fromElement, fromElement, fromElement, fromExpression, fromMember, fromNewClass, fromTypeTree, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedTypeFromTypeTree, getAnnotationMirror, getAnnotationWithMetaAnnotation, getBoxedType, getCurrentClassTree, getCurrentClassType, getCurrentMethodReceiver, getDeclAnnotation, getDeclAnnotations, getDeclAnnotationWithMetaAnnotation, getElementUtils, getEnclosingMethod, getEnclosingType, getImplicitReceiverType, getMethodReturnType, getMethodReturnType, getPath, getProcessingEnv, getQualifierHierarchy, getReceiverType, getSupportedTypeQualifiers, getTreeUtils, getTypeHierarchy, getUnboxedType, getUninferredWildcardType, getVisitorState, getWildcardBoundedBy, isAnyEnclosingThisDeref, isFromByteCode, isFromStubFile, isMostEnclosingThisDeref, isSupportedQualifier, isWithinConstructor, postProcessClassTree, setPathHack, toAnnotatedType, toString, type, typeVariablesFromUse
protected final javax.lang.model.element.AnnotationMirror READONLY
protected final javax.lang.model.element.AnnotationMirror THISMUTABLE
protected final javax.lang.model.element.AnnotationMirror MUTABLE
protected final javax.lang.model.element.AnnotationMirror POLYREAD
protected final javax.lang.model.element.AnnotationMirror QREADONLY
protected final javax.lang.model.element.AnnotationMirror ASSIGNABLE
public JavariAnnotatedTypeFactory(BaseTypeChecker checker)
JavariAnnotatedTypeFactory
that operates on a
particular AST.checker
- the checker to which this factory belongspublic boolean hasImmutabilityAnnotation(@ReadOnly AnnotatedTypeMirror type)
type
- an annotated type mirrorpublic void annotateImplicit(com.sun.source.tree.Tree tree, @Mutable AnnotatedTypeMirror type, boolean useFlow)
@ThisMutable
.
@Mutable
annotation.
@Mutable
.
@ReadOnly
,
@Mutable
or @PolyRead
, according to the
qualified type of this
.
annotateImplicit
in class GenericAnnotatedTypeFactory<CFValue,CFStore,CFTransfer,CFAnalysis>
tree
- an AST nodetype
- the type obtained from tree
public void annotateImplicit(javax.lang.model.element.Element element, @Mutable AnnotatedTypeMirror type)
@Mutable
annotation.
@ReadOnly
or
@ThisMutable
, according to the supertype.
annotateImplicit
in class GenericAnnotatedTypeFactory<CFValue,CFStore,CFTransfer,CFAnalysis>
element
- an elementtype
- the type obtained from elt
public AnnotatedTypeMirror.AnnotatedDeclaredType getSelfType(com.sun.source.tree.Tree tree)
AnnotatedTypeFactory
this
in the current location, which can
be used if this
has a special semantics (e.g. this
is non-null).
The parameter is an arbitrary tree and does not have to mention "this",
neither explicitly nor implicitly.
This method should be overridden for type-system specific behavior.
TODO: in 1.3, handle all receiver type annotations.
TODO: handle enclosing classes correctly.getSelfType
in class AnnotatedTypeFactory
protected void postDirectSuperTypes(AnnotatedTypeMirror type, java.util.List<? extends AnnotatedTypeMirror> supertypes)
AnnotatedTypeFactory
type
annotations to
supertypes
. This allows the type
and its supertypes
to have the qualifiers, e.g. the supertypes of an Immutable
type are also Immutable
.postDirectSuperTypes
in class GenericAnnotatedTypeFactory<CFValue,CFStore,CFTransfer,CFAnalysis>
type
- the type whose supertypes are desiredsupertypes
- the supertypes as specified by the base AnnotatedTypeFactorypublic Pair<AnnotatedTypeMirror.AnnotatedExecutableType,java.util.List<AnnotatedTypeMirror>> constructorFromUse(com.sun.source.tree.NewClassTree tree)
@PolyRead
receiver values are resolved by looking at
the mutability of any parameters marked as @PolyRead
. The rules
are similar to the ones applicable to
method invocation resolution, but without looking at this
.
@PolyRead
receive
@Mutable
arguments, the receiver value is resolved as
@Mutable
.
@PolyRead
receive
@Mutable
or @ThisMutable
arguments and the
condition above is not satisfied, the receiver value is
resolved as @ThisMutable
.
@PolyRead
receive
@Mutable
or @PolyRead
arguments and none of
the condition above is satisfied, the receiver value is
resolved as @PolyRead
.
@ReadOnly
.
constructorFromUse
in class GenericAnnotatedTypeFactory<CFValue,CFStore,CFTransfer,CFAnalysis>
tree
- the new class treepublic Pair<AnnotatedTypeMirror.AnnotatedExecutableType,java.util.List<AnnotatedTypeMirror>> methodFromUse(com.sun.source.tree.MethodInvocationTree tree)
@PolyRead
at the raw level on return values by looking at the
mutability of any parameters marked as @PolyRead
. For
this purpose, a @PolyRead
annotation on the receiver
counts as if this
were being passed as an argument to a
parameter marked as @PolyRead
.
@PolyRead
receive
@Mutable
arguments, the return value is resolved as
@Mutable
.
@PolyRead
receive
@Mutable
or @ThisMutable
arguments and the
condition above is not satisfied, the return value is resolved
as @ThisMutable
.
@PolyRead
receive
@Mutable
or @PolyRead
arguments and none of
the condition above is satisfied, the return value is resolved
as @PolyRead
.
@ReadOnly
.
methodFromUse
in class GenericAnnotatedTypeFactory<CFValue,CFStore,CFTransfer,CFAnalysis>
tree
- the method invocation treepublic void postAsMemberOf(AnnotatedTypeMirror type, AnnotatedTypeMirror owner, javax.lang.model.element.Element element)
@ThisMutable
implicit annotations with the qualified supertype annotation,
if the owner doesn't have a @ReadOnly
annotation.
Note on the given example that, if @ThisMutable tmObject
were resolved as @ReadOnly tmObject
, the code snippet
would be legal. Such a class could then be created to obtain
@Mutable
access to tmObject
from a @ReadOnly
reference to it, without type-checker errors.
@PolyRead Object breakJavari(@ReadOnly MyClass this, @PolyRead Object s) { tmObject = s; return null; }
postAsMemberOf
in class AnnotatedTypeFactory
type
- the annotated type of the elementowner
- the annotated type of the receiver of the accessing treeelement
- the element of the field or methodpublic QualifierHierarchy createQualifierHierarchy(MultiGraphQualifierHierarchy.MultiGraphFactory factory)
AnnotatedTypeFactory
createQualifierHierarchy
in class AnnotatedTypeFactory
protected TypeHierarchy createTypeHierarchy()
@QReadOnly
behavior on generic types,
creating a new TypeHierarchy
class that allows a
comparison of type arguments to succeed if the left hand side
is annotated with @QReadOnly
or if the regular
comparison succeeds.createTypeHierarchy
in class AnnotatedTypeFactory