use of com.sun.source.util.TreePath in project checker-framework by typetools.
the class LockVisitor method issueErrorIfGuardSatisfiedAnnotationInUnsupportedLocation.
/**
* Issues an error if a GuardSatisfied annotation is found in a location other than a method
* return type or parameter (including the receiver).
*
* @param annotationTree AnnotationTree used for error reporting and to help determine that an
* array parameter has no GuardSatisfied annotations except on the array type
*/
// TODO: Remove this method once @TargetLocations are enforced (i.e. once
// issue https://github.com/typetools/checker-framework/issues/515 is closed).
private void issueErrorIfGuardSatisfiedAnnotationInUnsupportedLocation(AnnotationTree annotationTree) {
TreePath currentPath = getCurrentPath();
TreePath path = getPathForLocalVariableRetrieval(currentPath);
if (path != null) {
Tree tree = path.getLeaf();
Tree.Kind kind = tree.getKind();
if (kind == Tree.Kind.METHOD) {
// The @GuardSatisfied annotation is on the return type.
return;
} else if (kind == Tree.Kind.VARIABLE) {
VariableTree varTree = (VariableTree) tree;
Tree varTypeTree = varTree.getType();
if (varTypeTree != null) {
TreePath parentPath = path.getParentPath();
if (parentPath != null && parentPath.getLeaf().getKind() == Tree.Kind.METHOD) {
Tree.Kind varTypeTreeKind = varTypeTree.getKind();
if (varTypeTreeKind == Tree.Kind.ANNOTATED_TYPE) {
AnnotatedTypeTree annotatedTypeTree = (AnnotatedTypeTree) varTypeTree;
if (annotatedTypeTree.getUnderlyingType().getKind() != Tree.Kind.ARRAY_TYPE || annotatedTypeTree.getAnnotations().contains(annotationTree)) {
// Method parameter
return;
}
} else if (varTypeTreeKind != Tree.Kind.ARRAY_TYPE) {
// Method parameter or receiver
return;
}
}
}
}
}
checker.report(Result.failure("guardsatisfied.location.disallowed"), annotationTree);
}
use of com.sun.source.util.TreePath in project checker-framework by typetools.
the class SignednessVisitor method isCastedShift.
/**
* Determines if a right shift operation, {@code >>} or {@code >>>}, is type casted such that
* the cast renders the shift signedness ({@code >>} vs {@code >>>}) irrelevent by discarding
* the bits duplicated into the shift result. For example, the following pair of right shifts on
* {@code short s} both produce the same results under any input, because of type casting:
*
* <p>{@code (byte)(s >> 8) == (byte)(b >>> 8);}
*
* @param shiftExpr a right shift expression: {@code expr1 >> expr2} or {@code expr1 >>> expr2}
* @return true iff the right shift is type casted such that a signed or unsigned right shift
* has the same effect
*/
private boolean isCastedShift(BinaryTree shiftExpr) {
// enclosing is the operation or statement that immediately contains shiftExpr
Tree enclosing;
{
TreePath parentPath = visitorState.getPath().getParentPath();
enclosing = parentPath.getLeaf();
// Strip away all parentheses from the shift operation
while (enclosing.getKind() == Kind.PARENTHESIZED) {
parentPath = parentPath.getParentPath();
enclosing = parentPath.getLeaf();
}
}
PrimitiveTypeTree castPrimitiveType = primitiveTypeCast(enclosing);
if (castPrimitiveType == null) {
return false;
}
TypeKind castTypeKind = castPrimitiveType.getPrimitiveTypeKind();
// Determine the type of the shift result
TypeKind shiftTypeKind = atypeFactory.getAnnotatedType(shiftExpr).getUnderlyingType().getKind();
// Determine shift literal
ExpressionTree shiftAmountExpr = shiftExpr.getRightOperand();
if (!isLiteral(shiftAmountExpr)) {
return false;
}
LiteralTree shiftLit = (LiteralTree) shiftAmountExpr;
return castIgnoresMSB(shiftTypeKind, castTypeKind, shiftLit);
}
use of com.sun.source.util.TreePath in project st-js by st-js.
the class DefaultCompoundAssignmentTemplate method getAssignOperator.
public static <JS> AssignOperator getAssignOperator(CompoundAssignmentTree tree, GenerationContext<JS> context) {
TypeMirror leftType = context.getTrees().getTypeMirror(new TreePath(context.getCurrentPath(), tree.getVariable()));
TypeMirror rightType = context.getTrees().getTypeMirror(new TreePath(context.getCurrentPath(), tree.getExpression()));
boolean integerDivision = tree.getKind() == Kind.DIVIDE_ASSIGNMENT && TypesUtils.isIntegral(leftType) && TypesUtils.isIntegral(rightType);
return integerDivision ? AssignOperator.ASSIGN : AssignOperator.valueOf(tree.getKind());
}
use of com.sun.source.util.TreePath in project st-js by st-js.
the class DefaultCompoundAssignmentTemplate method rightSide.
/**
* handle the case a /= b, where a and b are integers. it generates: a = stjs.trunc(a/(b));
*/
public static <JS> JS rightSide(JS left, JS right, CompoundAssignmentTree tree, GenerationContext<JS> context) {
TypeMirror leftType = context.getTrees().getTypeMirror(new TreePath(context.getCurrentPath(), tree.getVariable()));
TypeMirror rightType = context.getTrees().getTypeMirror(new TreePath(context.getCurrentPath(), tree.getExpression()));
JavaScriptBuilder<JS> js = context.js();
boolean integerDivision = tree.getKind() == Kind.DIVIDE_ASSIGNMENT && TypesUtils.isIntegral(leftType) && TypesUtils.isIntegral(rightType);
if (integerDivision) {
// force a cast for integer division to have the expected behavior in JavaScript too
JS target = js.property(js.name("stjs"), "trunc");
JS expr = js.binary(BinaryOperator.DIVIDE, Arrays.asList(left, js.paren(right)));
return js.functionCall(target, Collections.singleton(expr));
}
return right;
}
use of com.sun.source.util.TreePath in project st-js by st-js.
the class TreeUtils method enclosingPathOfType.
/**
* Gets the first enclosing tree in path, with any one of the specified kinds.
*
* @param path
* the path defining the tree node
* @return the enclosing tree of the given type as given by the path
* @param clz
* a {@link java.lang.Class} object.
*/
public static <T extends Tree> TreePath enclosingPathOfType(final TreePath path, final Class<T> clz) {
TreePath p = path;
while (p != null) {
Tree leaf = p.getLeaf();
assert leaf != null;
/* nninvariant */
if (clz.isAssignableFrom(leaf.getClass())) {
return p;
}
p = p.getParentPath();
}
return null;
}
Aggregations