use of com.sun.source.tree.IdentifierTree in project error-prone by google.
the class FindIdentifiers method createFindIdentifiersScanner.
/**
* Finds all identifiers in a tree. Takes an optional stop point as its argument: the depth-first
* walk will stop if this node is encountered.
*/
private static final TreeScanner<Void, Void> createFindIdentifiersScanner(ImmutableSet.Builder<Symbol> builder, @Nullable Tree stoppingPoint) {
return new TreeScanner<Void, Void>() {
@Override
public Void scan(Tree tree, Void unused) {
return Objects.equals(stoppingPoint, tree) ? null : super.scan(tree, unused);
}
@Override
public Void scan(Iterable<? extends Tree> iterable, Void unused) {
if (stoppingPoint != null && iterable != null) {
ImmutableList.Builder<Tree> builder = ImmutableList.builder();
for (Tree t : iterable) {
if (stoppingPoint.equals(t)) {
break;
}
builder.add(t);
}
iterable = builder.build();
}
return super.scan(iterable, unused);
}
@Override
public Void visitIdentifier(IdentifierTree identifierTree, Void unused) {
Symbol symbol = ASTHelpers.getSymbol(identifierTree);
if (symbol != null) {
builder.add(symbol);
}
return null;
}
};
}
use of com.sun.source.tree.IdentifierTree in project error-prone by google.
the class StringLiteralTest method notMatches.
@Test
public void notMatches() {
// TODO(b/67738557): consolidate helpers for creating fake trees
LiteralTree tree = new LiteralTree() {
@Override
public Kind getKind() {
throw new UnsupportedOperationException();
}
@Override
public <R, D> R accept(TreeVisitor<R, D> visitor, D data) {
throw new UnsupportedOperationException();
}
@Override
public Object getValue() {
return "a string literal";
}
};
assertFalse(new StringLiteral("different string").matches(tree, null));
IdentifierTree idTree = new IdentifierTree() {
@Override
public Name getName() {
return null;
}
@Override
public Kind getKind() {
throw new UnsupportedOperationException();
}
@Override
public <R, D> R accept(TreeVisitor<R, D> visitor, D data) {
throw new UnsupportedOperationException();
}
};
assertFalse(new StringLiteral("test").matches(idTree, null));
// TODO(b/67738557): consolidate helpers for creating fake trees
LiteralTree intTree = new LiteralTree() {
@Override
public Object getValue() {
return 5;
}
@Override
public Kind getKind() {
throw new UnsupportedOperationException();
}
@Override
public <R, D> R accept(TreeVisitor<R, D> visitor, D data) {
throw new UnsupportedOperationException();
}
};
assertFalse(new StringLiteral("test").matches(intTree, null));
}
use of com.sun.source.tree.IdentifierTree in project error-prone by google.
the class WildcardImport method qualifiedNameFix.
/**
* Add an import for {@code owner}, and qualify all on demand imported references to members of
* owner by owner's simple name.
*/
private static void qualifiedNameFix(final SuggestedFix.Builder fix, final Symbol owner, VisitorState state) {
fix.addImport(owner.getQualifiedName().toString());
final JCCompilationUnit unit = (JCCompilationUnit) state.getPath().getCompilationUnit();
new TreePathScanner<Void, Void>() {
@Override
public Void visitIdentifier(IdentifierTree tree, Void unused) {
Symbol sym = ASTHelpers.getSymbol(tree);
if (sym == null) {
return null;
}
Tree parent = getCurrentPath().getParentPath().getLeaf();
if (parent.getKind() == Tree.Kind.CASE && ((CaseTree) parent).getExpression().equals(tree) && sym.owner.getKind() == ElementKind.ENUM) {
// switch cases can refer to enum constants by simple name without importing them
return null;
}
if (sym.owner.equals(owner) && unit.starImportScope.includes(sym)) {
fix.prefixWith(tree, owner.getSimpleName() + ".");
}
return null;
}
}.scan(unit, null);
}
use of com.sun.source.tree.IdentifierTree in project error-prone by google.
the class Parameter method getArgumentName.
/**
* Extract the name from an argument.
*
* <p>
*
* <ul>
* <li>IdentifierTree - if the identifier is 'this' then use the name of the enclosing class,
* otherwise use the name of the identifier
* <li>MemberSelectTree - the name of its identifier
* <li>NewClassTree - the name of the class being constructed
* <li>Null literal - a wildcard name
* <li>MethodInvocationTree - use the method name stripping off 'get', 'set', 'is' prefix. If
* this results in an empty name then recursively search the receiver
* </ul>
*
* All other trees (including literals other than Null literal) do not have a name and this method
* will return the marker for an unknown name.
*/
@VisibleForTesting
static String getArgumentName(ExpressionTree expressionTree) {
switch(expressionTree.getKind()) {
case MEMBER_SELECT:
return ((MemberSelectTree) expressionTree).getIdentifier().toString();
case NULL_LITERAL:
// null could match anything pretty well
return NAME_NULL;
case IDENTIFIER:
IdentifierTree idTree = (IdentifierTree) expressionTree;
if (idTree.getName().contentEquals("this")) {
// for the 'this' keyword the argument name is the name of the object's class
Symbol sym = ASTHelpers.getSymbol(idTree);
return sym != null ? getClassName(ASTHelpers.enclosingClass(sym)) : NAME_NOT_PRESENT;
} else {
// if we have a variable, just extract its name
return idTree.getName().toString();
}
case METHOD_INVOCATION:
MethodInvocationTree methodInvocationTree = (MethodInvocationTree) expressionTree;
MethodSymbol methodSym = ASTHelpers.getSymbol(methodInvocationTree);
if (methodSym != null) {
String name = methodSym.getSimpleName().toString();
List<String> terms = NamingConventions.splitToLowercaseTerms(name);
String firstTerm = Iterables.getFirst(terms, null);
if (METHODNAME_PREFIXES_TO_REMOVE.contains(firstTerm)) {
if (terms.size() == 1) {
ExpressionTree receiver = ASTHelpers.getReceiver(methodInvocationTree);
if (receiver == null) {
return getClassName(ASTHelpers.enclosingClass(methodSym));
}
// recursively try to get a name from the receiver
return getArgumentName(receiver);
} else {
return name.substring(firstTerm.length());
}
} else {
return name;
}
} else {
return NAME_NOT_PRESENT;
}
case NEW_CLASS:
MethodSymbol constructorSym = ASTHelpers.getSymbol((NewClassTree) expressionTree);
return constructorSym != null && constructorSym.owner != null ? getClassName((ClassSymbol) constructorSym.owner) : NAME_NOT_PRESENT;
default:
return NAME_NOT_PRESENT;
}
}
use of com.sun.source.tree.IdentifierTree 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;
}
Aggregations