use of com.sun.source.tree.VariableTree 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 method = atypeFactory.getEnclosingMethod(tree);
if (method != null) {
return method;
} else {
return TreeUtils.elementFromTree(tree);
}
}
Tree prev = null;
for (Tree t : path) {
switch(t.getKind()) {
case VARIABLE:
VariableTree vtree = (VariableTree) t;
ExpressionTree vtreeInit = vtree.getInitializer();
if (vtreeInit != null && prev == vtreeInit) {
Element elt = TreeUtils.elementFromDeclaration((VariableTree) t);
DefaultQualifier d = elt.getAnnotation(DefaultQualifier.class);
DefaultQualifiers ds = elt.getAnnotation(DefaultQualifiers.class);
if (d == null && ds == null) {
break;
}
}
if (prev != null && prev.getKind() == Tree.Kind.MODIFIERS) {
// type.
break;
}
return TreeUtils.elementFromDeclaration((VariableTree) t);
case METHOD:
return TreeUtils.elementFromDeclaration((MethodTree) t);
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.VariableTree 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.
*
* @return type that path leaf is assigned to
*/
public static AnnotatedTypeMirror assignedTo(AnnotatedTypeFactory atypeFactory, TreePath path) {
Tree assignmentContext = TreeUtils.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);
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;
// FIXME: 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;
ExecutableElement constructorElt = TreeUtils.constructor(newClassTree);
AnnotatedTypeMirror receiver = atypeFactory.fromNewClass(newClassTree);
res = assignedToExecutable(atypeFactory, path, constructorElt, receiver, newClassTree.getArguments());
} else if (assignmentContext instanceof ReturnTree) {
HashSet<Kind> kinds = new HashSet<>(Arrays.asList(Kind.LAMBDA_EXPRESSION, Kind.METHOD));
Tree enclosing = TreeUtils.enclosingOfKind(path, kinds);
if (enclosing.getKind() == Kind.METHOD) {
res = (atypeFactory.getAnnotatedType((MethodTree) enclosing)).getReturnType();
} else {
Pair<AnnotatedDeclaredType, AnnotatedExecutableType> fninf = atypeFactory.getFnInterfaceFromTree((LambdaExpressionTree) enclosing);
res = fninf.second.getReturnType();
}
} else if (assignmentContext instanceof VariableTree) {
res = assignedToVariable(atypeFactory, assignmentContext);
} else {
ErrorReporter.errorAbort("AnnotatedTypes.assignedTo: shouldn't be here!");
res = null;
}
if (res != null && TypesUtils.isPrimitive(res.getUnderlyingType())) {
return atypeFactory.getBoxedType((AnnotatedPrimitiveType) res);
} else {
return res;
}
}
use of com.sun.source.tree.VariableTree in project st-js by st-js.
the class IdentifierGlobalScopeNameClashCheck method findVariablesInMethod.
private static void findVariablesInMethod(final String name, final GenerationContext<Void> context) {
MethodTree enclosingMethod = getEnclosingMethod(context.getCurrentPath());
if (enclosingMethod == null) {
// don't see a reason why!?
return;
}
enclosingMethod.accept(new TreeScanner<Void, Void>() {
private boolean checkStopped;
@Override
public Void visitClass(ClassTree arg0, Void arg1) {
// stop the checks if a new type is encountered
checkStopped = true;
return super.visitClass(arg0, arg1);
}
@Override
public Void visitVariable(VariableTree var, Void arg1) {
if (!checkStopped && var.getName().toString().equals(name)) {
context.addError(var, "A variable with the same name as your global variable is already defined in this method's scope. " + "Please rename either the local variable/parameter or the global variable.");
}
return super.visitVariable(var, arg1);
}
}, null);
}
use of com.sun.source.tree.VariableTree in project st-js by st-js.
the class MultipleVariableWriter method visit.
public JS visit(WriterVisitor<JS> visitor, List<VariableTree> trees, GenerationContext<JS> context, boolean isStatement) {
if (trees.isEmpty()) {
return context.js().emptyStatement();
}
List<NameValue<JS>> vars = new ArrayList<NameValue<JS>>();
for (VariableTree tree : trees) {
JS init = null;
if (tree.getInitializer() != null) {
init = visitor.scan(tree.getInitializer(), context);
}
vars.add(NameValue.of(tree.getName(), init));
}
return context.withPosition(trees.get(0), context.js().variableDeclaration(isStatement, vars));
}
use of com.sun.source.tree.VariableTree in project error-prone by google.
the class StreamResourceLeak method addFix.
@Override
protected void addFix(Description.Builder description, ExpressionTree tree, VisitorState state) {
TreePath parentPath = state.getPath().getParentPath();
Tree parent = parentPath.getLeaf();
SuggestedFix.Builder fix = SuggestedFix.builder();
String streamType = SuggestedFixes.prettyType(state, fix, ASTHelpers.getReturnType(tree));
if (parent instanceof MemberSelectTree) {
StatementTree statement = state.findEnclosing(StatementTree.class);
if (statement instanceof VariableTree) {
// Variables need to be declared outside the try-with-resources:
// e.g. `int count = Files.lines(p).count();`
// -> `int count; try (Stream<String> stream = Files.lines(p)) { count = stream.count(); }`
VariableTree var = (VariableTree) statement;
int pos = ((JCTree) var).getStartPosition();
int initPos = ((JCTree) var.getInitializer()).getStartPosition();
int eqPos = pos + state.getSourceForNode(var).substring(0, initPos - pos).lastIndexOf('=');
fix.replace(eqPos, initPos, String.format(";\ntry (%s stream = %s) {\n%s =", streamType, state.getSourceForNode(tree), var.getName().toString()));
} else {
// the non-variable case, e.g. `return Files.lines(p).count()`
// -> try (Stream<Stream> stream = Files.lines(p)) { return stream.count(); }`
fix.prefixWith(statement, String.format("try (%s stream = %s) {\n", streamType, state.getSourceForNode(tree)));
}
fix.replace(tree, "stream");
fix.postfixWith(statement, "}");
description.addFix(fix.build());
} else if (parent instanceof VariableTree) {
// If the stream is assigned to a variable, wrap the variable in a try-with-resources
// that includes all statements in the same block that reference the variable.
Tree grandParent = parentPath.getParentPath().getLeaf();
if (!(grandParent instanceof BlockTree)) {
return;
}
List<? extends StatementTree> statements = ((BlockTree) grandParent).getStatements();
int idx = statements.indexOf(parent);
int lastUse = idx;
for (int i = idx + 1; i < statements.size(); i++) {
boolean[] found = { false };
statements.get(i).accept(new TreeScanner<Void, Void>() {
@Override
public Void visitIdentifier(IdentifierTree tree, Void unused) {
if (Objects.equals(ASTHelpers.getSymbol(tree), ASTHelpers.getSymbol(parent))) {
found[0] = true;
}
return null;
}
}, null);
if (found[0]) {
lastUse = i;
}
}
fix.prefixWith(parent, "try (");
fix.replace(state.getEndPosition(((VariableTree) parent).getInitializer()), state.getEndPosition(parent), ") {");
fix.postfixWith(statements.get(lastUse), "}");
description.addFix(fix.build());
} else if (parent instanceof EnhancedForLoopTree) {
// If the stream is used in a loop (e.g. directory streams), wrap the loop in
// try-with-resources.
fix.prefixWith(parent, String.format("try (%s stream = %s) {\n", streamType, state.getSourceForNode(tree)));
fix.replace(tree, "stream");
fix.postfixWith(parent, "}");
description.addFix(fix.build());
} else if (parent instanceof MethodInvocationTree) {
// If the stream is used in a method that is called in an expression statement, wrap it in
// try-with-resources.
Tree grandParent = parentPath.getParentPath().getLeaf();
if (!(grandParent instanceof ExpressionStatementTree)) {
return;
}
fix.prefixWith(parent, String.format("try (%s stream = %s) {\n", streamType, state.getSourceForNode(tree)));
fix.replace(tree, "stream");
fix.postfixWith(grandParent, "}");
description.addFix(fix.build());
}
}
Aggregations