use of com.sun.source.tree.MethodTree in project bazel by bazelbuild.
the class JavaSource2CFGDOT method getMethodTreeAndCompilationUnit.
/**
* @return The AST of a specific method in a specific class as well as the
* {@link CompilationUnitTree} in a specific file (or null they do
* not exist).
*/
public static Entry</*@Nullable*/
MethodTree, /*@Nullable*/
CompilationUnitTree> getMethodTreeAndCompilationUnit(String file, final String method, String clas) {
final Holder<MethodTree> m = new Holder<>();
final Holder<CompilationUnitTree> c = new Holder<>();
BasicTypeProcessor typeProcessor = new BasicTypeProcessor() {
@Override
protected TreePathScanner<?, ?> createTreePathScanner(CompilationUnitTree root) {
c.value = root;
return new TreePathScanner<Void, Void>() {
@Override
public Void visitMethod(MethodTree node, Void p) {
ExecutableElement el = TreeUtils.elementFromDeclaration(node);
if (el.getSimpleName().contentEquals(method)) {
m.value = node;
// compilation).
throw new RuntimeException();
}
return null;
}
};
}
};
Context context = new Context();
JavaCompiler javac = new JavaCompiler(context);
javac.attrParseOnly = true;
JavacFileManager fileManager = (JavacFileManager) context.get(JavaFileManager.class);
JavaFileObject l = fileManager.getJavaFileObjectsFromStrings(List.of(file)).iterator().next();
PrintStream err = System.err;
try {
// redirect syserr to nothing (and prevent the compiler from issuing
// warnings about our exception.
System.setErr(new PrintStream(new OutputStream() {
@Override
public void write(int b) throws IOException {
}
}));
javac.compile(List.of(l), List.of(clas), List.of(typeProcessor));
} catch (Throwable e) {
// ok
} finally {
System.setErr(err);
}
return new Entry<MethodTree, CompilationUnitTree>() {
@Override
public CompilationUnitTree setValue(CompilationUnitTree value) {
return null;
}
@Override
public CompilationUnitTree getValue() {
return c.value;
}
@Override
public MethodTree getKey() {
return m.value;
}
};
}
use of com.sun.source.tree.MethodTree in project error-prone by google.
the class UseBinds method matchMethod.
@Override
public Description matchMethod(MethodTree method, VisitorState state) {
if (!CAN_BE_A_BINDS_METHOD.matches(method, state)) {
return NO_MATCH;
}
JCClassDecl enclosingClass = ASTHelpers.findEnclosingNode(state.getPath(), JCClassDecl.class);
// Dagger 1 modules don't support @Binds.
if (!IS_DAGGER_2_MODULE.matches(enclosingClass, state)) {
return NO_MATCH;
}
if (enclosingClass.getExtendsClause() != null) {
return fixByDelegating();
}
for (Tree member : enclosingClass.getMembers()) {
if (member.getKind().equals(Tree.Kind.METHOD) && !getSymbol(member).isConstructor()) {
MethodTree siblingMethod = (MethodTree) member;
Set<Modifier> siblingFlags = siblingMethod.getModifiers().getFlags();
if (!(siblingFlags.contains(Modifier.STATIC) || siblingFlags.contains(Modifier.ABSTRACT)) && !CAN_BE_A_BINDS_METHOD.matches(siblingMethod, state)) {
return fixByDelegating();
}
}
}
return fixByModifyingMethod(state, enclosingClass, method);
}
use of com.sun.source.tree.MethodTree in project error-prone by google.
the class Overrides method matchMethod.
@Override
public Description matchMethod(MethodTree methodTree, VisitorState state) {
MethodSymbol methodSymbol = ASTHelpers.getSymbol(methodTree);
boolean isVarargs = (methodSymbol.flags() & Flags.VARARGS) != 0;
Set<MethodSymbol> superMethods = ASTHelpers.findSuperMethods(methodSymbol, state.getTypes());
// If there are no super methods, we're fine:
if (superMethods.isEmpty()) {
return Description.NO_MATCH;
}
Iterator<MethodSymbol> superMethodsIterator = superMethods.iterator();
boolean areSupersVarargs = superMethodsIterator.next().isVarArgs();
while (superMethodsIterator.hasNext()) {
if (areSupersVarargs != superMethodsIterator.next().isVarArgs()) {
// current method is inconsistent with some of its supermethods, so report a match.
return describeMatch(methodTree);
}
}
// The current method is consistent with all of its supermethods:
if (isVarargs == areSupersVarargs) {
return Description.NO_MATCH;
}
// The current method is inconsistent with all of its supermethods, so flip the varargs-ness
// of the current method.
List<? extends VariableTree> parameterTree = methodTree.getParameters();
Tree paramType = parameterTree.get(parameterTree.size() - 1).getType();
CharSequence paramTypeSource = state.getSourceForNode(paramType);
if (paramTypeSource == null) {
// No fix if we don't have tree end positions.
return describeMatch(methodTree);
}
Description.Builder descriptionBuilder = buildDescription(methodTree);
if (isVarargs) {
descriptionBuilder.addFix(SuggestedFix.replace(paramType, "[]", paramTypeSource.length() - 3, 0));
} else {
// There may be a comment that includes a '[' character between the open and closed
// brackets of the array type. If so, we don't return a fix.
int arrayOpenIndex = paramTypeSource.length() - 2;
while (paramTypeSource.charAt(arrayOpenIndex) == ' ') {
arrayOpenIndex--;
}
if (paramTypeSource.charAt(arrayOpenIndex) == '[') {
descriptionBuilder.addFix(SuggestedFix.replace(paramType, "...", arrayOpenIndex, 0));
}
}
return descriptionBuilder.build();
}
use of com.sun.source.tree.MethodTree in project error-prone by google.
the class AmbiguousMethodReference method matchClass.
@Override
public Description matchClass(ClassTree tree, VisitorState state) {
ClassSymbol origin = getSymbol(tree);
Types types = state.getTypes();
Iterable<Symbol> members = types.membersClosure(getType(tree), /*skipInterface=*/
false).getSymbols();
// collect declared and inherited methods, grouped by reference descriptor
Map<String, List<MethodSymbol>> methods = stream(members.spliterator(), false).filter(MethodSymbol.class::isInstance).map(MethodSymbol.class::cast).filter(m -> m.isConstructor() || m.owner.equals(origin)).collect(groupingBy(m -> methodReferenceDescriptor(types, m), toCollection(ArrayList::new)));
// look for groups of ambiguous method references
for (Tree member : tree.getMembers()) {
if (!(member instanceof MethodTree)) {
continue;
}
MethodSymbol msym = getSymbol((MethodTree) member);
if (isSuppressed(msym)) {
continue;
}
List<MethodSymbol> clash = methods.remove(methodReferenceDescriptor(types, msym));
if (clash == null) {
continue;
}
clash.remove(msym);
// ignore overridden inherited methods and hidden interface methods
clash.removeIf(m -> types.isSubSignature(msym.type, m.type));
if (clash.isEmpty()) {
continue;
}
String message = String.format("This method's reference is ambiguous, its name and functional interface type" + " are the same as: %s", clash.stream().map(m -> Signatures.prettyMethodSignature(origin, m)).collect(joining(", ")));
state.reportMatch(buildDescription(member).setMessage(message).build());
}
return NO_MATCH;
}
use of com.sun.source.tree.MethodTree in project error-prone by google.
the class FindIdentifiers method findIdent.
/** Finds a declaration with the given name that is in scope at the current location. */
public static Symbol findIdent(String name, VisitorState state) {
ClassType enclosingClass = ASTHelpers.getType(state.findEnclosing(ClassTree.class));
if (enclosingClass == null || enclosingClass.tsym == null) {
return null;
}
Env<AttrContext> env = Enter.instance(state.context).getClassEnv(enclosingClass.tsym);
MethodTree enclosingMethod = state.findEnclosing(MethodTree.class);
if (enclosingMethod != null) {
env = MemberEnter.instance(state.context).getMethodEnv((JCMethodDecl) enclosingMethod, env);
}
try {
Method method = Resolve.class.getDeclaredMethod("findIdent", Env.class, Name.class, KindSelector.class);
method.setAccessible(true);
Symbol result = (Symbol) method.invoke(Resolve.instance(state.context), env, state.getName(name), KindSelector.VAR);
return result.exists() ? result : null;
} catch (ReflectiveOperationException e) {
throw new LinkageError(e.getMessage(), e);
}
}
Aggregations