use of com.sun.source.tree.NewArrayTree in project checker-framework by typetools.
the class TreeUtils method getAssignmentContext.
/**
* Returns the tree with the assignment context for the treePath leaf node. (Does not handle
* pseudo-assignment of an argument to a parameter or a receiver expression to a receiver.)
*
* <p>The assignment context for the {@code treePath} is the leaf of its parent, if the parent
* is one of the following trees:
*
* <ul>
* <li>AssignmentTree
* <li>CompoundAssignmentTree
* <li>MethodInvocationTree
* <li>NewArrayTree
* <li>NewClassTree
* <li>ReturnTree
* <li>VariableTree
* </ul>
*
* If the parent is a ConditionalExpressionTree we need to distinguish two cases: If the leaf is
* either the then or else branch of the ConditionalExpressionTree, then recurse on the parent.
* If the leaf is the condition of the ConditionalExpressionTree, then return null to not
* consider this assignment context.
*
* <p>If the leaf is a ParenthesizedTree, then recurse on the parent.
*
* <p>Otherwise, null is returned.
*
* @return the assignment context as described
*/
public static Tree getAssignmentContext(final TreePath treePath) {
TreePath parentPath = treePath.getParentPath();
if (parentPath == null) {
return null;
}
Tree parent = parentPath.getLeaf();
switch(parent.getKind()) {
case PARENTHESIZED:
return getAssignmentContext(parentPath);
case CONDITIONAL_EXPRESSION:
ConditionalExpressionTree cet = (ConditionalExpressionTree) parent;
if (cet.getCondition() == treePath.getLeaf()) {
// No point in going on.
return null;
}
// Otherwise use the context of the ConditionalExpressionTree.
return getAssignmentContext(parentPath);
case ASSIGNMENT:
case METHOD_INVOCATION:
case NEW_ARRAY:
case NEW_CLASS:
case RETURN:
case VARIABLE:
return parent;
default:
// so use instanceof rather than listing all 11.
if (parent instanceof CompoundAssignmentTree) {
return parent;
}
return null;
}
}
use of com.sun.source.tree.NewArrayTree in project checker-framework by typetools.
the class BaseTypeVisitor method commonAssignmentCheck.
/**
* Checks the validity of an assignment (or pseudo-assignment) from a value to a variable and
* emits an error message (through the compiler's messaging interface) if it is not valid.
*
* @param varType the annotated type of the lvalue (usually a variable)
* @param valueExp the AST node for the rvalue (the new value)
* @param errorKey the error message to use if the check fails (must be a compiler message key,
* see {@link org.checkerframework.checker.compilermsgs.qual.CompilerMessageKey})
*/
protected void commonAssignmentCheck(AnnotatedTypeMirror varType, ExpressionTree valueExp, @CompilerMessageKey String errorKey) {
if (shouldSkipUses(valueExp)) {
return;
}
if (valueExp.getKind() == Tree.Kind.MEMBER_REFERENCE || valueExp.getKind() == Tree.Kind.LAMBDA_EXPRESSION) {
// and do not need to be checked again as arguments.
return;
}
if (varType.getKind() == TypeKind.ARRAY && valueExp instanceof NewArrayTree && ((NewArrayTree) valueExp).getType() == null) {
AnnotatedTypeMirror compType = ((AnnotatedArrayType) varType).getComponentType();
NewArrayTree arrayTree = (NewArrayTree) valueExp;
assert arrayTree.getInitializers() != null : "array initializers are not expected to be null in: " + valueExp;
checkArrayInitialization(compType, arrayTree.getInitializers());
}
if (!validateTypeOf(valueExp)) {
return;
}
AnnotatedTypeMirror valueType = atypeFactory.getAnnotatedType(valueExp);
assert valueType != null : "null type for expression: " + valueExp;
commonAssignmentCheck(varType, valueType, valueExp, errorKey);
}
use of com.sun.source.tree.NewArrayTree in project st-js by st-js.
the class NewArrayWriter method typeName.
private static String typeName(NewArrayTree tree) {
Tree type = tree.getType();
if (type instanceof JCPrimitiveTypeTree) {
JCPrimitiveTypeTree prim = (JCPrimitiveTypeTree) type;
return prim.toString();
}
Type elementType = elementType(tree);
return elementType.toString();
}
use of com.sun.source.tree.NewArrayTree in project checker-framework by typetools.
the class TypeArgInferenceUtil method assignedTo.
/**
* Returns the annotated type that the leaf of path is assigned to, if it is within an assignment
* context. Returns the annotated type that the method invocation at the leaf is assigned to. If
* the result is a primitive, return the boxed version.
*
* @param atypeFactory the type factory, for looking up types
* @param path the path whole leaf to look up a type for
* @return the type of path's leaf
*/
// AST node comparisons
@SuppressWarnings("interning:not.interned")
public static AnnotatedTypeMirror assignedTo(AnnotatedTypeFactory atypeFactory, TreePath path) {
Tree assignmentContext = TreePathUtil.getAssignmentContext(path);
AnnotatedTypeMirror res;
if (assignmentContext == null) {
res = null;
} else if (assignmentContext instanceof AssignmentTree) {
ExpressionTree variable = ((AssignmentTree) assignmentContext).getVariable();
res = atypeFactory.getAnnotatedType(variable);
} else if (assignmentContext instanceof CompoundAssignmentTree) {
ExpressionTree variable = ((CompoundAssignmentTree) assignmentContext).getVariable();
res = atypeFactory.getAnnotatedType(variable);
} else if (assignmentContext instanceof MethodInvocationTree) {
MethodInvocationTree methodInvocation = (MethodInvocationTree) assignmentContext;
// TODO move to getAssignmentContext
if (methodInvocation.getMethodSelect() instanceof MemberSelectTree && ((MemberSelectTree) methodInvocation.getMethodSelect()).getExpression() == path.getLeaf()) {
return null;
}
ExecutableElement methodElt = TreeUtils.elementFromUse(methodInvocation);
AnnotatedTypeMirror receiver = atypeFactory.getReceiverType(methodInvocation);
if (TreeUtils.isSuperConstructorCall(methodInvocation)) {
receiver = atypeFactory.getSelfType(methodInvocation);
}
res = assignedToExecutable(atypeFactory, path, methodElt, receiver, methodInvocation.getArguments());
} else if (assignmentContext instanceof NewArrayTree) {
// TODO: I left the previous implementation below, it definitely caused infinite loops
// TODO: if you called it from places like the TreeAnnotator.
res = null;
// TODO: This may cause infinite loop
// AnnotatedTypeMirror type =
// atypeFactory.getAnnotatedType((NewArrayTree)assignmentContext);
// type = AnnotatedTypes.innerMostType(type);
// return type;
} else if (assignmentContext instanceof NewClassTree) {
// This need to be basically like MethodTree
NewClassTree newClassTree = (NewClassTree) assignmentContext;
if (newClassTree.getEnclosingExpression() instanceof NewClassTree && (newClassTree.getEnclosingExpression() == path.getLeaf())) {
return null;
}
ExecutableElement constructorElt = TreeUtils.constructor(newClassTree);
AnnotatedTypeMirror receiver = atypeFactory.fromNewClass(newClassTree);
res = assignedToExecutable(atypeFactory, path, constructorElt, receiver, newClassTree.getArguments());
} else if (assignmentContext instanceof ReturnTree) {
HashSet<Tree.Kind> kinds = new HashSet<>(Arrays.asList(Tree.Kind.LAMBDA_EXPRESSION, Tree.Kind.METHOD));
Tree enclosing = TreePathUtil.enclosingOfKind(path, kinds);
if (enclosing.getKind() == Tree.Kind.METHOD) {
res = atypeFactory.getAnnotatedType((MethodTree) enclosing).getReturnType();
} else {
AnnotatedExecutableType fninf = atypeFactory.getFunctionTypeFromTree((LambdaExpressionTree) enclosing);
res = fninf.getReturnType();
}
} else if (assignmentContext instanceof VariableTree) {
res = assignedToVariable(atypeFactory, assignmentContext);
} else {
throw new BugInCF("AnnotatedTypes.assignedTo: shouldn't be here");
}
if (res != null && TypesUtils.isPrimitive(res.getUnderlyingType())) {
return atypeFactory.getBoxedType((AnnotatedPrimitiveType) res);
} else {
return res;
}
}
use of com.sun.source.tree.NewArrayTree in project checker-framework by typetools.
the class NullnessVisitor method isNewArrayInToArray.
/**
* Return true if the given node is "new X[]", in the context "toArray(new X[])".
*
* @param node a node to test
* @return true if the node is a new array within acall to toArray()
*/
private boolean isNewArrayInToArray(NewArrayTree node) {
if (node.getDimensions().size() != 1) {
return false;
}
ExpressionTree dim = node.getDimensions().get(0);
ProcessingEnvironment env = checker.getProcessingEnvironment();
if (!TreeUtils.isMethodInvocation(dim, collectionSize, env)) {
return false;
}
ExpressionTree rcvsize = ((MethodInvocationTree) dim).getMethodSelect();
if (!(rcvsize instanceof MemberSelectTree)) {
return false;
}
rcvsize = ((MemberSelectTree) rcvsize).getExpression();
if (!(rcvsize instanceof IdentifierTree)) {
return false;
}
Tree encl = getCurrentPath().getParentPath().getLeaf();
if (!TreeUtils.isMethodInvocation(encl, collectionToArray, env)) {
return false;
}
ExpressionTree rcvtoarray = ((MethodInvocationTree) encl).getMethodSelect();
if (!(rcvtoarray instanceof MemberSelectTree)) {
return false;
}
rcvtoarray = ((MemberSelectTree) rcvtoarray).getExpression();
if (!(rcvtoarray instanceof IdentifierTree)) {
return false;
}
return ((IdentifierTree) rcvsize).getName() == ((IdentifierTree) rcvtoarray).getName();
}
Aggregations