test/tools/javac/util/context/T7021650.java

Fri, 25 Feb 2011 12:09:33 -0800

author
jjg
date
Fri, 25 Feb 2011 12:09:33 -0800
changeset 893
8f0dcb9499db
child 1097
497571d34112
permissions
-rw-r--r--

7021650: fix Context issues
Reviewed-by: mcimadamore

     1 /*
     2  * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  */
    24 /**
    25  * @test
    26  * @bug 7021650
    27  * @summary Fix Context issues
    28  * @library ../../lib
    29  * @build JavacTestingAbstractProcessor T7021650
    30  * @run main T7021650
    31  */
    33 import java.io.*;
    34 import java.net.*;
    35 import java.util.*;
    36 import javax.annotation.processing.*;
    37 import javax.lang.model.element.*;
    38 import javax.tools.*;
    40 import com.sun.tools.javac.comp.Attr;
    41 import com.sun.tools.javac.file.JavacFileManager;
    42 import com.sun.tools.javac.main.Main;
    43 import com.sun.tools.javac.processing.JavacProcessingEnvironment;
    44 import com.sun.tools.javac.util.Context;
    46 public class T7021650 extends JavacTestingAbstractProcessor {
    47     public static void main(String... args) throws Exception {
    48         new T7021650().run();
    49     }
    51     static File testSrc = new File(System.getProperty("test.src"));
    52     static final int MAX_ROUNDS = 3;
    54     /**
    55      * Perform a compilation with custom factories registered in the context,
    56      * and verify that corresponding objects are created in each round.
    57      */
    58     void run() throws Exception {
    59         Counter demoCounter = new Counter();
    60         Counter myAttrCounter = new Counter();
    62         Context context = new Context();
    63         // Use a custom file manager which creates classloaders for annotation
    64         // processors with a sensible delegation parent, so that all instances
    65         // of test classes come from the same class loader. This is important
    66         // because the test performs class checks on the instances of classes
    67         // found in the context for each round or processing.
    68         context.put(JavaFileManager.class, new Context.Factory<JavaFileManager>() {
    69             public JavaFileManager make(Context c) {
    70                 return new JavacFileManager(c, true, null) {
    71                     @Override
    72                     protected ClassLoader getClassLoader(URL[] urls) {
    73                         return new URLClassLoader(urls, T7021650.class.getClassLoader());
    74                     }
    75                 };
    76             }
    77         });
    79         Demo.preRegister(context, demoCounter);
    80         MyAttr.preRegister(context, myAttrCounter);
    82         String[] args = {
    83             "-d", ".",
    84             "-processor", T7021650.class.getName(),
    85             "-XprintRounds",
    86             new File(testSrc, T7021650.class.getName() + ".java").getPath()
    87         };
    89         compile(context, args);
    91         // Expect to create Demo for initial round, then MAX_ROUNDS in which
    92         // GenX files are generated, then standard final round of processing.
    93         checkEqual("demoCounter", demoCounter.count, MAX_ROUNDS + 2);
    95         // Expect to create MyAttr for same processing rounds as for Demo,
    96         // plus additional context for final compilation.
    97         checkEqual("myAttrCounter", myAttrCounter.count, MAX_ROUNDS + 3);
    98     }
   100     void compile(Context context, String... args) throws Exception {
   101         StringWriter sw = new StringWriter();
   102         PrintWriter pw = new PrintWriter(sw);
   103         Main m = new Main("javac", pw);
   104         int rc = m.compile(args, context);
   105         pw.close();
   106         String out = sw.toString();
   107         if (!out.isEmpty())
   108             System.err.println(out);
   109         if (rc != 0)
   110             throw new Exception("compilation failed unexpectedly: rc=" + rc);
   111     }
   113     void checkEqual(String label, int found, int expect) throws Exception {
   114         if (found != expect)
   115             throw new Exception("unexpected value for " + label
   116                     + ": expected " + expect
   117                     + ": found " + found);
   118     }
   120     //---------------
   122     /*
   123      * A custom class unknown to javac but nonetheless registered in the context.
   124      */
   125     static class Demo {
   126         static void preRegister(Context context, final Counter counter) {
   127             context.put(Demo.class, new Context.Factory<Demo>() {
   128                 public Demo make(Context c) {
   129                     counter.count++;
   130                     return new Demo(c);
   131                 }
   132             });
   133         }
   135         Demo(Context c) {
   136             c.put(Demo.class, this);
   137         }
   139         static Demo instance(Context context) {
   140             return context.get(Demo.class);
   141         }
   142     }
   144     /**
   145      * A custom version of a standard javac component.
   146      */
   147     static class MyAttr extends Attr {
   148         static void preRegister(Context context, final Counter counter) {
   149             context.put(attrKey, new Context.Factory<Attr>() {
   150                 public Attr make(Context c) {
   151                     counter.count++;
   152                     return new MyAttr(c);
   153                 }
   154             });
   155         }
   157         MyAttr(Context c) {
   158             super(c);
   159         }
   160     }
   162     static class Counter {
   163         int count;
   164     }
   166     //---------------
   168     int round = 0;
   170     @Override
   171     public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
   172         round++;
   174         Context context = ((JavacProcessingEnvironment) processingEnv).getContext();
   176         // verify items in context as expected
   177         check("Demo", Demo.instance(context), Demo.class);
   178         check("Attr", Attr.instance(context), MyAttr.class);
   180         // For a few rounds, generate new source files, so that we can check whether
   181         // values in the context are correctly handled in subsequent processing rounds
   182         if (round <= MAX_ROUNDS) {
   183             String pkg = "p";
   184             String currClass = "Gen" + round;
   185             String curr = pkg + "." + currClass;
   186             String next = (pkg + ".Gen" + (round + 1));
   187             StringBuilder text = new StringBuilder();
   188             text.append("package ").append(pkg).append(";\n");
   189             text.append("public class ").append(currClass).append(" {\n");
   190             if (round < MAX_ROUNDS)
   191                 text.append("    ").append(next).append(" x;\n");
   192             text.append("}\n");
   194             try {
   195                 JavaFileObject fo = filer.createSourceFile(curr);
   196                 Writer out = fo.openWriter();
   197                 try {
   198                     out.write(text.toString());
   199                 } finally {
   200                     out.close();
   201                 }
   202             } catch (IOException e) {
   203                 throw new Error(e);
   204             }
   205         }
   207         return true;
   208     }
   210     void check(String label, Object o, Class<?> clazz) {
   211         if (o == null)
   212             throw new IllegalStateException(label + ": no item found");
   213         if (!clazz.isAssignableFrom(o.getClass()))
   214             throw new IllegalStateException(label + ": unexpected class: " + o.getClass());
   215     }
   216 }

mercurial