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

Fri, 21 Dec 2012 08:45:43 -0800

author
darcy
date
Fri, 21 Dec 2012 08:45:43 -0800
changeset 1466
b52a38d4536c
parent 1097
497571d34112
child 2525
2eb010b6cb22
permissions
-rw-r--r--

8005282: Use @library tag with non-relative path for javac tests
Reviewed-by: jjg

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

mercurial