use of com.sun.source.tree.ClassTree 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.ClassTree 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.ClassTree 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;
}
use of com.sun.source.tree.ClassTree in project error-prone by google.
the class InconsistentCapitalization method matchClass.
@Override
public Description matchClass(ClassTree tree, VisitorState state) {
ImmutableSet<Symbol> fields = FieldScanner.findFields(tree);
if (fields.isEmpty()) {
return Description.NO_MATCH;
}
ImmutableMap<String, Symbol> fieldNamesMap = fields.stream().collect(toImmutableMap(symbol -> symbol.toString().toLowerCase(), identity()));
ImmutableMap<TreePath, Symbol> matchedParameters = MatchingParametersScanner.findMatchingParameters(fieldNamesMap, state.getPath());
if (matchedParameters.isEmpty()) {
return Description.NO_MATCH;
}
for (Entry<TreePath, Symbol> entry : matchedParameters.entrySet()) {
TreePath parameterPath = entry.getKey();
Symbol field = entry.getValue();
String fieldName = field.getSimpleName().toString();
VariableTree parameterTree = (VariableTree) parameterPath.getLeaf();
SuggestedFix.Builder fix = SuggestedFix.builder().merge(SuggestedFixes.renameVariable(parameterTree, fieldName, state));
if (parameterPath.getParentPath() != null) {
String qualifiedName = getExplicitQualification(parameterPath, tree, state) + field.getSimpleName();
// If the field was accessed in a non-qualified way, by renaming the parameter this may
// cause clashes with it. Thus, it is required to qualify all uses of the field within the
// parameter's scope just in case.
parameterPath.getParentPath().getLeaf().accept(new TreeScanner<Void, Void>() {
@Override
public Void visitIdentifier(IdentifierTree tree, Void unused) {
if (field.equals(ASTHelpers.getSymbol(tree))) {
fix.replace(tree, qualifiedName);
}
return null;
}
}, null);
}
state.reportMatch(buildDescription(parameterPath.getLeaf()).setMessage(String.format("Found the field '%s' with the same name as the parameter '%s' but with " + "different capitalization.", fieldName, ((VariableTree) parameterPath.getLeaf()).getName())).addFix(fix.build()).build());
}
return Description.NO_MATCH;
}
use of com.sun.source.tree.ClassTree in project error-prone by google.
the class DoubleBraceInitialization method matchNewClass.
@Override
public Description matchNewClass(NewClassTree tree, VisitorState state) {
ClassTree body = tree.getClassBody();
if (body == null) {
return NO_MATCH;
}
ImmutableList<? extends Tree> members = body.getMembers().stream().filter(m -> !(m instanceof MethodTree && ASTHelpers.isGeneratedConstructor((MethodTree) m))).collect(toImmutableList());
if (members.size() != 1) {
return NO_MATCH;
}
Tree member = Iterables.getOnlyElement(members);
if (!(member instanceof BlockTree)) {
return NO_MATCH;
}
BlockTree block = (BlockTree) member;
Optional<CollectionTypes> collectionType = Stream.of(CollectionTypes.values()).filter(type -> type.constructorMatcher.matches(tree, state)).findFirst();
if (!collectionType.isPresent()) {
return NO_MATCH;
}
Description.Builder description = buildDescription(tree);
collectionType.get().maybeFix(tree, state, block).ifPresent(description::addFix);
return description.build();
}
Aggregations