1 /*
   2  * Copyright (c) 2014, 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 /*
  26  * @test
  27  * @bug 8031744
  28  * @summary test that the right thing happens when we compile java/lang/annotation/Target.java
  29  * @library /tools/javac/lib
  30  * @build JavacTestingAbstractProcessor TestCompileMetaAnnotations
  31  * @compile -processor TestCompileMetaAnnotations -proc:only -implicit:class ../java/lang/annotation/Target.java
  32  */
  33 
  34 import com.sun.tools.javac.code.Attribute;
  35 import com.sun.tools.javac.code.Symbol;
  36 import com.sun.tools.javac.code.Symbol.ClassSymbol;
  37 import com.sun.tools.javac.code.Symtab;
  38 import com.sun.tools.javac.code.Type;
  39 import com.sun.tools.javac.processing.JavacProcessingEnvironment;
  40 import com.sun.tools.javac.util.Assert;
  41 import com.sun.tools.javac.util.Context;
  42 
  43 import java.util.*;
  44 import javax.annotation.processing.*;
  45 import javax.lang.model.element.*;
  46 
  47 @SupportedAnnotationTypes({"java.lang.annotation.Target"})
  48 public class TestCompileMetaAnnotations extends JavacTestingAbstractProcessor {
  49     private int round = 0;
  50 
  51     @Override
  52     public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
  53         if (round > 0) return false;
  54 
  55         JavacProcessingEnvironment env = (JavacProcessingEnvironment)processingEnv;
  56         Context ctx = env.getContext();
  57         Symtab tab = Symtab.instance(ctx);
  58 
  59         // game on!
  60         Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(java.lang.annotation.Target.class);
  61         Assert.check(elements.size() == 1);
  62 
  63         Type predefTargetType = tab.annotationTargetType;
  64         ClassSymbol predefTarget = (ClassSymbol)predefTargetType.tsym;
  65 
  66         ClassSymbol currentlyCompiling = (ClassSymbol)elements.toArray()[0];
  67         Type currentyCompilingType = currentlyCompiling.type;
  68 
  69         Attribute.Compound usingPredef = currentlyCompiling.attribute(predefTarget);
  70         Attribute.Compound usingCurrently = currentlyCompiling.attribute(currentlyCompiling);
  71 
  72         System.err.println("Predef: " + printSymbol(predefTarget));
  73         System.err.println("Compiling: " + printSymbol(currentlyCompiling));
  74         System.err.println("Using predef: " + usingPredef + " declared: " + printSymbol(usingPredef.type.tsym));
  75         System.err.println("Using currently: " + usingCurrently + " declared: " + printSymbol(usingCurrently.type.tsym));
  76 
  77         // Check that the predefined Symbol for @Target matches the Symbol we are currently compiling
  78         // and matches the tsym for the @Target... annotation on the declaration of
  79         // java.lang.annotation.Target
  80         Assert.check(predefTarget == currentlyCompiling);
  81         Assert.check(currentlyCompiling == usingPredef.type.tsym);
  82         Assert.check(usingPredef.type.tsym == usingCurrently.type.tsym);
  83 
  84         Assert.check(predefTargetType == currentyCompilingType);
  85 
  86         Assert.checkNonNull(predefTarget.sourcefile);
  87 
  88         round++;
  89         return true;
  90     }
  91 
  92     private String printSymbol(Symbol s) {
  93         return  s.getClass().getName() + "@0x" + Integer.toHexString(s.hashCode());
  94     }
  95 }