use of com.sun.source.tree.ClassTree in project checker-framework by typetools.
the class QualifierDefaults method nearestEnclosingExceptLocal.
/**
* Determines the nearest enclosing element for a tree by climbing the tree toward the root and
* obtaining the element for the first declaration (variable, method, or class) that encloses the
* tree. Initializers of local variables are handled in a special way: within an initializer we
* look for the DefaultQualifier(s) annotation and keep track of the previously visited tree.
* TODO: explain the behavior better.
*
* @param tree the tree
* @return the nearest enclosing element for a tree
*/
private Element nearestEnclosingExceptLocal(Tree tree) {
TreePath path = atypeFactory.getPath(tree);
if (path == null) {
Element element = atypeFactory.getEnclosingElementForArtificialTree(tree);
if (element != null) {
return element;
} else {
return TreeUtils.elementFromTree(tree);
}
}
Tree prev = null;
for (Tree t : path) {
switch(TreeUtils.getKindRecordAsClass(t)) {
case ANNOTATED_TYPE:
case ANNOTATION:
// If the tree is in an annotation, then there is no relevant scope.
return null;
case VARIABLE:
VariableTree vtree = (VariableTree) t;
ExpressionTree vtreeInit = vtree.getInitializer();
// check cached value
@SuppressWarnings("interning:not.interned") boolean sameAsPrev = (vtreeInit != null && prev == vtreeInit);
if (sameAsPrev) {
Element elt = TreeUtils.elementFromDeclaration((VariableTree) t);
AnnotationMirror d = atypeFactory.getDeclAnnotation(elt, DefaultQualifier.class);
AnnotationMirror ds = atypeFactory.getDeclAnnotation(elt, DefaultQualifier.List.class);
if (d == null && ds == null) {
break;
}
}
if (prev != null && prev.getKind() == Tree.Kind.MODIFIERS) {
// argument became incompatible with the declared type.
break;
}
return TreeUtils.elementFromDeclaration((VariableTree) t);
case METHOD:
return TreeUtils.elementFromDeclaration((MethodTree) t);
// Including RECORD
case CLASS:
case ENUM:
case INTERFACE:
case ANNOTATION_TYPE:
return TreeUtils.elementFromDeclaration((ClassTree) t);
// Do nothing.
default:
}
prev = t;
}
return null;
}
use of com.sun.source.tree.ClassTree in project checker-framework by typetools.
the class InitializationTransfer method initializedFieldsAfterCall.
/**
* Returns the fields that can safely be considered initialized after the method call {@code
* node}.
*
* @param node a method call
* @return the fields that are initialized after the method call
*/
protected List<VariableElement> initializedFieldsAfterCall(MethodInvocationNode node) {
List<VariableElement> result = new ArrayList<>();
MethodInvocationTree tree = node.getTree();
ExecutableElement method = TreeUtils.elementFromUse(tree);
boolean isConstructor = method.getSimpleName().contentEquals("<init>");
Node receiver = node.getTarget().getReceiver();
String methodString = tree.getMethodSelect().toString();
// invariant fields are guaranteed to be initialized.
if (isConstructor && receiver instanceof ThisNode && methodString.equals("this")) {
ClassTree clazz = TreePathUtil.enclosingClass(analysis.getTypeFactory().getPath(tree));
TypeElement clazzElem = TreeUtils.elementFromDeclaration(clazz);
markInvariantFieldsAsInitialized(result, clazzElem);
}
// invariant fields of any super class are guaranteed to be initialized.
if (isConstructor && receiver instanceof ThisNode && methodString.equals("super")) {
ClassTree clazz = TreePathUtil.enclosingClass(analysis.getTypeFactory().getPath(tree));
TypeElement clazzElem = TreeUtils.elementFromDeclaration(clazz);
TypeMirror superClass = clazzElem.getSuperclass();
while (superClass != null && superClass.getKind() != TypeKind.NONE) {
clazzElem = (TypeElement) analysis.getTypes().asElement(superClass);
superClass = clazzElem.getSuperclass();
markInvariantFieldsAsInitialized(result, clazzElem);
}
}
return result;
}
use of com.sun.source.tree.ClassTree in project checker-framework by typetools.
the class NullnessVisitor method processClassTree.
@Override
public void processClassTree(ClassTree classTree) {
Tree extendsClause = classTree.getExtendsClause();
if (extendsClause != null) {
reportErrorIfSupertypeContainsNullnessAnnotation(extendsClause);
}
for (Tree implementsClause : classTree.getImplementsClause()) {
reportErrorIfSupertypeContainsNullnessAnnotation(implementsClause);
}
if (classTree.getKind() == Tree.Kind.ENUM) {
for (Tree member : classTree.getMembers()) {
if (member.getKind() == Tree.Kind.VARIABLE && TreeUtils.elementFromDeclaration((VariableTree) member).getKind() == ElementKind.ENUM_CONSTANT) {
VariableTree varDecl = (VariableTree) member;
List<? extends AnnotationTree> annoTrees = varDecl.getModifiers().getAnnotations();
Tree type = varDecl.getType();
if (atypeFactory.containsNullnessAnnotation(annoTrees, type)) {
checker.reportError(member, "nullness.on.enum");
}
}
}
}
super.processClassTree(classTree);
}
use of com.sun.source.tree.ClassTree in project checker-framework by typetools.
the class LockTransfer method initialStore.
@Override
public LockStore initialStore(UnderlyingAST underlyingAST, List<LocalVariableNode> parameters) {
LockStore store = super.initialStore(underlyingAST, parameters);
Kind astKind = underlyingAST.getKind();
// Handle synchronized methods and constructors.
if (astKind == UnderlyingAST.Kind.METHOD) {
CFGMethod method = (CFGMethod) underlyingAST;
MethodTree methodTree = method.getMethod();
ExecutableElement methodElement = TreeUtils.elementFromDeclaration(methodTree);
if (methodElement.getModifiers().contains(Modifier.SYNCHRONIZED)) {
final ClassTree classTree = method.getClassTree();
TypeMirror classType = TreeUtils.typeOf(classTree);
if (methodElement.getModifiers().contains(Modifier.STATIC)) {
store.insertValue(new ClassName(classType), atypeFactory.LOCKHELD);
} else {
store.insertThisValue(atypeFactory.LOCKHELD, classType);
}
} else if (methodElement.getKind() == ElementKind.CONSTRUCTOR) {
store.setInConstructorOrInitializer();
}
} else if (astKind == Kind.ARBITRARY_CODE) {
// Handle initializers
store.setInConstructorOrInitializer();
}
return store;
}
use of com.sun.source.tree.ClassTree in project checker-framework by typetools.
the class CFAbstractTransfer method visitReturn.
@Override
public TransferResult<V, S> visitReturn(ReturnNode n, TransferInput<V, S> p) {
TransferResult<V, S> result = super.visitReturn(n, p);
if (shouldPerformWholeProgramInference(n.getTree())) {
// Retrieves class containing the method
ClassTree classTree = analysis.getContainingClass(n.getTree());
// classTree is null e.g. if this is a return statement in a lambda.
if (classTree == null) {
return result;
}
ClassSymbol classSymbol = (ClassSymbol) TreeUtils.elementFromTree(classTree);
ExecutableElement methodElem = TreeUtils.elementFromDeclaration(analysis.getContainingMethod(n.getTree()));
Map<AnnotatedDeclaredType, ExecutableElement> overriddenMethods = AnnotatedTypes.overriddenMethods(analysis.atypeFactory.getElementUtils(), analysis.atypeFactory, methodElem);
// Updates the inferred return type of the method
analysis.atypeFactory.getWholeProgramInference().updateFromReturn(n, classSymbol, analysis.getContainingMethod(n.getTree()), overriddenMethods);
}
return result;
}
Aggregations