Search in sources :

Example 6 with TreeMaker

use of com.sun.tools.javac.tree.TreeMaker 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();
    boolean unknown = isUnknownMethod(tree);
    AnnotationMirror estimate = getMethodVal(tree);
    if (estimate == null) {
        debugReflection("MethodVal is unknown for: " + tree);
        debugReflection("UnknownMethod annotation: " + unknown);
        return Collections.emptyList();
    }
    debugReflection("MethodVal type system annotations: " + estimate);
    List<String> listClassNames = AnnotationUtils.getElementValueArray(estimate, reflectionFactory.methodValClassNameElement, String.class);
    List<String> listMethodNames = AnnotationUtils.getElementValueArray(estimate, reflectionFactory.methodValMethodNameElement, String.class);
    List<Integer> listParamLengths = AnnotationUtils.getElementValueArray(estimate, reflectionFactory.methodValParamsElement, Integer.class);
    assert listClassNames.size() == listMethodNames.size() && listClassNames.size() == listParamLengths.size();
    List<MethodInvocationTree> methods = new ArrayList<>();
    for (int i = 0; i < listClassNames.size(); ++i) {
        String className = listClassNames.get(i);
        String methodName = listMethodNames.get(i);
        int paramLength = listParamLengths.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 (!processingEnv.getTypeUtils().isSubtype(receiver.type, symbol.owner.type)) {
                continue;
            }
            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;
}
Also used : Context(com.sun.tools.javac.util.Context) AttrContext(com.sun.tools.javac.comp.AttrContext) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) Symbol(com.sun.tools.javac.code.Symbol) ArrayList(java.util.ArrayList) JavacScope(com.sun.tools.javac.api.JavacScope) AttrContext(com.sun.tools.javac.comp.AttrContext) JCMethodInvocation(com.sun.tools.javac.tree.JCTree.JCMethodInvocation) AnnotationMirror(javax.lang.model.element.AnnotationMirror) TreeMaker(com.sun.tools.javac.tree.TreeMaker) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) TreePath(com.sun.source.util.TreePath) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) JavacProcessingEnvironment(com.sun.tools.javac.processing.JavacProcessingEnvironment)

Example 7 with TreeMaker

use of com.sun.tools.javac.tree.TreeMaker 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();
    AnnotationMirror estimate = getMethodVal(tree);
    if (estimate == null) {
        debugReflection("MethodVal is unknown for: " + tree);
        debugReflection("UnknownMethod annotation: " + isUnknownMethod(tree));
        return Collections.emptyList();
    }
    debugReflection("MethodVal type system annotations: " + estimate);
    List<String> listClassNames = AnnotationUtils.getElementValueArray(estimate, reflectionFactory.methodValClassNameElement, String.class);
    List<Integer> listParamLengths = AnnotationUtils.getElementValueArray(estimate, reflectionFactory.methodValParamsElement, Integer.class);
    assert listClassNames.size() == listParamLengths.size();
    List<JCNewClass> constructors = new ArrayList<>();
    for (int i = 0; i < listClassNames.size(); ++i) {
        String className = listClassNames.get(i);
        int paramLength = listParamLengths.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;
}
Also used : Context(com.sun.tools.javac.util.Context) AttrContext(com.sun.tools.javac.comp.AttrContext) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) Symbol(com.sun.tools.javac.code.Symbol) ArrayList(java.util.ArrayList) JavacScope(com.sun.tools.javac.api.JavacScope) AttrContext(com.sun.tools.javac.comp.AttrContext) JCMethodInvocation(com.sun.tools.javac.tree.JCTree.JCMethodInvocation) AnnotationMirror(javax.lang.model.element.AnnotationMirror) TreeMaker(com.sun.tools.javac.tree.TreeMaker) TreePath(com.sun.source.util.TreePath) JavacProcessingEnvironment(com.sun.tools.javac.processing.JavacProcessingEnvironment) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass)

Example 8 with TreeMaker

use of com.sun.tools.javac.tree.TreeMaker in project tutorials by eugenp.

the class SampleJavacPlugin method createCheck.

private static JCTree.JCIf createCheck(VariableTree parameter, Context context) {
    TreeMaker factory = TreeMaker.instance(context);
    Names symbolsTable = Names.instance(context);
    return factory.at(((JCTree) parameter).pos).If(factory.Parens(createIfCondition(factory, symbolsTable, parameter)), createIfBlock(factory, symbolsTable, parameter), null);
}
Also used : Names(com.sun.tools.javac.util.Names) TreeMaker(com.sun.tools.javac.tree.TreeMaker) JCTree(com.sun.tools.javac.tree.JCTree)

Aggregations

TreeMaker (com.sun.tools.javac.tree.TreeMaker)8 Symbol (com.sun.tools.javac.code.Symbol)3 JavacProcessingEnvironment (com.sun.tools.javac.processing.JavacProcessingEnvironment)3 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)3 Context (com.sun.tools.javac.util.Context)3 TreePath (com.sun.source.util.TreePath)2 JavacScope (com.sun.tools.javac.api.JavacScope)2 ClassSymbol (com.sun.tools.javac.code.Symbol.ClassSymbol)2 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)2 AttrContext (com.sun.tools.javac.comp.AttrContext)2 JCTree (com.sun.tools.javac.tree.JCTree)2 JCMethodInvocation (com.sun.tools.javac.tree.JCTree.JCMethodInvocation)2 ArrayList (java.util.ArrayList)2 AnnotationMirror (javax.lang.model.element.AnnotationMirror)2 BinaryTree (com.sun.source.tree.BinaryTree)1 ConditionalExpressionTree (com.sun.source.tree.ConditionalExpressionTree)1 LiteralTree (com.sun.source.tree.LiteralTree)1 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)1 Tree (com.sun.source.tree.Tree)1 UnaryTree (com.sun.source.tree.UnaryTree)1