test/tools/javac/api/taskListeners/TestSimpleAddRemove.java

Wed, 08 Oct 2014 14:16:40 -0700

author
asaha
date
Wed, 08 Oct 2014 14:16:40 -0700
changeset 2586
f5e5ca7505e2
parent 0
959103a6100f
permissions
-rw-r--r--

Merge

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation.
aoqi@0 8 *
aoqi@0 9 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 12 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 13 * accompanied this code).
aoqi@0 14 *
aoqi@0 15 * You should have received a copy of the GNU General Public License version
aoqi@0 16 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 18 *
aoqi@0 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 20 * or visit www.oracle.com if you need additional information or have any
aoqi@0 21 * questions.
aoqi@0 22 */
aoqi@0 23
aoqi@0 24 /*
aoqi@0 25 * @test
aoqi@0 26 * @bug 7093891
aoqi@0 27 * @summary support multiple task listeners
aoqi@0 28 */
aoqi@0 29
aoqi@0 30 import java.io.File;
aoqi@0 31 import java.io.IOException;
aoqi@0 32 import java.io.PrintWriter;
aoqi@0 33 import java.io.StringWriter;
aoqi@0 34 import java.net.URI;
aoqi@0 35 import java.util.ArrayList;
aoqi@0 36 import java.util.Arrays;
aoqi@0 37 import java.util.EnumMap;
aoqi@0 38 import java.util.List;
aoqi@0 39 import java.util.Set;
aoqi@0 40
aoqi@0 41 import javax.annotation.processing.AbstractProcessor;
aoqi@0 42 import javax.annotation.processing.RoundEnvironment;
aoqi@0 43 import javax.annotation.processing.SupportedAnnotationTypes;
aoqi@0 44 import javax.lang.model.element.TypeElement;
aoqi@0 45 import javax.tools.JavaFileObject;
aoqi@0 46 import javax.tools.SimpleJavaFileObject;
aoqi@0 47 import javax.tools.StandardJavaFileManager;
aoqi@0 48 import javax.tools.StandardLocation;
aoqi@0 49 import javax.tools.ToolProvider;
aoqi@0 50
aoqi@0 51 import com.sun.source.util.JavacTask;
aoqi@0 52 import com.sun.source.util.TaskEvent;
aoqi@0 53 import com.sun.source.util.TaskListener;
aoqi@0 54 import com.sun.tools.javac.api.JavacTool;
aoqi@0 55
aoqi@0 56 public class TestSimpleAddRemove {
aoqi@0 57 enum AddKind {
aoqi@0 58 SET_IN_TASK,
aoqi@0 59 ADD_IN_TASK,
aoqi@0 60 ADD_IN_PROCESSOR,
aoqi@0 61 ADD_IN_LISTENER;
aoqi@0 62 }
aoqi@0 63
aoqi@0 64 enum RemoveKind {
aoqi@0 65 REMOVE_IN_TASK,
aoqi@0 66 REMOVE_IN_PROCESSOR,
aoqi@0 67 REMOVE_IN_LISTENER,
aoqi@0 68 }
aoqi@0 69
aoqi@0 70 enum CompileKind {
aoqi@0 71 CALL {
aoqi@0 72 void run(JavacTask t) {
aoqi@0 73 if (!t.call()) throw new Error("compilation failed");
aoqi@0 74 }
aoqi@0 75 },
aoqi@0 76 GENERATE {
aoqi@0 77 void run(JavacTask t) throws IOException {
aoqi@0 78 t.generate();
aoqi@0 79 }
aoqi@0 80 };
aoqi@0 81 abstract void run(JavacTask t) throws IOException;
aoqi@0 82 }
aoqi@0 83
aoqi@0 84 static class EventKindCounter extends EnumMap<TaskEvent.Kind, EventKindCounter.Count> {
aoqi@0 85 static class Count {
aoqi@0 86 int started;
aoqi@0 87 int finished;
aoqi@0 88
aoqi@0 89 @Override
aoqi@0 90 public String toString() {
aoqi@0 91 return started + ":" + finished;
aoqi@0 92 }
aoqi@0 93 }
aoqi@0 94
aoqi@0 95 EventKindCounter() {
aoqi@0 96 super(TaskEvent.Kind.class);
aoqi@0 97 }
aoqi@0 98
aoqi@0 99 void inc(TaskEvent.Kind k, boolean started) {
aoqi@0 100 Count c = get(k);
aoqi@0 101 if (c == null)
aoqi@0 102 put(k, c = new Count());
aoqi@0 103
aoqi@0 104 if (started)
aoqi@0 105 c.started++;
aoqi@0 106 else
aoqi@0 107 c.finished++;
aoqi@0 108 }
aoqi@0 109 }
aoqi@0 110
aoqi@0 111 static class TestListener implements TaskListener {
aoqi@0 112 EventKindCounter counter;
aoqi@0 113
aoqi@0 114 TestListener(EventKindCounter c) {
aoqi@0 115 counter = c;
aoqi@0 116 }
aoqi@0 117
aoqi@0 118 public void started(TaskEvent e) {
aoqi@0 119 counter.inc(e.getKind(), true);
aoqi@0 120 }
aoqi@0 121
aoqi@0 122 public void finished(TaskEvent e) {
aoqi@0 123 counter.inc(e.getKind(), false);
aoqi@0 124 }
aoqi@0 125 }
aoqi@0 126
aoqi@0 127 static void addInListener(final JavacTask task, final TaskEvent.Kind kind, final TaskListener listener) {
aoqi@0 128 task.addTaskListener(new TaskListener() {
aoqi@0 129 public void started(TaskEvent e) {
aoqi@0 130 if (e.getKind() == kind) {
aoqi@0 131 task.addTaskListener(listener);
aoqi@0 132 task.removeTaskListener(this);
aoqi@0 133 }
aoqi@0 134 }
aoqi@0 135
aoqi@0 136 public void finished(TaskEvent e) { }
aoqi@0 137 });
aoqi@0 138 }
aoqi@0 139
aoqi@0 140 static void removeInListener(final JavacTask task, final TaskEvent.Kind kind, final TaskListener listener) {
aoqi@0 141 task.addTaskListener(new TaskListener() {
aoqi@0 142 public void started(TaskEvent e) {
aoqi@0 143 if (e.getKind() == kind) {
aoqi@0 144 task.removeTaskListener(listener);
aoqi@0 145 task.removeTaskListener(this);
aoqi@0 146 }
aoqi@0 147 }
aoqi@0 148
aoqi@0 149 public void finished(TaskEvent e) { }
aoqi@0 150 });
aoqi@0 151 }
aoqi@0 152
aoqi@0 153 @SupportedAnnotationTypes("*")
aoqi@0 154 class TestProcessor extends AbstractProcessor {
aoqi@0 155 AddKind ak;
aoqi@0 156 RemoveKind rk;
aoqi@0 157 TaskListener listener;
aoqi@0 158
aoqi@0 159 TestProcessor(AddKind ak, RemoveKind rk, TaskListener listener) {
aoqi@0 160 this.ak = ak;
aoqi@0 161 this.rk = rk;
aoqi@0 162 this.listener = listener;
aoqi@0 163 }
aoqi@0 164
aoqi@0 165 int round = 0;
aoqi@0 166
aoqi@0 167 @Override
aoqi@0 168 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
aoqi@0 169 // System.err.println("TestProcessor.process " + roundEnv);
aoqi@0 170 JavacTask task = JavacTask.instance(processingEnv);
aoqi@0 171 if (++round == 1) {
aoqi@0 172 switch (ak) {
aoqi@0 173 case ADD_IN_PROCESSOR:
aoqi@0 174 task.addTaskListener(listener);
aoqi@0 175 break;
aoqi@0 176 case ADD_IN_LISTENER:
aoqi@0 177 addInListener(task, TaskEvent.Kind.ANALYZE, listener);
aoqi@0 178 break;
aoqi@0 179 }
aoqi@0 180 } else if (roundEnv.processingOver()) {
aoqi@0 181 switch (rk) {
aoqi@0 182 case REMOVE_IN_PROCESSOR:
aoqi@0 183 task.removeTaskListener(listener);
aoqi@0 184 break;
aoqi@0 185 case REMOVE_IN_LISTENER:
aoqi@0 186 removeInListener(task, TaskEvent.Kind.GENERATE, listener);
aoqi@0 187 break;
aoqi@0 188 }
aoqi@0 189 }
aoqi@0 190 return true;
aoqi@0 191 }
aoqi@0 192 }
aoqi@0 193
aoqi@0 194 static class TestSource extends SimpleJavaFileObject {
aoqi@0 195 public TestSource() {
aoqi@0 196 super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
aoqi@0 197 }
aoqi@0 198
aoqi@0 199 @Override
aoqi@0 200 public CharSequence getCharContent(boolean ignoreEncodingErrors) {
aoqi@0 201 return "class Test { }";
aoqi@0 202 }
aoqi@0 203 }
aoqi@0 204
aoqi@0 205 public static void main(String... args) throws Exception {
aoqi@0 206 new TestSimpleAddRemove().run();
aoqi@0 207 }
aoqi@0 208
aoqi@0 209 JavacTool tool = (JavacTool) ToolProvider.getSystemJavaCompiler();
aoqi@0 210 StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
aoqi@0 211
aoqi@0 212 void run() throws Exception {
aoqi@0 213 for (CompileKind ck: CompileKind.values()) {
aoqi@0 214 for (AddKind ak: AddKind.values()) {
aoqi@0 215 for (RemoveKind rk: RemoveKind.values()) {
aoqi@0 216 test(ck, ak, rk);
aoqi@0 217 }
aoqi@0 218 }
aoqi@0 219 }
aoqi@0 220 if (errors > 0)
aoqi@0 221 throw new Exception(errors + " errors occurred");
aoqi@0 222 }
aoqi@0 223
aoqi@0 224 void test(CompileKind ck, AddKind ak, RemoveKind rk) throws IOException {
aoqi@0 225 System.err.println("Test: " + ck + " " + ak + " " + rk);
aoqi@0 226
aoqi@0 227 File tmpDir = new File(ck + "-" + ak + "-" + rk);
aoqi@0 228 tmpDir.mkdirs();
aoqi@0 229 fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(tmpDir));
aoqi@0 230
aoqi@0 231 List<String> options = new ArrayList<String>();
aoqi@0 232 Iterable<? extends JavaFileObject> files = Arrays.asList(new TestSource());
aoqi@0 233 StringWriter sw = new StringWriter();
aoqi@0 234 PrintWriter pw = new PrintWriter(sw);
aoqi@0 235 JavacTask task = tool.getTask(pw, fm, null, options, null, files);
aoqi@0 236
aoqi@0 237 EventKindCounter ec = new EventKindCounter();
aoqi@0 238 TaskListener listener = new TestListener(ec);
aoqi@0 239 boolean needProcessor = false;
aoqi@0 240
aoqi@0 241 switch (ak) {
aoqi@0 242 case SET_IN_TASK:
aoqi@0 243 task.setTaskListener(listener);
aoqi@0 244 break;
aoqi@0 245 case ADD_IN_TASK:
aoqi@0 246 task.addTaskListener(listener);
aoqi@0 247 break;
aoqi@0 248 case ADD_IN_PROCESSOR:
aoqi@0 249 case ADD_IN_LISTENER:
aoqi@0 250 needProcessor = true;
aoqi@0 251 }
aoqi@0 252
aoqi@0 253 switch (rk) {
aoqi@0 254 case REMOVE_IN_TASK:
aoqi@0 255 task.removeTaskListener(listener);
aoqi@0 256 break;
aoqi@0 257 case REMOVE_IN_PROCESSOR:
aoqi@0 258 case REMOVE_IN_LISTENER:
aoqi@0 259 needProcessor = true;
aoqi@0 260 }
aoqi@0 261
aoqi@0 262 if (needProcessor)
aoqi@0 263 task.setProcessors(Arrays.asList(new TestProcessor(ak, rk, listener)));
aoqi@0 264
aoqi@0 265 ck.run(task);
aoqi@0 266 System.err.println(ec);
aoqi@0 267
aoqi@0 268 check(ck, ak, rk, ec);
aoqi@0 269
aoqi@0 270 System.err.println();
aoqi@0 271 }
aoqi@0 272
aoqi@0 273 void check(CompileKind ck, AddKind ak, RemoveKind rk, EventKindCounter ec) {
aoqi@0 274 // All results should be independent of ck, so we can ignore that
aoqi@0 275
aoqi@0 276 // Quick way to compare expected values of ec, by comparing ec.toString()
aoqi@0 277 String expect = ec.toString();
aoqi@0 278 String found;
aoqi@0 279
aoqi@0 280 switch (ak) {
aoqi@0 281 // Add/set in task should record all events until the listener is removed
aoqi@0 282 case SET_IN_TASK:
aoqi@0 283 case ADD_IN_TASK:
aoqi@0 284 switch (rk) {
aoqi@0 285 case REMOVE_IN_TASK:
aoqi@0 286 // Remove will succeed, meaning no events will be recorded
aoqi@0 287 found = "{}";
aoqi@0 288 break;
aoqi@0 289 case REMOVE_IN_PROCESSOR:
aoqi@0 290 found = "{PARSE=1:1, ENTER=2:2, ANNOTATION_PROCESSING=1:0, ANNOTATION_PROCESSING_ROUND=2:1}";
aoqi@0 291 break;
aoqi@0 292 case REMOVE_IN_LISTENER:
aoqi@0 293 found = "{PARSE=1:1, ENTER=3:3, ANALYZE=1:1, GENERATE=1:0, ANNOTATION_PROCESSING=1:1, ANNOTATION_PROCESSING_ROUND=2:2}";
aoqi@0 294 break;
aoqi@0 295 default:
aoqi@0 296 throw new IllegalStateException();
aoqi@0 297 }
aoqi@0 298 break;
aoqi@0 299
aoqi@0 300 // "Add in processor" should skip initial PARSE/ENTER events
aoqi@0 301 case ADD_IN_PROCESSOR:
aoqi@0 302 switch (rk) {
aoqi@0 303 // Remove will fail (too early), so events to end will be recorded
aoqi@0 304 case REMOVE_IN_TASK:
aoqi@0 305 found = "{ENTER=2:2, ANALYZE=1:1, GENERATE=1:1, ANNOTATION_PROCESSING=0:1, ANNOTATION_PROCESSING_ROUND=1:2}";
aoqi@0 306 break;
aoqi@0 307 case REMOVE_IN_PROCESSOR:
aoqi@0 308 found = "{ENTER=1:1, ANNOTATION_PROCESSING_ROUND=1:1}";
aoqi@0 309 break;
aoqi@0 310 case REMOVE_IN_LISTENER:
aoqi@0 311 found = "{ENTER=2:2, ANALYZE=1:1, GENERATE=1:0, ANNOTATION_PROCESSING=0:1, ANNOTATION_PROCESSING_ROUND=1:2}";
aoqi@0 312 break;
aoqi@0 313 default:
aoqi@0 314 throw new IllegalStateException();
aoqi@0 315 }
aoqi@0 316 break;
aoqi@0 317
aoqi@0 318 // "Add in listener" will occur during "ANALYSE.started" event
aoqi@0 319 case ADD_IN_LISTENER:
aoqi@0 320 switch (rk) {
aoqi@0 321 // Remove will fail (too early, so events to end will be recorded
aoqi@0 322 case REMOVE_IN_TASK:
aoqi@0 323 case REMOVE_IN_PROCESSOR:
aoqi@0 324 found = "{ANALYZE=0:1, GENERATE=1:1}";
aoqi@0 325 break;
aoqi@0 326 // Remove will succeed during "GENERATE.finished" event
aoqi@0 327 case REMOVE_IN_LISTENER:
aoqi@0 328 found = "{ANALYZE=0:1, GENERATE=1:0}";
aoqi@0 329 break;
aoqi@0 330 default:
aoqi@0 331 throw new IllegalStateException();
aoqi@0 332 }
aoqi@0 333 break;
aoqi@0 334 default:
aoqi@0 335 throw new IllegalStateException();
aoqi@0 336 }
aoqi@0 337
aoqi@0 338 if (!found.equals(expect)) {
aoqi@0 339 System.err.println("Expected: " + expect);
aoqi@0 340 System.err.println(" Found: " + found);
aoqi@0 341 error("unexpected value found");
aoqi@0 342 }
aoqi@0 343 }
aoqi@0 344
aoqi@0 345 int errors;
aoqi@0 346
aoqi@0 347 void error(String message) {
aoqi@0 348 System.err.println("Error: " + message);
aoqi@0 349 errors++;
aoqi@0 350 }
aoqi@0 351 }

mercurial