use of com.sun.source.tree.VariableTree 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.VariableTree in project checker-framework by typetools.
the class NullnessVisitor method checkExceptionParameter.
@Override
protected void checkExceptionParameter(CatchTree node) {
VariableTree param = node.getParameter();
List<? extends AnnotationTree> annoTrees = param.getModifiers().getAnnotations();
Tree paramType = param.getType();
if (atypeFactory.containsNullnessAnnotation(annoTrees, paramType)) {
// This is a warning rather than an error because writing `@Nullable` could make sense
// if the catch block re-assigns the variable to null. (That would be bad style.)
checker.reportWarning(param, "nullness.on.exception.parameter");
}
// Don't call super.
// BasetypeVisitor forces annotations on exception parameters to be top, but because exceptions
// can never be null, the Nullness Checker does not require this check.
}
use of com.sun.source.tree.VariableTree in project checker-framework by typetools.
the class LockVisitor method visitMethod.
/**
* Issues an error if a method (explicitly or implicitly) annotated with @MayReleaseLocks has a
* formal parameter or receiver (explicitly or implicitly) annotated with @GuardSatisfied. Also
* issues an error if a synchronized method has a @LockingFree, @SideEffectFree, or @Pure
* annotation.
*
* @param node the MethodTree of the method definition to visit
*/
@Override
public Void visitMethod(MethodTree node, Void p) {
ExecutableElement methodElement = TreeUtils.elementFromDeclaration(node);
issueErrorIfMoreThanOneLockPreconditionMethodAnnotationPresent(methodElement, node);
SideEffectAnnotation sea = atypeFactory.methodSideEffectAnnotation(methodElement, true);
if (sea == SideEffectAnnotation.MAYRELEASELOCKS) {
boolean issueGSwithMRLWarning = false;
VariableTree receiver = node.getReceiverParameter();
if (receiver != null) {
if (atypeFactory.getAnnotatedType(receiver).hasAnnotation(checkerGuardSatisfiedClass)) {
issueGSwithMRLWarning = true;
}
}
if (!issueGSwithMRLWarning) {
// Skip loop if we already decided to issue the warning.
for (VariableTree vt : node.getParameters()) {
if (atypeFactory.getAnnotatedType(vt).hasAnnotation(checkerGuardSatisfiedClass)) {
issueGSwithMRLWarning = true;
break;
}
}
}
if (issueGSwithMRLWarning) {
checker.reportError(node, "guardsatisfied.with.mayreleaselocks");
}
}
// @GuardSatisfied without an index.
if (methodElement != null && methodElement.getKind() != ElementKind.CONSTRUCTOR) {
AnnotatedTypeMirror returnTypeATM = atypeFactory.getAnnotatedType(node).getReturnType();
if (returnTypeATM != null && returnTypeATM.hasAnnotation(GuardSatisfied.class)) {
int returnGuardSatisfiedIndex = atypeFactory.getGuardSatisfiedIndex(returnTypeATM);
if (returnGuardSatisfiedIndex == -1) {
checker.reportError(node, "guardsatisfied.return.must.have.index");
}
}
}
if (!sea.isWeakerThan(SideEffectAnnotation.LOCKINGFREE) && methodElement.getModifiers().contains(Modifier.SYNCHRONIZED)) {
checker.reportError(node, "lockingfree.synchronized.method", sea);
}
return super.visitMethod(node, p);
}
use of com.sun.source.tree.VariableTree in project checker-framework by typetools.
the class MustCallTransfer method getOrCreateTempVar.
/**
* Either returns the temporary variable associated with node, or creates one if one does not
* exist.
*
* @param node a node, which must be an expression (not a statement)
* @return a temporary variable node representing {@code node} that can be placed into a store
*/
@Nullable
private LocalVariableNode getOrCreateTempVar(Node node) {
LocalVariableNode localVariableNode = atypeFactory.tempVars.get(node.getTree());
if (localVariableNode == null) {
VariableTree temp = createTemporaryVar(node);
if (temp != null) {
IdentifierTree identifierTree = treeBuilder.buildVariableUse(temp);
localVariableNode = new LocalVariableNode(identifierTree);
localVariableNode.setInSource(true);
atypeFactory.tempVars.put(node.getTree(), localVariableNode);
}
}
return localVariableNode;
}
use of com.sun.source.tree.VariableTree in project checker-framework by typetools.
the class TreeUtils method bindingPatternTreeGetVariable.
/**
* Returns the binding variable of {@code bindingPatternTree}.
*
* @param bindingPatternTree the BindingPatternTree whose binding variable is returned
* @return the binding variable of {@code bindingPatternTree}
*/
public static VariableTree bindingPatternTreeGetVariable(Tree bindingPatternTree) {
try {
Class<?> bindingPatternClass = Class.forName("com.sun.source.tree.BindingPatternTree");
Method getVariableMethod = bindingPatternClass.getMethod("getVariable");
VariableTree variableTree = (VariableTree) getVariableMethod.invoke(bindingPatternTree);
if (variableTree != null) {
return variableTree;
}
throw new BugInCF("TreeUtils.bindingPatternTreeGetVariable: variable is null for tree: %s", bindingPatternTree);
} catch (ClassNotFoundException | NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
throw new BugInCF("TreeUtils.bindingPatternTreeGetVariable: reflection failed for tree: %s", bindingPatternTree, e);
}
}
Aggregations