Search in sources :

Example 41 with JavacProcessingEnvironment

use of com.sun.tools.javac.processing.JavacProcessingEnvironment 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 42 with JavacProcessingEnvironment

use of com.sun.tools.javac.processing.JavacProcessingEnvironment 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 43 with JavacProcessingEnvironment

use of com.sun.tools.javac.processing.JavacProcessingEnvironment in project checker-framework by typetools.

the class DefaultReflectionResolver method getConstructorSymbolsfor.

/**
 * Get set of Symbols for constructors based on class name and parameter length.
 *
 * @return the (potentially empty) set of corresponding constructor Symbol(s)
 */
private List<Symbol> getConstructorSymbolsfor(String className, int paramLength, Env<AttrContext> env) {
    Context context = ((JavacProcessingEnvironment) processingEnv).getContext();
    Resolve resolve = Resolve.instance(context);
    Names names = Names.instance(context);
    Symbol symClass = getSymbol(className, env, names, resolve);
    if (!symClass.exists()) {
        debugReflection("Unable to resolve class: " + className);
        return Collections.emptyList();
    }
    // TODO: Should this be used instead of the below??
    ElementFilter.constructorsIn(symClass.getEnclosedElements());
    // The common case is probably that `result` is a singleton at method exit.
    List<Symbol> result = new ArrayList<>();
    for (Symbol s : symClass.getEnclosedElements()) {
        // Check all constructors
        if (s.getKind() == ElementKind.CONSTRUCTOR) {
            // Check for number of parameters
            if (((MethodSymbol) s).getParameters().size() == paramLength) {
                result.add(s);
            }
        }
    }
    if (result.isEmpty()) {
        debugReflection("Unable to resolve constructor!");
    }
    return result;
}
Also used : Context(com.sun.tools.javac.util.Context) AttrContext(com.sun.tools.javac.comp.AttrContext) Names(com.sun.tools.javac.util.Names) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) Symbol(com.sun.tools.javac.code.Symbol) JavacProcessingEnvironment(com.sun.tools.javac.processing.JavacProcessingEnvironment) ArrayList(java.util.ArrayList) Resolve(com.sun.tools.javac.comp.Resolve)

Example 44 with JavacProcessingEnvironment

use of com.sun.tools.javac.processing.JavacProcessingEnvironment in project checker-framework by typetools.

the class SignaturePrinter method main.

public static void main(String[] args) {
    if (!(args.length == 1 && !args[0].startsWith(CHECKER_ARG)) && !(args.length == 2 && args[0].startsWith(CHECKER_ARG))) {
        printUsage();
        return;
    }
    // process arguments
    String checkerName = null;
    if (args[0].startsWith(CHECKER_ARG)) {
        checkerName = args[0].substring(CHECKER_ARG.length());
        if (!Signatures.isBinaryName(checkerName)) {
            throw new UserError("Bad checker name \"%s\"", checkerName);
        }
    }
    // Setup compiler environment
    Context context = new Context();
    JavacProcessingEnvironment env = JavacProcessingEnvironment.instance(context);
    SignaturePrinter printer = new SignaturePrinter();
    printer.init(env, checkerName);
    String className = args[args.length - 1];
    TypeElement elem = env.getElementUtils().getTypeElement(className);
    if (elem == null) {
        System.err.println("Couldn't find class: " + className);
        return;
    }
    printer.typeProcess(elem, null);
}
Also used : Context(com.sun.tools.javac.util.Context) UserError(org.checkerframework.javacutil.UserError) TypeElement(javax.lang.model.element.TypeElement) JavacProcessingEnvironment(com.sun.tools.javac.processing.JavacProcessingEnvironment)

Example 45 with JavacProcessingEnvironment

use of com.sun.tools.javac.processing.JavacProcessingEnvironment in project ceylon-compiler by ceylon.

the class TestContext method process.

@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
    round++;
    JavacProcessingEnvironment jpe = (JavacProcessingEnvironment) processingEnv;
    Context c = jpe.getContext();
    check(c.get(JavacElements.class), eltUtils);
    check(c.get(JavacTypes.class), typeUtils);
    check(c.get(JavacTrees.class), treeUtils);
    final int MAXROUNDS = 3;
    if (round < MAXROUNDS)
        generateSource("Gen" + round);
    return true;
}
Also used : Context(com.sun.tools.javac.util.Context) JavacTypes(com.sun.tools.javac.model.JavacTypes) JavacTrees(com.sun.tools.javac.api.JavacTrees) JavacElements(com.sun.tools.javac.model.JavacElements) JavacProcessingEnvironment(com.sun.tools.javac.processing.JavacProcessingEnvironment)

Aggregations

JavacProcessingEnvironment (com.sun.tools.javac.processing.JavacProcessingEnvironment)49 Context (com.sun.tools.javac.util.Context)30 Type (com.sun.tools.javac.code.Type)13 WildcardType (javax.lang.model.type.WildcardType)11 DeclaredType (javax.lang.model.type.DeclaredType)9 ArrayList (java.util.ArrayList)7 ArrayType (javax.lang.model.type.ArrayType)7 TreePath (com.sun.source.util.TreePath)6 Symtab (com.sun.tools.javac.code.Symtab)6 CapturedType (com.sun.tools.javac.code.Type.CapturedType)6 ClassType (com.sun.tools.javac.code.Type.ClassType)6 PrimitiveType (javax.lang.model.type.PrimitiveType)6 UnionType (javax.lang.model.type.UnionType)6 Symbol (com.sun.tools.javac.code.Symbol)5 ClassSymbol (com.sun.tools.javac.code.Symbol.ClassSymbol)5 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)5 Types (com.sun.tools.javac.code.Types)5 VariableTree (com.sun.source.tree.VariableTree)4 AttrContext (com.sun.tools.javac.comp.AttrContext)4 Log (com.sun.tools.javac.util.Log)3