use of com.sun.source.tree.VariableTree in project tutorials by eugenp.
the class SampleJavacPlugin method init.
@Override
public void init(JavacTask task, String... args) {
Context context = ((BasicJavacTask) task).getContext();
task.addTaskListener(new TaskListener() {
@Override
public void started(TaskEvent e) {
}
@Override
public void finished(TaskEvent e) {
if (e.getKind() != TaskEvent.Kind.PARSE) {
return;
}
e.getCompilationUnit().accept(new TreeScanner<Void, Void>() {
@Override
public Void visitMethod(MethodTree method, Void v) {
List<VariableTree> parametersToInstrument = method.getParameters().stream().filter(SampleJavacPlugin.this::shouldInstrument).collect(Collectors.toList());
if (!parametersToInstrument.isEmpty()) {
// There is a possible case that more than one argument is marked by @Positive,
// as the checks are added to the method's body beginning, we process parameters RTL
// to ensure correct order.
Collections.reverse(parametersToInstrument);
parametersToInstrument.forEach(p -> addCheck(method, p, context));
}
// hence, we want to proceed with method body AST as well.
return super.visitMethod(method, v);
}
}, null);
}
});
}
use of com.sun.source.tree.VariableTree in project error-prone by google.
the class FindIdentifiers method inStaticContext.
/**
* Returns true iff the leaf node of the {@code path} occurs in a JLS 8.3.1 static context.
*/
private static boolean inStaticContext(TreePath path) {
Tree prev = path.getLeaf();
path = path.getParentPath();
ClassSymbol enclosingClass = ASTHelpers.getSymbol(ASTHelpers.findEnclosingNode(path, ClassTree.class));
ClassSymbol directSuperClass = (ClassSymbol) enclosingClass.getSuperclass().tsym;
for (Tree tree : path) {
switch(tree.getKind()) {
case METHOD:
return ASTHelpers.getSymbol(tree).isStatic();
case // static initializer
BLOCK:
if (((BlockTree) tree).isStatic()) {
return true;
}
break;
case // variable initializer of static variable
VARIABLE:
VariableTree variableTree = (VariableTree) tree;
VarSymbol variableSym = ASTHelpers.getSymbol(variableTree);
if (variableSym.getKind() == ElementKind.FIELD) {
return Objects.equals(variableTree.getInitializer(), prev) && variableSym.isStatic();
}
break;
case // JLS 8.8.7.1 explicit constructor invocation
METHOD_INVOCATION:
MethodSymbol methodSym = ASTHelpers.getSymbol((MethodInvocationTree) tree);
if (methodSym == null) {
// visibility)
return true;
}
if (methodSym.isConstructor() && (Objects.equals(methodSym.owner, enclosingClass) || Objects.equals(methodSym.owner, directSuperClass))) {
return true;
}
break;
default:
break;
}
prev = tree;
}
return false;
}
use of com.sun.source.tree.VariableTree in project error-prone by google.
the class NullnessPropagationTransfer method fieldInitializerNullnessIfAvailable.
@Nullable
private Nullness fieldInitializerNullnessIfAvailable(ClassAndField accessed) {
if (!traversed.add(accessed.symbol)) {
// TODO(kmb): Try to recognize problems with initialization order
return NULL;
}
try {
JavacProcessingEnvironment javacEnv = JavacProcessingEnvironment.instance(context);
TreePath fieldDeclPath = Trees.instance(javacEnv).getPath(accessed.symbol);
// missing types.
if (fieldDeclPath == null || fieldDeclPath.getCompilationUnit() != compilationUnit || !(fieldDeclPath.getLeaf() instanceof VariableTree)) {
return null;
}
ExpressionTree initializer = ((VariableTree) fieldDeclPath.getLeaf()).getInitializer();
if (initializer == null) {
return null;
}
ClassTree classTree = (ClassTree) fieldDeclPath.getParentPath().getLeaf();
// Run flow analysis on field initializer. This is inefficient compared to just walking
// the initializer expression tree but it avoids duplicating the logic from this transfer
// function into a method that operates on Javac Nodes.
TreePath initializerPath = TreePath.getPath(fieldDeclPath, initializer);
UnderlyingAST ast = new UnderlyingAST.CFGStatement(initializerPath.getLeaf(), classTree);
ControlFlowGraph cfg = CFGBuilder.build(initializerPath, javacEnv, ast, /* assumeAssertionsEnabled */
false, /* assumeAssertionsDisabled */
false);
Analysis<Nullness, LocalStore<Nullness>, NullnessPropagationTransfer> analysis = new Analysis<>(javacEnv, this);
analysis.performAnalysis(cfg);
return analysis.getValue(initializerPath.getLeaf());
} finally {
traversed.remove(accessed.symbol);
}
}
use of com.sun.source.tree.VariableTree in project error-prone by google.
the class TrustingNullnessAnalysis method getFieldInitializerNullness.
/**
* Returns {@link Nullness} of the initializer of the {@link VariableTree} at the leaf of the
* given {@code fieldDeclPath}. Returns {@link Nullness#NULL} should there be no initializer.
*/
// TODO(kmb): Fold this functionality into Dataflow.expressionDataflow
public Nullness getFieldInitializerNullness(TreePath fieldDeclPath, Context context) {
Tree decl = fieldDeclPath.getLeaf();
checkArgument(decl instanceof VariableTree && ((JCVariableDecl) decl).sym.getKind() == ElementKind.FIELD, "Leaf of fieldDeclPath must be a field declaration: %s", decl);
ExpressionTree initializer = ((VariableTree) decl).getInitializer();
if (initializer == null) {
// An uninitialized field is null or 0 to start :)
return ((JCVariableDecl) decl).type.isPrimitive() ? Nullness.NONNULL : Nullness.NULL;
}
TreePath initializerPath = TreePath.getPath(fieldDeclPath, initializer);
ClassTree classTree = (ClassTree) fieldDeclPath.getParentPath().getLeaf();
JavacProcessingEnvironment javacEnv = JavacProcessingEnvironment.instance(context);
UnderlyingAST ast = new UnderlyingAST.CFGStatement(decl, classTree);
ControlFlowGraph cfg = CFGBuilder.build(initializerPath, javacEnv, ast, /* assumeAssertionsEnabled */
false, /* assumeAssertionsDisabled */
false);
try {
nullnessPropagation.setContext(context).setCompilationUnit(fieldDeclPath.getCompilationUnit());
Analysis<Nullness, LocalStore<Nullness>, TrustingNullnessPropagation> analysis = new Analysis<>(javacEnv, nullnessPropagation);
analysis.performAnalysis(cfg);
return analysis.getValue(initializer);
} finally {
nullnessPropagation.setContext(null).setCompilationUnit(null);
}
}
use of com.sun.source.tree.VariableTree in project error-prone by google.
the class DataFlow method findEnclosingMethodOrLambdaOrInitializer.
// TODO(user), remove once we merge jdk8 specific's with core
private static <T> TreePath findEnclosingMethodOrLambdaOrInitializer(TreePath path) {
while (path != null) {
if (path.getLeaf() instanceof MethodTree) {
return path;
}
TreePath parent = path.getParentPath();
if (parent != null) {
if (parent.getLeaf() instanceof ClassTree) {
if (path.getLeaf() instanceof BlockTree) {
// this is a class or instance initializer block
return path;
}
if (path.getLeaf() instanceof VariableTree && ((VariableTree) path.getLeaf()).getInitializer() != null) {
// this is a field with an inline initializer
return path;
}
}
if (parent.getLeaf() instanceof LambdaExpressionTree) {
return parent;
}
}
path = parent;
}
return null;
}
Aggregations