OnDemandAttribution.java revision 3661:39b3a85da6af
1/* 2 * Copyright (c) 2014, 2016, 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 */ 23 24/* 25 * @test 26 * @bug 8038455 8047347 27 * @summary Verify that in-method ClassSymbols from one round do not affect ClassSymbols in 28 * following rounds. 29 * @library /tools/javac/lib 30 * @modules jdk.compiler 31 * @build JavacTestingAbstractProcessor OnDemandAttribution 32 * @clean Gen 33 * @compile/process -processor OnDemandAttribution OnDemandAttributionData.java 34 */ 35 36import java.io.IOException; 37import java.io.Writer; 38import java.util.*; 39import javax.annotation.processing.*; 40import javax.lang.model.element.*; 41import static javax.lang.model.util.ElementFilter.constructorsIn; 42import com.sun.source.tree.*; 43import com.sun.source.util.*; 44 45public class OnDemandAttribution extends JavacTestingAbstractProcessor { 46 47 public OnDemandAttribution() { 48 } 49 50 int round; 51 Set<String> roots = new HashSet<>(); 52 53 public boolean process(Set<? extends TypeElement> annos,RoundEnvironment rEnv) { 54 for (Element root : rEnv.getRootElements()) { 55 while (root.getEnclosingElement().getKind() != ElementKind.PACKAGE) { 56 root = root.getEnclosingElement(); 57 } 58 roots.add(((TypeElement) root).getQualifiedName().toString()); 59 } 60 for (String root : roots) { 61 TypeElement currentClass = elements.getTypeElement(root); 62 ExecutableElement constr = constructorsIn(currentClass.getEnclosedElements()).get(0); 63 Trees trees = Trees.instance(processingEnv); 64 TreePath path = trees.getPath(constr); 65 66 new TreePathScanner<Void, Void>() { 67 @Override public Void visitClass(ClassTree node, Void p) { 68 if (node.getSimpleName().contentEquals("Local")) { 69 //will also attribute the body on demand: 70 Element el = trees.getElement(getCurrentPath()); 71 Name binaryName = elements.getBinaryName((TypeElement) el); 72 if (!binaryName.contentEquals("OnDemandAttributionData$1Local")) { 73 throw new IllegalStateException("Incorrect binary name=" + binaryName); 74 } 75 } 76 return super.visitClass(node, p); 77 } 78 @Override public Void visitNewClass(NewClassTree node, Void p) { 79 Element el = trees.getElement(getCurrentPath()); 80 Name binaryName = elements.getBinaryName((TypeElement) el.getEnclosingElement()); 81 if (!binaryName.contentEquals("OnDemandAttributionData$1")) { 82 throw new IllegalStateException("Incorrect binary name=" + binaryName); 83 } 84 return super.visitNewClass(node, p); 85 } 86 @Override 87 public Void visitMethodInvocation(MethodInvocationTree node, Void p) { 88 if (trees.getElement(getCurrentPath()) == null) 89 throw new IllegalStateException("No element for: " + node); 90 return super.visitMethodInvocation(node, p); 91 } 92 @Override 93 public Void visitIdentifier(IdentifierTree node, Void p) { 94 if (trees.getElement(getCurrentPath()) == null) 95 throw new IllegalStateException("No element for: " + node); 96 return super.visitIdentifier(node, p); 97 } 98 }.scan(path, null); 99 } 100 101 if (round++ == 0) { 102 try (Writer out = filer.createSourceFile("Gen").openWriter()) { 103 out.write("class Gen { public static long C = 1; }"); 104 } catch (IOException ex) { 105 throw new IllegalStateException(ex); 106 } 107 } 108 109 return true; 110 } 111} 112