use of com.sun.tools.javac.tree.JCTree.JCMethodInvocation in project checker-framework by typetools.
the class TreeUtils method constructor.
/**
* Determines the symbol for a constructor given an invocation via {@code new}.
*
* <p>If the tree is a declaration of an anonymous class, then method returns constructor that
* gets invoked in the extended class, rather than the anonymous constructor implicitly added by
* the constructor (JLS 15.9.5.1)
*
* @see #elementFromUse(NewClassTree)
* @param tree the constructor invocation
* @return the {@link ExecutableElement} corresponding to the constructor call in {@code tree}
*/
public static ExecutableElement constructor(NewClassTree tree) {
if (!(tree instanceof JCTree.JCNewClass)) {
ErrorReporter.errorAbort("InternalUtils.constructor: not a javac internal tree");
// dead code
return null;
}
JCNewClass newClassTree = (JCNewClass) tree;
if (tree.getClassBody() != null) {
// anonymous constructor bodies should contain exactly one statement
// in the form:
// super(arg1, ...)
// or
// o.super(arg1, ...)
//
// which is a method invocation (!) to the actual constructor
// the method call is guaranteed to return nonnull
JCMethodDecl anonConstructor = (JCMethodDecl) TreeInfo.declarationFor(newClassTree.constructor, newClassTree);
assert anonConstructor != null;
assert anonConstructor.body.stats.size() == 1;
JCExpressionStatement stmt = (JCExpressionStatement) anonConstructor.body.stats.head;
JCTree.JCMethodInvocation superInvok = (JCMethodInvocation) stmt.expr;
return (ExecutableElement) TreeInfo.symbol(superInvok.meth);
} else {
Element e = newClassTree.constructor;
return (ExecutableElement) e;
}
}
use of com.sun.tools.javac.tree.JCTree.JCMethodInvocation in project checker-framework by typetools.
the class DefaultReflectionResolver method resolveReflectiveMethod.
/**
* Resolves a reflective method call and returns all possible corresponding method calls.
*
* @param tree the MethodInvocationTree node that is to be resolved (Method.invoke)
* @return a (potentially empty) list of all resolved MethodInvocationTrees
*/
private List<MethodInvocationTree> resolveReflectiveMethod(MethodInvocationTree tree, AnnotatedTypeFactory reflectionFactory) {
assert isReflectiveMethodInvocation(tree);
JCMethodInvocation methodInvocation = (JCMethodInvocation) tree;
Context context = ((JavacProcessingEnvironment) processingEnv).getContext();
TreeMaker make = TreeMaker.instance(context);
TreePath path = reflectionFactory.getPath(tree);
JavacScope scope = (JavacScope) trees.getScope(path);
Env<AttrContext> env = scope.getEnv();
List<MethodInvocationTree> methods = new ArrayList<>();
boolean unknown = isUnknownMethod(tree);
AnnotationMirror estimate = getMethodVal(tree);
if (estimate == null) {
debugReflection("MethodVal is unknown for: " + tree);
debugReflection("UnknownMethod annotation: " + unknown);
return methods;
}
debugReflection("MethodVal type system annotations: " + estimate);
List<String> listClassNames = AnnotationUtils.getElementValueArray(estimate, "className", String.class, true);
List<String> listMethodNames = AnnotationUtils.getElementValueArray(estimate, "methodName", String.class, true);
List<Integer> listParamLenghts = AnnotationUtils.getElementValueArray(estimate, "params", Integer.class, true);
assert listClassNames.size() == listMethodNames.size() && listClassNames.size() == listParamLenghts.size();
for (int i = 0; i < listClassNames.size(); ++i) {
String className = listClassNames.get(i);
String methodName = listMethodNames.get(i);
int paramLength = listParamLenghts.get(i);
// Get receiver, which is always the first argument of the invoke
// method
JCExpression receiver = methodInvocation.args.head;
// The remaining list contains the arguments
com.sun.tools.javac.util.List<JCExpression> args = methodInvocation.args.tail;
// Resolve the Symbol(s) for the current method
for (Symbol symbol : getMethodSymbolsfor(className, methodName, paramLength, env)) {
if ((symbol.flags() & Flags.PUBLIC) > 0) {
debugReflection("Resolved public method: " + symbol.owner + "." + symbol);
} else {
debugReflection("Resolved non-public method: " + symbol.owner + "." + symbol);
}
JCExpression method = make.Select(receiver, symbol);
args = getCorrectedArgs(symbol, args);
// Build method invocation tree depending on the number of
// parameters
JCMethodInvocation syntTree = paramLength > 0 ? make.App(method, args) : make.App(method);
// add method invocation tree to the list of possible methods
methods.add(syntTree);
}
}
return methods;
}
use of com.sun.tools.javac.tree.JCTree.JCMethodInvocation in project checker-framework by typetools.
the class DefaultReflectionResolver method resolveReflectiveConstructor.
/**
* Resolves a reflective constructor call and returns all possible corresponding constructor
* calls.
*
* @param tree the MethodInvocationTree node that is to be resolved (Constructor.newInstance)
* @return a (potentially empty) list of all resolved MethodInvocationTrees
*/
private List<JCNewClass> resolveReflectiveConstructor(MethodInvocationTree tree, AnnotatedTypeFactory reflectionFactory) {
assert isReflectiveMethodInvocation(tree);
JCMethodInvocation methodInvocation = (JCMethodInvocation) tree;
Context context = ((JavacProcessingEnvironment) processingEnv).getContext();
TreeMaker make = TreeMaker.instance(context);
TreePath path = reflectionFactory.getPath(tree);
JavacScope scope = (JavacScope) trees.getScope(path);
Env<AttrContext> env = scope.getEnv();
List<JCNewClass> constructors = new ArrayList<>();
AnnotationMirror estimate = getMethodVal(tree);
if (estimate == null) {
debugReflection("MethodVal is unknown for: " + tree);
debugReflection("UnknownMethod annotation: " + isUnknownMethod(tree));
return constructors;
}
debugReflection("MethodVal type system annotations: " + estimate);
List<String> listClassNames = AnnotationUtils.getElementValueArray(estimate, "className", String.class, true);
List<Integer> listParamLenghts = AnnotationUtils.getElementValueArray(estimate, "params", Integer.class, true);
assert listClassNames.size() == listParamLenghts.size();
for (int i = 0; i < listClassNames.size(); ++i) {
String className = listClassNames.get(i);
int paramLength = listParamLenghts.get(i);
// Resolve the Symbol for the current constructor
for (Symbol symbol : getConstructorSymbolsfor(className, paramLength, env)) {
debugReflection("Resolved constructor: " + symbol.owner + "." + symbol);
JCNewClass syntTree = (JCNewClass) make.Create(symbol, methodInvocation.args);
// add constructor invocation tree to the list of possible
// constructors
constructors.add(syntTree);
}
}
return constructors;
}
use of com.sun.tools.javac.tree.JCTree.JCMethodInvocation in project st-js by st-js.
the class InternalUtils method constructor.
/**
* Determines the symbol for a constructor given an invocation via {@code new}. If the tree is a declaration of an
* anonymous class, then method returns constructor that gets invoked in the extended class, rather than the
* anonymous constructor implicitly added by the constructor (JLS 15.9.5.1)
*
* @param tree
* the constructor invocation
* @return the {@link javax.lang.model.element.ExecutableElement} corresponding to the constructor call in
* {@code tree}
*/
public static ExecutableElement constructor(NewClassTree tree) {
if (!(tree instanceof JCTree.JCNewClass)) {
ErrorReporter.errorAbort("InternalUtils.constructor: not a javac internal tree");
// dead code
return null;
}
JCNewClass newClassTree = (JCNewClass) tree;
if (RETURN_INVOKE_CONSTRUCTOR && tree.getClassBody() != null) {
// anonymous constructor bodies should contain exactly one statement
// in the form:
// super(arg1, ...)
// or
// o.super(arg1, ...)
//
// which is a method invocation (!) to the actual constructor
// the method call is guaranteed to return nonnull
JCMethodDecl anonConstructor = (JCMethodDecl) TreeInfo.declarationFor(newClassTree.constructor, newClassTree);
assert anonConstructor != null;
assert anonConstructor.body.stats.size() == 1;
JCExpressionStatement stmt = (JCExpressionStatement) anonConstructor.body.stats.head;
JCTree.JCMethodInvocation superInvok = (JCMethodInvocation) stmt.expr;
return (ExecutableElement) TreeInfo.symbol(superInvok.meth);
}
Element e = newClassTree.constructor;
assert e instanceof ExecutableElement;
return (ExecutableElement) e;
}
use of com.sun.tools.javac.tree.JCTree.JCMethodInvocation in project error-prone by google.
the class ShouldHaveEvenArgs method matchMethodInvocation.
@Override
public Description matchMethodInvocation(MethodInvocationTree methodInvocationTree, VisitorState state) {
if (!MATCHER.matches(methodInvocationTree, state)) {
return Description.NO_MATCH;
}
if (methodInvocationTree.getArguments().size() % 2 == 0) {
return Description.NO_MATCH;
}
JCMethodInvocation methodInvocation = (JCMethodInvocation) methodInvocationTree;
List<JCExpression> arguments = methodInvocation.getArguments();
Type typeVargs = methodInvocation.varargsElement;
if (typeVargs == null) {
return Description.NO_MATCH;
}
Type typeVarargsArr = state.arrayTypeForType(typeVargs);
Type lastArgType = ASTHelpers.getType(Iterables.getLast(arguments));
if (typeVarargsArr.equals(lastArgType)) {
return Description.NO_MATCH;
}
return describeMatch(methodInvocationTree);
}
Aggregations